From b4d3fa3c7ae756aa6add80e863d8b2dc68ef6ae0 Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:30:33 +0200 Subject: [PATCH 01/28] feat(dashboard run page): simplfy project folder creation project forlder name is derived from the execution title on folder create there is always a new folder created in the users workspace so that the user will be able to easily run the selected execution --- odtp/dashboard/page_run/folder.py | 31 +++++++------------------------ poetry.lock | 30 +++++++++++++++++++++++++++++- pyproject.toml | 1 + 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/odtp/dashboard/page_run/folder.py b/odtp/dashboard/page_run/folder.py index d637423f..114eb771 100644 --- a/odtp/dashboard/page_run/folder.py +++ b/odtp/dashboard/page_run/folder.py @@ -1,6 +1,9 @@ import json import logging import os.path +import os +import shutil +from slugify import slugify from nicegui import app, ui import odtp.dashboard.utils.storage as storage @@ -70,12 +73,8 @@ def ui_prepare_folder(dialog, result, workdir, current_run, folder_status): else: cli_output_command = None with ui.row().classes("w-full flex items-center"): - ui.button( - "Choose existing project folder", - on_click=lambda: pick_folder(workdir, current_run), - icon="folder", - ).props("flat") project_folder_input = ui.input( + value=slugify(execution["title"]), label="Project folder name", placeholder="execution", validation={ @@ -89,11 +88,6 @@ def ui_prepare_folder(dialog, result, workdir, current_run, folder_status): on_click=lambda: create_folder(workdir, project_folder_input, current_run), icon="add", ).props("flat ") - ui.button( - f"Reset project folder", - on_click=lambda: remove_project_folder(current_run), - icon="clear", - ).props("flat") with ui.row().classes("w-full"): from odtp.dashboard.page_run.run import run_command if cli_output_command: @@ -131,7 +125,9 @@ def create_folder(workdir, folder_name_input, current_run): try: folder_name = folder_name_input.value project_path = os.path.join(workdir, folder_name) - os.mkdir(project_path) + if os.path.exists(project_path): + shutil.rmtree(project_path) + os.makedirs(project_path) current_run["project_path"] = project_path current_run["stepper"] = rh.STEPPERS[rh.STEPPER_SELECT_FOLDER] app.storage.user[storage.EXECUTION_RUN] = json.dumps(current_run) @@ -151,19 +147,6 @@ def create_folder(workdir, folder_name_input, current_run): ui_stepper.refresh() -def remove_project_folder(current_run) -> None: - try: - current_run["project_path"] = "" - app.storage.user[storage.EXECUTION_RUN] = json.dumps(current_run) - ui.notify("The project path been reset", type="positive") - except Exception as e: - log.exception(f"The project directory could not be reset: an exception occurred: {e}") - else: - from odtp.dashboard.page_run.main import ui_workarea, ui_stepper - ui_stepper.refresh() - ui_workarea.refresh() - - def get_folder_status(execution_id, project_path): folder_empty = odtp_env.project_folder_is_empty(project_folder=project_path) folder_matches_execution = odtp_env.directory_folder_matches_execution( diff --git a/poetry.lock b/poetry.lock index eff32223..723e9101 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2416,6 +2416,23 @@ files = [ [package.extras] dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"] +[[package]] +name = "python-slugify" +version = "8.0.4" +description = "A Python slugify application that also handles Unicode" +optional = false +python-versions = ">=3.7" +files = [ + {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"}, + {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"}, +] + +[package.dependencies] +text-unidecode = ">=1.3" + +[package.extras] +unidecode = ["Unidecode (>=1.1.1)"] + [[package]] name = "python-socketio" version = "5.11.2" @@ -2989,6 +3006,17 @@ files = [ doc = ["reno", "sphinx"] test = ["pytest", "tornado (>=4.5)", "typeguard"] +[[package]] +name = "text-unidecode" +version = "1.3" +description = "The most basic Text::Unidecode port" +optional = false +python-versions = "*" +files = [ + {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, + {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, +] + [[package]] name = "toml" version = "0.10.2" @@ -3569,4 +3597,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "50a3826095f6dfaaf20e0ea2f0dccf9fa2eabe9603de1ded705ad2b025a222ba" +content-hash = "01a8a1407af6833d2985be45427d07be2ba86b3ef344ee3f82214538c3ecde84" diff --git a/pyproject.toml b/pyproject.toml index c5230b18..b46e9e6b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ pygwalker = "^0.3.17" streamlit-aggrid = "^0.3.4.post3" nicegui = "1.4.24" directory-tree = "^0.0.4" +python-slugify = "^8.0.4" [tool.poetry.group.dev.dependencies] pytest = "^7.2.1" From b7c82bfc3028eb89c43e1f45327794b59d420e7e Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Mon, 24 Jun 2024 11:39:13 +0200 Subject: [PATCH 02/28] fix(cloning of component repo): consider odtp-component-client clone the component repo in such a way that the submodule is taken from the component repo commit: this needs to first check out the component commit and the fetch the submodule --- odtp/run.py | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/odtp/run.py b/odtp/run.py index 5a330294..90aa0b90 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -90,24 +90,34 @@ def _download_repo(self): Args: destination (str): The destination directory to download the repository. """ - log.info(f"PREPARE: Downloading repository from {self.repo_url} to {self.repository_path}") - subprocess.run( - ["git", + log.debug(f"PREPARE: Downloading repository from {self.repo_url} to {self.repository_path}") + git_clone_command = [ + "git", "clone", - "--recurse-submodules", self.repo_url, - os.path.join(self.project_folder, "repository") - ] - ) - subprocess.run( - ["git", + self.repository_path, + ] + log.info(" ".join(git_clone_command)) + subprocess.run(git_clone_command) + git_checkout_command = [ + "git", "-C", - os.path.join(self.project_folder, - "repository"), + self.repository_path, "checkout", - self.commit_hash - ] - ) + self.commit_hash, + ] + log.info(" ".join(git_checkout_command)) + subprocess.run(git_checkout_command) + git_submodule_command = [ + "git", + "-C", + self.repository_path, + "submodule", + "update", + "--init", + ] + log.info(" ".join(git_submodule_command)) + subprocess.run(git_submodule_command) def _build_image(self): """ From b9e517493409216e45e64372769382d9682ba5a3 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Mon, 24 Jun 2024 15:47:14 +0200 Subject: [PATCH 03/28] fix(compose.prod.yml): removing app volume (#151) * fix(compose.prod.yml): removing app volume * typo(JSON_EDITOR): Correcting typo in variables * chore(compose.yml): Proposing compose.yml to avoid change in documentation with -f. --- compose.dev.yml | 2 +- compose.prod.yml => compose.yml | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) rename compose.prod.yml => compose.yml (96%) diff --git a/compose.dev.yml b/compose.dev.yml index 4ea254bd..e3f49927 100644 --- a/compose.dev.yml +++ b/compose.dev.yml @@ -26,7 +26,7 @@ services: ODTP_MONGO_DB: ${ODTP_MONGO_DB} ODTP_DASHBOARD_PORT: ${ODTP_DASHBOARD_PORT} ODTP_DASHBOARD_RELOAD: ${ODTP_DASHBOARD_RELOAD} - ODTP_DASHBOARD_JSON_EDITIOR: ${ODTP_DASHBOARD_JSON_EDITIOR} + ODTP_DASHBOARD_JSON_EDITOR: ${ODTP_DASHBOARD_JSON_EDITOR} ODTP_LOG_LEVEL: ${ODTP_LOG_LEVEL} RUN_LOG_LEVEL: ${ODTP_LOG_LEVEL} diff --git a/compose.prod.yml b/compose.yml similarity index 96% rename from compose.prod.yml rename to compose.yml index 2167f48e..252053f5 100644 --- a/compose.prod.yml +++ b/compose.yml @@ -11,7 +11,6 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock - ${ODTP_PATH}:${ODTP_PATH} - - ${APP_PATH}:/app environment: ODTP_PATH: ${ODTP_PATH} ODTP_MONGO_SERVER: mongodb://${MONGO_DB_USER}:${MONGO_DB_PASSWORD}@mongodb-instance:27017/ @@ -22,7 +21,7 @@ services: GITHUB_TOKEN: ${GITHUB_TOKEN} ODTP_MONGO_DB: ${ODTP_MONGO_DB} ODTP_DASHBOARD_PORT: ${ODTP_DASHBOARD_PORT} - ODTP_DASHBOARD_JSON_EDITIOR: ${ODTP_DASHBOARD_JSON_EDITIOR} + ODTP_DASHBOARD_JSON_EDITOR: ${ODTP_DASHBOARD_JSON_EDITOR} ODTP_LOG_LEVEL: ${ODTP_LOG_LEVEL} RUN_LOG_LEVEL: ${ODTP_LOG_LEVEL} From ddb0cd723a54550dd44fc042218286ebe786e430 Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Tue, 25 Jun 2024 06:00:04 +0200 Subject: [PATCH 04/28] fix(compose): fix env variable in compose files the variable had the wrong value --- compose.dev.yml | 2 +- compose.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/compose.dev.yml b/compose.dev.yml index e3f49927..e49112ed 100644 --- a/compose.dev.yml +++ b/compose.dev.yml @@ -28,7 +28,7 @@ services: ODTP_DASHBOARD_RELOAD: ${ODTP_DASHBOARD_RELOAD} ODTP_DASHBOARD_JSON_EDITOR: ${ODTP_DASHBOARD_JSON_EDITOR} ODTP_LOG_LEVEL: ${ODTP_LOG_LEVEL} - RUN_LOG_LEVEL: ${ODTP_LOG_LEVEL} + RUN_LOG_LEVEL: ${RUN_LOG_LEVEL} stdin_open: true tty: true diff --git a/compose.yml b/compose.yml index 252053f5..1d1e520a 100644 --- a/compose.yml +++ b/compose.yml @@ -23,7 +23,7 @@ services: ODTP_DASHBOARD_PORT: ${ODTP_DASHBOARD_PORT} ODTP_DASHBOARD_JSON_EDITOR: ${ODTP_DASHBOARD_JSON_EDITOR} ODTP_LOG_LEVEL: ${ODTP_LOG_LEVEL} - RUN_LOG_LEVEL: ${ODTP_LOG_LEVEL} + RUN_LOG_LEVEL: ${RUN_LOG_LEVEL} stdin_open: true tty: true From e02feb0b8595927791d6729212e1b4ed0db587d0 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Wed, 26 Jun 2024 15:43:37 +0200 Subject: [PATCH 05/28] =?UTF-8?q?feat(logs=20&=20output=20collections):=20?= =?UTF-8?q?Added=20missing=20collections=20in=20initial=E2=80=A6=20(#157)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit feat(logs & output collections): Added missing collections in initial configuration --- odtp/mongodb/db.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/odtp/mongodb/db.py b/odtp/mongodb/db.py index b21bc090..aec188b4 100644 --- a/odtp/mongodb/db.py +++ b/odtp/mongodb/db.py @@ -20,6 +20,8 @@ collection_executions = "executions" collection_steps = "steps" collection_results = "results" +collection_logs = "logs" +collection_outputs = "outputs" log = logging.getLogger(__name__) @@ -422,8 +424,11 @@ def init_collections(): collection_users, collection_components, collection_digital_twins, + collection_executions, + collection_outputs, collection_results, collection_versions, + collection_logs, ]: if name not in collection_names: db.create_collection(name) From 14bacff0d666899edf36480aff8f584cbb3d3a3f Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Wed, 26 Jun 2024 20:55:23 +0200 Subject: [PATCH 06/28] fix(S3 Initiation): Fix for S3 initial setup (#156) * fix(S3 Initiation): Fix for S3 initial setup * fix(exception): Exception applied on CLI and logging. * chore(cli/s3.py): adapt method to return value change * Erasing assignation. --------- Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- odtp/cli/s3.py | 2 +- odtp/cli/setup.py | 12 ++++++++++-- odtp/storage.py | 3 +-- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/odtp/cli/s3.py b/odtp/cli/s3.py index 00bfa1f2..8f5bbe79 100644 --- a/odtp/cli/s3.py +++ b/odtp/cli/s3.py @@ -31,7 +31,7 @@ def download( def check(): try: s3 = s3Manager() - bucket = s3.test_connection() + s3.test_connection() print("S3 is connected. Bucket is ready to use") except Exception as e: log.exception(f"S3 connection could not be established: an Exception {e} occurred") diff --git a/odtp/cli/setup.py b/odtp/cli/setup.py index a41cda4e..1b15f023 100644 --- a/odtp/cli/setup.py +++ b/odtp/cli/setup.py @@ -2,19 +2,27 @@ This scripts contains odtp subcommands for 'setup' """ import typer - +import logging from odtp.storage import s3Manager import odtp.mongodb.db as db app = typer.Typer() +log = logging.getLogger(__name__) @app.command() def initiate(): db.init_collections() odtpS3 = s3Manager() - odtpS3.create_folders(["odtp"]) + try: + bucketAvailable = odtpS3.test_connection() + except Exception as e: + logging.error("S3 bucket not found. Please create the bucket on minio folder or use the dashboard.") + log.exception(e) + + + odtpS3.createFolderStructure(["odtp"]) odtpS3.close() print("ODTP DB/S3 data generated") diff --git a/odtp/storage.py b/odtp/storage.py index 2a17b4e0..73dc5307 100644 --- a/odtp/storage.py +++ b/odtp/storage.py @@ -16,8 +16,7 @@ def __init__(self): self.bucketName = settings.ODTP_BUCKET_NAME def test_connection(self): - bucket = self.s3.head_bucket(Bucket=self.bucketName) - return bucket + self.s3.head_bucket(Bucket=self.bucketName) # Method to close the client connection def closeConnection(self): From b33ed0577fb618e6b715322b79a1f863d7543233 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Tue, 25 Jun 2024 14:20:59 +0200 Subject: [PATCH 07/28] =?UTF-8?q?fix(dependencies):=20Removing=20pyarrow?= =?UTF-8?q?=20and=20freezing=20numpy=20to=20<2=20to=20avoid=E2=80=A6=20(#1?= =?UTF-8?q?55)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix(dependencies): Removing pyarrow and freezing numpy to <2 to avoid errors and warnings --- Dockerfile | 23 +++++------------------ pyproject.toml | 13 +++++-------- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4592281c..0e4ae60f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -44,29 +44,16 @@ RUN wget https://www.python.org/ftp/python/3.11.0/Python-3.11.0.tar.xz \ # Remove the Python source and tarball to reduce image size RUN rm -rf Python-3.11.0.tar.xz Python-3.11.0 -# Install Python and Poetry -RUN python3 -m ensurepip && \ - pip3 install --upgrade pip setuptools - -# Install PyArrow in ALPINE -## https://stackoverflow.com/questions/49059779/how-to-install-pyarrow-on-an-alpine-docker-image/53116069#53116069 -## https://discuss.streamlit.io/t/anyone-tried-to-install-streamlit-in-alpine-docker-image/56893 -RUN apk update && apk add \ - apache-arrow-dev \ - py3-pyarrow \ - && rm -rf /var/lib/apt/lists/* - -RUN pip3 install --upgrade pip && \ - pip3 install --break-system-packages numpy pyarrow==12.0.0 - -# Add your application's source code +# Adding odtp source code and installing it. COPY . /app WORKDIR /app RUN pip3 install --break-system-packages $PIP_INSTALL_ARGS . +# Symbolic link to ODTP_PATH to facilitate debugging +RUN ln -s $ODTP_PATH /ODTP_PATH + # Symbolic link between python and python3 -RUN rm /usr/bin/python RUN ln -s /usr/local/bin/python3 /usr/bin/python # Entry point in a sh session -ENTRYPOINT ["sh"] +ENTRYPOINT ["sh"] \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index b46e9e6b..c884709c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "odtp" -version = "0.3.0" +version = "0.3.1" description = "A tool to deploy and manage open digital twins" authors = ["caviri ", "sabinem "] license = "AGPL 3.0" @@ -8,21 +8,18 @@ readme = "README.md" [tool.poetry.dependencies] python = "^3.11" +requests = "2.32.3" pydantic = "2.5.2" +numpy = "1.26.4" typer = "0.9.0" pymongo = ">=4.6.3" python-dotenv = "^1.0.0" boto3 = "^1.33.13" -barfi = "^0.7.0" -streamlit = "^1.29.0" -st-pages = "^0.4.5" -streamlit-card = "^1.0.0" -pygwalker = "^0.3.17" -streamlit-aggrid = "^0.3.4.post3" nicegui = "1.4.24" directory-tree = "^0.0.4" python-slugify = "^8.0.4" + [tool.poetry.group.dev.dependencies] pytest = "^7.2.1" black = ">=24.3.0" @@ -33,4 +30,4 @@ requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" [tool.poetry.scripts] -odtp = "odtp.cli.main:app" +odtp = "odtp.cli.main:app" \ No newline at end of file From 65acbf0a584d02f4de9f035d39c5bd46ea7d9aad Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios Date: Mon, 24 Jun 2024 15:23:47 +0200 Subject: [PATCH 08/28] fix(Missing method): Missing get_component_version --- odtp/mongodb/db.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/odtp/mongodb/db.py b/odtp/mongodb/db.py index aec188b4..73df95b4 100644 --- a/odtp/mongodb/db.py +++ b/odtp/mongodb/db.py @@ -154,6 +154,16 @@ def get_document_id_by_field_value(field_path, field_value, collection): return str(document["_id"]) else: return None + +def get_component_version(component_name, version_tag): + with MongoClient(ODTP_MONGO_SERVER) as client: + db = client[ODTP_MONGO_DB] + cursor = db[collection_versions].find({ + "component.componentName": component_name, + "component_version": version_tag + }) + version_documents = mongodb_utils.get_list_from_cursor(cursor) + return version_documents def add_user(name, github, email): From 26d8f43acf2690be138ce9697900da4c08cfebab Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Thu, 27 Jun 2024 13:49:40 +0200 Subject: [PATCH 09/28] fix(pyproject.toml): add pandas as a dependency --- poetry.lock | 1900 ++++++------------------------------------------ pyproject.toml | 1 + 2 files changed, 229 insertions(+), 1672 deletions(-) diff --git a/poetry.lock b/poetry.lock index 723e9101..7f90c7ef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,13 +2,13 @@ [[package]] name = "aiofiles" -version = "23.2.1" +version = "24.1.0" description = "File support for asyncio." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "aiofiles-23.2.1-py3-none-any.whl", hash = "sha256:19297512c647d4b27a2cf7c34caa7e405c0d60b5560618a29a9fe027b18b0107"}, - {file = "aiofiles-23.2.1.tar.gz", hash = "sha256:84ec2218d8419404abcb9f0c02df3f34c6e0a68ed41072acfb1cef5cbc29051a"}, + {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, + {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, ] [[package]] @@ -120,50 +120,26 @@ files = [ [package.dependencies] frozenlist = ">=1.1.0" -[[package]] -name = "altair" -version = "5.3.0" -description = "Vega-Altair: A declarative statistical visualization library for Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "altair-5.3.0-py3-none-any.whl", hash = "sha256:7084a1dab4d83c5e7e5246b92dc1b4451a6c68fd057f3716ee9d315c8980e59a"}, - {file = "altair-5.3.0.tar.gz", hash = "sha256:5a268b1a0983b23d8f9129f819f956174aa7aea2719ed55a52eba9979b9f6675"}, -] - -[package.dependencies] -jinja2 = "*" -jsonschema = ">=3.0" -numpy = "*" -packaging = "*" -pandas = ">=0.25" -toolz = "*" - -[package.extras] -all = ["altair-tiles (>=0.3.0)", "anywidget (>=0.9.0)", "pyarrow (>=11)", "vega-datasets (>=0.9.0)", "vegafusion[embed] (>=1.6.6)", "vl-convert-python (>=1.3.0)"] -dev = ["geopandas", "hatch", "ipython", "m2r", "mypy", "pandas-stubs", "pytest", "pytest-cov", "ruff (>=0.3.0)", "types-jsonschema", "types-setuptools"] -doc = ["docutils", "jinja2", "myst-parser", "numpydoc", "pillow (>=9,<10)", "pydata-sphinx-theme (>=0.14.1)", "scipy", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinxext-altair"] - [[package]] name = "annotated-types" -version = "0.6.0" +version = "0.7.0" description = "Reusable constraint types to use with typing.Annotated" optional = false python-versions = ">=3.8" files = [ - {file = "annotated_types-0.6.0-py3-none-any.whl", hash = "sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43"}, - {file = "annotated_types-0.6.0.tar.gz", hash = "sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d"}, + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] [[package]] name = "anyio" -version = "4.3.0" +version = "4.4.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, - {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, + {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, + {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, ] [package.dependencies] @@ -175,65 +151,6 @@ doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphin test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] trio = ["trio (>=0.23)"] -[[package]] -name = "appdirs" -version = "1.4.4" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -optional = false -python-versions = "*" -files = [ - {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, -] - -[[package]] -name = "arrow" -version = "1.3.0" -description = "Better dates & times for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, - {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, -] - -[package.dependencies] -python-dateutil = ">=2.7.0" -types-python-dateutil = ">=2.8.10" - -[package.extras] -doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] -test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] - -[[package]] -name = "astor" -version = "0.8.1" -description = "Read/rewrite/write Python ASTs" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" -files = [ - {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, - {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, -] - -[[package]] -name = "asttokens" -version = "2.4.1" -description = "Annotate AST trees with source code positions" -optional = false -python-versions = "*" -files = [ - {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, - {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, -] - -[package.dependencies] -six = ">=1.12.0" - -[package.extras] -astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] -test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] - [[package]] name = "attrs" version = "23.2.0" @@ -253,32 +170,6 @@ tests = ["attrs[tests-no-zope]", "zope-interface"] tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] -[[package]] -name = "backoff" -version = "2.2.1" -description = "Function decoration for backoff and retry" -optional = false -python-versions = ">=3.7,<4.0" -files = [ - {file = "backoff-2.2.1-py3-none-any.whl", hash = "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8"}, - {file = "backoff-2.2.1.tar.gz", hash = "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba"}, -] - -[[package]] -name = "barfi" -version = "0.7.0" -description = "Framework for a graphical programming environment." -optional = false -python-versions = ">=3.6" -files = [ - {file = "barfi-0.7.0-py3-none-any.whl", hash = "sha256:5f6bea5d1be09d39579fe0c6df5c52c6bd7dd94a2a53a0cb12e92306d82f198e"}, - {file = "barfi-0.7.0.tar.gz", hash = "sha256:2b920d93f27aa499c9698281af3dd51b8616d2611883e3644511b9e6acb4355f"}, -] - -[package.dependencies] -networkx = ">=2.6.2" -streamlit = ">=0.63" - [[package]] name = "bidict" version = "0.23.1" @@ -334,30 +225,19 @@ d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] -[[package]] -name = "blinker" -version = "1.8.2" -description = "Fast, simple object-to-object and broadcast signaling" -optional = false -python-versions = ">=3.8" -files = [ - {file = "blinker-1.8.2-py3-none-any.whl", hash = "sha256:1779309f71bf239144b9399d06ae925637cf6634cf6bd131104184531bf67c01"}, - {file = "blinker-1.8.2.tar.gz", hash = "sha256:8f77b09d3bf7c795e969e9486f39c2c5e9c39d4ee07424be2bc594ece9642d83"}, -] - [[package]] name = "boto3" -version = "1.34.103" +version = "1.34.134" description = "The AWS SDK for Python" optional = false python-versions = ">=3.8" files = [ - {file = "boto3-1.34.103-py3-none-any.whl", hash = "sha256:59b6499f1bb423dd99de6566a20d0a7cf1a5476824be3a792290fd86600e8365"}, - {file = "boto3-1.34.103.tar.gz", hash = "sha256:58d097241f3895c4a4c80c9e606689c6e06d77f55f9f53a4cc02dee7e03938b9"}, + {file = "boto3-1.34.134-py3-none-any.whl", hash = "sha256:342782c02ff077aae118c9c61179eed95c585831fba666baacc5588ff04aa6e1"}, + {file = "boto3-1.34.134.tar.gz", hash = "sha256:f6d6e5b0c9ab022a75373fa16c01f0cd54bc1bb64ef3b6ac64ac7cedd56cbe9c"}, ] [package.dependencies] -botocore = ">=1.34.103,<1.35.0" +botocore = ">=1.34.134,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -366,13 +246,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.103" +version = "1.34.134" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">=3.8" files = [ - {file = "botocore-1.34.103-py3-none-any.whl", hash = "sha256:0330d139f18f78d38127e65361859e24ebd6a8bcba184f903c01bb999a3fa431"}, - {file = "botocore-1.34.103.tar.gz", hash = "sha256:5f07e2c7302c0a9f469dcd08b4ddac152e9f5888b12220242c20056255010939"}, + {file = "botocore-1.34.134-py3-none-any.whl", hash = "sha256:45219e00639755f92569b29f8f279d5dde721494791412c1f7026a3779e8d9f4"}, + {file = "botocore-1.34.134.tar.gz", hash = "sha256:e29c299599426ed16dd2d4c1e20eef784f96b15e1850ebbc59a3250959285b95"}, ] [package.dependencies] @@ -381,28 +261,17 @@ python-dateutil = ">=2.1,<3.0.0" urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} [package.extras] -crt = ["awscrt (==0.20.9)"] - -[[package]] -name = "cachetools" -version = "5.3.3" -description = "Extensible memoizing collections and decorators" -optional = false -python-versions = ">=3.7" -files = [ - {file = "cachetools-5.3.3-py3-none-any.whl", hash = "sha256:0abad1021d3f8325b2fc1d2e9c8b9c9d57b04c3932657a72465447332c24d945"}, - {file = "cachetools-5.3.3.tar.gz", hash = "sha256:ba29e2dfa0b8b556606f097407ed1aa62080ee108ab0dc5ec9d6a723a007d105"}, -] +crt = ["awscrt (==0.20.11)"] [[package]] name = "certifi" -version = "2024.2.2" +version = "2024.6.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, - {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, + {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, + {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, ] [[package]] @@ -529,49 +398,6 @@ files = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "comm" -version = "0.2.2" -description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." -optional = false -python-versions = ">=3.8" -files = [ - {file = "comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3"}, - {file = "comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e"}, -] - -[package.dependencies] -traitlets = ">=4" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "dateutils" -version = "0.6.12" -description = "Various utilities for working with date and datetime objects" -optional = false -python-versions = "*" -files = [ - {file = "dateutils-0.6.12-py2.py3-none-any.whl", hash = "sha256:f33b6ab430fa4166e7e9cb8b21ee9f6c9843c48df1a964466f52c79b2a8d53b3"}, - {file = "dateutils-0.6.12.tar.gz", hash = "sha256:03dd90bcb21541bd4eb4b013637e4f1b5f944881c46cc6e4b67a6059e370e3f1"}, -] - -[package.dependencies] -python-dateutil = "*" -pytz = "*" - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -optional = false -python-versions = ">=3.5" -files = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] - [[package]] name = "directory-tree" version = "0.0.4" @@ -616,68 +442,6 @@ files = [ {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, ] -[[package]] -name = "duckdb" -version = "0.9.2" -description = "DuckDB embedded database" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:aadcea5160c586704c03a8a796c06a8afffbefefb1986601104a60cb0bfdb5ab"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:08215f17147ed83cbec972175d9882387366de2ed36c21cbe4add04b39a5bcb4"}, - {file = "duckdb-0.9.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ee6c2a8aba6850abef5e1be9dbc04b8e72a5b2c2b67f77892317a21fae868fe7"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ff49f3da9399900fd58b5acd0bb8bfad22c5147584ad2427a78d937e11ec9d0"}, - {file = "duckdb-0.9.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd5ac5baf8597efd2bfa75f984654afcabcd698342d59b0e265a0bc6f267b3f0"}, - {file = "duckdb-0.9.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:81c6df905589a1023a27e9712edb5b724566587ef280a0c66a7ec07c8083623b"}, - {file = "duckdb-0.9.2-cp310-cp310-win32.whl", hash = "sha256:a298cd1d821c81d0dec8a60878c4b38c1adea04a9675fb6306c8f9083bbf314d"}, - {file = "duckdb-0.9.2-cp310-cp310-win_amd64.whl", hash = "sha256:492a69cd60b6cb4f671b51893884cdc5efc4c3b2eb76057a007d2a2295427173"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:061a9ea809811d6e3025c5de31bc40e0302cfb08c08feefa574a6491e882e7e8"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a43f93be768af39f604b7b9b48891f9177c9282a408051209101ff80f7450d8f"}, - {file = "duckdb-0.9.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ac29c8c8f56fff5a681f7bf61711ccb9325c5329e64f23cb7ff31781d7b50773"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b14d98d26bab139114f62ade81350a5342f60a168d94b27ed2c706838f949eda"}, - {file = "duckdb-0.9.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:796a995299878913e765b28cc2b14c8e44fae2f54ab41a9ee668c18449f5f833"}, - {file = "duckdb-0.9.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6cb64ccfb72c11ec9c41b3cb6181b6fd33deccceda530e94e1c362af5f810ba1"}, - {file = "duckdb-0.9.2-cp311-cp311-win32.whl", hash = "sha256:930740cb7b2cd9e79946e1d3a8f66e15dc5849d4eaeff75c8788d0983b9256a5"}, - {file = "duckdb-0.9.2-cp311-cp311-win_amd64.whl", hash = "sha256:c28f13c45006fd525001b2011cdf91fa216530e9751779651e66edc0e446be50"}, - {file = "duckdb-0.9.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:fbce7bbcb4ba7d99fcec84cec08db40bc0dd9342c6c11930ce708817741faeeb"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:15a82109a9e69b1891f0999749f9e3265f550032470f51432f944a37cfdc908b"}, - {file = "duckdb-0.9.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9490fb9a35eb74af40db5569d90df8a04a6f09ed9a8c9caa024998c40e2506aa"}, - {file = "duckdb-0.9.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:696d5c6dee86c1a491ea15b74aafe34ad2b62dcd46ad7e03b1d00111ca1a8c68"}, - {file = "duckdb-0.9.2-cp37-cp37m-win32.whl", hash = "sha256:4f0935300bdf8b7631ddfc838f36a858c1323696d8c8a2cecbd416bddf6b0631"}, - {file = "duckdb-0.9.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0aab900f7510e4d2613263865570203ddfa2631858c7eb8cbed091af6ceb597f"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:7d8130ed6a0c9421b135d0743705ea95b9a745852977717504e45722c112bf7a"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:974e5de0294f88a1a837378f1f83330395801e9246f4e88ed3bfc8ada65dcbee"}, - {file = "duckdb-0.9.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4fbc297b602ef17e579bb3190c94d19c5002422b55814421a0fc11299c0c1100"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1dd58a0d84a424924a35b3772419f8cd78a01c626be3147e4934d7a035a8ad68"}, - {file = "duckdb-0.9.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11a1194a582c80dfb57565daa06141727e415ff5d17e022dc5f31888a5423d33"}, - {file = "duckdb-0.9.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:be45d08541002a9338e568dca67ab4f20c0277f8f58a73dfc1435c5b4297c996"}, - {file = "duckdb-0.9.2-cp38-cp38-win32.whl", hash = "sha256:dd6f88aeb7fc0bfecaca633629ff5c986ac966fe3b7dcec0b2c48632fd550ba2"}, - {file = "duckdb-0.9.2-cp38-cp38-win_amd64.whl", hash = "sha256:28100c4a6a04e69aa0f4a6670a6d3d67a65f0337246a0c1a429f3f28f3c40b9a"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7ae5bf0b6ad4278e46e933e51473b86b4b932dbc54ff097610e5b482dd125552"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e5d0bb845a80aa48ed1fd1d2d285dd352e96dc97f8efced2a7429437ccd1fe1f"}, - {file = "duckdb-0.9.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ce262d74a52500d10888110dfd6715989926ec936918c232dcbaddb78fc55b4"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6935240da090a7f7d2666f6d0a5e45ff85715244171ca4e6576060a7f4a1200e"}, - {file = "duckdb-0.9.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5cfb93e73911696a98b9479299d19cfbc21dd05bb7ab11a923a903f86b4d06e"}, - {file = "duckdb-0.9.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:64e3bc01751f31e7572d2716c3e8da8fe785f1cdc5be329100818d223002213f"}, - {file = "duckdb-0.9.2-cp39-cp39-win32.whl", hash = "sha256:6e5b80f46487636368e31b61461940e3999986359a78660a50dfdd17dd72017c"}, - {file = "duckdb-0.9.2-cp39-cp39-win_amd64.whl", hash = "sha256:e6142a220180dbeea4f341708bd5f9501c5c962ce7ef47c1cadf5e8810b4cb13"}, - {file = "duckdb-0.9.2.tar.gz", hash = "sha256:3843afeab7c3fc4a4c0b53686a4cc1d9cdbdadcbb468d60fef910355ecafd447"}, -] - -[[package]] -name = "executing" -version = "2.0.1" -description = "Get the currently executing AST node of a frame, and other information" -optional = false -python-versions = ">=3.5" -files = [ - {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, - {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, -] - -[package.extras] -tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] - [[package]] name = "fastapi" version = "0.109.2" @@ -783,126 +547,6 @@ files = [ {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, ] -[[package]] -name = "gitdb" -version = "4.0.11" -description = "Git Object Database" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4"}, - {file = "gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b"}, -] - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.43" -description = "GitPython is a Python library used to interact with Git repositories" -optional = false -python-versions = ">=3.7" -files = [ - {file = "GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff"}, - {file = "GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c"}, -] - -[package.dependencies] -gitdb = ">=4.0.1,<5" - -[package.extras] -doc = ["sphinx (==4.3.2)", "sphinx-autodoc-typehints", "sphinx-rtd-theme", "sphinxcontrib-applehelp (>=1.0.2,<=1.0.4)", "sphinxcontrib-devhelp (==1.0.2)", "sphinxcontrib-htmlhelp (>=2.0.0,<=2.0.1)", "sphinxcontrib-qthelp (==1.0.3)", "sphinxcontrib-serializinghtml (==1.1.5)"] -test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions"] - -[[package]] -name = "greenlet" -version = "3.0.3" -description = "Lightweight in-process concurrent programming" -optional = false -python-versions = ">=3.7" -files = [ - {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, - {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, - {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, - {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, - {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, - {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, - {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, - {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, - {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, - {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, - {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, - {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, - {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, - {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, - {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, - {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, - {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, - {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, - {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, - {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, - {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, - {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, - {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, - {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, - {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, - {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, - {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, - {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, -] - -[package.extras] -docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] - -[[package]] -name = "gw-dsl-parser" -version = "0.1.38" -description = "gw_dsl_parser: Convert your graphic-walker workflow to sql" -optional = false -python-versions = ">=3.6" -files = [ - {file = "gw_dsl_parser-0.1.38-py3-none-any.whl", hash = "sha256:b7dccb5e99a3b60e275c73d645f43a3499373dcf60059dcfcc2bc73c46b44a1c"}, - {file = "gw_dsl_parser-0.1.38.tar.gz", hash = "sha256:ec8bca2bbfe683c57a9049a131afdbf045964dc78f49726cd125e184091cc025"}, -] - -[package.dependencies] -wasmtime = "12.0.0" - -[package.extras] -dev = ["build", "pytest", "twine"] - [[package]] name = "h11" version = "0.14.0" @@ -1040,64 +684,6 @@ files = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] -[[package]] -name = "ipython" -version = "8.24.0" -description = "IPython: Productive Interactive Computing" -optional = false -python-versions = ">=3.10" -files = [ - {file = "ipython-8.24.0-py3-none-any.whl", hash = "sha256:d7bf2f6c4314984e3e02393213bab8703cf163ede39672ce5918c51fe253a2a3"}, - {file = "ipython-8.24.0.tar.gz", hash = "sha256:010db3f8a728a578bb641fdd06c063b9fb8e96a9464c63aec6310fbcb5e80501"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\" and sys_platform != \"emscripten\""} -prompt-toolkit = ">=3.0.41,<3.1.0" -pygments = ">=2.4.0" -stack-data = "*" -traitlets = ">=5.13.0" -typing-extensions = {version = ">=4.6", markers = "python_version < \"3.12\""} - -[package.extras] -all = ["ipython[black,doc,kernel,matplotlib,nbconvert,nbformat,notebook,parallel,qtconsole]", "ipython[test,test-extra]"] -black = ["black"] -doc = ["docrepr", "exceptiongroup", "ipykernel", "ipython[test]", "matplotlib", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "sphinxcontrib-jquery", "stack-data", "typing-extensions"] -kernel = ["ipykernel"] -matplotlib = ["matplotlib"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["ipywidgets", "notebook"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"] -test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"] - -[[package]] -name = "ipywidgets" -version = "8.1.2" -description = "Jupyter interactive widgets" -optional = false -python-versions = ">=3.7" -files = [ - {file = "ipywidgets-8.1.2-py3-none-any.whl", hash = "sha256:bbe43850d79fb5e906b14801d6c01402857996864d1e5b6fa62dd2ee35559f60"}, - {file = "ipywidgets-8.1.2.tar.gz", hash = "sha256:d0b9b41e49bae926a866e613a39b0f0097745d2b9f1f3dd406641b4a57ec42c9"}, -] - -[package.dependencies] -comm = ">=0.1.3" -ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0.10,<3.1.0" -traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0.10,<4.1.0" - -[package.extras] -test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] - [[package]] name = "isort" version = "5.13.2" @@ -1123,25 +709,6 @@ files = [ {file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"}, ] -[[package]] -name = "jedi" -version = "0.19.1" -description = "An autocompletion tool for Python that can be used for text editors." -optional = false -python-versions = ">=3.6" -files = [ - {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, - {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, -] - -[package.dependencies] -parso = ">=0.8.3,<0.9.0" - -[package.extras] -docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] - [[package]] name = "jinja2" version = "3.1.4" @@ -1170,95 +737,6 @@ files = [ {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, ] -[[package]] -name = "jsonschema" -version = "4.22.0" -description = "An implementation of JSON Schema validation for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema-4.22.0-py3-none-any.whl", hash = "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802"}, - {file = "jsonschema-4.22.0.tar.gz", hash = "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -jsonschema-specifications = ">=2023.03.6" -referencing = ">=0.28.4" -rpds-py = ">=0.7.1" - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jsonschema-specifications" -version = "2023.12.1" -description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -optional = false -python-versions = ">=3.8" -files = [ - {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, - {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, -] - -[package.dependencies] -referencing = ">=0.31.0" - -[[package]] -name = "jupyterlab-widgets" -version = "3.0.10" -description = "Jupyter interactive widgets for JupyterLab" -optional = false -python-versions = ">=3.7" -files = [ - {file = "jupyterlab_widgets-3.0.10-py3-none-any.whl", hash = "sha256:dd61f3ae7a5a7f80299e14585ce6cf3d6925a96c9103c978eda293197730cb64"}, - {file = "jupyterlab_widgets-3.0.10.tar.gz", hash = "sha256:04f2ac04976727e4f9d0fa91cdc2f1ab860f965e504c29dbd6a65c882c9d04c0"}, -] - -[[package]] -name = "kanaries-track" -version = "0.0.3" -description = "kanaries_track: track to kanaries data infra" -optional = false -python-versions = ">=3.6" -files = [ - {file = "kanaries_track-0.0.3-py3-none-any.whl", hash = "sha256:c1170c1046366a4f153e01c8469f9ef76f5ab9c347d0b558dede62ec3c9a0cbf"}, - {file = "kanaries_track-0.0.3.tar.gz", hash = "sha256:624bfba37c6018224019bcf7e32481f2d609595e03a20d72b9f3f9bc47b8d495"}, -] - -[package.dependencies] -backoff = "2.2.1" -dateutils = "0.6.12" -requests = "2.31.0" - -[package.extras] -dev = ["build", "pytest", "twine"] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -files = [ - {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, - {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, -] - -[package.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - [[package]] name = "markdown2" version = "2.4.13" @@ -1344,42 +822,6 @@ files = [ {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] -[[package]] -name = "matplotlib-inline" -version = "0.1.7" -description = "Inline Matplotlib backend for Jupyter" -optional = false -python-versions = ">=3.8" -files = [ - {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"}, - {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"}, -] - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, - {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, -] - -[[package]] -name = "monotonic" -version = "1.6" -description = "An implementation of time.monotonic() for Python 2 & < 3.3" -optional = false -python-versions = "*" -files = [ - {file = "monotonic-1.6-py2.py3-none-any.whl", hash = "sha256:68687e19a14f11f26d140dd5c86f3dba4bf5df58003000ed467e0e2a69bca96c"}, - {file = "monotonic-1.6.tar.gz", hash = "sha256:3a55207bcfed53ddd5c5bae174524062935efed17792e9de2ad0205ce9ad63f7"}, -] - [[package]] name = "multidict" version = "6.0.5" @@ -1490,24 +932,6 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -[[package]] -name = "networkx" -version = "3.3" -description = "Python package for creating and manipulating graphs and networks" -optional = false -python-versions = ">=3.10" -files = [ - {file = "networkx-3.3-py3-none-any.whl", hash = "sha256:28575580c6ebdaf4505b22c6256a2b9de86b316dc63ba9e93abde3d78dfdbcf2"}, - {file = "networkx-3.3.tar.gz", hash = "sha256:0c127d8b2f4865f59ae9cb8aafcd60b5c70f3241ebd66f7defad7c4ab90126c9"}, -] - -[package.extras] -default = ["matplotlib (>=3.6)", "numpy (>=1.23)", "pandas (>=1.4)", "scipy (>=1.9,!=1.11.0,!=1.11.1)"] -developer = ["changelist (==0.5)", "mypy (>=1.1)", "pre-commit (>=3.2)", "rtoml"] -doc = ["myst-nb (>=1.0)", "numpydoc (>=1.7)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.14)", "sphinx (>=7)", "sphinx-gallery (>=0.14)", "texext (>=0.6.7)"] -extra = ["lxml (>=4.6)", "pydot (>=2.0)", "pygraphviz (>=1.12)", "sympy (>=1.10)"] -test = ["pytest (>=7.2)", "pytest-cov (>=4.0)"] - [[package]] name = "nicegui" version = "1.4.24" @@ -1592,68 +1016,68 @@ files = [ [[package]] name = "orjson" -version = "3.10.3" +version = "3.10.5" description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" optional = false python-versions = ">=3.8" files = [ - {file = "orjson-3.10.3-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9fb6c3f9f5490a3eb4ddd46fc1b6eadb0d6fc16fb3f07320149c3286a1409dd8"}, - {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:252124b198662eee80428f1af8c63f7ff077c88723fe206a25df8dc57a57b1fa"}, - {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9f3e87733823089a338ef9bbf363ef4de45e5c599a9bf50a7a9b82e86d0228da"}, - {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8334c0d87103bb9fbbe59b78129f1f40d1d1e8355bbed2ca71853af15fa4ed3"}, - {file = "orjson-3.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1952c03439e4dce23482ac846e7961f9d4ec62086eb98ae76d97bd41d72644d7"}, - {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c0403ed9c706dcd2809f1600ed18f4aae50be263bd7112e54b50e2c2bc3ebd6d"}, - {file = "orjson-3.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:382e52aa4270a037d41f325e7d1dfa395b7de0c367800b6f337d8157367bf3a7"}, - {file = "orjson-3.10.3-cp310-none-win32.whl", hash = "sha256:be2aab54313752c04f2cbaab4515291ef5af8c2256ce22abc007f89f42f49109"}, - {file = "orjson-3.10.3-cp310-none-win_amd64.whl", hash = "sha256:416b195f78ae461601893f482287cee1e3059ec49b4f99479aedf22a20b1098b"}, - {file = "orjson-3.10.3-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:73100d9abbbe730331f2242c1fc0bcb46a3ea3b4ae3348847e5a141265479700"}, - {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:544a12eee96e3ab828dbfcb4d5a0023aa971b27143a1d35dc214c176fdfb29b3"}, - {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:520de5e2ef0b4ae546bea25129d6c7c74edb43fc6cf5213f511a927f2b28148b"}, - {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccaa0a401fc02e8828a5bedfd80f8cd389d24f65e5ca3954d72c6582495b4bcf"}, - {file = "orjson-3.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7bc9e8bc11bac40f905640acd41cbeaa87209e7e1f57ade386da658092dc16"}, - {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3582b34b70543a1ed6944aca75e219e1192661a63da4d039d088a09c67543b08"}, - {file = "orjson-3.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1c23dfa91481de880890d17aa7b91d586a4746a4c2aa9a145bebdbaf233768d5"}, - {file = "orjson-3.10.3-cp311-none-win32.whl", hash = "sha256:1770e2a0eae728b050705206d84eda8b074b65ee835e7f85c919f5705b006c9b"}, - {file = "orjson-3.10.3-cp311-none-win_amd64.whl", hash = "sha256:93433b3c1f852660eb5abdc1f4dd0ced2be031ba30900433223b28ee0140cde5"}, - {file = "orjson-3.10.3-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:a39aa73e53bec8d410875683bfa3a8edf61e5a1c7bb4014f65f81d36467ea098"}, - {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0943a96b3fa09bee1afdfccc2cb236c9c64715afa375b2af296c73d91c23eab2"}, - {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e852baafceff8da3c9defae29414cc8513a1586ad93e45f27b89a639c68e8176"}, - {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18566beb5acd76f3769c1d1a7ec06cdb81edc4d55d2765fb677e3eaa10fa99e0"}, - {file = "orjson-3.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bd2218d5a3aa43060efe649ec564ebedec8ce6ae0a43654b81376216d5ebd42"}, - {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:cf20465e74c6e17a104ecf01bf8cd3b7b252565b4ccee4548f18b012ff2f8069"}, - {file = "orjson-3.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ba7f67aa7f983c4345eeda16054a4677289011a478ca947cd69c0a86ea45e534"}, - {file = "orjson-3.10.3-cp312-none-win32.whl", hash = "sha256:17e0713fc159abc261eea0f4feda611d32eabc35708b74bef6ad44f6c78d5ea0"}, - {file = "orjson-3.10.3-cp312-none-win_amd64.whl", hash = "sha256:4c895383b1ec42b017dd2c75ae8a5b862fc489006afde06f14afbdd0309b2af0"}, - {file = "orjson-3.10.3-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:be2719e5041e9fb76c8c2c06b9600fe8e8584e6980061ff88dcbc2691a16d20d"}, - {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0175a5798bdc878956099f5c54b9837cb62cfbf5d0b86ba6d77e43861bcec2"}, - {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978be58a68ade24f1af7758626806e13cff7748a677faf95fbb298359aa1e20d"}, - {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:16bda83b5c61586f6f788333d3cf3ed19015e3b9019188c56983b5a299210eb5"}, - {file = "orjson-3.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ad1f26bea425041e0a1adad34630c4825a9e3adec49079b1fb6ac8d36f8b754"}, - {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9e253498bee561fe85d6325ba55ff2ff08fb5e7184cd6a4d7754133bd19c9195"}, - {file = "orjson-3.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0a62f9968bab8a676a164263e485f30a0b748255ee2f4ae49a0224be95f4532b"}, - {file = "orjson-3.10.3-cp38-none-win32.whl", hash = "sha256:8d0b84403d287d4bfa9bf7d1dc298d5c1c5d9f444f3737929a66f2fe4fb8f134"}, - {file = "orjson-3.10.3-cp38-none-win_amd64.whl", hash = "sha256:8bc7a4df90da5d535e18157220d7915780d07198b54f4de0110eca6b6c11e290"}, - {file = "orjson-3.10.3-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9059d15c30e675a58fdcd6f95465c1522b8426e092de9fff20edebfdc15e1cb0"}, - {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d40c7f7938c9c2b934b297412c067936d0b54e4b8ab916fd1a9eb8f54c02294"}, - {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d4a654ec1de8fdaae1d80d55cee65893cb06494e124681ab335218be6a0691e7"}, - {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:831c6ef73f9aa53c5f40ae8f949ff7681b38eaddb6904aab89dca4d85099cb78"}, - {file = "orjson-3.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99b880d7e34542db89f48d14ddecbd26f06838b12427d5a25d71baceb5ba119d"}, - {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2e5e176c994ce4bd434d7aafb9ecc893c15f347d3d2bbd8e7ce0b63071c52e25"}, - {file = "orjson-3.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b69a58a37dab856491bf2d3bbf259775fdce262b727f96aafbda359cb1d114d8"}, - {file = "orjson-3.10.3-cp39-none-win32.whl", hash = "sha256:b8d4d1a6868cde356f1402c8faeb50d62cee765a1f7ffcfd6de732ab0581e063"}, - {file = "orjson-3.10.3-cp39-none-win_amd64.whl", hash = "sha256:5102f50c5fc46d94f2033fe00d392588564378260d64377aec702f21a7a22912"}, - {file = "orjson-3.10.3.tar.gz", hash = "sha256:2b166507acae7ba2f7c315dcf185a9111ad5e992ac81f2d507aac39193c2c818"}, + {file = "orjson-3.10.5-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:545d493c1f560d5ccfc134803ceb8955a14c3fcb47bbb4b2fee0232646d0b932"}, + {file = "orjson-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4324929c2dd917598212bfd554757feca3e5e0fa60da08be11b4aa8b90013c1"}, + {file = "orjson-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c13ca5e2ddded0ce6a927ea5a9f27cae77eee4c75547b4297252cb20c4d30e6"}, + {file = "orjson-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b6c8e30adfa52c025f042a87f450a6b9ea29649d828e0fec4858ed5e6caecf63"}, + {file = "orjson-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:338fd4f071b242f26e9ca802f443edc588fa4ab60bfa81f38beaedf42eda226c"}, + {file = "orjson-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6970ed7a3126cfed873c5d21ece1cd5d6f83ca6c9afb71bbae21a0b034588d96"}, + {file = "orjson-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:235dadefb793ad12f7fa11e98a480db1f7c6469ff9e3da5e73c7809c700d746b"}, + {file = "orjson-3.10.5-cp310-none-win32.whl", hash = "sha256:be79e2393679eda6a590638abda16d167754393f5d0850dcbca2d0c3735cebe2"}, + {file = "orjson-3.10.5-cp310-none-win_amd64.whl", hash = "sha256:c4a65310ccb5c9910c47b078ba78e2787cb3878cdded1702ac3d0da71ddc5228"}, + {file = "orjson-3.10.5-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:cdf7365063e80899ae3a697def1277c17a7df7ccfc979990a403dfe77bb54d40"}, + {file = "orjson-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b68742c469745d0e6ca5724506858f75e2f1e5b59a4315861f9e2b1df77775a"}, + {file = "orjson-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7d10cc1b594951522e35a3463da19e899abe6ca95f3c84c69e9e901e0bd93d38"}, + {file = "orjson-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dcbe82b35d1ac43b0d84072408330fd3295c2896973112d495e7234f7e3da2e1"}, + {file = "orjson-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c0eb7e0c75e1e486c7563fe231b40fdd658a035ae125c6ba651ca3b07936f5"}, + {file = "orjson-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:53ed1c879b10de56f35daf06dbc4a0d9a5db98f6ee853c2dbd3ee9d13e6f302f"}, + {file = "orjson-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:099e81a5975237fda3100f918839af95f42f981447ba8f47adb7b6a3cdb078fa"}, + {file = "orjson-3.10.5-cp311-none-win32.whl", hash = "sha256:1146bf85ea37ac421594107195db8bc77104f74bc83e8ee21a2e58596bfb2f04"}, + {file = "orjson-3.10.5-cp311-none-win_amd64.whl", hash = "sha256:36a10f43c5f3a55c2f680efe07aa93ef4a342d2960dd2b1b7ea2dd764fe4a37c"}, + {file = "orjson-3.10.5-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:68f85ecae7af14a585a563ac741b0547a3f291de81cd1e20903e79f25170458f"}, + {file = "orjson-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28afa96f496474ce60d3340fe8d9a263aa93ea01201cd2bad844c45cd21f5268"}, + {file = "orjson-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9cd684927af3e11b6e754df80b9ffafd9fb6adcaa9d3e8fdd5891be5a5cad51e"}, + {file = "orjson-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d21b9983da032505f7050795e98b5d9eee0df903258951566ecc358f6696969"}, + {file = "orjson-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ad1de7fef79736dde8c3554e75361ec351158a906d747bd901a52a5c9c8d24b"}, + {file = "orjson-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2d97531cdfe9bdd76d492e69800afd97e5930cb0da6a825646667b2c6c6c0211"}, + {file = "orjson-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d69858c32f09c3e1ce44b617b3ebba1aba030e777000ebdf72b0d8e365d0b2b3"}, + {file = "orjson-3.10.5-cp312-none-win32.whl", hash = "sha256:64c9cc089f127e5875901ac05e5c25aa13cfa5dbbbd9602bda51e5c611d6e3e2"}, + {file = "orjson-3.10.5-cp312-none-win_amd64.whl", hash = "sha256:b2efbd67feff8c1f7728937c0d7f6ca8c25ec81373dc8db4ef394c1d93d13dc5"}, + {file = "orjson-3.10.5-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:03b565c3b93f5d6e001db48b747d31ea3819b89abf041ee10ac6988886d18e01"}, + {file = "orjson-3.10.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:584c902ec19ab7928fd5add1783c909094cc53f31ac7acfada817b0847975f26"}, + {file = "orjson-3.10.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a35455cc0b0b3a1eaf67224035f5388591ec72b9b6136d66b49a553ce9eb1e6"}, + {file = "orjson-3.10.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1670fe88b116c2745a3a30b0f099b699a02bb3482c2591514baf5433819e4f4d"}, + {file = "orjson-3.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:185c394ef45b18b9a7d8e8f333606e2e8194a50c6e3c664215aae8cf42c5385e"}, + {file = "orjson-3.10.5-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ca0b3a94ac8d3886c9581b9f9de3ce858263865fdaa383fbc31c310b9eac07c9"}, + {file = "orjson-3.10.5-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:dfc91d4720d48e2a709e9c368d5125b4b5899dced34b5400c3837dadc7d6271b"}, + {file = "orjson-3.10.5-cp38-none-win32.whl", hash = "sha256:c05f16701ab2a4ca146d0bca950af254cb7c02f3c01fca8efbbad82d23b3d9d4"}, + {file = "orjson-3.10.5-cp38-none-win_amd64.whl", hash = "sha256:8a11d459338f96a9aa7f232ba95679fc0c7cedbd1b990d736467894210205c09"}, + {file = "orjson-3.10.5-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:85c89131d7b3218db1b24c4abecea92fd6c7f9fab87441cfc342d3acc725d807"}, + {file = "orjson-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb66215277a230c456f9038d5e2d84778141643207f85336ef8d2a9da26bd7ca"}, + {file = "orjson-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:51bbcdea96cdefa4a9b4461e690c75ad4e33796530d182bdd5c38980202c134a"}, + {file = "orjson-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbead71dbe65f959b7bd8cf91e0e11d5338033eba34c114f69078d59827ee139"}, + {file = "orjson-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5df58d206e78c40da118a8c14fc189207fffdcb1f21b3b4c9c0c18e839b5a214"}, + {file = "orjson-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c4057c3b511bb8aef605616bd3f1f002a697c7e4da6adf095ca5b84c0fd43595"}, + {file = "orjson-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b39e006b00c57125ab974362e740c14a0c6a66ff695bff44615dcf4a70ce2b86"}, + {file = "orjson-3.10.5-cp39-none-win32.whl", hash = "sha256:eded5138cc565a9d618e111c6d5c2547bbdd951114eb822f7f6309e04db0fb47"}, + {file = "orjson-3.10.5-cp39-none-win_amd64.whl", hash = "sha256:cc28e90a7cae7fcba2493953cff61da5a52950e78dc2dacfe931a317ee3d8de7"}, + {file = "orjson-3.10.5.tar.gz", hash = "sha256:7a5baef8a4284405d96c90c7c62b755e9ef1ada84c2406c24a9ebec86b89f46d"}, ] [[package]] name = "packaging" -version = "24.0" +version = "24.1" description = "Core utilities for Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "packaging-24.0-py3-none-any.whl", hash = "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5"}, - {file = "packaging-24.0.tar.gz", hash = "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9"}, + {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, + {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, ] [[package]] @@ -1728,21 +1152,6 @@ sql-other = ["SQLAlchemy (>=2.0.0)", "adbc-driver-postgresql (>=0.8.0)", "adbc-d test = ["hypothesis (>=6.46.1)", "pytest (>=7.3.2)", "pytest-xdist (>=2.2.0)"] xml = ["lxml (>=4.9.2)"] -[[package]] -name = "parso" -version = "0.8.4" -description = "A Python Parser" -optional = false -python-versions = ">=3.6" -files = [ - {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"}, - {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"}, -] - -[package.extras] -qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] -testing = ["docopt", "pytest"] - [[package]] name = "pathspec" version = "0.12.1" @@ -1754,115 +1163,15 @@ files = [ {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] -[[package]] -name = "pexpect" -version = "4.9.0" -description = "Pexpect allows easy control of interactive console applications." -optional = false -python-versions = "*" -files = [ - {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, - {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, -] - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pillow" -version = "10.3.0" -description = "Python Imaging Library (Fork)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pillow-10.3.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:90b9e29824800e90c84e4022dd5cc16eb2d9605ee13f05d47641eb183cd73d45"}, - {file = "pillow-10.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a2c405445c79c3f5a124573a051062300936b0281fee57637e706453e452746c"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78618cdbccaa74d3f88d0ad6cb8ac3007f1a6fa5c6f19af64b55ca170bfa1edf"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:261ddb7ca91fcf71757979534fb4c128448b5b4c55cb6152d280312062f69599"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:ce49c67f4ea0609933d01c0731b34b8695a7a748d6c8d186f95e7d085d2fe475"}, - {file = "pillow-10.3.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:b14f16f94cbc61215115b9b1236f9c18403c15dd3c52cf629072afa9d54c1cbf"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d33891be6df59d93df4d846640f0e46f1a807339f09e79a8040bc887bdcd7ed3"}, - {file = "pillow-10.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b50811d664d392f02f7761621303eba9d1b056fb1868c8cdf4231279645c25f5"}, - {file = "pillow-10.3.0-cp310-cp310-win32.whl", hash = "sha256:ca2870d5d10d8726a27396d3ca4cf7976cec0f3cb706debe88e3a5bd4610f7d2"}, - {file = "pillow-10.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:f0d0591a0aeaefdaf9a5e545e7485f89910c977087e7de2b6c388aec32011e9f"}, - {file = "pillow-10.3.0-cp310-cp310-win_arm64.whl", hash = "sha256:ccce24b7ad89adb5a1e34a6ba96ac2530046763912806ad4c247356a8f33a67b"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:5f77cf66e96ae734717d341c145c5949c63180842a545c47a0ce7ae52ca83795"}, - {file = "pillow-10.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4b878386c4bf293578b48fc570b84ecfe477d3b77ba39a6e87150af77f40c57"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdcbb4068117dfd9ce0138d068ac512843c52295ed996ae6dd1faf537b6dbc27"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9797a6c8fe16f25749b371c02e2ade0efb51155e767a971c61734b1bf6293994"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:9e91179a242bbc99be65e139e30690e081fe6cb91a8e77faf4c409653de39451"}, - {file = "pillow-10.3.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:1b87bd9d81d179bd8ab871603bd80d8645729939f90b71e62914e816a76fc6bd"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:81d09caa7b27ef4e61cb7d8fbf1714f5aec1c6b6c5270ee53504981e6e9121ad"}, - {file = "pillow-10.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:048ad577748b9fa4a99a0548c64f2cb8d672d5bf2e643a739ac8faff1164238c"}, - {file = "pillow-10.3.0-cp311-cp311-win32.whl", hash = "sha256:7161ec49ef0800947dc5570f86568a7bb36fa97dd09e9827dc02b718c5643f09"}, - {file = "pillow-10.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:8eb0908e954d093b02a543dc963984d6e99ad2b5e36503d8a0aaf040505f747d"}, - {file = "pillow-10.3.0-cp311-cp311-win_arm64.whl", hash = "sha256:4e6f7d1c414191c1199f8996d3f2282b9ebea0945693fb67392c75a3a320941f"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_10_10_x86_64.whl", hash = "sha256:e46f38133e5a060d46bd630faa4d9fa0202377495df1f068a8299fd78c84de84"}, - {file = "pillow-10.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:50b8eae8f7334ec826d6eeffaeeb00e36b5e24aa0b9df322c247539714c6df19"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d3bea1c75f8c53ee4d505c3e67d8c158ad4df0d83170605b50b64025917f338"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:19aeb96d43902f0a783946a0a87dbdad5c84c936025b8419da0a0cd7724356b1"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:74d28c17412d9caa1066f7a31df8403ec23d5268ba46cd0ad2c50fb82ae40462"}, - {file = "pillow-10.3.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:ff61bfd9253c3915e6d41c651d5f962da23eda633cf02262990094a18a55371a"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d886f5d353333b4771d21267c7ecc75b710f1a73d72d03ca06df49b09015a9ef"}, - {file = "pillow-10.3.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4b5ec25d8b17217d635f8935dbc1b9aa5907962fae29dff220f2659487891cd3"}, - {file = "pillow-10.3.0-cp312-cp312-win32.whl", hash = "sha256:51243f1ed5161b9945011a7360e997729776f6e5d7005ba0c6879267d4c5139d"}, - {file = "pillow-10.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:412444afb8c4c7a6cc11a47dade32982439925537e483be7c0ae0cf96c4f6a0b"}, - {file = "pillow-10.3.0-cp312-cp312-win_arm64.whl", hash = "sha256:798232c92e7665fe82ac085f9d8e8ca98826f8e27859d9a96b41d519ecd2e49a"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:4eaa22f0d22b1a7e93ff0a596d57fdede2e550aecffb5a1ef1106aaece48e96b"}, - {file = "pillow-10.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cd5e14fbf22a87321b24c88669aad3a51ec052eb145315b3da3b7e3cc105b9a2"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1530e8f3a4b965eb6a7785cf17a426c779333eb62c9a7d1bbcf3ffd5bf77a4aa"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d512aafa1d32efa014fa041d38868fda85028e3f930a96f85d49c7d8ddc0383"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:339894035d0ede518b16073bdc2feef4c991ee991a29774b33e515f1d308e08d"}, - {file = "pillow-10.3.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:aa7e402ce11f0885305bfb6afb3434b3cd8f53b563ac065452d9d5654c7b86fd"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0ea2a783a2bdf2a561808fe4a7a12e9aa3799b701ba305de596bc48b8bdfce9d"}, - {file = "pillow-10.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c78e1b00a87ce43bb37642c0812315b411e856a905d58d597750eb79802aaaa3"}, - {file = "pillow-10.3.0-cp38-cp38-win32.whl", hash = "sha256:72d622d262e463dfb7595202d229f5f3ab4b852289a1cd09650362db23b9eb0b"}, - {file = "pillow-10.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:2034f6759a722da3a3dbd91a81148cf884e91d1b747992ca288ab88c1de15999"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2ed854e716a89b1afcedea551cd85f2eb2a807613752ab997b9974aaa0d56936"}, - {file = "pillow-10.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dc1a390a82755a8c26c9964d457d4c9cbec5405896cba94cf51f36ea0d855002"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4203efca580f0dd6f882ca211f923168548f7ba334c189e9eab1178ab840bf60"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3102045a10945173d38336f6e71a8dc71bcaeed55c3123ad4af82c52807b9375"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:6fb1b30043271ec92dc65f6d9f0b7a830c210b8a96423074b15c7bc999975f57"}, - {file = "pillow-10.3.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:1dfc94946bc60ea375cc39cff0b8da6c7e5f8fcdc1d946beb8da5c216156ddd8"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b09b86b27a064c9624d0a6c54da01c1beaf5b6cadfa609cf63789b1d08a797b9"}, - {file = "pillow-10.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d3b2348a78bc939b4fed6552abfd2e7988e0f81443ef3911a4b8498ca084f6eb"}, - {file = "pillow-10.3.0-cp39-cp39-win32.whl", hash = "sha256:45ebc7b45406febf07fef35d856f0293a92e7417ae7933207e90bf9090b70572"}, - {file = "pillow-10.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:0ba26351b137ca4e0db0342d5d00d2e355eb29372c05afd544ebf47c0956ffeb"}, - {file = "pillow-10.3.0-cp39-cp39-win_arm64.whl", hash = "sha256:50fd3f6b26e3441ae07b7c979309638b72abc1a25da31a81a7fbd9495713ef4f"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_10_10_x86_64.whl", hash = "sha256:6b02471b72526ab8a18c39cb7967b72d194ec53c1fd0a70b050565a0f366d355"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8ab74c06ffdab957d7670c2a5a6e1a70181cd10b727cd788c4dd9005b6a8acd9"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:048eeade4c33fdf7e08da40ef402e748df113fd0b4584e32c4af74fe78baaeb2"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e2ec1e921fd07c7cda7962bad283acc2f2a9ccc1b971ee4b216b75fad6f0463"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:4c8e73e99da7db1b4cad7f8d682cf6abad7844da39834c288fbfa394a47bbced"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:16563993329b79513f59142a6b02055e10514c1a8e86dca8b48a893e33cf91e3"}, - {file = "pillow-10.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:dd78700f5788ae180b5ee8902c6aea5a5726bac7c364b202b4b3e3ba2d293170"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:aff76a55a8aa8364d25400a210a65ff59d0168e0b4285ba6bf2bd83cf675ba32"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b7bc2176354defba3edc2b9a777744462da2f8e921fbaf61e52acb95bafa9828"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:793b4e24db2e8742ca6423d3fde8396db336698c55cd34b660663ee9e45ed37f"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d93480005693d247f8346bc8ee28c72a2191bdf1f6b5db469c096c0c867ac015"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c83341b89884e2b2e55886e8fbbf37c3fa5efd6c8907124aeb72f285ae5696e5"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1a1d1915db1a4fdb2754b9de292642a39a7fb28f1736699527bb649484fb966a"}, - {file = "pillow-10.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a0eaa93d054751ee9964afa21c06247779b90440ca41d184aeb5d410f20ff591"}, - {file = "pillow-10.3.0.tar.gz", hash = "sha256:9d2455fbf44c914840c793e89aa82d0e1763a14253a000743719ae5946814b2d"}, -] - -[package.extras] -docs = ["furo", "olefile", "sphinx (>=2.4)", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-removed-in", "sphinxext-opengraph"] -fpx = ["olefile"] -mic = ["olefile"] -tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "packaging", "pyroma", "pytest", "pytest-cov", "pytest-timeout"] -typing = ["typing-extensions"] -xmp = ["defusedxml"] - [[package]] name = "platformdirs" -version = "4.2.1" +version = "4.2.2" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." optional = false python-versions = ">=3.8" files = [ - {file = "platformdirs-4.2.1-py3-none-any.whl", hash = "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1"}, - {file = "platformdirs-4.2.1.tar.gz", hash = "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf"}, + {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, + {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, ] [package.extras] @@ -1885,40 +1194,6 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] -[[package]] -name = "prompt-toolkit" -version = "3.0.43" -description = "Library for building powerful interactive command lines in Python" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, - {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, -] - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "protobuf" -version = "4.25.3" -description = "" -optional = false -python-versions = ">=3.8" -files = [ - {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, - {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, - {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, - {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, - {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, - {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, - {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, - {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, - {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, - {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, -] - [[package]] name = "pscript" version = "0.7.7" @@ -1930,107 +1205,6 @@ files = [ {file = "pscript-0.7.7.tar.gz", hash = "sha256:8632f7a4483f235514aadee110edee82eb6d67336bf68744a7b18d76e50442f8"}, ] -[[package]] -name = "psutil" -version = "5.9.8" -description = "Cross-platform lib for process and system monitoring in Python." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -files = [ - {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, - {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, - {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, - {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, - {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, - {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, - {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, - {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, - {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, - {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, - {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, - {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, - {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, -] - -[package.extras] -test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -optional = false -python-versions = "*" -files = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] - -[[package]] -name = "pure-eval" -version = "0.2.2" -description = "Safely evaluate AST nodes without side effects" -optional = false -python-versions = "*" -files = [ - {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, - {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, -] - -[package.extras] -tests = ["pytest"] - -[[package]] -name = "pyarrow" -version = "16.0.0" -description = "Python library for Apache Arrow" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pyarrow-16.0.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:22a1fdb1254e5095d629e29cd1ea98ed04b4bbfd8e42cc670a6b639ccc208b60"}, - {file = "pyarrow-16.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:574a00260a4ed9d118a14770edbd440b848fcae5a3024128be9d0274dbcaf858"}, - {file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c0815d0ddb733b8c1b53a05827a91f1b8bde6240f3b20bf9ba5d650eb9b89cdf"}, - {file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df0080339387b5d30de31e0a149c0c11a827a10c82f0c67d9afae3981d1aabb7"}, - {file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:edf38cce0bf0dcf726e074159c60516447e4474904c0033f018c1f33d7dac6c5"}, - {file = "pyarrow-16.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:91d28f9a40f1264eab2af7905a4d95320ac2f287891e9c8b0035f264fe3c3a4b"}, - {file = "pyarrow-16.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:99af421ee451a78884d7faea23816c429e263bd3618b22d38e7992c9ce2a7ad9"}, - {file = "pyarrow-16.0.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:d22d0941e6c7bafddf5f4c0662e46f2075850f1c044bf1a03150dd9e189427ce"}, - {file = "pyarrow-16.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:266ddb7e823f03733c15adc8b5078db2df6980f9aa93d6bb57ece615df4e0ba7"}, - {file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cc23090224b6594f5a92d26ad47465af47c1d9c079dd4a0061ae39551889efe"}, - {file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:56850a0afe9ef37249d5387355449c0f94d12ff7994af88f16803a26d38f2016"}, - {file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:705db70d3e2293c2f6f8e84874b5b775f690465798f66e94bb2c07bab0a6bb55"}, - {file = "pyarrow-16.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:5448564754c154997bc09e95a44b81b9e31ae918a86c0fcb35c4aa4922756f55"}, - {file = "pyarrow-16.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:729f7b262aa620c9df8b9967db96c1575e4cfc8c25d078a06968e527b8d6ec05"}, - {file = "pyarrow-16.0.0-cp312-cp312-macosx_10_15_x86_64.whl", hash = "sha256:fb8065dbc0d051bf2ae2453af0484d99a43135cadabacf0af588a3be81fbbb9b"}, - {file = "pyarrow-16.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:20ce707d9aa390593ea93218b19d0eadab56390311cb87aad32c9a869b0e958c"}, - {file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5823275c8addbbb50cd4e6a6839952682a33255b447277e37a6f518d6972f4e1"}, - {file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ab8b9050752b16a8b53fcd9853bf07d8daf19093533e990085168f40c64d978"}, - {file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:42e56557bc7c5c10d3e42c3b32f6cff649a29d637e8f4e8b311d334cc4326730"}, - {file = "pyarrow-16.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:2a7abdee4a4a7cfa239e2e8d721224c4b34ffe69a0ca7981354fe03c1328789b"}, - {file = "pyarrow-16.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:ef2f309b68396bcc5a354106741d333494d6a0d3e1951271849787109f0229a6"}, - {file = "pyarrow-16.0.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:ed66e5217b4526fa3585b5e39b0b82f501b88a10d36bd0d2a4d8aa7b5a48e2df"}, - {file = "pyarrow-16.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cc8814310486f2a73c661ba8354540f17eef51e1b6dd090b93e3419d3a097b3a"}, - {file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c2f5e239db7ed43e0ad2baf46a6465f89c824cc703f38ef0fde927d8e0955f7"}, - {file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f293e92d1db251447cb028ae12f7bc47526e4649c3a9924c8376cab4ad6b98bd"}, - {file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:dd9334a07b6dc21afe0857aa31842365a62eca664e415a3f9536e3a8bb832c07"}, - {file = "pyarrow-16.0.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:d91073d1e2fef2c121154680e2ba7e35ecf8d4969cc0af1fa6f14a8675858159"}, - {file = "pyarrow-16.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:71d52561cd7aefd22cf52538f262850b0cc9e4ec50af2aaa601da3a16ef48877"}, - {file = "pyarrow-16.0.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b93c9a50b965ee0bf4fef65e53b758a7e8dcc0c2d86cebcc037aaaf1b306ecc0"}, - {file = "pyarrow-16.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d831690844706e374c455fba2fb8cfcb7b797bfe53ceda4b54334316e1ac4fa4"}, - {file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35692ce8ad0b8c666aa60f83950957096d92f2a9d8d7deda93fb835e6053307e"}, - {file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dd3151d098e56f16a8389c1247137f9e4c22720b01c6f3aa6dec29a99b74d80"}, - {file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:bd40467bdb3cbaf2044ed7a6f7f251c8f941c8b31275aaaf88e746c4f3ca4a7a"}, - {file = "pyarrow-16.0.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:00a1dcb22ad4ceb8af87f7bd30cc3354788776c417f493089e0a0af981bc8d80"}, - {file = "pyarrow-16.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:fda9a7cebd1b1d46c97b511f60f73a5b766a6de4c5236f144f41a5d5afec1f35"}, - {file = "pyarrow-16.0.0.tar.gz", hash = "sha256:59bb1f1edbbf4114c72415f039f1359f1a57d166a331c3229788ccbfbb31689a"}, -] - -[package.dependencies] -numpy = ">=1.16.6" - [[package]] name = "pydantic" version = "2.5.2" @@ -2167,25 +1341,6 @@ files = [ [package.dependencies] typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" -[[package]] -name = "pydeck" -version = "0.9.1" -description = "Widget for deck.gl maps" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydeck-0.9.1-py2.py3-none-any.whl", hash = "sha256:b3f75ba0d273fc917094fa61224f3f6076ca8752b93d46faf3bcfd9f9d59b038"}, - {file = "pydeck-0.9.1.tar.gz", hash = "sha256:f74475ae637951d63f2ee58326757f8d4f9cd9f2a457cf42950715003e2cb605"}, -] - -[package.dependencies] -jinja2 = ">=2.10.1" -numpy = ">=1.16.4" - -[package.extras] -carto = ["pydeck-carto"] -jupyter = ["ipykernel (>=5.1.2)", "ipython (>=5.8.0)", "ipywidgets (>=7,<8)", "traitlets (>=4.3.2)"] - [[package]] name = "pygments" version = "2.18.0" @@ -2200,116 +1355,63 @@ files = [ [package.extras] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pygwalker" -version = "0.3.20" -description = "pygwalker: Combining Jupyter Notebook with a Tableau-like UI" -optional = false -python-versions = ">=3.6" -files = [ - {file = "pygwalker-0.3.20-py3-none-any.whl", hash = "sha256:0c12538448ce8aaf402c3a8d32117fbb7507f66705b38e30afcc23f0ad076204"}, - {file = "pygwalker-0.3.20.tar.gz", hash = "sha256:a171447f1d154cd04887e22cf5f2d656f68aaf49c6bc9c3cb57fcd53888ac61b"}, -] - -[package.dependencies] -altair = ">=5.0.0" -appdirs = "*" -arrow = "*" -astor = "*" -duckdb = "0.9.2" -gw-dsl-parser = "0.1.38" -ipython = "*" -ipywidgets = "*" -jinja2 = "*" -kanaries-track = "0.0.3" -pandas = "*" -psutil = "*" -pyarrow = "*" -pydantic = "*" -pytz = "*" -requests = "*" -segment-analytics-python = "2.2.3" -sqlalchemy = "*" -sqlglot = ">=19.0.0" -typing-extensions = "*" - -[package.extras] -all = ["pygwalker[pandas,polars,streamlit]"] -dev = ["build", "twine"] -labv4 = ["ipywidgets (>=8.0.0)", "jupyter-client (>7.4.9)", "jupyter-server (>2.5.0)"] -notebook = ["ipywidgets (>7.0.0,<8.0.0)", "jupyter-client (>6.0.0,<=7.4.9)", "jupyter-server (<=2.5.0)"] -pandas = ["pandas"] -polars = ["polars"] -snowflake = ["pandas", "pyarrow (==10.0.1)", "snowflake-sqlalchemy (==1.5.0)", "sqlalchemy (==1.4.49)"] -streamlit = ["streamlit"] - [[package]] name = "pymongo" -version = "4.7.2" +version = "4.8.0" description = "Python driver for MongoDB " optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pymongo-4.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:268d8578c0500012140c5460755ea405cbfe541ef47c81efa9d6744f0f99aeca"}, - {file = "pymongo-4.7.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:827611beb6c483260d520cfa6a49662d980dfa5368a04296f65fa39e78fccea7"}, - {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a754e366c404d19ff3f077ddeed64be31e0bb515e04f502bf11987f1baa55a16"}, - {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c44efab10d9a3db920530f7bcb26af8f408b7273d2f0214081d3891979726328"}, - {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35b3f0c7d49724859d4df5f0445818d525824a6cd55074c42573d9b50764df67"}, - {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e37faf298a37ffb3e0809e77fbbb0a32b6a2d18a83c59cfc2a7b794ea1136b0"}, - {file = "pymongo-4.7.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1bcd58669e56c08f1e72c5758868b5df169fe267501c949ee83c418e9df9155"}, - {file = "pymongo-4.7.2-cp310-cp310-win32.whl", hash = "sha256:c72d16fede22efe7cdd1f422e8da15760e9498024040429362886f946c10fe95"}, - {file = "pymongo-4.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:12d1fef77d25640cb78893d07ff7d2fac4c4461d8eec45bd3b9ad491a1115d6e"}, - {file = "pymongo-4.7.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc5af24fcf5fc6f7f40d65446400d45dd12bea933d0299dc9e90c5b22197f1e9"}, - {file = "pymongo-4.7.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:730778b6f0964b164c187289f906bbc84cb0524df285b7a85aa355bbec43eb21"}, - {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47a1a4832ef2f4346dcd1a10a36ade7367ad6905929ddb476459abb4fd1b98cb"}, - {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6eab12c6385526d386543d6823b07187fefba028f0da216506e00f0e1855119"}, - {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37e9ea81fa59ee9274457ed7d59b6c27f6f2a5fe8e26f184ecf58ea52a019cb8"}, - {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e9d9d2c0aae73aa4369bd373ac2ac59f02c46d4e56c4b6d6e250cfe85f76802"}, - {file = "pymongo-4.7.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb6e00a79dff22c9a72212ad82021b54bdb3b85f38a85f4fc466bde581d7d17a"}, - {file = "pymongo-4.7.2-cp311-cp311-win32.whl", hash = "sha256:02efd1bb3397e24ef2af45923888b41a378ce00cb3a4259c5f4fc3c70497a22f"}, - {file = "pymongo-4.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:87bb453ac3eb44db95cb6d5a616fbc906c1c00661eec7f55696253a6245beb8a"}, - {file = "pymongo-4.7.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:12c466e02133b7f8f4ff1045c6b5916215c5f7923bc83fd6e28e290cba18f9f6"}, - {file = "pymongo-4.7.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f91073049c43d14e66696970dd708d319b86ee57ef9af359294eee072abaac79"}, - {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87032f818bf5052ab742812c715eff896621385c43f8f97cdd37d15b5d394e95"}, - {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a87eef394039765679f75c6a47455a4030870341cb76eafc349c5944408c882"}, - {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d275596f840018858757561840767b39272ac96436fcb54f5cac6d245393fd97"}, - {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82102e353be13f1a6769660dd88115b1da382447672ba1c2662a0fbe3df1d861"}, - {file = "pymongo-4.7.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:194065c9d445017b3c82fb85f89aa2055464a080bde604010dc8eb932a6b3c95"}, - {file = "pymongo-4.7.2-cp312-cp312-win32.whl", hash = "sha256:db4380d1e69fdad1044a4b8f3bb105200542c49a0dde93452d938ff9db1d6d29"}, - {file = "pymongo-4.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:fadc6e8db7707c861ebe25b13ad6aca19ea4d2c56bf04a26691f46c23dadf6e4"}, - {file = "pymongo-4.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2cb77d09bd012cb4b30636e7e38d00b5f9be5eb521c364bde66490c45ee6c4b4"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56bf8b706946952acdea0fe478f8e44f1ed101c4b87f046859e6c3abe6c0a9f4"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcf337d1b252405779d9c79978d6ca15eab3cdaa2f44c100a79221bddad97c8a"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ffd1519edbe311df73c74ec338de7d294af535b2748191c866ea3a7c484cd15"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4d59776f435564159196d971aa89422ead878174aff8fe18e06d9a0bc6d648c"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:347c49cf7f0ba49ea87c1a5a1984187ecc5516b7c753f31938bf7b37462824fd"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:84bc00200c3cbb6c98a2bb964c9e8284b641e4a33cf10c802390552575ee21de"}, - {file = "pymongo-4.7.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:fcaf8c911cb29316a02356f89dbc0e0dfcc6a712ace217b6b543805690d2aefd"}, - {file = "pymongo-4.7.2-cp37-cp37m-win32.whl", hash = "sha256:b48a5650ee5320d59f6d570bd99a8d5c58ac6f297a4e9090535f6561469ac32e"}, - {file = "pymongo-4.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:5239ef7e749f1326ea7564428bf861d5250aa39d7f26d612741b1b1273227062"}, - {file = "pymongo-4.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2dcf608d35644e8d276d61bf40a93339d8d66a0e5f3e3f75b2c155a421a1b71"}, - {file = "pymongo-4.7.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:25eeb2c18ede63891cbd617943dd9e6b9cbccc54f276e0b2e693a0cc40f243c5"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9349f0bb17a31371d4cacb64b306e4ca90413a3ad1fffe73ac7cd495570d94b5"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ffd4d7cb2e6c6e100e2b39606d38a9ffc934e18593dc9bb326196afc7d93ce3d"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9a8bd37f5dabc86efceb8d8cbff5969256523d42d08088f098753dba15f3b37a"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c78f156edc59b905c80c9003e022e1a764c54fd40ac4fea05b0764f829790e2"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9d892fb91e81cccb83f507cdb2ea0aa026ec3ced7f12a1d60f6a5bf0f20f9c1f"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87832d6076c2c82f42870157414fd876facbb6554d2faf271ffe7f8f30ce7bed"}, - {file = "pymongo-4.7.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ce1a374ea0e49808e0380ffc64284c0ce0f12bd21042b4bef1af3eb7bdf49054"}, - {file = "pymongo-4.7.2-cp38-cp38-win32.whl", hash = "sha256:eb0642e5f0dd7e86bb358749cc278e70b911e617f519989d346f742dc9520dfb"}, - {file = "pymongo-4.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:4bdb5ffe1cd3728c9479671a067ef44dacafc3743741d4dc700c377c4231356f"}, - {file = "pymongo-4.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:743552033c63f0afdb56b9189ab04b5c1dbffd7310cf7156ab98eebcecf24621"}, - {file = "pymongo-4.7.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5239776633f7578b81207e5646245415a5a95f6ae5ef5dff8e7c2357e6264bfc"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:727ad07952c155cd20045f2ce91143c7dc4fb01a5b4e8012905a89a7da554b0c"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9385654f01a90f73827af4db90c290a1519f7d9102ba43286e187b373e9a78e9"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0d833651f1ba938bb7501f13e326b96cfbb7d98867b2d545ca6d69c7664903e0"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf17ea9cea14d59b0527403dd7106362917ced7c4ec936c4ba22bd36c912c8e0"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cecd2df037249d1c74f0af86fb5b766104a5012becac6ff63d85d1de53ba8b98"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:65b4c00dedbd333698b83cd2095a639a6f0d7c4e2a617988f6c65fb46711f028"}, - {file = "pymongo-4.7.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:d9b6cbc037108ff1a0a867e7670d8513c37f9bcd9ee3d2464411bfabf70ca002"}, - {file = "pymongo-4.7.2-cp39-cp39-win32.whl", hash = "sha256:cf28430ec1924af1bffed37b69a812339084697fd3f3e781074a0148e6475803"}, - {file = "pymongo-4.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:e004527ea42a6b99a8b8d5b42b42762c3bdf80f88fbdb5c3a9d47f3808495b86"}, - {file = "pymongo-4.7.2.tar.gz", hash = "sha256:9024e1661c6e40acf468177bf90ce924d1bc681d2b244adda3ed7b2f4c4d17d7"}, + {file = "pymongo-4.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f2b7bec27e047e84947fbd41c782f07c54c30c76d14f3b8bf0c89f7413fac67a"}, + {file = "pymongo-4.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3c68fe128a171493018ca5c8020fc08675be130d012b7ab3efe9e22698c612a1"}, + {file = "pymongo-4.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:920d4f8f157a71b3cb3f39bc09ce070693d6e9648fb0e30d00e2657d1dca4e49"}, + {file = "pymongo-4.8.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:52b4108ac9469febba18cea50db972605cc43978bedaa9fea413378877560ef8"}, + {file = "pymongo-4.8.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:180d5eb1dc28b62853e2f88017775c4500b07548ed28c0bd9c005c3d7bc52526"}, + {file = "pymongo-4.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aec2b9088cdbceb87e6ca9c639d0ff9b9d083594dda5ca5d3c4f6774f4c81b33"}, + {file = "pymongo-4.8.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0cf61450feadca81deb1a1489cb1a3ae1e4266efd51adafecec0e503a8dcd84"}, + {file = "pymongo-4.8.0-cp310-cp310-win32.whl", hash = "sha256:8b18c8324809539c79bd6544d00e0607e98ff833ca21953df001510ca25915d1"}, + {file = "pymongo-4.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e5df28f74002e37bcbdfdc5109799f670e4dfef0fb527c391ff84f078050e7b5"}, + {file = "pymongo-4.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6b50040d9767197b77ed420ada29b3bf18a638f9552d80f2da817b7c4a4c9c68"}, + {file = "pymongo-4.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:417369ce39af2b7c2a9c7152c1ed2393edfd1cbaf2a356ba31eb8bcbd5c98dd7"}, + {file = "pymongo-4.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf821bd3befb993a6db17229a2c60c1550e957de02a6ff4dd0af9476637b2e4d"}, + {file = "pymongo-4.8.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9365166aa801c63dff1a3cb96e650be270da06e3464ab106727223123405510f"}, + {file = "pymongo-4.8.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc8b8582f4209c2459b04b049ac03c72c618e011d3caa5391ff86d1bda0cc486"}, + {file = "pymongo-4.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e5019f75f6827bb5354b6fef8dfc9d6c7446894a27346e03134d290eb9e758"}, + {file = "pymongo-4.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b5802151fc2b51cd45492c80ed22b441d20090fb76d1fd53cd7760b340ff554"}, + {file = "pymongo-4.8.0-cp311-cp311-win32.whl", hash = "sha256:4bf58e6825b93da63e499d1a58de7de563c31e575908d4e24876234ccb910eba"}, + {file = "pymongo-4.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:b747c0e257b9d3e6495a018309b9e0c93b7f0d65271d1d62e572747f4ffafc88"}, + {file = "pymongo-4.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e6a720a3d22b54183352dc65f08cd1547204d263e0651b213a0a2e577e838526"}, + {file = "pymongo-4.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:31e4d21201bdf15064cf47ce7b74722d3e1aea2597c6785882244a3bb58c7eab"}, + {file = "pymongo-4.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c6b804bb4f2d9dc389cc9e827d579fa327272cdb0629a99bfe5b83cb3e269ebf"}, + {file = "pymongo-4.8.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f2fbdb87fe5075c8beb17a5c16348a1ea3c8b282a5cb72d173330be2fecf22f5"}, + {file = "pymongo-4.8.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd39455b7ee70aabee46f7399b32ab38b86b236c069ae559e22be6b46b2bbfc4"}, + {file = "pymongo-4.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:940d456774b17814bac5ea7fc28188c7a1338d4a233efbb6ba01de957bded2e8"}, + {file = "pymongo-4.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:236bbd7d0aef62e64caf4b24ca200f8c8670d1a6f5ea828c39eccdae423bc2b2"}, + {file = "pymongo-4.8.0-cp312-cp312-win32.whl", hash = "sha256:47ec8c3f0a7b2212dbc9be08d3bf17bc89abd211901093e3ef3f2adea7de7a69"}, + {file = "pymongo-4.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e84bc7707492f06fbc37a9f215374d2977d21b72e10a67f1b31893ec5a140ad8"}, + {file = "pymongo-4.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:519d1bab2b5e5218c64340b57d555d89c3f6c9d717cecbf826fb9d42415e7750"}, + {file = "pymongo-4.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87075a1feb1e602e539bdb1ef8f4324a3427eb0d64208c3182e677d2c0718b6f"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f53429515d2b3e86dcc83dadecf7ff881e538c168d575f3688698a8707b80a"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdc20cd1e1141b04696ffcdb7c71e8a4a665db31fe72e51ec706b3bdd2d09f36"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:284d0717d1a7707744018b0b6ee7801b1b1ff044c42f7be7a01bb013de639470"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5bf0eb8b6ef40fa22479f09375468c33bebb7fe49d14d9c96c8fd50355188b0"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2ecd71b9226bd1d49416dc9f999772038e56f415a713be51bf18d8676a0841c8"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e0061af6e8c5e68b13f1ec9ad5251247726653c5af3c0bbdfbca6cf931e99216"}, + {file = "pymongo-4.8.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:658d0170f27984e0d89c09fe5c42296613b711a3ffd847eb373b0dbb5b648d5f"}, + {file = "pymongo-4.8.0-cp38-cp38-win32.whl", hash = "sha256:3ed1c316718a2836f7efc3d75b4b0ffdd47894090bc697de8385acd13c513a70"}, + {file = "pymongo-4.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:7148419eedfea9ecb940961cfe465efaba90595568a1fb97585fb535ea63fe2b"}, + {file = "pymongo-4.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8400587d594761e5136a3423111f499574be5fd53cf0aefa0d0f05b180710b0"}, + {file = "pymongo-4.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:af3e98dd9702b73e4e6fd780f6925352237f5dce8d99405ff1543f3771201704"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:de3a860f037bb51f968de320baef85090ff0bbb42ec4f28ec6a5ddf88be61871"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fc18b3a093f3db008c5fea0e980dbd3b743449eee29b5718bc2dc15ab5088bb"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18c9d8f975dd7194c37193583fd7d1eb9aea0c21ee58955ecf35362239ff31ac"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:408b2f8fdbeca3c19e4156f28fff1ab11c3efb0407b60687162d49f68075e63c"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6564780cafd6abeea49759fe661792bd5a67e4f51bca62b88faab497ab5fe89"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d18d86bc9e103f4d3d4f18b85a0471c0e13ce5b79194e4a0389a224bb70edd53"}, + {file = "pymongo-4.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9097c331577cecf8034422956daaba7ec74c26f7b255d718c584faddd7fa2e3c"}, + {file = "pymongo-4.8.0-cp39-cp39-win32.whl", hash = "sha256:d5428dbcd43d02f6306e1c3c95f692f68b284e6ee5390292242f509004c9e3a8"}, + {file = "pymongo-4.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:ef7225755ed27bfdb18730c68f6cb023d06c28f2b734597480fb4c0e500feb6f"}, + {file = "pymongo-4.8.0.tar.gz", hash = "sha256:454f2295875744dc70f1881e4b2eb99cdad008a33574bc8aaf120530f66c0cde"}, ] [package.dependencies] @@ -2317,6 +1419,7 @@ dnspython = ">=1.16.0,<3.0.0" [package.extras] aws = ["pymongo-auth-aws (>=1.1.0,<2.0.0)"] +docs = ["furo (==2023.9.10)", "readthedocs-sphinx-search (>=0.3,<1.0)", "sphinx (>=5.3,<8)", "sphinx-rtd-theme (>=2,<3)", "sphinxcontrib-shellcheck (>=1,<2)"] encryption = ["certifi", "pymongo-auth-aws (>=1.1.0,<2.0.0)", "pymongocrypt (>=1.6.0,<2.0.0)"] gssapi = ["pykerberos", "winkerberos (>=0.5.0)"] ocsp = ["certifi", "cryptography (>=2.5)", "pyopenssl (>=17.2.0)", "requests (<3.0.0)", "service-identity (>=18.1.0)"] @@ -2358,17 +1461,6 @@ files = [ [package.dependencies] six = ">=1.5" -[[package]] -name = "python-decouple" -version = "3.8" -description = "Strict separation of settings from code." -optional = false -python-versions = "*" -files = [ - {file = "python-decouple-3.8.tar.gz", hash = "sha256:ba6e2657d4f376ecc46f77a3a615e058d93ba5e465c01bbe57289bfb7cce680f"}, - {file = "python_decouple-3.8-py3-none-any.whl", hash = "sha256:d0d45340815b25f4de59c974b855bb38d03151d81b037d9e3f463b0c9f8cbd66"}, -] - [[package]] name = "python-dotenv" version = "1.0.1" @@ -2385,13 +1477,13 @@ cli = ["click (>=5.0)"] [[package]] name = "python-engineio" -version = "4.9.0" +version = "4.9.1" description = "Engine.IO server and client for Python" optional = false python-versions = ">=3.6" files = [ - {file = "python-engineio-4.9.0.tar.gz", hash = "sha256:e87459c15638e567711fd156e6f9c4a402668871bed79523f0ecfec744729ec7"}, - {file = "python_engineio-4.9.0-py3-none-any.whl", hash = "sha256:979859bff770725b75e60353d7ae53b397e8b517d05ba76733b404a3dcca3e4c"}, + {file = "python_engineio-4.9.1-py3-none-any.whl", hash = "sha256:f995e702b21f6b9ebde4e2000cd2ad0112ba0e5116ec8d22fe3515e76ba9dddd"}, + {file = "python_engineio-4.9.1.tar.gz", hash = "sha256:7631cf5563086076611e494c643b3fa93dd3a854634b5488be0bba0ef9b99709"}, ] [package.dependencies] @@ -2435,13 +1527,13 @@ unidecode = ["Unidecode (>=1.1.1)"] [[package]] name = "python-socketio" -version = "5.11.2" +version = "5.11.3" description = "Socket.IO server and client for Python" optional = false python-versions = ">=3.8" files = [ - {file = "python-socketio-5.11.2.tar.gz", hash = "sha256:ae6a1de5c5209ca859dc574dccc8931c4be17ee003e74ce3b8d1306162bb4a37"}, - {file = "python_socketio-5.11.2-py3-none-any.whl", hash = "sha256:b9f22a8ff762d7a6e123d16a43ddb1a27d50f07c3c88ea999334f2f89b0ad52b"}, + {file = "python_socketio-5.11.3-py3-none-any.whl", hash = "sha256:2a923a831ff70664b7c502df093c423eb6aa93c1ce68b8319e840227a26d8b69"}, + {file = "python_socketio-5.11.3.tar.gz", hash = "sha256:194af8cdbb7b0768c2e807ba76c7abc288eb5bb85559b7cddee51a6bc7a65737"}, ] [package.dependencies] @@ -2525,30 +1617,15 @@ files = [ {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, ] -[[package]] -name = "referencing" -version = "0.35.1" -description = "JSON Referencing + Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "referencing-0.35.1-py3-none-any.whl", hash = "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de"}, - {file = "referencing-0.35.1.tar.gz", hash = "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c"}, -] - -[package.dependencies] -attrs = ">=22.2.0" -rpds-py = ">=0.7.0" - [[package]] name = "requests" -version = "2.31.0" +version = "2.32.3" description = "Python HTTP for Humans." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, - {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] [package.dependencies] @@ -2561,141 +1638,15 @@ urllib3 = ">=1.21.1,<3" socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] -[[package]] -name = "rich" -version = "13.7.1" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "rpds-py" -version = "0.18.1" -description = "Python bindings to Rust's persistent data structures (rpds)" -optional = false -python-versions = ">=3.8" -files = [ - {file = "rpds_py-0.18.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53"}, - {file = "rpds_py-0.18.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0"}, - {file = "rpds_py-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da"}, - {file = "rpds_py-0.18.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1"}, - {file = "rpds_py-0.18.1-cp310-none-win32.whl", hash = "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333"}, - {file = "rpds_py-0.18.1-cp310-none-win_amd64.whl", hash = "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8"}, - {file = "rpds_py-0.18.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100"}, - {file = "rpds_py-0.18.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e"}, - {file = "rpds_py-0.18.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88"}, - {file = "rpds_py-0.18.1-cp311-none-win32.whl", hash = "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb"}, - {file = "rpds_py-0.18.1-cp311-none-win_amd64.whl", hash = "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3"}, - {file = "rpds_py-0.18.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8"}, - {file = "rpds_py-0.18.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac"}, - {file = "rpds_py-0.18.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a"}, - {file = "rpds_py-0.18.1-cp312-none-win32.whl", hash = "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6"}, - {file = "rpds_py-0.18.1-cp312-none-win_amd64.whl", hash = "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74"}, - {file = "rpds_py-0.18.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5"}, - {file = "rpds_py-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e"}, - {file = "rpds_py-0.18.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc"}, - {file = "rpds_py-0.18.1-cp38-none-win32.whl", hash = "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9"}, - {file = "rpds_py-0.18.1-cp38-none-win_amd64.whl", hash = "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93"}, - {file = "rpds_py-0.18.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab"}, - {file = "rpds_py-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b"}, - {file = "rpds_py-0.18.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26"}, - {file = "rpds_py-0.18.1-cp39-none-win32.whl", hash = "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360"}, - {file = "rpds_py-0.18.1-cp39-none-win_amd64.whl", hash = "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c"}, - {file = "rpds_py-0.18.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909"}, - {file = "rpds_py-0.18.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49"}, - {file = "rpds_py-0.18.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e"}, - {file = "rpds_py-0.18.1.tar.gz", hash = "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f"}, -] - [[package]] name = "s3transfer" -version = "0.10.1" +version = "0.10.2" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">= 3.8" +python-versions = ">=3.8" files = [ - {file = "s3transfer-0.10.1-py3-none-any.whl", hash = "sha256:ceb252b11bcf87080fb7850a224fb6e05c8a776bab8f2b64b7f25b969464839d"}, - {file = "s3transfer-0.10.1.tar.gz", hash = "sha256:5683916b4c724f799e600f41dd9e10a9ff19871bf87623cc8f491cb4f5fa0a19"}, + {file = "s3transfer-0.10.2-py3-none-any.whl", hash = "sha256:eca1c20de70a39daee580aef4986996620f365c4e0fda6a86100231d62f1bf69"}, + {file = "s3transfer-0.10.2.tar.gz", hash = "sha256:0711534e9356d3cc692fdde846b4a1e4b0cb6519971860796e6bc4c7aea00ef6"}, ] [package.dependencies] @@ -2704,26 +1655,6 @@ botocore = ">=1.33.2,<2.0a.0" [package.extras] crt = ["botocore[crt] (>=1.33.2,<2.0a.0)"] -[[package]] -name = "segment-analytics-python" -version = "2.2.3" -description = "The hassle-free way to integrate analytics into any python application." -optional = false -python-versions = ">=3.6.0" -files = [ - {file = "segment-analytics-python-2.2.3.tar.gz", hash = "sha256:0df5908e3df74b4482f33392fdd450df4c8351bf54974376fbe6bf33b0700865"}, - {file = "segment_analytics_python-2.2.3-py2.py3-none-any.whl", hash = "sha256:06cc3d8e79103f02c3878ec66cb66152415473d0d2a142b98a0ee18da972e109"}, -] - -[package.dependencies] -backoff = ">=2.1,<3.0" -monotonic = ">=1.5,<2.0" -python-dateutil = ">=2.2,<3.0" -requests = ">=2.7,<3.0" - -[package.extras] -test = ["flake8 (==3.7.9)", "mock (==2.0.0)", "pylint (==2.8.0)"] - [[package]] name = "simple-websocket" version = "1.0.0" @@ -2752,17 +1683,6 @@ files = [ {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, ] -[[package]] -name = "smmap" -version = "5.0.1" -description = "A pure Python implementation of a sliding window memory map manager" -optional = false -python-versions = ">=3.7" -files = [ - {file = "smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da"}, - {file = "smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62"}, -] - [[package]] name = "sniffio" version = "1.3.1" @@ -2774,141 +1694,6 @@ files = [ {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] -[[package]] -name = "sqlalchemy" -version = "2.0.30" -description = "Database Abstraction Library" -optional = false -python-versions = ">=3.7" -files = [ - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b48154678e76445c7ded1896715ce05319f74b1e73cf82d4f8b59b46e9c0ddc"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2753743c2afd061bb95a61a51bbb6a1a11ac1c44292fad898f10c9839a7f75b2"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a7bfc726d167f425d4c16269a9a10fe8630ff6d14b683d588044dcef2d0f6be7"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4f61ada6979223013d9ab83a3ed003ded6959eae37d0d685db2c147e9143797"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a365eda439b7a00732638f11072907c1bc8e351c7665e7e5da91b169af794af"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bba002a9447b291548e8d66fd8c96a6a7ed4f2def0bb155f4f0a1309fd2735d5"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win32.whl", hash = "sha256:0138c5c16be3600923fa2169532205d18891b28afa817cb49b50e08f62198bb8"}, - {file = "SQLAlchemy-2.0.30-cp310-cp310-win_amd64.whl", hash = "sha256:99650e9f4cf3ad0d409fed3eec4f071fadd032e9a5edc7270cd646a26446feeb"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:955991a09f0992c68a499791a753523f50f71a6885531568404fa0f231832aa0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f69e4c756ee2686767eb80f94c0125c8b0a0b87ede03eacc5c8ae3b54b99dc46"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69c9db1ce00e59e8dd09d7bae852a9add716efdc070a3e2068377e6ff0d6fdaa"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1429a4b0f709f19ff3b0cf13675b2b9bfa8a7e79990003207a011c0db880a13"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:efedba7e13aa9a6c8407c48facfdfa108a5a4128e35f4c68f20c3407e4376aa9"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:16863e2b132b761891d6c49f0a0f70030e0bcac4fd208117f6b7e053e68668d0"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win32.whl", hash = "sha256:2ecabd9ccaa6e914e3dbb2aa46b76dede7eadc8cbf1b8083c94d936bcd5ffb49"}, - {file = "SQLAlchemy-2.0.30-cp311-cp311-win_amd64.whl", hash = "sha256:0b3f4c438e37d22b83e640f825ef0f37b95db9aa2d68203f2c9549375d0b2260"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5a79d65395ac5e6b0c2890935bad892eabb911c4aa8e8015067ddb37eea3d56c"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9a5baf9267b752390252889f0c802ea13b52dfee5e369527da229189b8bd592e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb5a646930c5123f8461f6468901573f334c2c63c795b9af350063a736d0134"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:296230899df0b77dec4eb799bcea6fbe39a43707ce7bb166519c97b583cfcab3"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c62d401223f468eb4da32627bffc0c78ed516b03bb8a34a58be54d618b74d472"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3b69e934f0f2b677ec111b4d83f92dc1a3210a779f69bf905273192cf4ed433e"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win32.whl", hash = "sha256:77d2edb1f54aff37e3318f611637171e8ec71472f1fdc7348b41dcb226f93d90"}, - {file = "SQLAlchemy-2.0.30-cp312-cp312-win_amd64.whl", hash = "sha256:b6c7ec2b1f4969fc19b65b7059ed00497e25f54069407a8701091beb69e591a5"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5a8e3b0a7e09e94be7510d1661339d6b52daf202ed2f5b1f9f48ea34ee6f2d57"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b60203c63e8f984df92035610c5fb76d941254cf5d19751faab7d33b21e5ddc0"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f1dc3eabd8c0232ee8387fbe03e0a62220a6f089e278b1f0aaf5e2d6210741ad"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:40ad017c672c00b9b663fcfcd5f0864a0a97828e2ee7ab0c140dc84058d194cf"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e42203d8d20dc704604862977b1470a122e4892791fe3ed165f041e4bf447a1b"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win32.whl", hash = "sha256:2a4f4da89c74435f2bc61878cd08f3646b699e7d2eba97144030d1be44e27584"}, - {file = "SQLAlchemy-2.0.30-cp37-cp37m-win_amd64.whl", hash = "sha256:b6bf767d14b77f6a18b6982cbbf29d71bede087edae495d11ab358280f304d8e"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bc0c53579650a891f9b83fa3cecd4e00218e071d0ba00c4890f5be0c34887ed3"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:311710f9a2ee235f1403537b10c7687214bb1f2b9ebb52702c5aa4a77f0b3af7"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:408f8b0e2c04677e9c93f40eef3ab22f550fecb3011b187f66a096395ff3d9fd"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37a4b4fb0dd4d2669070fb05b8b8824afd0af57587393015baee1cf9890242d9"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:a943d297126c9230719c27fcbbeab57ecd5d15b0bd6bfd26e91bfcfe64220621"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0a089e218654e740a41388893e090d2e2c22c29028c9d1353feb38638820bbeb"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win32.whl", hash = "sha256:fa561138a64f949f3e889eb9ab8c58e1504ab351d6cf55259dc4c248eaa19da6"}, - {file = "SQLAlchemy-2.0.30-cp38-cp38-win_amd64.whl", hash = "sha256:7d74336c65705b986d12a7e337ba27ab2b9d819993851b140efdf029248e818e"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8c62fe2480dd61c532ccafdbce9b29dacc126fe8be0d9a927ca3e699b9491a"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2383146973a15435e4717f94c7509982770e3e54974c71f76500a0136f22810b"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8409de825f2c3b62ab15788635ccaec0c881c3f12a8af2b12ae4910a0a9aeef6"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0094c5dc698a5f78d3d1539853e8ecec02516b62b8223c970c86d44e7a80f6c7"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:edc16a50f5e1b7a06a2dcc1f2205b0b961074c123ed17ebda726f376a5ab0953"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f7703c2010355dd28f53deb644a05fc30f796bd8598b43f0ba678878780b6e4c"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win32.whl", hash = "sha256:1f9a727312ff6ad5248a4367358e2cf7e625e98b1028b1d7ab7b806b7d757513"}, - {file = "SQLAlchemy-2.0.30-cp39-cp39-win_amd64.whl", hash = "sha256:a0ef36b28534f2a5771191be6edb44cc2673c7b2edf6deac6562400288664221"}, - {file = "SQLAlchemy-2.0.30-py3-none-any.whl", hash = "sha256:7108d569d3990c71e26a42f60474b4c02c8586c4681af5fd67e51a044fdea86a"}, - {file = "SQLAlchemy-2.0.30.tar.gz", hash = "sha256:2b1708916730f4830bc69d6f49d37f7698b5bd7530aca7f04f785f8849e95255"}, -] - -[package.dependencies] -greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} -typing-extensions = ">=4.6.0" - -[package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] -aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] -aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] -mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] -postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] - -[[package]] -name = "sqlglot" -version = "23.15.8" -description = "An easily customizable SQL parser and transpiler" -optional = false -python-versions = ">=3.7" -files = [ - {file = "sqlglot-23.15.8-py3-none-any.whl", hash = "sha256:e1123f7dda94e1b9b2ab200fb52c12e9ea80d18aac8339e8e73959e7f5b49663"}, - {file = "sqlglot-23.15.8.tar.gz", hash = "sha256:4ca32ece6fd21bb6b42b09927f1fe38da832c6418d7202835313d7abc5d07620"}, -] - -[package.extras] -dev = ["duckdb (>=0.6)", "maturin (>=1.4,<2.0)", "mypy", "pandas", "pandas-stubs", "pdoc", "pre-commit", "pyspark", "python-dateutil", "ruff (==0.4.3)", "types-python-dateutil", "typing-extensions"] -rs = ["sqlglotrs (==0.2.5)"] - -[[package]] -name = "st-pages" -version = "0.4.5" -description = "An experimental version of Streamlit Multi-Page Apps" -optional = false -python-versions = ">=3.8, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*" -files = [ - {file = "st_pages-0.4.5-py3-none-any.whl", hash = "sha256:7cc0c9137bc2a3aba2c7918f76a9b220673b4344762544ebf5c5e56d16a6f360"}, - {file = "st_pages-0.4.5.tar.gz", hash = "sha256:0b95b2ae53e91f9922f2f254b356e1063981b5fcc89a48c4b89011806ccda465"}, -] - -[package.dependencies] -streamlit = ">=1.10.0" - -[[package]] -name = "stack-data" -version = "0.6.3" -description = "Extract data from python stack frames and tracebacks for informative displays" -optional = false -python-versions = "*" -files = [ - {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, - {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, -] - -[package.dependencies] -asttokens = ">=2.1.0" -executing = ">=1.2.0" -pure-eval = "*" - -[package.extras] -tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] - [[package]] name = "starlette" version = "0.36.3" @@ -2926,86 +1711,6 @@ anyio = ">=3.4.0,<5" [package.extras] full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] -[[package]] -name = "streamlit" -version = "1.34.0" -description = "A faster way to build and share data apps" -optional = false -python-versions = "!=3.9.7,>=3.8" -files = [ - {file = "streamlit-1.34.0-py2.py3-none-any.whl", hash = "sha256:411183cf7f525e468eb256b343c914782d11cd894b5e30a4ab3bb1d54e3ae339"}, - {file = "streamlit-1.34.0.tar.gz", hash = "sha256:135a3b79a686b3132b73f204450ad6e889de04f3349d692925e09f0e21e74b52"}, -] - -[package.dependencies] -altair = ">=4.0,<6" -blinker = ">=1.0.0,<2" -cachetools = ">=4.0,<6" -click = ">=7.0,<9" -gitpython = ">=3.0.7,<3.1.19 || >3.1.19,<4" -numpy = ">=1.19.3,<2" -packaging = ">=16.8,<25" -pandas = ">=1.3.0,<3" -pillow = ">=7.1.0,<11" -protobuf = ">=3.20,<5" -pyarrow = ">=7.0" -pydeck = ">=0.8.0b4,<1" -requests = ">=2.27,<3" -rich = ">=10.14.0,<14" -tenacity = ">=8.1.0,<9" -toml = ">=0.10.1,<2" -tornado = ">=6.0.3,<7" -typing-extensions = ">=4.3.0,<5" -watchdog = {version = ">=2.1.5", markers = "platform_system != \"Darwin\""} - -[package.extras] -snowflake = ["snowflake-connector-python (>=2.8.0)", "snowflake-snowpark-python (>=0.9.0)"] - -[[package]] -name = "streamlit-aggrid" -version = "0.3.4.post3" -description = "Streamlit component implementation of ag-grid" -optional = false -python-versions = ">=3.8" -files = [ - {file = "streamlit-aggrid-0.3.4.post3.tar.gz", hash = "sha256:0cb9332199e7735289a673efabc913e1a3466cc188bc025bec2c50c32ab1989a"}, - {file = "streamlit_aggrid-0.3.4.post3-py3-none-any.whl", hash = "sha256:b909117eb90cfdb855b1c74e694e9ec97554c101baaafb7339eaf885d1f4e49c"}, -] - -[package.dependencies] -pandas = ">=1.2" -python-decouple = ">=3.6,<4.0" -streamlit = ">=0.87.0" - -[[package]] -name = "streamlit-card" -version = "1.0.2" -description = "A streamlit component, to make UI cards" -optional = false -python-versions = ">=3.8" -files = [ - {file = "streamlit_card-1.0.2-py3-none-any.whl", hash = "sha256:f5d01ce57d6481eb3ba44e504146f56a7b82907d6700f0c19266ed6381a9c58f"}, - {file = "streamlit_card-1.0.2.tar.gz", hash = "sha256:8001cd5edd8a6e2db36ee81f37dc645f08f78c21a2ba968403176c68b4f33cb1"}, -] - -[package.dependencies] -streamlit = ">=0.63" - -[[package]] -name = "tenacity" -version = "8.3.0" -description = "Retry code until it succeeds" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tenacity-8.3.0-py3-none-any.whl", hash = "sha256:3649f6443dbc0d9b01b9d8020a9c4ec7a1ff5f6f3c6c8a036ef371f573fe9185"}, - {file = "tenacity-8.3.0.tar.gz", hash = "sha256:953d4e6ad24357bceffbc9707bc74349aca9d245f68eb65419cf0c249a1949a2"}, -] - -[package.extras] -doc = ["reno", "sphinx"] -test = ["pytest", "tornado (>=4.5)", "typeguard"] - [[package]] name = "text-unidecode" version = "1.3" @@ -3017,63 +1722,6 @@ files = [ {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, ] -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -files = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] - -[[package]] -name = "toolz" -version = "0.12.1" -description = "List processing tools and functional utilities" -optional = false -python-versions = ">=3.7" -files = [ - {file = "toolz-0.12.1-py3-none-any.whl", hash = "sha256:d22731364c07d72eea0a0ad45bafb2c2937ab6fd38a3507bf55eae8744aa7d85"}, - {file = "toolz-0.12.1.tar.gz", hash = "sha256:ecca342664893f177a13dac0e6b41cbd8ac25a358e5f215316d43e2100224f4d"}, -] - -[[package]] -name = "tornado" -version = "6.4" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -optional = false -python-versions = ">= 3.8" -files = [ - {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, - {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, - {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, - {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, - {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, - {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, - {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, -] - -[[package]] -name = "traitlets" -version = "5.14.3" -description = "Traitlets Python configuration system" -optional = false -python-versions = ">=3.8" -files = [ - {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"}, - {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"}, -] - -[package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<8.2)", "pytest-mock", "pytest-mypy-testing"] - [[package]] name = "typer" version = "0.9.0" @@ -3095,26 +1743,15 @@ dev = ["autoflake (>=1.3.1,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "pre-commit (>=2 doc = ["cairosvg (>=2.5.2,<3.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=8.1.4,<9.0.0)", "pillow (>=9.3.0,<10.0.0)"] test = ["black (>=22.3.0,<23.0.0)", "coverage (>=6.2,<7.0)", "isort (>=5.0.6,<6.0.0)", "mypy (==0.910)", "pytest (>=4.4.0,<8.0.0)", "pytest-cov (>=2.10.0,<5.0.0)", "pytest-sugar (>=0.9.4,<0.10.0)", "pytest-xdist (>=1.32.0,<4.0.0)", "rich (>=10.11.0,<14.0.0)", "shellingham (>=1.3.0,<2.0.0)"] -[[package]] -name = "types-python-dateutil" -version = "2.9.0.20240316" -description = "Typing stubs for python-dateutil" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-python-dateutil-2.9.0.20240316.tar.gz", hash = "sha256:5d2f2e240b86905e40944dd787db6da9263f0deabef1076ddaed797351ec0202"}, - {file = "types_python_dateutil-2.9.0.20240316-py3-none-any.whl", hash = "sha256:6b8cb66d960771ce5ff974e9dd45e38facb81718cc1e208b10b1baccbfdbee3b"}, -] - [[package]] name = "typing-extensions" -version = "4.11.0" +version = "4.12.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.11.0-py3-none-any.whl", hash = "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a"}, - {file = "typing_extensions-4.11.0.tar.gz", hash = "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0"}, + {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, + {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, ] [[package]] @@ -3130,13 +1767,13 @@ files = [ [[package]] name = "urllib3" -version = "2.2.1" +version = "2.2.2" description = "HTTP library with thread-safe connection pooling, file post, and more." optional = false python-versions = ">=3.8" files = [ - {file = "urllib3-2.2.1-py3-none-any.whl", hash = "sha256:450b20ec296a467077128bff42b73080516e71b56ff59a60a02bef2232c4fa9d"}, - {file = "urllib3-2.2.1.tar.gz", hash = "sha256:d0570876c61ab9e520d776c38acbbb5b05a776d3f9ff98a5c8fd5162a444cf19"}, + {file = "urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472"}, + {file = "urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168"}, ] [package.extras] @@ -3147,13 +1784,13 @@ zstd = ["zstandard (>=0.18.0)"] [[package]] name = "uvicorn" -version = "0.29.0" +version = "0.30.1" description = "The lightning-fast ASGI server." optional = false python-versions = ">=3.8" files = [ - {file = "uvicorn-0.29.0-py3-none-any.whl", hash = "sha256:2c2aac7ff4f4365c206fd773a39bf4ebd1047c238f8b8268ad996829323473de"}, - {file = "uvicorn-0.29.0.tar.gz", hash = "sha256:6a69214c0b6a087462412670b3ef21224fa48cae0e452b5883e8e8bdfdd11dd0"}, + {file = "uvicorn-0.30.1-py3-none-any.whl", hash = "sha256:cd17daa7f3b9d7a24de3617820e634d0933b69eed8e33a516071174427238c81"}, + {file = "uvicorn-0.30.1.tar.gz", hash = "sha256:d46cd8e0fd80240baffbcd9ec1012a712938754afcf81bce56c024c1656aece8"}, ] [package.dependencies] @@ -3228,163 +1865,93 @@ files = [ [package.dependencies] pscript = ">=0.7.0,<0.8.0" -[[package]] -name = "wasmtime" -version = "12.0.0" -description = "A WebAssembly runtime powered by Wasmtime" -optional = false -python-versions = ">=3.6" -files = [ - {file = "wasmtime-12.0.0-py3-none-any.whl", hash = "sha256:1fee5ac11726cad1f69611779e44ffcb60e912479d1a3c7c77099c3c2f068c36"}, - {file = "wasmtime-12.0.0-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:d5e284b37204535a2817f3563102ce8a41451a5f4203db059b051640bda8bcb8"}, - {file = "wasmtime-12.0.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2a931214e62aa3d23c61b5f5d2cc47ce10d708f4d8d02e12ea87004c0837e650"}, - {file = "wasmtime-12.0.0-py3-none-manylinux1_x86_64.whl", hash = "sha256:fa5372d8f3e2bfcaaf7cfffb0d5efc640351889d7aed6d34711f32a85fe9b5ff"}, - {file = "wasmtime-12.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:c72d1f9b253b97aff19375d6980e3e6380929424fe07b56364413bf54fd80049"}, - {file = "wasmtime-12.0.0-py3-none-win_amd64.whl", hash = "sha256:7eee12e6bb72123b3beec757d6b48f90b09a1097b1c6dadff7013ffbc46df2fe"}, -] - -[package.extras] -testing = ["coverage", "flake8 (==4.0.1)", "pycparser", "pytest", "pytest-flake8", "pytest-mypy"] - -[[package]] -name = "watchdog" -version = "4.0.0" -description = "Filesystem events monitoring" -optional = false -python-versions = ">=3.8" -files = [ - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, - {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, - {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, - {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, - {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, - {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, - {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, - {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, - {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, - {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, - {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, - {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, - {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, - {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, -] - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - [[package]] name = "watchfiles" -version = "0.21.0" +version = "0.22.0" description = "Simple, modern and high performance file watching and code reload in python." optional = false python-versions = ">=3.8" files = [ - {file = "watchfiles-0.21.0-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:27b4035013f1ea49c6c0b42d983133b136637a527e48c132d368eb19bf1ac6aa"}, - {file = "watchfiles-0.21.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c81818595eff6e92535ff32825f31c116f867f64ff8cdf6562cd1d6b2e1e8f3e"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6c107ea3cf2bd07199d66f156e3ea756d1b84dfd43b542b2d870b77868c98c03"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d9ac347653ebd95839a7c607608703b20bc07e577e870d824fa4801bc1cb124"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5eb86c6acb498208e7663ca22dbe68ca2cf42ab5bf1c776670a50919a56e64ab"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d0f32ebfaa9c6011f8454994f86108c2eb9c79b8b7de00b36d558cadcedaa3d"}, - {file = "watchfiles-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6d45d9b699ecbac6c7bd8e0a2609767491540403610962968d258fd6405c17c"}, - {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:aff06b2cac3ef4616e26ba17a9c250c1fe9dd8a5d907d0193f84c499b1b6e6a9"}, - {file = "watchfiles-0.21.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d9792dff410f266051025ecfaa927078b94cc7478954b06796a9756ccc7e14a9"}, - {file = "watchfiles-0.21.0-cp310-none-win32.whl", hash = "sha256:214cee7f9e09150d4fb42e24919a1e74d8c9b8a9306ed1474ecaddcd5479c293"}, - {file = "watchfiles-0.21.0-cp310-none-win_amd64.whl", hash = "sha256:1ad7247d79f9f55bb25ab1778fd47f32d70cf36053941f07de0b7c4e96b5d235"}, - {file = "watchfiles-0.21.0-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:668c265d90de8ae914f860d3eeb164534ba2e836811f91fecc7050416ee70aa7"}, - {file = "watchfiles-0.21.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3a23092a992e61c3a6a70f350a56db7197242f3490da9c87b500f389b2d01eef"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e7941bbcfdded9c26b0bf720cb7e6fd803d95a55d2c14b4bd1f6a2772230c586"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:11cd0c3100e2233e9c53106265da31d574355c288e15259c0d40a4405cbae317"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d78f30cbe8b2ce770160d3c08cff01b2ae9306fe66ce899b73f0409dc1846c1b"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6674b00b9756b0af620aa2a3346b01f8e2a3dc729d25617e1b89cf6af4a54eb1"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d"}, - {file = "watchfiles-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c873345680c1b87f1e09e0eaf8cf6c891b9851d8b4d3645e7efe2ec20a20cc7"}, - {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:49f56e6ecc2503e7dbe233fa328b2be1a7797d31548e7a193237dcdf1ad0eee0"}, - {file = "watchfiles-0.21.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:02d91cbac553a3ad141db016e3350b03184deaafeba09b9d6439826ee594b365"}, - {file = "watchfiles-0.21.0-cp311-none-win32.whl", hash = "sha256:ebe684d7d26239e23d102a2bad2a358dedf18e462e8808778703427d1f584400"}, - {file = "watchfiles-0.21.0-cp311-none-win_amd64.whl", hash = "sha256:4566006aa44cb0d21b8ab53baf4b9c667a0ed23efe4aaad8c227bfba0bf15cbe"}, - {file = "watchfiles-0.21.0-cp311-none-win_arm64.whl", hash = "sha256:c550a56bf209a3d987d5a975cdf2063b3389a5d16caf29db4bdddeae49f22078"}, - {file = "watchfiles-0.21.0-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:51ddac60b96a42c15d24fbdc7a4bfcd02b5a29c047b7f8bf63d3f6f5a860949a"}, - {file = "watchfiles-0.21.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:511f0b034120cd1989932bf1e9081aa9fb00f1f949fbd2d9cab6264916ae89b1"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb92d49dbb95ec7a07511bc9efb0faff8fe24ef3805662b8d6808ba8409a71a"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f92944efc564867bbf841c823c8b71bb0be75e06b8ce45c084b46411475a915"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:642d66b75eda909fd1112d35c53816d59789a4b38c141a96d62f50a3ef9b3360"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d23bcd6c8eaa6324fe109d8cac01b41fe9a54b8c498af9ce464c1aeeb99903d6"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18d5b4da8cf3e41895b34e8c37d13c9ed294954907929aacd95153508d5d89d7"}, - {file = "watchfiles-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b8d1eae0f65441963d805f766c7e9cd092f91e0c600c820c764a4ff71a0764c"}, - {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1fd9a5205139f3c6bb60d11f6072e0552f0a20b712c85f43d42342d162be1235"}, - {file = "watchfiles-0.21.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a1e3014a625bcf107fbf38eece0e47fa0190e52e45dc6eee5a8265ddc6dc5ea7"}, - {file = "watchfiles-0.21.0-cp312-none-win32.whl", hash = "sha256:9d09869f2c5a6f2d9df50ce3064b3391d3ecb6dced708ad64467b9e4f2c9bef3"}, - {file = "watchfiles-0.21.0-cp312-none-win_amd64.whl", hash = "sha256:18722b50783b5e30a18a8a5db3006bab146d2b705c92eb9a94f78c72beb94094"}, - {file = "watchfiles-0.21.0-cp312-none-win_arm64.whl", hash = "sha256:a3b9bec9579a15fb3ca2d9878deae789df72f2b0fdaf90ad49ee389cad5edab6"}, - {file = "watchfiles-0.21.0-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:4ea10a29aa5de67de02256a28d1bf53d21322295cb00bd2d57fcd19b850ebd99"}, - {file = "watchfiles-0.21.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:40bca549fdc929b470dd1dbfcb47b3295cb46a6d2c90e50588b0a1b3bd98f429"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9b37a7ba223b2f26122c148bb8d09a9ff312afca998c48c725ff5a0a632145f7"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec8c8900dc5c83650a63dd48c4d1d245343f904c4b64b48798c67a3767d7e165"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ad3fe0a3567c2f0f629d800409cd528cb6251da12e81a1f765e5c5345fd0137"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d353c4cfda586db2a176ce42c88f2fc31ec25e50212650c89fdd0f560ee507b"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:83a696da8922314ff2aec02987eefb03784f473281d740bf9170181829133765"}, - {file = "watchfiles-0.21.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5a03651352fc20975ee2a707cd2d74a386cd303cc688f407296064ad1e6d1562"}, - {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ad692bc7792be8c32918c699638b660c0de078a6cbe464c46e1340dadb94c19"}, - {file = "watchfiles-0.21.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06247538e8253975bdb328e7683f8515ff5ff041f43be6c40bff62d989b7d0b0"}, - {file = "watchfiles-0.21.0-cp38-none-win32.whl", hash = "sha256:9a0aa47f94ea9a0b39dd30850b0adf2e1cd32a8b4f9c7aa443d852aacf9ca214"}, - {file = "watchfiles-0.21.0-cp38-none-win_amd64.whl", hash = "sha256:8d5f400326840934e3507701f9f7269247f7c026d1b6cfd49477d2be0933cfca"}, - {file = "watchfiles-0.21.0-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7f762a1a85a12cc3484f77eee7be87b10f8c50b0b787bb02f4e357403cad0c0e"}, - {file = "watchfiles-0.21.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6e9be3ef84e2bb9710f3f777accce25556f4a71e15d2b73223788d528fcc2052"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4c48a10d17571d1275701e14a601e36959ffada3add8cdbc9e5061a6e3579a5d"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c889025f59884423428c261f212e04d438de865beda0b1e1babab85ef4c0f01"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:66fac0c238ab9a2e72d026b5fb91cb902c146202bbd29a9a1a44e8db7b710b6f"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b4a21f71885aa2744719459951819e7bf5a906a6448a6b2bbce8e9cc9f2c8128"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c9198c989f47898b2c22201756f73249de3748e0fc9de44adaf54a8b259cc0c"}, - {file = "watchfiles-0.21.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8f57c4461cd24fda22493109c45b3980863c58a25b8bec885ca8bea6b8d4b28"}, - {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:853853cbf7bf9408b404754b92512ebe3e3a83587503d766d23e6bf83d092ee6"}, - {file = "watchfiles-0.21.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d5b1dc0e708fad9f92c296ab2f948af403bf201db8fb2eb4c8179db143732e49"}, - {file = "watchfiles-0.21.0-cp39-none-win32.whl", hash = "sha256:59137c0c6826bd56c710d1d2bda81553b5e6b7c84d5a676747d80caf0409ad94"}, - {file = "watchfiles-0.21.0-cp39-none-win_amd64.whl", hash = "sha256:6cb8fdc044909e2078c248986f2fc76f911f72b51ea4a4fbbf472e01d14faa58"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ab03a90b305d2588e8352168e8c5a1520b721d2d367f31e9332c4235b30b8994"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:927c589500f9f41e370b0125c12ac9e7d3a2fd166b89e9ee2828b3dda20bfe6f"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bd467213195e76f838caf2c28cd65e58302d0254e636e7c0fca81efa4a2e62c"}, - {file = "watchfiles-0.21.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:08dca260e85ffae975448e344834d765983237ad6dc308231aa16e7933db763e"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ccceb50c611c433145502735e0370877cced72a6c70fd2410238bcbc7fe51d8"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:57d430f5fb63fea141ab71ca9c064e80de3a20b427ca2febcbfcef70ff0ce895"}, - {file = "watchfiles-0.21.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dd5fad9b9c0dd89904bbdea978ce89a2b692a7ee8a0ce19b940e538c88a809c"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:be6dd5d52b73018b21adc1c5d28ac0c68184a64769052dfeb0c5d9998e7f56a2"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:b3cab0e06143768499384a8a5efb9c4dc53e19382952859e4802f294214f36ec"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c6ed10c2497e5fedadf61e465b3ca12a19f96004c15dcffe4bd442ebadc2d85"}, - {file = "watchfiles-0.21.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43babacef21c519bc6631c5fce2a61eccdfc011b4bcb9047255e9620732c8097"}, - {file = "watchfiles-0.21.0.tar.gz", hash = "sha256:c76c635fabf542bb78524905718c39f736a98e5ab25b23ec6d4abede1a85a6a3"}, + {file = "watchfiles-0.22.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:da1e0a8caebf17976e2ffd00fa15f258e14749db5e014660f53114b676e68538"}, + {file = "watchfiles-0.22.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61af9efa0733dc4ca462347becb82e8ef4945aba5135b1638bfc20fad64d4f0e"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d9188979a58a096b6f8090e816ccc3f255f137a009dd4bbec628e27696d67c1"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2bdadf6b90c099ca079d468f976fd50062905d61fae183f769637cb0f68ba59a"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:067dea90c43bf837d41e72e546196e674f68c23702d3ef80e4e816937b0a3ffd"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bbf8a20266136507abf88b0df2328e6a9a7c7309e8daff124dda3803306a9fdb"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1235c11510ea557fe21be5d0e354bae2c655a8ee6519c94617fe63e05bca4171"}, + {file = "watchfiles-0.22.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2444dc7cb9d8cc5ab88ebe792a8d75709d96eeef47f4c8fccb6df7c7bc5be71"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:c5af2347d17ab0bd59366db8752d9e037982e259cacb2ba06f2c41c08af02c39"}, + {file = "watchfiles-0.22.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9624a68b96c878c10437199d9a8b7d7e542feddda8d5ecff58fdc8e67b460848"}, + {file = "watchfiles-0.22.0-cp310-none-win32.whl", hash = "sha256:4b9f2a128a32a2c273d63eb1fdbf49ad64852fc38d15b34eaa3f7ca2f0d2b797"}, + {file = "watchfiles-0.22.0-cp310-none-win_amd64.whl", hash = "sha256:2627a91e8110b8de2406d8b2474427c86f5a62bf7d9ab3654f541f319ef22bcb"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8c39987a1397a877217be1ac0fb1d8b9f662c6077b90ff3de2c05f235e6a8f96"}, + {file = "watchfiles-0.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a927b3034d0672f62fb2ef7ea3c9fc76d063c4b15ea852d1db2dc75fe2c09696"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052d668a167e9fc345c24203b104c313c86654dd6c0feb4b8a6dfc2462239249"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e45fb0d70dda1623a7045bd00c9e036e6f1f6a85e4ef2c8ae602b1dfadf7550"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c49b76a78c156979759d759339fb62eb0549515acfe4fd18bb151cc07366629c"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c4a65474fd2b4c63e2c18ac67a0c6c66b82f4e73e2e4d940f837ed3d2fd9d4da"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc0cba54f47c660d9fa3218158b8963c517ed23bd9f45fe463f08262a4adae1"}, + {file = "watchfiles-0.22.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94ebe84a035993bb7668f58a0ebf998174fb723a39e4ef9fce95baabb42b787f"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e0f0a874231e2839abbf473256efffe577d6ee2e3bfa5b540479e892e47c172d"}, + {file = "watchfiles-0.22.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:213792c2cd3150b903e6e7884d40660e0bcec4465e00563a5fc03f30ea9c166c"}, + {file = "watchfiles-0.22.0-cp311-none-win32.whl", hash = "sha256:b44b70850f0073b5fcc0b31ede8b4e736860d70e2dbf55701e05d3227a154a67"}, + {file = "watchfiles-0.22.0-cp311-none-win_amd64.whl", hash = "sha256:00f39592cdd124b4ec5ed0b1edfae091567c72c7da1487ae645426d1b0ffcad1"}, + {file = "watchfiles-0.22.0-cp311-none-win_arm64.whl", hash = "sha256:3218a6f908f6a276941422b035b511b6d0d8328edd89a53ae8c65be139073f84"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:c7b978c384e29d6c7372209cbf421d82286a807bbcdeb315427687f8371c340a"}, + {file = "watchfiles-0.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bd4c06100bce70a20c4b81e599e5886cf504c9532951df65ad1133e508bf20be"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:425440e55cd735386ec7925f64d5dde392e69979d4c8459f6bb4e920210407f2"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:68fe0c4d22332d7ce53ad094622b27e67440dacefbaedd29e0794d26e247280c"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a8a31bfd98f846c3c284ba694c6365620b637debdd36e46e1859c897123aa232"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc2e8fe41f3cac0660197d95216c42910c2b7e9c70d48e6d84e22f577d106fc1"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b7cc10261c2786c41d9207193a85c1db1b725cf87936df40972aab466179b6"}, + {file = "watchfiles-0.22.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28585744c931576e535860eaf3f2c0ec7deb68e3b9c5a85ca566d69d36d8dd27"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:00095dd368f73f8f1c3a7982a9801190cc88a2f3582dd395b289294f8975172b"}, + {file = "watchfiles-0.22.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:52fc9b0dbf54d43301a19b236b4a4614e610605f95e8c3f0f65c3a456ffd7d35"}, + {file = "watchfiles-0.22.0-cp312-none-win32.whl", hash = "sha256:581f0a051ba7bafd03e17127735d92f4d286af941dacf94bcf823b101366249e"}, + {file = "watchfiles-0.22.0-cp312-none-win_amd64.whl", hash = "sha256:aec83c3ba24c723eac14225194b862af176d52292d271c98820199110e31141e"}, + {file = "watchfiles-0.22.0-cp312-none-win_arm64.whl", hash = "sha256:c668228833c5619f6618699a2c12be057711b0ea6396aeaece4ded94184304ea"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:d47e9ef1a94cc7a536039e46738e17cce058ac1593b2eccdede8bf72e45f372a"}, + {file = "watchfiles-0.22.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:28f393c1194b6eaadcdd8f941307fc9bbd7eb567995232c830f6aef38e8a6e88"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd64f3a4db121bc161644c9e10a9acdb836853155a108c2446db2f5ae1778c3d"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2abeb79209630da981f8ebca30a2c84b4c3516a214451bfc5f106723c5f45843"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4cc382083afba7918e32d5ef12321421ef43d685b9a67cc452a6e6e18920890e"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d048ad5d25b363ba1d19f92dcf29023988524bee6f9d952130b316c5802069cb"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:103622865599f8082f03af4214eaff90e2426edff5e8522c8f9e93dc17caee13"}, + {file = "watchfiles-0.22.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3e1f3cf81f1f823e7874ae563457828e940d75573c8fbf0ee66818c8b6a9099"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8597b6f9dc410bdafc8bb362dac1cbc9b4684a8310e16b1ff5eee8725d13dcd6"}, + {file = "watchfiles-0.22.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0b04a2cbc30e110303baa6d3ddce8ca3664bc3403be0f0ad513d1843a41c97d1"}, + {file = "watchfiles-0.22.0-cp38-none-win32.whl", hash = "sha256:b610fb5e27825b570554d01cec427b6620ce9bd21ff8ab775fc3a32f28bba63e"}, + {file = "watchfiles-0.22.0-cp38-none-win_amd64.whl", hash = "sha256:fe82d13461418ca5e5a808a9e40f79c1879351fcaeddbede094028e74d836e86"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3973145235a38f73c61474d56ad6199124e7488822f3a4fc97c72009751ae3b0"}, + {file = "watchfiles-0.22.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:280a4afbc607cdfc9571b9904b03a478fc9f08bbeec382d648181c695648202f"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a0d883351a34c01bd53cfa75cd0292e3f7e268bacf2f9e33af4ecede7e21d1d"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9165bcab15f2b6d90eedc5c20a7f8a03156b3773e5fb06a790b54ccecdb73385"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc1b9b56f051209be458b87edb6856a449ad3f803315d87b2da4c93b43a6fe72"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dc1fc25a1dedf2dd952909c8e5cb210791e5f2d9bc5e0e8ebc28dd42fed7562"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc92d2d2706d2b862ce0568b24987eba51e17e14b79a1abcd2edc39e48e743c8"}, + {file = "watchfiles-0.22.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97b94e14b88409c58cdf4a8eaf0e67dfd3ece7e9ce7140ea6ff48b0407a593ec"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:96eec15e5ea7c0b6eb5bfffe990fc7c6bd833acf7e26704eb18387fb2f5fd087"}, + {file = "watchfiles-0.22.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:28324d6b28bcb8d7c1041648d7b63be07a16db5510bea923fc80b91a2a6cbed6"}, + {file = "watchfiles-0.22.0-cp39-none-win32.whl", hash = "sha256:8c3e3675e6e39dc59b8fe5c914a19d30029e36e9f99468dddffd432d8a7b1c93"}, + {file = "watchfiles-0.22.0-cp39-none-win_amd64.whl", hash = "sha256:25c817ff2a86bc3de3ed2df1703e3d24ce03479b27bb4527c57e722f8554d971"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:b810a2c7878cbdecca12feae2c2ae8af59bea016a78bc353c184fa1e09f76b68"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f7e1f9c5d1160d03b93fc4b68a0aeb82fe25563e12fbcdc8507f8434ab6f823c"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:030bc4e68d14bcad2294ff68c1ed87215fbd9a10d9dea74e7cfe8a17869785ab"}, + {file = "watchfiles-0.22.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ace7d060432acde5532e26863e897ee684780337afb775107c0a90ae8dbccfd2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5834e1f8b71476a26df97d121c0c0ed3549d869124ed2433e02491553cb468c2"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:0bc3b2f93a140df6806c8467c7f51ed5e55a931b031b5c2d7ff6132292e803d6"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8fdebb655bb1ba0122402352b0a4254812717a017d2dc49372a1d47e24073795"}, + {file = "watchfiles-0.22.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c8e0aa0e8cc2a43561e0184c0513e291ca891db13a269d8d47cb9841ced7c71"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2f350cbaa4bb812314af5dab0eb8d538481e2e2279472890864547f3fe2281ed"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7a74436c415843af2a769b36bf043b6ccbc0f8d784814ba3d42fc961cdb0a9dc"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00ad0bcd399503a84cc688590cdffbe7a991691314dde5b57b3ed50a41319a31"}, + {file = "watchfiles-0.22.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72a44e9481afc7a5ee3291b09c419abab93b7e9c306c9ef9108cb76728ca58d2"}, + {file = "watchfiles-0.22.0.tar.gz", hash = "sha256:988e981aaab4f3955209e7e28c7794acdb690be1efa7f16f8ea5aba7ffdadacb"}, ] [package.dependencies] anyio = ">=3.0.0" -[[package]] -name = "wcwidth" -version = "0.2.13" -description = "Measures the displayed width of unicode strings in a terminal" -optional = false -python-versions = "*" -files = [ - {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, - {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, -] - [[package]] name = "websockets" version = "12.0" @@ -3466,17 +2033,6 @@ files = [ {file = "websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b"}, ] -[[package]] -name = "widgetsnbextension" -version = "4.0.10" -description = "Jupyter interactive widgets for Jupyter Notebook" -optional = false -python-versions = ">=3.7" -files = [ - {file = "widgetsnbextension-4.0.10-py3-none-any.whl", hash = "sha256:d37c3724ec32d8c48400a435ecfa7d3e259995201fbefa37163124a9fcb393cc"}, - {file = "widgetsnbextension-4.0.10.tar.gz", hash = "sha256:64196c5ff3b9a9183a8e699a4227fb0b7002f252c814098e66c4d1cd0644688f"}, -] - [[package]] name = "wsproto" version = "1.2.0" @@ -3597,4 +2153,4 @@ multidict = ">=4.0" [metadata] lock-version = "2.0" python-versions = "^3.11" -content-hash = "01a8a1407af6833d2985be45427d07be2ba86b3ef344ee3f82214538c3ecde84" +content-hash = "aae5db2a78674fa5f3c6e3b65137ed51bd3945dc28af20e853475e09ea0f4582" diff --git a/pyproject.toml b/pyproject.toml index c884709c..d46e443d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ boto3 = "^1.33.13" nicegui = "1.4.24" directory-tree = "^0.0.4" python-slugify = "^8.0.4" +pandas = "^2.2.2" [tool.poetry.group.dev.dependencies] From 20161f06f84288e3f43e75d2bea4efdc62c34969 Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Sun, 30 Jun 2024 17:50:43 +0200 Subject: [PATCH 10/28] feat(run.py): add log dir as volume on docker run that way the log will be visible right away in the file system if if the docker run command fails at some point this seems to be essential for long running container and also in cases of ephemeral containers when an error occurs --- odtp/run.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/odtp/run.py b/odtp/run.py index 90aa0b90..0cbba5c8 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -12,6 +12,7 @@ REPO_DIR = "repository" INPUT_DIR = "odtp-input" OUTPUT_DIR = "odtp-output" +LOG_DIR = "odtp-logs" log = logging.getLogger(__name__) @@ -33,6 +34,7 @@ def __init__(self, repo_url="", commit_hash="", image_name="", project_folder="" self.dockerfile_path = os.path.join(self.project_folder, REPO_DIR) self.docker_image_name = image_name self.input_volume = os.path.join(self.project_folder, INPUT_DIR) + self.log_volume = os.path.join(self.project_folder, LOG_DIR) self.output_volume = os.path.join(self.project_folder, OUTPUT_DIR) def prepare_component(self): @@ -47,7 +49,8 @@ def _create_project_folder_structure(self): os.makedirs(self.repository_path, exist_ok=True) os.makedirs(self.input_volume, exist_ok=True) os.makedirs(self.output_volume, exist_ok=True) - + os.makedirs(self.log_volume, exist_ok=True) + def _check_project_folder_prepared(self): log.debug(f"VALIDATION: check project folder structure: {self.project_folder}") """check whether the project folder is prepared with the expected @@ -57,7 +60,7 @@ def _check_project_folder_prepared(self): for entry in entries: if entry.is_dir(): subdirs.append(entry.name) - if set(subdirs) != set(REPO_DIR, INPUT_DIR, OUTPUT_DIR): + if set(subdirs) != set(REPO_DIR, INPUT_DIR, OUTPUT_DIR, LOG_DIR): raise OdtpRunSetupException( f"""project folder {self.project_folder} does not have expected directory structure with {REPO_DIR}, {INPUT_DIR}, {OUTPUT_DIR}""" @@ -186,6 +189,7 @@ def run_component(self, parameters, secrets, ports, instance_name, step_id=None, docker_run_command = ["docker", "run", "--rm", "-it", "--name", instance_name, "--network", "odtp_odtp-network", "--volume", f"{os.path.abspath(self.input_volume)}:/odtp/odtp-input", + "--volume", f"{os.path.abspath(self.log_volume)}:/odtp/odtp-logs", "--volume", f"{os.path.abspath(self.output_volume)}:/odtp/odtp-output"] + env_args + ports_args + secrets_args + [self.docker_image_name] command_string = ' '.join(docker_run_command) From c75ae0ddefa5859d6a4079b42706abf88b3c6974 Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:02:27 +0200 Subject: [PATCH 11/28] feat(cli/execution.py): add log streaming command simplify the output and log streaming command: both just need the project path --- odtp/cli/execution.py | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index d55daf02..29f72c9b 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -9,8 +9,7 @@ import odtp.helpers.parse as odtp_parse from odtp.workflow import WorkflowManager from directory_tree import display_tree -import odtp.helpers.environment as odtp_env -from nicegui import ui +import os app = typer.Typer() @@ -92,9 +91,6 @@ def run( @app.command() def output( - execution_id: str = typer.Option( - ..., "--execution-id", help="Specify the ID of the execution" - ), project_path: str = typer.Option( ..., "--project-path", help="Specify the path for the execution" ), @@ -106,5 +102,18 @@ def output( raise typer.Abort() +@app.command() +def logs( + project_path: str = typer.Option( + ..., "--project-path", help="Specify the path for the execution" + ), +): + try: + os.system(f"tail -f {project_path}/*/odtp-logs/*") + except Exception as e: + print(f"ERROR: Streaming logs failed: {e}") + raise typer.Abort() + + if __name__ == "__main__": app() From f5f4ca5a889da9330569bc6768c09f0371d2b92b Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Sun, 30 Jun 2024 18:19:51 +0200 Subject: [PATCH 12/28] feat(dashboard/run page): simplify workflow and provide log access simplify the workflow and disable buttons after selection or when proceesing is not ready submit run and then offer a button to view log files --- odtp/dashboard/page_run/folder.py | 129 ++++++---------------- odtp/dashboard/page_run/helpers.py | 98 +++++++++++++++-- odtp/dashboard/page_run/main.py | 24 ++--- odtp/dashboard/page_run/run.py | 160 ++++++++-------------------- odtp/dashboard/page_run/secrets.py | 5 +- odtp/dashboard/page_run/workarea.py | 12 ++- 6 files changed, 191 insertions(+), 237 deletions(-) diff --git a/odtp/dashboard/page_run/folder.py b/odtp/dashboard/page_run/folder.py index 114eb771..bf2e3219 100644 --- a/odtp/dashboard/page_run/folder.py +++ b/odtp/dashboard/page_run/folder.py @@ -12,91 +12,41 @@ import odtp.dashboard.page_run.helpers as rh from odtp.dashboard.utils.file_picker import local_file_picker -FOLDER_NOT_SET = 0 -FOLDER_DOES_NOT_MATCH = 1 -FOLDER_EMPTY = 2 -FOLDER_PREPARED = 3 -FOLDER_HAS_OUTPUT = 4 - -FOLDER_STATUS = { - "not_set" - "no_match", - "empty", - "prepared", - "output", -} - log = logging.getLogger(__name__) -def ui_prepare_folder(dialog, result, workdir, current_run, folder_status): +def ui_prepare_folder(workdir, current_run, folder_status, project_path): stepper = current_run.get("stepper") if stepper and rh.STEPPERS.index(stepper) != rh.STEPPER_SELECT_FOLDER: return - project_path = current_run.get("project_path") - execution = current_run.get("execution") if project_path: - with ui.row().classes("w-full"): - ui.markdown( - f""" - **project path**: {project_path} - """ - ) - with ui.row(): - if folder_status == FOLDER_EMPTY: - ui.icon("check").classes("text-teal text-lg") - ui.label("Project folder for the execution run has been selected").classes("text-teal") - elif folder_status == FOLDER_NOT_SET: - ui.icon("clear").classes("text-red text-lg") - ui.label("Project folder missing: please select one").classes("text-red") - elif folder_status == FOLDER_DOES_NOT_MATCH: - ui.icon("clear").classes("text-red text-lg") - ui.label("The project folder structure does not match the steps of the execution: choose an empty project folder or create a new project folder").classes("text-red") - elif folder_status == FOLDER_PREPARED: - ui.icon("check").classes("text-teal text-lg") - ui.label("The execution has been prepared").classes("text-teal") - elif folder_status == FOLDER_HAS_OUTPUT: - ui.icon("check").classes("text-teal text-lg") - ui.label("The execution has been run").classes("text-teal") - folder_matches = folder_status in [ - FOLDER_EMPTY, - FOLDER_HAS_OUTPUT, - FOLDER_PREPARED, - ] - if folder_matches: - from odtp.dashboard.page_run.run import build_command - cli_output_command = build_command( - cmd="output", - execution_id=execution["execution_id"], - project_path=project_path, - ) - else: - cli_output_command = None - with ui.row().classes("w-full flex items-center"): - project_folder_input = ui.input( - value=slugify(execution["title"]), - label="Project folder name", - placeholder="execution", - validation={ - f"Please provide a folder name does not yet exist in the working directory": lambda value: validators.validate_folder_does_not_exist( - value, workdir + ui.label(project_path) + rh.ui_display_folder_status(folder_status) + if not project_path: + execution = current_run.get("execution") + preset_value = slugify(execution["title"]) + if not project_path: + with ui.row().classes("w-full flex items-center"): + project_folder_input = ui.input( + value=preset_value, + label="Project folder name", + placeholder="execution", + validation={ + f"Project folder already exists and is not empty": lambda value: validators.validate_folder_does_not_exist( + value, workdir + ) + }, ) - }, - ) - ui.button( - "Create new project folder", - on_click=lambda: create_folder(workdir, project_folder_input, current_run), - icon="add", - ).props("flat ") - with ui.row().classes("w-full"): - from odtp.dashboard.page_run.run import run_command - if cli_output_command: - ui.button( - "Show project folder", - on_click=lambda: run_command(cli_output_command, dialog, result), - icon="info", - ).props("no-caps") - rh.ui_next_back(current_run) + ui.button( + "Create new project folder", + on_click=lambda: create_folder(workdir, project_folder_input, current_run), + icon="add", + ).props("flat ") + if folder_status >= rh.FOLDER_EMPTY: + ready_for_next = True + else: + ready_for_next = False + rh.ui_next_back(current_run, ready_for_next) async def pick_folder(workdir, current_run) -> None: @@ -122,6 +72,13 @@ async def pick_folder(workdir, current_run) -> None: def create_folder(workdir, folder_name_input, current_run): + if ( + not folder_name_input.validate() + ): + ui.notify( + "Project folder already exists and is not empty", type="negative" + ) + return try: folder_name = folder_name_input.value project_path = os.path.join(workdir, folder_name) @@ -145,21 +102,3 @@ def create_folder(workdir, folder_name_input, current_run): from odtp.dashboard.page_run.main import ui_workarea, ui_stepper ui_workarea.refresh() ui_stepper.refresh() - - -def get_folder_status(execution_id, project_path): - folder_empty = odtp_env.project_folder_is_empty(project_folder=project_path) - folder_matches_execution = odtp_env.directory_folder_matches_execution( - project_folder=project_path, execution_id=execution_id - ) - folder_has_output = odtp_env.directory_has_output( - execution_id=execution_id, project_folder=project_path - ) - if folder_empty: - return FOLDER_EMPTY - elif folder_matches_execution and not folder_has_output: - return FOLDER_PREPARED - elif folder_matches_execution and folder_has_output: - return FOLDER_HAS_OUTPUT - else: - return FOLDER_DOES_NOT_MATCH diff --git a/odtp/dashboard/page_run/helpers.py b/odtp/dashboard/page_run/helpers.py index ad353e31..b7d135bb 100644 --- a/odtp/dashboard/page_run/helpers.py +++ b/odtp/dashboard/page_run/helpers.py @@ -2,6 +2,7 @@ import logging from nicegui import app, ui +import odtp.helpers.environment as odtp_env import odtp.dashboard.utils.storage as storage import odtp.dashboard.utils.ui_theme as ui_theme @@ -11,18 +12,32 @@ STEPPERS = ( "Display Execution", - "Add Secret Files", "Select Folder", + "Add Secret Files", "Prepare Execution (Build Images)", "Run Execution (Run Containers)", ) STEPPER_DISPLAY_EXECUTION = 0 -STEPPER_ADD_SECRETS = 1 -STEPPER_SELECT_FOLDER = 2 +STEPPER_SELECT_FOLDER = 1 +STEPPER_ADD_SECRETS = 2 STEPPER_PREPARE_EXECUTION = 3 STEPPER_RUN_EXECUTION = 4 +FOLDER_NOT_SET = 0 +FOLDER_DOES_NOT_MATCH = 1 +FOLDER_EMPTY = 2 +FOLDER_PREPARED = 3 +FOLDER_HAS_OUTPUT = 4 + +FOLDER_STATUS = { + "not_set" + "no_match", + "empty", + "prepared", + "output", +} + def execution_run_init(digital_twin, execution): step_count = len(execution["steps"]) @@ -45,19 +60,16 @@ def ui_execution_details(current_run): version_tags = execution.get("version_tags") current_ports = execution.get("ports") current_parameters = execution.get("parameters") - with ui.row(): - ui.icon("check").classes("text-teal text-lg") - ui.label("Execution to run is selected").classes("text-teal") ui_theme.ui_execution_display( execution_title=execution_title, version_tags=version_tags, ports=current_ports, parameters=current_parameters, ) - ui_next_back(current_run) + ui_next_back(current_run, ready_for_next=True) -def ui_next_back(current_run, ready_for_next=True): +def ui_next_back(current_run, ready_for_next=False): stepper = current_run.get("stepper") with ui.grid(columns=1).classes("w-full"): with ui.row().classes("w-full"): @@ -109,3 +121,73 @@ def next_step(current_run): else: from odtp.dashboard.page_run.main import ui_stepper ui_stepper.refresh() + +def get_folder_status(execution_id, project_path): + if not project_path: + return FOLDER_NOT_SET + folder_empty = odtp_env.project_folder_is_empty(project_folder=project_path) + folder_matches_execution = odtp_env.directory_folder_matches_execution( + project_folder=project_path, execution_id=execution_id + ) + folder_has_output = odtp_env.directory_has_output( + execution_id=execution_id, project_folder=project_path + ) + if folder_empty: + return FOLDER_EMPTY + elif folder_matches_execution and not folder_has_output: + return FOLDER_PREPARED + elif folder_matches_execution and folder_has_output: + return FOLDER_HAS_OUTPUT + else: + return FOLDER_DOES_NOT_MATCH + + +def ui_display_folder_status(folder_status): + with ui.row(): + if folder_status == FOLDER_EMPTY: + ui.icon("check").classes("text-teal text-lg") + ui.label("Project folder for the execution run has been selected").classes("text-teal") + elif folder_status == FOLDER_NOT_SET: + ui.icon("clear").classes("text-red text-lg") + ui.label("Project folder missing: please select one").classes("text-red") + elif folder_status == FOLDER_DOES_NOT_MATCH: + ui.icon("clear").classes("text-red text-lg") + ui.label("The project folder structure does not match the steps of the execution: choose an empty project folder or create a new project folder").classes("text-red") + elif folder_status == FOLDER_PREPARED: + ui.icon("check").classes("text-teal text-lg") + ui.label("Project folder for the execution run has been selected").classes("text-teal") + ui.icon("check").classes("text-teal text-lg") + ui.label("The execution has been prepared").classes("text-teal") + elif folder_status == FOLDER_HAS_OUTPUT: + ui.icon("check").classes("text-teal text-lg") + ui.label("Project folder for the execution run has been selected").classes("text-teal") + ui.icon("check").classes("text-teal text-lg") + ui.label("The execution has been prepared").classes("text-teal") + ui.icon("check").classes("text-teal text-lg") + ui.label("The execution has been run").classes("text-teal") + + +def ui_display_secrets(secrets): + with ui.row(): + if secrets: + ui.icon("check").classes("text-teal text-lg") + ui.label("Secrets have been set").classes("text-teal") + + + +def build_cli_command(cmd, project_path, execution_id=None, secret_files=None): + cli_parameters = [ + f"--project-path {project_path}", + ] + if execution_id: + cli_parameters.append( + f"--execution-id {execution_id}", + ) + if secret_files and [secret_file for secret_file in secret_files]: + secret_files_for_run = ",".join(secret_files) + if secret_files_for_run: + cli_parameters.append( + f"--secrets-files {secret_files_for_run}", + ) + cli_command = f"odtp execution {cmd} {' '.join(cli_parameters)}" + return cli_command diff --git a/odtp/dashboard/page_run/main.py b/odtp/dashboard/page_run/main.py index 07c21bdf..f8690e59 100644 --- a/odtp/dashboard/page_run/main.py +++ b/odtp/dashboard/page_run/main.py @@ -69,13 +69,10 @@ def ui_stepper( stepper = current_run.get("stepper") execution = current_run["execution"] project_path = current_run.get("project_path") - if project_path: - folder_status = folder.get_folder_status( - execution_id=execution["execution_id"], - project_path=project_path, - ) - else: - folder_status = folder.FOLDER_NOT_SET + folder_status = rh.get_folder_status( + execution_id=execution["execution_id"], + project_path=project_path, + ) if ODTP_DASHBOARD_JSON_EDITOR: with ui.expansion("Current Execution Run as JSON"): ui.json_editor( @@ -87,22 +84,21 @@ def ui_stepper( with ui.stepper(value=stepper).props("vertical").classes("w-full") as stepper: with ui.step(rh.STEPPERS[rh.STEPPER_DISPLAY_EXECUTION]): rh.ui_execution_details(current_run) - with ui.step(rh.STEPPERS[rh.STEPPER_ADD_SECRETS]): + with ui.step(rh.STEPPERS[rh.STEPPER_SELECT_FOLDER]): with ui.stepper_navigation(): with ui.row(): - secrets.ui_add_secrets_form( + folder.ui_prepare_folder( current_run=current_run, workdir=workdir, + project_path=project_path, + folder_status=folder_status, ) - with ui.step(rh.STEPPERS[rh.STEPPER_SELECT_FOLDER]): + with ui.step(rh.STEPPERS[rh.STEPPER_ADD_SECRETS]): with ui.stepper_navigation(): with ui.row(): - folder.ui_prepare_folder( - dialog=dialog, - result=result, + secrets.ui_add_secrets_form( current_run=current_run, workdir=workdir, - folder_status=folder_status, ) with ui.step(rh.STEPPERS[rh.STEPPER_PREPARE_EXECUTION]): with ui.stepper_navigation(): diff --git a/odtp/dashboard/page_run/run.py b/odtp/dashboard/page_run/run.py index fdb69991..52425484 100644 --- a/odtp/dashboard/page_run/run.py +++ b/odtp/dashboard/page_run/run.py @@ -25,82 +25,28 @@ def ui_prepare_execution(dialog, result, current_run, folder_status): - create folder structure """ ) - with ui.row().classes("w-full"): - if folder_status == folder.FOLDER_EMPTY: - ui.icon("check").classes("text-teal text-lg") - ui.label("Project folder for the execution run has been selected").classes("text-teal") - elif folder_status == folder.FOLDER_NOT_SET: - ui.icon("clear").classes("text-red text-lg") - ui.label("Project folder missing: please select one").classes("text-red") - elif folder_status == folder.FOLDER_DOES_NOT_MATCH: - ui.icon("clear").classes("text-red text-lg") - ui.label("The project folder structure does not match the steps of the execution: choose an empty project folder or create a new project folder").classes("text-red") - elif folder_status == folder.FOLDER_PREPARED: - ui.icon("check").classes("text-teal text-lg") - ui.label("The execution has been prepared").classes("text-teal") - elif folder_status == folder.FOLDER_HAS_OUTPUT: - ui.icon("check").classes("text-teal text-lg") - ui.label("The execution has been run").classes("text-teal") - folder_matches = folder_status in [ - folder.FOLDER_EMPTY, - folder.FOLDER_HAS_OUTPUT, - folder.FOLDER_PREPARED, - ] - if folder_matches: + if folder_status == rh.FOLDER_PREPARED: + with ui.row().classes("w-full"): + rh.ui_display_folder_status(folder_status) + if folder_status == rh.FOLDER_EMPTY: execution = current_run["execution"] - project_path = current_run["project_path"] - cli_output_command = build_command( - cmd="output", - execution_id=execution["execution_id"], - project_path=project_path, - ) - if folder_status == folder.FOLDER_EMPTY: - cli_prepare_command = build_command( + project_path = current_run["project_path"] + cli_prepare_command = rh.build_cli_command( cmd="prepare", execution_id=execution["execution_id"], project_path=project_path, ) - with ui.grid(columns=1): - if folder_status == folder.FOLDER_EMPTY: - with ui.row().classes("w-full"): - ui.label(cli_prepare_command).classes("font-mono") - with ui.row().classes("w-full"): - ui.button( - "Prepare execution", - on_click=lambda: run_command(cli_prepare_command, dialog, result), - icon="folder", - ).props("no-caps") - if folder_matches: - with ui.row().classes("w-full"): - ui.button( - "Show project folder", - on_click=lambda: run_command(cli_output_command, dialog, result), - icon="info", - ).props("no-caps") - rh.ui_next_back(current_run) - + with ui.grid(columns=1): + with ui.row().classes("w-full"): + ui.label(cli_prepare_command).classes("font-mono") + with ui.row().classes("w-full"): + ui.button( + "Prepare execution", + on_click=lambda: run_command(cli_prepare_command, dialog, result), + icon="folder", + ).props("no-caps") + rh.ui_next_back(current_run, ready_for_next=True) -def build_command(cmd, project_path, execution_id, secret_files=None): - cli_parameters = [ - f"--project-path {project_path}", - f"--execution-id {execution_id}", - ] - if secret_files and [secret_file for secret_file in secret_files]: - secret_files_for_run = ",".join(secret_files) - if secret_files_for_run: - cli_parameters.append( - f"--secrets-files {secret_files_for_run}", - ) - cli_command = f"odtp execution {cmd} {' '.join(cli_parameters)}" - return cli_command - - -def get_docker_command(execution_id): - cli_parameters = [ - f"--execution-id {execution_id}", - ] - cli_command = f"odtp execution docker_container {' '.join(cli_parameters)}" - return cli_command def ui_run_execution(dialog, result, current_run, folder_status): stepper = current_run.get("stepper") @@ -114,70 +60,54 @@ def ui_run_execution(dialog, result, current_run, folder_status): - Run docker images as containers - write output """ - ) - msg = "" - if folder_status == folder.FOLDER_DOES_NOT_MATCH: - msg = """The project folder structure does not match the steps of the execution: - choose an empty project folder and prepare the execution before you can run it.""" - text_color = "text-red" - elif folder_status == folder.FOLDER_NOT_SET: - msg = """The project folder has not been set: - Select an empty project folder and prepare the execution before you can run it.""" - text_color = "text-red" - elif folder_status == folder.FOLDER_EMPTY: - msg = """The project folder is empty: - Prepare the execution before you can run it.""" - text_color = "text-red" - if msg: - ui.label(msg).classes(text_color) - rh.ui_next_back(current_run, ready_for_next=False) - return - if folder_status == folder.FOLDER_HAS_OUTPUT: - msg = """The execution has already been run and the project folder has output.""" - text_color = "text-teal" - else: - msg = """The execution is ready to run.""" - text_color = "text-teal" - ui.label(msg).classes(text_color) + ) execution = current_run["execution"] project_path = current_run["project_path"] secret_files = current_run["secret_files"] - if folder_status != folder.FOLDER_HAS_OUTPUT: - cli_run_command = build_command( + ui.label(f"folder status {folder_status}") + if folder_status >= rh.FOLDER_PREPARED: + cli_run_command = rh.build_cli_command( cmd="run", secret_files=secret_files, execution_id=execution["execution_id"], project_path=project_path, ) + cli_log_command = rh.build_cli_command( + cmd="logs", + project_path=project_path, + ) with ui.row().classes("w-full"): ui.label(cli_run_command).classes("font-mono") - with ui.row().classes("w-full"): - ui.icon("warning").classes("text-lg text-yellow") - ui.label( - """It can take a while until you see output in this step: - loading means just that the job is still running.""" - ) with ui.row().classes("w-full"): ui.button( "Run execution", - on_click=lambda: run_command(cli_run_command, dialog, result), + on_click=lambda: submit_command(cli_run_command), icon="rocket", ).props("no-caps") - else: - cli_output_command = build_command( - cmd="output", - execution_id=execution["execution_id"], - project_path=project_path, - ) with ui.row().classes("w-full"): ui.button( - "Show folder with output", - on_click=lambda: run_command(cli_output_command, dialog, result), + "show logs", + on_click=lambda: run_command(cli_log_command, dialog, result), icon="info", ).props("no-caps") rh.ui_next_back(current_run, ready_for_next=False) +async def submit_command(command): + try: + log.info(command) + log.info(shlex.split(command, posix="win" not in sys.platform.lower())) + process = await asyncio.create_subprocess_exec( + *shlex.split(command, posix="win" not in sys.platform.lower()), + stdout=asyncio.subprocess.PIPE, + stderr=asyncio.subprocess.STDOUT, + cwd=os.path.dirname(os.path.abspath(__file__)), + ) + ui.notify(f"{command} has been submitted as {process}. Click on 'Show logs to view the progress", type="positive") + except Exception as e: + log.exception(f"run command failed with Exception {e}") + + async def run_command(command: str, dialog, result) -> None: """Run a command in the background and display the output in the pre-created dialog. This function has been copied from nicegui examples. @@ -185,8 +115,8 @@ async def run_command(command: str, dialog, result) -> None: try: dialog.open() result.content = "... loading" - # NOTE replace with machine-independent Python path (#1240) - command = command.replace("python3", sys.executable) + log.info(command) + log.info(shlex.split(command, posix="win" not in sys.platform.lower())) process = await asyncio.create_subprocess_exec( *shlex.split(command, posix="win" not in sys.platform.lower()), stdout=asyncio.subprocess.PIPE, @@ -196,7 +126,7 @@ async def run_command(command: str, dialog, result) -> None: # NOTE we need to read the output in chunks, otherwise the process will block output = "" while True: - new = await process.stdout.read(4096) + new = await process.stdout.read(100000) if not new: break output += new.decode() diff --git a/odtp/dashboard/page_run/secrets.py b/odtp/dashboard/page_run/secrets.py index 45afdd19..6dcf8941 100644 --- a/odtp/dashboard/page_run/secrets.py +++ b/odtp/dashboard/page_run/secrets.py @@ -21,8 +21,7 @@ def ui_add_secrets_form(current_run, workdir): if not version_tags: return with ui.row(): - ui.icon("check").classes("text-teal text-lg") - ui.label("Adding Secrets files is an optional step").classes("text-teal") + ui.label("Adding Secrets files is an optional step") with ui.grid(columns=2).classes("flex items-center w-full"): for j, version_tag in enumerate(version_tags): secret_file = current_run["secret_files"][j] @@ -52,7 +51,7 @@ def ui_add_secrets_form(current_run, workdir): on_click=lambda: remove_secrets_files(current_run), icon="clear", ).props("flat") - rh.ui_next_back(current_run) + rh.ui_next_back(current_run, ready_for_next=True) async def pick_secrets_file(step_nr, workdir, current_run) -> None: diff --git a/odtp/dashboard/page_run/workarea.py b/odtp/dashboard/page_run/workarea.py index 139f0023..c189b61e 100644 --- a/odtp/dashboard/page_run/workarea.py +++ b/odtp/dashboard/page_run/workarea.py @@ -2,6 +2,7 @@ import odtp.dashboard.utils.storage as storage import odtp.dashboard.utils.ui_theme as ui_theme +import odtp.dashboard.page_run.helpers as rh def ui_workarea_layout(current_user, workdir, current_execution, current_digital_twin): @@ -45,8 +46,13 @@ def ui_workarea_layout(current_user, workdir, current_execution, current_digital secret_files = "" else: ",".join(secret_files) + folder_status = rh.get_folder_status( + execution_id=current_execution["execution_id"], + project_path=project_path, + ) + project_path_display = project_path if not project_path: - project_path = ui_theme.MISSING_VALUE + project_path_display = ui_theme.MISSING_VALUE with ui.grid(columns=2): with ui.column(): ui.markdown( @@ -57,9 +63,11 @@ def ui_workarea_layout(current_user, workdir, current_execution, current_digital - **current execution**: {current_execution.get("title")} - **secret files**: {secret_files} - **work directory**: {workdir} - - **project directory**: {project_path} + - **project directory**: {project_path_display} """ ) + rh.ui_display_folder_status(folder_status) + rh.ui_display_secrets(secret_files) with ui.column(): if current_execution: ui.markdown( From 3eb6a23d43e13d6dbbf539b5807ee208546dda99 Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Mon, 1 Jul 2024 07:23:31 +0200 Subject: [PATCH 13/28] fix(logs in cli and gui): logs are seperated by steps logs can only be offered in the gui and cli per step --- odtp/cli/execution.py | 5 ++++- odtp/dashboard/page_run/helpers.py | 6 +++++- odtp/dashboard/page_run/run.py | 31 ++++++++++++++++++++---------- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index 29f72c9b..f510f0d0 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -107,9 +107,12 @@ def logs( project_path: str = typer.Option( ..., "--project-path", help="Specify the path for the execution" ), + step_nr: str = typer.Option( + ..., "--step-nr", help="Specify the step for the execution" + ), ): try: - os.system(f"tail -f {project_path}/*/odtp-logs/*") + os.system(f"tail -f {project_path}/{step_nr}_*/odtp-logs/*") except Exception as e: print(f"ERROR: Streaming logs failed: {e}") raise typer.Abort() diff --git a/odtp/dashboard/page_run/helpers.py b/odtp/dashboard/page_run/helpers.py index b7d135bb..fa3f8524 100644 --- a/odtp/dashboard/page_run/helpers.py +++ b/odtp/dashboard/page_run/helpers.py @@ -175,7 +175,7 @@ def ui_display_secrets(secrets): -def build_cli_command(cmd, project_path, execution_id=None, secret_files=None): +def build_cli_command(cmd, project_path, execution_id=None, secret_files=None, step_nr=None): cli_parameters = [ f"--project-path {project_path}", ] @@ -183,6 +183,10 @@ def build_cli_command(cmd, project_path, execution_id=None, secret_files=None): cli_parameters.append( f"--execution-id {execution_id}", ) + if step_nr: + cli_parameters.append( + f"--step-nr {step_nr}", + ) if secret_files and [secret_file for secret_file in secret_files]: secret_files_for_run = ",".join(secret_files) if secret_files_for_run: diff --git a/odtp/dashboard/page_run/run.py b/odtp/dashboard/page_run/run.py index 52425484..d929ed77 100644 --- a/odtp/dashboard/page_run/run.py +++ b/odtp/dashboard/page_run/run.py @@ -64,7 +64,6 @@ def ui_run_execution(dialog, result, current_run, folder_status): execution = current_run["execution"] project_path = current_run["project_path"] secret_files = current_run["secret_files"] - ui.label(f"folder status {folder_status}") if folder_status >= rh.FOLDER_PREPARED: cli_run_command = rh.build_cli_command( cmd="run", @@ -72,10 +71,13 @@ def ui_run_execution(dialog, result, current_run, folder_status): execution_id=execution["execution_id"], project_path=project_path, ) - cli_log_command = rh.build_cli_command( - cmd="logs", - project_path=project_path, - ) + cli_log_commands = [] + for i, _ in enumerate(execution["versions"]): + cli_log_commands. append(rh.build_cli_command( + cmd="logs", + project_path=project_path, + step_nr=str(i) + )) with ui.row().classes("w-full"): ui.label(cli_run_command).classes("font-mono") with ui.row().classes("w-full"): @@ -85,11 +87,20 @@ def ui_run_execution(dialog, result, current_run, folder_status): icon="rocket", ).props("no-caps") with ui.row().classes("w-full"): - ui.button( - "show logs", - on_click=lambda: run_command(cli_log_command, dialog, result), - icon="info", - ).props("no-caps") + ui.icon("warning").classes("text-lg text-yellow") + ui.label( + """The logs for a step only become available once it is running. + So if they are not available right away, they may be so when you + click the button again. + """ + ) + for i, cli_log_command in enumerate(cli_log_commands): + with ui.row().classes("w-full"): + ui.button( + f"show logs for step {i}", + on_click=lambda cli_log_command=cli_log_command: run_command(cli_log_command, dialog, result), + icon="info", + ).props("no-caps") rh.ui_next_back(current_run, ready_for_next=False) From 762b9145236ef190e9d9ca69996f578e2d76868c Mon Sep 17 00:00:00 2001 From: sabinem <5292683+sabinem@users.noreply.github.com> Date: Mon, 1 Jul 2024 08:18:37 +0200 Subject: [PATCH 14/28] fix(cli logs): adapt error handling to os.system os.system does not throw an error, but keyboard interruptions make sense here --- odtp/cli/execution.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index f510f0d0..ff521b5f 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -1,7 +1,7 @@ """ This scripts contains odtp subcommands for 'execution' """ - +import sys import typer from typing_extensions import Annotated @@ -112,10 +112,10 @@ def logs( ), ): try: - os.system(f"tail -f {project_path}/{step_nr}_*/odtp-logs/*") - except Exception as e: - print(f"ERROR: Streaming logs failed: {e}") - raise typer.Abort() + log_file_path = f"{project_path}/{step_nr}_*/odtp-logs/*" + os.system(f"tail -f {log_file_path}") + except KeyboardInterrupt: + sys.exit() if __name__ == "__main__": From 9876f6a1dfcf48d3466f2d41af5082c6e2c59ce4 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Mon, 1 Jul 2024 09:23:43 +0200 Subject: [PATCH 15/28] feat(execution-timestamps) (#159) * feat(execution-timestamps) * feat(excecution & step): Added Creation/Update timestamp. Removed start/ending from creation. * feat(step timestamps logs): Added timestamps on orchestrator. --- odtp/mongodb/db.py | 12 ++++++++---- odtp/workflow.py | 13 +++++++++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/odtp/mongodb/db.py b/odtp/mongodb/db.py index 73df95b4..4d366fdd 100644 --- a/odtp/mongodb/db.py +++ b/odtp/mongodb/db.py @@ -348,17 +348,19 @@ def add_execution( "component_versions": versions, "workflowExecutorSchema": workflow, }, - "start_timestamp": datetime.now(timezone.utc), - "end_timestamp": datetime.now(timezone.utc), + "start_timestamp": None, + "end_timestamp": None, # Array of ObjectIds referencing Steps collection. Change in a future by DAG graph "steps": [], + "createdAt": datetime.now(timezone.utc), + "updatedAt": datetime.now(timezone.utc) } steps = [] for i, version in enumerate(versions): step = { "timestamp": datetime.now(timezone.utc), - "start_timestamp": datetime.now(timezone.utc), - "end_timestamp": datetime.now(timezone.utc), + "start_timestamp": None, + "end_timestamp": None, "type": "ephemeral", "logs": [], "inputs": {}, @@ -366,6 +368,8 @@ def add_execution( "component_version": versions[i], "parameters": parameters[i] or {}, "ports": ports[i], + "createdAt": datetime.now(timezone.utc), + "updatedAt": datetime.now(timezone.utc) } steps.append(step) execution_id = append_execution_to_digital_twin(db, dt_id, execution) diff --git a/odtp/workflow.py b/odtp/workflow.py index 375557dd..a2d761c4 100644 --- a/odtp/workflow.py +++ b/odtp/workflow.py @@ -113,12 +113,19 @@ def run_workflow(self): # Temporally the parameters are taken from the environment files and not # taken from the steps documents + + # Start execution timestamp + db.set_document_timestamp(self.execution["_id"], db.collection_executions, "start_timestamp") + for step_index in self.schema["workflowExecutorSchema"]: log.info(f"running step {step_index}") step_index = int(step_index) step_id = self.execution["steps"][step_index] + # Start step timestamp + db.set_document_timestamp(step_id, db.collection_steps, "start_timestamp") + secrets = self.secrets[step_index] step_doc = db.get_document_by_id( @@ -173,6 +180,12 @@ def run_workflow(self): instance_name=self.instance_names[step_index], step_id=self.execution["steps"][step_index] ) + + # End step timestamp + db.set_document_timestamp(step_id, db.collection_steps, "end_timestamp") + + # End execution timestamp + db.set_document_timestamp(self.execution["_id"], db.collection_executions, "end_timestamp") def run_task(self): # Implement the logic of running one single task. From 17b368cf6ce7bd4f023e6d850da8707b7d8f2969 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Mon, 1 Jul 2024 14:47:32 +0200 Subject: [PATCH 16/28] feat(docker): Avoid rebuilding images available (#160) * feat(docker): Avoid rebuilding images available * fix(attribute_name): self.container_names --- odtp/run.py | 26 +++++++++++++++++++++----- odtp/workflow.py | 13 ++++++++----- pyproject.toml | 1 + 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/odtp/run.py b/odtp/run.py index 0cbba5c8..8e81e0a5 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -2,6 +2,7 @@ import os import json import subprocess +import docker import odtp.helpers.settings as config import odtp.helpers.git as git_helpers import odtp.helpers.environment as env_helpers @@ -40,8 +41,9 @@ def __init__(self, repo_url="", commit_hash="", image_name="", project_folder="" def prepare_component(self): self._checks_for_prepare() self._create_project_folder_structure() - self._download_repo() - self._build_image() + if not self._check_if_image_exists(): + self._download_repo() + self._build_image() def _create_project_folder_structure(self): """Create all the folder structure in project_folder""" @@ -86,6 +88,20 @@ def _checks_for_run(self, parameters, ports, image_name): db_utils.check_port_mappings_for_component_runs(ports) self._check_image_exists() + def _check_if_image_exists(self): + """ + Check whether a docker image exists + """ + logging.info(f"VALIDATION: Checking if Docker image exists: {self.docker_image_name}") + client = docker.from_env() + images = client.images.list(name=self.docker_image_name) + logging.info(f"Images found: {images}") + + if len(images) > 0: + return True + else: + return False + def _download_repo(self): """ Download a GitHub repository to the specified destination. @@ -152,14 +168,14 @@ def _create_volume(self, volume_name): log.info(f"RUN: Creating Docker volume {volume_name}") subprocess.run(["docker", "volume", "create", volume_name]) - def run_component(self, parameters, secrets, ports, instance_name, step_id=None, debug=False): + def run_component(self, parameters, secrets, ports, container_name, step_id=None, debug=False): """ Run a Docker component with the specified parameters. Args: secrets (dict): The secrets variables to pass to the Docker component. parameters (dict): The environment variables to pass to the Docker component. - instance_name (str, optional): The name of the Docker container. Defaults to "odtp_component". + container_name (str, optional): The name of the Docker container. Defaults to "odtp_component". Returns: str: The ID of the Docker run. @@ -186,7 +202,7 @@ def run_component(self, parameters, secrets, ports, instance_name, step_id=None, else: secrets_args = [""] - docker_run_command = ["docker", "run", "--rm", "-it", "--name", instance_name, + docker_run_command = ["docker", "run", "--rm", "-it", "--name", container_name, "--network", "odtp_odtp-network", "--volume", f"{os.path.abspath(self.input_volume)}:/odtp/odtp-input", "--volume", f"{os.path.abspath(self.log_volume)}:/odtp/odtp-logs", diff --git a/odtp/workflow.py b/odtp/workflow.py index a2d761c4..0790aa5a 100644 --- a/odtp/workflow.py +++ b/odtp/workflow.py @@ -20,7 +20,7 @@ def __init__(self, execution_data, working_path, secrets): self.image_names = [] self.repo_urls = [] self.commits = [] - self.instance_names = [] + self.container_names = [] self.steps_folder_paths = [] self.secrets = secrets @@ -48,12 +48,15 @@ def __init__(self, execution_data, working_path, secrets): step_folder_path = os.path.join(self.working_path, step_name) self.steps_folder_paths.append(step_folder_path) - image_name = step_name + image_name = odtp_utils.get_execution_step_name( + component_name=component_name, + component_version=component_version + ) self.image_names.append(image_name) self.repo_urls.append(repo_link) self.commits.append(commit_hash) - self.instance_names.append(image_name) + self.container_names.append(step_name) except Exception as e: raise OdtpRunSetupException( f"Workflowmanager could not be intialized: Exception occured: {e}" @@ -166,7 +169,7 @@ def run_workflow(self): # By now the image_name is just the name of the component and the version componentManager = DockerManager( repo_url=self.repo_urls[step_index], - image_name=self.image_names[step_index], + image_name=self.image_names[step_index], project_folder=self.steps_folder_paths[step_index] ) @@ -177,7 +180,7 @@ def run_workflow(self): parameters, secrets, ports=ports, - instance_name=self.instance_names[step_index], + container_name=self.container_names[step_index], step_id=self.execution["steps"][step_index] ) diff --git a/pyproject.toml b/pyproject.toml index d46e443d..cdbef866 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ python-dotenv = "^1.0.0" boto3 = "^1.33.13" nicegui = "1.4.24" directory-tree = "^0.0.4" +docker = "7.1.0" python-slugify = "^8.0.4" pandas = "^2.2.2" From 6a1478830c5df3e34be660bc62a95feb498f290c Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Mon, 1 Jul 2024 17:02:32 +0200 Subject: [PATCH 17/28] feat(CLI-table): Using pretty tables to get items from any collection. (#174) --- odtp/cli/db.py | 7 +++++- odtp/helpers/utils.py | 55 +++++++++++++++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 3 files changed, 62 insertions(+), 2 deletions(-) diff --git a/odtp/cli/db.py b/odtp/cli/db.py index de13ee57..a378d87b 100644 --- a/odtp/cli/db.py +++ b/odtp/cli/db.py @@ -12,7 +12,7 @@ @app.command() def get( - collection: str = typer.Option(..., "--collection", help="Specify the collection"), + collection: str = typer.Argument(...,help="Specify the collection"), id: Annotated[str, typer.Option(help="Specify the id")] = None, ): if id: @@ -21,6 +21,11 @@ def get( db_output = db.get_collection(collection=collection) odtp_utils.print_output_as_json(db_output) +@app.command() +def ls(collection_name: str): + """List all documents in a collection""" + db_output = db.get_collection(collection=collection_name) + odtp_utils.output_as_pretty_table(db_output, collection_name) @app.command() def showAll(): diff --git a/odtp/helpers/utils.py b/odtp/helpers/utils.py index f6cbb974..0c33c273 100644 --- a/odtp/helpers/utils.py +++ b/odtp/helpers/utils.py @@ -1,4 +1,5 @@ import json +from prettytable import PrettyTable import odtp.mongodb.db as db from odtp import __version__ @@ -45,3 +46,57 @@ def get_version_names_for_execution(execution, naming_function=get_execution_ste version_dict = get_version_name_dict_for_version_ids(version_ids, naming_function=naming_function) version_names = [version_dict[version_id] for version_id in version_ids] return version_names + +def output_as_pretty_table(db_output, collection_name): + table = PrettyTable() + + if collection_name == "users": + keys = ["_id", "displayName", "email", "github"] + table.field_names = ["User ID", "Display Name", "Email", "Github User"] + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "digitalTwins": + keys = ["_id", "name", "status", "public", "created_at", "updated_at", "userRef"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "executions": + keys = ["_id", "title", "description", "start_timestamp", "end_timestamp", "digitalTwinRef"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "components": + keys = ["_id", "author", "componentName", "repoLink", "status", "title", "type", "description", "created_at", "updated_at"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "versions": + keys = ["_id", "componentId", "odtp_version", "component_version", "commitHash", "title", "description", "ports", "created_at", "updated_at"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "outputs": + keys = ["_id", "output_type", "s3_bucket", "s3_key", "file_name", "file_size", "file_type", "created_at", "updated_at", "stepRef"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + elif collection_name == "results": + keys = ["_id", "executionRef", "digitalTwinRef", "title", "description", "created_at", "updated_at"] + table.field_names = keys + + for item in db_output: + table.add_row([item[key] for key in keys] ) + + print(table) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index cdbef866..838180e4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ directory-tree = "^0.0.4" docker = "7.1.0" python-slugify = "^8.0.4" pandas = "^2.2.2" - +prettytable = "3.10.0" [tool.poetry.group.dev.dependencies] pytest = "^7.2.1" From a4dc08ded21a41def19637e85933170d269e7c27 Mon Sep 17 00:00:00 2001 From: caviri <45425937+caviri@users.noreply.github.com> Date: Tue, 2 Jul 2024 06:25:40 +0200 Subject: [PATCH 18/28] fix(variable renaming): Missed renaming of 2 variables --- odtp/run.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/odtp/run.py b/odtp/run.py index 8e81e0a5..8b5f428d 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -217,11 +217,11 @@ def run_component(self, parameters, secrets, ports, container_name, step_id=None output, error = process.communicate() if process.returncode != 0: - log.exception(f"Failed to run Docker component {instance_name}: {error.decode()}") + log.exception(f"Failed to run Docker component {container_name}: {error.decode()}") return None else: docker_run_id = output.decode().strip() - log.info(f"Docker run was started with success: {instance_name}") + log.info(f"Docker run was started with success: {container_name}") return docker_run_id def stop_component(self, name="odtpruntest"): @@ -245,7 +245,7 @@ def stop_component(self, name="odtpruntest"): else: return f"Docker component {name} has been stopped." - def delete_component(self, instance_name="odtpruntest"): + def delete_component(self, container_name="odtpruntest"): """ Delete a Docker component. @@ -255,16 +255,16 @@ def delete_component(self, instance_name="odtpruntest"): Returns: str: A message indicating the Docker component has been deleted. """ - log.info(f"Deleting Docker component {instance_name}") - docker_rm_command = ["docker", "rm", instance_name] + log.info(f"Deleting Docker component {container_name}") + docker_rm_command = ["docker", "rm", container_name] process = subprocess.Popen(docker_rm_command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) _, error = process.communicate() if process.returncode != 0: - log.exception(f"Failed to delete Docker component {instance_name}: {error.decode()}") + log.exception(f"Failed to delete Docker component {container_name}: {error.decode()}") return None else: - return f"Docker component {instance_name} has been deleted." + return f"Docker component {container_name} has been deleted." def delete_image(self): """ From 9d412da7d14474c6f57c9d47d27b817e28d22550 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Tue, 2 Jul 2024 08:54:43 +0200 Subject: [PATCH 19/28] Logging and chores (#172) - delete unused functions - log instead of print in the cli for some commands --- odtp/cli/component.py | 21 ++++++++++---------- odtp/cli/db.py | 8 +++++--- odtp/cli/execution.py | 16 ++++++++++----- odtp/cli/new.py | 18 +++++++++-------- odtp/cli/s3.py | 4 ++-- odtp/cli/setup.py | 4 ++-- odtp/storage.py | 4 ++-- odtp/workflow.py | 45 +------------------------------------------ 8 files changed, 43 insertions(+), 77 deletions(-) diff --git a/odtp/cli/component.py b/odtp/cli/component.py index 8ef2edfa..96eaeee2 100644 --- a/odtp/cli/component.py +++ b/odtp/cli/component.py @@ -3,6 +3,7 @@ """ import typer from typing_extensions import Annotated +import logging from odtp.run import DockerManager import odtp.helpers.git as odtp_git @@ -11,6 +12,9 @@ app = typer.Typer() +log = logging.getLogger(__name__) + + ## Adding listing so we can have multiple flags from typing import List @@ -34,10 +38,10 @@ def prepare( ) componentManager.prepare_component() except Exception as e: - print(f"ERROR: Prepare component failed: {e}") + log.error(f"ERROR: Prepare component failed: {e}") raise typer.Abort() else: - print("SUCCESS: image for the component has been build") + log.info("SUCCESS: image for the component has been build") @app.command() def run( @@ -78,17 +82,12 @@ def run( instance_name=instance_name ) except Exception as e: - print(f"ERROR: Run of component failed: {e}") + log.error(f"ERROR: Run of component failed: {e}") raise typer.Abort() else: - print("SUCCESS: container for the component has been started") + log.info("SUCCESS: container for the component has been started") -#### TODO: Stop Component -@app.command() -def stop(): - pass - @app.command() def delete_instance( @@ -98,7 +97,7 @@ def delete_instance( ): componentManager = DockerManager() componentManager.delete_component(instance_name=instance_name) - print("Container deleted") + log.info("Container deleted") @app.command() @@ -109,7 +108,7 @@ def delete_image( ): componentManager = DockerManager(image_name=image_name) componentManager.delete_image() - print("Image deleted") + log.info("Image deleted") if __name__ == "__main__": diff --git a/odtp/cli/db.py b/odtp/cli/db.py index a378d87b..dfa14ece 100644 --- a/odtp/cli/db.py +++ b/odtp/cli/db.py @@ -3,12 +3,14 @@ """ import typer from typing_extensions import Annotated +import logging import odtp.mongodb.db as db import odtp.helpers.utils as odtp_utils app = typer.Typer() +log = logging.getLogger(__name__) @app.command() def get( @@ -81,7 +83,7 @@ def delete_document( id: str = typer.Option(help="Specify the id") ): db.delete_document_by_id(document_id=id, collection=collection) - print(f"Document with ID {id} was deleted") + log.info(f"Document with ID {id} was deleted") @app.command() @@ -89,13 +91,13 @@ def delete_collection( collection: str = typer.Option(..., "--collection", help="Specify the collection"), ): db.delete_collection(collection=collection) - print(f"Collection {collection} was deleted.") + log.info(f"Collection {collection} was deleted.") @app.command() def deleteAll(): db.delete_all() - print("All collection deleted.") + log.info("All collection deleted.") if __name__ == "__main__": diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index ff521b5f..78b65c1b 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -4,6 +4,7 @@ import sys import typer from typing_extensions import Annotated +import logging import odtp.mongodb.db as db import odtp.helpers.parse as odtp_parse @@ -13,6 +14,8 @@ app = typer.Typer() +log = logging.getLogger(__name__) + ## Adding listing so we can have multiple flags from typing import List @@ -45,10 +48,10 @@ def prepare( flowManager = WorkflowManager(execution, project_path, secrets) flowManager.prepare_workflow() except Exception as e: - print(f"ERROR: Prepare execution failed: {e}") + log.error(f"ERROR: Prepare execution failed: {e}") raise typer.Abort() else: - print("SUCCESS: images for the execution have been build") + log.info("SUCCESS: images for the execution have been build") @app.command() @@ -83,14 +86,17 @@ def run( flowManager = WorkflowManager(execution, project_path, secrets) flowManager.run_workflow() except Exception as e: - print(f"ERROR: Run execution failed: {e}") + log.error(f"ERROR: Prepare execution failed: {e}") raise typer.Abort() else: - print("SUCCESS: containers for the execution have been run") - + log.info("SUCCESS: containers for the execution have been run") @app.command() def output( + + execution_id: str = typer.Option( + ..., "--execution-id", help="Specify the ID of the execution" + ), project_path: str = typer.Option( ..., "--project-path", help="Specify the path for the execution" ), diff --git a/odtp/cli/new.py b/odtp/cli/new.py index a6250d28..2fcb0b08 100644 --- a/odtp/cli/new.py +++ b/odtp/cli/new.py @@ -3,6 +3,7 @@ """ import typer from typing_extensions import Annotated +import logging import odtp.mongodb.db as db import odtp.helpers.parse as odtp_parse @@ -15,6 +16,7 @@ app = typer.Typer() +log = logging.getLogger(__name__) @app.command() def user_entry( @@ -24,7 +26,7 @@ def user_entry( ): """Add new user in the MongoDB""" user_id = db.add_user(name=name, github=github, email=email) - print(f"A user has been added {user_id}") + log.info(f"A user has been added {user_id}") @app.command() @@ -57,11 +59,11 @@ def odtp_component_entry( ports=ports, ) except Exception as e: - print(f"ERROR: {e}") + log.error(f"ERROR: {e}") if hasattr(e, "__notes__"): - print(f"{','.join(e.__notes__)}") + log.error(f"{','.join(e.__notes__)}") raise typer.Abort() - print(f"""SUCCESS: component version has been added: see above for the details. + log.info(f"""SUCCESS: component version has been added: see above for the details. component_id: {component_id} version_id: {version_id}""") @@ -79,7 +81,7 @@ def digital_twin_entry( user_id = db.get_document_id_by_field_value("user_email", user_email, "users") dt_id = db.add_digital_twin(userRef=user_id, name=name) - print(f"Digital Twin added with ID {dt_id}") + log.info(f"Digital Twin added with ID {dt_id}") @app.command() @@ -130,11 +132,11 @@ def execution_entry( ports=ports, ) except Exception as e: - print(f"ERROR: {e}") + log.error(f"ERROR: {e}") if hasattr(e, "__notes__"): - print(f"{','.join(e.__notes__)}") + log.error(f"{','.join(e.__notes__)}") raise typer.Abort() - print(f"""SUCCESS: execution has been added: see above for the details. + log.info(f"""SUCCESS: execution has been added: see above for the details. execution id: {execution_id} step_ids: {step_ids}""") diff --git a/odtp/cli/s3.py b/odtp/cli/s3.py index 8f5bbe79..6815115f 100644 --- a/odtp/cli/s3.py +++ b/odtp/cli/s3.py @@ -32,10 +32,10 @@ def check(): try: s3 = s3Manager() s3.test_connection() - print("S3 is connected. Bucket is ready to use") + log.info("S3 is connected. Bucket is ready to use") except Exception as e: log.exception(f"S3 connection could not be established: an Exception {e} occurred") - print(f"S3 connection could not be established: an Exception {e} occurred") + log.error(f"S3 connection could not be established: an Exception {e} occurred") if __name__ == "__main__": diff --git a/odtp/cli/setup.py b/odtp/cli/setup.py index 1b15f023..f1be6c77 100644 --- a/odtp/cli/setup.py +++ b/odtp/cli/setup.py @@ -18,7 +18,7 @@ def initiate(): try: bucketAvailable = odtpS3.test_connection() except Exception as e: - logging.error("S3 bucket not found. Please create the bucket on minio folder or use the dashboard.") + log.error("S3 bucket not found. Please create the bucket on minio folder or use the dashboard.") log.exception(e) @@ -35,7 +35,7 @@ def delete(): odtpS3 = s3Manager() odtpS3.deleteAll() - print("All deleted") + log.info("All deleted") if __name__ == "__main__": diff --git a/odtp/storage.py b/odtp/storage.py index 73dc5307..fdedd653 100644 --- a/odtp/storage.py +++ b/odtp/storage.py @@ -36,7 +36,7 @@ def createFolderStructure(self, structure=["odtp"]): # Add a trailing slash to make S3 recognize it as a folder self.s3.put_object(Bucket=self.bucketName, Key=path + '/') - print("Folder Structure Created") + log.info("Folder Structure Created") # Method to create a specific folder # The idea is to create paths such as Digital Twin > Execution > Step > Output @@ -105,7 +105,7 @@ def deleteAll(self): # This will delete all objects in the bucket. bucket.objects.all().delete() - print("Folder Structure Deleted") + log.info("Folder Structure Deleted") # Method to delete one file in s3 def deleteFile(self, s3_path): diff --git a/odtp/workflow.py b/odtp/workflow.py index 0790aa5a..57ad7638 100644 --- a/odtp/workflow.py +++ b/odtp/workflow.py @@ -95,20 +95,6 @@ def prepare_workflow(self): log.info("COMPONENTS DOWNLOADED AND BUILT") - def download_data_from_storage(self): - # Implement the logic to download data from S3 - pass - - def download_and_build_components(self): - # This method will clone the githubs and build the components. - pass - - def extract_parameters(self): - # Implement the logic to extract parameters from the Barfi schema - # These parameters will be send as environment variable. - self.paramenters = {} - pass - def run_workflow(self): # Implement the logic to send tasks following the DAG schema. # This can make use of barfi workflow execution function. Each @@ -188,33 +174,4 @@ def run_workflow(self): db.set_document_timestamp(step_id, db.collection_steps, "end_timestamp") # End execution timestamp - db.set_document_timestamp(self.execution["_id"], db.collection_executions, "end_timestamp") - - def run_task(self): - # Implement the logic of running one single task. - # Send the step ID as Environment variable so the component can log the progress - pass - - def stop_workflow(self): - # This will stop the execution of the workflow. - pass - - def stop_task(self): - # This will stop one single task - pass - - def delete_workflow(self): - # This method will delete all records in the DB and related docker components downloaded in the folder. - pass - - def delete_db_entry(self): - # Method to remove the workflow execution from the database - pass - - def delete_docker_components(self): - # Method to remove all docker containers used by this workflow. - pass - - def restart_workflow(self): - # This will restart the execution of the workflow. - pass + db.set_document_timestamp(self.execution["_id"], db.collection_executions, "end_timestamp") \ No newline at end of file From ad5886861698d9bb8fcc243a8816905fe404e24c Mon Sep 17 00:00:00 2001 From: Sabine Maennel Date: Tue, 2 Jul 2024 11:07:53 +0200 Subject: [PATCH 20/28] fix(dashboard): changed names of timestamp fields for execution (#180) * fix(dashboard): changed names of timestamp fields for execution adapt to changes in the mongodb * feat(dashboard executions): show start and end timestamps in table view of executions show also start and end timestamps --------- Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- odtp/dashboard/page_executions/table.py | 8 +++++--- odtp/dashboard/utils/helpers.py | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/odtp/dashboard/page_executions/table.py b/odtp/dashboard/page_executions/table.py index d994b786..39684eab 100644 --- a/odtp/dashboard/page_executions/table.py +++ b/odtp/dashboard/page_executions/table.py @@ -13,8 +13,10 @@ def ui_table_layout(executions): return df = pd.DataFrame(data=executions) df["_id"] = df["_id"].astype("string") - df["timestamp"] = df["start_timestamp"] + df["createdAt"] = df["createdAt"] + df["start_timestamp"] = df["start_timestamp"].fillna('') + df["end_timestamp"] = df["end_timestamp"].fillna('') df["steps"] = df["steps"].apply(helpers.pd_lists_to_counts).astype("string") - df = df[["timestamp", "title", "steps"]] - df = df.sort_values(by="timestamp", ascending=False) + df = df[["createdAt", "title", "steps", "start_timestamp", "end_timestamp"]] + df = df.sort_values(by="createdAt", ascending=False) ui.table.from_pandas(df) diff --git a/odtp/dashboard/utils/helpers.py b/odtp/dashboard/utils/helpers.py index 0f29b99f..c2ec61dd 100644 --- a/odtp/dashboard/utils/helpers.py +++ b/odtp/dashboard/utils/helpers.py @@ -62,14 +62,14 @@ def get_execution_select_options(digital_twin_id): sub_collection=db.collection_executions, item_id=digital_twin_id, ref_name=db.collection_executions, - sort_by=[("start_timestamp", db.DESCENDING)], + sort_by=[("createdAt", db.DESCENDING)], ) if not executions: return {} execution_options = {} for execution in executions: execution_options[str(execution["_id"])] = ( - f"{execution['start_timestamp'].strftime('%d/%m/%y')} {execution.get('title')}" + f"{execution['createdAt'].strftime('%d/%m/%y')} {execution.get('title')}" ) return execution_options @@ -103,7 +103,7 @@ def build_execution_with_steps(execution_id): execution_with_steps = { "execution_id": execution_id, "title": execution.get("title"), - "timestamp": execution.get("start_timestamp").strftime("%m/%d/%Y, %H:%M:%S"), + "createdAt": execution.get("createdAt").strftime("%m/%d/%Y, %H:%M:%S"), "versions": execution["workflowSchema"]["component_versions"], "version_tags": version_tags, "steps": step_ids, From 9b4aeba0997addbf4311259812e0c9d44bb25c54 Mon Sep 17 00:00:00 2001 From: Sabine Maennel Date: Tue, 2 Jul 2024 11:08:16 +0200 Subject: [PATCH 21/28] chore(cli): cleanup execution commands that are only for the gui (#181) rename command for streaming logs remove command for showing directory folder Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- odtp/cli/execution.py | 19 +------------------ odtp/dashboard/page_run/run.py | 2 +- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index 78b65c1b..5ee7d2d6 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -9,7 +9,6 @@ import odtp.mongodb.db as db import odtp.helpers.parse as odtp_parse from odtp.workflow import WorkflowManager -from directory_tree import display_tree import os app = typer.Typer() @@ -91,25 +90,9 @@ def run( else: log.info("SUCCESS: containers for the execution have been run") -@app.command() -def output( - - execution_id: str = typer.Option( - ..., "--execution-id", help="Specify the ID of the execution" - ), - project_path: str = typer.Option( - ..., "--project-path", help="Specify the path for the execution" - ), -): - try: - display_tree(project_path) - except Exception as e: - print(f"ERROR: Output printing failed: {e}") - raise typer.Abort() - @app.command() -def logs( +def streamlogs( project_path: str = typer.Option( ..., "--project-path", help="Specify the path for the execution" ), diff --git a/odtp/dashboard/page_run/run.py b/odtp/dashboard/page_run/run.py index d929ed77..8f65a0bf 100644 --- a/odtp/dashboard/page_run/run.py +++ b/odtp/dashboard/page_run/run.py @@ -74,7 +74,7 @@ def ui_run_execution(dialog, result, current_run, folder_status): cli_log_commands = [] for i, _ in enumerate(execution["versions"]): cli_log_commands. append(rh.build_cli_command( - cmd="logs", + cmd="streamlogs", project_path=project_path, step_nr=str(i) )) From 6922b0ed82a591384336d19833ba9f709044a9f3 Mon Sep 17 00:00:00 2001 From: Sabine Maennel Date: Tue, 2 Jul 2024 17:57:58 +0200 Subject: [PATCH 22/28] feat/log commands to file (#165) * feat(logging): log commands to file to facilitate debugging * feat(cli execution): add both print and logs * chore(gitignore): add odtp.log to gitignore * fix(run.py): don't log secrets to file --------- Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- .gitignore | 1 + odtp/cli/execution.py | 16 ++++++++++++---- odtp/dashboard/page_run/run.py | 3 +++ odtp/helpers/settings.py | 10 ++++++++++ odtp/run.py | 16 +++++++++++----- odtp/workflow.py | 4 +++- 6 files changed, 40 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 4630bb9c..6d8a2794 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ __pycache__/ !.env*.dist .nicegui .local +odtp/odtp.log diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index 5ee7d2d6..8129817c 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -47,10 +47,14 @@ def prepare( flowManager = WorkflowManager(execution, project_path, secrets) flowManager.prepare_workflow() except Exception as e: - log.error(f"ERROR: Prepare execution failed: {e}") + msg = f"ERROR: Prepare execution failed: {e}" + log.exception(msg) + print(msg) raise typer.Abort() else: - log.info("SUCCESS: images for the execution have been build") + msg = "SUCCESS: images for the execution have been build" + log.info(msg) + print(msg) @app.command() @@ -85,10 +89,14 @@ def run( flowManager = WorkflowManager(execution, project_path, secrets) flowManager.run_workflow() except Exception as e: - log.error(f"ERROR: Prepare execution failed: {e}") + msg = f"ERROR: Prepare execution failed: {e}" + log.exception(msg) + print(msg) raise typer.Abort() else: - log.info("SUCCESS: containers for the execution have been run") + msg = "SUCCESS: containers for the execution have been run" + log.info(msg) + print(msg) @app.command() diff --git a/odtp/dashboard/page_run/run.py b/odtp/dashboard/page_run/run.py index 8f65a0bf..b24ff5de 100644 --- a/odtp/dashboard/page_run/run.py +++ b/odtp/dashboard/page_run/run.py @@ -5,10 +5,13 @@ import sys from nicegui import ui +import odtp.helpers.settings as config import odtp.dashboard.page_run.helpers as rh import odtp.dashboard.page_run.folder as folder log = logging.getLogger(__name__) +log.setLevel(logging.INFO) +log.addHandler(config.get_command_log_handler()) def ui_prepare_execution(dialog, result, current_run, folder_status): diff --git a/odtp/helpers/settings.py b/odtp/helpers/settings.py index 0dec8df0..386d433d 100644 --- a/odtp/helpers/settings.py +++ b/odtp/helpers/settings.py @@ -5,6 +5,7 @@ load_dotenv() logger = logging.getLogger(__name__) +code_file_dir = os.path.abspath(__file__) DEFAULT_LOG_LEVEL = "ERROR" DEFAULT_RUN_LOG_LEVEL = "INFO" @@ -49,3 +50,12 @@ class OdtpSettingsException(Exception): log_levels = logging.getLevelNamesMapping() if not RUN_LOG_LEVEL in log_levels.keys(): RUN_LOG_LEVEL = DEFAULT_RUN_LOG_LEVEL + +def get_command_log_handler(): + log_file_path = os.path.join(os.path.dirname(os.path.dirname(code_file_dir)), 'odtp.log') + command_log_handler = logging.FileHandler(log_file_path) + FORMATTER = logging.Formatter( + '%(asctime)s - [%(module)s:%(levelname)s] %(lineno)d %(filename)s %(funcName)s - %(message)s' + ) + command_log_handler.setFormatter(FORMATTER) + return command_log_handler diff --git a/odtp/run.py b/odtp/run.py index 8b5f428d..9595c266 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -17,7 +17,8 @@ log = logging.getLogger(__name__) -log.setLevel(logging.DEBUG) +log.setLevel(logging.INFO) +log.addHandler(config.get_command_log_handler()) class OdtpRunSetupException(Exception): @@ -77,7 +78,7 @@ def _checks_for_prepare(self): ) def _checks_for_run(self, parameters, ports, image_name): - log.info("VALIDATION: check for run") + log.info("VALIDATION: check for run") self._check_project_folder_prepared() self._check_image_exists() try: @@ -168,7 +169,7 @@ def _create_volume(self, volume_name): log.info(f"RUN: Creating Docker volume {volume_name}") subprocess.run(["docker", "volume", "create", volume_name]) - def run_component(self, parameters, secrets, ports, container_name, step_id=None, debug=False): + def run_component(self, parameters, secrets, ports, container_name, step_id=None): """ Run a Docker component with the specified parameters. @@ -209,9 +210,14 @@ def run_component(self, parameters, secrets, ports, container_name, step_id=None "--volume", f"{os.path.abspath(self.output_volume)}:/odtp/odtp-output"] + env_args + ports_args + secrets_args + [self.docker_image_name] command_string = ' '.join(docker_run_command) - if debug: - log.debug(f"Command to be executed: {command_string}") + command_string_log_safe = command_string + for value in [parameters["ODTP_SECRET_KEY"], parameters["ODTP_ACCESS_KEY"], parameters["ODTP_MONGO_SERVER"]]: + command_string_log_safe = command_string_log_safe.replace(value, "x") + if secrets: + for value in secrets.values(): + command_string_log_safe = command_string_log_safe.replace(value, "x") + log.info(command_string_log_safe) process = subprocess.Popen(command_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output, error = process.communicate() diff --git a/odtp/workflow.py b/odtp/workflow.py index 57ad7638..23bef008 100644 --- a/odtp/workflow.py +++ b/odtp/workflow.py @@ -1,13 +1,15 @@ import os from odtp.run import DockerManager, OdtpRunSetupException import odtp.helpers.utils as odtp_utils +import odtp.helpers.settings as config import odtp.helpers.environment as env_helpers import odtp.mongodb.db as db import logging import zipfile log = logging.getLogger(__name__) -log.setLevel(logging.DEBUG) +log.setLevel(logging.INFO) +log.addHandler(config.get_command_log_handler()) class WorkflowManager: From e7e2f6d319a76ed530185f1f4e7244fb2c0aae7f Mon Sep 17 00:00:00 2001 From: Sabine Maennel Date: Wed, 3 Jul 2024 11:51:23 +0200 Subject: [PATCH 23/28] Fix/dashboard run page layout (#182) fix(dashboard run page): fix minor styling issue Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- odtp/dashboard/page_run/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/odtp/dashboard/page_run/run.py b/odtp/dashboard/page_run/run.py index b24ff5de..2192e1be 100644 --- a/odtp/dashboard/page_run/run.py +++ b/odtp/dashboard/page_run/run.py @@ -41,7 +41,7 @@ def ui_prepare_execution(dialog, result, current_run, folder_status): ) with ui.grid(columns=1): with ui.row().classes("w-full"): - ui.label(cli_prepare_command).classes("font-mono") + ui.label(cli_prepare_command).classes("font-mono w-full") with ui.row().classes("w-full"): ui.button( "Prepare execution", From 398db44bfff65495cb81781d7ddbe946996c018c Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Wed, 3 Jul 2024 12:43:10 +0200 Subject: [PATCH 24/28] Delete s3 Objects and items related to an execution (#173) * feat(delete): CLI method to delete execution s3 and project folder * feat(delete): CLI method to delete all MDB entries related to an execution * feat(execution delete): Keep folder * fix(project-path): Optional * fix(execution): Remove typo and non used method * fix(delete outputs): Fixed bug and added proejct_path as optional. * Using print statements. * chore(delete log): Logging only in debug * fix(DT Entry): Wrong email field was retrieved. --- odtp/cli/execution.py | 52 +++++++++++++++++++++++++++- odtp/cli/new.py | 2 +- odtp/helpers/environment.py | 12 +++++++ odtp/mongodb/db.py | 68 ++++++++++++++++++++++++++++++++++++- odtp/run.py | 2 +- odtp/storage.py | 17 ++++++++++ 6 files changed, 149 insertions(+), 4 deletions(-) diff --git a/odtp/cli/execution.py b/odtp/cli/execution.py index 8129817c..54c38c5b 100644 --- a/odtp/cli/execution.py +++ b/odtp/cli/execution.py @@ -4,17 +4,23 @@ import sys import typer from typing_extensions import Annotated -import logging +import logging import odtp.mongodb.db as db import odtp.helpers.parse as odtp_parse from odtp.workflow import WorkflowManager +from directory_tree import display_tree +import odtp.helpers.environment as odtp_env +from odtp.storage import s3Manager +from nicegui import ui import os app = typer.Typer() log = logging.getLogger(__name__) +log = logging.getLogger(__name__) + ## Adding listing so we can have multiple flags from typing import List @@ -115,5 +121,49 @@ def streamlogs( sys.exit() +@app.command() +def delete( + execution_name: str = typer.Option( + None, "--execution-name", help="Specify the name of the execution" + ), + execution_id: str = typer.Option( + None, "--execution-id", help="Specify the ID of the execution" + ), + project_path: str = typer.Option( + None, "--project-path", help="Specify the path for the execution" + ), + keep_project_path: bool = typer.Option( + True, "--keep-project-path", help="Keep the project directory after deleting contents" + ), +): + try: + if execution_id is None and execution_name is None: + raise typer.Exit("Please provide either --execution-name or --execution-id") + + if execution_name: + execution_id = db.get_document_id_by_field_value("title", execution_name, db.collection_executions) + + # S3 + s3_keys = db.get_all_outputs_s3_keys(execution_id) + s3M = s3Manager() + s3M.deletePaths(s3_keys) + + # DB + db.delete_execution(execution_id) + + # Folders + if project_path: + odtp_env.delete_folder(project_path, keep_project_path=keep_project_path) + + except Exception as e: + msg = f"ERROR: Delete execution failed: {e}" + log.exception(msg) + print(msg) + raise typer.Abort() + else: + msg = "SUCCESS: execution has been deleted" + log.info(msg) + print(msg) + if __name__ == "__main__": app() diff --git a/odtp/cli/new.py b/odtp/cli/new.py index 2fcb0b08..23d8ef61 100644 --- a/odtp/cli/new.py +++ b/odtp/cli/new.py @@ -78,7 +78,7 @@ def digital_twin_entry( raise typer.Exit("Please provide either --user-id or --user-email") if user_email: - user_id = db.get_document_id_by_field_value("user_email", user_email, "users") + user_id = db.get_document_id_by_field_value("email", user_email, "users") dt_id = db.add_digital_twin(userRef=user_id, name=name) log.info(f"Digital Twin added with ID {dt_id}") diff --git a/odtp/helpers/environment.py b/odtp/helpers/environment.py index 5c7ab88c..b8317a84 100644 --- a/odtp/helpers/environment.py +++ b/odtp/helpers/environment.py @@ -1,9 +1,12 @@ import os +import shutil +import logging import odtp.helpers.utils as utils import odtp.helpers.utils as odtp_utils import odtp.mongodb.db as db +log = logging.getLogger(__name__) class OdtpLocalEnvironmentException(Exception): pass @@ -58,3 +61,12 @@ def directory_has_output(execution_id, project_folder): if len(os.listdir(output_dir)) != 0: return True return False + +def delete_folder(folder_path, keep_project_path=True): + if os.path.exists(folder_path): + shutil.rmtree(folder_path) + + if keep_project_path: + os.mkdir(folder_path) + + log.info("Folder deleted: %s", folder_path) \ No newline at end of file diff --git a/odtp/mongodb/db.py b/odtp/mongodb/db.py index 4d366fdd..e8635ca2 100644 --- a/odtp/mongodb/db.py +++ b/odtp/mongodb/db.py @@ -124,10 +124,11 @@ def check_document_id_in_collection(document_id, collection): def delete_document_by_id(document_id, collection): + log.debug(f"Deleting {collection} : {document_id}") with MongoClient(ODTP_MONGO_SERVER) as client: db = client[ODTP_MONGO_DB] document = db[collection].delete_one({"_id": ObjectId(document_id)}) - log.info(f"Document with ID {document_id} was deleted") + log.debug(f"Document with ID {document_id} was deleted") def get_sub_collection_items(collection, sub_collection, item_id, ref_name, sort_by=None): @@ -165,6 +166,26 @@ def get_component_version(component_name, version_tag): version_documents = mongodb_utils.get_list_from_cursor(cursor) return version_documents +def get_documents_id_by_field_value(field_path, field_value, collection): + with MongoClient(ODTP_MONGO_SERVER) as client: + db = client[ODTP_MONGO_DB] + documents_cursors = db[collection].find({field_path: field_value}, {"_id": 1}) + + documents = [str(doc["_id"]) for doc in documents_cursors] + if len(documents) > 0: + return documents + else: + return None + +def remove_value_from_list_in_field(collection, document_id, field_name, value): + with MongoClient(ODTP_MONGO_SERVER) as client: + db = client[ODTP_MONGO_DB] + db[collection].update_one( + {"_id": ObjectId(document_id)}, + {"$pull": {field_name: value}} + ) + + def add_user(name, github, email): """add new user and return id""" @@ -406,6 +427,51 @@ def append_step_to_execution(db, execution_id, step): db.executions.update_one({"_id": execution_id}, {"$push": {"steps": step_id}}) return step_id +def get_all_outputs_s3_keys(execution_id): + execution_doc = get_document_by_id(execution_id, collection_executions) + digital_twin_id = execution_doc["digitalTwinRef"] + steps_ids = execution_doc['steps'] + + s3_keys = [] + for step_id in steps_ids: + output_ids = get_documents_id_by_field_value("stepRef", str(step_id), collection_outputs) + if output_ids: + s3_keys += [get_document_by_id(output_id, collection_outputs)["s3_key"] for output_id in output_ids] + + return s3_keys + +def delete_execution(execution_id, debug=True): + # DB + # Delete execution, steps, output, logs, + # Update: remove id from results, remove execution from dt + execution_doc = get_document_by_id(execution_id, collection_executions) + digital_twin_id = execution_doc["digitalTwinRef"] + # TODO: Waiting for results to be implemented + #results_id = get_document_by_id(digital_twin_id, collection_digital_twins)["results"][0] + + steps_ids = execution_doc['steps'] + for step_id in steps_ids: + logs_ids = get_documents_id_by_field_value("stepRef", str(step_id), collection_logs) + if logs_ids: + _ = [delete_document_by_id(log_id, collection_logs) for log_id in logs_ids] + + output_ids = get_documents_id_by_field_value("stepRef", str(step_id), collection_outputs) + if output_ids: + # Update the results document without any outputs reference + for output_id in output_ids: + # TODO: Waiting for results to be implemented + #_ = remove_value_from_list_in_field(collection_results, results_id, "output", ObjectId(output_id)) + pass + # Delete the output document + _ = [delete_document_by_id(output_id, collection_outputs) for output_id in output_ids] + + _ = delete_document_by_id(step_id, collection_steps) + + _ = delete_document_by_id(execution_id, collection_executions) + + # Update the digital twin document without the execution reference + _ = remove_value_from_list_in_field(collection_digital_twins, digital_twin_id, "executions", ObjectId(execution_id)) + def delete_collection(collection): with MongoClient(ODTP_MONGO_SERVER) as client: diff --git a/odtp/run.py b/odtp/run.py index 9595c266..6a6f1dd2 100644 --- a/odtp/run.py +++ b/odtp/run.py @@ -221,7 +221,7 @@ def run_component(self, parameters, secrets, ports, container_name, step_id=None process = subprocess.Popen(command_string, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) output, error = process.communicate() - + if process.returncode != 0: log.exception(f"Failed to run Docker component {container_name}: {error.decode()}") return None diff --git a/odtp/storage.py b/odtp/storage.py index fdedd653..4bbb8872 100644 --- a/odtp/storage.py +++ b/odtp/storage.py @@ -122,6 +122,23 @@ def deleteFile(self, s3_path): self.s3.delete_object(Bucket=self.bucketName, Key=s3_path) log.info(f"File '{s3_path}' deleted from S3 bucket") + # Method to delete multiple files in s3 + def deletePaths(self, s3_paths): + """ + Deletes multiple files from specific paths in the S3 bucket. + Args: + s3_paths (list): A list of S3 paths of the files to delete. + Returns: + None + """ + + for s3_path in s3_paths: + objects_to_delete = self.s3.list_objects(Bucket=self.bucketName, Prefix=s3_path) + if 'Contents' in objects_to_delete: + for key in objects_to_delete['Contents']: + self.s3.delete_object(Bucket=self.bucketName, Key=key['Key']) + log.info(f"Path '{s3_path}' deleted from S3 bucket") + def create_folders(self, structure): self.s3.createFolderStructure(structure) log.info("Folder structure generated") From c4b0bfaa1fe3f622082952075933fbe9d2170c5d Mon Sep 17 00:00:00 2001 From: caviri <45425937+caviri@users.noreply.github.com> Date: Wed, 3 Jul 2024 12:48:01 +0200 Subject: [PATCH 25/28] chore(Version & Authors): Update for v0.4.0 --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 838180e4..f1f54423 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,8 @@ [tool.poetry] name = "odtp" -version = "0.3.1" +version = "0.4.0" description = "A tool to deploy and manage open digital twins" -authors = ["caviri ", "sabinem "] +authors = ["caviri ", "sabinem ", "sabrinaossey ", "rmfranken "] license = "AGPL 3.0" readme = "README.md" From b68a6333ad9f1be19c19e192c818ed1703221400 Mon Sep 17 00:00:00 2001 From: Sabine Maennel Date: Wed, 3 Jul 2024 13:45:26 +0200 Subject: [PATCH 26/28] chore(.env.dist files): provide extra file for dev setup (#184) Co-authored-by: sabinem <5292683+sabinem@users.noreply.github.com> --- .env.dist.compose | 12 ++++++----- .env.dist.compose.dev | 48 +++++++++++++++++++++++++++++++++++++++++++ .env.dist.local | 8 +++++--- .gitignore | 2 +- 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 .env.dist.compose.dev diff --git a/.env.dist.compose b/.env.dist.compose index f445f2b7..94961488 100644 --- a/.env.dist.compose +++ b/.env.dist.compose @@ -7,11 +7,11 @@ # odtp db instance in the mongo db: "odtp" ODTP_MONGO_DB= -# s3 bucket name: "odtp" +# s3 bucket name: "odtp" ODTP_BUCKET_NAME= # s3 access and secret key -ODTP_ACCESS_KEY= +ODTP_ACCESS_KEY= ODTP_SECRET_KEY= # your github token @@ -34,9 +34,11 @@ MONGODB_PATH= ODTP_DASHBOARD_PORT= ODTP_DASHBOARD_JSON_EDITOR= -# Log level -ODTP_LOG_LEVEL= -RUN_LOG_LEVEL= +# Log Level General +ODTP_LOG_LEVEL=ERROR + +# Log Level when running executions +RUN_LOG_LEVEL=INFO # App Path APP_PATH= diff --git a/.env.dist.compose.dev b/.env.dist.compose.dev new file mode 100644 index 00000000..1e132a27 --- /dev/null +++ b/.env.dist.compose.dev @@ -0,0 +1,48 @@ +# environment variables for installation with docker compose +# with the dev version: compose.dev.yml +# ----------------------------------------------------------- +# fill these variables in case you want to install odtp with +# docker compose + +# local setup and compose + +# odtp db instance in the mongo db: "odtp" +ODTP_MONGO_DB= +# s3 bucket name: "odtp" +ODTP_BUCKET_NAME= + +# s3 access and secret key +ODTP_ACCESS_KEY= +ODTP_SECRET_KEY= + +# your github token +GITHUB_TOKEN= + +# mongodb user and password +MONGO_DB_USER= +MONGO_DB_PASSWORD= + +# mongoexpress user and password +MONGO_EXPRESS_USER= +MONGO_EXPRESS_PASSWORD= + +# absolute path for docker volumes +ODTP_PATH= +MINIO_PATH= +MONGODB_PATH= + +# Dashboard parameters +ODTP_DASHBOARD_PORT= +ODTP_DASHBOARD_JSON_EDITOR= + +# Log Level General +ODTP_LOG_LEVEL=ERROR + +# Log Level when running executions +RUN_LOG_LEVEL=INFO + +# App Path +APP_PATH= + +# Install the package in editable mode. +PIP_INSTALL_ARGS="--editable" diff --git a/.env.dist.local b/.env.dist.local index c33b3c32..893b9da9 100644 --- a/.env.dist.local +++ b/.env.dist.local @@ -29,6 +29,8 @@ ODTP_DASHBOARD_JSON_EDITOR= # Working directory for user projects ODTP_PATH= -# Log level -ODTP_LOG_LEVEL= -RUN_LOG_LEVEL= +# Log Level General +ODTP_LOG_LEVEL=ERROR + +# Log Level when running executions +RUN_LOG_LEVEL=INFO diff --git a/.gitignore b/.gitignore index 6d8a2794..6bdec2cf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ __pycache__/ .DS_Store .env* -!.env*.dist +!.env.dist.* .nicegui .local odtp/odtp.log From b1748c73ee81aa175125ef39b9ecf042f097434a Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Wed, 3 Jul 2024 14:49:30 +0200 Subject: [PATCH 27/28] chore(changelog): v0.3.1/v0.4.0 changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59db811b..9dd9f8d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ ## Changelog +- v0.4.0 + - gui: the general workflow for the user was improved (new Items are selected automatically for example) + - gui: validation has been implemented in the forms to make sure data that is entered will be valid + - gui: the run page for executions has been improved in the gui: logs are now also available from the gui when a workflow runs + - gui: on the dashboard homepage you can now directly see whether all services including github are connected + - logging: improve logging at GUI/CLI: run commands are now logged to a file, while everything else is still logged to the command line: this is so run commands can be easier debugged by knowing what was run in docker and how that run was triggered + - logging: the logs of the execution runs are now exposed as volumes, so that will be directly available when the component starts and will remain in the project path even after a component exited prematurely + - execution: execution and step timestamps + - cli: printing table from mongodb colleciton + - cli: delete methods for execution and related items. + - components: avoid rebuilding image if component is available + - compose: a dev version for docker compose has been added to facilitate development + +- v0.3.1 + - hotfixes for bugs + - removal of unused dependencies and adition of pandas + - v0.3.0 dashboard refactoring - dashboard was refactored since code files were getting too long - homepage of the dashboard got an upgrade and also contains now connection checks From f5a49b1131f1cca0060bfbc8d69862cf4593bae0 Mon Sep 17 00:00:00 2001 From: Carlos Vivar Rios <45425937+caviri@users.noreply.github.com> Date: Wed, 3 Jul 2024 15:13:53 +0200 Subject: [PATCH 28/28] chore(changelog): Added workarea changes --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dd9f8d1..2012ee76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - gui: validation has been implemented in the forms to make sure data that is entered will be valid - gui: the run page for executions has been improved in the gui: logs are now also available from the gui when a workflow runs - gui: on the dashboard homepage you can now directly see whether all services including github are connected + - gui: the workarea in the dashboard was removed and replace by an info section on top of the pages - logging: improve logging at GUI/CLI: run commands are now logged to a file, while everything else is still logged to the command line: this is so run commands can be easier debugged by knowing what was run in docker and how that run was triggered - logging: the logs of the execution runs are now exposed as volumes, so that will be directly available when the component starts and will remain in the project path even after a component exited prematurely - execution: execution and step timestamps