From 204fc56794e8eafb11f08e841378eaa1b17ac26e Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 13 Dec 2022 14:11:07 -0500 Subject: [PATCH 001/615] schematic docker container publish through ghcr.io --- .github/workflows/docker_build.yml | 49 ++++++++++++++++++++++++++++++ Dockerfile | 2 ++ 2 files changed, 51 insertions(+) create mode 100644 .github/workflows/docker_build.yml diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml new file mode 100644 index 000000000..9ebdd3664 --- /dev/null +++ b/.github/workflows/docker_build.yml @@ -0,0 +1,49 @@ +# Taken from https://github.com/Sage-Bionetworks/data_curator/blob/schematic-rest-api/.github/workflows/docker_build.yml +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help + +name: Create and publish a Docker image + +on: + push: + tags: + - '*beta*' + +env: + REGISTRY: ghcr.io + IMAGE_PATH: ghcr.io/${{ github.repository }} + +jobs: + build-and-push-image: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Log in to the Container registry + uses: docker/login-action@f054a8b539a109f9f41c372932f1ae047eff08c9 + with: + registry: ${{ env.REGISTRY }} + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Extract metadata (tags, labels) for Docker + id: meta + uses: docker/metadata-action@98669ae865ea3cffbcbaa878cf57c20bbf1c6c38 + with: + images: ${{ env.IMAGE_PATH }} + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{raw}} + - name: Build and push Docker image + uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index 833b74f92..d1dea5ed5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -30,3 +30,5 @@ RUN poetry install --no-interaction --no-ansi --no-root COPY . ./ RUN poetry install --no-interaction --no-ansi --only-root + +CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file From 45786a2b3a6f9c687b8792ef4b8d0fae786dcd81 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 13 Dec 2022 15:04:44 -0500 Subject: [PATCH 002/615] ignore tags related to docker image publish --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index e0658f7d5..bbffcd480 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -2,7 +2,7 @@ name: Publish to PyPI on: push: tags: - - '*' + - 'v[1-9][0-9].[0-9]+.[0-9]+' branches: [main] jobs: From 272e365acd16048dfd741da9adb8dc182ca4f427 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 13 Dec 2022 16:17:59 -0500 Subject: [PATCH 003/615] remove entry point --- Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index d1dea5ed5..b452a3dd8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,6 +29,4 @@ RUN poetry install --no-interaction --no-ansi --no-root COPY . ./ -RUN poetry install --no-interaction --no-ansi --only-root - -CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file +RUN poetry install --no-interaction --no-ansi --only-root \ No newline at end of file From 1147f4429aca21627bf540785560c00b2643ad0d Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 14 Dec 2022 14:53:29 -0500 Subject: [PATCH 004/615] remove sqlite3 for security reason --- Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index b452a3dd8..92ee72662 100644 --- a/Dockerfile +++ b/Dockerfile @@ -16,8 +16,8 @@ RUN apt-get update -qqy \ libopenblas-dev \ gfortran -# remove libtiff5 for security reasons -RUN apt remove -y libtiff5 +# remove libtiff5 and sqlite3 for security reasons +RUN apt remove -y libtiff5 sqlite3 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" From 60154b54d70008347e06753978bcd1c8ba6b0f66 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Dec 2022 12:04:50 -0500 Subject: [PATCH 005/615] change base image to 3.10.9 --- Dockerfile | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 92ee72662..9f205b273 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,4 @@ -# FROM python:3.10.6 -FROM python:3.10.8-slim-bullseye +FROM python:3.10.9-slim-bullseye ENV PYTHONFAULTHANDLER=1 \ PYTHONUNBUFFERED=1 \ @@ -7,7 +6,7 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0rc1 + POETRY_VERSION=1.2.0 WORKDIR /usr/src/app @@ -17,7 +16,7 @@ RUN apt-get update -qqy \ gfortran # remove libtiff5 and sqlite3 for security reasons -RUN apt remove -y libtiff5 sqlite3 +RUN apt remove -y libtiff5 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" From 31f3c4df0d8d49e41481f180e3c79733001ebb07 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 16 Dec 2022 13:40:51 -0500 Subject: [PATCH 006/615] add entry point back --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 9f205b273..14dd6231d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,4 +28,6 @@ RUN poetry install --no-interaction --no-ansi --no-root COPY . ./ -RUN poetry install --no-interaction --no-ansi --only-root \ No newline at end of file +RUN poetry install --no-interaction --no-ansi --only-root + +CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file From cf8242ec03fbb74b4d674e2ec091e6593b436dd1 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 16 Dec 2022 17:39:23 -0500 Subject: [PATCH 007/615] remove duplicated line in docker file --- Dockerfile | 2 -- 1 file changed, 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 14dd6231d..a7c445d7d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -28,6 +28,4 @@ RUN poetry install --no-interaction --no-ansi --no-root COPY . ./ -RUN poetry install --no-interaction --no-ansi --only-root - CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file From ae4866abc0361281db5524ba2043be0f69831cd8 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 21 Dec 2022 13:57:57 -0500 Subject: [PATCH 008/615] print all env variables for testing --- schematic/utils/google_api_utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/utils/google_api_utils.py b/schematic/utils/google_api_utils.py index 8e7fa682b..b59515cf0 100644 --- a/schematic/utils/google_api_utils.py +++ b/schematic/utils/google_api_utils.py @@ -65,6 +65,7 @@ def build_credentials() -> Dict[str, Any]: def build_service_account_creds() -> Dict[str, Any]: + print('see all the environment variable', print(os.environ)) if "SERVICE_ACCOUNT_CREDS" in os.environ: dict_creds=json.loads(os.environ["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) From 996491c26e9cc2addb40557df8c42dd0acda8598 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 22 Dec 2022 14:32:43 -0500 Subject: [PATCH 009/615] add test printing --- schematic/utils/google_api_utils.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/schematic/utils/google_api_utils.py b/schematic/utils/google_api_utils.py index b59515cf0..c4c9aa756 100644 --- a/schematic/utils/google_api_utils.py +++ b/schematic/utils/google_api_utils.py @@ -65,10 +65,21 @@ def build_credentials() -> Dict[str, Any]: def build_service_account_creds() -> Dict[str, Any]: - print('see all the environment variable', print(os.environ)) + print('check if SERVICE_ACCOUNT_CREDS environment variable exists', "SERVICE_ACCOUNT_CREDS" in os.environ) + print('get SERVICE_ACCOUNT_CREDS', os.environ.get('SERVICE_ACCOUNT_CREDS', 'default')) + print('get SECRETS_MANAGER_SECRETS', os.environ.get('SECRETS_MANAGER_SECRETS', 'default2')) + print('TEST_CREDS', os.environ.get('TEST_CREDS', 'default3')) + if "SERVICE_ACCOUNT_CREDS" in os.environ: dict_creds=json.loads(os.environ["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) + + # for AWS deployment + elif "SECRETS_MANAGER_SECRETS" in os.environ: + print('this line is being executed') + dict_creds = json.loads(os.environ["SECRETS_MANAGER_SECRETS"]) + print('dict_creds', dict_creds) + credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) else: credentials = service_account.Credentials.from_service_account_file( CONFIG.SERVICE_ACCT_CREDS, scopes=SCOPES From 7a25a1632298a140b51ca52953e70e0d38f7cf78 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 22 Dec 2022 17:25:44 -0500 Subject: [PATCH 010/615] add boto3 --- poetry.lock | 132 +++++++++++++++++++++++----- pyproject.toml | 1 + schematic/utils/google_api_utils.py | 11 ++- 3 files changed, 120 insertions(+), 24 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4c3b9f23b..bee60434c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -120,10 +120,10 @@ optional = false python-versions = ">=3.5" [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope.interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope.interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope.interface"] -tests-no-zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope-interface"] +docs = ["furo", "sphinx", "sphinx-notfound-page", "zope-interface"] +tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope-interface"] +tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] [[package]] name = "babel" @@ -193,6 +193,38 @@ webencodings = "*" css = ["tinycss2 (>=1.1.0,<1.2)"] dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] +[[package]] +name = "boto3" +version = "1.26.36" +description = "The AWS SDK for Python" +category = "main" +optional = false +python-versions = ">= 3.7" + +[package.dependencies] +botocore = ">=1.29.36,<1.30.0" +jmespath = ">=0.7.1,<2.0.0" +s3transfer = ">=0.6.0,<0.7.0" + +[package.extras] +crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] + +[[package]] +name = "botocore" +version = "1.29.36" +description = "Low-level, data-driven core of boto 3." +category = "main" +optional = false +python-versions = ">= 3.7" + +[package.dependencies] +jmespath = ">=0.7.1,<2.0.0" +python-dateutil = ">=2.1,<3.0.0" +urllib3 = ">=1.25.4,<1.27" + +[package.extras] +crt = ["awscrt (==0.15.3)"] + [[package]] name = "cachetools" version = "5.2.0" @@ -229,7 +261,7 @@ optional = false python-versions = ">=3.6.0" [package.extras] -unicode-backport = ["unicodedata2"] +unicode_backport = ["unicodedata2"] [[package]] name = "click" @@ -383,7 +415,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "docutils" @@ -516,7 +548,7 @@ six = ">=1.9.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] -enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +enterprise_cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] @@ -617,9 +649,9 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] arrow = ["feather-format (>=0.4.1)", "pyarrow"] athena = ["pyathena (>=1.11)", "sqlalchemy (>=1.3.18,<2.0.0)"] -aws-secrets = ["boto3 (==1.17.106)"] +aws_secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] -azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] +azure_secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydantic (>=1.0,<2.0)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] @@ -682,7 +714,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flake8 (<5)", "flufl-flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "inflection" @@ -829,7 +861,7 @@ python-versions = ">=3.7" [package.extras] test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async_generator", "trio"] +trio = ["async-generator", "trio"] [[package]] name = "jinja2" @@ -845,6 +877,14 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] +[[package]] +name = "jmespath" +version = "1.0.1" +description = "JSON Matching Expressions" +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "jsonpatch" version = "1.32" @@ -881,7 +921,7 @@ six = ">=1.11.0" [package.extras] format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format_nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] [[package]] name = "jupyter-client" @@ -987,7 +1027,7 @@ six = "*" [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] +testing = ["backports-unittest-mock", "collective-checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] [[package]] name = "makefun" @@ -1702,7 +1742,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-oauthlib" @@ -1753,6 +1793,20 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "s3transfer" +version = "0.6.0" +description = "An Amazon S3 Transfer Manager" +category = "main" +optional = false +python-versions = ">= 3.7" + +[package.dependencies] +botocore = ">=1.12.36,<2.0a.0" + +[package.extras] +crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] + [[package]] name = "scipy" version = "1.7.3" @@ -1785,8 +1839,8 @@ optional = false python-versions = "*" [package.extras] -nativelib = ["pyobjc-framework-Cocoa", "pywin32"] -objc = ["pyobjc-framework-Cocoa"] +nativelib = ["pyobjc-framework-cocoa", "pywin32"] +objc = ["pyobjc-framework-cocoa"] win32 = ["pywin32"] [[package]] @@ -1801,7 +1855,7 @@ python-versions = ">=3.6" certs = ["certifi (==2016.9.26)"] docs = ["jaraco.packaging (>=8.2)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx"] ssl = ["wincertstore (==0.2)"] -testing = ["flake8-2020", "jaraco.envs", "mock", "paver", "pip (>=19.1)", "pytest (>=3.5,!=3.7.3)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "virtualenv (>=13.0.0)", "wheel"] +testing = ["flake8-2020", "jaraco-envs", "mock", "paver", "pip (>=19.1)", "pytest (>=3.5,!=3.7.3)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -2105,7 +2159,7 @@ pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] +devenv = ["black", "pyroma", "pytest-cov", "zest-releaser"] test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] [[package]] @@ -2207,12 +2261,12 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco-functools", "jaraco-itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.7.1,<3.11" -content-hash = "3292d40bff445ff16b9c13585b4b3dbd47d6328807367ac8efdeccdb96da349c" +content-hash = "0143bd1854720814a8a121ebcbc656ddbaa7874fb838c3ff37ace877fe6294f9" [metadata.files] alabaster = [ @@ -2306,6 +2360,14 @@ bleach = [ {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, ] +boto3 = [ + {file = "boto3-1.26.36-py3-none-any.whl", hash = "sha256:8bd5fdd528260c4da3e070c00468cfd4a50ad75570e81a409970c4490fdee458"}, + {file = "boto3-1.26.36.tar.gz", hash = "sha256:061c3f0022227a02902d9b3737214f9a3de86f5ba70953c6515d68391c735709"}, +] +botocore = [ + {file = "botocore-1.29.36-py3-none-any.whl", hash = "sha256:927dd5c6b155f30d122c1d34f96aba8502e2e02f2d7a170351804d3de81f0c5e"}, + {file = "botocore-1.29.36.tar.gz", hash = "sha256:5cb1fb381c427fe12274eb866f2ff739169e0e1f33c2481a474ba2ff8ca43f75"}, +] cachetools = [ {file = "cachetools-5.2.0-py3-none-any.whl", hash = "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"}, {file = "cachetools-5.2.0.tar.gz", hash = "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757"}, @@ -2640,6 +2702,10 @@ jinja2 = [ {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, ] +jmespath = [ + {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, + {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, +] jsonpatch = [ {file = "jsonpatch-1.32-py2.py3-none-any.whl", hash = "sha256:26ac385719ac9f54df8a2f0827bb8253aa3ea8ab7b3368457bcdb8c14595a397"}, {file = "jsonpatch-1.32.tar.gz", hash = "sha256:b6ddfe6c3db30d81a96aaeceb6baf916094ffa23d7dd5fa2c13e13f8b6e600c2"}, @@ -2951,12 +3017,34 @@ py = [ {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pyasn1-modules = [ {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, + {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, + {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, + {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, + {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, + {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, + {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, + {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, + {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, + {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, + {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, ] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, @@ -3352,6 +3440,10 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] +s3transfer = [ + {file = "s3transfer-0.6.0-py3-none-any.whl", hash = "sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd"}, + {file = "s3transfer-0.6.0.tar.gz", hash = "sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"}, +] scipy = [ {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, diff --git a/pyproject.toml b/pyproject.toml index 9ca4d70e1..71d27d6e7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,6 +68,7 @@ openpyxl = "^3.0.9" Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" +boto3 = "^1.26.36" [tool.poetry.dev-dependencies] diff --git a/schematic/utils/google_api_utils.py b/schematic/utils/google_api_utils.py index c4c9aa756..d56a4cee0 100644 --- a/schematic/utils/google_api_utils.py +++ b/schematic/utils/google_api_utils.py @@ -3,6 +3,7 @@ import logging import json import pygsheets as ps +import boto3 from typing import Dict, Any @@ -65,8 +66,6 @@ def build_credentials() -> Dict[str, Any]: def build_service_account_creds() -> Dict[str, Any]: - print('check if SERVICE_ACCOUNT_CREDS environment variable exists', "SERVICE_ACCOUNT_CREDS" in os.environ) - print('get SERVICE_ACCOUNT_CREDS', os.environ.get('SERVICE_ACCOUNT_CREDS', 'default')) print('get SECRETS_MANAGER_SECRETS', os.environ.get('SECRETS_MANAGER_SECRETS', 'default2')) print('TEST_CREDS', os.environ.get('TEST_CREDS', 'default3')) @@ -77,8 +76,12 @@ def build_service_account_creds() -> Dict[str, Any]: # for AWS deployment elif "SECRETS_MANAGER_SECRETS" in os.environ: print('this line is being executed') - dict_creds = json.loads(os.environ["SECRETS_MANAGER_SECRETS"]) - print('dict_creds', dict_creds) + session = boto3.session.Session() + region_name = os.environ['AWS_REGION'] + client = session.client(service_name='secretsmanager', region_name=region_name) + secret_value_response = client.get_secret_value(SecretId="schematic-test") + all_secrets = json.loads(secret_value_response['SecretString']) + dict_creds=json.loads(all_secrets["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) else: credentials = service_account.Credentials.from_service_account_file( From 615531b9de766cc6b23def0b6a428f3a533a93aa Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 22 Dec 2022 18:31:05 -0500 Subject: [PATCH 011/615] remove boto3; try loading SECRETS_MANAGER_SECRETS env variable --- poetry.lock | 72 +---------------------------- pyproject.toml | 1 - schematic/utils/google_api_utils.py | 12 +---- 3 files changed, 3 insertions(+), 82 deletions(-) diff --git a/poetry.lock b/poetry.lock index bee60434c..5bfb7bd30 100644 --- a/poetry.lock +++ b/poetry.lock @@ -193,38 +193,6 @@ webencodings = "*" css = ["tinycss2 (>=1.1.0,<1.2)"] dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] -[[package]] -name = "boto3" -version = "1.26.36" -description = "The AWS SDK for Python" -category = "main" -optional = false -python-versions = ">= 3.7" - -[package.dependencies] -botocore = ">=1.29.36,<1.30.0" -jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.6.0,<0.7.0" - -[package.extras] -crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] - -[[package]] -name = "botocore" -version = "1.29.36" -description = "Low-level, data-driven core of boto 3." -category = "main" -optional = false -python-versions = ">= 3.7" - -[package.dependencies] -jmespath = ">=0.7.1,<2.0.0" -python-dateutil = ">=2.1,<3.0.0" -urllib3 = ">=1.25.4,<1.27" - -[package.extras] -crt = ["awscrt (==0.15.3)"] - [[package]] name = "cachetools" version = "5.2.0" @@ -877,14 +845,6 @@ MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] -[[package]] -name = "jmespath" -version = "1.0.1" -description = "JSON Matching Expressions" -category = "main" -optional = false -python-versions = ">=3.7" - [[package]] name = "jsonpatch" version = "1.32" @@ -1793,20 +1753,6 @@ category = "main" optional = false python-versions = ">=3.5" -[[package]] -name = "s3transfer" -version = "0.6.0" -description = "An Amazon S3 Transfer Manager" -category = "main" -optional = false -python-versions = ">= 3.7" - -[package.dependencies] -botocore = ">=1.12.36,<2.0a.0" - -[package.extras] -crt = ["botocore[crt] (>=1.20.29,<2.0a.0)"] - [[package]] name = "scipy" version = "1.7.3" @@ -2266,7 +2212,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco-functools", "jaraco-itertools" [metadata] lock-version = "1.1" python-versions = ">=3.7.1,<3.11" -content-hash = "0143bd1854720814a8a121ebcbc656ddbaa7874fb838c3ff37ace877fe6294f9" +content-hash = "3292d40bff445ff16b9c13585b4b3dbd47d6328807367ac8efdeccdb96da349c" [metadata.files] alabaster = [ @@ -2360,14 +2306,6 @@ bleach = [ {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, ] -boto3 = [ - {file = "boto3-1.26.36-py3-none-any.whl", hash = "sha256:8bd5fdd528260c4da3e070c00468cfd4a50ad75570e81a409970c4490fdee458"}, - {file = "boto3-1.26.36.tar.gz", hash = "sha256:061c3f0022227a02902d9b3737214f9a3de86f5ba70953c6515d68391c735709"}, -] -botocore = [ - {file = "botocore-1.29.36-py3-none-any.whl", hash = "sha256:927dd5c6b155f30d122c1d34f96aba8502e2e02f2d7a170351804d3de81f0c5e"}, - {file = "botocore-1.29.36.tar.gz", hash = "sha256:5cb1fb381c427fe12274eb866f2ff739169e0e1f33c2481a474ba2ff8ca43f75"}, -] cachetools = [ {file = "cachetools-5.2.0-py3-none-any.whl", hash = "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"}, {file = "cachetools-5.2.0.tar.gz", hash = "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757"}, @@ -2702,10 +2640,6 @@ jinja2 = [ {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, ] -jmespath = [ - {file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"}, - {file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"}, -] jsonpatch = [ {file = "jsonpatch-1.32-py2.py3-none-any.whl", hash = "sha256:26ac385719ac9f54df8a2f0827bb8253aa3ea8ab7b3368457bcdb8c14595a397"}, {file = "jsonpatch-1.32.tar.gz", hash = "sha256:b6ddfe6c3db30d81a96aaeceb6baf916094ffa23d7dd5fa2c13e13f8b6e600c2"}, @@ -3440,10 +3374,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] -s3transfer = [ - {file = "s3transfer-0.6.0-py3-none-any.whl", hash = "sha256:06176b74f3a15f61f1b4f25a1fc29a4429040b7647133a463da8fa5bd28d5ecd"}, - {file = "s3transfer-0.6.0.tar.gz", hash = "sha256:2ed07d3866f523cc561bf4a00fc5535827981b117dd7876f036b0c1aca42c947"}, -] scipy = [ {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, diff --git a/pyproject.toml b/pyproject.toml index 71d27d6e7..9ca4d70e1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,6 @@ openpyxl = "^3.0.9" Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" -boto3 = "^1.26.36" [tool.poetry.dev-dependencies] diff --git a/schematic/utils/google_api_utils.py b/schematic/utils/google_api_utils.py index d56a4cee0..4cdf20c19 100644 --- a/schematic/utils/google_api_utils.py +++ b/schematic/utils/google_api_utils.py @@ -3,7 +3,6 @@ import logging import json import pygsheets as ps -import boto3 from typing import Dict, Any @@ -67,21 +66,14 @@ def build_credentials() -> Dict[str, Any]: def build_service_account_creds() -> Dict[str, Any]: print('get SECRETS_MANAGER_SECRETS', os.environ.get('SECRETS_MANAGER_SECRETS', 'default2')) - print('TEST_CREDS', os.environ.get('TEST_CREDS', 'default3')) - if "SERVICE_ACCOUNT_CREDS" in os.environ: dict_creds=json.loads(os.environ["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) # for AWS deployment elif "SECRETS_MANAGER_SECRETS" in os.environ: - print('this line is being executed') - session = boto3.session.Session() - region_name = os.environ['AWS_REGION'] - client = session.client(service_name='secretsmanager', region_name=region_name) - secret_value_response = client.get_secret_value(SecretId="schematic-test") - all_secrets = json.loads(secret_value_response['SecretString']) - dict_creds=json.loads(all_secrets["SERVICE_ACCOUNT_CREDS"]) + all_secrets_dict =json.loads(os.environ["SECRETS_MANAGER_SECRETS"]) + dict_creds=json.loads(all_secrets_dict["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) else: credentials = service_account.Credentials.from_service_account_file( From 2945a69d2fce2e540e31e16ceb4677152a37e1de Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 3 Jan 2023 11:06:09 -0500 Subject: [PATCH 012/615] delete old code --- schematic/utils/google_api_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/utils/google_api_utils.py b/schematic/utils/google_api_utils.py index 4cdf20c19..8844c3da0 100644 --- a/schematic/utils/google_api_utils.py +++ b/schematic/utils/google_api_utils.py @@ -65,7 +65,6 @@ def build_credentials() -> Dict[str, Any]: def build_service_account_creds() -> Dict[str, Any]: - print('get SECRETS_MANAGER_SECRETS', os.environ.get('SECRETS_MANAGER_SECRETS', 'default2')) if "SERVICE_ACCOUNT_CREDS" in os.environ: dict_creds=json.loads(os.environ["SERVICE_ACCOUNT_CREDS"]) credentials = service_account.Credentials.from_service_account_info(dict_creds, scopes=SCOPES) From 598fb68fe390b05886d7207a3ac315df1b6ea575 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:10:06 -0500 Subject: [PATCH 013/615] try building dockerfile from sub directory --- .github/workflows/docker_build.yml | 3 ++- aws/Dockerfile | 32 ++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 aws/Dockerfile diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 9ebdd3664..33a07817a 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,8 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - context: . + context: ./aws + file: ./aws/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/aws/Dockerfile b/aws/Dockerfile new file mode 100644 index 000000000..91b8071e2 --- /dev/null +++ b/aws/Dockerfile @@ -0,0 +1,32 @@ +# FROM python:3.10.6 +FROM python:3.10.8-slim-bullseye + +ENV PYTHONFAULTHANDLER=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONHASHSEED=random \ + PIP_NO_CACHE_DIR=off \ + PIP_DISABLE_PIP_VERSION_CHECK=on \ + PIP_DEFAULT_TIMEOUT=200 \ + POETRY_VERSION=1.2.0rc1 + +WORKDIR /usr/src/app + +RUN apt-get update -qqy \ + && apt-get install -qqy \ + libopenblas-dev \ + gfortran + +# remove libtiff5 for security reasons +RUN apt remove -y libtiff5 + +RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" + +COPY pyproject.toml poetry.lock ./ + +RUN poetry config virtualenvs.create false + +RUN poetry install --no-interaction --no-ansi --no-root + +COPY . ./ + +RUN poetry install --no-interaction --no-ansi --only-root \ No newline at end of file From e11355485657385be95e23939d6d0e58f7dc8d70 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:13:09 -0500 Subject: [PATCH 014/615] edit file path --- aws/Dockerfile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aws/Dockerfile b/aws/Dockerfile index 91b8071e2..8bbf6b708 100644 --- a/aws/Dockerfile +++ b/aws/Dockerfile @@ -21,12 +21,12 @@ RUN apt remove -y libtiff5 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" -COPY pyproject.toml poetry.lock ./ +COPY ../pyproject.toml poetry.lock ./ RUN poetry config virtualenvs.create false RUN poetry install --no-interaction --no-ansi --no-root -COPY . ./ +COPY ../ ./ RUN poetry install --no-interaction --no-ansi --only-root \ No newline at end of file From 09f68eb84b2bd1922357ef0f6ee745e041509d32 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:18:49 -0500 Subject: [PATCH 015/615] update path of poetry.lock --- aws/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aws/Dockerfile b/aws/Dockerfile index 8bbf6b708..c9221f45f 100644 --- a/aws/Dockerfile +++ b/aws/Dockerfile @@ -21,7 +21,7 @@ RUN apt remove -y libtiff5 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" -COPY ../pyproject.toml poetry.lock ./ +COPY ../pyproject.toml ../poetry.lock ./ RUN poetry config virtualenvs.create false From 87d94da3f85b97d578b857aca4f082568f36439f Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:37:00 -0500 Subject: [PATCH 016/615] stop context changing; try only change the docker file that gets used --- .github/workflows/docker_build.yml | 1 - Dockerfile | 13 ++++++------- aws/Dockerfile | 12 +++++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 33a07817a..396b3e96b 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,6 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - context: ./aws file: ./aws/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} diff --git a/Dockerfile b/Dockerfile index a7c445d7d..f41ca51b7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,5 @@ -FROM python:3.10.9-slim-bullseye +# FROM python:3.10.6 +FROM python:3.10.8-slim-bullseye ENV PYTHONFAULTHANDLER=1 \ PYTHONUNBUFFERED=1 \ @@ -6,7 +7,7 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0 + POETRY_VERSION=1.2.0rc1 WORKDIR /usr/src/app @@ -15,8 +16,8 @@ RUN apt-get update -qqy \ libopenblas-dev \ gfortran -# remove libtiff5 and sqlite3 for security reasons -RUN apt remove -y libtiff5 +# remove libtiff5 for security reasons +RUN apt remove -y libtiff5 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" @@ -26,6 +27,4 @@ RUN poetry config virtualenvs.create false RUN poetry install --no-interaction --no-ansi --no-root -COPY . ./ - -CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file +COPY . ./ \ No newline at end of file diff --git a/aws/Dockerfile b/aws/Dockerfile index c9221f45f..1a063a20d 100644 --- a/aws/Dockerfile +++ b/aws/Dockerfile @@ -1,5 +1,5 @@ # FROM python:3.10.6 -FROM python:3.10.8-slim-bullseye +FROM python:3.10.9-slim-bullseye ENV PYTHONFAULTHANDLER=1 \ PYTHONUNBUFFERED=1 \ @@ -7,7 +7,7 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0rc1 + POETRY_VERSION=1.2.0 WORKDIR /usr/src/app @@ -21,12 +21,14 @@ RUN apt remove -y libtiff5 RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" -COPY ../pyproject.toml ../poetry.lock ./ +COPY pyproject.toml poetry.lock ./ RUN poetry config virtualenvs.create false RUN poetry install --no-interaction --no-ansi --no-root -COPY ../ ./ +COPY . ./ -RUN poetry install --no-interaction --no-ansi --only-root \ No newline at end of file +RUN poetry install --no-interaction --no-ansi --only-root + +CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file From bf2bdf671c25401fe0504b65c886b2347fd8c7ce Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:41:48 -0500 Subject: [PATCH 017/615] set context to root --- .github/workflows/docker_build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 396b3e96b..65b96c779 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,6 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: + context: . file: ./aws/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} From 2026b8292ba8bccf9a9136c9cf4b0235bee85f9f Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:52:42 -0500 Subject: [PATCH 018/615] force the context to be default context --- .github/workflows/docker_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 65b96c779..6440f4e63 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - context: . + context: {{defaultContext}} file: ./aws/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} From 9eb4dcce5161f59e69d05a1cad41edea0b37f39b Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 14:59:00 -0500 Subject: [PATCH 019/615] reset context --- .github/workflows/docker_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 6440f4e63..486729271 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - context: {{defaultContext}} + context: ../ file: ./aws/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} From e4fa4618ec6c4839773f170bde1e3bad8c99ab08 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 16:45:27 -0500 Subject: [PATCH 020/615] change to use dev.Dockerfile; remove aws directory --- .github/workflows/docker_build.yml | 3 +-- aws/Dockerfile => dev.Dockerfile | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename aws/Dockerfile => dev.Dockerfile (100%) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 486729271..6c951e44d 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,8 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - context: ../ - file: ./aws/Dockerfile + file: dev.Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file diff --git a/aws/Dockerfile b/dev.Dockerfile similarity index 100% rename from aws/Dockerfile rename to dev.Dockerfile From 8a43f9253c53e2bdc89511b82b502a6cc2dc27b2 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 10 Jan 2023 17:04:34 -0500 Subject: [PATCH 021/615] remove duplicated line and add comment --- dev.Dockerfile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/dev.Dockerfile b/dev.Dockerfile index 1a063a20d..159f71ee5 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -1,4 +1,4 @@ -# FROM python:3.10.6 +## For aws deployments FROM python:3.10.9-slim-bullseye ENV PYTHONFAULTHANDLER=1 \ @@ -29,6 +29,4 @@ RUN poetry install --no-interaction --no-ansi --no-root COPY . ./ -RUN poetry install --no-interaction --no-ansi --only-root - CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file From 191a6bdcb793676a7e86b99ae5eb384c5e6ee721 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 10:45:55 -0700 Subject: [PATCH 022/615] separate table formatting and upload in store --- schematic/store/synapse.py | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 86603932d..3cb851a22 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -621,7 +621,7 @@ def upload_project_manifests_to_synapse(self, projectId: str) -> List[str]: manifest_name = manifest_info["properties"]["name"] manifest_path = manifest_info["path"] manifest_df = load_df(manifest_path) - manifest_table_id = upload_format_manifest_table(manifest, datasetId, datasetName) + manifest_table_id = uploadDB(manifest, datasetId, datasetName) manifest_loaded.append(datasetName) return manifest_loaded @@ -750,9 +750,24 @@ def get_table_info(self, datasetId: str = None, projectId: str = None) -> List[s return {None:None} @missing_entity_handler - def upload_format_manifest_table(self, se, manifest, datasetId, table_name, restrict, useSchemaLabel): + def uploadDB(self, + se: SchemaExplorer, + manifest: pd.DataFrame, + datasetId: str, + table_name: str, + restrict: bool = False, + useSchemaLabel: bool = True, + existingTableId: str = None,): + + + col_schema, table_manifest = self.formatDB(se, manifest, datasetId, useSchemaLabel) + + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, restrict) + + return manifest_table_id, manifest, table_manifest + + def formatDB(self, se, manifest, datasetId, useSchemaLabel): # Rename the manifest columns to display names to match fileview - table_info = self.get_table_info(datasetId = datasetId) blacklist_chars = ['(', ')', '.', ' ', '-'] manifest_columns = manifest.columns.tolist() @@ -785,6 +800,18 @@ def upload_format_manifest_table(self, se, manifest, datasetId, table_name, rest if col['name'] == 'Uuid': col_schema[i]['maximumSize'] = 64 + return col_schema, table_manifest + + def buildDB(self, + datasetId: str, + table_name: str, + col_schema: List, + table_manifest: pd.DataFrame, + restrict: bool = False, + ): + + table_info = self.get_table_info(datasetId = datasetId) + # Put table manifest onto synapse schema = Schema(name=table_name, columns=col_schema, parent=self.getDatasetProject(datasetId)) if table_name not in table_info.keys(): @@ -804,8 +831,8 @@ def upload_format_manifest_table(self, se, manifest, datasetId, table_name, rest restrict = restrict, manipulation = 'replace') + return manifest_table_id - return manifest_table_id, manifest, table_manifest def uplodad_manifest_file(self, manifest, metadataManifestPath, datasetId, restrict_manifest, component_name = ''): # Update manifest to have the new entityId column @@ -1089,7 +1116,7 @@ def associateMetadataWithFiles( # If specified, upload manifest as a table and get the SynID and manifest if manifest_record_type == 'table' or manifest_record_type == 'both': - manifest_synapse_table_id, manifest, table_manifest = self.upload_format_manifest_table( + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel) # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed From 54e5253b1aec7d08df08578e27fba3c5a92f1c03 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 10:47:35 -0700 Subject: [PATCH 023/615] skip api tests when combination tests are run runcombos --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 012369891..3192670d7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,7 +109,7 @@ jobs: run: > source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ - -m "not (google_credentials_needed or table_operations)" + -m "not (google_credentials_needed or schematic_api or table_operations)" - name: Run tests env: From 8eeda0c9cf13faa1957d859d3f8c537942bb8ae8 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 11:26:37 -0700 Subject: [PATCH 024/615] update CLI to accept table manipulation param --- schematic/help.py | 6 ++++++ schematic/models/commands.py | 8 +++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/schematic/help.py b/schematic/help.py index ecd901120..746db2ba2 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -112,6 +112,12 @@ "'table' will store the manifest as a table and a csv on Synapse. 'both' will do both of the options specified above. " "Default value is 'table'." ), + "table_manipulation":( + "Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. " + "'replace' will remove the rows and columns from the existing table and store the new rows and columns, preserving the name and synID. " + "'upsert' will add the new rows to the table and preserve the exisitng rows and columns in the existing table. " + "Default value is 'replace'. " + ), }, "validate": { "short_help": ("Validation of manifest files."), diff --git a/schematic/models/commands.py b/schematic/models/commands.py index ff7414065..4f2ecbd01 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -95,9 +95,15 @@ def model(ctx, config): # use as `schematic model ...` callback=parse_synIDs, help=query_dict(model_commands, ("model", "validate", "project_scope")), ) +@click.option( + "--table_manipulation", + "-tm", + default='replace', + type=click.Choice(['replace', 'upsert'], case_sensitive=True), + help=query_dict(model_commands, ("model", "submit", "table_manipulation"))) @click.pass_obj def submit_manifest( - ctx, manifest_path, dataset_id, validate_component, manifest_record_type, use_schema_label, hide_blanks, restrict_rules, project_scope, + ctx, manifest_path, dataset_id, validate_component, manifest_record_type, use_schema_label, hide_blanks, restrict_rules, project_scope, table_manipulation, ): """ Running CLI with manifest validation (optional) and submission options. From 1acd5cc2875d6526ccc149f9bb4f287f6b982509 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 12 Jan 2023 13:26:56 -0500 Subject: [PATCH 025/615] point to listen to port 80 --- dev.Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dev.Dockerfile b/dev.Dockerfile index 159f71ee5..c9c05ec1e 100644 --- a/dev.Dockerfile +++ b/dev.Dockerfile @@ -1,13 +1,15 @@ ## For aws deployments FROM python:3.10.9-slim-bullseye +# set APP_PORT to 80 to avoid 308 unhealthy target group error ENV PYTHONFAULTHANDLER=1 \ PYTHONUNBUFFERED=1 \ PYTHONHASHSEED=random \ PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0 + POETRY_VERSION=1.2.0 \ + APP_PORT=80 WORKDIR /usr/src/app From d89cc8a4aeb27357292def1cbe10ac2fb70380d5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 11:38:18 -0700 Subject: [PATCH 026/615] propagate new param through to buildDB --- schematic/models/commands.py | 1 + schematic/models/metadata.py | 5 +++++ schematic/store/synapse.py | 11 +++++++---- tests/test_store.py | 7 ++++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 4f2ecbd01..1444cb6b8 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -128,6 +128,7 @@ def submit_manifest( use_schema_label=use_schema_label, hide_blanks=hide_blanks, project_scope=project_scope, + table_manipulation=table_manipulation, ) ''' diff --git a/schematic/models/metadata.py b/schematic/models/metadata.py index 1304246ba..be1cf131b 100644 --- a/schematic/models/metadata.py +++ b/schematic/models/metadata.py @@ -288,6 +288,7 @@ def submit_metadata_manifest( hide_blanks: bool = False, input_token: str = None, project_scope: List = None, + table_manipulation: str = 'replace' ) -> string: """Wrap methods that are responsible for validation of manifests for a given component, and association of the same manifest file with a specified dataset. @@ -341,6 +342,7 @@ def submit_metadata_manifest( manifest_record_type = manifest_record_type, useSchemaLabel = use_schema_label, hideBlanks = hide_blanks, + table_manipulation=table_manipulation, ) restrict_maniest = True @@ -352,6 +354,7 @@ def submit_metadata_manifest( useSchemaLabel = use_schema_label, hideBlanks = hide_blanks, restrict_manifest=restrict_maniest, + table_manipulation=table_manipulation, ) logger.info(f"No validation errors occured during validation.") @@ -372,6 +375,7 @@ def submit_metadata_manifest( manifest_record_type=manifest_record_type, useSchemaLabel=use_schema_label, hideBlanks=hide_blanks, + table_manipulation=table_manipulation, ) restrict_maniest = True @@ -383,6 +387,7 @@ def submit_metadata_manifest( useSchemaLabel=use_schema_label, hideBlanks=hide_blanks, restrict_manifest=restrict_maniest, + table_manipulation=table_manipulation, ) logger.debug( diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 3cb851a22..e2bfebdc2 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -757,12 +757,14 @@ def uploadDB(self, table_name: str, restrict: bool = False, useSchemaLabel: bool = True, - existingTableId: str = None,): + existingTableId: str = None, + table_manipulation: str = 'replace', + ): col_schema, table_manifest = self.formatDB(se, manifest, datasetId, useSchemaLabel) - manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, restrict) + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) return manifest_table_id, manifest, table_manifest @@ -807,6 +809,7 @@ def buildDB(self, table_name: str, col_schema: List, table_manifest: pd.DataFrame, + table_manipulation: str, restrict: bool = False, ): @@ -1034,7 +1037,7 @@ def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPa def associateMetadataWithFiles( self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'both', - useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', ) -> str: """Associate metadata with files in a storage dataset already on Synapse. Upload metadataManifest in the storage dataset folder on Synapse as well. Return synapseId of the uploaded manifest file. @@ -1117,7 +1120,7 @@ def associateMetadataWithFiles( # If specified, upload manifest as a table and get the SynID and manifest if manifest_record_type == 'table' or manifest_record_type == 'both': manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( - se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel) + se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation=table_manipulation,) # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed # also set metadata for each synapse entity as Synapse annotations diff --git a/tests/test_store.py b/tests/test_store.py index 7ecbdb33c..0c8ffacf0 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -271,7 +271,7 @@ def test_tidy_table(self, dataset_fileview_table_tidy): class TestTableOperations: def test_createTable(self, helpers, synapse_store, config, projectId, datasetId): - + table_manipulation = None # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -298,6 +298,7 @@ def test_createTable(self, helpers, synapse_store, config, projectId, datasetId) useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, + table_manipulation=table_manipulation, ) existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -307,6 +308,8 @@ def test_createTable(self, helpers, synapse_store, config, projectId, datasetId) assert table_name in existing_tables.keys() def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId): + table_manipulation = 'replace' + table_name='followup_synapse_storage_manifest_table' manifest_path = "mock_manifests/table_manifest.csv" replacement_manifest_path = "mock_manifests/table_manifest_replacement.csv" @@ -334,6 +337,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, + table_manipulation=table_manipulation, ) existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -355,6 +359,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, + table_manipulation=table_manipulation, ) existing_tables = synapse_store.get_table_info(projectId = projectId) From 729c4acce9dfafddbd6c648cac177a7388664d9b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 12:06:09 -0700 Subject: [PATCH 027/615] add TableOperations Object --- schematic/store/synapse.py | 114 +++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index e2bfebdc2..0f5f8b9b5 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1572,6 +1572,120 @@ def make_synapse_table(self, return table.schema.id +class TableOperations: + + def createTable(self, tableToLoad: pd.DataFrame = None, datasetID: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): + datasetEntity = self.syn.get(datasetID, downloadFile = False) + datasetName = datasetEntity.name + table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) + + if not table_name: + table_name = datasetName + 'table' + datasetParentProject = self.getDatasetProject(datasetID) + if specifySchema: + if columnTypeDict == {}: + logger.error("Did not provide a columnTypeDict.") + #create list of columns: + cols = [] + for col in tableToLoad.columns: + if col in table_schema_by_cname: + col_type = table_schema_by_cname[col]['columnType'] + max_size = table_schema_by_cname[col]['maximumSize'] if 'maximumSize' in table_schema_by_cname[col].keys() else 100 + max_list_len = 250 + if max_size and max_list_len: + cols.append(Column(name=col, columnType=col_type, + maximumSize=max_size, maximumListLength=max_list_len)) + elif max_size: + cols.append(Column(name=col, columnType=col_type, + maximumSize=max_size)) + else: + cols.append(Column(name=col, columnType=col_type)) + else: + #TODO add warning that the given col was not found and it's max size is set to 100 + cols.append(Column(name=col, columnType='STRING', maximumSize=100)) + schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) + table = Table(schema, tableToLoad) + table = self.syn.store(table, isRestricted = restrict) + return table.schema.id + else: + # For just uploading the tables to synapse using default + # column types. + table = build_table(table_name, datasetParentProject, tableToLoad) + table = self.syn.store(table, isRestricted = restrict) + return table.schema.id + + def replaceTable(self, tableToLoad: pd.DataFrame = None, existingTableId: str = None, specifySchema: bool = True, datasetID: str = None, columnTypeDict: dict = None, restrict: bool = False): + datasetEntity = self.syn.get(datasetID, downloadFile = False) + datasetName = datasetEntity.name + table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) + existing_table, existing_results = self.get_synapse_table(existingTableId) + # remove rows + self.syn.delete(existing_results) + # wait for row deletion to finish on synapse before getting empty table + sleep(10) + + # removes all current columns + current_table = self.syn.get(existingTableId) + current_columns = self.syn.getTableColumns(current_table) + for col in current_columns: + current_table.removeColumn(col) + + if not table_name: + table_name = datasetName + 'table' + + # Process columns according to manifest entries + table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) + datasetParentProject = self.getDatasetProject(datasetID) + if specifySchema: + if columnTypeDict == {}: + logger.error("Did not provide a columnTypeDict.") + #create list of columns: + cols = [] + + for col in tableToLoad.columns: + + if col in table_schema_by_cname: + col_type = table_schema_by_cname[col]['columnType'] + max_size = table_schema_by_cname[col]['maximumSize'] if 'maximumSize' in table_schema_by_cname[col].keys() else 100 + max_list_len = 250 + if max_size and max_list_len: + cols.append(Column(name=col, columnType=col_type, + maximumSize=max_size, maximumListLength=max_list_len)) + elif max_size: + cols.append(Column(name=col, columnType=col_type, + maximumSize=max_size)) + else: + cols.append(Column(name=col, columnType=col_type)) + else: + + #TODO add warning that the given col was not found and it's max size is set to 100 + cols.append(Column(name=col, columnType='STRING', maximumSize=100)) + + # adds new columns to schema + for col in cols: + current_table.addColumn(col) + self.syn.store(current_table, isRestricted = restrict) + + # wait for synapse store to finish + sleep(1) + + # build schema and table from columns and store with necessary restrictions + schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) + schema.id = existingTableId + table = Table(schema, tableToLoad, etag = existing_results.etag) + table = self.syn.store(table, isRestricted = restrict) + else: + logging.error("Must specify a schema for table replacements") + + # remove system metadata from manifest + existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) + return existingTableId + + def upsertTable(self, table_name: str = None, data: pd.DataFrame = None): + raise NotImplementedError + + + class DatasetFileView: """Helper class to create temporary dataset file views. This class can be used in conjunction with a 'with' statement. From 57c224e2dc610024d8eedb421ba17472d395fd10 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 12 Jan 2023 13:46:40 -0700 Subject: [PATCH 028/615] use new object, remove make_synapse_table --- schematic/store/synapse.py | 245 +++++++------------------------------ 1 file changed, 45 insertions(+), 200 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 0f5f8b9b5..c7b94f9f0 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -766,7 +766,7 @@ def uploadDB(self, manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) - return manifest_table_id, manifest, table_manifest + return manifest_table_id, manifest, table_manifest, col_schema def formatDB(self, se, manifest, datasetId, useSchemaLabel): # Rename the manifest columns to display names to match fileview @@ -814,25 +814,18 @@ def buildDB(self, ): table_info = self.get_table_info(datasetId = datasetId) - # Put table manifest onto synapse schema = Schema(name=table_name, columns=col_schema, parent=self.getDatasetProject(datasetId)) - if table_name not in table_info.keys(): - manifest_table_id = self.make_synapse_table(table_to_load = table_manifest, - dataset_id = datasetId, - existingTableId = None, - table_name = table_name, - column_type_dictionary = col_schema, - restrict = restrict, - manipulation = 'replace') + + + if table_name in table_info.keys() and table_info[table_name]: + + if table_manipulation.lower() == 'replace': + manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) + elif table_manipulation.lower() == 'upsert': + manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) else: - manifest_table_id = self.make_synapse_table(table_to_load = table_manifest, - dataset_id = datasetId, - existingTableId = table_info[table_name], - table_name = table_name, - column_type_dictionary = col_schema, - restrict = restrict, - manipulation = 'replace') + manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) return manifest_table_id @@ -1119,7 +1112,7 @@ def associateMetadataWithFiles( # If specified, upload manifest as a table and get the SynID and manifest if manifest_record_type == 'table' or manifest_record_type == 'both': - manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + manifest_synapse_table_id, manifest, table_manifest, col_schema = self.uploadDB( se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation=table_manipulation,) # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed @@ -1162,15 +1155,15 @@ def associateMetadataWithFiles( if manifest_record_type == 'table' or manifest_record_type == 'both': # Update manifest Synapse table with new entity id column. - self.make_synapse_table( - table_to_load = table_manifest, - dataset_id = datasetId, - existingTableId = manifest_synapse_table_id, - table_name = table_name, - update_col = 'Uuid', - specify_schema = False, - restrict = restrict_manifest - ) + + TableOperations.replaceTable(self, + tableToLoad=table_manifest, + tableName=table_name, + existingTableId=manifest_synapse_table_id, + specifySchema=True, + datasetId=datasetId, + columnTypeDict=col_schema, + restrict=restrict_manifest) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1424,164 +1417,16 @@ def _get_table_schema_by_cname(self, table_schema): return table_schema_by_cname - def make_synapse_table(self, - table_to_load: pd.DataFrame, - dataset_id: str, table_name: str, - existingTableId: str = None, - update_col: str = 'entityId', - column_type_dictionary: Dict = {}, - specify_schema: bool = True, - restrict: bool = False, - manipulation: str = 'update') -> str: - ''' - Make a synapse table for record based data - - Args: - table_to_load (pd.DataFrame): table to upload to synapse - dataset_id (str): synID for dataset related to manifest to be uploaded as table - existingTableId (str): Optional, synID of existing table to upload to - table_name (str): Name of the table that will be displayed on synapse - update_col (str): Optional, if updating a table by aligning on index, column to use as indices - column_type_dictionary (Dict): dictionary of column types - specify_schema (bool): specify a schema for the table at upload according to types in column_type_dictionary - restrict (bool): set to True if access restrictions need to be imposed on table when stored on synapse, False otherwise - manipulation (str): type of manipulation to do if a table exists already. Can be either "update" or "replace". - Defaults to "update" to preserve old behavior - - Returns: - str: synId of table uploaded to synapse - - ''' - if existingTableId: - existing_table, existing_results = self.get_synapse_table(existingTableId) - - manipulation = manipulation.lower() - if manipulation not in ['update', 'replace']: - raise NotImplementedError( - "Currently, only 'update' and 'replace' table operations are supported." - ) - - # create/update a table corresponding to this dataset in this dataset's parent project - # update_col is the column in the table that has a unique code that will allow Synapse to - # locate its position in the old and new table. - if manipulation == 'update': - table_to_load = update_df(existing_table, table_to_load, update_col) - # store table with existing etag data and impose restrictions as appropriate - self.syn.store(Table(existingTableId, table_to_load, etag = existing_results.etag), isRestricted = restrict) - - elif manipulation == 'replace': - # remove rows - self.syn.delete(existing_results) - # wait for row deletion to finish on synapse before getting empty table - sleep(10) - - # removes all current columns - current_table = self.syn.get(existingTableId) - current_columns = self.syn.getTableColumns(current_table) - for col in current_columns: - current_table.removeColumn(col) - - if not table_name: - table_name = datasetName + 'table' - - # Process columns according to manifest entries - table_schema_by_cname = self._get_table_schema_by_cname(column_type_dictionary) - datasetParentProject = self.getDatasetProject(dataset_id) - if specify_schema: - if column_type_dictionary == {}: - logger.error("Did not provide a column_type_dictionary.") - #create list of columns: - cols = [] - - for col in table_to_load.columns: - - if col in table_schema_by_cname: - col_type = table_schema_by_cname[col]['columnType'] - max_size = table_schema_by_cname[col]['maximumSize'] if 'maximumSize' in table_schema_by_cname[col].keys() else 100 - max_list_len = 250 - if max_size and max_list_len: - cols.append(Column(name=col, columnType=col_type, - maximumSize=max_size, maximumListLength=max_list_len)) - elif max_size: - cols.append(Column(name=col, columnType=col_type, - maximumSize=max_size)) - else: - cols.append(Column(name=col, columnType=col_type)) - else: - - #TODO add warning that the given col was not found and it's max size is set to 100 - cols.append(Column(name=col, columnType='STRING', maximumSize=100)) - - # adds new columns to schema - for col in cols: - current_table.addColumn(col) - self.syn.store(current_table, isRestricted = restrict) - - # wait for synapse store to finish - sleep(1) - - # build schema and table from columns and store with necessary restrictions - schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) - schema.id = existingTableId - table = Table(schema, table_to_load, etag = existing_results.etag) - table = self.syn.store(table, isRestricted = restrict) - else: - logging.error("Must specify a schema for table replacements") - - # remove system metadata from manifest - existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) - return existingTableId - else: - datasetEntity = self.syn.get(dataset_id, downloadFile = False) - datasetName = datasetEntity.name - table_schema_by_cname = self._get_table_schema_by_cname(column_type_dictionary) - - if not table_name: - table_name = datasetName + 'table' - datasetParentProject = self.getDatasetProject(dataset_id) - if specify_schema: - if column_type_dictionary == {}: - logger.error("Did not provide a column_type_dictionary.") - #create list of columns: - cols = [] - for col in table_to_load.columns: - if col in table_schema_by_cname: - col_type = table_schema_by_cname[col]['columnType'] - max_size = table_schema_by_cname[col]['maximumSize'] if 'maximumSize' in table_schema_by_cname[col].keys() else 100 - max_list_len = 250 - if max_size and max_list_len: - cols.append(Column(name=col, columnType=col_type, - maximumSize=max_size, maximumListLength=max_list_len)) - elif max_size: - cols.append(Column(name=col, columnType=col_type, - maximumSize=max_size)) - else: - cols.append(Column(name=col, columnType=col_type)) - else: - #TODO add warning that the given col was not found and it's max size is set to 100 - cols.append(Column(name=col, columnType='STRING', maximumSize=100)) - schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) - table = Table(schema, table_to_load) - table = self.syn.store(table, isRestricted = restrict) - return table.schema.id - else: - # For just uploading the tables to synapse using default - # column types. - table = build_table(table_name, datasetParentProject, table_to_load) - table = self.syn.store(table, isRestricted = restrict) - return table.schema.id - - class TableOperations: - def createTable(self, tableToLoad: pd.DataFrame = None, datasetID: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): - datasetEntity = self.syn.get(datasetID, downloadFile = False) + def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, datasetId: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): + datasetEntity = synStore.syn.get(datasetId, downloadFile = False) datasetName = datasetEntity.name - table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) + table_schema_by_cname = synStore._get_table_schema_by_cname(columnTypeDict) - if not table_name: - table_name = datasetName + 'table' - datasetParentProject = self.getDatasetProject(datasetID) + if not tableName: + tableName = datasetName + 'table' + datasetParentProject = synStore.getDatasetProject(datasetId) if specifySchema: if columnTypeDict == {}: logger.error("Did not provide a columnTypeDict.") @@ -1603,39 +1448,39 @@ def createTable(self, tableToLoad: pd.DataFrame = None, datasetID: str = None, c else: #TODO add warning that the given col was not found and it's max size is set to 100 cols.append(Column(name=col, columnType='STRING', maximumSize=100)) - schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) + schema = Schema(name=tableName, columns=cols, parent=datasetParentProject) table = Table(schema, tableToLoad) - table = self.syn.store(table, isRestricted = restrict) + table = synStore.syn.store(table, isRestricted = restrict) return table.schema.id else: # For just uploading the tables to synapse using default # column types. - table = build_table(table_name, datasetParentProject, tableToLoad) - table = self.syn.store(table, isRestricted = restrict) + table = build_table(tableName, datasetParentProject, tableToLoad) + table = synStore.syn.store(table, isRestricted = restrict) return table.schema.id - def replaceTable(self, tableToLoad: pd.DataFrame = None, existingTableId: str = None, specifySchema: bool = True, datasetID: str = None, columnTypeDict: dict = None, restrict: bool = False): - datasetEntity = self.syn.get(datasetID, downloadFile = False) + def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, specifySchema: bool = True, datasetId: str = None, columnTypeDict: dict = None, restrict: bool = False): + datasetEntity = synStore.syn.get(datasetId, downloadFile = False) datasetName = datasetEntity.name - table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) - existing_table, existing_results = self.get_synapse_table(existingTableId) + table_schema_by_cname = synStore._get_table_schema_by_cname(columnTypeDict) + existing_table, existing_results = synStore.get_synapse_table(existingTableId) # remove rows - self.syn.delete(existing_results) + synStore.syn.delete(existing_results) # wait for row deletion to finish on synapse before getting empty table sleep(10) # removes all current columns - current_table = self.syn.get(existingTableId) - current_columns = self.syn.getTableColumns(current_table) + current_table = synStore.syn.get(existingTableId) + current_columns = synStore.syn.getTableColumns(current_table) for col in current_columns: current_table.removeColumn(col) - if not table_name: - table_name = datasetName + 'table' + if not tableName: + tableName = datasetName + 'table' # Process columns according to manifest entries - table_schema_by_cname = self._get_table_schema_by_cname(columnTypeDict) - datasetParentProject = self.getDatasetProject(datasetID) + table_schema_by_cname = synStore._get_table_schema_by_cname(columnTypeDict) + datasetParentProject = synStore.getDatasetProject(datasetId) if specifySchema: if columnTypeDict == {}: logger.error("Did not provide a columnTypeDict.") @@ -1664,16 +1509,16 @@ def replaceTable(self, tableToLoad: pd.DataFrame = None, existingTableId: str = # adds new columns to schema for col in cols: current_table.addColumn(col) - self.syn.store(current_table, isRestricted = restrict) + synStore.syn.store(current_table, isRestricted = restrict) # wait for synapse store to finish sleep(1) # build schema and table from columns and store with necessary restrictions - schema = Schema(name=table_name, columns=cols, parent=datasetParentProject) + schema = Schema(name=tableName, columns=cols, parent=datasetParentProject) schema.id = existingTableId table = Table(schema, tableToLoad, etag = existing_results.etag) - table = self.syn.store(table, isRestricted = restrict) + table = synStore.syn.store(table, isRestricted = restrict) else: logging.error("Must specify a schema for table replacements") @@ -1681,7 +1526,7 @@ def replaceTable(self, tableToLoad: pd.DataFrame = None, existingTableId: str = existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) return existingTableId - def upsertTable(self, table_name: str = None, data: pd.DataFrame = None): + def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): raise NotImplementedError From 8e8ff510599c68bfabe684a11764b0d6d570bce4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 13 Jan 2023 14:02:32 -0700 Subject: [PATCH 029/615] raise errors for `wrong schema` invalidity --- schematic/models/validate_attribute.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 53b8c1916..cd28614cb 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -37,11 +37,14 @@ def generate_schema_error(row_num: str, attribute_name: str, error_msg: str, inv warning_list = [] #Determine which, if any, message to raise - raises = GenerateError.get_message_level( - val_rule = 'schema', - attribute_name = attribute_name, - sg = sg, - ) + if attribute_name.lower() == 'wrong schema': + raises = 'error' + else: + raises = GenerateError.get_message_level( + val_rule = 'schema', + attribute_name = attribute_name, + sg = sg, + ) #if a message needs to be raised, get the approrpiate function to do so if raises: From 9e52f2ce414aa43d99be6a87c883ac42a9e810d9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:32:02 -0700 Subject: [PATCH 030/615] add upsert test and dummy data --- tests/data/mock_manifests/table_manifest.csv | 19 +++--- tests/test_store.py | 67 ++++++++++++++++++++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/tests/data/mock_manifests/table_manifest.csv b/tests/data/mock_manifests/table_manifest.csv index c64988577..9ee49f177 100644 --- a/tests/data/mock_manifests/table_manifest.csv +++ b/tests/data/mock_manifests/table_manifest.csv @@ -1,10 +1,11 @@ Component,Days to Follow Up,Adverse Event,Progression or Recurrence,Barretts Esophagus Goblet Cells Present,BMI,Cause of Response,Comorbidity,Comorbidity Method of Diagnosis,Days to Adverse Event,Days to Comorbidity,Diabetes Treatment Type,Disease Response,DLCO Ref Predictive Percent,ECOG Performance Status,FEV1 FVC Post Bronch Percent,FEV 1 FVC Pre Bronch Percent,FEV1 Ref Post Bronch Percent,FEV1 Ref Pre Bronch Percent,Height,Hepatitis Sustained Virological Response,HPV Positive Type,Karnofsky Performance Status,Menopause Status,Pancreatitis Onset Year,Reflux Treatment Type,Risk Factor,Risk Factor Treatment,Viral Hepatitis Serologies,Weight,Days to Progression,Days to Progression Free,Days to Recurrence,Progression or Recurrence Anatomic Site,Progression or Recurrence Type,entityId,HTAN Participant ID -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454.0 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458 +FollowUp,93,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,463 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454 diff --git a/tests/test_store.py b/tests/test_store.py index 0c8ffacf0..3543287d5 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -373,3 +373,70 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId assert (daysToFollowUp == '89').all() # delete table synapse_store.syn.delete(tableId) + + def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId): + table_manipulation = 'upsert' + + table_name='followup_synapse_storage_manifest_table' + manifest_path = "mock_manifests/table_manifest.csv" + replacement_manifest_path = "mock_manifests/table_manifest_upsert.csv" + column_of_interest="DaystoFollowUp" + + # Check if FollowUp table exists if so delete + existing_tables = synapse_store.get_table_info(projectId = projectId) + + if table_name in existing_tables.keys(): + synapse_store.syn.delete(existing_tables[table_name]) + sleep(10) + # assert no table + assert table_name not in synapse_store.get_table_info(projectId = projectId).keys() + + # associate org FollowUp metadata with files + inputModelLocaiton = helpers.get_data_path(get_from_config(config.DATA, ("model", "input", "location"))) + sg = SchemaGenerator(inputModelLocaiton) + + # updating file view on synapse takes a long time + manifestId = synapse_store.associateMetadataWithFiles( + schemaGenerator = sg, + metadataManifestPath = helpers.get_data_path(manifest_path), + datasetId = datasetId, + manifest_record_type = 'table', + useSchemaLabel = True, + hideBlanks = True, + restrict_manifest = False, + table_manipulation=table_manipulation, + ) + existing_tables = synapse_store.get_table_info(projectId = projectId) + + # Query table for DaystoFollowUp column + tableId = existing_tables[table_name] + daysToFollowUp = synapse_store.syn.tableQuery( + f"SELECT {column_of_interest} FROM {tableId}" + ).asDataFrame().squeeze() + + # assert Days to FollowUp == 73 + assert (daysToFollowUp == '73.0').all() + + # Associate new manifest with files + manifestId = synapse_store.associateMetadataWithFiles( + schemaGenerator = sg, + metadataManifestPath = helpers.get_data_path(replacement_manifest_path), + datasetId = datasetId, + manifest_record_type = 'table', + useSchemaLabel = True, + hideBlanks = True, + restrict_manifest = False, + table_manipulation=table_manipulation, + ) + existing_tables = synapse_store.get_table_info(projectId = projectId) + + # Query table for DaystoFollowUp column + tableId = existing_tables[table_name] + daysToFollowUp = synapse_store.syn.tableQuery( + f"SELECT {column_of_interest} FROM {tableId}" + ).asDataFrame().squeeze() + + # assert Days to FollowUp is not all '73' + assert not (daysToFollowUp == '73').all() + # delete table + synapse_store.syn.delete(tableId) From b7ec889dd490ce26d6c9701219012475b8f95c6e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:43:52 -0700 Subject: [PATCH 031/615] set primary key annotation for uploaded table --- tests/test_store.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 3543287d5..72c3188dc 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -408,8 +408,13 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) ) existing_tables = synapse_store.get_table_info(projectId = projectId) - # Query table for DaystoFollowUp column + #set primary key annotation for uploaded table tableId = existing_tables[table_name] + annos = synapse_store.get_annotations(tableId) + annos['primary_key'] = 'FollowUp_id' + annos=synapse_store.set_annotations(annos) + + # Query table for DaystoFollowUp column daysToFollowUp = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() From a98d379f0594c65d50b349f950872f7e6f97201b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:48:30 -0700 Subject: [PATCH 032/615] correct object usage --- tests/test_store.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index 72c3188dc..a86e1aac6 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -410,9 +410,9 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) #set primary key annotation for uploaded table tableId = existing_tables[table_name] - annos = synapse_store.get_annotations(tableId) + annos = synapse_store.syn.get_annotations(tableId) annos['primary_key'] = 'FollowUp_id' - annos=synapse_store.set_annotations(annos) + annos=synapse_store.syn.set_annotations(annos) # Query table for DaystoFollowUp column daysToFollowUp = synapse_store.syn.tableQuery( From 0c865b2a4539d7ff2e4d78d9eb5902e2c9263e48 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:53:29 -0700 Subject: [PATCH 033/615] revert manifest change --- tests/data/mock_manifests/table_manifest.csv | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/data/mock_manifests/table_manifest.csv b/tests/data/mock_manifests/table_manifest.csv index 9ee49f177..c64988577 100644 --- a/tests/data/mock_manifests/table_manifest.csv +++ b/tests/data/mock_manifests/table_manifest.csv @@ -1,11 +1,10 @@ Component,Days to Follow Up,Adverse Event,Progression or Recurrence,Barretts Esophagus Goblet Cells Present,BMI,Cause of Response,Comorbidity,Comorbidity Method of Diagnosis,Days to Adverse Event,Days to Comorbidity,Diabetes Treatment Type,Disease Response,DLCO Ref Predictive Percent,ECOG Performance Status,FEV1 FVC Post Bronch Percent,FEV 1 FVC Pre Bronch Percent,FEV1 Ref Post Bronch Percent,FEV1 Ref Pre Bronch Percent,Height,Hepatitis Sustained Virological Response,HPV Positive Type,Karnofsky Performance Status,Menopause Status,Pancreatitis Onset Year,Reflux Treatment Type,Risk Factor,Risk Factor Treatment,Viral Hepatitis Serologies,Weight,Days to Progression,Days to Progression Free,Days to Recurrence,Progression or Recurrence Anatomic Site,Progression or Recurrence Type,entityId,HTAN Participant ID -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458 -FollowUp,93,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,463 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454.0 From 393525b361cdc89e9acc447ad3bd659cb9b80931 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 18 Jan 2023 15:39:02 -0500 Subject: [PATCH 034/615] added an endpoint to check if something is in the asset view --- api/openapi/api.yaml | 39 +++++++++++++++++++++++++++++++++++++- api/routes.py | 12 ++++++++++++ schematic/store/synapse.py | 10 ++++++++++ 3 files changed, 60 insertions(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index f6d06965f..16ff449b4 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -645,6 +645,43 @@ paths: description: Check schematic log. tags: - Synapse Storage + /storage/if_in_asset_view: + get: + summary: Check if a file or a folder is in a given asset view. Return "true" or "false" + description: Check if a file or a folder is in a given asset view. Return "true" or "false" + operationId: api.routes.check_if_files_in_assetview + parameters: + - in: query + name: input_token + schema: + type: string + nullable: false + description: Token + example: Token + required: true + - in: query + name: asset_view + schema: + type: string + nullable: false + description: ID of view listing all project data assets. For example, for Synapse this would be the Synapse ID of the fileview listing all data assets for a given project.(i.e. master_fileview in config.yml) + example: syn23643253 + required: true + - in: query + name: id + schema: + type: string + nullable: false + description: ID of file or folder. For example, for Synapse this would be the Synapse ID. + example: syn30988314 + required: true + responses: + "200": + description: return "true" or "false" + "500": + description: Check schematic log. + tags: + - Synapse Storage /schemas/get/schema: get: summary: Return schema as a pickle file @@ -987,4 +1024,4 @@ paths: schema: type: string tags: - - Visualization Operations + - Visualization Operations \ No newline at end of file diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..04227dd86 100644 --- a/api/routes.py +++ b/api/routes.py @@ -437,6 +437,18 @@ def get_files_storage_dataset(input_token, asset_view, dataset_id, full_path, fi file_lst = store.getFilesInStorageDataset(datasetId=dataset_id, fileNames=file_names, fullpath=full_path) return file_lst +def check_if_files_in_assetview(input_token, asset_view, id): + # call config handler + config_handler(asset_view=asset_view) + + # use Synapse Storage + store = SynapseStorage(input_token=input_token) + + # call function and check if a file or a folder is in asset view + if_exists = store.checkIfinAssetView(id) + + return if_exists + def get_component_requirements(schema_url, source_component, as_graph): metadata_model = initalize_metadata_model(schema_url) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 86603932d..d8571641d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1311,6 +1311,16 @@ def raise_final_error(retry_state): [wait_fixed(20)]), retry=retry_if_exception_type(LookupError), retry_error_callback = raise_final_error) + + def checkIfinAssetView(self, syn_id) -> str: + # get data in administrative fileview for this pipeline + assetViewTable = self.getStorageFileviewTable() + all_files = list(assetViewTable["id"]) + if syn_id in all_files: + return True + else: + return False + def getDatasetProject(self, datasetId: str) -> str: """Get parent project for a given dataset ID. From 6be9acdf5eb77cb8802711d0c055e3bdee36d753 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 19 Jan 2023 00:25:44 -0500 Subject: [PATCH 035/615] add test related to checking entity type --- api/openapi/api.yaml | 40 +++++++++++++++++++++++++++++++++++++- api/routes.py | 14 +++++++++++-- schematic/exceptions.py | 23 ++++++++++++++++++++++ schematic/store/synapse.py | 19 ++++++++++++++++++ tests/test_api.py | 34 ++++++++++++++++++++++++++++++-- 5 files changed, 125 insertions(+), 5 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 16ff449b4..f68c9df8f 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -645,6 +645,44 @@ paths: description: Check schematic log. tags: - Synapse Storage + /storage/entity/type: + get: + summary: Check type of an entity + description: Check type of an entity and return entity type + operationId: api.routes.check_entity_type + parameters: + - in: query + name: input_token + schema: + type: string + nullable: false + description: Token + example: Token + required: true + - in: query + name: asset_view + schema: + type: string + nullable: false + description: ID of view listing all project data assets. For example, for Synapse this would be the Synapse ID of the fileview listing all data assets for a given project.(i.e. master_fileview in config.yml) + example: syn23643253 + required: true + - in: query + name: entity_id + schema: + type: string + nullable: false + description: ID of an entity. It could be a file, a folder, a project, or an asset view + example: syn30988314 + required: true + responses: + "200": + description: return type of a schematic entity + "500": + description: Check schematic log. + tags: + - Synapse Storage + /storage/if_in_asset_view: get: summary: Check if a file or a folder is in a given asset view. Return "true" or "false" @@ -668,7 +706,7 @@ paths: example: syn23643253 required: true - in: query - name: id + name: entity_id schema: type: string nullable: false diff --git a/api/routes.py b/api/routes.py index 04227dd86..077275bda 100644 --- a/api/routes.py +++ b/api/routes.py @@ -437,7 +437,7 @@ def get_files_storage_dataset(input_token, asset_view, dataset_id, full_path, fi file_lst = store.getFilesInStorageDataset(datasetId=dataset_id, fileNames=file_names, fullpath=full_path) return file_lst -def check_if_files_in_assetview(input_token, asset_view, id): +def check_if_files_in_assetview(input_token, asset_view, entity_id): # call config handler config_handler(asset_view=asset_view) @@ -445,10 +445,20 @@ def check_if_files_in_assetview(input_token, asset_view, id): store = SynapseStorage(input_token=input_token) # call function and check if a file or a folder is in asset view - if_exists = store.checkIfinAssetView(id) + if_exists = store.checkIfinAssetView(entity_id) return if_exists +def check_entity_type(input_token, asset_view, entity_id): + # call config handler + config_handler(asset_view=asset_view) + + # use Synapse Storage + store = SynapseStorage(input_token=input_token) + + entity_type = store.checkEntityType(entity_id) + return entity_type + def get_component_requirements(schema_url, source_component, as_graph): metadata_model = initalize_metadata_model(schema_url) diff --git a/schematic/exceptions.py b/schematic/exceptions.py index b496a3e6d..4aff3fef9 100644 --- a/schematic/exceptions.py +++ b/schematic/exceptions.py @@ -28,6 +28,29 @@ def __init__(self, config_keys: Sequence[Any], message: str = None) -> str: def __str__(self): return f"{self.message}" +class WrongEntityTypeError(Exception): + """Exception raised when the entity type is not desired + + Args: + entity id: For synapse, thi + message: custom/pre-defined error message to be returned. + + Returns: + message. + """ + def __init__(self, syn_id: str, message: str = None) -> str: + self.message = ( + f"'{syn_id}'' is not a desired entity type" + "Please ensure that you put in the right syn_id" + ) + + if message: + self.message = message + + super().__init__(self.message) + + def __str__(self): + return f"{self.message}" class MissingConfigAndArgumentValueError(Exception): """Exception raised when configuration value not provided in config file. diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d8571641d..56fc5c71b 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -96,6 +96,25 @@ def __init__( self._query_fileview() + def checkEntityType(self, syn_id): + """ + Check the entity type of a synapse entity + return: type of synapse entity + """ + entity = self.syn.get(syn_id) + type_entity = str(type(entity)) + + if type_entity == "": + return "asset view" + elif type_entity == "": + return "folder" + elif type_entity == "": + return "file" + elif type_entity == "": + return "project" + else: + return type_entity + def _query_fileview(self): try: self.storageFileview = CONFIG["synapse"]["master_fileview"] diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..11a5c1ed8 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -141,10 +141,40 @@ def test_get_storage_projects(self, syn_token, client): response = client.get("http://localhost:3001/v1/storage/projects", query_string = params) assert response.status_code == 200 - - + @pytest.mark.parametrize("entity_id", ["syn34640850", "syn23643253", "syn24992754"]) + def test_get_entity_type(self, syn_token, client, entity_id): + params = { + "input_token": syn_token, + "asset_view": "syn23643253", + "entity_id": entity_id + } + response = client.get("http://localhost:3001/v1/storage/entity/type", query_string = params) + + assert response.status_code == 200 + response_dt = json.loads(response.data) + if entity_id == "syn23643253": + assert response_dt == "asset view" + elif entity_id == "syn34640850": + assert response_dt == "folder" + elif entity_id == "syn24992754": + assert response_dt == "project" + + @pytest.mark.parametrize("entity_id", ["syn30988314", "syn27221721"]) + def test_if_in_assetview(self, syn_token, client, entity_id): + params = { + "input_token": syn_token, + "asset_view": "syn23643253", + "entity_id": entity_id + } + response = client.get("http://localhost:3001/v1/storage/if_in_asset_view", query_string = params) + assert response.status_code == 200 + response_dt = json.loads(response.data) + if entity_id == "syn30988314": + assert response_dt == True + elif entity_id == "syn27221721": + assert response_dt == False @pytest.mark.schematic_api class TestMetadataModelOperation: From e9bd0345154d8e840ea1900a5e3a380935043c17 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 19 Jan 2023 11:53:28 -0500 Subject: [PATCH 036/615] fix input token error on aws --- api/openapi/api.yaml | 6 ++++++ api/routes.py | 13 +++++++------ schematic/manifest/generator.py | 6 ++++-- 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index f6d06965f..d051fa608 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -23,6 +23,12 @@ paths: example: >- https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld required: true + - in: query + name: input_token + schema: + type: string + description: Token is needed if getting an existing manifest on AWS + required: false - in: query name: title schema: diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..29e1b0790 100644 --- a/api/routes.py +++ b/api/routes.py @@ -197,7 +197,7 @@ def get_temp_jsonld(schema_url): return tmp_file.name # @before_request -def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, asset_view = None, output_format=None, title=None): +def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, asset_view = None, output_format=None, title=None, input_token=None): """Get the immediate dependencies that are related to a given source node. Args: schema_url: link to data model in json ld format @@ -206,6 +206,7 @@ def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, output_format: contains three option: "excel", "google_sheet", and "dataframe". if set to "excel", return an excel spreadsheet use_annotations: Whether to use existing annotations during manifest generation asset_view: ID of view listing all project data assets. For example, for Synapse this would be the Synapse ID of the fileview listing all data assets for a given project. + input_token: Token Returns: Googlesheet URL (if sheet_url is True), or pandas dataframe (if sheet_url is False). """ @@ -251,7 +252,7 @@ def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, ) - def create_single_manifest(data_type, title, dataset_id=None, output_format=None): + def create_single_manifest(data_type, title, dataset_id=None, output_format=None, input_token=None): # create object of type ManifestGenerator manifest_generator = ManifestGenerator( path_to_json_ld=jsonld, @@ -267,7 +268,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None output_format = "dataframe" result = manifest_generator.get_manifest( - dataset_id=dataset_id, sheet_url=True, output_format=output_format + dataset_id=dataset_id, sheet_url=True, output_format=output_format, input_token=input_token ) # return an excel file if output_format is set to "excel" @@ -291,7 +292,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None else: t = f'Example.{component}.manifest' if output_format != "excel": - result = create_single_manifest(data_type=component, output_format=output_format, title=t) + result = create_single_manifest(data_type=component, output_format=output_format, title=t, input_token=input_token) all_results.append(result) else: app.logger.error('Currently we do not support returning multiple files as Excel format at once. Please choose a different output format. ') @@ -306,9 +307,9 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None t = title if dataset_ids: # if a dataset_id is provided add this to the function call. - result = create_single_manifest(data_type=dt, dataset_id=dataset_ids[i], output_format=output_format, title=t) + result = create_single_manifest(data_type=dt, dataset_id=dataset_ids[i], output_format=output_format, title=t, input_token=input_token) else: - result = create_single_manifest(data_type=dt, output_format=output_format, title=t) + result = create_single_manifest(data_type=dt, output_format=output_format, title=t, input_token=input_token) # if output is pandas dataframe or google sheet url if isinstance(result, str) or isinstance(result, pd.DataFrame): diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index da8a500d6..04aa1be68 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1504,7 +1504,7 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st return manifest_url def get_manifest( - self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None + self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None, input_token: str = None ) -> Union[str, pd.DataFrame]: """Gets manifest for a given dataset on Synapse. TODO: move this function to class MetadatModel (after MetadataModel is refactored) @@ -1514,6 +1514,7 @@ def get_manifest( sheet_url: Determines if googlesheet URL or pandas dataframe should be returned. output_format: Determines if Google sheet URL, pandas dataframe, or Excel spreadsheet gets returned. output_path: Determines the output path of the exported manifest + input_token: Token in .synapseConfig. Since we could not pre-load access_token as an environment variable on AWS, we have to add this variable. Returns: Googlesheet URL, pandas dataframe, or an Excel spreadsheet @@ -1535,7 +1536,8 @@ def get_manifest( #TODO: avoid explicitly exposing Synapse store functionality # just instantiate a Store class and let it decide at runtime/config # the store type - + if input_token: + store = SynapseStorage(input_token=input_token) store = SynapseStorage() # Get manifest file associated with given dataset (if applicable) From ce267070d5844b585c24e29dbe84e58ca6654350 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 09:54:53 -0700 Subject: [PATCH 037/615] update testing data --- tests/data/mock_manifests/rdb_table_manifest.csv | 5 +++++ tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 tests/data/mock_manifests/rdb_table_manifest.csv create mode 100644 tests/data/mock_manifests/rdb_table_manifest_upsert.csv diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv new file mode 100644 index 000000000..a2272e6fa --- /dev/null +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -0,0 +1,5 @@ +Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +1,Male,1965,Healthy,Patient,, +2,Female,1966,Healthy,Patient,, +3,Male,1967,Healthy,Patient,, +4,Female,1968,Healthy,Patient,, diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv new file mode 100644 index 000000000..f37da7f2f --- /dev/null +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -0,0 +1,5 @@ +Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +5,Male,1954,Healthy,Patient,, +6,Female,1955,Healthy,Patient,, +7,Male,1956,Healthy,Patient,, +8,Female,1957,Healthy,Patient,, From 00121a82ebbffc7964ba7df1b95a1d526b517e07 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:20:36 -0700 Subject: [PATCH 038/615] add table upsert functionality --- schematic/store/synapse.py | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c7b94f9f0..55ae01515 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -38,6 +38,10 @@ import uuid +from schematic_db.synapse.synapse import SynapseConfig +from schematic_db.rdb.synapse_database import SynapseDatabase +from schematic_db.schema.schema import get_key_attribute + from schematic.utils.df_utils import update_df, load_df from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list from schematic.schemas.explorer import SchemaExplorer @@ -823,7 +827,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) + manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) else: manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) @@ -1526,8 +1530,21 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) return existingTableId - def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): - raise NotImplementedError + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) + + if config.has_option('authentication', 'username') and config.has_option('authentication', 'authtoken'): + cache_root_dir = config.get('authentication', 'username') + + synConfig = SynapseConfig(config.get('authentication', 'username'),config.get('authentication', 'authtoken'),synStore.getDatasetProject(datasetId)) + else: + raise ValueError + + synapseDB = SynapseDatabase(synConfig) + synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) + + return existingTableId + From 4079267f9458f92df70c19a25c80866049c487e9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:21:52 -0700 Subject: [PATCH 039/615] add update table functionality --- schematic/store/synapse.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 55ae01515..5722af384 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1160,13 +1160,11 @@ def associateMetadataWithFiles( if manifest_record_type == 'table' or manifest_record_type == 'both': # Update manifest Synapse table with new entity id column. - TableOperations.replaceTable(self, + TableOperations.updateTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=manifest_synapse_table_id, specifySchema=True, - datasetId=datasetId, - columnTypeDict=col_schema, restrict=restrict_manifest) # Set annotations for the table manifest @@ -1545,7 +1543,14 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + existing_table, existing_results = synStore.get_synapse_table(existingTableId) + + tableToLoad = update_df(existing_table, tableToLoad, update_col) + # store table with existing etag data and impose restrictions as appropriate + synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) + return class DatasetFileView: From cd91ff94b9778329416c815424010678df52c544 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:22:16 -0700 Subject: [PATCH 040/615] rm unused params --- schematic/store/synapse.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 5722af384..e01368945 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1162,9 +1162,7 @@ def associateMetadataWithFiles( TableOperations.updateTable(self, tableToLoad=table_manifest, - tableName=table_name, existingTableId=manifest_synapse_table_id, - specifySchema=True, restrict=restrict_manifest) # Set annotations for the table manifest From 62254674b006497c0193bd95ed924dace6abfb5e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:00:21 -0700 Subject: [PATCH 041/615] update upsert test for new dummy data --- tests/test_store.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index a86e1aac6..c87f995b2 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -377,10 +377,10 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId): table_manipulation = 'upsert' - table_name='followup_synapse_storage_manifest_table' - manifest_path = "mock_manifests/table_manifest.csv" - replacement_manifest_path = "mock_manifests/table_manifest_upsert.csv" - column_of_interest="DaystoFollowUp" + table_name='patient_synapse_storage_manifest_table' + manifest_path = "mock_manifests/rdb_table_manifest.csv" + replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" + column_of_interest="PatientID" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -411,22 +411,24 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) #set primary key annotation for uploaded table tableId = existing_tables[table_name] annos = synapse_store.syn.get_annotations(tableId) - annos['primary_key'] = 'FollowUp_id' + annos['primary_key'] = 'PatientID' annos=synapse_store.syn.set_annotations(annos) + sleep(5) # Query table for DaystoFollowUp column - daysToFollowUp = synapse_store.syn.tableQuery( + patientIDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() - # assert Days to FollowUp == 73 - assert (daysToFollowUp == '73.0').all() + # assert max ID is '4' and that there are 4 entries + assert patientIDs.max() == '4' + assert patientIDs.size == 4 # Associate new manifest with files manifestId = synapse_store.associateMetadataWithFiles( schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(replacement_manifest_path), - datasetId = datasetId, + datasetId = datasetId, manifest_record_type = 'table', useSchemaLabel = True, hideBlanks = True, @@ -437,11 +439,12 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # Query table for DaystoFollowUp column tableId = existing_tables[table_name] - daysToFollowUp = synapse_store.syn.tableQuery( + patientIDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() - # assert Days to FollowUp is not all '73' - assert not (daysToFollowUp == '73').all() + # assert max ID is '4' and that there are 4 entries + assert patientIDs.max() == '8' + assert patientIDs.size == 8 # delete table synapse_store.syn.delete(tableId) From f5fed46faa9761a59be4653b893634e65eb1c092 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:12:22 -0700 Subject: [PATCH 042/615] reimplement table update functionality --- schematic/store/synapse.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c7b94f9f0..a7cc1150c 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1156,13 +1156,9 @@ def associateMetadataWithFiles( if manifest_record_type == 'table' or manifest_record_type == 'both': # Update manifest Synapse table with new entity id column. - TableOperations.replaceTable(self, + TableOperations.updateTable(self, tableToLoad=table_manifest, - tableName=table_name, existingTableId=manifest_synapse_table_id, - specifySchema=True, - datasetId=datasetId, - columnTypeDict=col_schema, restrict=restrict_manifest) # Set annotations for the table manifest @@ -1529,7 +1525,14 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): raise NotImplementedError + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + existing_table, existing_results = synStore.get_synapse_table(existingTableId) + + tableToLoad = update_df(existing_table, tableToLoad, update_col) + # store table with existing etag data and impose restrictions as appropriate + synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) + return class DatasetFileView: """Helper class to create temporary dataset file views. From 6af97c905ad5fbb8ce28268fa93feea8df955d73 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:22:50 -0700 Subject: [PATCH 043/615] add additional logic check for annotations --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a7cc1150c..8da02df2b 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -537,7 +537,7 @@ def getProjectManifests(self, projectId: str) -> List[str]: annotations = self.getFileAnnotations(manifestId) # If manifest has annotations specifying component, use that - if 'Component' in annotations: + if annotations and 'Component' in annotations: component = annotations['Component'] entity = self.syn.get(manifestId, downloadFile=False) manifest_name = entity["properties"]["name"] From 9523c43e141e9163965a48bd990615bdc64e3827 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:40:27 -0700 Subject: [PATCH 044/615] remove col_schema return --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 8da02df2b..51fb97182 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -766,7 +766,7 @@ def uploadDB(self, manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) - return manifest_table_id, manifest, table_manifest, col_schema + return manifest_table_id, manifest, table_manifest def formatDB(self, se, manifest, datasetId, useSchemaLabel): # Rename the manifest columns to display names to match fileview @@ -1112,7 +1112,7 @@ def associateMetadataWithFiles( # If specified, upload manifest as a table and get the SynID and manifest if manifest_record_type == 'table' or manifest_record_type == 'both': - manifest_synapse_table_id, manifest, table_manifest, col_schema = self.uploadDB( + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation=table_manipulation,) # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed From d7ed1209e5e43c9f01982a998f04ab6e83a8cdb2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:48:28 -0700 Subject: [PATCH 045/615] clean synStore method inputs and add docstrings --- schematic/store/synapse.py | 49 +++++++++++++++++++++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 51fb97182..c8a606bfc 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -760,6 +760,25 @@ def uploadDB(self, existingTableId: str = None, table_manipulation: str = 'replace', ): + """ + Method to upload a database to an asset store. In synapse, this will upload a metadata table + + Args: + se: schemaExplorer object + manifest: pd.Df manifest to upload + datasetId: synID of the dataset for the manifest + table_name: name of the table to be uploaded + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + useSchemaLabel: bool whether to use schemaLabel (True) or display label (False) + existingTableId: str of the synId of the existing table, if one already exists + table_manipulation: str, 'replace' or 'upsert', in the case where a manifest already exists, should the new metadata replace the existing (replace) or be added to it (upsert) + + Returns: + manifest_table_id: synID of the uploaded table + manifest: the original manifset + table_manifest: manifest formatted appropriately for the table + + """ col_schema, table_manifest = self.formatDB(se, manifest, datasetId, useSchemaLabel) @@ -768,7 +787,20 @@ def uploadDB(self, return manifest_table_id, manifest, table_manifest - def formatDB(self, se, manifest, datasetId, useSchemaLabel): + def formatDB(self, se, manifest, useSchemaLabel): + """ + Method to format a manifest appropriatly for upload as table + + Args: + se: schemaExplorer object + manifest: pd.Df manifest to upload + useSchemaLabel: bool whether to use schemaLabel (True) or display label (False) + + Returns: + col_schema: schema for table columns: type, size, etc + table_manifest: formatted manifest + + """ # Rename the manifest columns to display names to match fileview blacklist_chars = ['(', ')', '.', ' ', '-'] @@ -812,7 +844,22 @@ def buildDB(self, table_manipulation: str, restrict: bool = False, ): + """ + Method to construct the table appropriately: create new table, replace existing, or upsert new into existing + Calls TableOperations class to execute + + Args: + datasetId: synID of the dataset for the manifest + table_name: name of the table to be uploaded + col_schema: schema for table columns: type, size, etc from `formatDB` + table_manifest: formatted manifest taht can be uploaded as a table + table_manipulation: str, 'replace' or 'upsert', in the case where a manifest already exists, should the new metadata replace the existing (replace) or be added to it (upsert) + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + Returns: + manifest_table_id: synID of the uploaded table + + """ table_info = self.get_table_info(datasetId = datasetId) # Put table manifest onto synapse schema = Schema(name=table_name, columns=col_schema, parent=self.getDatasetProject(datasetId)) From 86b57fea0982370f901c3221dd70afaa7cd5ba62 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:02:48 -0700 Subject: [PATCH 046/615] update method inputs outputs and docstrings --- schematic/store/synapse.py | 68 ++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c8a606bfc..d9bd5bcbc 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1203,10 +1203,7 @@ def associateMetadataWithFiles( if manifest_record_type == 'table' or manifest_record_type == 'both': # Update manifest Synapse table with new entity id column. - TableOperations.updateTable(self, - tableToLoad=table_manifest, - existingTableId=manifest_synapse_table_id, - restrict=restrict_manifest) + manifest_synapse_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=manifest_synapse_table_id, restrict=restrict_manifest) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1461,8 +1458,36 @@ def _get_table_schema_by_cname(self, table_schema): return table_schema_by_cname class TableOperations: + """ + Object to hold functions for various table operations specific to the Synapse Asset Store. + + Currently implement operations are: + createTable: upload a manifest as a new table when none exist + replaceTable: replace a metadata in a table from one manifest with metadata from another manifest + updateTable: add a column to a table that already exists on synapse + + Operations currently in development are: + upsertTable: add metadata from a manifest to an existing table that contains metadata from another manifest + """ + def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, datasetId: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): + """ + Method to create a table from a metadata manifest and upload it to synapse + + Args: + tableToLoad: manifest formatted appropriately for the table + tableName: name of the table to be uploaded + datasetId: synID of the dataset for the manifest + columnTypeDict: dictionary schema for table columns: type, size, etc + specifySchema: to specify a specific schema for the table format + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + + + Returns: + table.schema.id: synID of the newly created table + """ + datasetEntity = synStore.syn.get(datasetId, downloadFile = False) datasetName = datasetEntity.name table_schema_by_cname = synStore._get_table_schema_by_cname(columnTypeDict) @@ -1503,6 +1528,22 @@ def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return table.schema.id def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, specifySchema: bool = True, datasetId: str = None, columnTypeDict: dict = None, restrict: bool = False): + """ + Method to create a table from a metadata manifest and upload it to synapse + + Args: + tableToLoad: manifest formatted appropriately for the table + tableName: name of the table to be uploaded + existingTableId: synId of the existing table to be replaced + specifySchema: to infer a schema for the table format + datasetId: synID of the dataset for the manifest + columnTypeDict: dictionary schema for table columns: type, size, etc + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + + + Returns: + existingTableId: synID of the already existing table that had its metadata replaced + """ datasetEntity = synStore.syn.get(datasetId, downloadFile = False) datasetName = datasetEntity.name table_schema_by_cname = synStore._get_table_schema_by_cname(columnTypeDict) @@ -1572,14 +1613,27 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): raise NotImplementedError - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, updateCol: str = 'Uuid', restrict: bool = False): + """ + Method to update an existing table with a new column + + Args: + tableToLoad: manifest formatted appropriately for the table, that contains the new column + existingTableId: synId of the existing table to be replaced + updateCol: column to index the old and new tables on + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + + + Returns: + existingTableId: synID of the already existing table that had its metadata replaced + """ existing_table, existing_results = synStore.get_synapse_table(existingTableId) - tableToLoad = update_df(existing_table, tableToLoad, update_col) + tableToLoad = update_df(existing_table, tableToLoad, updateCol) # store table with existing etag data and impose restrictions as appropriate synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) - return + return existingTableId class DatasetFileView: """Helper class to create temporary dataset file views. From 6eb5e12f34cae530fe94b411a9288fb272ec05e3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:07:09 -0700 Subject: [PATCH 047/615] remove extra input --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d9bd5bcbc..35f765f7d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -781,7 +781,7 @@ def uploadDB(self, """ - col_schema, table_manifest = self.formatDB(se, manifest, datasetId, useSchemaLabel) + col_schema, table_manifest = self.formatDB(se, manifest, useSchemaLabel) manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) From 43e717edcf4e4a725954ad9ecf1bf0a14ba83c79 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 12:39:23 -0700 Subject: [PATCH 048/615] reorder logic --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 35f765f7d..1faa7cf1c 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -543,7 +543,7 @@ def getProjectManifests(self, projectId: str) -> List[str]: manifest_name = entity["properties"]["name"] # otherwise download the manifest and parse for information - elif 'Component' not in annotations or not annotations: + elif not annotations or 'Component' not in annotations: logging.debug( f"No component annotations have been found for manifest {manifestId}. " "The manifest will be downloaded and parsed instead. " From cc06d8ad7a9dd46937047e9b16282c4b7c9c7a8e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 14:07:15 -0700 Subject: [PATCH 049/615] use common table upload method in aMWF --- schematic/store/synapse.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 1faa7cf1c..eac966b95 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -871,6 +871,8 @@ def buildDB(self, manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) + elif table_manipulation.lower() == 'update': + manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) else: manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) @@ -1202,9 +1204,10 @@ def associateMetadataWithFiles( if manifest_record_type == 'table' or manifest_record_type == 'both': # Update manifest Synapse table with new entity id column. - - manifest_synapse_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=manifest_synapse_table_id, restrict=restrict_manifest) + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation='update',) + # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) self.syn.set_annotations(manifest_annotations) From bfb1838134f17d97615117eaef0da720fda350f3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 14:23:01 -0700 Subject: [PATCH 050/615] add `primary_key` annotation at upload when 'upsert' is specified --- schematic/store/synapse.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 894c4426e..90ebf5db7 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -831,6 +831,14 @@ def buildDB(self, else: manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) + + if table_manipulation.lower() == 'upsert': + existing_tables=self.get_table_info(datasetId=datasetId) + tableId=existing_tables[table_name] + annos = self.syn.get_annotations(tableId) + annos['primary_key'] = get_key_attribute(table_manifest['Component'][0]) + annos = self.syn.set_annotations(annos) + return manifest_table_id From 9fc8bf0dcae172ea0fe78b34293e73d1362ea265 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 14:24:06 -0700 Subject: [PATCH 051/615] change to primary key col name in test data --- tests/data/mock_manifests/rdb_table_manifest.csv | 2 +- tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index a2272e6fa..785ed869a 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,4 +1,4 @@ -Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History 1,Male,1965,Healthy,Patient,, 2,Female,1966,Healthy,Patient,, 3,Male,1967,Healthy,Patient,, diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index f37da7f2f..ddc2ecf5b 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,4 +1,4 @@ -Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History 5,Male,1954,Healthy,Patient,, 6,Female,1955,Healthy,Patient,, 7,Male,1956,Healthy,Patient,, From 6bd262e8a50d43c746a6a2a07a73a2f6f9305dae Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 19 Jan 2023 17:32:49 -0500 Subject: [PATCH 052/615] fix error in loop --- schematic/store/synapse.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 86603932d..11eb358bf 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -571,9 +571,10 @@ def getProjectManifests(self, projectId: str) -> List[str]: logging.warning( f"Manifest {manifestId} is composed of multiple components. Schematic does not support mulit-component manifests at this time." "Behavior of manifests with multiple components is undefined" - ) - - #save manifest list with applicable informaiton + ) + else: + manifest_name = "" + component = None if component: manifest = ( (datasetId, datasetName), @@ -594,6 +595,8 @@ def getProjectManifests(self, projectId: str) -> List[str]: ("", ""), ) + print('manifest', manifest) + if manifest: manifests.append(manifest) From d6f5d5a78fc20cedd9ba93ece3dd6be0e3dbd0a7 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 20 Jan 2023 13:14:33 -0500 Subject: [PATCH 053/615] add else statement --- schematic/manifest/generator.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 04aa1be68..cc2302abd 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1537,8 +1537,10 @@ def get_manifest( # just instantiate a Store class and let it decide at runtime/config # the store type if input_token: + # for getting an existing manifest on AWS store = SynapseStorage(input_token=input_token) - store = SynapseStorage() + else: + store = SynapseStorage() # Get manifest file associated with given dataset (if applicable) # populate manifest with set of new files (if applicable) From 2eb4cace42198d88e1c06d4b666ac1d4d0433d04 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:32:02 -0700 Subject: [PATCH 054/615] add upsert test and dummy data --- tests/data/mock_manifests/table_manifest.csv | 19 +++--- tests/test_store.py | 67 ++++++++++++++++++++ 2 files changed, 77 insertions(+), 9 deletions(-) diff --git a/tests/data/mock_manifests/table_manifest.csv b/tests/data/mock_manifests/table_manifest.csv index c64988577..9ee49f177 100644 --- a/tests/data/mock_manifests/table_manifest.csv +++ b/tests/data/mock_manifests/table_manifest.csv @@ -1,10 +1,11 @@ Component,Days to Follow Up,Adverse Event,Progression or Recurrence,Barretts Esophagus Goblet Cells Present,BMI,Cause of Response,Comorbidity,Comorbidity Method of Diagnosis,Days to Adverse Event,Days to Comorbidity,Diabetes Treatment Type,Disease Response,DLCO Ref Predictive Percent,ECOG Performance Status,FEV1 FVC Post Bronch Percent,FEV 1 FVC Pre Bronch Percent,FEV1 Ref Post Bronch Percent,FEV1 Ref Pre Bronch Percent,Height,Hepatitis Sustained Virological Response,HPV Positive Type,Karnofsky Performance Status,Menopause Status,Pancreatitis Onset Year,Reflux Treatment Type,Risk Factor,Risk Factor Treatment,Viral Hepatitis Serologies,Weight,Days to Progression,Days to Progression Free,Days to Recurrence,Progression or Recurrence Anatomic Site,Progression or Recurrence Type,entityId,HTAN Participant ID -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462.0 -FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454.0 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458 +FollowUp,93,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,463 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462 +FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454 diff --git a/tests/test_store.py b/tests/test_store.py index 0c8ffacf0..3543287d5 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -373,3 +373,70 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId assert (daysToFollowUp == '89').all() # delete table synapse_store.syn.delete(tableId) + + def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId): + table_manipulation = 'upsert' + + table_name='followup_synapse_storage_manifest_table' + manifest_path = "mock_manifests/table_manifest.csv" + replacement_manifest_path = "mock_manifests/table_manifest_upsert.csv" + column_of_interest="DaystoFollowUp" + + # Check if FollowUp table exists if so delete + existing_tables = synapse_store.get_table_info(projectId = projectId) + + if table_name in existing_tables.keys(): + synapse_store.syn.delete(existing_tables[table_name]) + sleep(10) + # assert no table + assert table_name not in synapse_store.get_table_info(projectId = projectId).keys() + + # associate org FollowUp metadata with files + inputModelLocaiton = helpers.get_data_path(get_from_config(config.DATA, ("model", "input", "location"))) + sg = SchemaGenerator(inputModelLocaiton) + + # updating file view on synapse takes a long time + manifestId = synapse_store.associateMetadataWithFiles( + schemaGenerator = sg, + metadataManifestPath = helpers.get_data_path(manifest_path), + datasetId = datasetId, + manifest_record_type = 'table', + useSchemaLabel = True, + hideBlanks = True, + restrict_manifest = False, + table_manipulation=table_manipulation, + ) + existing_tables = synapse_store.get_table_info(projectId = projectId) + + # Query table for DaystoFollowUp column + tableId = existing_tables[table_name] + daysToFollowUp = synapse_store.syn.tableQuery( + f"SELECT {column_of_interest} FROM {tableId}" + ).asDataFrame().squeeze() + + # assert Days to FollowUp == 73 + assert (daysToFollowUp == '73.0').all() + + # Associate new manifest with files + manifestId = synapse_store.associateMetadataWithFiles( + schemaGenerator = sg, + metadataManifestPath = helpers.get_data_path(replacement_manifest_path), + datasetId = datasetId, + manifest_record_type = 'table', + useSchemaLabel = True, + hideBlanks = True, + restrict_manifest = False, + table_manipulation=table_manipulation, + ) + existing_tables = synapse_store.get_table_info(projectId = projectId) + + # Query table for DaystoFollowUp column + tableId = existing_tables[table_name] + daysToFollowUp = synapse_store.syn.tableQuery( + f"SELECT {column_of_interest} FROM {tableId}" + ).asDataFrame().squeeze() + + # assert Days to FollowUp is not all '73' + assert not (daysToFollowUp == '73').all() + # delete table + synapse_store.syn.delete(tableId) From 72d6c472eec1a0417e18fdb1252063a18faf0bce Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:43:52 -0700 Subject: [PATCH 055/615] set primary key annotation for uploaded table --- tests/test_store.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 3543287d5..72c3188dc 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -408,8 +408,13 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) ) existing_tables = synapse_store.get_table_info(projectId = projectId) - # Query table for DaystoFollowUp column + #set primary key annotation for uploaded table tableId = existing_tables[table_name] + annos = synapse_store.get_annotations(tableId) + annos['primary_key'] = 'FollowUp_id' + annos=synapse_store.set_annotations(annos) + + # Query table for DaystoFollowUp column daysToFollowUp = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() From 3913507b18cc059778170e2a6aa503fbbf843b2f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:48:30 -0700 Subject: [PATCH 056/615] correct object usage --- tests/test_store.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index 72c3188dc..a86e1aac6 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -410,9 +410,9 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) #set primary key annotation for uploaded table tableId = existing_tables[table_name] - annos = synapse_store.get_annotations(tableId) + annos = synapse_store.syn.get_annotations(tableId) annos['primary_key'] = 'FollowUp_id' - annos=synapse_store.set_annotations(annos) + annos=synapse_store.syn.set_annotations(annos) # Query table for DaystoFollowUp column daysToFollowUp = synapse_store.syn.tableQuery( From 3cdcb367ac4d0bd641c05d299aa6f72e46411825 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 18 Jan 2023 11:53:29 -0700 Subject: [PATCH 057/615] revert manifest change --- tests/data/mock_manifests/table_manifest.csv | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/tests/data/mock_manifests/table_manifest.csv b/tests/data/mock_manifests/table_manifest.csv index 9ee49f177..c64988577 100644 --- a/tests/data/mock_manifests/table_manifest.csv +++ b/tests/data/mock_manifests/table_manifest.csv @@ -1,11 +1,10 @@ Component,Days to Follow Up,Adverse Event,Progression or Recurrence,Barretts Esophagus Goblet Cells Present,BMI,Cause of Response,Comorbidity,Comorbidity Method of Diagnosis,Days to Adverse Event,Days to Comorbidity,Diabetes Treatment Type,Disease Response,DLCO Ref Predictive Percent,ECOG Performance Status,FEV1 FVC Post Bronch Percent,FEV 1 FVC Pre Bronch Percent,FEV1 Ref Post Bronch Percent,FEV1 Ref Pre Bronch Percent,Height,Hepatitis Sustained Virological Response,HPV Positive Type,Karnofsky Performance Status,Menopause Status,Pancreatitis Onset Year,Reflux Treatment Type,Risk Factor,Risk Factor Treatment,Viral Hepatitis Serologies,Weight,Days to Progression,Days to Progression Free,Days to Recurrence,Progression or Recurrence Anatomic Site,Progression or Recurrence Type,entityId,HTAN Participant ID -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458 -FollowUp,93,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,463 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462 -FollowUp,73,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249015,455.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22249915,456.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22687161,457.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22688035,458.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978930,459.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978946,460.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22978975,461.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn22979177,462.0 +FollowUp,73.0,,Not Reported,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,syn21989551,454.0 From b2276e6c02e7f4c3a24f93bddf08b2bf9e82a692 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 09:54:53 -0700 Subject: [PATCH 058/615] update testing data --- tests/data/mock_manifests/rdb_table_manifest.csv | 5 +++++ tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 tests/data/mock_manifests/rdb_table_manifest.csv create mode 100644 tests/data/mock_manifests/rdb_table_manifest_upsert.csv diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv new file mode 100644 index 000000000..a2272e6fa --- /dev/null +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -0,0 +1,5 @@ +Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +1,Male,1965,Healthy,Patient,, +2,Female,1966,Healthy,Patient,, +3,Male,1967,Healthy,Patient,, +4,Female,1968,Healthy,Patient,, diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv new file mode 100644 index 000000000..f37da7f2f --- /dev/null +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -0,0 +1,5 @@ +Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +5,Male,1954,Healthy,Patient,, +6,Female,1955,Healthy,Patient,, +7,Male,1956,Healthy,Patient,, +8,Female,1957,Healthy,Patient,, From 04e931e5875f1743e02f890bbef2ca5e4d906f05 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:20:36 -0700 Subject: [PATCH 059/615] add table upsert functionality --- schematic/store/synapse.py | 30 +++++++----------------------- 1 file changed, 7 insertions(+), 23 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index eac966b95..1b011bfcf 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -38,6 +38,10 @@ import uuid +from schematic_db.synapse.synapse import SynapseConfig +from schematic_db.rdb.synapse_database import SynapseDatabase +from schematic_db.schema.schema import get_key_attribute + from schematic.utils.df_utils import update_df, load_df from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list from schematic.schemas.explorer import SchemaExplorer @@ -870,7 +874,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) + manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) else: @@ -1613,30 +1617,10 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) return existingTableId - def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): - raise NotImplementedError - - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, updateCol: str = 'Uuid', restrict: bool = False): - """ - Method to update an existing table with a new column - - Args: - tableToLoad: manifest formatted appropriately for the table, that contains the new column - existingTableId: synId of the existing table to be replaced - updateCol: column to index the old and new tables on - restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions - + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) - Returns: - existingTableId: synID of the already existing table that had its metadata replaced - """ - existing_table, existing_results = synStore.get_synapse_table(existingTableId) - - tableToLoad = update_df(existing_table, tableToLoad, updateCol) - # store table with existing etag data and impose restrictions as appropriate - synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) - return existingTableId class DatasetFileView: """Helper class to create temporary dataset file views. From b8a9c1878724c8c2ff9afbb63172f5666f1063a8 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 10:21:52 -0700 Subject: [PATCH 060/615] add update table functionality --- schematic/store/synapse.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 1b011bfcf..f8246d3de 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1622,6 +1622,21 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non + synapseDB = SynapseDatabase(synConfig) + synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) + + return existingTableId + + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + existing_table, existing_results = synStore.get_synapse_table(existingTableId) + + tableToLoad = update_df(existing_table, tableToLoad, update_col) + # store table with existing etag data and impose restrictions as appropriate + synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) + + return + + class DatasetFileView: """Helper class to create temporary dataset file views. This class can be used in conjunction with a 'with' statement. From 81c0b5f4160b43a6185378a60f81d6bae66292ff Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 11:00:21 -0700 Subject: [PATCH 061/615] update upsert test for new dummy data --- tests/test_store.py | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index a86e1aac6..c87f995b2 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -377,10 +377,10 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId): table_manipulation = 'upsert' - table_name='followup_synapse_storage_manifest_table' - manifest_path = "mock_manifests/table_manifest.csv" - replacement_manifest_path = "mock_manifests/table_manifest_upsert.csv" - column_of_interest="DaystoFollowUp" + table_name='patient_synapse_storage_manifest_table' + manifest_path = "mock_manifests/rdb_table_manifest.csv" + replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" + column_of_interest="PatientID" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -411,22 +411,24 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) #set primary key annotation for uploaded table tableId = existing_tables[table_name] annos = synapse_store.syn.get_annotations(tableId) - annos['primary_key'] = 'FollowUp_id' + annos['primary_key'] = 'PatientID' annos=synapse_store.syn.set_annotations(annos) + sleep(5) # Query table for DaystoFollowUp column - daysToFollowUp = synapse_store.syn.tableQuery( + patientIDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() - # assert Days to FollowUp == 73 - assert (daysToFollowUp == '73.0').all() + # assert max ID is '4' and that there are 4 entries + assert patientIDs.max() == '4' + assert patientIDs.size == 4 # Associate new manifest with files manifestId = synapse_store.associateMetadataWithFiles( schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(replacement_manifest_path), - datasetId = datasetId, + datasetId = datasetId, manifest_record_type = 'table', useSchemaLabel = True, hideBlanks = True, @@ -437,11 +439,12 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # Query table for DaystoFollowUp column tableId = existing_tables[table_name] - daysToFollowUp = synapse_store.syn.tableQuery( + patientIDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() - # assert Days to FollowUp is not all '73' - assert not (daysToFollowUp == '73').all() + # assert max ID is '4' and that there are 4 entries + assert patientIDs.max() == '8' + assert patientIDs.size == 8 # delete table synapse_store.syn.delete(tableId) From 1758b6d7145839311fea1b73834ca14f38a159f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 14:23:01 -0700 Subject: [PATCH 062/615] add `primary_key` annotation at upload when 'upsert' is specified --- schematic/store/synapse.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index f8246d3de..4e0cb0a03 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -880,6 +880,14 @@ def buildDB(self, else: manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) + + if table_manipulation.lower() == 'upsert': + existing_tables=self.get_table_info(datasetId=datasetId) + tableId=existing_tables[table_name] + annos = self.syn.get_annotations(tableId) + annos['primary_key'] = get_key_attribute(table_manifest['Component'][0]) + annos = self.syn.set_annotations(annos) + return manifest_table_id From 1c6185a8acfcf384c89e66b8bab0eb2e0bf32767 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 19 Jan 2023 14:24:06 -0700 Subject: [PATCH 063/615] change to primary key col name in test data --- tests/data/mock_manifests/rdb_table_manifest.csv | 2 +- tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index a2272e6fa..785ed869a 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,4 +1,4 @@ -Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History 1,Male,1965,Healthy,Patient,, 2,Female,1966,Healthy,Patient,, 3,Male,1967,Healthy,Patient,, diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index f37da7f2f..ddc2ecf5b 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,4 +1,4 @@ -Patient ID,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History +Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History 5,Male,1954,Healthy,Patient,, 6,Female,1955,Healthy,Patient,, 7,Male,1956,Healthy,Patient,, From e25bb815784ca3a62129d95ba745eecf0d2f7b51 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 10:09:32 -0700 Subject: [PATCH 064/615] Revert "Merge branch 'develop-schematicDB-incorp' of https://github.com/Sage-Bionetworks/schematic into develop-schematicDB-incorp" This reverts commit 01274af48daf71caf926e10bc3a9f000352c3771, reversing changes made to 1c6185a8acfcf384c89e66b8bab0eb2e0bf32767. --- schematic/store/synapse.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 5144a7305..4e0cb0a03 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -874,7 +874,9 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) + manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) + elif table_manipulation.lower() == 'update': + manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) else: manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) @@ -1623,8 +1625,15 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) return existingTableId - def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): - raise NotImplementedError + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) + + + + synapseDB = SynapseDatabase(synConfig) + synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) + + return existingTableId def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): existing_table, existing_results = synStore.get_synapse_table(existingTableId) From 80f5ca7ce21ba9a6126fb20e4720db9fc22671a5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 10:43:31 -0700 Subject: [PATCH 065/615] re-add synConfig build --- schematic/store/synapse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 4e0cb0a03..bd11dc8ce 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1628,6 +1628,8 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) + if config.has_option('authentication', 'username') and config.has_option('authentication', 'authtoken'): + synConfig = SynapseConfig(config.get('authentication', 'username'), config.get('authentication', 'authtoken'), synStore.getDatasetProject(datasetId) ) synapseDB = SynapseDatabase(synConfig) From 31f6bd1717121d53107775b836dfb79ac7cfbfd6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 10:43:41 -0700 Subject: [PATCH 066/615] return table ID for updates --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index bd11dc8ce..926754967 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1644,7 +1644,7 @@ def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str # store table with existing etag data and impose restrictions as appropriate synStore.syn.store(Table(existingTableId, tableToLoad, etag = existing_results.etag), isRestricted = restrict) - return + return existingTableId class DatasetFileView: From c8501664ca2cd5d1a1da3953312df7782ea65517 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:28:54 -0700 Subject: [PATCH 067/615] remove `v3.7` and `v3.8` tests --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3192670d7..3437bf14b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,7 +31,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.7", "3.8", "3.9", "3.10"] + python-version: ["3.9", "3.10"] steps: From 781859173490ae109b7810a34c8afc044bc7e552 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 13:30:27 -0700 Subject: [PATCH 068/615] remove old python versions from .toml --- poetry.lock | 1349 ++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 725 insertions(+), 626 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5bfb7bd30..23ab3478e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,10 @@ [[package]] name = "alabaster" -version = "0.7.12" +version = "0.7.13" description = "A configurable sidebar-enabled Sphinx theme" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "altair" @@ -36,7 +36,6 @@ python-versions = ">=3.6.2" [package.dependencies] idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] @@ -69,7 +68,6 @@ python-versions = ">=3.6" [package.dependencies] argon2-cffi-bindings = "*" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] dev = ["cogapp", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "pre-commit", "pytest", "sphinx", "sphinx-notfound-page", "tomli"] @@ -92,16 +90,18 @@ dev = ["cogapp", "pre-commit", "pytest", "wheel"] tests = ["pytest"] [[package]] -name = "astunparse" -version = "1.6.3" -description = "An AST unparser for Python" +name = "asttokens" +version = "2.2.1" +description = "Annotate AST trees with source code positions" category = "main" optional = false python-versions = "*" [package.dependencies] -six = ">=1.6.1,<2.0" -wheel = ">=0.23.0,<1.0" +six = "*" + +[package.extras] +test = ["astroid", "pytest"] [[package]] name = "atomicwrites" @@ -113,17 +113,18 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" -version = "22.1.0" +version = "22.2.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [package.extras] -dev = ["cloudpickle", "coverage[toml] (>=5.0.2)", "furo", "hypothesis", "mypy (>=0.900,!=0.940)", "pre-commit", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "sphinx", "sphinx-notfound-page", "zope-interface"] -docs = ["furo", "sphinx", "sphinx-notfound-page", "zope-interface"] -tests = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "zope-interface"] -tests_no_zope = ["cloudpickle", "coverage[toml] (>=5.0.2)", "hypothesis", "mypy (>=0.900,!=0.940)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] [[package]] name = "babel" @@ -144,17 +145,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "black" version = "20.8b1" @@ -179,7 +169,7 @@ d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] [[package]] name = "bleach" -version = "5.0.1" +version = "6.0.0" description = "An easy safelist-based HTML-sanitizing tool." category = "main" optional = false @@ -191,11 +181,10 @@ webencodings = "*" [package.extras] css = ["tinycss2 (>=1.1.0,<1.2)"] -dev = ["Sphinx (==4.3.2)", "black (==22.3.0)", "build (==0.8.0)", "flake8 (==4.0.1)", "hashin (==0.17.0)", "mypy (==0.961)", "pip-tools (==6.6.2)", "pytest (==7.1.2)", "tox (==3.25.0)", "twine (==4.0.1)", "wheel (==0.37.1)"] [[package]] name = "cachetools" -version = "5.2.0" +version = "5.3.0" description = "Extensible memoizing collections and decorators" category = "main" optional = false @@ -203,7 +192,7 @@ python-versions = "~=3.7" [[package]] name = "certifi" -version = "2022.9.24" +version = "2022.12.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -222,14 +211,11 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "2.1.1" +version = "3.0.1" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = ">=3.6.0" - -[package.extras] -unicode_backport = ["unicodedata2"] +python-versions = "*" [[package]] name = "click" @@ -270,6 +256,20 @@ category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +[[package]] +name = "comm" +version = "0.1.2" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +traitlets = ">=5.3" + +[package.extras] +test = ["pytest"] + [[package]] name = "connexion" version = "2.14.1" @@ -281,7 +281,6 @@ python-versions = ">=3.6" [package.dependencies] clickclick = ">=1.2,<21" flask = ">=1.0.4,<3" -importlib-metadata = {version = ">=1", markers = "python_version < \"3.8\""} inflection = ">=0.3.1,<0.6" itsdangerous = ">=0.24" jsonschema = ">=2.5.1,<5" @@ -300,7 +299,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14 [[package]] name = "coverage" -version = "6.5.0" +version = "7.0.5" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -311,7 +310,7 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "38.0.4" +version = "39.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -321,16 +320,16 @@ python-versions = ">=3.6" cffi = ">=1.12" [package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1)", "sphinx-rtd-theme"] +docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1,!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "flake8", "flake8-import-order", "pep8-naming"] +pep8test = ["black", "ruff"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] [[package]] name = "dateparser" -version = "1.1.4" +version = "1.1.6" description = "Date parsing library designed to parse dates from HTML pages" category = "main" optional = false @@ -349,7 +348,7 @@ langdetect = ["langdetect"] [[package]] name = "debugpy" -version = "1.6.4" +version = "1.6.6" description = "An implementation of the Debug Adapter Protocol for Python" category = "main" optional = false @@ -383,7 +382,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "docutils" @@ -409,6 +408,17 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "executing" +version = "1.2.0" +description = "Get the currently executing AST node of a frame, and other information" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +tests = ["asttokens", "littleutils", "pytest", "rich"] + [[package]] name = "fastjsonschema" version = "2.16.2" @@ -429,7 +439,6 @@ optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" @@ -467,20 +476,20 @@ Six = "*" [[package]] name = "google-api-core" -version = "2.10.2" +version = "2.11.0" description = "Google API client core library" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -google-auth = ">=1.25.0,<3.0dev" +google-auth = ">=2.14.1,<3.0dev" googleapis-common-protos = ">=1.56.2,<2.0dev" protobuf = ">=3.19.5,<3.20.0 || >3.20.0,<3.20.1 || >3.20.1,<4.21.0 || >4.21.0,<4.21.1 || >4.21.1,<4.21.2 || >4.21.2,<4.21.3 || >4.21.3,<4.21.4 || >4.21.4,<4.21.5 || >4.21.5,<5.0.0dev" requests = ">=2.18.0,<3.0.0dev" [package.extras] -grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio-status (>=1.33.2,<2.0dev)"] +grpc = ["grpcio (>=1.33.2,<2.0dev)", "grpcio (>=1.49.1,<2.0dev)", "grpcio-status (>=1.33.2,<2.0dev)", "grpcio-status (>=1.49.1,<2.0dev)"] grpcgcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] @@ -502,7 +511,7 @@ uritemplate = ">=3.0.0,<4dev" [[package]] name = "google-auth" -version = "2.14.1" +version = "2.16.0" description = "Google Authentication Library" category = "main" optional = false @@ -516,9 +525,10 @@ six = ">=1.9.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] -enterprise_cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] +requests = ["requests (>=2.20.0,<3.0.0dev)"] [[package]] name = "google-auth-httplib2" @@ -550,7 +560,7 @@ tool = ["click (>=6.0.0)"] [[package]] name = "googleapis-common-protos" -version = "1.57.0" +version = "1.58.0" description = "Common protobufs used in Google APIs" category = "main" optional = false @@ -577,7 +587,7 @@ test = ["mock (>=3)", "pytest (>=4)", "pytest-cov", "pytest-mock (>=2)"] [[package]] name = "great-expectations" -version = "0.15.34" +version = "0.15.44" description = "Always know what to expect from your data." category = "main" optional = false @@ -593,15 +603,21 @@ Ipython = ">=7.16.3" ipywidgets = ">=7.5.1" jinja2 = ">=2.10" jsonpatch = ">=1.22" -jsonschema = ">=2.5.1,<=4.7.2" +jsonschema = ">=2.5.1" makefun = ">=1.7.0,<2" marshmallow = ">=3.7.1,<4.0.0" mistune = ">=0.8.4" nbformat = ">=5.0" notebook = ">=6.4.10" -numpy = ">=1.18.5" +numpy = [ + {version = ">=1.19.5", markers = "python_version == \"3.8\" or python_version == \"3.9\""}, + {version = ">=1.23.0", markers = "python_version >= \"3.10\""}, +] packaging = "*" -pandas = ">=1.1.0" +pandas = [ + {version = ">=1.1.3", markers = "python_version == \"3.9\""}, + {version = ">=1.4.0", markers = "python_version >= \"3.10\""}, +] pydantic = ">=1.0,<2.0" pyparsing = ">=2.4" python-dateutil = ">=2.8.1" @@ -617,14 +633,14 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] arrow = ["feather-format (>=0.4.1)", "pyarrow"] athena = ["pyathena (>=1.11)", "sqlalchemy (>=1.3.18,<2.0.0)"] -aws_secrets = ["boto3 (==1.17.106)"] +aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] -azure_secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] -bigquery = ["gcsfs (>=0.5.1)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydantic (>=1.0,<2.0)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] +bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] -gcp = ["gcsfs (>=0.5.1)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] +gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] hive = ["PyHive (>=0.6.5)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)"] mssql = ["pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)"] mysql = ["PyMySQL (>=0.9.3,<0.10)", "sqlalchemy (>=1.3.18,<2.0.0)"] @@ -636,7 +652,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=1.7.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.6.0)", "pydantic (>=1.0,<2.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.6.0)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -669,20 +685,19 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "5.1.0" +version = "6.0.0" description = "Read metadata from Python packages" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl-flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "inflection" @@ -694,22 +709,23 @@ python-versions = ">=3.5" [[package]] name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.16.2" +version = "6.20.2" description = "IPython Kernel for Jupyter" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" debugpy = ">=1.0" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" @@ -719,19 +735,22 @@ packaging = "*" psutil = "*" pyzmq = ">=17" tornado = ">=6.1" -traitlets = ">=5.1.0" +traitlets = ">=5.4.0" [package.extras] -docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt"] -test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-cov", "pytest-timeout"] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov", "pytest-timeout"] [[package]] name = "ipython" -version = "7.34.0" +version = "8.8.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -742,21 +761,23 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" -pygments = "*" -setuptools = ">=18.5" -traitlets = ">=4.2" +prompt-toolkit = ">=3.0.11,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" [package.extras] -all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] -doc = ["Sphinx (>=1.3)"] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.20)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] -test = ["ipykernel", "nbformat", "nose (>=0.10.1)", "numpy (>=1.17)", "pygments", "requests", "testpath"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.20)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] [[package]] name = "ipython-genutils" @@ -768,7 +789,7 @@ python-versions = "*" [[package]] name = "ipywidgets" -version = "8.0.2" +version = "8.0.4" description = "Jupyter interactive widgets" category = "main" optional = false @@ -829,7 +850,7 @@ python-versions = ">=3.7" [package.extras] test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async-generator", "trio"] +trio = ["async_generator", "trio"] [[package]] name = "jinja2" @@ -874,18 +895,17 @@ python-versions = "*" [package.dependencies] attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} pyrsistent = ">=0.14.0" setuptools = "*" six = ">=1.11.0" [package.extras] format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format_nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] [[package]] name = "jupyter-client" -version = "7.4.7" +version = "7.4.9" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -906,17 +926,19 @@ test = ["codecov", "coverage", "ipykernel (>=6.12)", "ipython", "mypy", "pre-com [[package]] name = "jupyter-core" -version = "4.12.0" +version = "5.1.5" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] +platformdirs = ">=2.5" pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = "*" +traitlets = ">=5.3" [package.extras] +docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] [[package]] @@ -950,7 +972,7 @@ test = ["coverage", "ipykernel", "pytest (>=6.0)", "pytest-console-scripts", "py [[package]] name = "jupyterlab-widgets" -version = "3.0.3" +version = "3.0.5" description = "Jupyter interactive widgets for JupyterLab" category = "main" optional = false @@ -987,7 +1009,7 @@ six = "*" [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["backports-unittest-mock", "collective-checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] +testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] [[package]] name = "makefun" @@ -1119,7 +1141,7 @@ test = ["ipykernel", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "pytest", "py [[package]] name = "nbformat" -version = "5.7.0" +version = "5.7.3" description = "The Jupyter Notebook format" category = "main" optional = false @@ -1127,13 +1149,13 @@ python-versions = ">=3.7" [package.dependencies] fastjsonschema = "*" -importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.8\""} jsonschema = ">=2.6" jupyter-core = "*" traitlets = ">=5.1" [package.extras] -test = ["check-manifest", "pep440", "pre-commit", "pytest", "testpath"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] [[package]] name = "nest-asyncio" @@ -1145,18 +1167,18 @@ python-versions = ">=3.5" [[package]] name = "networkx" -version = "2.6.3" +version = "2.8.8" description = "Python package for creating and manipulating graphs and networks" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.extras] -default = ["matplotlib (>=3.3)", "numpy (>=1.19)", "pandas (>=1.1)", "scipy (>=1.5,!=1.6.1)"] -developer = ["black (==21.5b1)", "pre-commit (>=2.12)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.1)", "pillow (>=8.2)", "pydata-sphinx-theme (>=0.6,<1.0)", "sphinx (>=4.0,<5.0)", "sphinx-gallery (>=0.9,<1.0)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.5)", "pydot (>=1.4.1)", "pygraphviz (>=1.7)"] -test = ["codecov (>=2.1)", "pytest (>=6.2)", "pytest-cov (>=2.12)"] +default = ["matplotlib (>=3.4)", "numpy (>=1.19)", "pandas (>=1.3)", "scipy (>=1.8)"] +developer = ["mypy (>=0.982)", "pre-commit (>=2.20)"] +doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.2)", "pydata-sphinx-theme (>=0.11)", "sphinx (>=5.2)", "sphinx-gallery (>=0.11)", "texext (>=0.6.6)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.9)", "sympy (>=1.10)"] +test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "notebook" @@ -1205,11 +1227,11 @@ test = ["pytest", "pytest-console-scripts", "pytest-tornasync"] [[package]] name = "numpy" -version = "1.21.6" -description = "NumPy is the fundamental package for array computing with Python." +version = "1.24.1" +description = "Fundamental package for array computing in Python" category = "main" optional = false -python-versions = ">=3.7,<3.11" +python-versions = ">=3.8" [[package]] name = "oauth2client" @@ -1252,35 +1274,30 @@ et-xmlfile = "*" [[package]] name = "packaging" -version = "21.3" +version = "23.0" description = "Core utilities for Python packages" category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" +python-versions = ">=3.7" [[package]] name = "pandas" -version = "1.3.5" +version = "1.5.3" description = "Powerful data structures for data analysis, time series, and statistics" category = "main" optional = false -python-versions = ">=3.7.1" +python-versions = ">=3.8" [package.dependencies] numpy = [ - {version = ">=1.17.3", markers = "platform_machine != \"aarch64\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, - {version = ">=1.19.2", markers = "platform_machine == \"aarch64\" and python_version < \"3.10\""}, - {version = ">=1.20.0", markers = "platform_machine == \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.20.3", markers = "python_version < \"3.10\""}, {version = ">=1.21.0", markers = "python_version >= \"3.10\""}, ] -python-dateutil = ">=2.7.3" -pytz = ">=2017.3" +python-dateutil = ">=2.8.1" +pytz = ">=2020.1" [package.extras] -test = ["hypothesis (>=3.58)", "pytest (>=6.0)", "pytest-xdist"] +test = ["hypothesis (>=5.5.3)", "pytest (>=6.0)", "pytest-xdist (>=1.31)"] [[package]] name = "pandocfilters" @@ -1304,7 +1321,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.10.2" +version = "0.10.3" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false @@ -1312,20 +1329,19 @@ python-versions = ">=3.7" [[package]] name = "pdoc" -version = "12.3.0" +version = "12.3.1" description = "API Documentation for Python Projects" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -astunparse = {version = "*", markers = "python_version < \"3.9\""} Jinja2 = ">=2.11.0" MarkupSafe = "*" pygments = ">=2.12.0" [package.extras] -dev = ["autoflake", "black", "flake8", "hypothesis", "mypy", "pytest", "pytest-cov", "pytest-timeout", "pyupgrade", "reorder-python-imports", "tox", "yesqa"] +dev = ["black", "hypothesis", "mypy", "pytest", "pytest-cov", "pytest-timeout", "ruff", "tox", "types-pygments"] [[package]] name = "pexpect" @@ -1346,6 +1362,18 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "platformdirs" +version = "2.6.2" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] + [[package]] name = "pluggy" version = "1.0.0" @@ -1354,16 +1382,13 @@ category = "dev" optional = false python-versions = ">=3.6" -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] [[package]] name = "prometheus-client" -version = "0.15.0" +version = "0.16.0" description = "Python client for the Prometheus monitoring system." category = "main" optional = false @@ -1374,7 +1399,7 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.33" +version = "3.0.36" description = "Library for building powerful interactive command lines in Python" category = "main" optional = false @@ -1385,7 +1410,7 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.21.9" +version = "4.21.12" description = "" category = "main" optional = false @@ -1410,11 +1435,22 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +category = "main" +optional = false +python-versions = "*" + +[package.extras] +tests = ["pytest"] + [[package]] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "main" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -1455,14 +1491,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.10.2" +version = "1.10.4" description = "Data validation and settings management using python type hints" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -typing-extensions = ">=4.1.0" +typing-extensions = ">=4.2.0" [package.extras] dotenv = ["python-dotenv (>=0.10.4)"] @@ -1478,7 +1514,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" -version = "2.13.0" +version = "2.14.0" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false @@ -1515,7 +1551,7 @@ diagrams = ["jinja2", "railroad-diagrams"] [[package]] name = "pyrsistent" -version = "0.19.2" +version = "0.19.3" description = "Persistent/Functional/Immutable data structures" category = "main" optional = false @@ -1533,7 +1569,6 @@ python-versions = ">=3.6" atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -1597,7 +1632,7 @@ cli = ["click (>=5.0)"] [[package]] name = "pytz" -version = "2022.6" +version = "2022.7.1" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -1612,7 +1647,6 @@ optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" [package.dependencies] -"backports.zoneinfo" = {version = "*", markers = "python_version >= \"3.6\" and python_version < \"3.9\""} tzdata = {version = "*", markers = "python_version >= \"3.6\""} [[package]] @@ -1633,7 +1667,7 @@ python-versions = "*" [[package]] name = "pywinpty" -version = "2.0.9" +version = "2.0.10" description = "Pseudo terminal support for Windows from Python." category = "main" optional = false @@ -1649,7 +1683,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "pyzmq" -version = "24.0.1" +version = "25.0.0" description = "Python bindings for 0MQ" category = "main" optional = false @@ -1657,7 +1691,6 @@ python-versions = ">=3.6" [package.dependencies] cffi = {version = "*", markers = "implementation_name == \"pypy\""} -py = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "rdflib" @@ -1688,7 +1721,7 @@ python-versions = ">=3.6" [[package]] name = "requests" -version = "2.28.1" +version = "2.28.2" description = "Python HTTP for Humans." category = "main" optional = false @@ -1696,13 +1729,13 @@ python-versions = ">=3.7, <4" [package.dependencies] certifi = ">=2017.4.17" -charset-normalizer = ">=2,<3" +charset-normalizer = ">=2,<4" idna = ">=2.5,<4" urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-oauthlib" @@ -1755,14 +1788,19 @@ python-versions = ">=3.5" [[package]] name = "scipy" -version = "1.7.3" -description = "SciPy: Scientific Library for Python" +version = "1.10.0" +description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false -python-versions = ">=3.7,<3.11" +python-versions = "<3.12,>=3.8" [package.dependencies] -numpy = ">=1.16.5,<1.23.0" +numpy = ">=1.19.5,<1.27.0" + +[package.extras] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] +doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] +test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] [[package]] name = "secretstorage" @@ -1785,8 +1823,8 @@ optional = false python-versions = "*" [package.extras] -nativelib = ["pyobjc-framework-cocoa", "pywin32"] -objc = ["pyobjc-framework-cocoa"] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] [[package]] @@ -1801,7 +1839,7 @@ python-versions = ">=3.6" certs = ["certifi (==2016.9.26)"] docs = ["jaraco.packaging (>=8.2)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx"] ssl = ["wincertstore (==0.2)"] -testing = ["flake8-2020", "jaraco-envs", "mock", "paver", "pip (>=19.1)", "pytest (>=3.5,!=3.7.3)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "virtualenv (>=13.0.0)", "wheel"] +testing = ["flake8-2020", "jaraco.envs", "mock", "paver", "pip (>=19.1)", "pytest (>=3.5,!=3.7.3)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -1874,11 +1912,11 @@ sphinx = ">=2.0" [[package]] name = "sphinxcontrib-applehelp" -version = "1.0.2" -description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" +version = "1.0.4" +description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.8" [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] @@ -1943,6 +1981,22 @@ python-versions = ">=3.5" lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "stack-data" +version = "0.6.2" +description = "Extract data from python stack frames and tracebacks for informative displays" +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + [[package]] name = "swagger-ui-bundle" version = "0.0.9" @@ -1988,7 +2042,7 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"] [[package]] name = "terminado" -version = "0.17.0" +version = "0.17.1" description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." category = "main" optional = false @@ -2000,7 +2054,7 @@ pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} tornado = ">=6.1.0" [package.extras] -docs = ["pydata-sphinx-theme", "sphinx"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] [[package]] @@ -2057,7 +2111,7 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.6.0" +version = "5.8.1" description = "Traitlets Python configuration system" category = "main" optional = false @@ -2065,7 +2119,7 @@ python-versions = ">=3.7" [package.extras] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] -test = ["pre-commit", "pytest"] +test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typed-ast" @@ -2085,7 +2139,7 @@ python-versions = ">=3.7" [[package]] name = "tzdata" -version = "2022.6" +version = "2022.7" description = "Provider of IANA time zone data" category = "main" optional = false @@ -2100,12 +2154,11 @@ optional = false python-versions = ">=3.6" [package.dependencies] -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -devenv = ["black", "pyroma", "pytest-cov", "zest-releaser"] +devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] [[package]] @@ -2118,7 +2171,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "urllib3" -version = "1.26.13" +version = "1.26.14" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -2131,7 +2184,7 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] name = "wcwidth" -version = "0.2.5" +version = "0.2.6" description = "Measures the displayed width of unicode strings in a terminal" category = "main" optional = false @@ -2170,20 +2223,9 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" dev = ["coverage", "pallets-sphinx-themes", "pytest", "pytest-timeout", "sphinx", "sphinx-issues", "tox"] watchdog = ["watchdog"] -[[package]] -name = "wheel" -version = "0.38.4" -description = "A built-package format for Python" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -test = ["pytest (>=3.0.0)"] - [[package]] name = "widgetsnbextension" -version = "4.0.3" +version = "4.0.5" description = "Jupyter interactive widgets for Jupyter Notebook" category = "main" optional = false @@ -2207,17 +2249,17 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] -testing = ["flake8 (<5)", "func-timeout", "jaraco-functools", "jaraco-itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" -python-versions = ">=3.7.1,<3.11" -content-hash = "3292d40bff445ff16b9c13585b4b3dbd47d6328807367ac8efdeccdb96da349c" +python-versions = ">=3.9.0,<3.11" +content-hash = "07e5b9f29e35366d3bb1402137bf8b98a7e0a5a1fdcf26856a0b1c675535b876" [metadata.files] alabaster = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, + {file = "alabaster-0.7.13-py3-none-any.whl", hash = "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3"}, + {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] altair = [ {file = "altair-4.2.0-py3-none-any.whl", hash = "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a"}, @@ -2262,16 +2304,16 @@ argon2-cffi-bindings = [ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, ] -astunparse = [ - {file = "astunparse-1.6.3-py2.py3-none-any.whl", hash = "sha256:c2652417f2c8b5bb325c885ae329bdf3f86424075c4fd1a128674bc6fba4b8e8"}, - {file = "astunparse-1.6.3.tar.gz", hash = "sha256:5ad93a8456f0d084c3456d059fd9a92cce667963232cbf763eac3bc5b7940872"}, +asttokens = [ + {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, + {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, ] atomicwrites = [ {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, ] attrs = [ - {file = "attrs-22.1.0-py2.py3-none-any.whl", hash = "sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c"}, - {file = "attrs-22.1.0.tar.gz", hash = "sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6"}, + {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, + {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, ] babel = [ {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, @@ -2281,38 +2323,20 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] -backports-zoneinfo = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] bleach = [ - {file = "bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, - {file = "bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, + {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, + {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, ] cachetools = [ - {file = "cachetools-5.2.0-py3-none-any.whl", hash = "sha256:f9f17d2aec496a9aa6b76f53e3b614c965223c061982d434d160f930c698a9db"}, - {file = "cachetools-5.2.0.tar.gz", hash = "sha256:6a94c6402995a99c3970cc7e4884bb60b4a8639938157eeed436098bf9831757"}, + {file = "cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"}, + {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, ] certifi = [ - {file = "certifi-2022.9.24-py3-none-any.whl", hash = "sha256:90c1a32f1d68f940488354e36370f6cca89f0f106db09518524c88d6ed83f382"}, - {file = "certifi-2022.9.24.tar.gz", hash = "sha256:0d9c601124e5a6ba9712dbc60d9c53c21e34f5f641fe83002317394311bdce14"}, + {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, + {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, ] cffi = [ {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, @@ -2381,8 +2405,94 @@ cffi = [ {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, ] charset-normalizer = [ - {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, - {file = "charset_normalizer-2.1.1-py3-none-any.whl", hash = "sha256:83e9a75d1911279afd89352c68b45348559d1fc0506b054b346651b5e7fee29f"}, + {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"}, + {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"}, + {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"}, + {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"}, + {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"}, + {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"}, + {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"}, + {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, ] click = [ {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, @@ -2400,113 +2510,115 @@ colorama = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] +comm = [ + {file = "comm-0.1.2-py3-none-any.whl", hash = "sha256:9f3abf3515112fa7c55a42a6a5ab358735c9dccc8b5910a9d8e3ef5998130666"}, + {file = "comm-0.1.2.tar.gz", hash = "sha256:3e2f5826578e683999b93716285b3b1f344f157bf75fa9ce0a797564e742f062"}, +] connexion = [ {file = "connexion-2.14.1-py2.py3-none-any.whl", hash = "sha256:f343717241b4c4802a694c38fee66fb1693c897fe4ea5a957fa9b3b07caf6394"}, {file = "connexion-2.14.1.tar.gz", hash = "sha256:99aa5781e70a7b94f8ffae8cf89f309d49cdb811bbd65a8e2f2546f3b19a01e6"}, ] coverage = [ - {file = "coverage-6.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ef8674b0ee8cc11e2d574e3e2998aea5df5ab242e012286824ea3c6970580e53"}, - {file = "coverage-6.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:784f53ebc9f3fd0e2a3f6a78b2be1bd1f5575d7863e10c6e12504f240fd06660"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4a5be1748d538a710f87542f22c2cad22f80545a847ad91ce45e77417293eb4"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:83516205e254a0cb77d2d7bb3632ee019d93d9f4005de31dca0a8c3667d5bc04"}, - {file = "coverage-6.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af4fffaffc4067232253715065e30c5a7ec6faac36f8fc8d6f64263b15f74db0"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:97117225cdd992a9c2a5515db1f66b59db634f59d0679ca1fa3fe8da32749cae"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a1170fa54185845505fbfa672f1c1ab175446c887cce8212c44149581cf2d466"}, - {file = "coverage-6.5.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:11b990d520ea75e7ee8dcab5bc908072aaada194a794db9f6d7d5cfd19661e5a"}, - {file = "coverage-6.5.0-cp310-cp310-win32.whl", hash = "sha256:5dbec3b9095749390c09ab7c89d314727f18800060d8d24e87f01fb9cfb40b32"}, - {file = "coverage-6.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:59f53f1dc5b656cafb1badd0feb428c1e7bc19b867479ff72f7a9dd9b479f10e"}, - {file = "coverage-6.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4a5375e28c5191ac38cca59b38edd33ef4cc914732c916f2929029b4bfb50795"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ed2820d919351f4167e52425e096af41bfabacb1857186c1ea32ff9983ed75"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:33a7da4376d5977fbf0a8ed91c4dffaaa8dbf0ddbf4c8eea500a2486d8bc4d7b"}, - {file = "coverage-6.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8fb6cf131ac4070c9c5a3e21de0f7dc5a0fbe8bc77c9456ced896c12fcdad91"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a6b7d95969b8845250586f269e81e5dfdd8ff828ddeb8567a4a2eaa7313460c4"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1ef221513e6f68b69ee9e159506d583d31aa3567e0ae84eaad9d6ec1107dddaa"}, - {file = "coverage-6.5.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cca4435eebea7962a52bdb216dec27215d0df64cf27fc1dd538415f5d2b9da6b"}, - {file = "coverage-6.5.0-cp311-cp311-win32.whl", hash = "sha256:98e8a10b7a314f454d9eff4216a9a94d143a7ee65018dd12442e898ee2310578"}, - {file = "coverage-6.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:bc8ef5e043a2af066fa8cbfc6e708d58017024dc4345a1f9757b329a249f041b"}, - {file = "coverage-6.5.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4433b90fae13f86fafff0b326453dd42fc9a639a0d9e4eec4d366436d1a41b6d"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4f05d88d9a80ad3cac6244d36dd89a3c00abc16371769f1340101d3cb899fc3"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94e2565443291bd778421856bc975d351738963071e9b8839ca1fc08b42d4bef"}, - {file = "coverage-6.5.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:027018943386e7b942fa832372ebc120155fd970837489896099f5cfa2890f79"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:255758a1e3b61db372ec2736c8e2a1fdfaf563977eedbdf131de003ca5779b7d"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:851cf4ff24062c6aec510a454b2584f6e998cada52d4cb58c5e233d07172e50c"}, - {file = "coverage-6.5.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:12adf310e4aafddc58afdb04d686795f33f4d7a6fa67a7a9d4ce7d6ae24d949f"}, - {file = "coverage-6.5.0-cp37-cp37m-win32.whl", hash = "sha256:b5604380f3415ba69de87a289a2b56687faa4fe04dbee0754bfcae433489316b"}, - {file = "coverage-6.5.0-cp37-cp37m-win_amd64.whl", hash = "sha256:4a8dbc1f0fbb2ae3de73eb0bdbb914180c7abfbf258e90b311dcd4f585d44bd2"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d900bb429fdfd7f511f868cedd03a6bbb142f3f9118c09b99ef8dc9bf9643c3c"}, - {file = "coverage-6.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2198ea6fc548de52adc826f62cb18554caedfb1d26548c1b7c88d8f7faa8f6ba"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c4459b3de97b75e3bd6b7d4b7f0db13f17f504f3d13e2a7c623786289dd670e"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:20c8ac5386253717e5ccc827caad43ed66fea0efe255727b1053a8154d952398"}, - {file = "coverage-6.5.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b07130585d54fe8dff3d97b93b0e20290de974dc8177c320aeaf23459219c0b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:dbdb91cd8c048c2b09eb17713b0c12a54fbd587d79adcebad543bc0cd9a3410b"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:de3001a203182842a4630e7b8d1a2c7c07ec1b45d3084a83d5d227a3806f530f"}, - {file = "coverage-6.5.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:e07f4a4a9b41583d6eabec04f8b68076ab3cd44c20bd29332c6572dda36f372e"}, - {file = "coverage-6.5.0-cp38-cp38-win32.whl", hash = "sha256:6d4817234349a80dbf03640cec6109cd90cba068330703fa65ddf56b60223a6d"}, - {file = "coverage-6.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:7ccf362abd726b0410bf8911c31fbf97f09f8f1061f8c1cf03dfc4b6372848f6"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:633713d70ad6bfc49b34ead4060531658dc6dfc9b3eb7d8a716d5873377ab745"}, - {file = "coverage-6.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:95203854f974e07af96358c0b261f1048d8e1083f2de9b1c565e1be4a3a48cfc"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9023e237f4c02ff739581ef35969c3739445fb059b060ca51771e69101efffe"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:265de0fa6778d07de30bcf4d9dc471c3dc4314a23a3c6603d356a3c9abc2dfcf"}, - {file = "coverage-6.5.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f830ed581b45b82451a40faabb89c84e1a998124ee4212d440e9c6cf70083e5"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7b6be138d61e458e18d8e6ddcddd36dd96215edfe5f1168de0b1b32635839b62"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42eafe6778551cf006a7c43153af1211c3aaab658d4d66fa5fcc021613d02518"}, - {file = "coverage-6.5.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:723e8130d4ecc8f56e9a611e73b31219595baa3bb252d539206f7bbbab6ffc1f"}, - {file = "coverage-6.5.0-cp39-cp39-win32.whl", hash = "sha256:d9ecf0829c6a62b9b573c7bb6d4dcd6ba8b6f80be9ba4fc7ed50bf4ac9aecd72"}, - {file = "coverage-6.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc2af30ed0d5ae0b1abdb4ebdce598eafd5b35397d4d75deb341a614d333d987"}, - {file = "coverage-6.5.0-pp36.pp37.pp38-none-any.whl", hash = "sha256:1431986dac3923c5945271f169f59c45b8802a114c8f548d611f2015133df77a"}, - {file = "coverage-6.5.0.tar.gz", hash = "sha256:f642e90754ee3e06b0e7e51bce3379590e76b7f76b708e1a71ff043f87025c84"}, + {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, + {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, + {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, + {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, + {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, + {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, + {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, + {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, + {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, + {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, + {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, + {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, + {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, + {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, + {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, + {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, + {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, + {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, + {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, + {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, + {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, + {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, + {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, + {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, + {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, + {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, + {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, + {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, + {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, + {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, + {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, ] cryptography = [ - {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:2fa36a7b2cc0998a3a4d5af26ccb6273f3df133d61da2ba13b3286261e7efb70"}, - {file = "cryptography-38.0.4-cp36-abi3-macosx_10_10_x86_64.whl", hash = "sha256:1f13ddda26a04c06eb57119caf27a524ccae20533729f4b1e4a69b54e07035eb"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:2ec2a8714dd005949d4019195d72abed84198d877112abb5a27740e217e0ea8d"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50a1494ed0c3f5b4d07650a68cd6ca62efe8b596ce743a5c94403e6f11bf06c1"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a10498349d4c8eab7357a8f9aa3463791292845b79597ad1b98a543686fb1ec8"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:10652dd7282de17990b88679cb82f832752c4e8237f0c714be518044269415db"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bfe6472507986613dc6cc00b3d492b2f7564b02b3b3682d25ca7f40fa3fd321b"}, - {file = "cryptography-38.0.4-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ce127dd0a6a0811c251a6cddd014d292728484e530d80e872ad9806cfb1c5b3c"}, - {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:53049f3379ef05182864d13bb9686657659407148f901f3f1eee57a733fb4b00"}, - {file = "cryptography-38.0.4-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:8a4b2bdb68a447fadebfd7d24855758fe2d6fecc7fed0b78d190b1af39a8e3b0"}, - {file = "cryptography-38.0.4-cp36-abi3-win32.whl", hash = "sha256:1d7e632804a248103b60b16fb145e8df0bc60eed790ece0d12efe8cd3f3e7744"}, - {file = "cryptography-38.0.4-cp36-abi3-win_amd64.whl", hash = "sha256:8e45653fb97eb2f20b8c96f9cd2b3a0654d742b47d638cf2897afbd97f80fa6d"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca57eb3ddaccd1112c18fc80abe41db443cc2e9dcb1917078e02dfa010a4f353"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:c9e0d79ee4c56d841bd4ac6e7697c8ff3c8d6da67379057f29e66acffcd1e9a7"}, - {file = "cryptography-38.0.4-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:0e70da4bdff7601b0ef48e6348339e490ebfb0cbe638e083c9c41fb49f00c8bd"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-macosx_10_10_x86_64.whl", hash = "sha256:998cd19189d8a747b226d24c0207fdaa1e6658a1d3f2494541cb9dfbf7dcb6d2"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67461b5ebca2e4c2ab991733f8ab637a7265bb582f07c7c88914b5afb88cb95b"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4eb85075437f0b1fd8cd66c688469a0c4119e0ba855e3fef86691971b887caf6"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:3178d46f363d4549b9a76264f41c6948752183b3f587666aff0555ac50fd7876"}, - {file = "cryptography-38.0.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:6391e59ebe7c62d9902c24a4d8bcbc79a68e7c4ab65863536127c8a9cd94043b"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-macosx_10_10_x86_64.whl", hash = "sha256:78e47e28ddc4ace41dd38c42e6feecfdadf9c3be2af389abbfeef1ff06822285"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fb481682873035600b5502f0015b664abc26466153fab5c6bc92c1ea69d478b"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:4367da5705922cf7070462e964f66e4ac24162e22ab0a2e9d31f1b270dd78083"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b4cad0cea995af760f82820ab4ca54e5471fc782f70a007f31531957f43e9dee"}, - {file = "cryptography-38.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:80ca53981ceeb3241998443c4964a387771588c4e4a5d92735a493af868294f9"}, - {file = "cryptography-38.0.4.tar.gz", hash = "sha256:175c1a818b87c9ac80bb7377f5520b7f31b3ef2a0004e2420319beadedb67290"}, + {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, + {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96"}, + {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717"}, + {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df"}, + {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1"}, + {file = "cryptography-39.0.0-cp36-abi3-win32.whl", hash = "sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de"}, + {file = "cryptography-39.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e"}, + {file = "cryptography-39.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb"}, + {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f"}, + {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458"}, + {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190"}, + {file = "cryptography-39.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773"}, + {file = "cryptography-39.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856"}, + {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f"}, + {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce"}, + {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8"}, + {file = "cryptography-39.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39"}, + {file = "cryptography-39.0.0.tar.gz", hash = "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf"}, ] dateparser = [ - {file = "dateparser-1.1.4-py2.py3-none-any.whl", hash = "sha256:4431159799b63d8acec5d7d844c5e06edf3d1b0eb2bda6d4cac87134ddddd01c"}, - {file = "dateparser-1.1.4.tar.gz", hash = "sha256:73ec6e44a133c54076ecf9f9dc0fbe3dd4831f154f977ff06f53114d57c5425e"}, + {file = "dateparser-1.1.6-py2.py3-none-any.whl", hash = "sha256:c47b6e4b8c4b2b2a21690111b6571b6991295ba327ec6503753abeebf5e80696"}, + {file = "dateparser-1.1.6.tar.gz", hash = "sha256:e703db1815270c020552f4b3e3a981937b48b2cbcfcef5347071b74788dd9214"}, ] debugpy = [ - {file = "debugpy-1.6.4-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:6ae238943482c78867ac707c09122688efb700372b617ffd364261e5e41f7a2f"}, - {file = "debugpy-1.6.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2a39e7da178e1f22f4bc04b57f085e785ed1bcf424aaf318835a1a7129eefe35"}, - {file = "debugpy-1.6.4-cp310-cp310-win32.whl", hash = "sha256:143f79d0798a9acea21cd1d111badb789f19d414aec95fa6389cfea9485ddfb1"}, - {file = "debugpy-1.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:563f148f94434365ec0ce94739c749aabf60bf67339e68a9446499f3582d62f3"}, - {file = "debugpy-1.6.4-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1caee68f7e254267df908576c0d0938f8f88af16383f172cb9f0602e24c30c01"}, - {file = "debugpy-1.6.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e2a83d31a16b83666f19fa06d97b2cc311af88e6266590579737949971a17e"}, - {file = "debugpy-1.6.4-cp37-cp37m-win32.whl", hash = "sha256:82229790442856962aec4767b98ba2559fe0998f897e9f21fb10b4fd24b6c436"}, - {file = "debugpy-1.6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:67edf033f9e512958f7b472975ff9d9b7ff64bf4440f6f6ae44afdc66b89e6b6"}, - {file = "debugpy-1.6.4-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:4ab5e938925e5d973f567d6ef32751b17d10f3be3a8c4d73c52f53e727f69bf1"}, - {file = "debugpy-1.6.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8df268e9f72fc06efc2e75e8dc8e2b881d6a397356faec26efb2ee70b6863b7"}, - {file = "debugpy-1.6.4-cp38-cp38-win32.whl", hash = "sha256:86bd25f38f8b6c5d430a5e2931eebbd5f580c640f4819fcd236d0498790c7204"}, - {file = "debugpy-1.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:62ba4179b372a62abf9c89b56997d70a4100c6dea6c2a4e0e4be5f45920b3253"}, - {file = "debugpy-1.6.4-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:d2968e589bda4e485a9c61f113754a28e48d88c5152ed8e0b2564a1fadbe50a5"}, - {file = "debugpy-1.6.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e62b8034ede98932b92268669318848a0d42133d857087a3b9cec03bb844c615"}, - {file = "debugpy-1.6.4-cp39-cp39-win32.whl", hash = "sha256:3d9c31baf64bf959a593996c108e911c5a9aa1693a296840e5469473f064bcec"}, - {file = "debugpy-1.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:ea4bf208054e6d41749f17612066da861dff10102729d32c85b47f155223cf2b"}, - {file = "debugpy-1.6.4-py2.py3-none-any.whl", hash = "sha256:e886a1296cd20a10172e94788009ce74b759e54229ebd64a43fa5c2b4e62cd76"}, - {file = "debugpy-1.6.4.zip", hash = "sha256:d5ab9bd3f4e7faf3765fd52c7c43c074104ab1e109621dc73219099ed1a5399d"}, + {file = "debugpy-1.6.6-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:0ea1011e94416e90fb3598cc3ef5e08b0a4dd6ce6b9b33ccd436c1dffc8cd664"}, + {file = "debugpy-1.6.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dff595686178b0e75580c24d316aa45a8f4d56e2418063865c114eef651a982e"}, + {file = "debugpy-1.6.6-cp310-cp310-win32.whl", hash = "sha256:87755e173fcf2ec45f584bb9d61aa7686bb665d861b81faa366d59808bbd3494"}, + {file = "debugpy-1.6.6-cp310-cp310-win_amd64.whl", hash = "sha256:72687b62a54d9d9e3fb85e7a37ea67f0e803aaa31be700e61d2f3742a5683917"}, + {file = "debugpy-1.6.6-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:78739f77c58048ec006e2b3eb2e0cd5a06d5f48c915e2fc7911a337354508110"}, + {file = "debugpy-1.6.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23c29e40e39ad7d869d408ded414f6d46d82f8a93b5857ac3ac1e915893139ca"}, + {file = "debugpy-1.6.6-cp37-cp37m-win32.whl", hash = "sha256:7aa7e103610e5867d19a7d069e02e72eb2b3045b124d051cfd1538f1d8832d1b"}, + {file = "debugpy-1.6.6-cp37-cp37m-win_amd64.whl", hash = "sha256:f6383c29e796203a0bba74a250615ad262c4279d398e89d895a69d3069498305"}, + {file = "debugpy-1.6.6-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:23363e6d2a04d726bbc1400bd4e9898d54419b36b2cdf7020e3e215e1dcd0f8e"}, + {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, + {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, + {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, + {file = "debugpy-1.6.6-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:11a0f3a106f69901e4a9a5683ce943a7a5605696024134b522aa1bfda25b5fec"}, + {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, + {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, + {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, + {file = "debugpy-1.6.6-py2.py3-none-any.whl", hash = "sha256:be596b44448aac14eb3614248c91586e2bc1728e020e82ef3197189aae556115"}, + {file = "debugpy-1.6.6.zip", hash = "sha256:b9c2130e1c632540fbf9c2c88341493797ddf58016e7cba02e311de9b0a96b67"}, ] decorator = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, @@ -2532,6 +2644,10 @@ et-xmlfile = [ {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] +executing = [ + {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, + {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, +] fastjsonschema = [ {file = "fastjsonschema-2.16.2-py3-none-any.whl", hash = "sha256:21f918e8d9a1a4ba9c22e09574ba72267a6762d47822db9add95f6454e51cc1c"}, {file = "fastjsonschema-2.16.2.tar.gz", hash = "sha256:01e366f25d9047816fe3d288cbfc3e10541daf0af2044763f3d0ade42476da18"}, @@ -2549,16 +2665,16 @@ flask-cors = [ {file = "Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"}, ] google-api-core = [ - {file = "google-api-core-2.10.2.tar.gz", hash = "sha256:10c06f7739fe57781f87523375e8e1a3a4674bf6392cd6131a3222182b971320"}, - {file = "google_api_core-2.10.2-py3-none-any.whl", hash = "sha256:34f24bd1d5f72a8c4519773d99ca6bf080a6c4e041b4e9f024fe230191dda62e"}, + {file = "google-api-core-2.11.0.tar.gz", hash = "sha256:4b9bb5d5a380a0befa0573b302651b8a9a89262c1730e37bf423cec511804c22"}, + {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ {file = "google-api-python-client-1.12.11.tar.gz", hash = "sha256:1b4bd42a46321e13c0542a9e4d96fa05d73626f07b39f83a73a947d70ca706a9"}, {file = "google_api_python_client-1.12.11-py2.py3-none-any.whl", hash = "sha256:7e0a1a265c8d3088ee1987778c72683fcb376e32bada8d7767162bd9c503fd9b"}, ] google-auth = [ - {file = "google-auth-2.14.1.tar.gz", hash = "sha256:ccaa901f31ad5cbb562615eb8b664b3dd0bf5404a67618e642307f00613eda4d"}, - {file = "google_auth-2.14.1-py2.py3-none-any.whl", hash = "sha256:f5d8701633bebc12e0deea4df8abd8aff31c28b355360597f7f2ee60f2e4d016"}, + {file = "google-auth-2.16.0.tar.gz", hash = "sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd"}, + {file = "google_auth-2.16.0-py2.py3-none-any.whl", hash = "sha256:5045648c821fb72384cdc0e82cc326df195f113a33049d9b62b74589243d2acc"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.0.4.tar.gz", hash = "sha256:8d092cc60fb16517b12057ec0bba9185a96e3b7169d86ae12eae98e645b7bc39"}, @@ -2569,16 +2685,16 @@ google-auth-oauthlib = [ {file = "google_auth_oauthlib-0.4.6-py2.py3-none-any.whl", hash = "sha256:3f2a6e802eebbb6fb736a370fbf3b055edcb6b52878bf2f26330b5e041316c73"}, ] googleapis-common-protos = [ - {file = "googleapis-common-protos-1.57.0.tar.gz", hash = "sha256:27a849d6205838fb6cc3c1c21cb9800707a661bb21c6ce7fb13e99eb1f8a0c46"}, - {file = "googleapis_common_protos-1.57.0-py2.py3-none-any.whl", hash = "sha256:a9f4a1d7f6d9809657b7f1316a1aa527f6664891531bcfcc13b6696e685f443c"}, + {file = "googleapis-common-protos-1.58.0.tar.gz", hash = "sha256:c727251ec025947d545184ba17e3578840fc3a24a0516a020479edab660457df"}, + {file = "googleapis_common_protos-1.58.0-py2.py3-none-any.whl", hash = "sha256:ca3befcd4580dab6ad49356b46bf165bb68ff4b32389f028f1abd7c10ab9519a"}, ] graphviz = [ {file = "graphviz-0.16-py2.py3-none-any.whl", hash = "sha256:3cad5517c961090dfc679df6402a57de62d97703e2880a1a46147bb0dc1639eb"}, {file = "graphviz-0.16.zip", hash = "sha256:d2d25af1c199cad567ce4806f0449cb74eb30cf451fd7597251e1da099ac6e57"}, ] great-expectations = [ - {file = "great_expectations-0.15.34-py3-none-any.whl", hash = "sha256:82fbdb113dd5158f5236469ba352094df10f5faf9498517f2809440ca8689239"}, - {file = "great_expectations-0.15.34.tar.gz", hash = "sha256:09a4a3cb8d4648a410bc89fa349b16c885dcbcbffd3ff7808357d8bf7399b621"}, + {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, + {file = "great_expectations-0.15.44.tar.gz", hash = "sha256:547a3f252cfc41124b299b226399b1169b01e127e717f97ee5dd16e34d0e2a64"}, ] httplib2 = [ {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, @@ -2593,32 +2709,32 @@ imagesize = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] importlib-metadata = [ - {file = "importlib_metadata-5.1.0-py3-none-any.whl", hash = "sha256:d84d17e21670ec07990e1044a99efe8d615d860fd176fc29ef5c306068fda313"}, - {file = "importlib_metadata-5.1.0.tar.gz", hash = "sha256:d5059f9f1e8e41f80e9c56c2ee58811450c31984dfa625329ffd7c0dad88a73b"}, + {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, + {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, ] inflection = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, {file = "inflection-0.5.1.tar.gz", hash = "sha256:1a29730d366e996aaacffb2f1f1cb9593dc38e2ddd30c91250c6dde09ea9b417"}, ] iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.16.2-py3-none-any.whl", hash = "sha256:67daf93e5b52456cd8eea87a8b59405d2bb80ae411864a1ea206c3631d8179af"}, - {file = "ipykernel-6.16.2.tar.gz", hash = "sha256:463f3d87a92e99969b1605cb7a5b4d7b36b7145a0e72d06e65918a6ddefbe630"}, + {file = "ipykernel-6.20.2-py3-none-any.whl", hash = "sha256:5d0675d5f48bf6a95fd517d7b70bcb3b2c5631b2069949b5c2d6e1d7477fb5a0"}, + {file = "ipykernel-6.20.2.tar.gz", hash = "sha256:1893c5b847033cd7a58f6843b04a9349ffb1031bc6588401cadc9adb58da428e"}, ] ipython = [ - {file = "ipython-7.34.0-py3-none-any.whl", hash = "sha256:c175d2440a1caff76116eb719d40538fbb316e214eda85c5515c303aacbfb23e"}, - {file = "ipython-7.34.0.tar.gz", hash = "sha256:af3bdb46aa292bce5615b1b2ebc76c2080c5f77f54bda2ec72461317273e7cd6"}, + {file = "ipython-8.8.0-py3-none-any.whl", hash = "sha256:da01e6df1501e6e7c32b5084212ddadd4ee2471602e2cf3e0190f4de6b0ea481"}, + {file = "ipython-8.8.0.tar.gz", hash = "sha256:f3bf2c08505ad2c3f4ed5c46ae0331a8547d36bf4b21a451e8ae80c0791db95b"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, ] ipywidgets = [ - {file = "ipywidgets-8.0.2-py3-none-any.whl", hash = "sha256:1dc3dd4ee19ded045ea7c86eb273033d238d8e43f9e7872c52d092683f263891"}, - {file = "ipywidgets-8.0.2.tar.gz", hash = "sha256:08cb75c6e0a96836147cbfdc55580ae04d13e05d26ffbc377b4e1c68baa28b1f"}, + {file = "ipywidgets-8.0.4-py3-none-any.whl", hash = "sha256:ebb195e743b16c3947fe8827190fb87b4d00979c0fbf685afe4d2c4927059fa1"}, + {file = "ipywidgets-8.0.4.tar.gz", hash = "sha256:c0005a77a47d77889cafed892b58e33b4a2a96712154404c6548ec22272811ea"}, ] isodate = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, @@ -2653,20 +2769,20 @@ jsonschema = [ {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] jupyter-client = [ - {file = "jupyter_client-7.4.7-py3-none-any.whl", hash = "sha256:df56ae23b8e1da1b66f89dee1368e948b24a7f780fa822c5735187589fc4c157"}, - {file = "jupyter_client-7.4.7.tar.gz", hash = "sha256:330f6b627e0b4bf2f54a3a0dd9e4a22d2b649c8518168afedce2c96a1ceb2860"}, + {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, + {file = "jupyter_client-7.4.9.tar.gz", hash = "sha256:52be28e04171f07aed8f20e1616a5a552ab9fee9cbbe6c1896ae170c3880d392"}, ] jupyter-core = [ - {file = "jupyter_core-4.12.0-py3-none-any.whl", hash = "sha256:a54672c539333258495579f6964144924e0aa7b07f7069947bef76d7ea5cb4c1"}, - {file = "jupyter_core-4.12.0.tar.gz", hash = "sha256:87f39d7642412ae8a52291cc68e71ac01dfa2c735df2701f8108251d51b4f460"}, + {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, + {file = "jupyter_core-5.1.5.tar.gz", hash = "sha256:8e54c48cde1e0c8345f64bcf9658b78044ddf02b273726cea9d9f59be4b02130"}, ] jupyter-server = [ {file = "jupyter_server-1.15.6-py3-none-any.whl", hash = "sha256:e393934c19fcc324a7fca77f811eacd91201440f04c6fbb15c959c463baaa9c5"}, {file = "jupyter_server-1.15.6.tar.gz", hash = "sha256:56bd6f580d1f46b62294990e8e78651025729f5d3fc798f10f2c03f0cdcbf28d"}, ] jupyterlab-widgets = [ - {file = "jupyterlab_widgets-3.0.3-py3-none-any.whl", hash = "sha256:6aa1bc0045470d54d76b9c0b7609a8f8f0087573bae25700a370c11f82cb38c8"}, - {file = "jupyterlab_widgets-3.0.3.tar.gz", hash = "sha256:c767181399b4ca8b647befe2d913b1260f51bf9d8ef9b7a14632d4c1a7b536bd"}, + {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, + {file = "jupyterlab_widgets-3.0.5.tar.gz", hash = "sha256:eeaecdeaf6c03afc960ddae201ced88d5979b4ca9c3891bcb8f6631af705f5ef"}, ] keyring = [ {file = "keyring-23.4.1-py3-none-any.whl", hash = "sha256:17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca"}, @@ -2780,16 +2896,16 @@ nbconvert = [ {file = "nbconvert-5.5.0.tar.gz", hash = "sha256:138381baa41d83584459b5cfecfc38c800ccf1f37d9ddd0bd440783346a4c39c"}, ] nbformat = [ - {file = "nbformat-5.7.0-py3-none-any.whl", hash = "sha256:1b05ec2c552c2f1adc745f4eddce1eac8ca9ffd59bb9fd859e827eaa031319f9"}, - {file = "nbformat-5.7.0.tar.gz", hash = "sha256:1d4760c15c1a04269ef5caf375be8b98dd2f696e5eb9e603ec2bf091f9b0d3f3"}, + {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, + {file = "nbformat-5.7.3.tar.gz", hash = "sha256:4b021fca24d3a747bf4e626694033d792d594705829e5e35b14ee3369f9f6477"}, ] nest-asyncio = [ {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, {file = "nest_asyncio-1.5.6.tar.gz", hash = "sha256:d267cc1ff794403f7df692964d1d2a3fa9418ffea2a3f6859a439ff482fef290"}, ] networkx = [ - {file = "networkx-2.6.3-py3-none-any.whl", hash = "sha256:80b6b89c77d1dfb64a4c7854981b60aeea6360ac02c6d4e4913319e0a313abef"}, - {file = "networkx-2.6.3.tar.gz", hash = "sha256:c0946ed31d71f1b732b5aaa6da5a0388a345019af232ce2f49c766e2d6795c51"}, + {file = "networkx-2.8.8-py3-none-any.whl", hash = "sha256:e435dfa75b1d7195c7b8378c3859f0445cd88c6b0375c181ed66823a9ceb7524"}, + {file = "networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e"}, ] notebook = [ {file = "notebook-6.5.2-py3-none-any.whl", hash = "sha256:e04f9018ceb86e4fa841e92ea8fb214f8d23c1cedfde530cc96f92446924f0e4"}, @@ -2800,37 +2916,34 @@ notebook-shim = [ {file = "notebook_shim-0.2.2.tar.gz", hash = "sha256:090e0baf9a5582ff59b607af523ca2db68ff216da0c69956b62cab2ef4fc9c3f"}, ] numpy = [ - {file = "numpy-1.21.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8737609c3bbdd48e380d463134a35ffad3b22dc56295eff6f79fd85bd0eeeb25"}, - {file = "numpy-1.21.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fdffbfb6832cd0b300995a2b08b8f6fa9f6e856d562800fea9182316d99c4e8e"}, - {file = "numpy-1.21.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3820724272f9913b597ccd13a467cc492a0da6b05df26ea09e78b171a0bb9da6"}, - {file = "numpy-1.21.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f17e562de9edf691a42ddb1eb4a5541c20dd3f9e65b09ded2beb0799c0cf29bb"}, - {file = "numpy-1.21.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f30427731561ce75d7048ac254dbe47a2ba576229250fb60f0fb74db96501a1"}, - {file = "numpy-1.21.6-cp310-cp310-win32.whl", hash = "sha256:d4bf4d43077db55589ffc9009c0ba0a94fa4908b9586d6ccce2e0b164c86303c"}, - {file = "numpy-1.21.6-cp310-cp310-win_amd64.whl", hash = "sha256:d136337ae3cc69aa5e447e78d8e1514be8c3ec9b54264e680cf0b4bd9011574f"}, - {file = "numpy-1.21.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6aaf96c7f8cebc220cdfc03f1d5a31952f027dda050e5a703a0d1c396075e3e7"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:67c261d6c0a9981820c3a149d255a76918278a6b03b6a036800359aba1256d46"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a6be4cb0ef3b8c9250c19cc122267263093eee7edd4e3fa75395dfda8c17a8e2"}, - {file = "numpy-1.21.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7c4068a8c44014b2d55f3c3f574c376b2494ca9cc73d2f1bd692382b6dffe3db"}, - {file = "numpy-1.21.6-cp37-cp37m-win32.whl", hash = "sha256:7c7e5fa88d9ff656e067876e4736379cc962d185d5cd808014a8a928d529ef4e"}, - {file = "numpy-1.21.6-cp37-cp37m-win_amd64.whl", hash = "sha256:bcb238c9c96c00d3085b264e5c1a1207672577b93fa666c3b14a45240b14123a"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:82691fda7c3f77c90e62da69ae60b5ac08e87e775b09813559f8901a88266552"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:643843bcc1c50526b3a71cd2ee561cf0d8773f062c8cbaf9ffac9fdf573f83ab"}, - {file = "numpy-1.21.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:357768c2e4451ac241465157a3e929b265dfac85d9214074985b1786244f2ef3"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9f411b2c3f3d76bba0865b35a425157c5dcf54937f82bbeb3d3c180789dd66a6"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4aa48afdce4660b0076a00d80afa54e8a97cd49f457d68a4342d188a09451c1a"}, - {file = "numpy-1.21.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a96eef20f639e6a97d23e57dd0c1b1069a7b4fd7027482a4c5c451cd7732f4"}, - {file = "numpy-1.21.6-cp38-cp38-win32.whl", hash = "sha256:5c3c8def4230e1b959671eb959083661b4a0d2e9af93ee339c7dada6759a9470"}, - {file = "numpy-1.21.6-cp38-cp38-win_amd64.whl", hash = "sha256:bf2ec4b75d0e9356edea834d1de42b31fe11f726a81dfb2c2112bc1eaa508fcf"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4391bd07606be175aafd267ef9bea87cf1b8210c787666ce82073b05f202add1"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:67f21981ba2f9d7ba9ade60c9e8cbaa8cf8e9ae51673934480e45cf55e953673"}, - {file = "numpy-1.21.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee5ec40fdd06d62fe5d4084bef4fd50fd4bb6bfd2bf519365f569dc470163ab0"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:1dbe1c91269f880e364526649a52eff93ac30035507ae980d2fed33aaee633ac"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d9caa9d5e682102453d96a0ee10c7241b72859b01a941a397fd965f23b3e016b"}, - {file = "numpy-1.21.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58459d3bad03343ac4b1b42ed14d571b8743dc80ccbf27444f266729df1d6f5b"}, - {file = "numpy-1.21.6-cp39-cp39-win32.whl", hash = "sha256:7f5ae4f304257569ef3b948810816bc87c9146e8c446053539947eedeaa32786"}, - {file = "numpy-1.21.6-cp39-cp39-win_amd64.whl", hash = "sha256:e31f0bb5928b793169b87e3d1e070f2342b22d5245c755e2b81caa29756246c3"}, - {file = "numpy-1.21.6-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd1c8f6bd65d07d3810b90d02eba7997e32abbdf1277a481d698969e921a3be0"}, - {file = "numpy-1.21.6.zip", hash = "sha256:ecb55251139706669fdec2ff073c98ef8e9a84473e51e716211b41aa0f18e656"}, + {file = "numpy-1.24.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7"}, + {file = "numpy-1.24.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9"}, + {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7"}, + {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398"}, + {file = "numpy-1.24.1-cp310-cp310-win32.whl", hash = "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2"}, + {file = "numpy-1.24.1-cp310-cp310-win_amd64.whl", hash = "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2"}, + {file = "numpy-1.24.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8"}, + {file = "numpy-1.24.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032"}, + {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1"}, + {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9"}, + {file = "numpy-1.24.1-cp311-cp311-win32.whl", hash = "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36"}, + {file = "numpy-1.24.1-cp311-cp311-win_amd64.whl", hash = "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51"}, + {file = "numpy-1.24.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407"}, + {file = "numpy-1.24.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954"}, + {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36"}, + {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7"}, + {file = "numpy-1.24.1-cp38-cp38-win32.whl", hash = "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1"}, + {file = "numpy-1.24.1-cp38-cp38-win_amd64.whl", hash = "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c"}, + {file = "numpy-1.24.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6"}, + {file = "numpy-1.24.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7"}, + {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700"}, + {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf"}, + {file = "numpy-1.24.1-cp39-cp39-win32.whl", hash = "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f"}, + {file = "numpy-1.24.1-cp39-cp39-win_amd64.whl", hash = "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e"}, + {file = "numpy-1.24.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d"}, + {file = "numpy-1.24.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086"}, + {file = "numpy-1.24.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566"}, + {file = "numpy-1.24.1.tar.gz", hash = "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2"}, ] oauth2client = [ {file = "oauth2client-3.0.0.tar.gz", hash = "sha256:5b5b056ec6f2304e7920b632885bd157fa71d1a7f3ddd00a43b1541a8d1a2460"}, @@ -2844,35 +2957,37 @@ openpyxl = [ {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, ] packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, + {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, + {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] pandas = [ - {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:62d5b5ce965bae78f12c1c0df0d387899dd4211ec0bdc52822373f13a3a022b9"}, - {file = "pandas-1.3.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:adfeb11be2d54f275142c8ba9bf67acee771b7186a5745249c7d5a06c670136b"}, - {file = "pandas-1.3.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:60a8c055d58873ad81cae290d974d13dd479b82cbb975c3e1fa2cf1920715296"}, - {file = "pandas-1.3.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd541ab09e1f80a2a1760032d665f6e032d8e44055d602d65eeea6e6e85498cb"}, - {file = "pandas-1.3.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2651d75b9a167cc8cc572cf787ab512d16e316ae00ba81874b560586fa1325e0"}, - {file = "pandas-1.3.5-cp310-cp310-win_amd64.whl", hash = "sha256:aaf183a615ad790801fa3cf2fa450e5b6d23a54684fe386f7e3208f8b9bfbef6"}, - {file = "pandas-1.3.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:344295811e67f8200de2390093aeb3c8309f5648951b684d8db7eee7d1c81fb7"}, - {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:552020bf83b7f9033b57cbae65589c01e7ef1544416122da0c79140c93288f56"}, - {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cce0c6bbeb266b0e39e35176ee615ce3585233092f685b6a82362523e59e5b4"}, - {file = "pandas-1.3.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7d28a3c65463fd0d0ba8bbb7696b23073efee0510783340a44b08f5e96ffce0c"}, - {file = "pandas-1.3.5-cp37-cp37m-win32.whl", hash = "sha256:a62949c626dd0ef7de11de34b44c6475db76995c2064e2d99c6498c3dba7fe58"}, - {file = "pandas-1.3.5-cp37-cp37m-win_amd64.whl", hash = "sha256:8025750767e138320b15ca16d70d5cdc1886e8f9cc56652d89735c016cd8aea6"}, - {file = "pandas-1.3.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fe95bae4e2d579812865db2212bb733144e34d0c6785c0685329e5b60fcb85dd"}, - {file = "pandas-1.3.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f261553a1e9c65b7a310302b9dbac31cf0049a51695c14ebe04e4bfd4a96f02"}, - {file = "pandas-1.3.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6dbec5f3e6d5dc80dcfee250e0a2a652b3f28663492f7dab9a24416a48ac39"}, - {file = "pandas-1.3.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3bc49af96cd6285030a64779de5b3688633a07eb75c124b0747134a63f4c05f"}, - {file = "pandas-1.3.5-cp38-cp38-win32.whl", hash = "sha256:b6b87b2fb39e6383ca28e2829cddef1d9fc9e27e55ad91ca9c435572cdba51bf"}, - {file = "pandas-1.3.5-cp38-cp38-win_amd64.whl", hash = "sha256:a395692046fd8ce1edb4c6295c35184ae0c2bbe787ecbe384251da609e27edcb"}, - {file = "pandas-1.3.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bd971a3f08b745a75a86c00b97f3007c2ea175951286cdda6abe543e687e5f2f"}, - {file = "pandas-1.3.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37f06b59e5bc05711a518aa10beaec10942188dccb48918bb5ae602ccbc9f1a0"}, - {file = "pandas-1.3.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c21778a688d3712d35710501f8001cdbf96eb70a7c587a3d5613573299fdca6"}, - {file = "pandas-1.3.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3345343206546545bc26a05b4602b6a24385b5ec7c75cb6059599e3d56831da2"}, - {file = "pandas-1.3.5-cp39-cp39-win32.whl", hash = "sha256:c69406a2808ba6cf580c2255bcf260b3f214d2664a3a4197d0e640f573b46fd3"}, - {file = "pandas-1.3.5-cp39-cp39-win_amd64.whl", hash = "sha256:32e1a26d5ade11b547721a72f9bfc4bd113396947606e00d5b4a5b79b3dcb006"}, - {file = "pandas-1.3.5.tar.gz", hash = "sha256:1e4285f5de1012de20ca46b188ccf33521bff61ba5c5ebd78b4fb28e5416a9f1"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, + {file = "pandas-1.5.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:50869a35cbb0f2e0cd5ec04b191e7b12ed688874bd05dd777c19b28cbea90996"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c3ac844a0fe00bfaeb2c9b51ab1424e5c8744f89860b138434a363b1f620f354"}, + {file = "pandas-1.5.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a0a56cef15fd1586726dace5616db75ebcfec9179a3a55e78f72c5639fa2a23"}, + {file = "pandas-1.5.3-cp310-cp310-win_amd64.whl", hash = "sha256:478ff646ca42b20376e4ed3fa2e8d7341e8a63105586efe54fa2508ee087f328"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6973549c01ca91ec96199e940495219c887ea815b2083722821f1d7abfa2b4dc"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c39a8da13cede5adcd3be1182883aea1c925476f4e84b2807a46e2775306305d"}, + {file = "pandas-1.5.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f76d097d12c82a535fda9dfe5e8dd4127952b45fea9b0276cb30cca5ea313fbc"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e474390e60ed609cec869b0da796ad94f420bb057d86784191eefc62b65819ae"}, + {file = "pandas-1.5.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5f2b952406a1588ad4cad5b3f55f520e82e902388a6d5a4a91baa8d38d23c7f6"}, + {file = "pandas-1.5.3-cp311-cp311-win_amd64.whl", hash = "sha256:bc4c368f42b551bf72fac35c5128963a171b40dce866fb066540eeaf46faa003"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14e45300521902689a81f3f41386dc86f19b8ba8dd5ac5a3c7010ef8d2932813"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9842b6f4b8479e41968eced654487258ed81df7d1c9b7b870ceea24ed9459b31"}, + {file = "pandas-1.5.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26d9c71772c7afb9d5046e6e9cf42d83dd147b5cf5bcb9d97252077118543792"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5fbcb19d6fceb9e946b3e23258757c7b225ba450990d9ed63ccceeb8cae609f7"}, + {file = "pandas-1.5.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:565fa34a5434d38e9d250af3c12ff931abaf88050551d9fbcdfafca50d62babf"}, + {file = "pandas-1.5.3-cp38-cp38-win32.whl", hash = "sha256:87bd9c03da1ac870a6d2c8902a0e1fd4267ca00f13bc494c9e5a9020920e1d51"}, + {file = "pandas-1.5.3-cp38-cp38-win_amd64.whl", hash = "sha256:41179ce559943d83a9b4bbacb736b04c928b095b5f25dd2b7389eda08f46f373"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c74a62747864ed568f5a82a49a23a8d7fe171d0c69038b38cedf0976831296fa"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c4c00e0b0597c8e4f59e8d461f797e5d70b4d025880516a8261b2817c47759ee"}, + {file = "pandas-1.5.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a50d9a4336a9621cab7b8eb3fb11adb82de58f9b91d84c2cd526576b881a0c5a"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd05f7783b3274aa206a1af06f0ceed3f9b412cf665b7247eacd83be41cf7bf0"}, + {file = "pandas-1.5.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f69c4029613de47816b1bb30ff5ac778686688751a5e9c99ad8c7031f6508e5"}, + {file = "pandas-1.5.3-cp39-cp39-win32.whl", hash = "sha256:7cec0bee9f294e5de5bbfc14d0573f65526071029d036b753ee6507d2a21480a"}, + {file = "pandas-1.5.3-cp39-cp39-win_amd64.whl", hash = "sha256:dfd681c5dc216037e0b0a2c821f5ed99ba9f03ebcf119c7dac0e9a7b960b9ec9"}, + {file = "pandas-1.5.3.tar.gz", hash = "sha256:74a3fd7e5a7ec052f183273dc7b0acd3a863edf7520f5d3a1765c04ffdb3b0b1"}, ] pandocfilters = [ {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, @@ -2883,12 +2998,12 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ - {file = "pathspec-0.10.2-py3-none-any.whl", hash = "sha256:88c2606f2c1e818b978540f73ecc908e13999c6c3a383daf3705652ae79807a5"}, - {file = "pathspec-0.10.2.tar.gz", hash = "sha256:8f6bf73e5758fd365ef5d58ce09ac7c27d2833a8d7da51712eac6e27e35141b0"}, + {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, + {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, ] pdoc = [ - {file = "pdoc-12.3.0-py3-none-any.whl", hash = "sha256:0c520a6af892863b8712abb6abaad2c928366d7dee727715177774623c30405d"}, - {file = "pdoc-12.3.0.tar.gz", hash = "sha256:b245903dd8fb515b99d838bb1ad3efeb706fa0efd925a886c4624bf946afaab5"}, + {file = "pdoc-12.3.1-py3-none-any.whl", hash = "sha256:c3f24f31286e634de9c76fa6e67bd5c0c5e74360b41dc91e6b82499831eb52d8"}, + {file = "pdoc-12.3.1.tar.gz", hash = "sha256:453236f225feddb8a9071428f1982a78d74b9b3da4bc4433aedb64dbd0cc87ab"}, ] pexpect = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, @@ -2898,33 +3013,35 @@ pickleshare = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] +platformdirs = [ + {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, + {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, +] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] prometheus-client = [ - {file = "prometheus_client-0.15.0-py3-none-any.whl", hash = "sha256:db7c05cbd13a0f79975592d112320f2605a325969b270a94b71dcabc47b931d2"}, - {file = "prometheus_client-0.15.0.tar.gz", hash = "sha256:be26aa452490cfcf6da953f9436e95a9f2b4d578ca80094b4458930e5f584ab1"}, + {file = "prometheus_client-0.16.0-py3-none-any.whl", hash = "sha256:0836af6eb2c8f4fed712b2f279f6c0a8bbab29f9f4aa15276b91c7cb0d1616ab"}, + {file = "prometheus_client-0.16.0.tar.gz", hash = "sha256:a03e35b359f14dd1630898543e2120addfdeacd1a6069c1367ae90fd93ad3f48"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.33-py3-none-any.whl", hash = "sha256:ced598b222f6f4029c0800cefaa6a17373fb580cd093223003475ce32805c35b"}, - {file = "prompt_toolkit-3.0.33.tar.gz", hash = "sha256:535c29c31216c77302877d5120aef6c94ff573748a5b5ca5b1b1f76f5e700c73"}, + {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, + {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, ] protobuf = [ - {file = "protobuf-4.21.9-cp310-abi3-win32.whl", hash = "sha256:6e0be9f09bf9b6cf497b27425487706fa48c6d1632ddd94dab1a5fe11a422392"}, - {file = "protobuf-4.21.9-cp310-abi3-win_amd64.whl", hash = "sha256:a7d0ea43949d45b836234f4ebb5ba0b22e7432d065394b532cdca8f98415e3cf"}, - {file = "protobuf-4.21.9-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:b5ab0b8918c136345ff045d4b3d5f719b505b7c8af45092d7f45e304f55e50a1"}, - {file = "protobuf-4.21.9-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:2c9c2ed7466ad565f18668aa4731c535511c5d9a40c6da39524bccf43e441719"}, - {file = "protobuf-4.21.9-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:e575c57dc8b5b2b2caa436c16d44ef6981f2235eb7179bfc847557886376d740"}, - {file = "protobuf-4.21.9-cp37-cp37m-win32.whl", hash = "sha256:9227c14010acd9ae7702d6467b4625b6fe853175a6b150e539b21d2b2f2b409c"}, - {file = "protobuf-4.21.9-cp37-cp37m-win_amd64.whl", hash = "sha256:a419cc95fca8694804709b8c4f2326266d29659b126a93befe210f5bbc772536"}, - {file = "protobuf-4.21.9-cp38-cp38-win32.whl", hash = "sha256:5b0834e61fb38f34ba8840d7dcb2e5a2f03de0c714e0293b3963b79db26de8ce"}, - {file = "protobuf-4.21.9-cp38-cp38-win_amd64.whl", hash = "sha256:84ea107016244dfc1eecae7684f7ce13c788b9a644cd3fca5b77871366556444"}, - {file = "protobuf-4.21.9-cp39-cp39-win32.whl", hash = "sha256:f9eae277dd240ae19bb06ff4e2346e771252b0e619421965504bd1b1bba7c5fa"}, - {file = "protobuf-4.21.9-cp39-cp39-win_amd64.whl", hash = "sha256:6e312e280fbe3c74ea9e080d9e6080b636798b5e3939242298b591064470b06b"}, - {file = "protobuf-4.21.9-py2.py3-none-any.whl", hash = "sha256:7eb8f2cc41a34e9c956c256e3ac766cf4e1a4c9c925dc757a41a01be3e852965"}, - {file = "protobuf-4.21.9-py3-none-any.whl", hash = "sha256:48e2cd6b88c6ed3d5877a3ea40df79d08374088e89bedc32557348848dff250b"}, - {file = "protobuf-4.21.9.tar.gz", hash = "sha256:61f21493d96d2a77f9ca84fefa105872550ab5ef71d21c458eb80edcf4885a99"}, + {file = "protobuf-4.21.12-cp310-abi3-win32.whl", hash = "sha256:b135410244ebe777db80298297a97fbb4c862c881b4403b71bac9d4107d61fd1"}, + {file = "protobuf-4.21.12-cp310-abi3-win_amd64.whl", hash = "sha256:89f9149e4a0169cddfc44c74f230d7743002e3aa0b9472d8c28f0388102fc4c2"}, + {file = "protobuf-4.21.12-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:299ea899484ee6f44604deb71f424234f654606b983cb496ea2a53e3c63ab791"}, + {file = "protobuf-4.21.12-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:d1736130bce8cf131ac7957fa26880ca19227d4ad68b4888b3be0dea1f95df97"}, + {file = "protobuf-4.21.12-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:78a28c9fa223998472886c77042e9b9afb6fe4242bd2a2a5aced88e3f4422aa7"}, + {file = "protobuf-4.21.12-cp37-cp37m-win32.whl", hash = "sha256:3d164928ff0727d97022957c2b849250ca0e64777ee31efd7d6de2e07c494717"}, + {file = "protobuf-4.21.12-cp37-cp37m-win_amd64.whl", hash = "sha256:f45460f9ee70a0ec1b6694c6e4e348ad2019275680bd68a1d9314b8c7e01e574"}, + {file = "protobuf-4.21.12-cp38-cp38-win32.whl", hash = "sha256:6ab80df09e3208f742c98443b6166bcb70d65f52cfeb67357d52032ea1ae9bec"}, + {file = "protobuf-4.21.12-cp38-cp38-win_amd64.whl", hash = "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30"}, + {file = "protobuf-4.21.12-cp39-cp39-win32.whl", hash = "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc"}, + {file = "protobuf-4.21.12-cp39-cp39-win_amd64.whl", hash = "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b"}, + {file = "protobuf-4.21.12-py3-none-any.whl", hash = "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462"}, ] psutil = [ {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, @@ -2946,39 +3063,21 @@ ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] +pure-eval = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] py = [ {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, ] pyasn1 = [ - {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, - {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, - {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, - {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, - {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, - {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, - {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, - {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, - {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, - {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, - {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pyasn1-modules = [ {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, - {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, - {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, - {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, - {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, - {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, - {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, - {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, - {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, - {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, - {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, - {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, ] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, @@ -2989,50 +3088,50 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.10.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb6ad4489af1bac6955d38ebcb95079a836af31e4c4f74aba1ca05bb9f6027bd"}, - {file = "pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a1f5a63a6dfe19d719b1b6e6106561869d2efaca6167f84f5ab9347887d78b98"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:352aedb1d71b8b0736c6d56ad2bd34c6982720644b0624462059ab29bd6e5912"}, - {file = "pydantic-1.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19b3b9ccf97af2b7519c42032441a891a5e05c68368f40865a90eb88833c2559"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e9069e1b01525a96e6ff49e25876d90d5a563bc31c658289a8772ae186552236"}, - {file = "pydantic-1.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:355639d9afc76bcb9b0c3000ddcd08472ae75318a6eb67a15866b87e2efa168c"}, - {file = "pydantic-1.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:ae544c47bec47a86bc7d350f965d8b15540e27e5aa4f55170ac6a75e5f73b644"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a4c805731c33a8db4b6ace45ce440c4ef5336e712508b4d9e1aafa617dc9907f"}, - {file = "pydantic-1.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d49f3db871575e0426b12e2f32fdb25e579dea16486a26e5a0474af87cb1ab0a"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37c90345ec7dd2f1bcef82ce49b6235b40f282b94d3eec47e801baf864d15525"}, - {file = "pydantic-1.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b5ba54d026c2bd2cb769d3468885f23f43710f651688e91f5fb1edcf0ee9283"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05e00dbebbe810b33c7a7362f231893183bcc4251f3f2ff991c31d5c08240c42"}, - {file = "pydantic-1.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2d0567e60eb01bccda3a4df01df677adf6b437958d35c12a3ac3e0f078b0ee52"}, - {file = "pydantic-1.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:c6f981882aea41e021f72779ce2a4e87267458cc4d39ea990729e21ef18f0f8c"}, - {file = "pydantic-1.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4aac8e7103bf598373208f6299fa9a5cfd1fc571f2d40bf1dd1955a63d6eeb5"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:81a7b66c3f499108b448f3f004801fcd7d7165fb4200acb03f1c2402da73ce4c"}, - {file = "pydantic-1.10.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bedf309630209e78582ffacda64a21f96f3ed2e51fbf3962d4d488e503420254"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9300fcbebf85f6339a02c6994b2eb3ff1b9c8c14f502058b5bf349d42447dcf5"}, - {file = "pydantic-1.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:216f3bcbf19c726b1cc22b099dd409aa371f55c08800bcea4c44c8f74b73478d"}, - {file = "pydantic-1.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:dd3f9a40c16daf323cf913593083698caee97df2804aa36c4b3175d5ac1b92a2"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b97890e56a694486f772d36efd2ba31612739bc6f3caeee50e9e7e3ebd2fdd13"}, - {file = "pydantic-1.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9cabf4a7f05a776e7793e72793cd92cc865ea0e83a819f9ae4ecccb1b8aa6116"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06094d18dd5e6f2bbf93efa54991c3240964bb663b87729ac340eb5014310624"}, - {file = "pydantic-1.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc78cc83110d2f275ec1970e7a831f4e371ee92405332ebfe9860a715f8336e1"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ee433e274268a4b0c8fde7ad9d58ecba12b069a033ecc4645bb6303c062d2e9"}, - {file = "pydantic-1.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c2abc4393dea97a4ccbb4ec7d8658d4e22c4765b7b9b9445588f16c71ad9965"}, - {file = "pydantic-1.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:0b959f4d8211fc964772b595ebb25f7652da3f22322c007b6fed26846a40685e"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c33602f93bfb67779f9c507e4d69451664524389546bacfe1bee13cae6dc7488"}, - {file = "pydantic-1.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5760e164b807a48a8f25f8aa1a6d857e6ce62e7ec83ea5d5c5a802eac81bad41"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6eb843dcc411b6a2237a694f5e1d649fc66c6064d02b204a7e9d194dff81eb4b"}, - {file = "pydantic-1.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b8795290deaae348c4eba0cebb196e1c6b98bdbe7f50b2d0d9a4a99716342fe"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:e0bedafe4bc165ad0a56ac0bd7695df25c50f76961da29c050712596cf092d6d"}, - {file = "pydantic-1.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e05aed07fa02231dbf03d0adb1be1d79cabb09025dd45aa094aa8b4e7b9dcda"}, - {file = "pydantic-1.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:c1ba1afb396148bbc70e9eaa8c06c1716fdddabaf86e7027c5988bae2a829ab6"}, - {file = "pydantic-1.10.2-py3-none-any.whl", hash = "sha256:1b6ee725bd6e83ec78b1aa32c5b1fa67a3a65badddde3976bca5fe4568f27709"}, - {file = "pydantic-1.10.2.tar.gz", hash = "sha256:91b8e218852ef6007c2b98cd861601c6a09f1aa32bbbb74fab5b1c33d4a1e410"}, + {file = "pydantic-1.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854"}, + {file = "pydantic-1.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817"}, + {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c"}, + {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e"}, + {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85"}, + {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6"}, + {file = "pydantic-1.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d"}, + {file = "pydantic-1.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53"}, + {file = "pydantic-1.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3"}, + {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a"}, + {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d"}, + {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72"}, + {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857"}, + {file = "pydantic-1.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3"}, + {file = "pydantic-1.10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00"}, + {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978"}, + {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e"}, + {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa"}, + {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8"}, + {file = "pydantic-1.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903"}, + {file = "pydantic-1.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423"}, + {file = "pydantic-1.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f"}, + {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06"}, + {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15"}, + {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c"}, + {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416"}, + {file = "pydantic-1.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6"}, + {file = "pydantic-1.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d"}, + {file = "pydantic-1.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f"}, + {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024"}, + {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c"}, + {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28"}, + {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f"}, + {file = "pydantic-1.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4"}, + {file = "pydantic-1.10.4-py3-none-any.whl", hash = "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774"}, + {file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"}, ] pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ - {file = "Pygments-2.13.0-py3-none-any.whl", hash = "sha256:f643f331ab57ba3c9d89212ee4a2dabc6e94f117cf4eefde99a0574720d14c42"}, - {file = "Pygments-2.13.0.tar.gz", hash = "sha256:56a8508ae95f98e2b9bdf93a6be5ae3f7d8af858b43e02c5a2ff083726be40c1"}, + {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, + {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, ] pygsheets = [ {file = "pygsheets-2.0.5-py2.py3-none-any.whl", hash = "sha256:85a4c871ac1d53013e042c13552b07f908b991c3d8c8770b3a68eb3452c8c218"}, @@ -3043,28 +3142,33 @@ pyparsing = [ {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, ] pyrsistent = [ - {file = "pyrsistent-0.19.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d6982b5a0237e1b7d876b60265564648a69b14017f3b5f908c5be2de3f9abb7a"}, - {file = "pyrsistent-0.19.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:187d5730b0507d9285a96fca9716310d572e5464cadd19f22b63a6976254d77a"}, - {file = "pyrsistent-0.19.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:055ab45d5911d7cae397dc418808d8802fb95262751872c841c170b0dbf51eed"}, - {file = "pyrsistent-0.19.2-cp310-cp310-win32.whl", hash = "sha256:456cb30ca8bff00596519f2c53e42c245c09e1a4543945703acd4312949bfd41"}, - {file = "pyrsistent-0.19.2-cp310-cp310-win_amd64.whl", hash = "sha256:b39725209e06759217d1ac5fcdb510e98670af9e37223985f330b611f62e7425"}, - {file = "pyrsistent-0.19.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2aede922a488861de0ad00c7630a6e2d57e8023e4be72d9d7147a9fcd2d30712"}, - {file = "pyrsistent-0.19.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:879b4c2f4d41585c42df4d7654ddffff1239dc4065bc88b745f0341828b83e78"}, - {file = "pyrsistent-0.19.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43bec251bbd10e3cb58ced80609c5c1eb238da9ca78b964aea410fb820d00d6"}, - {file = "pyrsistent-0.19.2-cp37-cp37m-win32.whl", hash = "sha256:d690b18ac4b3e3cab73b0b7aa7dbe65978a172ff94970ff98d82f2031f8971c2"}, - {file = "pyrsistent-0.19.2-cp37-cp37m-win_amd64.whl", hash = "sha256:3ba4134a3ff0fc7ad225b6b457d1309f4698108fb6b35532d015dca8f5abed73"}, - {file = "pyrsistent-0.19.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a178209e2df710e3f142cbd05313ba0c5ebed0a55d78d9945ac7a4e09d923308"}, - {file = "pyrsistent-0.19.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e371b844cec09d8dc424d940e54bba8f67a03ebea20ff7b7b0d56f526c71d584"}, - {file = "pyrsistent-0.19.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:111156137b2e71f3a9936baf27cb322e8024dac3dc54ec7fb9f0bcf3249e68bb"}, - {file = "pyrsistent-0.19.2-cp38-cp38-win32.whl", hash = "sha256:e5d8f84d81e3729c3b506657dddfe46e8ba9c330bf1858ee33108f8bb2adb38a"}, - {file = "pyrsistent-0.19.2-cp38-cp38-win_amd64.whl", hash = "sha256:9cd3e9978d12b5d99cbdc727a3022da0430ad007dacf33d0bf554b96427f33ab"}, - {file = "pyrsistent-0.19.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f1258f4e6c42ad0b20f9cfcc3ada5bd6b83374516cd01c0960e3cb75fdca6770"}, - {file = "pyrsistent-0.19.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21455e2b16000440e896ab99e8304617151981ed40c29e9507ef1c2e4314ee95"}, - {file = "pyrsistent-0.19.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd880614c6237243ff53a0539f1cb26987a6dc8ac6e66e0c5a40617296a045e"}, - {file = "pyrsistent-0.19.2-cp39-cp39-win32.whl", hash = "sha256:71d332b0320642b3261e9fee47ab9e65872c2bd90260e5d225dabeed93cbd42b"}, - {file = "pyrsistent-0.19.2-cp39-cp39-win_amd64.whl", hash = "sha256:dec3eac7549869365fe263831f576c8457f6c833937c68542d08fde73457d291"}, - {file = "pyrsistent-0.19.2-py3-none-any.whl", hash = "sha256:ea6b79a02a28550c98b6ca9c35b9f492beaa54d7c5c9e9949555893c8a9234d0"}, - {file = "pyrsistent-0.19.2.tar.gz", hash = "sha256:bfa0351be89c9fcbcb8c9879b826f4353be10f58f8a677efab0c017bf7137ec2"}, + {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, + {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, + {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, + {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, + {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, + {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, + {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, + {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, + {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, + {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, + {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, + {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, + {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, + {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, ] pytest = [ {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, @@ -3087,8 +3191,8 @@ python-dotenv = [ {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, ] pytz = [ - {file = "pytz-2022.6-py2.py3-none-any.whl", hash = "sha256:222439474e9c98fced559f1709d89e6c9cbf8d79c794ff3eb9f8800064291427"}, - {file = "pytz-2022.6.tar.gz", hash = "sha256:e89512406b793ca39f5971bc999cc538ce125c0e51c27941bef4568b460095e2"}, + {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, + {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, ] pytz-deprecation-shim = [ {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, @@ -3115,12 +3219,12 @@ pywin32-ctypes = [ {file = "pywin32_ctypes-0.2.0-py2.py3-none-any.whl", hash = "sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98"}, ] pywinpty = [ - {file = "pywinpty-2.0.9-cp310-none-win_amd64.whl", hash = "sha256:30a7b371446a694a6ce5ef906d70ac04e569de5308c42a2bdc9c3bc9275ec51f"}, - {file = "pywinpty-2.0.9-cp311-none-win_amd64.whl", hash = "sha256:d78ef6f4bd7a6c6f94dc1a39ba8fb028540cc39f5cb593e756506db17843125f"}, - {file = "pywinpty-2.0.9-cp37-none-win_amd64.whl", hash = "sha256:5ed36aa087e35a3a183f833631b3e4c1ae92fe2faabfce0fa91b77ed3f0f1382"}, - {file = "pywinpty-2.0.9-cp38-none-win_amd64.whl", hash = "sha256:2352f44ee913faaec0a02d3c112595e56b8af7feeb8100efc6dc1a8685044199"}, - {file = "pywinpty-2.0.9-cp39-none-win_amd64.whl", hash = "sha256:ba75ec55f46c9e17db961d26485b033deb20758b1731e8e208e1e8a387fcf70c"}, - {file = "pywinpty-2.0.9.tar.gz", hash = "sha256:01b6400dd79212f50a2f01af1c65b781290ff39610853db99bf03962eb9a615f"}, + {file = "pywinpty-2.0.10-cp310-none-win_amd64.whl", hash = "sha256:4c7d06ad10f6e92bc850a467f26d98f4f30e73d2fe5926536308c6ae0566bc16"}, + {file = "pywinpty-2.0.10-cp311-none-win_amd64.whl", hash = "sha256:7ffbd66310b83e42028fc9df7746118978d94fba8c1ebf15a7c1275fdd80b28a"}, + {file = "pywinpty-2.0.10-cp37-none-win_amd64.whl", hash = "sha256:38cb924f2778b5751ef91a75febd114776b3af0ae411bc667be45dd84fc881d3"}, + {file = "pywinpty-2.0.10-cp38-none-win_amd64.whl", hash = "sha256:902d79444b29ad1833b8d5c3c9aabdfd428f4f068504430df18074007c8c0de8"}, + {file = "pywinpty-2.0.10-cp39-none-win_amd64.whl", hash = "sha256:3c46aef80dd50979aff93de199e4a00a8ee033ba7a03cadf0a91fed45f0c39d7"}, + {file = "pywinpty-2.0.10.tar.gz", hash = "sha256:cdbb5694cf8c7242c2ecfaca35c545d31fa5d5814c3d67a4e628f803f680ebea"}, ] pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, @@ -3154,80 +3258,83 @@ pyyaml = [ {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] pyzmq = [ - {file = "pyzmq-24.0.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:28b119ba97129d3001673a697b7cce47fe6de1f7255d104c2f01108a5179a066"}, - {file = "pyzmq-24.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bcbebd369493d68162cddb74a9c1fcebd139dfbb7ddb23d8f8e43e6c87bac3a6"}, - {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae61446166983c663cee42c852ed63899e43e484abf080089f771df4b9d272ef"}, - {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87f7ac99b15270db8d53f28c3c7b968612993a90a5cf359da354efe96f5372b4"}, - {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca7c3956b03b7663fac4d150f5e6d4f6f38b2462c1e9afd83bcf7019f17913"}, - {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8c78bfe20d4c890cb5580a3b9290f700c570e167d4cdcc55feec07030297a5e3"}, - {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:48f721f070726cd2a6e44f3c33f8ee4b24188e4b816e6dd8ba542c8c3bb5b246"}, - {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afe1f3bc486d0ce40abb0a0c9adb39aed3bbac36ebdc596487b0cceba55c21c1"}, - {file = "pyzmq-24.0.1-cp310-cp310-win32.whl", hash = "sha256:3e6192dbcefaaa52ed81be88525a54a445f4b4fe2fffcae7fe40ebb58bd06bfd"}, - {file = "pyzmq-24.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:86de64468cad9c6d269f32a6390e210ca5ada568c7a55de8e681ca3b897bb340"}, - {file = "pyzmq-24.0.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:838812c65ed5f7c2bd11f7b098d2e5d01685a3f6d1f82849423b570bae698c00"}, - {file = "pyzmq-24.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfb992dbcd88d8254471760879d48fb20836d91baa90f181c957122f9592b3dc"}, - {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7abddb2bd5489d30ffeb4b93a428130886c171b4d355ccd226e83254fcb6b9ef"}, - {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94010bd61bc168c103a5b3b0f56ed3b616688192db7cd5b1d626e49f28ff51b3"}, - {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8242543c522d84d033fe79be04cb559b80d7eb98ad81b137ff7e0a9020f00ace"}, - {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ccb94342d13e3bf3ffa6e62f95b5e3f0bc6bfa94558cb37f4b3d09d6feb536ff"}, - {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6640f83df0ae4ae1104d4c62b77e9ef39be85ebe53f636388707d532bee2b7b8"}, - {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a180dbd5ea5d47c2d3b716d5c19cc3fb162d1c8db93b21a1295d69585bfddac1"}, - {file = "pyzmq-24.0.1-cp311-cp311-win32.whl", hash = "sha256:624321120f7e60336be8ec74a172ae7fba5c3ed5bf787cc85f7e9986c9e0ebc2"}, - {file = "pyzmq-24.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:1724117bae69e091309ffb8255412c4651d3f6355560d9af312d547f6c5bc8b8"}, - {file = "pyzmq-24.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:15975747462ec49fdc863af906bab87c43b2491403ab37a6d88410635786b0f4"}, - {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b947e264f0e77d30dcbccbb00f49f900b204b922eb0c3a9f0afd61aaa1cedc3d"}, - {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ec91f1bad66f3ee8c6deb65fa1fe418e8ad803efedd69c35f3b5502f43bd1dc"}, - {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:db03704b3506455d86ec72c3358a779e9b1d07b61220dfb43702b7b668edcd0d"}, - {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e7e66b4e403c2836ac74f26c4b65d8ac0ca1eef41dfcac2d013b7482befaad83"}, - {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7a23ccc1083c260fa9685c93e3b170baba45aeed4b524deb3f426b0c40c11639"}, - {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fa0ae3275ef706c0309556061185dd0e4c4cd3b7d6f67ae617e4e677c7a41e2e"}, - {file = "pyzmq-24.0.1-cp36-cp36m-win32.whl", hash = "sha256:f01de4ec083daebf210531e2cca3bdb1608dbbbe00a9723e261d92087a1f6ebc"}, - {file = "pyzmq-24.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:de4217b9eb8b541cf2b7fde4401ce9d9a411cc0af85d410f9d6f4333f43640be"}, - {file = "pyzmq-24.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:78068e8678ca023594e4a0ab558905c1033b2d3e806a0ad9e3094e231e115a33"}, - {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77c2713faf25a953c69cf0f723d1b7dd83827b0834e6c41e3fb3bbc6765914a1"}, - {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bb4af15f305056e95ca1bd086239b9ebc6ad55e9f49076d27d80027f72752f6"}, - {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0f14cffd32e9c4c73da66db97853a6aeceaac34acdc0fae9e5bbc9370281864c"}, - {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0108358dab8c6b27ff6b985c2af4b12665c1bc659648284153ee501000f5c107"}, - {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d66689e840e75221b0b290b0befa86f059fb35e1ee6443bce51516d4d61b6b99"}, - {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae08ac90aa8fa14caafc7a6251bd218bf6dac518b7bff09caaa5e781119ba3f2"}, - {file = "pyzmq-24.0.1-cp37-cp37m-win32.whl", hash = "sha256:8421aa8c9b45ea608c205db9e1c0c855c7e54d0e9c2c2f337ce024f6843cab3b"}, - {file = "pyzmq-24.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54d8b9c5e288362ec8595c1d98666d36f2070fd0c2f76e2b3c60fbad9bd76227"}, - {file = "pyzmq-24.0.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:acbd0a6d61cc954b9f535daaa9ec26b0a60a0d4353c5f7c1438ebc88a359a47e"}, - {file = "pyzmq-24.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:47b11a729d61a47df56346283a4a800fa379ae6a85870d5a2e1e4956c828eedc"}, - {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abe6eb10122f0d746a0d510c2039ae8edb27bc9af29f6d1b05a66cc2401353ff"}, - {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:07bec1a1b22dacf718f2c0e71b49600bb6a31a88f06527dfd0b5aababe3fa3f7"}, - {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d945a85b70da97ae86113faf9f1b9294efe66bd4a5d6f82f2676d567338b66"}, - {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1b7928bb7580736ffac5baf814097be342ba08d3cfdfb48e52773ec959572287"}, - {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b946da90dc2799bcafa682692c1d2139b2a96ec3c24fa9fc6f5b0da782675330"}, - {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c8840f064b1fb377cffd3efeaad2b190c14d4c8da02316dae07571252d20b31f"}, - {file = "pyzmq-24.0.1-cp38-cp38-win32.whl", hash = "sha256:4854f9edc5208f63f0841c0c667260ae8d6846cfa233c479e29fdc85d42ebd58"}, - {file = "pyzmq-24.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:42d4f97b9795a7aafa152a36fe2ad44549b83a743fd3e77011136def512e6c2a"}, - {file = "pyzmq-24.0.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:52afb0ac962963fff30cf1be775bc51ae083ef4c1e354266ab20e5382057dd62"}, - {file = "pyzmq-24.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bad8210ad4df68c44ff3685cca3cda448ee46e20d13edcff8909eba6ec01ca4"}, - {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dabf1a05318d95b1537fd61d9330ef4313ea1216eea128a17615038859da3b3b"}, - {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5bd3d7dfd9cd058eb68d9a905dec854f86649f64d4ddf21f3ec289341386c44b"}, - {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8012bce6836d3f20a6c9599f81dfa945f433dab4dbd0c4917a6fb1f998ab33d"}, - {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c31805d2c8ade9b11feca4674eee2b9cce1fec3e8ddb7bbdd961a09dc76a80ea"}, - {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3104f4b084ad5d9c0cb87445cc8cfd96bba710bef4a66c2674910127044df209"}, - {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:df0841f94928f8af9c7a1f0aaaffba1fb74607af023a152f59379c01c53aee58"}, - {file = "pyzmq-24.0.1-cp39-cp39-win32.whl", hash = "sha256:a435ef8a3bd95c8a2d316d6e0ff70d0db524f6037411652803e118871d703333"}, - {file = "pyzmq-24.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:2032d9cb994ce3b4cba2b8dfae08c7e25bc14ba484c770d4d3be33c27de8c45b"}, - {file = "pyzmq-24.0.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bb5635c851eef3a7a54becde6da99485eecf7d068bd885ac8e6d173c4ecd68b0"}, - {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:83ea1a398f192957cb986d9206ce229efe0ee75e3c6635baff53ddf39bd718d5"}, - {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:941fab0073f0a54dc33d1a0460cb04e0d85893cb0c5e1476c785000f8b359409"}, - {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8f482c44ccb5884bf3f638f29bea0f8dc68c97e38b2061769c4cb697f6140d"}, - {file = "pyzmq-24.0.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:613010b5d17906c4367609e6f52e9a2595e35d5cc27d36ff3f1b6fa6e954d944"}, - {file = "pyzmq-24.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:65c94410b5a8355cfcf12fd600a313efee46ce96a09e911ea92cf2acf6708804"}, - {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:20e7eeb1166087db636c06cae04a1ef59298627f56fb17da10528ab52a14c87f"}, - {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2712aee7b3834ace51738c15d9ee152cc5a98dc7d57dd93300461b792ab7b43"}, - {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a7c280185c4da99e0cc06c63bdf91f5b0b71deb70d8717f0ab870a43e376db8"}, - {file = "pyzmq-24.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:858375573c9225cc8e5b49bfac846a77b696b8d5e815711b8d4ba3141e6e8879"}, - {file = "pyzmq-24.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:80093b595921eed1a2cead546a683b9e2ae7f4a4592bb2ab22f70d30174f003a"}, - {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f3f3154fde2b1ff3aa7b4f9326347ebc89c8ef425ca1db8f665175e6d3bd42f"}, - {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb756147314430bee5d10919b8493c0ccb109ddb7f5dfd2fcd7441266a25b75"}, - {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e706bac34e9f50779cb8c39f10b53a4d15aebb97235643d3112ac20bd577b4"}, - {file = "pyzmq-24.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:687700f8371643916a1d2c61f3fdaa630407dd205c38afff936545d7b7466066"}, - {file = "pyzmq-24.0.1.tar.gz", hash = "sha256:216f5d7dbb67166759e59b0479bca82b8acf9bed6015b526b8eb10143fb08e77"}, + {file = "pyzmq-25.0.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:2d05d904f03ddf1e0d83d97341354dfe52244a619b5a1440a5f47a5b3451e84e"}, + {file = "pyzmq-25.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a154ef810d44f9d28868be04641f837374a64e7449df98d9208e76c260c7ef1"}, + {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:487305c2a011fdcf3db1f24e8814bb76d23bc4d2f46e145bc80316a59a9aa07d"}, + {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e7b87638ee30ab13230e37ce5331b3e730b1e0dda30120b9eeec3540ed292c8"}, + {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75243e422e85a62f0ab7953dc315452a56b2c6a7e7d1a3c3109ac3cc57ed6b47"}, + {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:31e523d067ce44a04e876bed3ff9ea1ff8d1b6636d16e5fcace9d22f8c564369"}, + {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8539216173135e9e89f6b1cc392e74e6b935b91e8c76106cf50e7a02ab02efe5"}, + {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2754fa68da08a854f4816e05160137fa938a2347276471103d31e04bcee5365c"}, + {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1bc30f0c18444d51e9b0d0dd39e3a4e7c53ee74190bebef238cd58de577ea9"}, + {file = "pyzmq-25.0.0-cp310-cp310-win32.whl", hash = "sha256:01d53958c787cfea34091fcb8ef36003dbb7913b8e9f8f62a0715234ebc98b70"}, + {file = "pyzmq-25.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:58fc3ad5e1cfd2e6d24741fbb1e216b388115d31b0ca6670f894187f280b6ba6"}, + {file = "pyzmq-25.0.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:e4bba04ea779a3d7ef25a821bb63fd0939142c88e7813e5bd9c6265a20c523a2"}, + {file = "pyzmq-25.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af1fbfb7ad6ac0009ccee33c90a1d303431c7fb594335eb97760988727a37577"}, + {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85456f0d8f3268eecd63dede3b99d5bd8d3b306310c37d4c15141111d22baeaf"}, + {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0645b5a2d2a06fd8eb738018490c514907f7488bf9359c6ee9d92f62e844b76f"}, + {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f72ea279b2941a5203e935a4588b9ba8a48aeb9a926d9dfa1986278bd362cb8"}, + {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:4e295f7928a31ae0f657e848c5045ba6d693fe8921205f408ca3804b1b236968"}, + {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ac97e7d647d5519bcef48dd8d3d331f72975afa5c4496c95f6e854686f45e2d9"}, + {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:656281d496aaf9ca4fd4cea84e6d893e3361057c4707bd38618f7e811759103c"}, + {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f6116991568aac48b94d6d8aaed6157d407942ea385335a6ed313692777fb9d"}, + {file = "pyzmq-25.0.0-cp311-cp311-win32.whl", hash = "sha256:0282bba9aee6e0346aa27d6c69b5f7df72b5a964c91958fc9e0c62dcae5fdcdc"}, + {file = "pyzmq-25.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:526f884a27e8bba62fe1f4e07c62be2cfe492b6d432a8fdc4210397f8cf15331"}, + {file = "pyzmq-25.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ccb3e1a863222afdbda42b7ca8ac8569959593d7abd44f5a709177d6fa27d266"}, + {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4046d03100aca266e70d54a35694cb35d6654cfbef633e848b3c4a8d64b9d187"}, + {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3100dddcada66ec5940ed6391ebf9d003cc3ede3d320748b2737553019f58230"}, + {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7877264aa851c19404b1bb9dbe6eed21ea0c13698be1eda3784aab3036d1c861"}, + {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5049e75cc99db65754a3da5f079230fb8889230cf09462ec972d884d1704a3ed"}, + {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:81f99fb1224d36eb91557afec8cdc2264e856f3464500b55749020ce4c848ef2"}, + {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a1cd4a95f176cdc0ee0a82d49d5830f13ae6015d89decbf834c273bc33eeb3d3"}, + {file = "pyzmq-25.0.0-cp36-cp36m-win32.whl", hash = "sha256:926236ca003aec70574754f39703528947211a406f5c6c8b3e50eca04a9e87fc"}, + {file = "pyzmq-25.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:94f0a7289d0f5c80807c37ebb404205e7deb737e8763eb176f4770839ee2a287"}, + {file = "pyzmq-25.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f3f96d452e9580cb961ece2e5a788e64abaecb1232a80e61deffb28e105ff84a"}, + {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:930e6ad4f2eaac31a3d0c2130619d25db754b267487ebc186c6ad18af2a74018"}, + {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e1081d7030a1229c8ff90120346fb7599b54f552e98fcea5170544e7c6725aab"}, + {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:531866c491aee5a1e967c286cfa470dffac1e2a203b1afda52d62b58782651e9"}, + {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fc7c1421c5b1c916acf3128bf3cc7ea7f5018b58c69a6866d70c14190e600ce9"}, + {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9a2d5e419bd39a1edb6cdd326d831f0120ddb9b1ff397e7d73541bf393294973"}, + {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:183e18742be3621acf8908903f689ec520aee3f08449bfd29f583010ca33022b"}, + {file = "pyzmq-25.0.0-cp37-cp37m-win32.whl", hash = "sha256:02f5cb60a7da1edd5591a15efa654ffe2303297a41e1b40c3c8942f8f11fc17c"}, + {file = "pyzmq-25.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:cac602e02341eaaf4edfd3e29bd3fdef672e61d4e6dfe5c1d065172aee00acee"}, + {file = "pyzmq-25.0.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:e14df47c1265356715d3d66e90282a645ebc077b70b3806cf47efcb7d1d630cb"}, + {file = "pyzmq-25.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:293a7c2128690f496057f1f1eb6074f8746058d13588389981089ec45d8fdc77"}, + {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:731b208bc9412deeb553c9519dca47136b5a01ca66667cafd8733211941b17e4"}, + {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b055a1cddf8035966ad13aa51edae5dc8f1bba0b5d5e06f7a843d8b83dc9b66b"}, + {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17e1cb97d573ea84d7cd97188b42ca6f611ab3ee600f6a75041294ede58e3d20"}, + {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:60ecbfe7669d3808ffa8a7dd1487d6eb8a4015b07235e3b723d4b2a2d4de7203"}, + {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4c25c95416133942280faaf068d0fddfd642b927fb28aaf4ab201a738e597c1e"}, + {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:be05504af0619d1cffa500af1e0ede69fb683f301003851f5993b5247cc2c576"}, + {file = "pyzmq-25.0.0-cp38-cp38-win32.whl", hash = "sha256:6bf3842af37af43fa953e96074ebbb5315f6a297198f805d019d788a1021dbc8"}, + {file = "pyzmq-25.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:b90bb8dfbbd138558f1f284fecfe328f7653616ff9a972433a00711d9475d1a9"}, + {file = "pyzmq-25.0.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:62b9e80890c0d2408eb42d5d7e1fc62a5ce71be3288684788f74cf3e59ffd6e2"}, + {file = "pyzmq-25.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484c2c4ee02c1edc07039f42130bd16e804b1fe81c4f428e0042e03967f40c20"}, + {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9ca6db34b26c4d3e9b0728841ec9aa39484eee272caa97972ec8c8e231b20c7e"}, + {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:610d2d112acd4e5501fac31010064a6c6efd716ceb968e443cae0059eb7b86de"}, + {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3594c0ff604e685d7e907860b61d0e10e46c74a9ffca168f6e9e50ea934ee440"}, + {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c21a5f4e54a807df5afdef52b6d24ec1580153a6bcf0607f70a6e1d9fa74c5c3"}, + {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4725412e27612f0d7d7c2f794d89807ad0227c2fc01dd6146b39ada49c748ef9"}, + {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4d3d604fe0a67afd1aff906e54da557a5203368a99dcc50a70eef374f1d2abef"}, + {file = "pyzmq-25.0.0-cp39-cp39-win32.whl", hash = "sha256:3670e8c5644768f214a3b598fe46378a4a6f096d5fb82a67dfd3440028460565"}, + {file = "pyzmq-25.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:e99629a976809fe102ef73e856cf4b2660acd82a412a51e80ba2215e523dfd0a"}, + {file = "pyzmq-25.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:66509c48f7446b640eeae24b60c9c1461799a27b1b0754e438582e36b5af3315"}, + {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c464cc508177c09a5a6122b67f978f20e2954a21362bf095a0da4647e3e908"}, + {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28bcb2e66224a7ac2843eb632e4109d6b161479e7a2baf24e37210461485b4f1"}, + {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0e7ef9ac807db50b4eb6f534c5dcc22f998f5dae920cc28873d2c1d080a4fc9"}, + {file = "pyzmq-25.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5050f5c50b58a6e38ccaf9263a356f74ef1040f5ca4030225d1cb1a858c5b7b6"}, + {file = "pyzmq-25.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2a73af6504e0d2805e926abf136ebf536735a13c22f709be7113c2ec65b4bec3"}, + {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0e8d00228db627ddd1b418c7afd81820b38575f237128c9650365f2dd6ac3443"}, + {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5605621f2181f20b71f13f698944deb26a0a71af4aaf435b34dd90146092d530"}, + {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6136bfb0e5a9cf8c60c6ac763eb21f82940a77e6758ea53516c8c7074f4ff948"}, + {file = "pyzmq-25.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0a90b2480a26aef7c13cff18703ba8d68e181facb40f78873df79e6d42c1facc"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00c94fd4c9dd3c95aace0c629a7fa713627a5c80c1819326b642adf6c4b8e2a2"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20638121b0bdc80777ce0ec8c1f14f1ffec0697a1f88f0b564fa4a23078791c4"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f75b4b8574f3a8a0d6b4b52606fc75b82cb4391471be48ab0b8677c82f9ed4"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cbb885f347eba7ab7681c450dee5b14aed9f153eec224ec0c3f299273d9241f"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c48f257da280b3be6c94e05bd575eddb1373419dbb1a72c3ce64e88f29d1cd6d"}, + {file = "pyzmq-25.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:866eabf7c1315ef2e93e34230db7cbf672e0d7c626b37c11f7e870c8612c3dcc"}, + {file = "pyzmq-25.0.0.tar.gz", hash = "sha256:f330a1a2c7f89fd4b0aa4dcb7bf50243bf1c8da9a2f1efc31daf57a2046b31f2"}, ] rdflib = [ {file = "rdflib-5.0.0-py3-none-any.whl", hash = "sha256:88208ea971a87886d60ae2b1a4b2cdc263527af0454c422118d43fe64b357877"}, @@ -3324,8 +3431,8 @@ regex = [ {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, ] requests = [ - {file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"}, - {file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"}, + {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, + {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, ] requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, @@ -3375,35 +3482,27 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] scipy = [ - {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, - {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, - {file = "scipy-1.7.3-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094"}, - {file = "scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9"}, - {file = "scipy-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf"}, - {file = "scipy-1.7.3-cp37-cp37m-win32.whl", hash = "sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c"}, - {file = "scipy-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c"}, - {file = "scipy-1.7.3-cp38-cp38-win32.whl", hash = "sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95"}, - {file = "scipy-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12"}, - {file = "scipy-1.7.3-cp39-cp39-win32.whl", hash = "sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9"}, - {file = "scipy-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e"}, - {file = "scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf"}, + {file = "scipy-1.10.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b901b423c91281a974f6cd1c36f5c6c523e665b5a6d5e80fcb2334e14670eefd"}, + {file = "scipy-1.10.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16ba05d3d1b9f2141004f3f36888e05894a525960b07f4c2bfc0456b955a00be"}, + {file = "scipy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:151f066fe7d6653c3ffefd489497b8fa66d7316e3e0d0c0f7ff6acca1b802809"}, + {file = "scipy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f9ea0a37aca111a407cb98aa4e8dfde6e5d9333bae06dfa5d938d14c80bb5c3"}, + {file = "scipy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:27e548276b5a88b51212b61f6dda49a24acf5d770dff940bd372b3f7ced8c6c2"}, + {file = "scipy-1.10.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:42ab8b9e7dc1ebe248e55f54eea5307b6ab15011a7883367af48dd781d1312e4"}, + {file = "scipy-1.10.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e096b062d2efdea57f972d232358cb068413dc54eec4f24158bcbb5cb8bddfd8"}, + {file = "scipy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df25a28bd22c990b22129d3c637fd5c3be4b7c94f975dca909d8bab3309b694"}, + {file = "scipy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ad449db4e0820e4b42baccefc98ec772ad7818dcbc9e28b85aa05a536b0f1a2"}, + {file = "scipy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:6faf86ef7717891195ae0537e48da7524d30bc3b828b30c9b115d04ea42f076f"}, + {file = "scipy-1.10.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:4bd0e3278126bc882d10414436e58fa3f1eca0aa88b534fcbf80ed47e854f46c"}, + {file = "scipy-1.10.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:38bfbd18dcc69eeb589811e77fae552fa923067fdfbb2e171c9eac749885f210"}, + {file = "scipy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ab2a58064836632e2cec31ca197d3695c86b066bc4818052b3f5381bfd2a728"}, + {file = "scipy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd7a30970c29d9768a7164f564d1fbf2842bfc77b7d114a99bc32703ce0bf48"}, + {file = "scipy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:9b878c671655864af59c108c20e4da1e796154bd78c0ed6bb02bc41c84625686"}, + {file = "scipy-1.10.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:3afcbddb4488ac950ce1147e7580178b333a29cd43524c689b2e3543a080a2c8"}, + {file = "scipy-1.10.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:6e4497e5142f325a5423ff5fda2fff5b5d953da028637ff7c704378c8c284ea7"}, + {file = "scipy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:441cab2166607c82e6d7a8683779cb89ba0f475b983c7e4ab88f3668e268c143"}, + {file = "scipy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0490dc499fe23e4be35b8b6dd1e60a4a34f0c4adb30ac671e6332446b3cbbb5a"}, + {file = "scipy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:954ff69d2d1bf666b794c1d7216e0a746c9d9289096a64ab3355a17c7c59db54"}, + {file = "scipy-1.10.0.tar.gz", hash = "sha256:c8b3cbc636a87a89b770c6afc999baa6bcbb01691b5ccbbc1b1791c7c0a07540"}, ] secretstorage = [ {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, @@ -3438,8 +3537,8 @@ sphinx-click = [ {file = "sphinx_click-3.1.0-py3-none-any.whl", hash = "sha256:8fb0b048a577d346d741782e44d041d7e908922858273d99746f305870116121"}, ] sphinxcontrib-applehelp = [ - {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, - {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, + {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, + {file = "sphinxcontrib_applehelp-1.0.4-py3-none-any.whl", hash = "sha256:29d341f67fb0f6f586b23ad80e072c8e6ad0b48417db2bde114a4c9746feb228"}, ] sphinxcontrib-devhelp = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, @@ -3461,6 +3560,10 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] +stack-data = [ + {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, + {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, +] swagger-ui-bundle = [ {file = "swagger_ui_bundle-0.0.9-py3-none-any.whl", hash = "sha256:cea116ed81147c345001027325c1ddc9ca78c1ee7319935c3c75d3669279d575"}, {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"}, @@ -3474,8 +3577,8 @@ tenacity = [ {file = "tenacity-8.1.0.tar.gz", hash = "sha256:e48c437fdf9340f5666b92cd7990e96bc5fc955e1298baf4a907e3972067a445"}, ] terminado = [ - {file = "terminado-0.17.0-py3-none-any.whl", hash = "sha256:bf6fe52accd06d0661d7611cc73202121ec6ee51e46d8185d489ac074ca457c2"}, - {file = "terminado-0.17.0.tar.gz", hash = "sha256:520feaa3aeab8ad64a69ca779be54be9234edb2d0d6567e76c93c2c9a4e6e43f"}, + {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, + {file = "terminado-0.17.1.tar.gz", hash = "sha256:6ccbbcd3a4f8a25a5ec04991f39a0b8db52dfcd487ea0e578d977e6752380333"}, ] testpath = [ {file = "testpath-0.6.0-py3-none-any.whl", hash = "sha256:8ada9f80a2ac6fb0391aa7cdb1a7d11cfa8429f693eda83f74dde570fe6fa639"}, @@ -3507,8 +3610,8 @@ tqdm = [ {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, ] traitlets = [ - {file = "traitlets-5.6.0-py3-none-any.whl", hash = "sha256:1410755385d778aed847d68deb99b3ba30fbbf489e17a1e8cbb753060d5cce73"}, - {file = "traitlets-5.6.0.tar.gz", hash = "sha256:10b6ed1c9cedee83e795db70a8b9c2db157bb3778ec4587a349ecb7ef3b1033b"}, + {file = "traitlets-5.8.1-py3-none-any.whl", hash = "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861"}, + {file = "traitlets-5.8.1.tar.gz", hash = "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b"}, ] typed-ast = [ {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, @@ -3541,8 +3644,8 @@ typing-extensions = [ {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, ] tzdata = [ - {file = "tzdata-2022.6-py2.py3-none-any.whl", hash = "sha256:04a680bdc5b15750c39c12a448885a51134a27ec9af83667663f0b3a1bf3f342"}, - {file = "tzdata-2022.6.tar.gz", hash = "sha256:91f11db4503385928c15598c98573e3af07e7229181bee5375bd30f1695ddcae"}, + {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, + {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, ] tzlocal = [ {file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"}, @@ -3553,12 +3656,12 @@ uritemplate = [ {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"}, ] urllib3 = [ - {file = "urllib3-1.26.13-py2.py3-none-any.whl", hash = "sha256:47cc05d99aaa09c9e72ed5809b60e7ba354e64b59c9c173ac3018642d8bb41fc"}, - {file = "urllib3-1.26.13.tar.gz", hash = "sha256:c083dd0dce68dbfbe1129d5271cb90f9447dea7d52097c6e0126120c521ddea8"}, + {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, + {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, ] wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, + {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, + {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, @@ -3572,13 +3675,9 @@ werkzeug = [ {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, ] -wheel = [ - {file = "wheel-0.38.4-py3-none-any.whl", hash = "sha256:b60533f3f5d530e971d6737ca6d58681ee434818fab630c83a734bb10c083ce8"}, - {file = "wheel-0.38.4.tar.gz", hash = "sha256:965f5259b566725405b05e7cf774052044b1ed30119b5d586b2703aafe8719ac"}, -] widgetsnbextension = [ - {file = "widgetsnbextension-4.0.3-py3-none-any.whl", hash = "sha256:7f3b0de8fda692d31ef03743b598620e31c2668b835edbd3962d080ccecf31eb"}, - {file = "widgetsnbextension-4.0.3.tar.gz", hash = "sha256:34824864c062b0b3030ad78210db5ae6a3960dfb61d5b27562d6631774de0286"}, + {file = "widgetsnbextension-4.0.5-py3-none-any.whl", hash = "sha256:eaaaf434fb9b08bd197b2a14ffe45ddb5ac3897593d43c69287091e5f3147bf7"}, + {file = "widgetsnbextension-4.0.5.tar.gz", hash = "sha256:003f716d930d385be3fd9de42dd9bf008e30053f73bddde235d14fbeaeff19af"}, ] wrapt = [ {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, diff --git a/pyproject.toml b/pyproject.toml index b3289d2c2..41eb59dc4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -35,7 +35,7 @@ schematic = "schematic.__main__:main" [tool.poetry.dependencies] -python = ">=3.7.1,<3.11" +python = ">=3.9.0,<3.11" click = "^7.1.2" click-log = "^0.3.2" From 41148af31980178fb2d6488fafa2c77c72e85c4b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:09:12 -0700 Subject: [PATCH 069/615] update dependencies for schematic-db and add --- poetry.lock | 680 +++++++++++++++++++++++++++++++++++++++---------- pyproject.toml | 15 +- 2 files changed, 556 insertions(+), 139 deletions(-) diff --git a/poetry.lock b/poetry.lock index 23ab3478e..07abff672 100644 --- a/poetry.lock +++ b/poetry.lock @@ -42,14 +42,6 @@ doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] trio = ["trio (>=0.16,<0.22)"] -[[package]] -name = "appdirs" -version = "1.4.4" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = "*" - [[package]] name = "appnope" version = "0.1.3" @@ -89,6 +81,19 @@ cffi = ">=1.0.1" dev = ["cogapp", "pre-commit", "pytest", "wheel"] tests = ["pytest"] +[[package]] +name = "astroid" +version = "2.13.3" +description = "An abstract syntax tree for Python with inference support." +category = "main" +optional = false +python-versions = ">=3.7.2" + +[package.dependencies] +lazy-object-proxy = ">=1.4.0" +typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} +wrapt = {version = ">=1.11,<2", markers = "python_version < \"3.11\""} + [[package]] name = "asttokens" version = "2.2.1" @@ -107,7 +112,7 @@ test = ["astroid", "pytest"] name = "atomicwrites" version = "1.4.1" description = "Atomic file writes." -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" @@ -147,25 +152,25 @@ python-versions = "*" [[package]] name = "black" -version = "20.8b1" +version = "22.12.0" description = "The uncompromising code formatter." -category = "dev" +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -appdirs = "*" -click = ">=7.1.2" +click = ">=8.0.0" mypy-extensions = ">=0.4.3" -pathspec = ">=0.6,<1" -regex = ">=2020.1.8" -toml = ">=0.10.1" -typed-ast = ">=1.4.0" -typing-extensions = ">=3.7.4" +pathspec = ">=0.9.0" +platformdirs = ">=2" +tomli = {version = ">=1.1.0", markers = "python_full_version < \"3.11.0a7\""} +typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.3.2)", "aiohttp-cors"] +d = ["aiohttp (>=3.7.4)"] +jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] +uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "bleach" @@ -219,15 +224,18 @@ python-versions = "*" [[package]] name = "click" -version = "7.1.2" +version = "8.1.3" description = "Composable command line interface toolkit" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} [[package]] name = "click-log" -version = "0.3.2" +version = "0.4.0" description = "Logging integration for Click" category = "main" optional = false @@ -384,6 +392,17 @@ wrapt = ">=1.10,<2" [package.extras] dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +[[package]] +name = "dill" +version = "0.3.6" +description = "serialize all of python" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +graph = ["objgraph (>=1.7.2)"] + [[package]] name = "docutils" version = "0.19" @@ -445,21 +464,21 @@ pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "flask" -version = "1.1.4" +version = "2.1.3" description = "A simple framework for building complex web applications." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -click = ">=5.1,<8.0" -itsdangerous = ">=0.24,<2.0" -Jinja2 = ">=2.10.1,<3.0" -Werkzeug = ">=0.15,<2.0" +click = ">=8.0" +importlib-metadata = {version = ">=3.6.0", markers = "python_version < \"3.10\""} +itsdangerous = ">=2.0" +Jinja2 = ">=3.0" +Werkzeug = ">=2.0" [package.extras] -dev = ["coverage", "pallets-sphinx-themes", "pytest", "sphinx", "sphinx-issues", "sphinxcontrib-log-cabinet", "tox"] -docs = ["pallets-sphinx-themes", "sphinx", "sphinx-issues", "sphinxcontrib-log-cabinet"] +async = ["asgiref (>=3.2)"] dotenv = ["python-dotenv"] [[package]] @@ -656,6 +675,18 @@ test = ["black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstri trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] +[[package]] +name = "greenlet" +version = "2.0.1" +description = "Lightweight in-process concurrent programming" +category = "main" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" + +[package.extras] +docs = ["Sphinx", "docutils (<0.18)"] +test = ["faulthandler", "objgraph", "psutil"] + [[package]] name = "httplib2" version = "0.21.0" @@ -711,7 +742,7 @@ python-versions = ">=3.5" name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -816,13 +847,27 @@ python-versions = "*" [package.dependencies] six = "*" +[[package]] +name = "isort" +version = "5.11.4" +description = "A Python utility / library to sort Python imports." +category = "main" +optional = false +python-versions = ">=3.7.0" + +[package.extras] +colors = ["colorama (>=0.4.3,<0.5.0)"] +pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +plugins = ["setuptools"] +requirements-deprecated-finder = ["pip-api", "pipreqs"] + [[package]] name = "itsdangerous" -version = "1.1.0" -description = "Various helpers to pass data to untrusted environments and back." +version = "2.1.2" +description = "Safely pass data to untrusted environments and back." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.7" [[package]] name = "jedi" @@ -854,17 +899,17 @@ trio = ["async_generator", "trio"] [[package]] name = "jinja2" -version = "2.11.3" +version = "3.1.2" description = "A very fast and expressive template engine." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] -MarkupSafe = ">=0.23" +MarkupSafe = ">=2.0" [package.extras] -i18n = ["Babel (>=0.8)"] +i18n = ["Babel (>=2.7)"] [[package]] name = "jsonpatch" @@ -1011,6 +1056,14 @@ six = "*" docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] +[[package]] +name = "lazy-object-proxy" +version = "1.9.0" +description = "A fast and thorough lazy object proxy." +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "makefun" version = "1.15.0" @@ -1059,7 +1112,7 @@ traitlets = "*" name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" -category = "dev" +category = "main" optional = false python-versions = "*" @@ -1071,14 +1124,40 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "mypy" +version = "0.982" +description = "Optional static typing for Python" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +mypy-extensions = ">=0.4.3" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + [[package]] name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" +category = "main" optional = false python-versions = "*" +[[package]] +name = "mysqlclient" +version = "2.1.1" +description = "Python interface to MySQL" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "nbclassic" version = "0.4.8" @@ -1323,7 +1402,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.10.3" description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -1378,7 +1457,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest- name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -1427,6 +1506,14 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] +[[package]] +name = "psycopg2" +version = "2.9.5" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "ptyprocess" version = "0.7.0" @@ -1450,7 +1537,7 @@ tests = ["pytest"] name = "py" version = "1.11.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "dev" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" @@ -1538,6 +1625,29 @@ google-auth-oauthlib = "*" [package.extras] pandas = ["pandas (>=0.14.0)"] +[[package]] +name = "pylint" +version = "2.15.10" +description = "python code static checker" +category = "main" +optional = false +python-versions = ">=3.7.2" + +[package.dependencies] +astroid = ">=2.12.13,<=2.14.0-dev0" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +dill = {version = ">=0.2", markers = "python_version < \"3.11\""} +isort = ">=4.2.5,<6" +mccabe = ">=0.6,<0.8" +platformdirs = ">=2.2.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +tomlkit = ">=0.10.1" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +spelling = ["pyenchant (>=3.2,<4.0)"] +testutils = ["gitpython (>3)"] + [[package]] name = "pyparsing" version = "3.0.9" @@ -1561,7 +1671,7 @@ python-versions = ">=3.7" name = "pytest" version = "6.2.5" description = "pytest: simple powerful testing with Python" -category = "dev" +category = "main" optional = false python-versions = ">=3.6" @@ -1598,7 +1708,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.10.0" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -1675,11 +1785,11 @@ python-versions = ">=3.7" [[package]] name = "pyyaml" -version = "5.4.1" +version = "6.0" description = "YAML parser and emitter for Python" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +python-versions = ">=3.6" [[package]] name = "pyzmq" @@ -1786,6 +1896,31 @@ category = "main" optional = false python-versions = ">=3.5" +[[package]] +name = "schematic-db" +version = "0.0.4" +description = "" +category = "main" +optional = false +python-versions = ">=3.9,<4.0" + +[package.dependencies] +black = ">=22.6.0,<23.0.0" +mypy = ">=0.982,<0.983" +mysqlclient = ">=2.1.1,<3.0.0" +networkx = ">=2.8.6,<3.0.0" +pandas = ">=1.4.3,<2.0.0" +pdoc = ">=12.1.0,<13.0.0" +psycopg2 = ">=2.9.5,<3.0.0" +pylint = ">=2.15.4,<3.0.0" +pytest-mock = ">=3.10.0,<4.0.0" +PyYAML = ">=6.0,<7.0" +requests = ">=2.28.1,<3.0.0" +SQLAlchemy = ">=1.4.39,<2.0.0" +SQLAlchemy-Utils = ">=0.38.3,<0.39.0" +synapseclient = ">=2.6.0,<3.0.0" +tenacity = ">=8.1.0,<9.0.0" + [[package]] name = "scipy" version = "1.10.0" @@ -1981,6 +2116,63 @@ python-versions = ">=3.5" lint = ["docutils-stubs", "flake8", "mypy"] test = ["pytest"] +[[package]] +name = "sqlalchemy" +version = "1.4.46" +description = "Database Abstraction Library" +category = "main" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (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\")"} + +[package.extras] +aiomysql = ["aiomysql", "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)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] +mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +pymysql = ["pymysql", "pymysql (<1)"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sqlalchemy-utils" +version = "0.38.3" +description = "Various utility functions for SQLAlchemy." +category = "main" +optional = false +python-versions = "~=3.6" + +[package.dependencies] +SQLAlchemy = ">=1.3" + +[package.extras] +arrow = ["arrow (>=0.3.4)"] +babel = ["Babel (>=1.3)"] +color = ["colour (>=0.0.4)"] +encrypted = ["cryptography (>=0.6)"] +intervals = ["intervals (>=0.7.1)"] +password = ["passlib (>=1.6,<2.0)"] +pendulum = ["pendulum (>=2.0.5)"] +phone = ["phonenumbers (>=5.9.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +timezone = ["python-dateutil"] +url = ["furl (>=0.4.1)"] + [[package]] name = "stack-data" version = "0.6.2" @@ -2076,6 +2268,22 @@ category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +category = "main" +optional = false +python-versions = ">=3.7" + +[[package]] +name = "tomlkit" +version = "0.11.6" +description = "Style preserving TOML library" +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "toolz" version = "0.12.0" @@ -2121,14 +2329,6 @@ python-versions = ">=3.7" docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] -[[package]] -name = "typed-ast" -version = "1.5.4" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" -optional = false -python-versions = ">=3.6" - [[package]] name = "typing-extensions" version = "4.4.0" @@ -2213,14 +2413,13 @@ test = ["websockets"] [[package]] name = "werkzeug" -version = "1.0.1" +version = "2.1.2" description = "The comprehensive WSGI web application library." category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.extras] -dev = ["coverage", "pallets-sphinx-themes", "pytest", "pytest-timeout", "sphinx", "sphinx-issues", "tox"] watchdog = ["watchdog"] [[package]] @@ -2254,7 +2453,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "07e5b9f29e35366d3bb1402137bf8b98a7e0a5a1fdcf26856a0b1c675535b876" +content-hash = "cf52bf7f954db2bd6f4e2e1b29cd16b2f1dd136306c86de68b741080e3cbceae" [metadata.files] alabaster = [ @@ -2269,10 +2468,6 @@ anyio = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, ] -appdirs = [ - {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, -] appnope = [ {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, {file = "appnope-0.1.3.tar.gz", hash = "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24"}, @@ -2304,6 +2499,10 @@ argon2-cffi-bindings = [ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, ] +astroid = [ + {file = "astroid-2.13.3-py3-none-any.whl", hash = "sha256:14c1603c41cc61aae731cad1884a073c4645e26f126d13ac8346113c95577f3b"}, + {file = "astroid-2.13.3.tar.gz", hash = "sha256:6afc22718a48a689ca24a97981ad377ba7fb78c133f40335dfd16772f29bcfb1"}, +] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, @@ -2324,7 +2523,18 @@ backcall = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] black = [ - {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, + {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, + {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, + {file = "black-22.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d30b212bffeb1e252b31dd269dfae69dd17e06d92b87ad26e23890f3efea366f"}, + {file = "black-22.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:7412e75863aa5c5411886804678b7d083c7c28421210180d67dfd8cf1221e1f4"}, + {file = "black-22.12.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c116eed0efb9ff870ded8b62fe9f28dd61ef6e9ddd28d83d7d264a38417dcee2"}, + {file = "black-22.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1f58cbe16dfe8c12b7434e50ff889fa479072096d79f0a7f25e4ab8e94cd8350"}, + {file = "black-22.12.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77d86c9f3db9b1bf6761244bc0b3572a546f5fe37917a044e02f3166d5aafa7d"}, + {file = "black-22.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:82d9fe8fee3401e02e79767016b4907820a7dc28d70d137eb397b92ef3cc5bfc"}, + {file = "black-22.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:101c69b23df9b44247bd88e1d7e90154336ac4992502d4197bdac35dd7ee3320"}, + {file = "black-22.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:559c7a1ba9a006226f09e4916060982fd27334ae1998e7a38b3f33a37f7a2148"}, + {file = "black-22.12.0-py3-none-any.whl", hash = "sha256:436cc9167dd28040ad90d3b404aec22cedf24a6e4d7de221bec2730ec0c97bcf"}, + {file = "black-22.12.0.tar.gz", hash = "sha256:229351e5a18ca30f447bf724d007f890f97e13af070bb6ad4c0a441cd7596a2f"}, ] bleach = [ {file = "bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, @@ -2495,12 +2705,12 @@ charset-normalizer = [ {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, ] click = [ - {file = "click-7.1.2-py2.py3-none-any.whl", hash = "sha256:dacca89f4bfadd5de3d7489b7c8a566eee0d3676333fbb50030263894c38c0dc"}, - {file = "click-7.1.2.tar.gz", hash = "sha256:d2b5255c7c6349bc1bd1e59e08cd12acbbd63ce649f2588755783aa94dfb6b1a"}, + {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, + {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, ] click-log = [ - {file = "click-log-0.3.2.tar.gz", hash = "sha256:16fd1ca3fc6b16c98cea63acf1ab474ea8e676849dc669d86afafb0ed7003124"}, - {file = "click_log-0.3.2-py2.py3-none-any.whl", hash = "sha256:eee14dc37cdf3072158570f00406572f9e03e414accdccfccd4c538df9ae322c"}, + {file = "click-log-0.4.0.tar.gz", hash = "sha256:3970f8570ac54491237bcdb3d8ab5e3eef6c057df29f8c3d1151a51a9c23b975"}, + {file = "click_log-0.4.0-py2.py3-none-any.whl", hash = "sha256:a43e394b528d52112af599f2fc9e4b7cf3c15f94e53581f74fa6867e68c91756"}, ] clickclick = [ {file = "clickclick-20.10.2-py2.py3-none-any.whl", hash = "sha256:c8f33e6d9ec83f68416dd2136a7950125bd256ec39ccc9a85c6e280a16be2bb5"}, @@ -2632,6 +2842,10 @@ deprecated = [ {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, ] +dill = [ + {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, + {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, +] docutils = [ {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, @@ -2657,8 +2871,8 @@ flake8 = [ {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, ] flask = [ - {file = "Flask-1.1.4-py2.py3-none-any.whl", hash = "sha256:c34f04500f2cbbea882b1acb02002ad6fe6b7ffa64a6164577995657f50aed22"}, - {file = "Flask-1.1.4.tar.gz", hash = "sha256:0fbeb6180d383a9186d0d6ed954e0042ad9f18e0e8de088b2b419d526927d196"}, + {file = "Flask-2.1.3-py3-none-any.whl", hash = "sha256:9013281a7402ad527f8fd56375164f3aa021ecfaff89bfe3825346c24f87e04c"}, + {file = "Flask-2.1.3.tar.gz", hash = "sha256:15972e5017df0575c3d6c090ba168b6db90259e620ac8d7ea813a396bad5b6cb"}, ] flask-cors = [ {file = "Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"}, @@ -2696,6 +2910,68 @@ great-expectations = [ {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, {file = "great_expectations-0.15.44.tar.gz", hash = "sha256:547a3f252cfc41124b299b226399b1169b01e127e717f97ee5dd16e34d0e2a64"}, ] +greenlet = [ + {file = "greenlet-2.0.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c"}, + {file = "greenlet-2.0.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4f09b0010e55bec3239278f642a8a506b91034f03a4fb28289a7d448a67f1515"}, + {file = "greenlet-2.0.1-cp27-cp27m-win32.whl", hash = "sha256:1407fe45246632d0ffb7a3f4a520ba4e6051fc2cbd61ba1f806900c27f47706a"}, + {file = "greenlet-2.0.1-cp27-cp27m-win_amd64.whl", hash = "sha256:3001d00eba6bbf084ae60ec7f4bb8ed375748f53aeaefaf2a37d9f0370558524"}, + {file = "greenlet-2.0.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d566b82e92ff2e09dd6342df7e0eb4ff6275a3f08db284888dcd98134dbd4243"}, + {file = "greenlet-2.0.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0722c9be0797f544a3ed212569ca3fe3d9d1a1b13942d10dd6f0e8601e484d26"}, + {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d37990425b4687ade27810e3b1a1c37825d242ebc275066cfee8cb6b8829ccd"}, + {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be35822f35f99dcc48152c9839d0171a06186f2d71ef76dc57fa556cc9bf6b45"}, + {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c140e7eb5ce47249668056edf3b7e9900c6a2e22fb0eaf0513f18a1b2c14e1da"}, + {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d21681f09e297a5adaa73060737e3aa1279a13ecdcfcc6ef66c292cb25125b2d"}, + {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb412b7db83fe56847df9c47b6fe3f13911b06339c2aa02dcc09dce8bbf582cd"}, + {file = "greenlet-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6a08799e9e88052221adca55741bf106ec7ea0710bca635c208b751f0d5b617"}, + {file = "greenlet-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e112e03d37987d7b90c1e98ba5e1b59e1645226d78d73282f45b326f7bddcb9"}, + {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56961cfca7da2fdd178f95ca407fa330c64f33289e1804b592a77d5593d9bd94"}, + {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13ba6e8e326e2116c954074c994da14954982ba2795aebb881c07ac5d093a58a"}, + {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bf633a50cc93ed17e494015897361010fc08700d92676c87931d3ea464123ce"}, + {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9f2c221eecb7ead00b8e3ddb913c67f75cba078fd1d326053225a3f59d850d72"}, + {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:13ebf93c343dd8bd010cd98e617cb4c1c1f352a0cf2524c82d3814154116aa82"}, + {file = "greenlet-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:6f61d71bbc9b4a3de768371b210d906726535d6ca43506737682caa754b956cd"}, + {file = "greenlet-2.0.1-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:2d0bac0385d2b43a7bd1d651621a4e0f1380abc63d6fb1012213a401cbd5bf8f"}, + {file = "greenlet-2.0.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:f6327b6907b4cb72f650a5b7b1be23a2aab395017aa6f1adb13069d66360eb3f"}, + {file = "greenlet-2.0.1-cp35-cp35m-win32.whl", hash = "sha256:81b0ea3715bf6a848d6f7149d25bf018fd24554a4be01fcbbe3fdc78e890b955"}, + {file = "greenlet-2.0.1-cp35-cp35m-win_amd64.whl", hash = "sha256:38255a3f1e8942573b067510f9611fc9e38196077b0c8eb7a8c795e105f9ce77"}, + {file = "greenlet-2.0.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:04957dc96669be041e0c260964cfef4c77287f07c40452e61abe19d647505581"}, + {file = "greenlet-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:4aeaebcd91d9fee9aa768c1b39cb12214b30bf36d2b7370505a9f2165fedd8d9"}, + {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974a39bdb8c90a85982cdb78a103a32e0b1be986d411303064b28a80611f6e51"}, + {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dca09dedf1bd8684767bc736cc20c97c29bc0c04c413e3276e0962cd7aeb148"}, + {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c0757db9bd08470ff8277791795e70d0bf035a011a528ee9a5ce9454b6cba2"}, + {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5067920de254f1a2dee8d3d9d7e4e03718e8fd2d2d9db962c8c9fa781ae82a39"}, + {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5a8e05057fab2a365c81abc696cb753da7549d20266e8511eb6c9d9f72fe3e92"}, + {file = "greenlet-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:3d75b8d013086b08e801fbbb896f7d5c9e6ccd44f13a9241d2bf7c0df9eda928"}, + {file = "greenlet-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:097e3dae69321e9100202fc62977f687454cd0ea147d0fd5a766e57450c569fd"}, + {file = "greenlet-2.0.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:cb242fc2cda5a307a7698c93173d3627a2a90d00507bccf5bc228851e8304963"}, + {file = "greenlet-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:72b00a8e7c25dcea5946692a2485b1a0c0661ed93ecfedfa9b6687bd89a24ef5"}, + {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce"}, + {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000"}, + {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2"}, + {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9"}, + {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1"}, + {file = "greenlet-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1"}, + {file = "greenlet-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23"}, + {file = "greenlet-2.0.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:cd4ccc364cf75d1422e66e247e52a93da6a9b73cefa8cad696f3cbbb75af179d"}, + {file = "greenlet-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c8b1c43e75c42a6cafcc71defa9e01ead39ae80bd733a2608b297412beede68"}, + {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e"}, + {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48"}, + {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764"}, + {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0"}, + {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9"}, + {file = "greenlet-2.0.1-cp38-cp38-win32.whl", hash = "sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608"}, + {file = "greenlet-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6"}, + {file = "greenlet-2.0.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b1992ba9d4780d9af9726bbcef6a1db12d9ab1ccc35e5773685a24b7fb2758eb"}, + {file = "greenlet-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:b5e83e4de81dcc9425598d9469a624826a0b1211380ac444c7c791d4a2137c19"}, + {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5"}, + {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7"}, + {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d"}, + {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726"}, + {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e"}, + {file = "greenlet-2.0.1-cp39-cp39-win32.whl", hash = "sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a"}, + {file = "greenlet-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6"}, + {file = "greenlet-2.0.1.tar.gz", hash = "sha256:42e602564460da0e8ee67cb6d7236363ee5e131aa15943b6670e44e5c2ed0f67"}, +] httplib2 = [ {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, {file = "httplib2-0.21.0.tar.gz", hash = "sha256:fc144f091c7286b82bec71bdbd9b27323ba709cc612568d3000893bfd9cb4b34"}, @@ -2740,9 +3016,13 @@ isodate = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, ] +isort = [ + {file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"}, + {file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"}, +] itsdangerous = [ - {file = "itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, - {file = "itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, + {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {file = "itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, ] jedi = [ {file = "jedi-0.18.2-py2.py3-none-any.whl", hash = "sha256:203c1fd9d969ab8f2119ec0a3342e0b49910045abe6af0a3ae83a5764d54639e"}, @@ -2753,8 +3033,8 @@ jeepney = [ {file = "jeepney-0.8.0.tar.gz", hash = "sha256:5efe48d255973902f6badc3ce55e2aa6c5c3b3bc642059ef3a91247bcfcc5806"}, ] jinja2 = [ - {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, - {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, + {file = "Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, + {file = "Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, ] jsonpatch = [ {file = "jsonpatch-1.32-py2.py3-none-any.whl", hash = "sha256:26ac385719ac9f54df8a2f0827bb8253aa3ea8ab7b3368457bcdb8c14595a397"}, @@ -2792,6 +3072,44 @@ keyrings-alt = [ {file = "keyrings.alt-3.1-py2.py3-none-any.whl", hash = "sha256:6a00fa799baf1385cf9620bd01bcc815aa56e6970342a567bcfea0c4d21abe5f"}, {file = "keyrings.alt-3.1.tar.gz", hash = "sha256:b59c86b67b9027a86e841a49efc41025bcc3b1b0308629617b66b7011e52db5a"}, ] +lazy-object-proxy = [ + {file = "lazy-object-proxy-1.9.0.tar.gz", hash = "sha256:659fb5809fa4629b8a1ac5106f669cfc7bef26fbb389dda53b3e010d1ac4ebae"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b40387277b0ed2d0602b8293b94d7257e17d1479e257b4de114ea11a8cb7f2d7"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8c6cfb338b133fbdbc5cfaa10fe3c6aeea827db80c978dbd13bc9dd8526b7d4"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:721532711daa7db0d8b779b0bb0318fa87af1c10d7fe5e52ef30f8eff254d0cd"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:66a3de4a3ec06cd8af3f61b8e1ec67614fbb7c995d02fa224813cb7afefee701"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa3de4088c89a1b69f8ec0dcc169aa725b0ff017899ac568fe44ddc1396df46"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win32.whl", hash = "sha256:f0705c376533ed2a9e5e97aacdbfe04cecd71e0aa84c7c0595d02ef93b6e4455"}, + {file = "lazy_object_proxy-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:ea806fd4c37bf7e7ad82537b0757999264d5f70c45468447bb2b91afdbe73a6e"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:946d27deaff6cf8452ed0dba83ba38839a87f4f7a9732e8f9fd4107b21e6ff07"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79a31b086e7e68b24b99b23d57723ef7e2c6d81ed21007b6281ebcd1688acb0a"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f699ac1c768270c9e384e4cbd268d6e67aebcfae6cd623b4d7c3bfde5a35db59"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bfb38f9ffb53b942f2b5954e0f610f1e721ccebe9cce9025a38c8ccf4a5183a4"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:189bbd5d41ae7a498397287c408617fe5c48633e7755287b21d741f7db2706a9"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win32.whl", hash = "sha256:81fc4d08b062b535d95c9ea70dbe8a335c45c04029878e62d744bdced5141586"}, + {file = "lazy_object_proxy-1.9.0-cp311-cp311-win_amd64.whl", hash = "sha256:f2457189d8257dd41ae9b434ba33298aec198e30adf2dcdaaa3a28b9994f6adb"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9e25ef10a39e8afe59a5c348a4dbf29b4868ab76269f81ce1674494e2565a6e"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cbf9b082426036e19c6924a9ce90c740a9861e2bdc27a4834fd0a910742ac1e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f5fa4a61ce2438267163891961cfd5e32ec97a2c444e5b842d574251ade27d2"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8fa02eaab317b1e9e03f69aab1f91e120e7899b392c4fc19807a8278a07a97e8"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7c21c95cae3c05c14aafffe2865bbd5e377cfc1348c4f7751d9dc9a48ca4bda"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win32.whl", hash = "sha256:f12ad7126ae0c98d601a7ee504c1122bcef553d1d5e0c3bfa77b16b3968d2734"}, + {file = "lazy_object_proxy-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:edd20c5a55acb67c7ed471fa2b5fb66cb17f61430b7a6b9c3b4a1e40293b1671"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2d0daa332786cf3bb49e10dc6a17a52f6a8f9601b4cf5c295a4f85854d61de63"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cd077f3d04a58e83d04b20e334f678c2b0ff9879b9375ed107d5d07ff160171"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:660c94ea760b3ce47d1855a30984c78327500493d396eac4dfd8bd82041b22be"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212774e4dfa851e74d393a2370871e174d7ff0ebc980907723bb67d25c8a7c30"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f0117049dd1d5635bbff65444496c90e0baa48ea405125c088e93d9cf4525b11"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win32.whl", hash = "sha256:0a891e4e41b54fd5b8313b96399f8b0e173bbbfc03c7631f01efbe29bb0bcf82"}, + {file = "lazy_object_proxy-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:9990d8e71b9f6488e91ad25f322898c136b008d87bf852ff65391b004da5e17b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9e7551208b2aded9c1447453ee366f1c4070602b3d932ace044715d89666899b"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f83ac4d83ef0ab017683d715ed356e30dd48a93746309c8f3517e1287523ef4"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7322c3d6f1766d4ef1e51a465f47955f1e8123caee67dd641e67d539a534d006"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:18b78ec83edbbeb69efdc0e9c1cb41a3b1b1ed11ddd8ded602464c3fc6020494"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:09763491ce220c0299688940f8dc2c5d05fd1f45af1e42e636b2e8b2303e4382"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win32.whl", hash = "sha256:9090d8e53235aa280fc9239a86ae3ea8ac58eff66a705fa6aa2ec4968b95c821"}, + {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, +] makefun = [ {file = "makefun-1.15.0-py2.py3-none-any.whl", hash = "sha256:d79319f9e71b6825ca163be0afa45cbc5b1215e682efa35b2d355a03c594279c"}, {file = "makefun-1.15.0.tar.gz", hash = "sha256:5b110e733d94f7a49d8ac27b1e2d40f2bb0501e98c1d825e0d932d26920dd5df"}, @@ -2883,10 +3201,45 @@ mistune = [ {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, ] +mypy = [ + {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, + {file = "mypy-0.982-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:41fd1cf9bc0e1c19b9af13a6580ccb66c381a5ee2cf63ee5ebab747a4badeba3"}, + {file = "mypy-0.982-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f793e3dd95e166b66d50e7b63e69e58e88643d80a3dcc3bcd81368e0478b089c"}, + {file = "mypy-0.982-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86ebe67adf4d021b28c3f547da6aa2cce660b57f0432617af2cca932d4d378a6"}, + {file = "mypy-0.982-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:175f292f649a3af7082fe36620369ffc4661a71005aa9f8297ea473df5772046"}, + {file = "mypy-0.982-cp310-cp310-win_amd64.whl", hash = "sha256:8ee8c2472e96beb1045e9081de8e92f295b89ac10c4109afdf3a23ad6e644f3e"}, + {file = "mypy-0.982-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58f27ebafe726a8e5ccb58d896451dd9a662a511a3188ff6a8a6a919142ecc20"}, + {file = "mypy-0.982-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d6af646bd46f10d53834a8e8983e130e47d8ab2d4b7a97363e35b24e1d588947"}, + {file = "mypy-0.982-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:e7aeaa763c7ab86d5b66ff27f68493d672e44c8099af636d433a7f3fa5596d40"}, + {file = "mypy-0.982-cp37-cp37m-win_amd64.whl", hash = "sha256:724d36be56444f569c20a629d1d4ee0cb0ad666078d59bb84f8f887952511ca1"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:14d53cdd4cf93765aa747a7399f0961a365bcddf7855d9cef6306fa41de01c24"}, + {file = "mypy-0.982-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:26ae64555d480ad4b32a267d10cab7aec92ff44de35a7cd95b2b7cb8e64ebe3e"}, + {file = "mypy-0.982-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6389af3e204975d6658de4fb8ac16f58c14e1bacc6142fee86d1b5b26aa52bda"}, + {file = "mypy-0.982-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b35ce03a289480d6544aac85fa3674f493f323d80ea7226410ed065cd46f206"}, + {file = "mypy-0.982-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c6e564f035d25c99fd2b863e13049744d96bd1947e3d3d2f16f5828864506763"}, + {file = "mypy-0.982-cp38-cp38-win_amd64.whl", hash = "sha256:cebca7fd333f90b61b3ef7f217ff75ce2e287482206ef4a8b18f32b49927b1a2"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a705a93670c8b74769496280d2fe6cd59961506c64f329bb179970ff1d24f9f8"}, + {file = "mypy-0.982-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:75838c649290d83a2b83a88288c1eb60fe7a05b36d46cbea9d22efc790002146"}, + {file = "mypy-0.982-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:91781eff1f3f2607519c8b0e8518aad8498af1419e8442d5d0afb108059881fc"}, + {file = "mypy-0.982-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eaa97b9ddd1dd9901a22a879491dbb951b5dec75c3b90032e2baa7336777363b"}, + {file = "mypy-0.982-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a692a8e7d07abe5f4b2dd32d731812a0175626a90a223d4b58f10f458747dd8a"}, + {file = "mypy-0.982-cp39-cp39-win_amd64.whl", hash = "sha256:eb7a068e503be3543c4bd329c994103874fa543c1727ba5288393c21d912d795"}, + {file = "mypy-0.982-py3-none-any.whl", hash = "sha256:1021c241e8b6e1ca5a47e4d52601274ac078a89845cfde66c6d5f769819ffa1d"}, + {file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"}, +] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] +mysqlclient = [ + {file = "mysqlclient-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c1ed71bd6244993b526113cca3df66428609f90e4652f37eb51c33496d478b37"}, + {file = "mysqlclient-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:c812b67e90082a840efb82a8978369e6e69fc62ce1bda4ca8f3084a9d862308b"}, + {file = "mysqlclient-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:0d1cd3a5a4d28c222fa199002810e8146cffd821410b67851af4cc80aeccd97c"}, + {file = "mysqlclient-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b355c8b5a7d58f2e909acdbb050858390ee1b0e13672ae759e5e784110022994"}, + {file = "mysqlclient-2.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:996924f3483fd36a34a5812210c69e71dea5a3d5978d01199b78b7f6d485c855"}, + {file = "mysqlclient-2.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:dea88c8d3f5a5d9293dfe7f087c16dd350ceb175f2f6631c9cf4caf3e19b7a96"}, + {file = "mysqlclient-2.1.1.tar.gz", hash = "sha256:828757e419fb11dd6c5ed2576ec92c3efaa93a0f7c39e263586d1ee779c3d782"}, +] nbclassic = [ {file = "nbclassic-0.4.8-py3-none-any.whl", hash = "sha256:cbf05df5842b420d5cece0143462380ea9d308ff57c2dc0eb4d6e035b18fbfb3"}, {file = "nbclassic-0.4.8.tar.gz", hash = "sha256:c74d8a500f8e058d46b576a41e5bc640711e1032cf7541dde5f73ea49497e283"}, @@ -3059,6 +3412,21 @@ psutil = [ {file = "psutil-5.9.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e"}, {file = "psutil-5.9.4.tar.gz", hash = "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62"}, ] +psycopg2 = [ + {file = "psycopg2-2.9.5-cp310-cp310-win32.whl", hash = "sha256:d3ef67e630b0de0779c42912fe2cbae3805ebaba30cda27fea2a3de650a9414f"}, + {file = "psycopg2-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:4cb9936316d88bfab614666eb9e32995e794ed0f8f6b3b718666c22819c1d7ee"}, + {file = "psycopg2-2.9.5-cp311-cp311-win32.whl", hash = "sha256:093e3894d2d3c592ab0945d9eba9d139c139664dcf83a1c440b8a7aa9bb21955"}, + {file = "psycopg2-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:920bf418000dd17669d2904472efeab2b20546efd0548139618f8fa305d1d7ad"}, + {file = "psycopg2-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:b9ac1b0d8ecc49e05e4e182694f418d27f3aedcfca854ebd6c05bb1cffa10d6d"}, + {file = "psycopg2-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:fc04dd5189b90d825509caa510f20d1d504761e78b8dfb95a0ede180f71d50e5"}, + {file = "psycopg2-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:922cc5f0b98a5f2b1ff481f5551b95cd04580fd6f0c72d9b22e6c0145a4840e0"}, + {file = "psycopg2-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a"}, + {file = "psycopg2-2.9.5-cp38-cp38-win32.whl", hash = "sha256:f5b6320dbc3cf6cfb9f25308286f9f7ab464e65cfb105b64cc9c52831748ced2"}, + {file = "psycopg2-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e"}, + {file = "psycopg2-2.9.5-cp39-cp39-win32.whl", hash = "sha256:322fd5fca0b1113677089d4ebd5222c964b1760e361f151cbb2706c4912112c5"}, + {file = "psycopg2-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:190d51e8c1b25a47484e52a79638a8182451d6f6dff99f26ad9bd81e5359a0fa"}, + {file = "psycopg2-2.9.5.tar.gz", hash = "sha256:a5246d2e683a972e2187a8714b5c2cf8156c064629f9a9b1a873c1730d9e245a"}, +] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -3137,6 +3505,10 @@ pygsheets = [ {file = "pygsheets-2.0.5-py2.py3-none-any.whl", hash = "sha256:85a4c871ac1d53013e042c13552b07f908b991c3d8c8770b3a68eb3452c8c218"}, {file = "pygsheets-2.0.5.tar.gz", hash = "sha256:ea6ce75dabd1359e49fd36920ff0d25ff9428ccc3d5d2474bdba80fb8653ad80"}, ] +pylint = [ + {file = "pylint-2.15.10-py3-none-any.whl", hash = "sha256:9df0d07e8948a1c3ffa3b6e2d7e6e63d9fb457c5da5b961ed63106594780cc7e"}, + {file = "pylint-2.15.10.tar.gz", hash = "sha256:b3dc5ef7d33858f297ac0d06cc73862f01e4f2e74025ec3eff347ce0bc60baf5"}, +] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, @@ -3227,35 +3599,46 @@ pywinpty = [ {file = "pywinpty-2.0.10.tar.gz", hash = "sha256:cdbb5694cf8c7242c2ecfaca35c545d31fa5d5814c3d67a4e628f803f680ebea"}, ] pyyaml = [ - {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, - {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, - {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, - {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, - {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, - {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, - {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, - {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, - {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, - {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, - {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, - {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, - {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, - {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, - {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, - {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, - {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, + {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] pyzmq = [ {file = "pyzmq-25.0.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:2d05d904f03ddf1e0d83d97341354dfe52244a619b5a1440a5f47a5b3451e84e"}, @@ -3481,6 +3864,10 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:184faeaec61dbaa3cace407cffc5819f7b977e75360e8d5ca19461cd851a5fc5"}, {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] +schematic-db = [ + {file = "schematic_db-0.0.4-py3-none-any.whl", hash = "sha256:ace33e59dec49acdc5749b5a8f1254087344e04676042ccdc5cd07253009bcf7"}, + {file = "schematic_db-0.0.4.tar.gz", hash = "sha256:d0da4fc36dafe40040abcb27482b170776d03b406e5e31686ebd127b00032293"}, +] scipy = [ {file = "scipy-1.10.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b901b423c91281a974f6cd1c36f5c6c523e665b5a6d5e80fcb2334e14670eefd"}, {file = "scipy-1.10.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16ba05d3d1b9f2141004f3f36888e05894a525960b07f4c2bfc0456b955a00be"}, @@ -3560,6 +3947,53 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] +sqlalchemy = [ + {file = "SQLAlchemy-1.4.46-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:7001f16a9a8e06488c3c7154827c48455d1c1507d7228d43e781afbc8ceccf6d"}, + {file = "SQLAlchemy-1.4.46-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c7a46639ba058d320c9f53a81db38119a74b8a7a1884df44d09fbe807d028aaf"}, + {file = "SQLAlchemy-1.4.46-cp27-cp27m-win32.whl", hash = "sha256:c04144a24103135ea0315d459431ac196fe96f55d3213bfd6d39d0247775c854"}, + {file = "SQLAlchemy-1.4.46-cp27-cp27m-win_amd64.whl", hash = "sha256:7b81b1030c42b003fc10ddd17825571603117f848814a344d305262d370e7c34"}, + {file = "SQLAlchemy-1.4.46-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:939f9a018d2ad04036746e15d119c0428b1e557470361aa798e6e7d7f5875be0"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b7f4b6aa6e87991ec7ce0e769689a977776db6704947e562102431474799a857"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf17ac9a61e7a3f1c7ca47237aac93cabd7f08ad92ac5b96d6f8dea4287fc1"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7f8267682eb41a0584cf66d8a697fef64b53281d01c93a503e1344197f2e01fe"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cb0ad8a190bc22d2112001cfecdec45baffdf41871de777239da6a28ed74b6"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-win32.whl", hash = "sha256:5f752676fc126edc1c4af0ec2e4d2adca48ddfae5de46bb40adbd3f903eb2120"}, + {file = "SQLAlchemy-1.4.46-cp310-cp310-win_amd64.whl", hash = "sha256:31de1e2c45e67a5ec1ecca6ec26aefc299dd5151e355eb5199cd9516b57340be"}, + {file = "SQLAlchemy-1.4.46-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d68e1762997bfebf9e5cf2a9fd0bcf9ca2fdd8136ce7b24bbd3bbfa4328f3e4a"}, + {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d112b0f3c1bc5ff70554a97344625ef621c1bfe02a73c5d97cac91f8cd7a41e"}, + {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69fac0a7054d86b997af12dc23f581cf0b25fb1c7d1fed43257dee3af32d3d6d"}, + {file = "SQLAlchemy-1.4.46-cp311-cp311-win32.whl", hash = "sha256:887865924c3d6e9a473dc82b70977395301533b3030d0f020c38fd9eba5419f2"}, + {file = "SQLAlchemy-1.4.46-cp311-cp311-win_amd64.whl", hash = "sha256:984ee13543a346324319a1fb72b698e521506f6f22dc37d7752a329e9cd00a32"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:9167d4227b56591a4cc5524f1b79ccd7ea994f36e4c648ab42ca995d28ebbb96"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d61e9ecc849d8d44d7f80894ecff4abe347136e9d926560b818f6243409f3c86"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3ec187acf85984263299a3f15c34a6c0671f83565d86d10f43ace49881a82718"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9883f5fae4fd8e3f875adc2add69f8b945625811689a6c65866a35ee9c0aea23"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-win32.whl", hash = "sha256:535377e9b10aff5a045e3d9ada8a62d02058b422c0504ebdcf07930599890eb0"}, + {file = "SQLAlchemy-1.4.46-cp36-cp36m-win_amd64.whl", hash = "sha256:18cafdb27834fa03569d29f571df7115812a0e59fd6a3a03ccb0d33678ec8420"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:a1ad90c97029cc3ab4ffd57443a20fac21d2ec3c89532b084b073b3feb5abff3"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4847f4b1d822754e35707db913396a29d874ee77b9c3c3ef3f04d5a9a6209618"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a99282848b6cae0056b85da17392a26b2d39178394fc25700bcf967e06e97a"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4b1cc7835b39835c75cf7c20c926b42e97d074147c902a9ebb7cf2c840dc4e2"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-win32.whl", hash = "sha256:c522e496f9b9b70296a7675272ec21937ccfc15da664b74b9f58d98a641ce1b6"}, + {file = "SQLAlchemy-1.4.46-cp37-cp37m-win_amd64.whl", hash = "sha256:ae067ab639fa499f67ded52f5bc8e084f045d10b5ac7bb928ae4ca2b6c0429a5"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e3c1808008124850115a3f7e793a975cfa5c8a26ceeeb9ff9cbb4485cac556df"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d164df3d83d204c69f840da30b292ac7dc54285096c6171245b8d7807185aa"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b33ffbdbbf5446cf36cd4cc530c9d9905d3c2fe56ed09e25c22c850cdb9fac92"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d94682732d1a0def5672471ba42a29ff5e21bb0aae0afa00bb10796fc1e28dd"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-win32.whl", hash = "sha256:f8cb80fe8d14307e4124f6fad64dfd87ab749c9d275f82b8b4ec84c84ecebdbe"}, + {file = "SQLAlchemy-1.4.46-cp38-cp38-win_amd64.whl", hash = "sha256:07e48cbcdda6b8bc7a59d6728bd3f5f574ffe03f2c9fb384239f3789c2d95c2e"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1b1e5e96e2789d89f023d080bee432e2fef64d95857969e70d3cadec80bd26f0"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3714e5b33226131ac0da60d18995a102a17dddd42368b7bdd206737297823ad"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:955162ad1a931fe416eded6bb144ba891ccbf9b2e49dc7ded39274dd9c5affc5"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6e4cb5c63f705c9d546a054c60d326cbde7421421e2d2565ce3e2eee4e1a01f"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-win32.whl", hash = "sha256:51e1ba2884c6a2b8e19109dc08c71c49530006c1084156ecadfaadf5f9b8b053"}, + {file = "SQLAlchemy-1.4.46-cp39-cp39-win_amd64.whl", hash = "sha256:315676344e3558f1f80d02535f410e80ea4e8fddba31ec78fe390eff5fb8f466"}, + {file = "SQLAlchemy-1.4.46.tar.gz", hash = "sha256:6913b8247d8a292ef8315162a51931e2b40ce91681f1b6f18f697045200c4a30"}, +] +sqlalchemy-utils = [ + {file = "SQLAlchemy-Utils-0.38.3.tar.gz", hash = "sha256:9f9afba607a40455cf703adfa9846584bf26168a0c5a60a70063b70d65051f4d"}, + {file = "SQLAlchemy_Utils-0.38.3-py3-none-any.whl", hash = "sha256:5c13b5d08adfaa85f3d4e8ec09a75136216fad41346980d02974a70a77988bf9"}, +] stack-data = [ {file = "stack_data-0.6.2-py3-none-any.whl", hash = "sha256:cbb2a53eb64e5785878201a97ed7c7b94883f48b87bfb0bbe8b623c74679e4a8"}, {file = "stack_data-0.6.2.tar.gz", hash = "sha256:32d2dd0376772d01b6cb9fc996f3c8b57a357089dec328ed4b6553d037eaf815"}, @@ -3588,6 +4022,14 @@ toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] +tomli = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] +tomlkit = [ + {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, + {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, +] toolz = [ {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, @@ -3613,32 +4055,6 @@ traitlets = [ {file = "traitlets-5.8.1-py3-none-any.whl", hash = "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861"}, {file = "traitlets-5.8.1.tar.gz", hash = "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b"}, ] -typed-ast = [ - {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {file = "typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {file = "typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {file = "typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {file = "typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {file = "typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {file = "typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {file = "typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {file = "typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {file = "typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {file = "typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {file = "typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {file = "typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, - {file = "typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {file = "typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {file = "typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, -] typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, @@ -3672,8 +4088,8 @@ websocket-client = [ {file = "websocket_client-1.4.2-py3-none-any.whl", hash = "sha256:d6b06432f184438d99ac1f456eaf22fe1ade524c3dd16e661142dc54e9cba574"}, ] werkzeug = [ - {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, - {file = "Werkzeug-1.0.1.tar.gz", hash = "sha256:6c80b1e5ad3665290ea39320b91e1be1e0d5f60652b964a3070216de83d2e47c"}, + {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, + {file = "Werkzeug-2.1.2.tar.gz", hash = "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6"}, ] widgetsnbextension = [ {file = "widgetsnbextension-4.0.5-py3-none-any.whl", hash = "sha256:eaaaf434fb9b08bd197b2a14ffe45ddb5ac3897593d43c69287091e5f3147bf7"}, diff --git a/pyproject.toml b/pyproject.toml index 41eb59dc4..bc5b53acf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,8 +37,8 @@ schematic = "schematic.__main__:main" [tool.poetry.dependencies] python = ">=3.9.0,<3.11" -click = "^7.1.2" -click-log = "^0.3.2" +click = "^8.0.0" +click-log = "^0.4.0" google-api-python-client = "^1.12.8" google-auth-httplib2 = "^0.0.4" google-auth-oauthlib = "^0.4.2" @@ -50,24 +50,25 @@ numpy = "^1.21.1" oauth2client = "<4.0.0" # Specified because of bug in version ^4.0.0 pandas = "^1.3.1" pygsheets = "^2.0.4" -PyYAML = "^5.4.1" +PyYAML = "^6.0.0" rdflib = "^5.0.0" setuptools = "^52.0.0" synapseclient = "^2.6.0" tenacity = "^8.0.1" toml = "^0.10.2" -Flask = "^1.1.4" +Flask = ">=1.1.4" connexion = {extras = ["swagger-ui"], version = "^2.8.0"} great-expectations = "^0.15.0" sphinx-click = "^3.1.0" MarkupSafe = "2.0.1" -itsdangerous = "1.1.0" -Jinja2 = "2.11.3" +itsdangerous = "^2.0.0" +Jinja2 = ">2.11.3" openpyxl = "^3.0.9" "backports.zoneinfo" = {markers = "python_version < \"3.9\"", version = "^0.2.1"} Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" +schematic-db = "^0.0.4" [tool.poetry.dev-dependencies] @@ -76,7 +77,7 @@ pytest-cov = "^2.11.1" pytest-mock = "^3.5.1" flake8 = "^3.8.4" python-dotenv = "^0.15.0" -black = {version = "^20.8b1", allow-prereleases = true} +black = {version = "^22.6.0", allow-prereleases = true} [tool.black] From 16d8abce67e453d819b673f9624b507bba755648 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:38:32 -0700 Subject: [PATCH 070/615] update toml dependencies to latest major or minor version except networkx --- poetry.lock | 698 ++++++++++++++++++++++++++++++++----------------- pyproject.toml | 30 +-- 2 files changed, 466 insertions(+), 262 deletions(-) diff --git a/poetry.lock b/poetry.lock index 07abff672..004ba6910 100644 --- a/poetry.lock +++ b/poetry.lock @@ -81,6 +81,17 @@ cffi = ">=1.0.1" dev = ["cogapp", "pre-commit", "pytest", "wheel"] tests = ["pytest"] +[[package]] +name = "arrow" +version = "1.2.3" +description = "Better dates & times for Python" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +python-dateutil = ">=2.7.0" + [[package]] name = "astroid" version = "2.13.3" @@ -108,14 +119,6 @@ six = "*" [package.extras] test = ["astroid", "pytest"] -[[package]] -name = "atomicwrites" -version = "1.4.1" -description = "Atomic file writes." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - [[package]] name = "attrs" version = "22.2.0" @@ -150,6 +153,21 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "black" version = "22.12.0" @@ -313,6 +331,9 @@ category = "dev" optional = false python-versions = ">=3.7" +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + [package.extras] toml = ["tomli"] @@ -427,6 +448,17 @@ category = "main" optional = false python-versions = ">=3.6" +[[package]] +name = "exceptiongroup" +version = "1.1.0" +description = "Backport of PEP 654 (exception groups)" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +test = ["pytest (>=6)"] + [[package]] name = "executing" version = "1.2.0" @@ -451,16 +483,16 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "flake8" -version = "3.9.2" +version = "6.0.0" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +python-versions = ">=3.8.1" [package.dependencies] -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" +mccabe = ">=0.7.0,<0.8.0" +pycodestyle = ">=2.10.0,<2.11.0" +pyflakes = ">=3.0.0,<3.1.0" [[package]] name = "flask" @@ -493,6 +525,14 @@ python-versions = "*" Flask = ">=0.9" Six = "*" +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" + [[package]] name = "google-api-core" version = "2.11.0" @@ -514,19 +554,18 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "1.12.11" +version = "2.74.0" description = "Google API Client Library for Python" category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +python-versions = ">=3.7" [package.dependencies] -google-api-core = {version = ">=1.21.0,<3dev", markers = "python_version >= \"3\""} -google-auth = {version = ">=1.16.0,<3dev", markers = "python_version >= \"3\""} -google-auth-httplib2 = ">=0.0.3" +google-api-core = ">=1.31.5,<2.0.0 || >2.3.0,<3.0.0dev" +google-auth = ">=1.19.0,<3.0.0dev" +google-auth-httplib2 = ">=0.1.0" httplib2 = ">=0.15.0,<1dev" -six = ">=1.13.0,<2dev" -uritemplate = ">=3.0.0,<4dev" +uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" @@ -551,7 +590,7 @@ requests = ["requests (>=2.20.0,<3.0.0dev)"] [[package]] name = "google-auth-httplib2" -version = "0.0.4" +version = "0.1.0" description = "Google Authentication Library: httplib2 transport" category = "main" optional = false @@ -559,19 +598,19 @@ python-versions = "*" [package.dependencies] google-auth = "*" -httplib2 = ">=0.9.1" +httplib2 = ">=0.15.0" six = "*" [[package]] name = "google-auth-oauthlib" -version = "0.4.6" +version = "0.8.0" description = "Google Authentication Library" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -google-auth = ">=1.0.0" +google-auth = ">=2.15.0" requests-oauthlib = ">=0.7.0" [package.extras] @@ -593,16 +632,16 @@ grpc = ["grpcio (>=1.44.0,<2.0.0dev)"] [[package]] name = "graphviz" -version = "0.16" +version = "0.20.1" description = "Simple Python interface for Graphviz" category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.7" [package.extras] dev = ["flake8", "pep8-naming", "tox (>=3)", "twine", "wheel"] -docs = ["sphinx (>=1.8)", "sphinx-rtd-theme"] -test = ["mock (>=3)", "pytest (>=4)", "pytest-cov", "pytest-mock (>=2)"] +docs = ["sphinx (>=5)", "sphinx-autodoc-typehints", "sphinx-rtd-theme"] +test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>=3)"] [[package]] name = "great-expectations" @@ -847,6 +886,17 @@ python-versions = "*" [package.dependencies] six = "*" +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +arrow = ">=0.15.0" + [[package]] name = "isort" version = "5.11.4" @@ -932,21 +982,27 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "jsonschema" -version = "3.2.0" +version = "4.17.3" description = "An implementation of JSON Schema validation for Python" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] attrs = ">=17.4.0" -pyrsistent = ">=0.14.0" -setuptools = "*" -six = ">=1.11.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} +pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} [package.extras] -format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] -format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "webcolors"] +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 = "jupyter-client" @@ -986,34 +1042,82 @@ traitlets = ">=5.3" docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "jupyter-events" +version = "0.6.3" +description = "Jupyter Event System library" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +jsonschema = {version = ">=3.2.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "pytest-cov", "rich"] + [[package]] name = "jupyter-server" -version = "1.15.6" +version = "2.1.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -anyio = ">=3.1.0" +anyio = ">=3.1.0,<4" argon2-cffi = "*" jinja2 = "*" -jupyter-client = ">=6.1.1" -jupyter-core = ">=4.6.0" -nbconvert = "*" -nbformat = ">=5.2.0" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-events = ">=0.4.0" +jupyter-server-terminals = "*" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" packaging = "*" prometheus-client = "*" pywinpty = {version = "*", markers = "os_name == \"nt\""} -pyzmq = ">=17" -Send2Trash = "*" +pyzmq = ">=24" +send2trash = "*" terminado = ">=0.8.3" -tornado = ">=6.1.0" -traitlets = ">=5" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" websocket-client = "*" [package.extras] -test = ["coverage", "ipykernel", "pytest (>=6.0)", "pytest-console-scripts", "pytest-cov", "pytest-mock", "pytest-timeout", "pytest-tornasync", "requests"] +docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.4.4" +description = "A Jupyter Server Extension Providing Terminals." +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<3.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.2.2" +description = "Pygments theme using JupyterLab CSS variables" +category = "main" +optional = false +python-versions = ">=3.7" [[package]] name = "jupyterlab-widgets" @@ -1074,11 +1178,11 @@ python-versions = "*" [[package]] name = "markupsafe" -version = "2.0.1" +version = "2.1.0" description = "Safely add untrusted strings to HTML/XML markup." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "marshmallow" @@ -1110,11 +1214,11 @@ traitlets = "*" [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" description = "McCabe checker, plugin for flake8" category = "main" optional = false -python-versions = "*" +python-versions = ">=3.6" [[package]] name = "mistune" @@ -1190,33 +1294,59 @@ docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib- json-logging = ["json-logging"] test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] +[[package]] +name = "nbclient" +version = "0.7.2" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "main" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +nbformat = ">=5.1" +traitlets = ">=5.3" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme"] +test = ["ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + [[package]] name = "nbconvert" -version = "5.5.0" +version = "7.2.9" description = "Converting Jupyter Notebooks" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] +beautifulsoup4 = "*" bleach = "*" defusedxml = "*" -entrypoints = ">=0.2.2" -jinja2 = ">=2.4" -jupyter-core = "*" -mistune = ">=0.8.1" -nbformat = ">=4.4" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<3" +nbclient = ">=0.5.0" +nbformat = ">=5.1" +packaging = "*" pandocfilters = ">=1.4.1" -pygments = "*" -testpath = "*" -traitlets = ">=4.2" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.0" [package.extras] -all = ["ipykernel", "ipython", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "pytest", "pytest-cov", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt", "tornado (>=4.0)"] -docs = ["ipython", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -execute = ["jupyter-client (>=4.2)"] -serve = ["tornado (>=4.0)"] -test = ["ipykernel", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "pytest", "pytest-cov"] +all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["nbconvert[qtpng]"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] +webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] name = "nbformat" @@ -1314,7 +1444,7 @@ python-versions = ">=3.8" [[package]] name = "oauth2client" -version = "3.0.0" +version = "4.1.3" description = "OAuth 2.0 client library" category = "main" optional = false @@ -1533,14 +1663,6 @@ python-versions = "*" [package.extras] tests = ["pytest"] -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - [[package]] name = "pyasn1" version = "0.4.8" @@ -1562,11 +1684,11 @@ pyasn1 = ">=0.4.6,<0.5.0" [[package]] name = "pycodestyle" -version = "2.7.0" +version = "2.10.0" description = "Python style guide checker" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "pycparser" @@ -1593,11 +1715,11 @@ email = ["email-validator (>=1.0.3)"] [[package]] name = "pyflakes" -version = "2.3.1" +version = "3.0.1" description = "passive checker of Python programs" category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "pygments" @@ -1612,15 +1734,15 @@ plugins = ["importlib-metadata"] [[package]] name = "pygsheets" -version = "2.0.5" +version = "2.0.6" description = "Google Spreadsheets Python API v4" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] -google-api-python-client = ">=1.5.5" -google-auth-oauthlib = "*" +google-api-python-client = ">=2.50.0" +google-auth-oauthlib = ">=0.7.1" [package.extras] pandas = ["pandas (>=0.14.0)"] @@ -1669,37 +1791,35 @@ python-versions = ">=3.7" [[package]] name = "pytest" -version = "6.2.5" +version = "7.2.1" description = "pytest: simple powerful testing with Python" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] +testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-cov" -version = "2.12.1" +version = "4.0.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.6" [package.dependencies] -coverage = ">=5.2.1" +coverage = {version = ">=5.2.1", extras = ["toml"]} pytest = ">=4.6" -toml = "*" [package.extras] testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] @@ -1740,6 +1860,14 @@ python-versions = "*" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-json-logger" +version = "2.0.4" +description = "A python library adding a json log formatter" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "pytz" version = "2022.7.1" @@ -1804,22 +1932,24 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "rdflib" -version = "5.0.0" +version = "6.2.0" description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] isodate = "*" pyparsing = "*" -six = "*" +setuptools = "*" [package.extras] -docs = ["sphinx (<3)", "sphinxcontrib-apidoc"] +berkeleydb = ["berkeleydb"] +dev = ["black (==22.6.0)", "flake8", "flakeheaven", "isort", "mypy", "pep8-naming", "types-setuptools"] +docs = ["myst-parser", "sphinx (<6)", "sphinx-autodoc-typehints", "sphinxcontrib-apidoc", "sphinxcontrib-kroki"] html = ["html5lib"] -sparql = ["requests"] -tests = ["doctest-ignore-unicode", "html5lib", "networkx", "nose"] +networkx = ["networkx"] +tests = ["html5lib", "pytest", "pytest-cov"] [[package]] name = "regex" @@ -1862,6 +1992,25 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "rsa" version = "4.9" @@ -1964,17 +2113,16 @@ win32 = ["pywin32"] [[package]] name = "setuptools" -version = "52.0.0" +version = "66.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -certs = ["certifi (==2016.9.26)"] -docs = ["jaraco.packaging (>=8.2)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx"] -ssl = ["wincertstore (==0.2)"] -testing = ["flake8-2020", "jaraco.envs", "mock", "paver", "pip (>=19.1)", "pytest (>=3.5,!=3.7.3)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-flake8", "pytest-mypy", "pytest-virtualenv (>=1.2.7)", "pytest-xdist", "virtualenv (>=13.0.0)", "wheel"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -2000,26 +2148,34 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "sphinx" -version = "5.1.1" +version = "6.1.3" description = "Python documentation generator" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" [package.dependencies] alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.20" -imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" +babel = ">=2.9" +colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} +docutils = ">=0.18,<0.20" +imagesize = ">=1.3" +importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} +Jinja2 = ">=3.0" +packaging = ">=21.0" +Pygments = ">=2.13" +requests = ">=2.25.0" +snowballstemmer = ">=2.0" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = ">=2.0.0" @@ -2029,16 +2185,16 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] -lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-bugbear", "flake8-comprehensions", "isort", "mypy (>=0.971)", "sphinx-lint", "types-requests", "types-typed-ast"] -test = ["cython", "html5lib", "pytest (>=4.6)", "typed-ast"] +lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] +test = ["cython", "html5lib", "pytest (>=4.6)"] [[package]] name = "sphinx-click" -version = "3.1.0" +version = "4.4.0" description = "Sphinx extension that automatically documents click applications" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] click = ">=7.0" @@ -2250,15 +2406,19 @@ docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] [[package]] -name = "testpath" -version = "0.6.0" -description = "Test utilities for code working with files and commands" +name = "tinycss2" +version = "1.2.1" +description = "A tiny CSS parser" category = "main" optional = false -python-versions = ">= 3.5" +python-versions = ">=3.7" + +[package.dependencies] +webencodings = ">=0.4" [package.extras] -test = ["pytest"] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] [[package]] name = "toml" @@ -2361,13 +2521,24 @@ tzdata = {version = "*", markers = "platform_system == \"Windows\""} devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] +[[package]] +name = "uri-template" +version = "1.2.0" +description = "RFC 6570 URI Template Processor" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.extras] +dev = ["flake8 (<4.0.0)", "flake8-annotations", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-noqa", "flake8-requirements", "flake8-type-annotations", "flake8-use-fstring", "mypy", "pep8-naming"] + [[package]] name = "uritemplate" -version = "3.0.1" -description = "URI templates" +version = "4.1.1" +description = "Implementation of RFC 6570 URI Templates" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +python-versions = ">=3.6" [[package]] name = "urllib3" @@ -2390,6 +2561,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "webcolors" +version = "1.12" +description = "A library for working with color names and color values formats defined by HTML and CSS." +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "webencodings" version = "0.5.1" @@ -2453,7 +2632,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "cf52bf7f954db2bd6f4e2e1b29cd16b2f1dd136306c86de68b741080e3cbceae" +content-hash = "866d25aeeb497f81c53616a8db3c5011e316f6a9fb50195449d0285febe16af0" [metadata.files] alabaster = [ @@ -2499,6 +2678,10 @@ argon2-cffi-bindings = [ {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, ] +arrow = [ + {file = "arrow-1.2.3-py3-none-any.whl", hash = "sha256:5a49ab92e3b7b71d96cd6bfcc4df14efefc9dfa96ea19045815914a6ab6b1fe2"}, + {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, +] astroid = [ {file = "astroid-2.13.3-py3-none-any.whl", hash = "sha256:14c1603c41cc61aae731cad1884a073c4645e26f126d13ac8346113c95577f3b"}, {file = "astroid-2.13.3.tar.gz", hash = "sha256:6afc22718a48a689ca24a97981ad377ba7fb78c133f40335dfd16772f29bcfb1"}, @@ -2507,9 +2690,6 @@ asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, ] -atomicwrites = [ - {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"}, -] attrs = [ {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, @@ -2522,6 +2702,10 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] black = [ {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, {file = "black-22.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:159a46a4947f73387b4d83e87ea006dbb2337eab6c879620a3ba52699b1f4351"}, @@ -2858,6 +3042,10 @@ et-xmlfile = [ {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"}, {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] +exceptiongroup = [ + {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, + {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, +] executing = [ {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, @@ -2867,8 +3055,8 @@ fastjsonschema = [ {file = "fastjsonschema-2.16.2.tar.gz", hash = "sha256:01e366f25d9047816fe3d288cbfc3e10541daf0af2044763f3d0ade42476da18"}, ] flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, + {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, + {file = "flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, ] flask = [ {file = "Flask-2.1.3-py3-none-any.whl", hash = "sha256:9013281a7402ad527f8fd56375164f3aa021ecfaff89bfe3825346c24f87e04c"}, @@ -2878,33 +3066,37 @@ flask-cors = [ {file = "Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"}, {file = "Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"}, ] +fqdn = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] google-api-core = [ {file = "google-api-core-2.11.0.tar.gz", hash = "sha256:4b9bb5d5a380a0befa0573b302651b8a9a89262c1730e37bf423cec511804c22"}, {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-1.12.11.tar.gz", hash = "sha256:1b4bd42a46321e13c0542a9e4d96fa05d73626f07b39f83a73a947d70ca706a9"}, - {file = "google_api_python_client-1.12.11-py2.py3-none-any.whl", hash = "sha256:7e0a1a265c8d3088ee1987778c72683fcb376e32bada8d7767162bd9c503fd9b"}, + {file = "google-api-python-client-2.74.0.tar.gz", hash = "sha256:22c9565b6d4343e35a6d614f2c075e765888a81e11444a27c570e0865631a3f9"}, + {file = "google_api_python_client-2.74.0-py2.py3-none-any.whl", hash = "sha256:679669b709450a12dacf28612adf0538afc858566b6ee01628e4013a2073dffc"}, ] google-auth = [ {file = "google-auth-2.16.0.tar.gz", hash = "sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd"}, {file = "google_auth-2.16.0-py2.py3-none-any.whl", hash = "sha256:5045648c821fb72384cdc0e82cc326df195f113a33049d9b62b74589243d2acc"}, ] google-auth-httplib2 = [ - {file = "google-auth-httplib2-0.0.4.tar.gz", hash = "sha256:8d092cc60fb16517b12057ec0bba9185a96e3b7169d86ae12eae98e645b7bc39"}, - {file = "google_auth_httplib2-0.0.4-py2.py3-none-any.whl", hash = "sha256:aeaff501738b289717fac1980db9711d77908a6c227f60e4aa1923410b43e2ee"}, + {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, + {file = "google_auth_httplib2-0.1.0-py2.py3-none-any.whl", hash = "sha256:31e49c36c6b5643b57e82617cb3e021e3e1d2df9da63af67252c02fa9c1f4a10"}, ] google-auth-oauthlib = [ - {file = "google-auth-oauthlib-0.4.6.tar.gz", hash = "sha256:a90a072f6993f2c327067bf65270046384cda5a8ecb20b94ea9a687f1f233a7a"}, - {file = "google_auth_oauthlib-0.4.6-py2.py3-none-any.whl", hash = "sha256:3f2a6e802eebbb6fb736a370fbf3b055edcb6b52878bf2f26330b5e041316c73"}, + {file = "google-auth-oauthlib-0.8.0.tar.gz", hash = "sha256:81056a310fb1c4a3e5a7e1a443e1eb96593c6bbc55b26c0261e4d3295d3e6593"}, + {file = "google_auth_oauthlib-0.8.0-py2.py3-none-any.whl", hash = "sha256:40cc612a13c3336d5433e94e2adb42a0c88f6feb6c55769e44500fc70043a576"}, ] googleapis-common-protos = [ {file = "googleapis-common-protos-1.58.0.tar.gz", hash = "sha256:c727251ec025947d545184ba17e3578840fc3a24a0516a020479edab660457df"}, {file = "googleapis_common_protos-1.58.0-py2.py3-none-any.whl", hash = "sha256:ca3befcd4580dab6ad49356b46bf165bb68ff4b32389f028f1abd7c10ab9519a"}, ] graphviz = [ - {file = "graphviz-0.16-py2.py3-none-any.whl", hash = "sha256:3cad5517c961090dfc679df6402a57de62d97703e2880a1a46147bb0dc1639eb"}, - {file = "graphviz-0.16.zip", hash = "sha256:d2d25af1c199cad567ce4806f0449cb74eb30cf451fd7597251e1da099ac6e57"}, + {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, + {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, @@ -3016,6 +3208,10 @@ isodate = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, {file = "isodate-0.6.1.tar.gz", hash = "sha256:48c5881de7e8b0a0d648cb024c8062dc84e7b840ed81e864c7614fd3c127bde9"}, ] +isoduration = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] isort = [ {file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"}, {file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"}, @@ -3045,8 +3241,8 @@ jsonpointer = [ {file = "jsonpointer-2.3.tar.gz", hash = "sha256:97cba51526c829282218feb99dab1b1e6bdf8efd1c43dc9d57be093c0d69c99a"}, ] jsonschema = [ - {file = "jsonschema-3.2.0-py2.py3-none-any.whl", hash = "sha256:4e5b3cf8216f577bee9ce139cbe72eca3ea4f292ec60928ff24758ce626cd163"}, - {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, + {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, + {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] jupyter-client = [ {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, @@ -3056,9 +3252,21 @@ jupyter-core = [ {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, {file = "jupyter_core-5.1.5.tar.gz", hash = "sha256:8e54c48cde1e0c8345f64bcf9658b78044ddf02b273726cea9d9f59be4b02130"}, ] +jupyter-events = [ + {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, + {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, +] jupyter-server = [ - {file = "jupyter_server-1.15.6-py3-none-any.whl", hash = "sha256:e393934c19fcc324a7fca77f811eacd91201440f04c6fbb15c959c463baaa9c5"}, - {file = "jupyter_server-1.15.6.tar.gz", hash = "sha256:56bd6f580d1f46b62294990e8e78651025729f5d3fc798f10f2c03f0cdcbf28d"}, + {file = "jupyter_server-2.1.0-py3-none-any.whl", hash = "sha256:90cd6f2bd0581ddd9b2dbe82026a0f4c228a1d95c86e22460efbfdfc931fcf56"}, + {file = "jupyter_server-2.1.0.tar.gz", hash = "sha256:efaae5e4f0d5f22c7f2f2dc848635036ee74a2df02abed52d30d9d95121ad382"}, +] +jupyter-server-terminals = [ + {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, + {file = "jupyter_server_terminals-0.4.4.tar.gz", hash = "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d"}, +] +jupyterlab-pygments = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, ] jupyterlab-widgets = [ {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, @@ -3115,75 +3323,46 @@ makefun = [ {file = "makefun-1.15.0.tar.gz", hash = "sha256:5b110e733d94f7a49d8ac27b1e2d40f2bb0501e98c1d825e0d932d26920dd5df"}, ] markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3028252424c72b2602a323f70fbf50aa80a5d3aa616ea6add4ba21ae9cc9da4c"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:290b02bab3c9e216da57c1d11d2ba73a9f73a614bbdcc027d299a60cdfabb11a"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e104c0c2b4cd765b4e83909cde7ec61a1e313f8a75775897db321450e928cce"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24c3be29abb6b34052fd26fc7a8e0a49b1ee9d282e3665e8ad09a0a68faee5b3"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204730fd5fe2fe3b1e9ccadb2bd18ba8712b111dcabce185af0b3b5285a7c989"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d3b64c65328cb4cd252c94f83e66e3d7acf8891e60ebf588d7b493a55a1dbf26"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:96de1932237abe0a13ba68b63e94113678c379dca45afa040a17b6e1ad7ed076"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75bb36f134883fdbe13d8e63b8675f5f12b80bb6627f7714c7d6c5becf22719f"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-win32.whl", hash = "sha256:4056f752015dfa9828dce3140dbadd543b555afb3252507348c493def166d454"}, + {file = "MarkupSafe-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:d4e702eea4a2903441f2735799d217f4ac1b55f7d8ad96ab7d4e25417cb0827c"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f0eddfcabd6936558ec020130f932d479930581171368fd728efcfb6ef0dd357"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ddea4c352a488b5e1069069f2f501006b1a4362cb906bee9a193ef1245a7a61"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:09c86c9643cceb1d87ca08cdc30160d1b7ab49a8a21564868921959bd16441b8"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a0a0abef2ca47b33fb615b491ce31b055ef2430de52c5b3fb19a4042dbc5cadb"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:736895a020e31b428b3382a7887bfea96102c529530299f426bf2e636aacec9e"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:679cbb78914ab212c49c67ba2c7396dc599a8479de51b9a87b174700abd9ea49"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:84ad5e29bf8bab3ad70fd707d3c05524862bddc54dc040982b0dbcff36481de7"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-win32.whl", hash = "sha256:8da5924cb1f9064589767b0f3fc39d03e3d0fb5aa29e0cb21d43106519bd624a"}, + {file = "MarkupSafe-2.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:454ffc1cbb75227d15667c09f164a0099159da0c1f3d2636aa648f12675491ad"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:142119fb14a1ef6d758912b25c4e803c3ff66920635c44078666fe7cc3f8f759"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b2a5a856019d2833c56a3dcac1b80fe795c95f401818ea963594b345929dffa7"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d1fb9b2eec3c9714dd936860850300b51dbaa37404209c8d4cb66547884b7ed"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:62c0285e91414f5c8f621a17b69fc0088394ccdaa961ef469e833dbff64bd5ea"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc3150f85e2dbcf99e65238c842d1cfe69d3e7649b19864c1cc043213d9cd730"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f02cf7221d5cd915d7fa58ab64f7ee6dd0f6cddbb48683debf5d04ae9b1c2cc1"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d5653619b3eb5cbd35bfba3c12d575db2a74d15e0e1c08bf1db788069d410ce8"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7d2f5d97fcbd004c03df8d8fe2b973fe2b14e7bfeb2cfa012eaa8759ce9a762f"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-win32.whl", hash = "sha256:3cace1837bc84e63b3fd2dfce37f08f8c18aeb81ef5cf6bb9b51f625cb4e6cd8"}, + {file = "MarkupSafe-2.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:fabbe18087c3d33c5824cb145ffca52eccd053061df1d79d4b66dafa5ad2a5ea"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:023af8c54fe63530545f70dd2a2a7eed18d07a9a77b94e8bf1e2ff7f252db9a3"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d66624f04de4af8bbf1c7f21cc06649c1c69a7f84109179add573ce35e46d448"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c532d5ab79be0199fa2658e24a02fce8542df196e60665dd322409a03db6a52c"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ec74fada3841b8c5f4c4f197bea916025cb9aa3fe5abf7d52b655d042f956"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c653fde75a6e5eb814d2a0a89378f83d1d3f502ab710904ee585c38888816c"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:961eb86e5be7d0973789f30ebcf6caab60b844203f4396ece27310295a6082c7"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:598b65d74615c021423bd45c2bc5e9b59539c875a9bdb7e5f2a6b92dfcfc268d"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:599941da468f2cf22bf90a84f6e2a65524e87be2fce844f96f2dd9a6c9d1e635"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-win32.whl", hash = "sha256:e6f7f3f41faffaea6596da86ecc2389672fa949bd035251eab26dc6697451d05"}, + {file = "MarkupSafe-2.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:b8811d48078d1cf2a6863dafb896e68406c5f513048451cd2ded0473133473c7"}, + {file = "MarkupSafe-2.1.0.tar.gz", hash = "sha256:80beaf63ddfbc64a0452b841d8036ca0611e049650e20afcb882f5d3c266d65f"}, ] marshmallow = [ {file = "marshmallow-3.19.0-py3-none-any.whl", hash = "sha256:93f0958568da045b0021ec6aeb7ac37c81bfcccbb9a0e7ed8559885070b3a19b"}, @@ -3194,8 +3373,8 @@ matplotlib-inline = [ {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, ] mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, + {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mistune = [ {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, @@ -3244,9 +3423,13 @@ nbclassic = [ {file = "nbclassic-0.4.8-py3-none-any.whl", hash = "sha256:cbf05df5842b420d5cece0143462380ea9d308ff57c2dc0eb4d6e035b18fbfb3"}, {file = "nbclassic-0.4.8.tar.gz", hash = "sha256:c74d8a500f8e058d46b576a41e5bc640711e1032cf7541dde5f73ea49497e283"}, ] +nbclient = [ + {file = "nbclient-0.7.2-py3-none-any.whl", hash = "sha256:d97ac6257de2794f5397609df754fcbca1a603e94e924eb9b99787c031ae2e7c"}, + {file = "nbclient-0.7.2.tar.gz", hash = "sha256:884a3f4a8c4fc24bb9302f263e0af47d97f0d01fe11ba714171b320c8ac09547"}, +] nbconvert = [ - {file = "nbconvert-5.5.0-py2.py3-none-any.whl", hash = "sha256:4a978548d8383f6b2cfca4a3b0543afb77bc7cb5a96e8b424337ab58c12da9bc"}, - {file = "nbconvert-5.5.0.tar.gz", hash = "sha256:138381baa41d83584459b5cfecfc38c800ccf1f37d9ddd0bd440783346a4c39c"}, + {file = "nbconvert-7.2.9-py3-none-any.whl", hash = "sha256:495638c5e06005f4a5ce828d8a81d28e34f95c20f4384d5d7a22254b443836e7"}, + {file = "nbconvert-7.2.9.tar.gz", hash = "sha256:a42c3ac137c64f70cbe4d763111bf358641ea53b37a01a5c202ed86374af5234"}, ] nbformat = [ {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, @@ -3299,7 +3482,8 @@ numpy = [ {file = "numpy-1.24.1.tar.gz", hash = "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2"}, ] oauth2client = [ - {file = "oauth2client-3.0.0.tar.gz", hash = "sha256:5b5b056ec6f2304e7920b632885bd157fa71d1a7f3ddd00a43b1541a8d1a2460"}, + {file = "oauth2client-4.1.3-py2.py3-none-any.whl", hash = "sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac"}, + {file = "oauth2client-4.1.3.tar.gz", hash = "sha256:d486741e451287f69568a4d26d70d9acd73a2bbfa275746c535b4209891cccc6"}, ] oauthlib = [ {file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, @@ -3435,10 +3619,6 @@ pure-eval = [ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] pyasn1 = [ {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, @@ -3448,8 +3628,8 @@ pyasn1-modules = [ {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, ] pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, + {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, + {file = "pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, ] pycparser = [ {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, @@ -3494,16 +3674,16 @@ pydantic = [ {file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"}, ] pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, + {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, + {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] pygments = [ {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, ] pygsheets = [ - {file = "pygsheets-2.0.5-py2.py3-none-any.whl", hash = "sha256:85a4c871ac1d53013e042c13552b07f908b991c3d8c8770b3a68eb3452c8c218"}, - {file = "pygsheets-2.0.5.tar.gz", hash = "sha256:ea6ce75dabd1359e49fd36920ff0d25ff9428ccc3d5d2474bdba80fb8653ad80"}, + {file = "pygsheets-2.0.6-py3-none-any.whl", hash = "sha256:3338c2eb8990fdee9f463b42a370ec0870c118d607d775471a6dfb8b08f6cd87"}, + {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ {file = "pylint-2.15.10-py3-none-any.whl", hash = "sha256:9df0d07e8948a1c3ffa3b6e2d7e6e63d9fb457c5da5b961ed63106594780cc7e"}, @@ -3543,12 +3723,12 @@ pyrsistent = [ {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, ] pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, + {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"}, + {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"}, ] pytest-cov = [ - {file = "pytest-cov-2.12.1.tar.gz", hash = "sha256:261ceeb8c227b726249b376b8526b600f38667ee314f910353fa318caa01f4d7"}, - {file = "pytest_cov-2.12.1-py2.py3-none-any.whl", hash = "sha256:261bb9e47e65bd099c89c3edf92972865210c36813f80ede5277dceb77a4a62a"}, + {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, + {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, ] pytest-mock = [ {file = "pytest-mock-3.10.0.tar.gz", hash = "sha256:fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"}, @@ -3562,6 +3742,10 @@ python-dotenv = [ {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, ] +python-json-logger = [ + {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, + {file = "python_json_logger-2.0.4-py3-none-any.whl", hash = "sha256:3b03487b14eb9e4f77e4fc2a023358b5394b82fd89cecf5586259baed57d8c6f"}, +] pytz = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, @@ -3720,8 +3904,8 @@ pyzmq = [ {file = "pyzmq-25.0.0.tar.gz", hash = "sha256:f330a1a2c7f89fd4b0aa4dcb7bf50243bf1c8da9a2f1efc31daf57a2046b31f2"}, ] rdflib = [ - {file = "rdflib-5.0.0-py3-none-any.whl", hash = "sha256:88208ea971a87886d60ae2b1a4b2cdc263527af0454c422118d43fe64b357877"}, - {file = "rdflib-5.0.0.tar.gz", hash = "sha256:78149dd49d385efec3b3adfbd61c87afaf1281c30d3fcaf1b323b34f603fb155"}, + {file = "rdflib-6.2.0-py3-none-any.whl", hash = "sha256:85c34a86dfc517a41e5f2425a41a0aceacc23983462b32e68610b9fad1383bca"}, + {file = "rdflib-6.2.0.tar.gz", hash = "sha256:62dc3c86d1712db0f55785baf8047f63731fa59b2682be03219cb89262065942"}, ] regex = [ {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, @@ -3821,6 +4005,14 @@ requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, ] +rfc3339-validator = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] +rfc3986-validator = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] rsa = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -3900,8 +4092,8 @@ send2trash = [ {file = "Send2Trash-1.8.0.tar.gz", hash = "sha256:d2c24762fd3759860a0aff155e45871447ea58d2be6bdd39b5c8f966a0c99c2d"}, ] setuptools = [ - {file = "setuptools-52.0.0-py3-none-any.whl", hash = "sha256:0a6f1f18249f78cffdad842efadf1ed7b039fa3355d93f3890f56bd66a48cf27"}, - {file = "setuptools-52.0.0.tar.gz", hash = "sha256:fb3a1ee622509550dbf1d419f241296169d7f09cb1eb5b1736f2f10965932b96"}, + {file = "setuptools-66.1.1-py3-none-any.whl", hash = "sha256:6f590d76b713d5de4e49fe4fbca24474469f53c83632d5d0fd056f7ff7e8112b"}, + {file = "setuptools-66.1.1.tar.gz", hash = "sha256:ac4008d396bc9cd983ea483cb7139c0240a07bbc74ffb6232fceffedc6cf03a8"}, ] six = [ {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, @@ -3915,13 +4107,17 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] sphinx = [ - {file = "Sphinx-5.1.1-py3-none-any.whl", hash = "sha256:309a8da80cb6da9f4713438e5b55861877d5d7976b69d87e336733637ea12693"}, - {file = "Sphinx-5.1.1.tar.gz", hash = "sha256:ba3224a4e206e1fbdecf98a4fae4992ef9b24b85ebf7b584bb340156eaf08d89"}, + {file = "Sphinx-6.1.3.tar.gz", hash = "sha256:0dac3b698538ffef41716cf97ba26c1c7788dba73ce6f150c1ff5b4720786dd2"}, + {file = "sphinx-6.1.3-py3-none-any.whl", hash = "sha256:807d1cb3d6be87eb78a381c3e70ebd8d346b9a25f3753e9947e866b2786865fc"}, ] sphinx-click = [ - {file = "sphinx-click-3.1.0.tar.gz", hash = "sha256:36dbf271b1d2600fb05bd598ddeed0b6b6acf35beaf8bc9d507ba7716b232b0e"}, - {file = "sphinx_click-3.1.0-py3-none-any.whl", hash = "sha256:8fb0b048a577d346d741782e44d041d7e908922858273d99746f305870116121"}, + {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, + {file = "sphinx_click-4.4.0-py3-none-any.whl", hash = "sha256:2821c10a68fc9ee6ce7c92fad26540d8d8c8f45e6d7258f0e4fb7529ae8fab49"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.4.tar.gz", hash = "sha256:828f867945bbe39817c210a1abfd1bc4895c8b73fcaade56d45357a348a07d7e"}, @@ -4014,9 +4210,9 @@ terminado = [ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, {file = "terminado-0.17.1.tar.gz", hash = "sha256:6ccbbcd3a4f8a25a5ec04991f39a0b8db52dfcd487ea0e578d977e6752380333"}, ] -testpath = [ - {file = "testpath-0.6.0-py3-none-any.whl", hash = "sha256:8ada9f80a2ac6fb0391aa7cdb1a7d11cfa8429f693eda83f74dde570fe6fa639"}, - {file = "testpath-0.6.0.tar.gz", hash = "sha256:2f1b97e6442c02681ebe01bd84f531028a7caea1af3825000f52345c30285e0f"}, +tinycss2 = [ + {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, + {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, ] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, @@ -4067,9 +4263,13 @@ tzlocal = [ {file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"}, {file = "tzlocal-4.2.tar.gz", hash = "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"}, ] +uri-template = [ + {file = "uri_template-1.2.0-py3-none-any.whl", hash = "sha256:f1699c77b73b925cf4937eae31ab282a86dc885c333f2e942513f08f691fc7db"}, + {file = "uri_template-1.2.0.tar.gz", hash = "sha256:934e4d09d108b70eb8a24410af8615294d09d279ce0e7cbcdaef1bd21f932b06"}, +] uritemplate = [ - {file = "uritemplate-3.0.1-py2.py3-none-any.whl", hash = "sha256:07620c3f3f8eed1f12600845892b0e036a2420acf513c53f7de0abd911a5894f"}, - {file = "uritemplate-3.0.1.tar.gz", hash = "sha256:5af8ad10cec94f215e3f48112de2022e1d5a37ed427fbd88652fa908f2ab7cae"}, + {file = "uritemplate-4.1.1-py2.py3-none-any.whl", hash = "sha256:830c08b8d99bdd312ea4ead05994a38e8936266f84b9a7878232db50b044e02e"}, + {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] urllib3 = [ {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, @@ -4079,6 +4279,10 @@ wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +webcolors = [ + {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"}, + {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"}, +] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, diff --git a/pyproject.toml b/pyproject.toml index bc5b53acf..103f842d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,28 +39,28 @@ python = ">=3.9.0,<3.11" click = "^8.0.0" click-log = "^0.4.0" -google-api-python-client = "^1.12.8" -google-auth-httplib2 = "^0.0.4" -google-auth-oauthlib = "^0.4.2" -graphviz = "^0.16" +google-api-python-client = "^2.0.0" +google-auth-httplib2 = "^0.1.0" +google-auth-oauthlib = "^0.8.0" +graphviz = "^0.20.0" inflection = "^0.5.1" -jsonschema = "^3.2.0" -networkx = "^2.5" +jsonschema = "^4.0.0" +networkx = ">=2.2.8" numpy = "^1.21.1" -oauth2client = "<4.0.0" # Specified because of bug in version ^4.0.0 +oauth2client = "^4.1.0" # Specified because of bug in version ^4.0.0 pandas = "^1.3.1" pygsheets = "^2.0.4" PyYAML = "^6.0.0" -rdflib = "^5.0.0" -setuptools = "^52.0.0" +rdflib = "^6.0.0" +setuptools = "^66.0.0" synapseclient = "^2.6.0" tenacity = "^8.0.1" toml = "^0.10.2" -Flask = ">=1.1.4" +Flask = "^2.0.0" connexion = {extras = ["swagger-ui"], version = "^2.8.0"} great-expectations = "^0.15.0" -sphinx-click = "^3.1.0" -MarkupSafe = "2.0.1" +sphinx-click = "^4.0.0" +MarkupSafe = "2.1.0" itsdangerous = "^2.0.0" Jinja2 = ">2.11.3" openpyxl = "^3.0.9" @@ -72,10 +72,10 @@ schematic-db = "^0.0.4" [tool.poetry.dev-dependencies] -pytest = "^6.2.2" -pytest-cov = "^2.11.1" +pytest = "^7.0.0" +pytest-cov = "^4.0.0" pytest-mock = "^3.5.1" -flake8 = "^3.8.4" +flake8 = "^6.0.0" python-dotenv = "^0.15.0" black = {version = "^22.6.0", allow-prereleases = true} From 860a6eb0bf36b4bd0a717d8b8e83c00b586a1765 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:50:08 -0700 Subject: [PATCH 071/615] update `python-dotenv` --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 103f842d4..601341590 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ pytest = "^7.0.0" pytest-cov = "^4.0.0" pytest-mock = "^3.5.1" flake8 = "^6.0.0" -python-dotenv = "^0.15.0" +python-dotenv = "^0.21.0" black = {version = "^22.6.0", allow-prereleases = true} From e27bc5e678ec07f418928bb8646558192ef48741 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:51:26 -0700 Subject: [PATCH 072/615] Revert "update `python-dotenv`" This reverts commit 860a6eb0bf36b4bd0a717d8b8e83c00b586a1765. --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 601341590..103f842d4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ pytest = "^7.0.0" pytest-cov = "^4.0.0" pytest-mock = "^3.5.1" flake8 = "^6.0.0" -python-dotenv = "^0.21.0" +python-dotenv = "^0.15.0" black = {version = "^22.6.0", allow-prereleases = true} From 03211b314846bf87be5bc3998b10fd70a18414dd Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 14:53:22 -0700 Subject: [PATCH 073/615] update `python-dotenv` --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index 004ba6910..af5f918e0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1851,11 +1851,11 @@ six = ">=1.5" [[package]] name = "python-dotenv" -version = "0.15.0" -description = "Add .env support to your django/flask apps in development and deployments" +version = "0.21.1" +description = "Read key-value pairs from a .env file and set them as environment variables" category = "dev" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.extras] cli = ["click (>=5.0)"] @@ -2632,7 +2632,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "866d25aeeb497f81c53616a8db3c5011e316f6a9fb50195449d0285febe16af0" +content-hash = "0a0f14e5e3bcd037d02670e9741ce17fcd6a11873e177221281805533fa4fecd" [metadata.files] alabaster = [ @@ -3739,8 +3739,8 @@ python-dateutil = [ {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, ] python-dotenv = [ - {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, - {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, + {file = "python-dotenv-0.21.1.tar.gz", hash = "sha256:1c93de8f636cde3ce377292818d0e440b6e45a82f215c3744979151fa8151c49"}, + {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, ] python-json-logger = [ {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, diff --git a/pyproject.toml b/pyproject.toml index 103f842d4..601341590 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -76,7 +76,7 @@ pytest = "^7.0.0" pytest-cov = "^4.0.0" pytest-mock = "^3.5.1" flake8 = "^6.0.0" -python-dotenv = "^0.15.0" +python-dotenv = "^0.21.0" black = {version = "^22.6.0", allow-prereleases = true} From 07362dfebf06d7704aef3ff7b9ea91076aeb9c43 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 24 Jan 2023 15:03:07 -0700 Subject: [PATCH 074/615] update to upcoming release version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 601341590..71f0488e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "schematicpy" -version = "1.0.0" +version = "22.3.2" description = "Package for biomedical data model and metadata ingress management" authors = [ "Milen Nikolov ", From 24fa1ca7f8e7dc73fd0f13375f445c31b1d351f7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 25 Jan 2023 16:57:54 -0700 Subject: [PATCH 075/615] update api for new parameter --- api/openapi/api.yaml | 5 +++++ api/routes.py | 4 +++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index f6d06965f..bedf0ae3b 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -298,6 +298,11 @@ paths: "Cancer Type": "Breast", "Family History": "Breast, Lung", }]' + - in: query + name: table_manipulation + schema: + type: string + enum: ["replace", "upsert"] operationId: api.routes.submit_manifest_route responses: "200": diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..c87f84995 100644 --- a/api/routes.py +++ b/api/routes.py @@ -370,13 +370,15 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None input_token = connexion.request.args["input_token"] + table_manipulation = connexion.request.args["table_manipulation"] + if data_type == 'None': validate_component = None else: validate_component = data_type manifest_id = metadata_model.submit_metadata_manifest( - path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules) + path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules, table_manipulation=table_manipulation) return manifest_id From fb36655bb47318c5897456b32cd40ef8c4fe5836 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 26 Jan 2023 09:54:21 -0700 Subject: [PATCH 076/615] fix function call --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index eac966b95..82e43984d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -870,7 +870,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, table_name=table_name, data = None) + manifest_table_id = TableOperations.upsertTable(self, tableName=table_name, data = None) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) else: From ad0066dd8bdb1f1199634773828303d0214bc714 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 26 Jan 2023 09:54:31 -0700 Subject: [PATCH 077/615] add message to error --- schematic/store/synapse.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 82e43984d..ddbb1fa89 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1614,7 +1614,9 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No return existingTableId def upsertTable(synStore, tableName: str = None, data: pd.DataFrame = None): - raise NotImplementedError + raise NotImplementedError( + "Table upsert functionality has not been implemented yet." + ) def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, updateCol: str = 'Uuid', restrict: bool = False): """ From 9e3417273ef426a8424bff349dc308fd02582508 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 27 Jan 2023 10:56:01 -0800 Subject: [PATCH 078/615] add get_nodes_display_names endpoint to api.yaml --- api/openapi/api.yaml | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index f6d06965f..32337c96f 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -891,6 +891,39 @@ paths: description: Check schematic log. tags: - Schema Operation + + /schemas/get_nodes_display_names: + get: + summary: Get display names for nodes labels in a list. + description: et display names for nodes labels in a list. + operationId: api.routes.get_nodes_display_names + parameters: + - in: query + name: schema_url + schema: + type: string + description: Data Model URL + example: >- + https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld + required: true + - in: query + name: node_list + schema: + type: array + items: + type: string + nullable: false + description: List of node labels. + example: ['FamilyHistory', 'Biospecimen'] + required: true + responses: + "200": + description: return List[str] + "500": + description: Check schematic log. + tags: + - Schema Operation + /visualize/tangled_tree/layers: get: summary: Get layers of tangled tree. From 6696fd805e4334ebb80e546b5142286786ec5af8 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 27 Jan 2023 10:56:30 -0800 Subject: [PATCH 079/615] add get_nodes_diplay_names route --- api/routes.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..851afcbfb 100644 --- a/api/routes.py +++ b/api/routes.py @@ -688,4 +688,19 @@ def get_if_node_required(schema_url: str, node_display_name: str) -> bool: return is_required +def get_nodes_display_names(schema_url: str, node_list: list[str]) -> list: + """From a list of node labels retrieve their display names, return as list. + + Args: + schema_url (str): Data Model URL + node_list (List[str]): List of node labels. + + Returns: + node_display_names (List[str]): List of node display names. + + """ + gen = SchemaGenerator(path_to_json_ld=schema_url) + mm_graph = gen.se.get_nx_schema() + node_display_names = gen.get_nodes_display_names(node_list, mm_graph) + return node_display_names From 46c8bb4623088d8b93aa6e766232d98c0a6612a2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 27 Jan 2023 12:40:50 -0700 Subject: [PATCH 080/615] update `schematic-db` to `v0.0.6` --- poetry.lock | 242 +++++++++++++++++++++---------------------------- pyproject.toml | 2 +- 2 files changed, 103 insertions(+), 141 deletions(-) diff --git a/poetry.lock b/poetry.lock index af5f918e0..31d5b32d4 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,7 +8,7 @@ python-versions = ">=3.6" [[package]] name = "altair" -version = "4.2.0" +version = "4.2.1" description = "Altair: A declarative statistical visualization library for Python." category = "main" optional = false @@ -298,7 +298,7 @@ test = ["pytest"] [[package]] name = "connexion" -version = "2.14.1" +version = "2.14.2" description = "Connexion - API first applications with OpenAPI/Swagger and Flask" category = "main" optional = false @@ -306,7 +306,7 @@ python-versions = ">=3.6" [package.dependencies] clickclick = ">=1.2,<21" -flask = ">=1.0.4,<3" +flask = ">=1.0.4,<2.3" inflection = ">=0.3.1,<0.6" itsdangerous = ">=0.24" jsonschema = ">=2.5.1,<5" @@ -314,18 +314,18 @@ packaging = ">=20" PyYAML = ">=5.1,<7" requests = ">=2.9.1,<3" swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""} -werkzeug = ">=1.0,<3" +werkzeug = ">=1.0,<2.3" [package.extras] aiohttp = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)"] docs = ["sphinx-autoapi (==1.8.1)"] -flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"] +flask = ["flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)"] swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] -tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] +tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] [[package]] name = "coverage" -version = "7.0.5" +version = "7.1.0" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -645,7 +645,7 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= [[package]] name = "great-expectations" -version = "0.15.44" +version = "0.15.46" description = "Always know what to expect from your data." category = "main" optional = false @@ -695,7 +695,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -710,7 +710,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.6.0)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -816,7 +816,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.8.0" +version = "8.9.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -831,7 +831,7 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=3.0.11,<3.1.0" +prompt-toolkit = ">=3.0.30,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" @@ -1006,24 +1006,23 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jupyter-client" -version = "7.4.9" +version = "8.0.1" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -entrypoints = "*" -jupyter-core = ">=4.9.2" -nest-asyncio = ">=1.5.4" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" -traitlets = "*" +traitlets = ">=5.3" [package.extras] -doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -test = ["codecov", "coverage", "ipykernel (>=6.12)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" @@ -1254,18 +1253,10 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "mysqlclient" -version = "2.1.1" -description = "Python interface to MySQL" -category = "main" -optional = false -python-versions = ">=3.5" - [[package]] name = "nbclassic" -version = "0.4.8" -description = "A web-based notebook environment for interactive computing" +version = "0.5.1" +description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false python-versions = ">=3.7" @@ -1277,7 +1268,7 @@ ipython-genutils = "*" jinja2 = "*" jupyter-client = ">=6.1.1" jupyter-core = ">=4.6.1" -jupyter-server = ">=1.8" +jupyter-server = ">=1.17.0" nbconvert = ">=5" nbformat = "*" nest-asyncio = ">=1.5" @@ -1292,7 +1283,7 @@ traitlets = ">=4.2.1" [package.extras] docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] json-logging = ["json-logging"] -test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] +test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] [[package]] name = "nbclient" @@ -1530,7 +1521,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.10.3" +version = "0.11.0" description = "Utility library for gitignore style pattern matching of file paths." category = "main" optional = false @@ -1636,14 +1627,6 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] -[[package]] -name = "psycopg2" -version = "2.9.5" -description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" -optional = false -python-versions = ">=3.6" - [[package]] name = "ptyprocess" version = "0.7.0" @@ -2047,7 +2030,7 @@ python-versions = ">=3.5" [[package]] name = "schematic-db" -version = "0.0.4" +version = "0.0.6" description = "" category = "main" optional = false @@ -2056,20 +2039,23 @@ python-versions = ">=3.9,<4.0" [package.dependencies] black = ">=22.6.0,<23.0.0" mypy = ">=0.982,<0.983" -mysqlclient = ">=2.1.1,<3.0.0" networkx = ">=2.8.6,<3.0.0" pandas = ">=1.4.3,<2.0.0" pdoc = ">=12.1.0,<13.0.0" -psycopg2 = ">=2.9.5,<3.0.0" pylint = ">=2.15.4,<3.0.0" pytest-mock = ">=3.10.0,<4.0.0" PyYAML = ">=6.0,<7.0" requests = ">=2.28.1,<3.0.0" SQLAlchemy = ">=1.4.39,<2.0.0" SQLAlchemy-Utils = ">=0.38.3,<0.39.0" -synapseclient = ">=2.6.0,<3.0.0" +synapseclient = {version = ">=2.6.0,<3.0.0", optional = true, markers = "extra == \"synapse\""} tenacity = ">=8.1.0,<9.0.0" +[package.extras] +mysql = ["mysqlclient (>=2.1.1,<3.0.0)"] +postgres = ["psycopg2 (>=2.9.5,<3.0.0)"] +synapse = ["synapseclient (>=2.6.0,<3.0.0)"] + [[package]] name = "scipy" version = "1.10.0" @@ -2579,7 +2565,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.4.2" +version = "1.5.0" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2632,7 +2618,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "0a0f14e5e3bcd037d02670e9741ce17fcd6a11873e177221281805533fa4fecd" +content-hash = "b268daa6fbb4696ed28f1b35352775a63cf26ed49382b40a482c535ee3df0a1e" [metadata.files] alabaster = [ @@ -2640,8 +2626,8 @@ alabaster = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] altair = [ - {file = "altair-4.2.0-py3-none-any.whl", hash = "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a"}, - {file = "altair-4.2.0.tar.gz", hash = "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"}, + {file = "altair-4.2.1-py3-none-any.whl", hash = "sha256:67e099a651c78028c4e135e3b5bd9680ed7dd928ca7b61c9c7376c58e41d2b02"}, + {file = "altair-4.2.1.tar.gz", hash = "sha256:4939fd9119c57476bf305af9ca0bd1aa7779b2450b874d3623660e879d0fcad1"}, ] anyio = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, @@ -2909,61 +2895,61 @@ comm = [ {file = "comm-0.1.2.tar.gz", hash = "sha256:3e2f5826578e683999b93716285b3b1f344f157bf75fa9ce0a797564e742f062"}, ] connexion = [ - {file = "connexion-2.14.1-py2.py3-none-any.whl", hash = "sha256:f343717241b4c4802a694c38fee66fb1693c897fe4ea5a957fa9b3b07caf6394"}, - {file = "connexion-2.14.1.tar.gz", hash = "sha256:99aa5781e70a7b94f8ffae8cf89f309d49cdb811bbd65a8e2f2546f3b19a01e6"}, + {file = "connexion-2.14.2-py2.py3-none-any.whl", hash = "sha256:a73b96a0e07b16979a42cde7c7e26afe8548099e352cf350f80c57185e0e0b36"}, + {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, - {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, - {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, - {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, - {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, - {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, - {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, - {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, - {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, - {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, - {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, - {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, - {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, - {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, - {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"}, + {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"}, + {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"}, + {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"}, + {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"}, + {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"}, + {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"}, + {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"}, + {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"}, + {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"}, + {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"}, + {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"}, + {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"}, + {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] cryptography = [ {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, @@ -3099,8 +3085,8 @@ graphviz = [ {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ - {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, - {file = "great_expectations-0.15.44.tar.gz", hash = "sha256:547a3f252cfc41124b299b226399b1169b01e127e717f97ee5dd16e34d0e2a64"}, + {file = "great_expectations-0.15.46-py3-none-any.whl", hash = "sha256:06373b688fce107a6659766b29ac7abe6ab01c62ad8ceda57e0e2ffb9b05db35"}, + {file = "great_expectations-0.15.46.tar.gz", hash = "sha256:f674cb57dbd8fc993fcf7b2d167253bceaa79db13cea0f5a9c92fd6ea13870bc"}, ] greenlet = [ {file = "greenlet-2.0.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c"}, @@ -3193,8 +3179,8 @@ ipykernel = [ {file = "ipykernel-6.20.2.tar.gz", hash = "sha256:1893c5b847033cd7a58f6843b04a9349ffb1031bc6588401cadc9adb58da428e"}, ] ipython = [ - {file = "ipython-8.8.0-py3-none-any.whl", hash = "sha256:da01e6df1501e6e7c32b5084212ddadd4ee2471602e2cf3e0190f4de6b0ea481"}, - {file = "ipython-8.8.0.tar.gz", hash = "sha256:f3bf2c08505ad2c3f4ed5c46ae0331a8547d36bf4b21a451e8ae80c0791db95b"}, + {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, + {file = "ipython-8.9.0.tar.gz", hash = "sha256:71618e82e6d59487bea059626e7c79fb4a5b760d1510d02fab1160db6fdfa1f7"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -3245,8 +3231,8 @@ jsonschema = [ {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] jupyter-client = [ - {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, - {file = "jupyter_client-7.4.9.tar.gz", hash = "sha256:52be28e04171f07aed8f20e1616a5a552ab9fee9cbbe6c1896ae170c3880d392"}, + {file = "jupyter_client-8.0.1-py3-none-any.whl", hash = "sha256:6016b874fd1111d721bc5bee30624399e876e79e6f395d1a559e6dce9fb2e1ba"}, + {file = "jupyter_client-8.0.1.tar.gz", hash = "sha256:3f67b1c8b7687e6db09bef10ff97669932b5e6ef6f5a8ee56d444b89022c5007"}, ] jupyter-core = [ {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, @@ -3410,18 +3396,9 @@ mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] -mysqlclient = [ - {file = "mysqlclient-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:c1ed71bd6244993b526113cca3df66428609f90e4652f37eb51c33496d478b37"}, - {file = "mysqlclient-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:c812b67e90082a840efb82a8978369e6e69fc62ce1bda4ca8f3084a9d862308b"}, - {file = "mysqlclient-2.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:0d1cd3a5a4d28c222fa199002810e8146cffd821410b67851af4cc80aeccd97c"}, - {file = "mysqlclient-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b355c8b5a7d58f2e909acdbb050858390ee1b0e13672ae759e5e784110022994"}, - {file = "mysqlclient-2.1.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:996924f3483fd36a34a5812210c69e71dea5a3d5978d01199b78b7f6d485c855"}, - {file = "mysqlclient-2.1.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:dea88c8d3f5a5d9293dfe7f087c16dd350ceb175f2f6631c9cf4caf3e19b7a96"}, - {file = "mysqlclient-2.1.1.tar.gz", hash = "sha256:828757e419fb11dd6c5ed2576ec92c3efaa93a0f7c39e263586d1ee779c3d782"}, -] nbclassic = [ - {file = "nbclassic-0.4.8-py3-none-any.whl", hash = "sha256:cbf05df5842b420d5cece0143462380ea9d308ff57c2dc0eb4d6e035b18fbfb3"}, - {file = "nbclassic-0.4.8.tar.gz", hash = "sha256:c74d8a500f8e058d46b576a41e5bc640711e1032cf7541dde5f73ea49497e283"}, + {file = "nbclassic-0.5.1-py3-none-any.whl", hash = "sha256:32c235e1f22f4048f3b877d354c198202898797cf9c2085856827598cead001b"}, + {file = "nbclassic-0.5.1.tar.gz", hash = "sha256:8e8ffce7582bb7a4baf11fa86a3d88b184e8e7df78eed4ead69f15aa4fc0e323"}, ] nbclient = [ {file = "nbclient-0.7.2-py3-none-any.whl", hash = "sha256:d97ac6257de2794f5397609df754fcbca1a603e94e924eb9b99787c031ae2e7c"}, @@ -3535,8 +3512,8 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ - {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, - {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, + {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, + {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, ] pdoc = [ {file = "pdoc-12.3.1-py3-none-any.whl", hash = "sha256:c3f24f31286e634de9c76fa6e67bd5c0c5e74360b41dc91e6b82499831eb52d8"}, @@ -3596,21 +3573,6 @@ psutil = [ {file = "psutil-5.9.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e"}, {file = "psutil-5.9.4.tar.gz", hash = "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62"}, ] -psycopg2 = [ - {file = "psycopg2-2.9.5-cp310-cp310-win32.whl", hash = "sha256:d3ef67e630b0de0779c42912fe2cbae3805ebaba30cda27fea2a3de650a9414f"}, - {file = "psycopg2-2.9.5-cp310-cp310-win_amd64.whl", hash = "sha256:4cb9936316d88bfab614666eb9e32995e794ed0f8f6b3b718666c22819c1d7ee"}, - {file = "psycopg2-2.9.5-cp311-cp311-win32.whl", hash = "sha256:093e3894d2d3c592ab0945d9eba9d139c139664dcf83a1c440b8a7aa9bb21955"}, - {file = "psycopg2-2.9.5-cp311-cp311-win_amd64.whl", hash = "sha256:920bf418000dd17669d2904472efeab2b20546efd0548139618f8fa305d1d7ad"}, - {file = "psycopg2-2.9.5-cp36-cp36m-win32.whl", hash = "sha256:b9ac1b0d8ecc49e05e4e182694f418d27f3aedcfca854ebd6c05bb1cffa10d6d"}, - {file = "psycopg2-2.9.5-cp36-cp36m-win_amd64.whl", hash = "sha256:fc04dd5189b90d825509caa510f20d1d504761e78b8dfb95a0ede180f71d50e5"}, - {file = "psycopg2-2.9.5-cp37-cp37m-win32.whl", hash = "sha256:922cc5f0b98a5f2b1ff481f5551b95cd04580fd6f0c72d9b22e6c0145a4840e0"}, - {file = "psycopg2-2.9.5-cp37-cp37m-win_amd64.whl", hash = "sha256:1e5a38aa85bd660c53947bd28aeaafb6a97d70423606f1ccb044a03a1203fe4a"}, - {file = "psycopg2-2.9.5-cp38-cp38-win32.whl", hash = "sha256:f5b6320dbc3cf6cfb9f25308286f9f7ab464e65cfb105b64cc9c52831748ced2"}, - {file = "psycopg2-2.9.5-cp38-cp38-win_amd64.whl", hash = "sha256:1a5c7d7d577e0eabfcf15eb87d1e19314c8c4f0e722a301f98e0e3a65e238b4e"}, - {file = "psycopg2-2.9.5-cp39-cp39-win32.whl", hash = "sha256:322fd5fca0b1113677089d4ebd5222c964b1760e361f151cbb2706c4912112c5"}, - {file = "psycopg2-2.9.5-cp39-cp39-win_amd64.whl", hash = "sha256:190d51e8c1b25a47484e52a79638a8182451d6f6dff99f26ad9bd81e5359a0fa"}, - {file = "psycopg2-2.9.5.tar.gz", hash = "sha256:a5246d2e683a972e2187a8714b5c2cf8156c064629f9a9b1a873c1730d9e245a"}, -] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, @@ -4057,8 +4019,8 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] schematic-db = [ - {file = "schematic_db-0.0.4-py3-none-any.whl", hash = "sha256:ace33e59dec49acdc5749b5a8f1254087344e04676042ccdc5cd07253009bcf7"}, - {file = "schematic_db-0.0.4.tar.gz", hash = "sha256:d0da4fc36dafe40040abcb27482b170776d03b406e5e31686ebd127b00032293"}, + {file = "schematic_db-0.0.6-py3-none-any.whl", hash = "sha256:4bcf7ca487e88af52c2e77f31f7c0cb5f967617d68d2efe8433f57abb1c40ac8"}, + {file = "schematic_db-0.0.6.tar.gz", hash = "sha256:d3505850fb7c23d5c2dd1ad2147cfb29ab86eaf72bf71b390f7707545576bb88"}, ] scipy = [ {file = "scipy-1.10.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b901b423c91281a974f6cd1c36f5c6c523e665b5a6d5e80fcb2334e14670eefd"}, @@ -4288,8 +4250,8 @@ webencodings = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.4.2.tar.gz", hash = "sha256:d6e8f90ca8e2dd4e8027c4561adeb9456b54044312dba655e7cae652ceb9ae59"}, - {file = "websocket_client-1.4.2-py3-none-any.whl", hash = "sha256:d6b06432f184438d99ac1f456eaf22fe1ade524c3dd16e661142dc54e9cba574"}, + {file = "websocket-client-1.5.0.tar.gz", hash = "sha256:561ca949e5bbb5d33409a37235db55c279235c78ee407802f1d2314fff8a8536"}, + {file = "websocket_client-1.5.0-py3-none-any.whl", hash = "sha256:fb5d81b95d350f3a54838ebcb4c68a5353bbd1412ae8f068b1e5280faeb13074"}, ] werkzeug = [ {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, diff --git a/pyproject.toml b/pyproject.toml index 71f0488e6..d94950f0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ openpyxl = "^3.0.9" Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" -schematic-db = "^0.0.4" +schematic-db = {version = "^0.0.6", extras = ["synapse"]} [tool.poetry.dev-dependencies] From 6dccc16c5d187a47783f57f69b63ddb52c32e195 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 27 Jan 2023 12:04:31 -0800 Subject: [PATCH 081/615] add get_node_validation_rules to api.yaml --- api/openapi/api.yaml | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index f6d06965f..71ba98613 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -770,7 +770,35 @@ paths: tags: - Schema Operation - + /schemas/get_node_validation_rules: + get: + summary: Get validation rules for a given node + description: Get validation rules for a given node + operationId: api.routes.get_node_validation_rules + parameters: + - in: query + name: schema_url + schema: + type: string + description: Data Model URL + example: >- + https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld + required: true + - in: query + name: node_display_name + schema: + type: string + nullable: false + description: Display label of node + example: CheckRegexList + required: true + responses: + "200": + description: return a list + "500": + description: Check schematic log. + tags: + - Schema Operation /explorer/get_node_dependencies: From c25f2de44828844c92d16069ecc085e9e7760593 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 27 Jan 2023 12:04:56 -0800 Subject: [PATCH 082/615] add get_node_validation_rules call to routes --- api/routes.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..163293ccc 100644 --- a/api/routes.py +++ b/api/routes.py @@ -688,4 +688,16 @@ def get_if_node_required(schema_url: str, node_display_name: str) -> bool: return is_required +def get_node_validation_rules(schema_url: str, node_display_name: str) -> list: + """ + Args: + schema_url (str): Data Model URL + node_display_name (str): node display name + Returns: + List of valiation rules for a given node. + """ + gen = SchemaGenerator(path_to_json_ld=schema_url) + node_validation_rules = gen.get_node_validation_rules(node_display_name) + + return node_validation_rules From 092e7b2a2566c16790c008054b011805ced2bb51 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 27 Jan 2023 12:18:54 -0800 Subject: [PATCH 083/615] rearrange where get_nodes_display_names is located in api.yaml for clarity/organization --- api/openapi/api.yaml | 62 ++++++++++++++++++++++---------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 32337c96f..d173b68ac 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -770,6 +770,37 @@ paths: tags: - Schema Operation + /schemas/get_nodes_display_names: + get: + summary: Get display names for nodes labels in a list. + description: et display names for nodes labels in a list. + operationId: api.routes.get_nodes_display_names + parameters: + - in: query + name: schema_url + schema: + type: string + description: Data Model URL + example: >- + https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld + required: true + - in: query + name: node_list + schema: + type: array + items: + type: string + nullable: false + description: List of node labels. + example: ['FamilyHistory', 'Biospecimen'] + required: true + responses: + "200": + description: return List[str] + "500": + description: Check schematic log. + tags: + - Schema Operation @@ -892,37 +923,6 @@ paths: tags: - Schema Operation - /schemas/get_nodes_display_names: - get: - summary: Get display names for nodes labels in a list. - description: et display names for nodes labels in a list. - operationId: api.routes.get_nodes_display_names - parameters: - - in: query - name: schema_url - schema: - type: string - description: Data Model URL - example: >- - https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld - required: true - - in: query - name: node_list - schema: - type: array - items: - type: string - nullable: false - description: List of node labels. - example: ['FamilyHistory', 'Biospecimen'] - required: true - responses: - "200": - description: return List[str] - "500": - description: Check schematic log. - tags: - - Schema Operation /visualize/tangled_tree/layers: get: From 04cf3d837a7281c3dea2a3b393f77ac846989e03 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:50:09 -0700 Subject: [PATCH 084/615] add new library --- poetry.lock | 461 +++++++++++++++++++++++++++++++++++-------------- pyproject.toml | 2 +- 2 files changed, 335 insertions(+), 128 deletions(-) diff --git a/poetry.lock b/poetry.lock index 23ab3478e..2cec41288 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,7 +8,7 @@ python-versions = ">=3.6" [[package]] name = "altair" -version = "4.2.0" +version = "4.2.2" description = "Altair: A declarative statistical visualization library for Python." category = "main" optional = false @@ -145,6 +145,21 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "black" version = "20.8b1" @@ -272,7 +287,7 @@ test = ["pytest"] [[package]] name = "connexion" -version = "2.14.1" +version = "2.14.2" description = "Connexion - API first applications with OpenAPI/Swagger and Flask" category = "main" optional = false @@ -280,7 +295,7 @@ python-versions = ">=3.6" [package.dependencies] clickclick = ">=1.2,<21" -flask = ">=1.0.4,<3" +flask = ">=1.0.4,<2.3" inflection = ">=0.3.1,<0.6" itsdangerous = ">=0.24" jsonschema = ">=2.5.1,<5" @@ -288,18 +303,18 @@ packaging = ">=20" PyYAML = ">=5.1,<7" requests = ">=2.9.1,<3" swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""} -werkzeug = ">=1.0,<3" +werkzeug = ">=1.0,<2.3" [package.extras] aiohttp = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)"] docs = ["sphinx-autoapi (==1.8.1)"] -flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"] +flask = ["flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)"] swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] -tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] +tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] [[package]] name = "coverage" -version = "7.0.5" +version = "7.1.0" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -384,6 +399,17 @@ wrapt = ">=1.10,<2" [package.extras] dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +[[package]] +name = "dill" +version = "0.3.6" +description = "serialize all of python" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +graph = ["objgraph (>=1.7.2)"] + [[package]] name = "docutils" version = "0.19" @@ -587,7 +613,7 @@ test = ["mock (>=3)", "pytest (>=4)", "pytest-cov", "pytest-mock (>=2)"] [[package]] name = "great-expectations" -version = "0.15.44" +version = "0.15.46" description = "Always know what to expect from your data." category = "main" optional = false @@ -637,7 +663,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -652,7 +678,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.6.0)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -746,7 +772,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.8.0" +version = "8.9.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -761,7 +787,7 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=3.0.11,<3.1.0" +prompt-toolkit = ">=3.0.30,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" @@ -895,9 +921,14 @@ python-versions = "*" [package.dependencies] attrs = ">=17.4.0" +idna = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format_nongpl\""} pyrsistent = ">=0.14.0" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format_nongpl\""} setuptools = "*" six = ">=1.11.0" +webcolors = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} [package.extras] format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] @@ -905,24 +936,23 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "jupyter-client" -version = "7.4.9" +version = "8.0.1" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -entrypoints = "*" -jupyter-core = ">=4.9.2" -nest-asyncio = ">=1.5.4" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" -traitlets = "*" +traitlets = ">=5.3" [package.extras] -doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -test = ["codecov", "coverage", "ipykernel (>=6.12)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" @@ -941,34 +971,82 @@ traitlets = ">=5.3" docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "jupyter-events" +version = "0.6.3" +description = "Jupyter Event System library" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +jsonschema = {version = ">=3.2.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "pytest-cov", "rich"] + [[package]] name = "jupyter-server" -version = "1.15.6" +version = "2.1.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -anyio = ">=3.1.0" +anyio = ">=3.1.0,<4" argon2-cffi = "*" jinja2 = "*" -jupyter-client = ">=6.1.1" -jupyter-core = ">=4.6.0" -nbconvert = "*" -nbformat = ">=5.2.0" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-events = ">=0.4.0" +jupyter-server-terminals = "*" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" packaging = "*" prometheus-client = "*" pywinpty = {version = "*", markers = "os_name == \"nt\""} -pyzmq = ">=17" -Send2Trash = "*" +pyzmq = ">=24" +send2trash = "*" terminado = ">=0.8.3" -tornado = ">=6.1.0" -traitlets = ">=5" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" websocket-client = "*" [package.extras] -test = ["coverage", "ipykernel", "pytest (>=6.0)", "pytest-console-scripts", "pytest-cov", "pytest-mock", "pytest-timeout", "pytest-tornasync", "requests"] +docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.4.4" +description = "A Jupyter Server Extension Providing Terminals." +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<3.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.2.2" +description = "Pygments theme using JupyterLab CSS variables" +category = "main" +optional = false +python-versions = ">=3.7" [[package]] name = "jupyterlab-widgets" @@ -1065,8 +1143,8 @@ python-versions = "*" [[package]] name = "mistune" -version = "2.0.4" -description = "A sane Markdown parser with useful plugins and renderers" +version = "0.8.4" +description = "The fastest markdown parser in pure Python" category = "main" optional = false python-versions = "*" @@ -1081,8 +1159,8 @@ python-versions = "*" [[package]] name = "nbclassic" -version = "0.4.8" -description = "A web-based notebook environment for interactive computing" +version = "0.5.1" +description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false python-versions = ">=3.7" @@ -1094,7 +1172,7 @@ ipython-genutils = "*" jinja2 = "*" jupyter-client = ">=6.1.1" jupyter-core = ">=4.6.1" -jupyter-server = ">=1.8" +jupyter-server = ">=1.17.0" nbconvert = ">=5" nbformat = "*" nest-asyncio = ">=1.5" @@ -1109,35 +1187,57 @@ traitlets = ">=4.2.1" [package.extras] docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] json-logging = ["json-logging"] -test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] +test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] + +[[package]] +name = "nbclient" +version = "0.5.13" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "main" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +jupyter-client = ">=6.1.5" +nbformat = ">=5.0" +nest-asyncio = "*" +traitlets = ">=5.0.0" + +[package.extras] +sphinx = ["Sphinx (>=1.7)", "mock", "moto", "myst-parser", "sphinx-book-theme"] +test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "ipywidgets (<8.0.0)", "mypy", "pip (>=18.1)", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=38.6.0)", "twine (>=1.11.0)", "wheel (>=0.31.0)", "xmltodict"] [[package]] name = "nbconvert" -version = "5.5.0" +version = "6.4.5" description = "Converting Jupyter Notebooks" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] +beautifulsoup4 = "*" bleach = "*" defusedxml = "*" entrypoints = ">=0.2.2" jinja2 = ">=2.4" jupyter-core = "*" -mistune = ">=0.8.1" +jupyterlab-pygments = "*" +MarkupSafe = ">=2.0" +mistune = ">=0.8.1,<2" +nbclient = ">=0.5.0,<0.6.0" nbformat = ">=4.4" pandocfilters = ">=1.4.1" -pygments = "*" +pygments = ">=2.4.1" testpath = "*" -traitlets = ">=4.2" +traitlets = ">=5.0" [package.extras] -all = ["ipykernel", "ipython", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "pytest", "pytest-cov", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt", "tornado (>=4.0)"] -docs = ["ipython", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -execute = ["jupyter-client (>=4.2)"] +all = ["ipykernel", "ipython", "ipywidgets (>=7)", "nbsphinx (>=0.2.12)", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "tornado (>=4.0)"] +docs = ["ipython", "nbsphinx (>=0.2.12)", "sphinx (>=1.5.1)", "sphinx-rtd-theme"] serve = ["tornado (>=4.0)"] -test = ["ipykernel", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "pytest", "pytest-cov"] +test = ["ipykernel", "ipywidgets (>=7)", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency"] +webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] name = "nbformat" @@ -1280,6 +1380,23 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "pandarallel" +version = "1.6.4" +description = "An easy to use library to speed up computation (by parallelizing on multi CPUs) with pandas." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +dill = ">=0.3.1" +pandas = ">=1" +psutil = "*" + +[package.extras] +dev = ["numpy", "pytest", "pytest-cov"] +doc = ["mkdocs-material"] + [[package]] name = "pandas" version = "1.5.3" @@ -1321,7 +1438,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.10.3" +version = "0.11.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false @@ -1630,6 +1747,14 @@ python-versions = "*" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-json-logger" +version = "2.0.4" +description = "A python library adding a json log formatter" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "pytz" version = "2022.7.1" @@ -1752,6 +1877,25 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "rsa" version = "4.9" @@ -1865,6 +2009,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "sphinx" version = "5.1.1" @@ -2190,6 +2342,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "webcolors" +version = "1.12" +description = "A library for working with color names and color values formats defined by HTML and CSS." +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "webencodings" version = "0.5.1" @@ -2200,7 +2360,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.4.2" +version = "1.5.0" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2241,20 +2401,20 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.11.0" +version = "3.12.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "07e5b9f29e35366d3bb1402137bf8b98a7e0a5a1fdcf26856a0b1c675535b876" +content-hash = "e82d6157ac805d5de2a0e2213ade4a1d8091e0c0225c984c8ab9265028c253f8" [metadata.files] alabaster = [ @@ -2262,8 +2422,8 @@ alabaster = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] altair = [ - {file = "altair-4.2.0-py3-none-any.whl", hash = "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a"}, - {file = "altair-4.2.0.tar.gz", hash = "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"}, + {file = "altair-4.2.2-py3-none-any.whl", hash = "sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87"}, + {file = "altair-4.2.2.tar.gz", hash = "sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5"}, ] anyio = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, @@ -2323,6 +2483,10 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] @@ -2515,61 +2679,61 @@ comm = [ {file = "comm-0.1.2.tar.gz", hash = "sha256:3e2f5826578e683999b93716285b3b1f344f157bf75fa9ce0a797564e742f062"}, ] connexion = [ - {file = "connexion-2.14.1-py2.py3-none-any.whl", hash = "sha256:f343717241b4c4802a694c38fee66fb1693c897fe4ea5a957fa9b3b07caf6394"}, - {file = "connexion-2.14.1.tar.gz", hash = "sha256:99aa5781e70a7b94f8ffae8cf89f309d49cdb811bbd65a8e2f2546f3b19a01e6"}, + {file = "connexion-2.14.2-py2.py3-none-any.whl", hash = "sha256:a73b96a0e07b16979a42cde7c7e26afe8548099e352cf350f80c57185e0e0b36"}, + {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, - {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, - {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, - {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, - {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, - {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, - {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, - {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, - {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, - {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, - {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, - {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, - {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, - {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, - {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"}, + {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"}, + {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"}, + {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"}, + {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"}, + {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"}, + {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"}, + {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"}, + {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"}, + {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"}, + {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"}, + {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"}, + {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"}, + {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] cryptography = [ {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, @@ -2632,6 +2796,10 @@ deprecated = [ {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, ] +dill = [ + {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, + {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, +] docutils = [ {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, @@ -2693,8 +2861,8 @@ graphviz = [ {file = "graphviz-0.16.zip", hash = "sha256:d2d25af1c199cad567ce4806f0449cb74eb30cf451fd7597251e1da099ac6e57"}, ] great-expectations = [ - {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, - {file = "great_expectations-0.15.44.tar.gz", hash = "sha256:547a3f252cfc41124b299b226399b1169b01e127e717f97ee5dd16e34d0e2a64"}, + {file = "great_expectations-0.15.46-py3-none-any.whl", hash = "sha256:06373b688fce107a6659766b29ac7abe6ab01c62ad8ceda57e0e2ffb9b05db35"}, + {file = "great_expectations-0.15.46.tar.gz", hash = "sha256:f674cb57dbd8fc993fcf7b2d167253bceaa79db13cea0f5a9c92fd6ea13870bc"}, ] httplib2 = [ {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, @@ -2725,8 +2893,8 @@ ipykernel = [ {file = "ipykernel-6.20.2.tar.gz", hash = "sha256:1893c5b847033cd7a58f6843b04a9349ffb1031bc6588401cadc9adb58da428e"}, ] ipython = [ - {file = "ipython-8.8.0-py3-none-any.whl", hash = "sha256:da01e6df1501e6e7c32b5084212ddadd4ee2471602e2cf3e0190f4de6b0ea481"}, - {file = "ipython-8.8.0.tar.gz", hash = "sha256:f3bf2c08505ad2c3f4ed5c46ae0331a8547d36bf4b21a451e8ae80c0791db95b"}, + {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, + {file = "ipython-8.9.0.tar.gz", hash = "sha256:71618e82e6d59487bea059626e7c79fb4a5b760d1510d02fab1160db6fdfa1f7"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -2769,16 +2937,28 @@ jsonschema = [ {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] jupyter-client = [ - {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, - {file = "jupyter_client-7.4.9.tar.gz", hash = "sha256:52be28e04171f07aed8f20e1616a5a552ab9fee9cbbe6c1896ae170c3880d392"}, + {file = "jupyter_client-8.0.1-py3-none-any.whl", hash = "sha256:6016b874fd1111d721bc5bee30624399e876e79e6f395d1a559e6dce9fb2e1ba"}, + {file = "jupyter_client-8.0.1.tar.gz", hash = "sha256:3f67b1c8b7687e6db09bef10ff97669932b5e6ef6f5a8ee56d444b89022c5007"}, ] jupyter-core = [ {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, {file = "jupyter_core-5.1.5.tar.gz", hash = "sha256:8e54c48cde1e0c8345f64bcf9658b78044ddf02b273726cea9d9f59be4b02130"}, ] +jupyter-events = [ + {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, + {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, +] jupyter-server = [ - {file = "jupyter_server-1.15.6-py3-none-any.whl", hash = "sha256:e393934c19fcc324a7fca77f811eacd91201440f04c6fbb15c959c463baaa9c5"}, - {file = "jupyter_server-1.15.6.tar.gz", hash = "sha256:56bd6f580d1f46b62294990e8e78651025729f5d3fc798f10f2c03f0cdcbf28d"}, + {file = "jupyter_server-2.1.0-py3-none-any.whl", hash = "sha256:90cd6f2bd0581ddd9b2dbe82026a0f4c228a1d95c86e22460efbfdfc931fcf56"}, + {file = "jupyter_server-2.1.0.tar.gz", hash = "sha256:efaae5e4f0d5f22c7f2f2dc848635036ee74a2df02abed52d30d9d95121ad382"}, +] +jupyter-server-terminals = [ + {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, + {file = "jupyter_server_terminals-0.4.4.tar.gz", hash = "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d"}, +] +jupyterlab-pygments = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, ] jupyterlab-widgets = [ {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, @@ -2880,20 +3060,24 @@ mccabe = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] mistune = [ - {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, - {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, + {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, + {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] nbclassic = [ - {file = "nbclassic-0.4.8-py3-none-any.whl", hash = "sha256:cbf05df5842b420d5cece0143462380ea9d308ff57c2dc0eb4d6e035b18fbfb3"}, - {file = "nbclassic-0.4.8.tar.gz", hash = "sha256:c74d8a500f8e058d46b576a41e5bc640711e1032cf7541dde5f73ea49497e283"}, + {file = "nbclassic-0.5.1-py3-none-any.whl", hash = "sha256:32c235e1f22f4048f3b877d354c198202898797cf9c2085856827598cead001b"}, + {file = "nbclassic-0.5.1.tar.gz", hash = "sha256:8e8ffce7582bb7a4baf11fa86a3d88b184e8e7df78eed4ead69f15aa4fc0e323"}, +] +nbclient = [ + {file = "nbclient-0.5.13-py3-none-any.whl", hash = "sha256:47ac905af59379913c1f8f541098d2550153cf8dc58553cbe18c702b181518b0"}, + {file = "nbclient-0.5.13.tar.gz", hash = "sha256:40c52c9b5e3c31faecaee69f202b3f53e38d7c1c563de0fadde9d7eda0fdafe8"}, ] nbconvert = [ - {file = "nbconvert-5.5.0-py2.py3-none-any.whl", hash = "sha256:4a978548d8383f6b2cfca4a3b0543afb77bc7cb5a96e8b424337ab58c12da9bc"}, - {file = "nbconvert-5.5.0.tar.gz", hash = "sha256:138381baa41d83584459b5cfecfc38c800ccf1f37d9ddd0bd440783346a4c39c"}, + {file = "nbconvert-6.4.5-py3-none-any.whl", hash = "sha256:e01d219f55cc79f9701c834d605e8aa3acf35725345d3942e3983937f368ce14"}, + {file = "nbconvert-6.4.5.tar.gz", hash = "sha256:21163a8e2073c07109ca8f398836e45efdba2aacea68d6f75a8a545fef070d4e"}, ] nbformat = [ {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, @@ -2960,6 +3144,9 @@ packaging = [ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] +pandarallel = [ + {file = "pandarallel-1.6.4.tar.gz", hash = "sha256:70091652485050241ffac37c3e94d21732697c63ee4613ae7bf85da076be41f2"}, +] pandas = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, @@ -2998,8 +3185,8 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ - {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, - {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, + {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, + {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, ] pdoc = [ {file = "pdoc-12.3.1-py3-none-any.whl", hash = "sha256:c3f24f31286e634de9c76fa6e67bd5c0c5e74360b41dc91e6b82499831eb52d8"}, @@ -3190,6 +3377,10 @@ python-dotenv = [ {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, ] +python-json-logger = [ + {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, + {file = "python_json_logger-2.0.4-py3-none-any.whl", hash = "sha256:3b03487b14eb9e4f77e4fc2a023358b5394b82fd89cecf5586259baed57d8c6f"}, +] pytz = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, @@ -3438,6 +3629,14 @@ requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, ] +rfc3339-validator = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] +rfc3986-validator = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] rsa = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -3528,6 +3727,10 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] sphinx = [ {file = "Sphinx-5.1.1-py3-none-any.whl", hash = "sha256:309a8da80cb6da9f4713438e5b55861877d5d7976b69d87e336733637ea12693"}, {file = "Sphinx-5.1.1.tar.gz", hash = "sha256:ba3224a4e206e1fbdecf98a4fae4992ef9b24b85ebf7b584bb340156eaf08d89"}, @@ -3663,13 +3866,17 @@ wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +webcolors = [ + {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"}, + {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"}, +] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.4.2.tar.gz", hash = "sha256:d6e8f90ca8e2dd4e8027c4561adeb9456b54044312dba655e7cae652ceb9ae59"}, - {file = "websocket_client-1.4.2-py3-none-any.whl", hash = "sha256:d6b06432f184438d99ac1f456eaf22fe1ade524c3dd16e661142dc54e9cba574"}, + {file = "websocket-client-1.5.0.tar.gz", hash = "sha256:561ca949e5bbb5d33409a37235db55c279235c78ee407802f1d2314fff8a8536"}, + {file = "websocket_client-1.5.0-py3-none-any.whl", hash = "sha256:fb5d81b95d350f3a54838ebcb4c68a5353bbd1412ae8f068b1e5280faeb13074"}, ] werkzeug = [ {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, @@ -3746,6 +3953,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, - {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, + {file = "zipp-3.12.0-py3-none-any.whl", hash = "sha256:9eb0a4c5feab9b08871db0d672745b53450d7f26992fd1e4653aa43345e97b86"}, + {file = "zipp-3.12.0.tar.gz", hash = "sha256:73efd63936398aac78fd92b6f4865190119d6c91b531532e798977ea8dd402eb"}, ] diff --git a/pyproject.toml b/pyproject.toml index 41eb59dc4..a10ab89cf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -68,7 +68,7 @@ openpyxl = "^3.0.9" Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" - +pandarallel = "^1.6.4" [tool.poetry.dev-dependencies] pytest = "^6.2.2" From d88c4f303e834bee898c546ba28638e46ae554dc Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:50:53 -0700 Subject: [PATCH 085/615] parallelize operations in `load_df` --- schematic/utils/df_utils.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 800c2e6e8..5da7e642a 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -5,6 +5,8 @@ from copy import deepcopy import dateparser as dp import datetime as dt +from pandarallel import pandarallel +import time logger = logging.getLogger(__name__) @@ -33,13 +35,16 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): return org_df else: + + pandarallel.initialize(verbose = 1) + float_df=deepcopy(org_df) #Find integers stored as strings #Cast the columns in dataframe to string while preserving NaN null_cells = org_df.isnull() org_df = org_df.astype(str).mask(null_cells, '') - ints = org_df.applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) - dates = org_df.applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) + ints = org_df.parallel_applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) + dates = org_df.parallel_applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) #convert strings to numerical dtype (float) if possible, preserve non-numerical strings for col in org_df.columns: From 3dd06e6e943848faf1ba09ea83bd834fee6d6593 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 27 Jan 2023 16:51:35 -0700 Subject: [PATCH 086/615] remove time import --- schematic/utils/df_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 5da7e642a..81f6e5038 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -6,7 +6,6 @@ import dateparser as dp import datetime as dt from pandarallel import pandarallel -import time logger = logging.getLogger(__name__) From d4a2ddd4129e539d51b2321144f433643f2645c8 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 30 Jan 2023 12:51:10 -0700 Subject: [PATCH 087/615] return None when not passing in dt through cli --- schematic/utils/cli_utils.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/utils/cli_utils.py b/schematic/utils/cli_utils.py index 3421d1be8..8a1f27ad5 100644 --- a/schematic/utils/cli_utils.py +++ b/schematic/utils/cli_utils.py @@ -162,4 +162,7 @@ def parse_comma_str_to_list( ctx, param, comma_string, ) -> List[str]: - return comma_string.split(",") \ No newline at end of file + if comma_string: + return comma_string.split(",") + else: + return None \ No newline at end of file From f2c8728115b1af53f477cde4e86096347a69c035 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 30 Jan 2023 12:51:30 -0700 Subject: [PATCH 088/615] fill data type from config if not in cli --- schematic/models/commands.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 1444cb6b8..18a620661 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -202,7 +202,8 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules """ Running CLI for manifest validation. """ - data_type = fill_in_from_config("data_type", data_type, ("manifest", "data_type")) + if not data_type: + data_type = fill_in_from_config("data_type", data_type, ("manifest", "data_type")) try: len(data_type) == 1 From a3576af4f9b1284c0e636f0432e0cccfb9c8bc30 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 30 Jan 2023 14:00:23 -0700 Subject: [PATCH 089/615] only parallelize for large manifests --- schematic/utils/df_utils.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 81f6e5038..f34f02c01 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -34,16 +34,19 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): return org_df else: - - pandarallel.initialize(verbose = 1) - float_df=deepcopy(org_df) #Find integers stored as strings #Cast the columns in dataframe to string while preserving NaN null_cells = org_df.isnull() org_df = org_df.astype(str).mask(null_cells, '') - ints = org_df.parallel_applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) - dates = org_df.parallel_applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) + + if org_df.size < 1000: + ints = org_df.applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) + dates = org_df.applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) + else: + pandarallel.initialize(verbose = 1) + ints = org_df.parallel_applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) + dates = org_df.parallel_applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) #convert strings to numerical dtype (float) if possible, preserve non-numerical strings for col in org_df.columns: From ce9fc13bcb15a085873372e4bcb587bc444ea77c Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 31 Jan 2023 12:19:23 -0500 Subject: [PATCH 090/615] add test_get_nodes_display_names test --- tests/test_api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..5e5c86d53 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -213,6 +213,17 @@ def test_if_node_required(test, client, data_model_jsonld): assert response.status_code == 200 assert response_dta == True + def test_get_nodes_display_names(test, client, data_model_jsonld): + params = { + "schema_url": data_model_jsonld, + "node_list": ["FamilyHistory", "Biospecimen"] + } + response = client.get("http://localhost:3001/v1/schemas/get_nodes_display_names", query_string = params) + response_dta = json.loads(response.data) + assert response.status_code == 200 + assert "Family History" and "Biospecimen" in response_dta + + @pytest.mark.schematic_api class TestSchemaGeneratorOperation: @pytest.mark.parametrize("relationship", ["parentOf", "requiresDependency", "rangeValue", "domainValue"]) From 840b13b624272ad604c67e90743e3a99eb54b78d Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 31 Jan 2023 12:21:48 -0500 Subject: [PATCH 091/615] remove print statement --- schematic/store/synapse.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 11eb358bf..ad0d178c4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -595,8 +595,6 @@ def getProjectManifests(self, projectId: str) -> List[str]: ("", ""), ) - print('manifest', manifest) - if manifest: manifests.append(manifest) From 5cfdbda0a484a64569aee2707e2ef80c67e13943 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 31 Jan 2023 10:25:16 -0700 Subject: [PATCH 092/615] make `v2.7.0` synapseclient minimum --- poetry.lock | 444 ++++++++++++++++++++++++++++++++++--------------- pyproject.toml | 2 +- 2 files changed, 309 insertions(+), 137 deletions(-) diff --git a/poetry.lock b/poetry.lock index 23ab3478e..6628c4966 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,7 +8,7 @@ python-versions = ">=3.6" [[package]] name = "altair" -version = "4.2.0" +version = "4.2.2" description = "Altair: A declarative statistical visualization library for Python." category = "main" optional = false @@ -145,6 +145,21 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "beautifulsoup4" +version = "4.11.1" +description = "Screen-scraping library" +category = "main" +optional = false +python-versions = ">=3.6.0" + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +html5lib = ["html5lib"] +lxml = ["lxml"] + [[package]] name = "black" version = "20.8b1" @@ -272,7 +287,7 @@ test = ["pytest"] [[package]] name = "connexion" -version = "2.14.1" +version = "2.14.2" description = "Connexion - API first applications with OpenAPI/Swagger and Flask" category = "main" optional = false @@ -280,7 +295,7 @@ python-versions = ">=3.6" [package.dependencies] clickclick = ">=1.2,<21" -flask = ">=1.0.4,<3" +flask = ">=1.0.4,<2.3" inflection = ">=0.3.1,<0.6" itsdangerous = ">=0.24" jsonschema = ">=2.5.1,<5" @@ -288,18 +303,18 @@ packaging = ">=20" PyYAML = ">=5.1,<7" requests = ">=2.9.1,<3" swagger-ui-bundle = {version = ">=0.0.2,<0.1", optional = true, markers = "extra == \"swagger-ui\""} -werkzeug = ">=1.0,<3" +werkzeug = ">=1.0,<2.3" [package.extras] aiohttp = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)"] docs = ["sphinx-autoapi (==1.8.1)"] -flask = ["flask (>=1.0.4,<3)", "itsdangerous (>=0.24)"] +flask = ["flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)"] swagger-ui = ["swagger-ui-bundle (>=0.0.2,<0.1)"] -tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] +tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14.0,<2)", "aiohttp-remotes", "decorator (>=5,<6)", "flask (>=1.0.4,<2.3)", "itsdangerous (>=0.24)", "pytest (>=6,<7)", "pytest-aiohttp", "pytest-cov (>=2,<3)", "swagger-ui-bundle (>=0.0.2,<0.1)", "testfixtures (>=6,<7)"] [[package]] name = "coverage" -version = "7.0.5" +version = "7.1.0" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -587,7 +602,7 @@ test = ["mock (>=3)", "pytest (>=4)", "pytest-cov", "pytest-mock (>=2)"] [[package]] name = "great-expectations" -version = "0.15.44" +version = "0.15.46" description = "Always know what to expect from your data." category = "main" optional = false @@ -637,7 +652,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.6.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -652,7 +667,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "darglint (>=1.8.1)", "docstring-parser (==0.15)", "flake8 (==5.0.4)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=1.7.1)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.6.0)", "pydocstyle (>=6.1.1)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "pyupgrade (==2.7.2)", "requirements-parser (>=0.2.0)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -746,7 +761,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.8.0" +version = "8.9.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -761,7 +776,7 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=3.0.11,<3.1.0" +prompt-toolkit = ">=3.0.30,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" @@ -895,9 +910,14 @@ python-versions = "*" [package.dependencies] attrs = ">=17.4.0" +idna = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format_nongpl\""} pyrsistent = ">=0.14.0" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format_nongpl\""} setuptools = "*" six = ">=1.11.0" +webcolors = {version = "*", optional = true, markers = "extra == \"format_nongpl\""} [package.extras] format = ["idna", "jsonpointer (>1.13)", "rfc3987", "strict-rfc3339", "webcolors"] @@ -905,28 +925,27 @@ format-nongpl = ["idna", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-va [[package]] name = "jupyter-client" -version = "7.4.9" +version = "8.0.2" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -entrypoints = "*" -jupyter-core = ">=4.9.2" -nest-asyncio = ">=1.5.4" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" python-dateutil = ">=2.8.2" pyzmq = ">=23.0" tornado = ">=6.2" -traitlets = "*" +traitlets = ">=5.3" [package.extras] -doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -test = ["codecov", "coverage", "ipykernel (>=6.12)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] +docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" -version = "5.1.5" +version = "5.2.0" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "main" optional = false @@ -941,34 +960,82 @@ traitlets = ">=5.3" docs = ["myst-parser", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] +[[package]] +name = "jupyter-events" +version = "0.6.3" +description = "Jupyter Event System library" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.dependencies] +jsonschema = {version = ">=3.2.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "pytest-cov", "rich"] + [[package]] name = "jupyter-server" -version = "1.15.6" +version = "2.1.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] -anyio = ">=3.1.0" +anyio = ">=3.1.0,<4" argon2-cffi = "*" jinja2 = "*" -jupyter-client = ">=6.1.1" -jupyter-core = ">=4.6.0" -nbconvert = "*" -nbformat = ">=5.2.0" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" +jupyter-events = ">=0.4.0" +jupyter-server-terminals = "*" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" packaging = "*" prometheus-client = "*" pywinpty = {version = "*", markers = "os_name == \"nt\""} -pyzmq = ">=17" -Send2Trash = "*" +pyzmq = ">=24" +send2trash = "*" terminado = ">=0.8.3" -tornado = ">=6.1.0" -traitlets = ">=5" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" websocket-client = "*" [package.extras] -test = ["coverage", "ipykernel", "pytest (>=6.0)", "pytest-console-scripts", "pytest-cov", "pytest-mock", "pytest-timeout", "pytest-tornasync", "requests"] +docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.4.4" +description = "A Jupyter Server Extension Providing Terminals." +category = "main" +optional = false +python-versions = ">=3.8" + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<3.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["coverage", "jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-cov", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.2.2" +description = "Pygments theme using JupyterLab CSS variables" +category = "main" +optional = false +python-versions = ">=3.7" [[package]] name = "jupyterlab-widgets" @@ -1065,8 +1132,8 @@ python-versions = "*" [[package]] name = "mistune" -version = "2.0.4" -description = "A sane Markdown parser with useful plugins and renderers" +version = "0.8.4" +description = "The fastest markdown parser in pure Python" category = "main" optional = false python-versions = "*" @@ -1081,8 +1148,8 @@ python-versions = "*" [[package]] name = "nbclassic" -version = "0.4.8" -description = "A web-based notebook environment for interactive computing" +version = "0.5.1" +description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false python-versions = ">=3.7" @@ -1094,7 +1161,7 @@ ipython-genutils = "*" jinja2 = "*" jupyter-client = ">=6.1.1" jupyter-core = ">=4.6.1" -jupyter-server = ">=1.8" +jupyter-server = ">=1.17.0" nbconvert = ">=5" nbformat = "*" nest-asyncio = ">=1.5" @@ -1109,35 +1176,57 @@ traitlets = ">=4.2.1" [package.extras] docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] json-logging = ["json-logging"] -test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] +test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] + +[[package]] +name = "nbclient" +version = "0.5.13" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +category = "main" +optional = false +python-versions = ">=3.7.0" + +[package.dependencies] +jupyter-client = ">=6.1.5" +nbformat = ">=5.0" +nest-asyncio = "*" +traitlets = ">=5.0.0" + +[package.extras] +sphinx = ["Sphinx (>=1.7)", "mock", "moto", "myst-parser", "sphinx-book-theme"] +test = ["black", "check-manifest", "flake8", "ipykernel", "ipython (<8.0.0)", "ipywidgets (<8.0.0)", "mypy", "pip (>=18.1)", "pytest (>=4.1)", "pytest-asyncio", "pytest-cov (>=2.6.1)", "setuptools (>=38.6.0)", "twine (>=1.11.0)", "wheel (>=0.31.0)", "xmltodict"] [[package]] name = "nbconvert" -version = "5.5.0" +version = "6.4.5" description = "Converting Jupyter Notebooks" category = "main" optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +python-versions = ">=3.7" [package.dependencies] +beautifulsoup4 = "*" bleach = "*" defusedxml = "*" entrypoints = ">=0.2.2" jinja2 = ">=2.4" jupyter-core = "*" -mistune = ">=0.8.1" +jupyterlab-pygments = "*" +MarkupSafe = ">=2.0" +mistune = ">=0.8.1,<2" +nbclient = ">=0.5.0,<0.6.0" nbformat = ">=4.4" pandocfilters = ">=1.4.1" -pygments = "*" +pygments = ">=2.4.1" testpath = "*" -traitlets = ">=4.2" +traitlets = ">=5.0" [package.extras] -all = ["ipykernel", "ipython", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "pytest", "pytest-cov", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt", "tornado (>=4.0)"] -docs = ["ipython", "jupyter-client (>=4.2)", "nbsphinx (>=0.2.12)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -execute = ["jupyter-client (>=4.2)"] +all = ["ipykernel", "ipython", "ipywidgets (>=7)", "nbsphinx (>=0.2.12)", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "tornado (>=4.0)"] +docs = ["ipython", "nbsphinx (>=0.2.12)", "sphinx (>=1.5.1)", "sphinx-rtd-theme"] serve = ["tornado (>=4.0)"] -test = ["ipykernel", "ipywidgets (>=7)", "jupyter-client (>=4.2)", "pytest", "pytest-cov"] +test = ["ipykernel", "ipywidgets (>=7)", "pyppeteer (>=1,<1.1)", "pytest", "pytest-cov", "pytest-dependency"] +webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] name = "nbformat" @@ -1263,7 +1352,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openpyxl" -version = "3.0.10" +version = "3.1.0" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1321,7 +1410,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.10.3" +version = "0.11.0" description = "Utility library for gitignore style pattern matching of file paths." category = "dev" optional = false @@ -1630,6 +1719,14 @@ python-versions = "*" [package.extras] cli = ["click (>=5.0)"] +[[package]] +name = "python-json-logger" +version = "2.0.4" +description = "A python library adding a json log formatter" +category = "main" +optional = false +python-versions = ">=3.5" + [[package]] name = "pytz" version = "2022.7.1" @@ -1752,6 +1849,25 @@ requests = ">=2.0.0" [package.extras] rsa = ["oauthlib[signedtoken] (>=3.0.0)"] +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "rsa" version = "4.9" @@ -1865,6 +1981,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "soupsieve" +version = "2.3.2.post1" +description = "A modern CSS selector implementation for Beautiful Soup." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "sphinx" version = "5.1.1" @@ -2111,7 +2235,7 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.8.1" +version = "5.9.0" description = "Traitlets Python configuration system" category = "main" optional = false @@ -2190,6 +2314,14 @@ category = "main" optional = false python-versions = "*" +[[package]] +name = "webcolors" +version = "1.12" +description = "A library for working with color names and color values formats defined by HTML and CSS." +category = "main" +optional = false +python-versions = ">=3.7" + [[package]] name = "webencodings" version = "0.5.1" @@ -2200,7 +2332,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.4.2" +version = "1.5.0" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2241,20 +2373,20 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.11.0" +version = "3.12.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "07e5b9f29e35366d3bb1402137bf8b98a7e0a5a1fdcf26856a0b1c675535b876" +content-hash = "f790014ec51c7560bb79eb72ceff372e6e6d1575956a39b0986b8808cad5e16d" [metadata.files] alabaster = [ @@ -2262,8 +2394,8 @@ alabaster = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] altair = [ - {file = "altair-4.2.0-py3-none-any.whl", hash = "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a"}, - {file = "altair-4.2.0.tar.gz", hash = "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"}, + {file = "altair-4.2.2-py3-none-any.whl", hash = "sha256:8b45ebeaf8557f2d760c5c77b79f02ae12aee7c46c27c06014febab6f849bc87"}, + {file = "altair-4.2.2.tar.gz", hash = "sha256:39399a267c49b30d102c10411e67ab26374156a84b1aeb9fcd15140429ba49c5"}, ] anyio = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, @@ -2323,6 +2455,10 @@ backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] +beautifulsoup4 = [ + {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, + {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, +] black = [ {file = "black-20.8b1.tar.gz", hash = "sha256:1c02557aa099101b9d21496f8a914e9ed2222ef70336404eeeac8edba836fbea"}, ] @@ -2515,61 +2651,61 @@ comm = [ {file = "comm-0.1.2.tar.gz", hash = "sha256:3e2f5826578e683999b93716285b3b1f344f157bf75fa9ce0a797564e742f062"}, ] connexion = [ - {file = "connexion-2.14.1-py2.py3-none-any.whl", hash = "sha256:f343717241b4c4802a694c38fee66fb1693c897fe4ea5a957fa9b3b07caf6394"}, - {file = "connexion-2.14.1.tar.gz", hash = "sha256:99aa5781e70a7b94f8ffae8cf89f309d49cdb811bbd65a8e2f2546f3b19a01e6"}, + {file = "connexion-2.14.2-py2.py3-none-any.whl", hash = "sha256:a73b96a0e07b16979a42cde7c7e26afe8548099e352cf350f80c57185e0e0b36"}, + {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2a7f23bbaeb2a87f90f607730b45564076d870f1fb07b9318d0c21f36871932b"}, - {file = "coverage-7.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c18d47f314b950dbf24a41787ced1474e01ca816011925976d90a88b27c22b89"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef14d75d86f104f03dea66c13188487151760ef25dd6b2dbd541885185f05f40"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66e50680e888840c0995f2ad766e726ce71ca682e3c5f4eee82272c7671d38a2"}, - {file = "coverage-7.0.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9fed35ca8c6e946e877893bbac022e8563b94404a605af1d1e6accc7eb73289"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d8d04e755934195bdc1db45ba9e040b8d20d046d04d6d77e71b3b34a8cc002d0"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e109f1c9a3ece676597831874126555997c48f62bddbcace6ed17be3e372de8"}, - {file = "coverage-7.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0a1890fca2962c4f1ad16551d660b46ea77291fba2cc21c024cd527b9d9c8809"}, - {file = "coverage-7.0.5-cp310-cp310-win32.whl", hash = "sha256:be9fcf32c010da0ba40bf4ee01889d6c737658f4ddff160bd7eb9cac8f094b21"}, - {file = "coverage-7.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:cbfcba14a3225b055a28b3199c3d81cd0ab37d2353ffd7f6fd64844cebab31ad"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:30b5fec1d34cc932c1bc04017b538ce16bf84e239378b8f75220478645d11fca"}, - {file = "coverage-7.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1caed2367b32cc80a2b7f58a9f46658218a19c6cfe5bc234021966dc3daa01f0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d254666d29540a72d17cc0175746cfb03d5123db33e67d1020e42dae611dc196"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19245c249aa711d954623d94f23cc94c0fd65865661f20b7781210cb97c471c0"}, - {file = "coverage-7.0.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b05ed4b35bf6ee790832f68932baf1f00caa32283d66cc4d455c9e9d115aafc"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:29de916ba1099ba2aab76aca101580006adfac5646de9b7c010a0f13867cba45"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e057e74e53db78122a3979f908973e171909a58ac20df05c33998d52e6d35757"}, - {file = "coverage-7.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:411d4ff9d041be08fdfc02adf62e89c735b9468f6d8f6427f8a14b6bb0a85095"}, - {file = "coverage-7.0.5-cp311-cp311-win32.whl", hash = "sha256:52ab14b9e09ce052237dfe12d6892dd39b0401690856bcfe75d5baba4bfe2831"}, - {file = "coverage-7.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:1f66862d3a41674ebd8d1a7b6f5387fe5ce353f8719040a986551a545d7d83ea"}, - {file = "coverage-7.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b69522b168a6b64edf0c33ba53eac491c0a8f5cc94fa4337f9c6f4c8f2f5296c"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436e103950d05b7d7f55e39beeb4d5be298ca3e119e0589c0227e6d0b01ee8c7"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c56bec53d6e3154eaff6ea941226e7bd7cc0d99f9b3756c2520fc7a94e6d96"}, - {file = "coverage-7.0.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a38362528a9115a4e276e65eeabf67dcfaf57698e17ae388599568a78dcb029"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f67472c09a0c7486e27f3275f617c964d25e35727af952869dd496b9b5b7f6a3"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:220e3fa77d14c8a507b2d951e463b57a1f7810a6443a26f9b7591ef39047b1b2"}, - {file = "coverage-7.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ecb0f73954892f98611e183f50acdc9e21a4653f294dfbe079da73c6378a6f47"}, - {file = "coverage-7.0.5-cp37-cp37m-win32.whl", hash = "sha256:d8f3e2e0a1d6777e58e834fd5a04657f66affa615dae61dd67c35d1568c38882"}, - {file = "coverage-7.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9e662e6fc4f513b79da5d10a23edd2b87685815b337b1a30cd11307a6679148d"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:790e4433962c9f454e213b21b0fd4b42310ade9c077e8edcb5113db0818450cb"}, - {file = "coverage-7.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49640bda9bda35b057b0e65b7c43ba706fa2335c9a9896652aebe0fa399e80e6"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d66187792bfe56f8c18ba986a0e4ae44856b1c645336bd2c776e3386da91e1dd"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:276f4cd0001cd83b00817c8db76730938b1ee40f4993b6a905f40a7278103b3a"}, - {file = "coverage-7.0.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95304068686545aa368b35dfda1cdfbbdbe2f6fe43de4a2e9baa8ebd71be46e2"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:17e01dd8666c445025c29684d4aabf5a90dc6ef1ab25328aa52bedaa95b65ad7"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea76dbcad0b7b0deb265d8c36e0801abcddf6cc1395940a24e3595288b405ca0"}, - {file = "coverage-7.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:50a6adc2be8edd7ee67d1abc3cd20678987c7b9d79cd265de55941e3d0d56499"}, - {file = "coverage-7.0.5-cp38-cp38-win32.whl", hash = "sha256:e4ce984133b888cc3a46867c8b4372c7dee9cee300335e2925e197bcd45b9e16"}, - {file = "coverage-7.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:4a950f83fd3f9bca23b77442f3a2b2ea4ac900944d8af9993743774c4fdc57af"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c2155943896ac78b9b0fd910fb381186d0c345911f5333ee46ac44c8f0e43ab"}, - {file = "coverage-7.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:54f7e9705e14b2c9f6abdeb127c390f679f6dbe64ba732788d3015f7f76ef637"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ee30375b409d9a7ea0f30c50645d436b6f5dfee254edffd27e45a980ad2c7f4"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b78729038abea6a5df0d2708dce21e82073463b2d79d10884d7d591e0f385ded"}, - {file = "coverage-7.0.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13250b1f0bd023e0c9f11838bdeb60214dd5b6aaf8e8d2f110c7e232a1bff83b"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2c407b1950b2d2ffa091f4e225ca19a66a9bd81222f27c56bd12658fc5ca1209"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c76a3075e96b9c9ff00df8b5f7f560f5634dffd1658bafb79eb2682867e94f78"}, - {file = "coverage-7.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f26648e1b3b03b6022b48a9b910d0ae209e2d51f50441db5dce5b530fad6d9b1"}, - {file = "coverage-7.0.5-cp39-cp39-win32.whl", hash = "sha256:ba3027deb7abf02859aca49c865ece538aee56dcb4871b4cced23ba4d5088904"}, - {file = "coverage-7.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:949844af60ee96a376aac1ded2a27e134b8c8d35cc006a52903fc06c24a3296f"}, - {file = "coverage-7.0.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:b9727ac4f5cf2cbf87880a63870b5b9730a8ae3a4a360241a0fdaa2f71240ff0"}, - {file = "coverage-7.0.5.tar.gz", hash = "sha256:051afcbd6d2ac39298d62d340f94dbb6a1f31de06dfaf6fcef7b759dd3860c45"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"}, + {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"}, + {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"}, + {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"}, + {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"}, + {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"}, + {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"}, + {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"}, + {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"}, + {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"}, + {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"}, + {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"}, + {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"}, + {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"}, + {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"}, + {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"}, + {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"}, + {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"}, + {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"}, + {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"}, + {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"}, + {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"}, + {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"}, + {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"}, + {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"}, + {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"}, + {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"}, + {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] cryptography = [ {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, @@ -2693,8 +2829,8 @@ graphviz = [ {file = "graphviz-0.16.zip", hash = "sha256:d2d25af1c199cad567ce4806f0449cb74eb30cf451fd7597251e1da099ac6e57"}, ] great-expectations = [ - {file = "great_expectations-0.15.44-py3-none-any.whl", hash = "sha256:656f66051506074faa334ab9ec1df7f53e035b044e098cc7f0741fa0d114e51a"}, - {file = "great_expectations-0.15.44.tar.gz", hash = "sha256:547a3f252cfc41124b299b226399b1169b01e127e717f97ee5dd16e34d0e2a64"}, + {file = "great_expectations-0.15.46-py3-none-any.whl", hash = "sha256:06373b688fce107a6659766b29ac7abe6ab01c62ad8ceda57e0e2ffb9b05db35"}, + {file = "great_expectations-0.15.46.tar.gz", hash = "sha256:f674cb57dbd8fc993fcf7b2d167253bceaa79db13cea0f5a9c92fd6ea13870bc"}, ] httplib2 = [ {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, @@ -2725,8 +2861,8 @@ ipykernel = [ {file = "ipykernel-6.20.2.tar.gz", hash = "sha256:1893c5b847033cd7a58f6843b04a9349ffb1031bc6588401cadc9adb58da428e"}, ] ipython = [ - {file = "ipython-8.8.0-py3-none-any.whl", hash = "sha256:da01e6df1501e6e7c32b5084212ddadd4ee2471602e2cf3e0190f4de6b0ea481"}, - {file = "ipython-8.8.0.tar.gz", hash = "sha256:f3bf2c08505ad2c3f4ed5c46ae0331a8547d36bf4b21a451e8ae80c0791db95b"}, + {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, + {file = "ipython-8.9.0.tar.gz", hash = "sha256:71618e82e6d59487bea059626e7c79fb4a5b760d1510d02fab1160db6fdfa1f7"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -2769,16 +2905,28 @@ jsonschema = [ {file = "jsonschema-3.2.0.tar.gz", hash = "sha256:c8a85b28d377cc7737e46e2d9f2b4f44ee3c0e1deac6bf46ddefc7187d30797a"}, ] jupyter-client = [ - {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, - {file = "jupyter_client-7.4.9.tar.gz", hash = "sha256:52be28e04171f07aed8f20e1616a5a552ab9fee9cbbe6c1896ae170c3880d392"}, + {file = "jupyter_client-8.0.2-py3-none-any.whl", hash = "sha256:c53731eb590b68839b0ce04bf46ff8c4f03278f5d9fe5c3b0f268a57cc2bd97e"}, + {file = "jupyter_client-8.0.2.tar.gz", hash = "sha256:47ac9f586dbcff4d79387ec264faf0fdeb5f14845fa7345fd7d1e378f8096011"}, ] jupyter-core = [ - {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, - {file = "jupyter_core-5.1.5.tar.gz", hash = "sha256:8e54c48cde1e0c8345f64bcf9658b78044ddf02b273726cea9d9f59be4b02130"}, + {file = "jupyter_core-5.2.0-py3-none-any.whl", hash = "sha256:4bdc2928c37f6917130c667d8b8708f20aee539d8283c6be72aabd2a4b4c83b0"}, + {file = "jupyter_core-5.2.0.tar.gz", hash = "sha256:1407cdb4c79ee467696c04b76633fc1884015fa109323365a6372c8e890cc83f"}, +] +jupyter-events = [ + {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, + {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, ] jupyter-server = [ - {file = "jupyter_server-1.15.6-py3-none-any.whl", hash = "sha256:e393934c19fcc324a7fca77f811eacd91201440f04c6fbb15c959c463baaa9c5"}, - {file = "jupyter_server-1.15.6.tar.gz", hash = "sha256:56bd6f580d1f46b62294990e8e78651025729f5d3fc798f10f2c03f0cdcbf28d"}, + {file = "jupyter_server-2.1.0-py3-none-any.whl", hash = "sha256:90cd6f2bd0581ddd9b2dbe82026a0f4c228a1d95c86e22460efbfdfc931fcf56"}, + {file = "jupyter_server-2.1.0.tar.gz", hash = "sha256:efaae5e4f0d5f22c7f2f2dc848635036ee74a2df02abed52d30d9d95121ad382"}, +] +jupyter-server-terminals = [ + {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, + {file = "jupyter_server_terminals-0.4.4.tar.gz", hash = "sha256:57ab779797c25a7ba68e97bcfb5d7740f2b5e8a83b5e8102b10438041a7eac5d"}, +] +jupyterlab-pygments = [ + {file = "jupyterlab_pygments-0.2.2-py2.py3-none-any.whl", hash = "sha256:2405800db07c9f770863bcf8049a529c3dd4d3e28536638bd7c1c01d2748309f"}, + {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, ] jupyterlab-widgets = [ {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, @@ -2880,20 +3028,24 @@ mccabe = [ {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] mistune = [ - {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, - {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, + {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, + {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] nbclassic = [ - {file = "nbclassic-0.4.8-py3-none-any.whl", hash = "sha256:cbf05df5842b420d5cece0143462380ea9d308ff57c2dc0eb4d6e035b18fbfb3"}, - {file = "nbclassic-0.4.8.tar.gz", hash = "sha256:c74d8a500f8e058d46b576a41e5bc640711e1032cf7541dde5f73ea49497e283"}, + {file = "nbclassic-0.5.1-py3-none-any.whl", hash = "sha256:32c235e1f22f4048f3b877d354c198202898797cf9c2085856827598cead001b"}, + {file = "nbclassic-0.5.1.tar.gz", hash = "sha256:8e8ffce7582bb7a4baf11fa86a3d88b184e8e7df78eed4ead69f15aa4fc0e323"}, +] +nbclient = [ + {file = "nbclient-0.5.13-py3-none-any.whl", hash = "sha256:47ac905af59379913c1f8f541098d2550153cf8dc58553cbe18c702b181518b0"}, + {file = "nbclient-0.5.13.tar.gz", hash = "sha256:40c52c9b5e3c31faecaee69f202b3f53e38d7c1c563de0fadde9d7eda0fdafe8"}, ] nbconvert = [ - {file = "nbconvert-5.5.0-py2.py3-none-any.whl", hash = "sha256:4a978548d8383f6b2cfca4a3b0543afb77bc7cb5a96e8b424337ab58c12da9bc"}, - {file = "nbconvert-5.5.0.tar.gz", hash = "sha256:138381baa41d83584459b5cfecfc38c800ccf1f37d9ddd0bd440783346a4c39c"}, + {file = "nbconvert-6.4.5-py3-none-any.whl", hash = "sha256:e01d219f55cc79f9701c834d605e8aa3acf35725345d3942e3983937f368ce14"}, + {file = "nbconvert-6.4.5.tar.gz", hash = "sha256:21163a8e2073c07109ca8f398836e45efdba2aacea68d6f75a8a545fef070d4e"}, ] nbformat = [ {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, @@ -2953,8 +3105,8 @@ oauthlib = [ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, ] openpyxl = [ - {file = "openpyxl-3.0.10-py2.py3-none-any.whl", hash = "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355"}, - {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, + {file = "openpyxl-3.1.0-py2.py3-none-any.whl", hash = "sha256:24d7d361025d186ba91eff58135d50855cf035a84371b891e58fb6eb5125660f"}, + {file = "openpyxl-3.1.0.tar.gz", hash = "sha256:eccedbe1cdd8b2494057e73959b496821141038dbb7eb9266ea59e3f34208231"}, ] packaging = [ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, @@ -2998,8 +3150,8 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ - {file = "pathspec-0.10.3-py3-none-any.whl", hash = "sha256:3c95343af8b756205e2aba76e843ba9520a24dd84f68c22b9f93251507509dd6"}, - {file = "pathspec-0.10.3.tar.gz", hash = "sha256:56200de4077d9d0791465aa9095a01d421861e405b5096955051deefd697d6f6"}, + {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, + {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, ] pdoc = [ {file = "pdoc-12.3.1-py3-none-any.whl", hash = "sha256:c3f24f31286e634de9c76fa6e67bd5c0c5e74360b41dc91e6b82499831eb52d8"}, @@ -3190,6 +3342,10 @@ python-dotenv = [ {file = "python-dotenv-0.15.0.tar.gz", hash = "sha256:587825ed60b1711daea4832cf37524dfd404325b7db5e25ebe88c495c9f807a0"}, {file = "python_dotenv-0.15.0-py2.py3-none-any.whl", hash = "sha256:0c8d1b80d1a1e91717ea7d526178e3882732420b03f08afea0406db6402e220e"}, ] +python-json-logger = [ + {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, + {file = "python_json_logger-2.0.4-py3-none-any.whl", hash = "sha256:3b03487b14eb9e4f77e4fc2a023358b5394b82fd89cecf5586259baed57d8c6f"}, +] pytz = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, @@ -3438,6 +3594,14 @@ requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, {file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, ] +rfc3339-validator = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] +rfc3986-validator = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] rsa = [ {file = "rsa-4.9-py3-none-any.whl", hash = "sha256:90260d9058e514786967344d0ef75fa8727eed8a7d2e43ce9f4bcf1b536174f7"}, {file = "rsa-4.9.tar.gz", hash = "sha256:e38464a49c6c85d7f1351b0126661487a7e0a14a50f1675ec50eb34d4f20ef21"}, @@ -3528,6 +3692,10 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] +soupsieve = [ + {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, + {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, +] sphinx = [ {file = "Sphinx-5.1.1-py3-none-any.whl", hash = "sha256:309a8da80cb6da9f4713438e5b55861877d5d7976b69d87e336733637ea12693"}, {file = "Sphinx-5.1.1.tar.gz", hash = "sha256:ba3224a4e206e1fbdecf98a4fae4992ef9b24b85ebf7b584bb340156eaf08d89"}, @@ -3610,8 +3778,8 @@ tqdm = [ {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, ] traitlets = [ - {file = "traitlets-5.8.1-py3-none-any.whl", hash = "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861"}, - {file = "traitlets-5.8.1.tar.gz", hash = "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b"}, + {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, + {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typed-ast = [ {file = "typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, @@ -3663,13 +3831,17 @@ wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] +webcolors = [ + {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"}, + {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"}, +] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.4.2.tar.gz", hash = "sha256:d6e8f90ca8e2dd4e8027c4561adeb9456b54044312dba655e7cae652ceb9ae59"}, - {file = "websocket_client-1.4.2-py3-none-any.whl", hash = "sha256:d6b06432f184438d99ac1f456eaf22fe1ade524c3dd16e661142dc54e9cba574"}, + {file = "websocket-client-1.5.0.tar.gz", hash = "sha256:561ca949e5bbb5d33409a37235db55c279235c78ee407802f1d2314fff8a8536"}, + {file = "websocket_client-1.5.0-py3-none-any.whl", hash = "sha256:fb5d81b95d350f3a54838ebcb4c68a5353bbd1412ae8f068b1e5280faeb13074"}, ] werkzeug = [ {file = "Werkzeug-1.0.1-py2.py3-none-any.whl", hash = "sha256:2de2a5db0baeae7b2d2664949077c2ac63fbd16d98da0ff71837f7d1dea3fd43"}, @@ -3746,6 +3918,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, - {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, + {file = "zipp-3.12.0-py3-none-any.whl", hash = "sha256:9eb0a4c5feab9b08871db0d672745b53450d7f26992fd1e4653aa43345e97b86"}, + {file = "zipp-3.12.0.tar.gz", hash = "sha256:73efd63936398aac78fd92b6f4865190119d6c91b531532e798977ea8dd402eb"}, ] diff --git a/pyproject.toml b/pyproject.toml index 41eb59dc4..283de8873 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,7 +53,7 @@ pygsheets = "^2.0.4" PyYAML = "^5.4.1" rdflib = "^5.0.0" setuptools = "^52.0.0" -synapseclient = "^2.6.0" +synapseclient = "^2.7.0" tenacity = "^8.0.1" toml = "^0.10.2" Flask = "^1.1.4" From 74b45e6b4521b1d9aeb70192816c97cb43e742bd Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 31 Jan 2023 10:27:49 -0700 Subject: [PATCH 093/615] revert hotfix for `load_df` in PR #902 --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index ddbb1fa89..d262836aa 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1125,7 +1125,7 @@ def associateMetadataWithFiles( load_args={ "dtype":"string", } - manifest = load_df(metadataManifestPath, preserve_raw_input = True, **load_args) #HOTFIX: set preserve_raw_input to true to allow mixed type cols in table uploads schematic#870 + manifest = load_df(metadataManifestPath, preserve_raw_input = False, **load_args) except FileNotFoundError as err: raise FileNotFoundError( f"No manifest file was found at this path: {metadataManifestPath}" From ac7a44fd4220e9db76f49a06ba2a878fab62ae01 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 31 Jan 2023 12:44:40 -0500 Subject: [PATCH 094/615] add input_token parameter in test --- tests/test_api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..bc626d3f8 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -324,6 +324,7 @@ def test_generate_existing_manifest(self, client, data_model_jsonld, data_type, "title": "Example", "data_type": data_type, "use_annotations": False, + "input_token": None } if dataset_id: params['dataset_id'] = dataset_id @@ -369,6 +370,7 @@ def test_generate_new_manifest(self, caplog, client, data_model_jsonld, data_typ "data_type": data_type, "use_annotations": False, "dataset_id": None, + "input_token": None } if output_format: From fdf70706bc5b37240b17cd54779765f59da42620 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 31 Jan 2023 14:43:14 -0500 Subject: [PATCH 095/615] udpate relevant functions --- api/routes.py | 2 +- schematic/manifest/generator.py | 5 ++--- tests/test_api.py | 8 +++++--- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/api/routes.py b/api/routes.py index 309a6aaf3..10b63c43a 100644 --- a/api/routes.py +++ b/api/routes.py @@ -275,7 +275,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None dir_name = os.path.dirname(result) file_name = os.path.basename(result) mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' - return send_from_directory(directory=dir_name, filename=file_name, as_attachment=True, mimetype=mimetype, cache_timeout=0) + return send_from_directory(directory=dir_name, path=file_name, as_attachment=True, mimetype=mimetype, max_age=0) return result diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index da8a500d6..d0dfc9ac0 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1602,9 +1602,8 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a # initalize excel writer writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') - writer.book = workbook - writer.sheets = {ws.title: ws for ws in workbook.worksheets} - worksheet = writer.sheets["Sheet1"] + writer.worksheets = {ws.title: ws for ws in workbook.worksheets} + worksheet = writer.worksheets["Sheet1"] # add additional content to the existing spreadsheet additional_df.to_excel(writer, sheet_name = "Sheet1", startrow=1, index = False, header=False) diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..f222c9f53 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -54,6 +54,7 @@ def syn_token(config): class TestSynapseStorage: @pytest.mark.parametrize("return_type", ["json", "csv"]) def test_get_storage_assets_tables(self, client, syn_token, return_type): + print('ensure that local changes are working') params = { "input_token": syn_token, "asset_view": "syn23643253", @@ -305,7 +306,8 @@ def ifPandasDataframe(self, response_dt): assert isinstance(df, pd.DataFrame) - @pytest.mark.parametrize("output_format", [None, "excel", "google_sheet", "dataframe (only if getting existing manifests)"]) + #@pytest.mark.parametrize("output_format", [None, "excel", "google_sheet", "dataframe (only if getting existing manifests)"]) + @pytest.mark.parametrize("output_format", ["excel"]) @pytest.mark.parametrize("data_type", ["Biospecimen", "Patient", "all manifests", ["Biospecimen", "Patient"]]) def test_generate_existing_manifest(self, client, data_model_jsonld, data_type, output_format, caplog): # set dataset @@ -341,8 +343,8 @@ def test_generate_existing_manifest(self, client, data_model_jsonld, data_type, if isinstance(data_type, list) and len(data_type) > 1: # return warning message for record in caplog.records: - assert record.levelname == "WARNING" - assert "Currently we do not support returning multiple files as Excel format at once." in caplog.text + if record.message == "Currently we do not support returning multiple files as Excel format at once.": + assert record.levelname == "WARNING" self.ifExcelExists(response, "Example.Biospecimen.manifest.xlsx") # for single data type else: From 1a47f54734c79e1b87c529b1a539be68fe6cda64 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 09:30:11 -0800 Subject: [PATCH 096/615] added date GE rule --- schematic/models/GE_Helpers.py | 16 ++++++++++++++++ schematic/utils/validate_rules_utils.py | 7 +++++++ 2 files changed, 23 insertions(+) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 2ddb7ff28..1fe0348d1 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -218,6 +218,22 @@ def build_expectation_suite(self,): }, "validation_rule": rule } + + #Validate date + elif base_rule=='date': + args["mostly"]=1.0 + args["type_"]='date' + meta={ + "notes": { + "format": "markdown", + "content": ( + "Expect column values to be of date type. " + "**Markdown** `Supported`" + ), + }, + "validation_rule": rule + } + elif base_rule==("recommended"): args["mostly"]=0.0000000001 args["regex_list"]=['^$'] diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 3edcc358b..390a9c586 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -43,6 +43,13 @@ def validation_rule_info(): 'complementary_rules': None, 'default_message_level': 'error'}, + "date": { + 'arguments':(1, 0), + 'type': "type_validation", + 'complementary_rules': None, + 'default_message_level': 'error' + }, + "regex": { 'arguments':(3, 2), 'fixed_arg': ['strict'], From 662104b94eaedf227de421f64638750baa6fa433 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 09:59:25 -0800 Subject: [PATCH 097/615] remove line to parse dates --- schematic/utils/df_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 800c2e6e8..20a6770f9 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -39,7 +39,6 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): null_cells = org_df.isnull() org_df = org_df.astype(str).mask(null_cells, '') ints = org_df.applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) - dates = org_df.applymap(lambda x: _parse_dates(x), na_action='ignore').fillna(False) #convert strings to numerical dtype (float) if possible, preserve non-numerical strings for col in org_df.columns: From bdca7af5311b6f3958483a5a9e59ec3ecf194713 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 09:59:50 -0800 Subject: [PATCH 098/615] add date to dict --- schematic/models/GE_Helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 1fe0348d1..b75634c75 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -127,6 +127,7 @@ def build_expectation_suite(self,): "float": "expect_column_values_to_be_in_type_list", "str": "expect_column_values_to_be_of_type", "num": "expect_column_values_to_be_in_type_list", + "date": "expect_column_values_to_be_of_type", "recommended": "expect_column_values_to_not_match_regex_list", "protectAges": "expect_column_values_to_be_between", "unique": "expect_column_values_to_be_unique", From d68aad2bdd3bffe2130499a74e0a9a181c8c4173 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 10:00:36 -0800 Subject: [PATCH 099/615] remove line to parse dates --- schematic/utils/df_utils.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 20a6770f9..fc0f6f48e 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -50,7 +50,6 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): #Store values that were entered as ints and dates processed_df=processed_df.mask(ints != False, other = ints) - processed_df=processed_df.mask(dates != False, other = dates) return processed_df From 738bd74fe33af322e0d524b6cece9d8b3a15d3bf Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 11:01:18 -0700 Subject: [PATCH 100/615] raise `KeyError` for missing credentials --- schematic/store/synapse.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 926754967..f72731f4e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1630,7 +1630,10 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non if config.has_option('authentication', 'username') and config.has_option('authentication', 'authtoken'): synConfig = SynapseConfig(config.get('authentication', 'username'), config.get('authentication', 'authtoken'), synStore.getDatasetProject(datasetId) ) - + else: + raise KeyError( + "Username or authtoken credentials missing in .synapseConfig" + ) synapseDB = SynapseDatabase(synConfig) synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) From b00abb49324228c8de278c943873acc43be14d13 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 10:05:37 -0800 Subject: [PATCH 101/615] fix date expectation --- schematic/models/GE_Helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index b75634c75..4c9a29692 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -127,7 +127,7 @@ def build_expectation_suite(self,): "float": "expect_column_values_to_be_in_type_list", "str": "expect_column_values_to_be_of_type", "num": "expect_column_values_to_be_in_type_list", - "date": "expect_column_values_to_be_of_type", + "date": "expect_column_values_to_be_dateutil_parseable", "recommended": "expect_column_values_to_not_match_regex_list", "protectAges": "expect_column_values_to_be_between", "unique": "expect_column_values_to_be_unique", From 5b63b006d0362fa8b34a6933a4bc51215a04a43d Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 10:18:50 -0800 Subject: [PATCH 102/615] added date rule to schema --- tests/data/example.model.csv | 2 +- tests/data/example.model.jsonld | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index cfe08da33..3a6aaacda 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -36,4 +36,4 @@ Check Recommended,,,,,FALSE,DataProperty,,,recommended Check Ages,,,,,TRUE,DataProperty,,,protectAges Check Unique,,,,,TRUE,DataProperty,,,unique error Check Range,,,,,TRUE,DataProperty,,,inRange 50 100 error -Check Date,,,,,TRUE,DataProperty,,, +Check Date,,,,,TRUE,DataProperty,,,date diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index b7396e479..f61eb3ddd 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2893,7 +2893,7 @@ }, "sms:displayName": "Check Date", "sms:required": "sms:true", - "sms:validationRules": [] + "sms:validationRules": ["date"] }, { "@id": "bts:Component", From 4c8c8bba00622af2a8f43fc20a4c1be7bc75ae0c Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 11:14:40 -0800 Subject: [PATCH 103/615] redo date GE arguments --- schematic/models/GE_Helpers.py | 7 +++++-- schematic/utils/validate_rules_utils.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 4c9a29692..8e91613c5 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -223,12 +223,15 @@ def build_expectation_suite(self,): #Validate date elif base_rule=='date': args["mostly"]=1.0 - args["type_"]='date' + args["result_format"]=None + args["include_config"]=False + args["catch_exceptions"]=None + args["meta"]=None meta={ "notes": { "format": "markdown", "content": ( - "Expect column values to be of date type. " + "Expect column values to be parsable by dateutils. " "**Markdown** `Supported`" ), }, diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 390a9c586..70a3437c8 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -45,7 +45,7 @@ def validation_rule_info(): "date": { 'arguments':(1, 0), - 'type': "type_validation", + 'type': "content_validation", 'complementary_rules': None, 'default_message_level': 'error' }, From 8ff7106cbac653150dba8bbd1e6fe53f83ee6aec Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 11:59:00 -0800 Subject: [PATCH 104/615] redid rules --- schematic/models/GE_Helpers.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 8e91613c5..d8760eb51 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -223,10 +223,6 @@ def build_expectation_suite(self,): #Validate date elif base_rule=='date': args["mostly"]=1.0 - args["result_format"]=None - args["include_config"]=False - args["catch_exceptions"]=None - args["meta"]=None meta={ "notes": { "format": "markdown", From 46d70edda9715afa715972f091d87ec5c2d448f3 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 1 Feb 2023 15:25:17 -0500 Subject: [PATCH 105/615] added test for get_node_validation_rules --- tests/test_api.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..1fb57a9a2 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -212,6 +212,16 @@ def test_if_node_required(test, client, data_model_jsonld): response_dta = json.loads(response.data) assert response.status_code == 200 assert response_dta == True + def test_get_node_validation_rules(test, client, data_model_jsonld): + params = { + "schema_url": data_model_jsonld, + "node_display_name": "CheckRegexList" + } + response = client.get("http://localhost:3001/v1/schemas/get_node_validation_rules", query_string = params) + response_dta = json.loads(response.data) + assert response.status_code == 200 + assert "list strict" in response_dta + assert "regex match [a-f]" in response_dta @pytest.mark.schematic_api class TestSchemaGeneratorOperation: From 7bf662e1d271318f7ea3411fc49e6a62becc24aa Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 13:40:22 -0700 Subject: [PATCH 106/615] update docstrings --- schematic/store/synapse.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index f72731f4e..c185400f2 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1544,7 +1544,7 @@ def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, specifySchema: bool = True, datasetId: str = None, columnTypeDict: dict = None, restrict: bool = False): """ - Method to create a table from a metadata manifest and upload it to synapse + Method to replace an existing table on synapse with metadata from a new manifest Args: tableToLoad: manifest formatted appropriately for the table @@ -1626,6 +1626,20 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No return existingTableId def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + """ + Method to upsert rows from a new manifest into an existing table on synapse + + Args: + tableToLoad: manifest formatted appropriately for the table + tableName: name of the table to be uploaded + existingTableId: synId of the existing table to be replaced + datasetId: synID of the dataset for the manifest + columnTypeDict: dictionary schema for table columns: type, size, etc + + + Returns: + existingTableId: synID of the already existing table that had its metadata replaced + """ config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) if config.has_option('authentication', 'username') and config.has_option('authentication', 'authtoken'): @@ -1641,6 +1655,19 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + """ + Method to update an existing table with a new column + + Args: + tableToLoad: manifest formatted appropriately for the table, that contains the new column + existingTableId: synId of the existing table to be replaced + updateCol: column to index the old and new tables on + restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions + + + Returns: + existingTableId: synID of the already existing table that had its metadata replaced + """ existing_table, existing_results = synStore.get_synapse_table(existingTableId) tableToLoad = update_df(existing_table, tableToLoad, update_col) From e560fcb60f3d13ccacd85b0c7df69f862d102686 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 12:47:44 -0800 Subject: [PATCH 107/615] fixed rules --- schematic/models/GE_Helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index d8760eb51..6299492b7 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -418,6 +418,7 @@ def generate_errors( # indices and values cannot be returned else: for i, item in enumerate(self.manifest[errColumn]): + logging.warning(result_dict) observed_type=result_dict['result']['observed_value'] indices.append(i) if isinstance(item,type_dict[observed_type]) else indices values.append(item) if isinstance(item,type_dict[observed_type]) else values From e963dedee7f9fac103a19de185ebae3f00fcc631 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 1 Feb 2023 12:48:12 -0800 Subject: [PATCH 108/615] added dashes to dates to make them read as strings --- tests/data/mock_manifests/Invalid_Test_Manifest.csv | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/data/mock_manifests/Invalid_Test_Manifest.csv b/tests/data/mock_manifests/Invalid_Test_Manifest.csv index 43a90873b..5a4fbd99c 100644 --- a/tests/data/mock_manifests/Invalid_Test_Manifest.csv +++ b/tests/data/mock_manifests/Invalid_Test_Manifest.csv @@ -1,4 +1,4 @@ Component,Check List,Check Regex List,Check Regex Format,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date -MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32984 +MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32-984 MockComponent,invalid list values,ab cd ef,m,q,c,99,5.63,94,http://googlef.com/,7163,51100,9965,71738,,32851,str1,30,notADate -MockComponent,"ab,cd","ab,cd,ef",b,b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,8085,8085,1738,210065,,6550,str1,90,8443094 +MockComponent,"ab,cd","ab,cd,ef",b,b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,8085,8085,1738,210065,,6550,str1,90,84-43-094 From b35465c5f39f41bd3064708eb36dee0cf891ed58 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 14:29:13 -0700 Subject: [PATCH 109/615] allow `table_manipulation` to be `None` --- schematic/store/synapse.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c185400f2..a0fc8c8a6 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -868,8 +868,10 @@ def buildDB(self, # Put table manifest onto synapse schema = Schema(name=table_name, columns=col_schema, parent=self.getDatasetProject(datasetId)) - - if table_name in table_info.keys() and table_info[table_name]: + + if not table_manipulation or (table_name not in table_info.keys() and table_info[table_name]): + manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) + elif table_name in table_info.keys() and table_info[table_name]: if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) @@ -877,11 +879,10 @@ def buildDB(self, manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) - else: - manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) - if table_manipulation.lower() == 'upsert': + + if table_manipulation and table_manipulation.lower() == 'upsert': existing_tables=self.get_table_info(datasetId=datasetId) tableId=existing_tables[table_name] annos = self.syn.get_annotations(tableId) From 1a987a1372a32c503300f91992c747f5896e1890 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 1 Feb 2023 17:08:46 -0500 Subject: [PATCH 110/615] modify test --- tests/test_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index f222c9f53..2ea5a1078 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -385,13 +385,13 @@ def test_generate_new_manifest(self, caplog, client, data_model_jsonld, data_typ if data_type == "all manifests": # return error message for record in caplog.records: - assert record.levelname == "ERROR" - assert "Currently we do not support returning multiple files as Excel format at once. Please choose a different output format." in caplog.text + if record.message == "Currently we do not support returning multiple files as Excel format at once.": + assert record.levelname == "WARNING" elif isinstance(data_type, list) and len(data_type) > 1: # return warning message for record in caplog.records: - assert record.levelname == "WARNING" - assert "Currently we do not support returning multiple files as Excel format at once." in caplog.text + if record.message == "Currently we do not support returning multiple files as Excel format at once.": + assert record.levelname == "WARNING" self.ifExcelExists(response, "Example.Biospecimen.manifest.xlsx") else: self.ifExcelExists(response, "Example.xlsx") From befa3a85c27b4121c8bbaa30363930342ef5a943 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:20:45 -0700 Subject: [PATCH 111/615] update create table choice logic --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a0fc8c8a6..b6ae82bdc 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -869,7 +869,7 @@ def buildDB(self, schema = Schema(name=table_name, columns=col_schema, parent=self.getDatasetProject(datasetId)) - if not table_manipulation or (table_name not in table_info.keys() and table_info[table_name]): + if not table_manipulation or table_name not in table_info.keys(): manifest_table_id = TableOperations.createTable(self, tableToLoad=table_manifest, tableName=table_name, datasetId=datasetId, columnTypeDict=col_schema, specifySchema=True, restrict=restrict) elif table_name in table_info.keys() and table_info[table_name]: From 4f96f4f5b1e1f851983085617343ab48d5e2c0ac Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:44:38 -0700 Subject: [PATCH 112/615] update tests --- tests/test_store.py | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index c87f995b2..f3950f90e 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -348,7 +348,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId ).asDataFrame().squeeze() # assert Days to FollowUp == 73 - assert (daysToFollowUp == '73.0').all() + assert (daysToFollowUp == 73).all() # Associate replacement manifest with files manifestId = synapse_store.associateMetadataWithFiles( @@ -370,7 +370,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId ).asDataFrame().squeeze() # assert Days to FollowUp == 89 now and not 73 - assert (daysToFollowUp == '89').all() + assert (daysToFollowUp == 89).all() # delete table synapse_store.syn.delete(tableId) @@ -380,7 +380,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) table_name='patient_synapse_storage_manifest_table' manifest_path = "mock_manifests/rdb_table_manifest.csv" replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" - column_of_interest="PatientID" + column_of_interest="Patient_id" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -401,7 +401,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = datasetId, manifest_record_type = 'table', - useSchemaLabel = True, + useSchemaLabel = False, hideBlanks = True, restrict_manifest = False, table_manipulation=table_manipulation, @@ -410,10 +410,6 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) #set primary key annotation for uploaded table tableId = existing_tables[table_name] - annos = synapse_store.syn.get_annotations(tableId) - annos['primary_key'] = 'PatientID' - annos=synapse_store.syn.set_annotations(annos) - sleep(5) # Query table for DaystoFollowUp column patientIDs = synapse_store.syn.tableQuery( @@ -421,7 +417,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert patientIDs.max() == '4' + assert patientIDs.max() == 4 assert patientIDs.size == 4 # Associate new manifest with files @@ -430,7 +426,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) metadataManifestPath = helpers.get_data_path(replacement_manifest_path), datasetId = datasetId, manifest_record_type = 'table', - useSchemaLabel = True, + useSchemaLabel = False, hideBlanks = True, restrict_manifest = False, table_manipulation=table_manipulation, @@ -444,7 +440,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert patientIDs.max() == '8' + assert patientIDs.max() == 8 assert patientIDs.size == 8 # delete table synapse_store.syn.delete(tableId) From 2360ab9289d28c936dec089b8ecdf3d71c42ae44 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 1 Feb 2023 15:52:36 -0700 Subject: [PATCH 113/615] remove hotfix from earlier PR --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index b6ae82bdc..a62b5ecf5 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1138,7 +1138,7 @@ def associateMetadataWithFiles( load_args={ "dtype":"string", } - manifest = load_df(metadataManifestPath, preserve_raw_input = True, **load_args) #HOTFIX: set preserve_raw_input to true to allow mixed type cols in table uploads schematic#870 + manifest = load_df(metadataManifestPath, preserve_raw_input = False, **load_args) except FileNotFoundError as err: raise FileNotFoundError( f"No manifest file was found at this path: {metadataManifestPath}" From 52ef3d380106f3bf44c5a8ed2e7c23646790791f Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 3 Feb 2023 14:10:58 -0500 Subject: [PATCH 114/615] added test for table upsert and upload --- api/openapi/api.yaml | 1 + api/routes.py | 2 +- tests/test_api.py | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index bedf0ae3b..2a9b75594 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -303,6 +303,7 @@ paths: schema: type: string enum: ["replace", "upsert"] + required: true operationId: api.routes.submit_manifest_route responses: "200": diff --git a/api/routes.py b/api/routes.py index c87f84995..5069d7093 100644 --- a/api/routes.py +++ b/api/routes.py @@ -378,7 +378,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None validate_component = data_type manifest_id = metadata_model.submit_metadata_manifest( - path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules, table_manipulation=table_manipulation) + path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules) return manifest_id diff --git a/tests/test_api.py b/tests/test_api.py index 67b31a12a..9f7d3d71a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -512,7 +512,8 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): assert response_path.endswith(".csv") @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) - def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv): + @pytest.mark.parametrize("table_manipulation", ["replace", "upsert"]) + def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, table_manipulation): params = { "input_token": syn_token, "schema_url": data_model_jsonld, @@ -521,6 +522,7 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t "manifest_record_type": "table", "asset_view": "syn44259375", "dataset_id": "syn44259313", + "table_manipulation": table_manipulation } if json_str: From 7b758b8280b5e36d289addc026a18aa0c500fd98 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 3 Feb 2023 14:18:35 -0500 Subject: [PATCH 115/615] fix syntax --- schematic/manifest/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index da8a500d6..4550b2038 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1603,7 +1603,7 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a # initalize excel writer writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') writer.book = workbook - writer.sheets = {ws.title: ws for ws in workbook.worksheets} + writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.sheets["Sheet1"] # add additional content to the existing spreadsheet From 931221a1ff566a26165b5360eec78f44206f4c32 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 3 Feb 2023 15:49:10 -0500 Subject: [PATCH 116/615] add description of table_manipulation --- api/openapi/api.yaml | 3 ++- api/routes.py | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 2a9b75594..df6b40aeb 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -300,10 +300,11 @@ paths: }]' - in: query name: table_manipulation + description: Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'.replace' will remove the rows and columns from the existing table and store the new rows and columns, preserving the name and synID.'upsert' will add the new rows to the table and preserve the exisitng rows and columns in the existing table. If nothing is selected, the default is "replace" schema: type: string enum: ["replace", "upsert"] - required: true + required: false operationId: api.routes.submit_manifest_route responses: "200": diff --git a/api/routes.py b/api/routes.py index 5069d7093..6479fc054 100644 --- a/api/routes.py +++ b/api/routes.py @@ -349,7 +349,7 @@ def validate_manifest_route(schema_url, data_type, json_str=None): return res_dict -def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None): +def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None, table_manipulation=None): # call config_handler() config_handler(asset_view = asset_view) @@ -370,7 +370,8 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None input_token = connexion.request.args["input_token"] - table_manipulation = connexion.request.args["table_manipulation"] + if not table_manipulation: + table_manipulation = "replace" if data_type == 'None': validate_component = None @@ -378,7 +379,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None validate_component = data_type manifest_id = metadata_model.submit_metadata_manifest( - path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules) + path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules, table_manipulation = table_manipulation) return manifest_id From 485b9779054db52d60fd577aecd964642903476b Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 6 Feb 2023 15:10:56 -0500 Subject: [PATCH 117/615] remove print statement --- tests/test_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 2ea5a1078..474f5dd80 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -54,7 +54,6 @@ def syn_token(config): class TestSynapseStorage: @pytest.mark.parametrize("return_type", ["json", "csv"]) def test_get_storage_assets_tables(self, client, syn_token, return_type): - print('ensure that local changes are working') params = { "input_token": syn_token, "asset_view": "syn23643253", From 1bf0c235887507cf4bbf31546351ec342bba6574 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 13:46:59 -0700 Subject: [PATCH 118/615] Update poetry.lock --- poetry.lock | 321 ++++++++++++++++++++++++++-------------------------- 1 file changed, 161 insertions(+), 160 deletions(-) diff --git a/poetry.lock b/poetry.lock index 31d5b32d4..e8600abfc 100644 --- a/poetry.lock +++ b/poetry.lock @@ -8,7 +8,7 @@ python-versions = ">=3.6" [[package]] name = "altair" -version = "4.2.1" +version = "4.2.0" description = "Altair: A declarative statistical visualization library for Python." category = "main" optional = false @@ -94,7 +94,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.13.3" +version = "2.14.1" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false @@ -155,7 +155,7 @@ python-versions = "*" [[package]] name = "beautifulsoup4" -version = "4.11.1" +version = "4.11.2" description = "Screen-scraping library" category = "main" optional = false @@ -358,7 +358,7 @@ test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0 [[package]] name = "dateparser" -version = "1.1.6" +version = "1.1.7" description = "Date parsing library designed to parse dates from HTML pages" category = "main" optional = false @@ -554,7 +554,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.74.0" +version = "2.76.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -645,14 +645,14 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= [[package]] name = "great-expectations" -version = "0.15.46" +version = "0.15.47" description = "Always know what to expect from your data." category = "main" optional = false python-versions = "*" [package.dependencies] -altair = ">=4.0.0,<5" +altair = ">=4.0.0,<4.2.1" Click = ">=7.1.2" colorama = ">=0.4.3" cryptography = ">=3.2" @@ -674,7 +674,7 @@ numpy = [ packaging = "*" pandas = [ {version = ">=1.1.3", markers = "python_version == \"3.9\""}, - {version = ">=1.4.0", markers = "python_version >= \"3.10\""}, + {version = ">=1.3.0", markers = "python_version >= \"3.10\""}, ] pydantic = ">=1.0,<2.0" pyparsing = ">=2.4" @@ -695,7 +695,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -710,13 +710,13 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.230)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] [[package]] name = "greenlet" -version = "2.0.1" +version = "2.0.2" description = "Lightweight in-process concurrent programming" category = "main" optional = false @@ -724,7 +724,7 @@ python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] docs = ["Sphinx", "docutils (<0.18)"] -test = ["faulthandler", "objgraph", "psutil"] +test = ["objgraph", "psutil"] [[package]] name = "httplib2" @@ -787,7 +787,7 @@ python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.20.2" +version = "6.21.1" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -796,9 +796,10 @@ python-versions = ">=3.8" [package.dependencies] appnope = {version = "*", markers = "platform_system == \"Darwin\""} comm = ">=0.1.1" -debugpy = ">=1.0" +debugpy = ">=1.6.5" ipython = ">=7.23.1" jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" @@ -899,15 +900,15 @@ arrow = ">=0.15.0" [[package]] name = "isort" -version = "5.11.4" +version = "5.12.0" description = "A Python utility / library to sort Python imports." category = "main" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" [package.extras] -colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pipreqs", "requirementslib"] +colors = ["colorama (>=0.4.3)"] +pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] plugins = ["setuptools"] requirements-deprecated-finder = ["pip-api", "pipreqs"] @@ -1006,7 +1007,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jupyter-client" -version = "8.0.1" +version = "8.0.2" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -1026,7 +1027,7 @@ test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-co [[package]] name = "jupyter-core" -version = "5.1.5" +version = "5.2.0" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "main" optional = false @@ -1064,14 +1065,14 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= [[package]] name = "jupyter-server" -version = "2.1.0" +version = "2.2.1" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false python-versions = ">=3.8" [package.dependencies] -anyio = ">=3.1.0,<4" +anyio = ">=3.1.0" argon2-cffi = "*" jinja2 = "*" jupyter-client = ">=7.4.4" @@ -1247,11 +1248,11 @@ reports = ["lxml"] [[package]] name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.5" [[package]] name = "nbclassic" @@ -1427,7 +1428,7 @@ test = ["pytest", "pytest-console-scripts", "pytest-tornasync"] [[package]] name = "numpy" -version = "1.24.1" +version = "1.24.2" description = "Fundamental package for array computing in Python" category = "main" optional = false @@ -1463,7 +1464,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openpyxl" -version = "3.0.10" +version = "3.1.0" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1732,14 +1733,14 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.15.10" +version = "2.16.1" description = "python code static checker" category = "main" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.12.13,<=2.14.0-dev0" +astroid = ">=2.14.1,<=2.16.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = {version = ">=0.2", markers = "python_version < \"3.11\""} isort = ">=4.2.5,<6" @@ -2213,11 +2214,11 @@ test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" -version = "2.0.0" +version = "2.0.1" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" [package.extras] lint = ["docutils-stubs", "flake8", "mypy"] @@ -2465,7 +2466,7 @@ telegram = ["requests"] [[package]] name = "traitlets" -version = "5.8.1" +version = "5.9.0" description = "Traitlets Python configuration system" category = "main" optional = false @@ -2565,7 +2566,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.5.0" +version = "1.5.1" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2605,20 +2606,20 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.11.0" +version = "3.12.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "b268daa6fbb4696ed28f1b35352775a63cf26ed49382b40a482c535ee3df0a1e" +content-hash = "c453989be896b19f387baa64f58dbcd3e4438b0b47a66b92e1dc15b3db4d6f26" [metadata.files] alabaster = [ @@ -2626,8 +2627,8 @@ alabaster = [ {file = "alabaster-0.7.13.tar.gz", hash = "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2"}, ] altair = [ - {file = "altair-4.2.1-py3-none-any.whl", hash = "sha256:67e099a651c78028c4e135e3b5bd9680ed7dd928ca7b61c9c7376c58e41d2b02"}, - {file = "altair-4.2.1.tar.gz", hash = "sha256:4939fd9119c57476bf305af9ca0bd1aa7779b2450b874d3623660e879d0fcad1"}, + {file = "altair-4.2.0-py3-none-any.whl", hash = "sha256:0c724848ae53410c13fa28be2b3b9a9dcb7b5caa1a70f7f217bd663bb419935a"}, + {file = "altair-4.2.0.tar.gz", hash = "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"}, ] anyio = [ {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, @@ -2669,8 +2670,8 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.13.3-py3-none-any.whl", hash = "sha256:14c1603c41cc61aae731cad1884a073c4645e26f126d13ac8346113c95577f3b"}, - {file = "astroid-2.13.3.tar.gz", hash = "sha256:6afc22718a48a689ca24a97981ad377ba7fb78c133f40335dfd16772f29bcfb1"}, + {file = "astroid-2.14.1-py3-none-any.whl", hash = "sha256:23c718921acab5f08cbbbe9293967f1f8fec40c336d19cd75dc12a9ea31d2eb2"}, + {file = "astroid-2.14.1.tar.gz", hash = "sha256:bd1aa4f9915c98e8aaebcd4e71930154d4e8c9aaf05d35ac0a63d1956091ae3f"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, @@ -2689,8 +2690,8 @@ backcall = [ {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] beautifulsoup4 = [ - {file = "beautifulsoup4-4.11.1-py3-none-any.whl", hash = "sha256:58d5c3d29f5a36ffeb94f02f0d786cd53014cf9b3b3951d42e0080d8a9498d30"}, - {file = "beautifulsoup4-4.11.1.tar.gz", hash = "sha256:ad9aa55b65ef2808eb405f46cf74df7fcb7044d5cbc26487f96eb2ef2e436693"}, + {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, + {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, ] black = [ {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, @@ -2977,8 +2978,8 @@ cryptography = [ {file = "cryptography-39.0.0.tar.gz", hash = "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf"}, ] dateparser = [ - {file = "dateparser-1.1.6-py2.py3-none-any.whl", hash = "sha256:c47b6e4b8c4b2b2a21690111b6571b6991295ba327ec6503753abeebf5e80696"}, - {file = "dateparser-1.1.6.tar.gz", hash = "sha256:e703db1815270c020552f4b3e3a981937b48b2cbcfcef5347071b74788dd9214"}, + {file = "dateparser-1.1.7-py2.py3-none-any.whl", hash = "sha256:fbed8b738a24c9cd7f47c4f2089527926566fe539e1a06125eddba75917b1eef"}, + {file = "dateparser-1.1.7.tar.gz", hash = "sha256:ff047d9cffad4d3113ead8ec0faf8a7fc43bab7d853ac8715e071312b53c465a"}, ] debugpy = [ {file = "debugpy-1.6.6-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:0ea1011e94416e90fb3598cc3ef5e08b0a4dd6ce6b9b33ccd436c1dffc8cd664"}, @@ -3061,8 +3062,8 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.74.0.tar.gz", hash = "sha256:22c9565b6d4343e35a6d614f2c075e765888a81e11444a27c570e0865631a3f9"}, - {file = "google_api_python_client-2.74.0-py2.py3-none-any.whl", hash = "sha256:679669b709450a12dacf28612adf0538afc858566b6ee01628e4013a2073dffc"}, + {file = "google-api-python-client-2.76.0.tar.gz", hash = "sha256:1446d8c618191afdb1190296a4f9648955460184c655da2bfa40c2968e6caac6"}, + {file = "google_api_python_client-2.76.0-py2.py3-none-any.whl", hash = "sha256:514326068802f8e8b32c282c2c1f528cf007247ba19470de6d013731985a3d28"}, ] google-auth = [ {file = "google-auth-2.16.0.tar.gz", hash = "sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd"}, @@ -3085,70 +3086,70 @@ graphviz = [ {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ - {file = "great_expectations-0.15.46-py3-none-any.whl", hash = "sha256:06373b688fce107a6659766b29ac7abe6ab01c62ad8ceda57e0e2ffb9b05db35"}, - {file = "great_expectations-0.15.46.tar.gz", hash = "sha256:f674cb57dbd8fc993fcf7b2d167253bceaa79db13cea0f5a9c92fd6ea13870bc"}, + {file = "great_expectations-0.15.47-py3-none-any.whl", hash = "sha256:82bbd508ce77d2dec5989b1b8746539212915343cce69dcdd9b134a35ed62f31"}, + {file = "great_expectations-0.15.47.tar.gz", hash = "sha256:efd7d312d427b9dbb257a042a841076ae962232a649002386bd9408c8a05f30a"}, ] greenlet = [ - {file = "greenlet-2.0.1-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:9ed358312e63bf683b9ef22c8e442ef6c5c02973f0c2a939ec1d7b50c974015c"}, - {file = "greenlet-2.0.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4f09b0010e55bec3239278f642a8a506b91034f03a4fb28289a7d448a67f1515"}, - {file = "greenlet-2.0.1-cp27-cp27m-win32.whl", hash = "sha256:1407fe45246632d0ffb7a3f4a520ba4e6051fc2cbd61ba1f806900c27f47706a"}, - {file = "greenlet-2.0.1-cp27-cp27m-win_amd64.whl", hash = "sha256:3001d00eba6bbf084ae60ec7f4bb8ed375748f53aeaefaf2a37d9f0370558524"}, - {file = "greenlet-2.0.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d566b82e92ff2e09dd6342df7e0eb4ff6275a3f08db284888dcd98134dbd4243"}, - {file = "greenlet-2.0.1-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:0722c9be0797f544a3ed212569ca3fe3d9d1a1b13942d10dd6f0e8601e484d26"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d37990425b4687ade27810e3b1a1c37825d242ebc275066cfee8cb6b8829ccd"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be35822f35f99dcc48152c9839d0171a06186f2d71ef76dc57fa556cc9bf6b45"}, - {file = "greenlet-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c140e7eb5ce47249668056edf3b7e9900c6a2e22fb0eaf0513f18a1b2c14e1da"}, - {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d21681f09e297a5adaa73060737e3aa1279a13ecdcfcc6ef66c292cb25125b2d"}, - {file = "greenlet-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb412b7db83fe56847df9c47b6fe3f13911b06339c2aa02dcc09dce8bbf582cd"}, - {file = "greenlet-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:c6a08799e9e88052221adca55741bf106ec7ea0710bca635c208b751f0d5b617"}, - {file = "greenlet-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e112e03d37987d7b90c1e98ba5e1b59e1645226d78d73282f45b326f7bddcb9"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56961cfca7da2fdd178f95ca407fa330c64f33289e1804b592a77d5593d9bd94"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13ba6e8e326e2116c954074c994da14954982ba2795aebb881c07ac5d093a58a"}, - {file = "greenlet-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bf633a50cc93ed17e494015897361010fc08700d92676c87931d3ea464123ce"}, - {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9f2c221eecb7ead00b8e3ddb913c67f75cba078fd1d326053225a3f59d850d72"}, - {file = "greenlet-2.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:13ebf93c343dd8bd010cd98e617cb4c1c1f352a0cf2524c82d3814154116aa82"}, - {file = "greenlet-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:6f61d71bbc9b4a3de768371b210d906726535d6ca43506737682caa754b956cd"}, - {file = "greenlet-2.0.1-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:2d0bac0385d2b43a7bd1d651621a4e0f1380abc63d6fb1012213a401cbd5bf8f"}, - {file = "greenlet-2.0.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:f6327b6907b4cb72f650a5b7b1be23a2aab395017aa6f1adb13069d66360eb3f"}, - {file = "greenlet-2.0.1-cp35-cp35m-win32.whl", hash = "sha256:81b0ea3715bf6a848d6f7149d25bf018fd24554a4be01fcbbe3fdc78e890b955"}, - {file = "greenlet-2.0.1-cp35-cp35m-win_amd64.whl", hash = "sha256:38255a3f1e8942573b067510f9611fc9e38196077b0c8eb7a8c795e105f9ce77"}, - {file = "greenlet-2.0.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:04957dc96669be041e0c260964cfef4c77287f07c40452e61abe19d647505581"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:4aeaebcd91d9fee9aa768c1b39cb12214b30bf36d2b7370505a9f2165fedd8d9"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974a39bdb8c90a85982cdb78a103a32e0b1be986d411303064b28a80611f6e51"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8dca09dedf1bd8684767bc736cc20c97c29bc0c04c413e3276e0962cd7aeb148"}, - {file = "greenlet-2.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4c0757db9bd08470ff8277791795e70d0bf035a011a528ee9a5ce9454b6cba2"}, - {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5067920de254f1a2dee8d3d9d7e4e03718e8fd2d2d9db962c8c9fa781ae82a39"}, - {file = "greenlet-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:5a8e05057fab2a365c81abc696cb753da7549d20266e8511eb6c9d9f72fe3e92"}, - {file = "greenlet-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:3d75b8d013086b08e801fbbb896f7d5c9e6ccd44f13a9241d2bf7c0df9eda928"}, - {file = "greenlet-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:097e3dae69321e9100202fc62977f687454cd0ea147d0fd5a766e57450c569fd"}, - {file = "greenlet-2.0.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:cb242fc2cda5a307a7698c93173d3627a2a90d00507bccf5bc228851e8304963"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:72b00a8e7c25dcea5946692a2485b1a0c0661ed93ecfedfa9b6687bd89a24ef5"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5b0ff9878333823226d270417f24f4d06f235cb3e54d1103b71ea537a6a86ce"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be9e0fb2ada7e5124f5282d6381903183ecc73ea019568d6d63d33f25b2a9000"}, - {file = "greenlet-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b493db84d124805865adc587532ebad30efa68f79ad68f11b336e0a51ec86c2"}, - {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0459d94f73265744fee4c2d5ec44c6f34aa8a31017e6e9de770f7bcf29710be9"}, - {file = "greenlet-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:a20d33124935d27b80e6fdacbd34205732660e0a1d35d8b10b3328179a2b51a1"}, - {file = "greenlet-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:ea688d11707d30e212e0110a1aac7f7f3f542a259235d396f88be68b649e47d1"}, - {file = "greenlet-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:afe07421c969e259e9403c3bb658968702bc3b78ec0b6fde3ae1e73440529c23"}, - {file = "greenlet-2.0.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:cd4ccc364cf75d1422e66e247e52a93da6a9b73cefa8cad696f3cbbb75af179d"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:4c8b1c43e75c42a6cafcc71defa9e01ead39ae80bd733a2608b297412beede68"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:659f167f419a4609bc0516fb18ea69ed39dbb25594934bd2dd4d0401660e8a1e"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:356e4519d4dfa766d50ecc498544b44c0249b6de66426041d7f8b751de4d6b48"}, - {file = "greenlet-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:811e1d37d60b47cb8126e0a929b58c046251f28117cb16fcd371eed61f66b764"}, - {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d38ffd0e81ba8ef347d2be0772e899c289b59ff150ebbbbe05dc61b1246eb4e0"}, - {file = "greenlet-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0109af1138afbfb8ae647e31a2b1ab030f58b21dd8528c27beaeb0093b7938a9"}, - {file = "greenlet-2.0.1-cp38-cp38-win32.whl", hash = "sha256:88c8d517e78acdf7df8a2134a3c4b964415b575d2840a2746ddb1cc6175f8608"}, - {file = "greenlet-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:d6ee1aa7ab36475035eb48c01efae87d37936a8173fc4d7b10bb02c2d75dd8f6"}, - {file = "greenlet-2.0.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:b1992ba9d4780d9af9726bbcef6a1db12d9ab1ccc35e5773685a24b7fb2758eb"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:b5e83e4de81dcc9425598d9469a624826a0b1211380ac444c7c791d4a2137c19"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:505138d4fa69462447a562a7c2ef723c6025ba12ac04478bc1ce2fcc279a2db5"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cce1e90dd302f45716a7715517c6aa0468af0bf38e814ad4eab58e88fc09f7f7"}, - {file = "greenlet-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e9744c657d896c7b580455e739899e492a4a452e2dd4d2b3e459f6b244a638d"}, - {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:662e8f7cad915ba75d8017b3e601afc01ef20deeeabf281bd00369de196d7726"}, - {file = "greenlet-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:41b825d65f31e394b523c84db84f9383a2f7eefc13d987f308f4663794d2687e"}, - {file = "greenlet-2.0.1-cp39-cp39-win32.whl", hash = "sha256:db38f80540083ea33bdab614a9d28bcec4b54daa5aff1668d7827a9fc769ae0a"}, - {file = "greenlet-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b23d2a46d53210b498e5b701a1913697671988f4bf8e10f935433f6e7c332fb6"}, - {file = "greenlet-2.0.1.tar.gz", hash = "sha256:42e602564460da0e8ee67cb6d7236363ee5e131aa15943b6670e44e5c2ed0f67"}, + {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, + {file = "greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, + {file = "greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, + {file = "greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, + {file = "greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, + {file = "greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, + {file = "greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, + {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, + {file = "greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, + {file = "greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, + {file = "greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, + {file = "greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, + {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, + {file = "greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, + {file = "greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, + {file = "greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, + {file = "greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, + {file = "greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, + {file = "greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, + {file = "greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, + {file = "greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, + {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, + {file = "greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, + {file = "greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, + {file = "greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, + {file = "greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, + {file = "greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, + {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, + {file = "greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, + {file = "greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, + {file = "greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, + {file = "greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, + {file = "greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, + {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, + {file = "greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, + {file = "greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, + {file = "greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, + {file = "greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, + {file = "greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, + {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, + {file = "greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, + {file = "greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, + {file = "greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, + {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, ] httplib2 = [ {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, @@ -3175,8 +3176,8 @@ iniconfig = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.20.2-py3-none-any.whl", hash = "sha256:5d0675d5f48bf6a95fd517d7b70bcb3b2c5631b2069949b5c2d6e1d7477fb5a0"}, - {file = "ipykernel-6.20.2.tar.gz", hash = "sha256:1893c5b847033cd7a58f6843b04a9349ffb1031bc6588401cadc9adb58da428e"}, + {file = "ipykernel-6.21.1-py3-none-any.whl", hash = "sha256:1a04bb359212e23e46adc0116ec82ea128c1e5bd532fde4fbe679787ff36f0cf"}, + {file = "ipykernel-6.21.1.tar.gz", hash = "sha256:a0f8eece39cab1ee352c9b59ec67bbe44d8299f8238e4c16ff7f4cf0052d3378"}, ] ipython = [ {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, @@ -3199,8 +3200,8 @@ isoduration = [ {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, ] isort = [ - {file = "isort-5.11.4-py3-none-any.whl", hash = "sha256:c033fd0edb91000a7f09527fe5c75321878f98322a77ddcc81adbd83724afb7b"}, - {file = "isort-5.11.4.tar.gz", hash = "sha256:6db30c5ded9815d813932c04c2f85a360bcdd35fed496f4d8f35495ef0a261b6"}, + {file = "isort-5.12.0-py3-none-any.whl", hash = "sha256:f84c2818376e66cf843d497486ea8fed8700b340f308f076c6fb1229dff318b6"}, + {file = "isort-5.12.0.tar.gz", hash = "sha256:8bef7dde241278824a6d83f44a544709b065191b95b6e50894bdc722fcba0504"}, ] itsdangerous = [ {file = "itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, @@ -3231,20 +3232,20 @@ jsonschema = [ {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] jupyter-client = [ - {file = "jupyter_client-8.0.1-py3-none-any.whl", hash = "sha256:6016b874fd1111d721bc5bee30624399e876e79e6f395d1a559e6dce9fb2e1ba"}, - {file = "jupyter_client-8.0.1.tar.gz", hash = "sha256:3f67b1c8b7687e6db09bef10ff97669932b5e6ef6f5a8ee56d444b89022c5007"}, + {file = "jupyter_client-8.0.2-py3-none-any.whl", hash = "sha256:c53731eb590b68839b0ce04bf46ff8c4f03278f5d9fe5c3b0f268a57cc2bd97e"}, + {file = "jupyter_client-8.0.2.tar.gz", hash = "sha256:47ac9f586dbcff4d79387ec264faf0fdeb5f14845fa7345fd7d1e378f8096011"}, ] jupyter-core = [ - {file = "jupyter_core-5.1.5-py3-none-any.whl", hash = "sha256:83064d61bb2a9bc874e8184331c117b3778c2a7e1851f60cb00d273ceb3285ae"}, - {file = "jupyter_core-5.1.5.tar.gz", hash = "sha256:8e54c48cde1e0c8345f64bcf9658b78044ddf02b273726cea9d9f59be4b02130"}, + {file = "jupyter_core-5.2.0-py3-none-any.whl", hash = "sha256:4bdc2928c37f6917130c667d8b8708f20aee539d8283c6be72aabd2a4b4c83b0"}, + {file = "jupyter_core-5.2.0.tar.gz", hash = "sha256:1407cdb4c79ee467696c04b76633fc1884015fa109323365a6372c8e890cc83f"}, ] jupyter-events = [ {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, ] jupyter-server = [ - {file = "jupyter_server-2.1.0-py3-none-any.whl", hash = "sha256:90cd6f2bd0581ddd9b2dbe82026a0f4c228a1d95c86e22460efbfdfc931fcf56"}, - {file = "jupyter_server-2.1.0.tar.gz", hash = "sha256:efaae5e4f0d5f22c7f2f2dc848635036ee74a2df02abed52d30d9d95121ad382"}, + {file = "jupyter_server-2.2.1-py3-none-any.whl", hash = "sha256:854fb7d49f6b7f545d4f8354172b004dcda887ba0699def7112daf785ba3c9ce"}, + {file = "jupyter_server-2.2.1.tar.gz", hash = "sha256:5afb8a0cdfee37d02d69bdf470ae9cbb1dee5d4788f9bc6cc8e54bd8c83fb096"}, ] jupyter-server-terminals = [ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, @@ -3393,8 +3394,8 @@ mypy = [ {file = "mypy-0.982.tar.gz", hash = "sha256:85f7a343542dc8b1ed0a888cdd34dca56462654ef23aa673907305b260b3d746"}, ] mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] nbclassic = [ {file = "nbclassic-0.5.1-py3-none-any.whl", hash = "sha256:32c235e1f22f4048f3b877d354c198202898797cf9c2085856827598cead001b"}, @@ -3429,34 +3430,34 @@ notebook-shim = [ {file = "notebook_shim-0.2.2.tar.gz", hash = "sha256:090e0baf9a5582ff59b607af523ca2db68ff216da0c69956b62cab2ef4fc9c3f"}, ] numpy = [ - {file = "numpy-1.24.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:179a7ef0889ab769cc03573b6217f54c8bd8e16cef80aad369e1e8185f994cd7"}, - {file = "numpy-1.24.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b09804ff570b907da323b3d762e74432fb07955701b17b08ff1b5ebaa8cfe6a9"}, - {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1b739841821968798947d3afcefd386fa56da0caf97722a5de53e07c4ccedc7"}, - {file = "numpy-1.24.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e3463e6ac25313462e04aea3fb8a0a30fb906d5d300f58b3bc2c23da6a15398"}, - {file = "numpy-1.24.1-cp310-cp310-win32.whl", hash = "sha256:b31da69ed0c18be8b77bfce48d234e55d040793cebb25398e2a7d84199fbc7e2"}, - {file = "numpy-1.24.1-cp310-cp310-win_amd64.whl", hash = "sha256:b07b40f5fb4fa034120a5796288f24c1fe0e0580bbfff99897ba6267af42def2"}, - {file = "numpy-1.24.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7094891dcf79ccc6bc2a1f30428fa5edb1e6fb955411ffff3401fb4ea93780a8"}, - {file = "numpy-1.24.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:28e418681372520c992805bb723e29d69d6b7aa411065f48216d8329d02ba032"}, - {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e274f0f6c7efd0d577744f52032fdd24344f11c5ae668fe8d01aac0422611df1"}, - {file = "numpy-1.24.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0044f7d944ee882400890f9ae955220d29b33d809a038923d88e4e01d652acd9"}, - {file = "numpy-1.24.1-cp311-cp311-win32.whl", hash = "sha256:442feb5e5bada8408e8fcd43f3360b78683ff12a4444670a7d9e9824c1817d36"}, - {file = "numpy-1.24.1-cp311-cp311-win_amd64.whl", hash = "sha256:de92efa737875329b052982e37bd4371d52cabf469f83e7b8be9bb7752d67e51"}, - {file = "numpy-1.24.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b162ac10ca38850510caf8ea33f89edcb7b0bb0dfa5592d59909419986b72407"}, - {file = "numpy-1.24.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:26089487086f2648944f17adaa1a97ca6aee57f513ba5f1c0b7ebdabbe2b9954"}, - {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:caf65a396c0d1f9809596be2e444e3bd4190d86d5c1ce21f5fc4be60a3bc5b36"}, - {file = "numpy-1.24.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b0677a52f5d896e84414761531947c7a330d1adc07c3a4372262f25d84af7bf7"}, - {file = "numpy-1.24.1-cp38-cp38-win32.whl", hash = "sha256:dae46bed2cb79a58d6496ff6d8da1e3b95ba09afeca2e277628171ca99b99db1"}, - {file = "numpy-1.24.1-cp38-cp38-win_amd64.whl", hash = "sha256:6ec0c021cd9fe732e5bab6401adea5a409214ca5592cd92a114f7067febcba0c"}, - {file = "numpy-1.24.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:28bc9750ae1f75264ee0f10561709b1462d450a4808cd97c013046073ae64ab6"}, - {file = "numpy-1.24.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84e789a085aabef2f36c0515f45e459f02f570c4b4c4c108ac1179c34d475ed7"}, - {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e669fbdcdd1e945691079c2cae335f3e3a56554e06bbd45d7609a6cf568c700"}, - {file = "numpy-1.24.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef85cf1f693c88c1fd229ccd1055570cb41cdf4875873b7728b6301f12cd05bf"}, - {file = "numpy-1.24.1-cp39-cp39-win32.whl", hash = "sha256:87a118968fba001b248aac90e502c0b13606721b1343cdaddbc6e552e8dfb56f"}, - {file = "numpy-1.24.1-cp39-cp39-win_amd64.whl", hash = "sha256:ddc7ab52b322eb1e40521eb422c4e0a20716c271a306860979d450decbb51b8e"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:ed5fb71d79e771ec930566fae9c02626b939e37271ec285e9efaf1b5d4370e7d"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad2925567f43643f51255220424c23d204024ed428afc5aad0f86f3ffc080086"}, - {file = "numpy-1.24.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:cfa1161c6ac8f92dea03d625c2d0c05e084668f4a06568b77a25a89111621566"}, - {file = "numpy-1.24.1.tar.gz", hash = "sha256:2386da9a471cc00a1f47845e27d916d5ec5346ae9696e01a8a34760858fe9dd2"}, + {file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"}, + {file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"}, + {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"}, + {file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"}, + {file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"}, + {file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"}, + {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"}, + {file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"}, + {file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"}, + {file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"}, + {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"}, + {file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"}, + {file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"}, + {file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"}, + {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"}, + {file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"}, + {file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"}, + {file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"}, + {file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"}, ] oauth2client = [ {file = "oauth2client-4.1.3-py2.py3-none-any.whl", hash = "sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac"}, @@ -3467,8 +3468,8 @@ oauthlib = [ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, ] openpyxl = [ - {file = "openpyxl-3.0.10-py2.py3-none-any.whl", hash = "sha256:0ab6d25d01799f97a9464630abacbb34aafecdcaa0ef3cba6d6b3499867d0355"}, - {file = "openpyxl-3.0.10.tar.gz", hash = "sha256:e47805627aebcf860edb4edf7987b1309c1b3632f3750538ed962bbcc3bd7449"}, + {file = "openpyxl-3.1.0-py2.py3-none-any.whl", hash = "sha256:24d7d361025d186ba91eff58135d50855cf035a84371b891e58fb6eb5125660f"}, + {file = "openpyxl-3.1.0.tar.gz", hash = "sha256:eccedbe1cdd8b2494057e73959b496821141038dbb7eb9266ea59e3f34208231"}, ] packaging = [ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, @@ -3648,8 +3649,8 @@ pygsheets = [ {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.15.10-py3-none-any.whl", hash = "sha256:9df0d07e8948a1c3ffa3b6e2d7e6e63d9fb457c5da5b961ed63106594780cc7e"}, - {file = "pylint-2.15.10.tar.gz", hash = "sha256:b3dc5ef7d33858f297ac0d06cc73862f01e4f2e74025ec3eff347ce0bc60baf5"}, + {file = "pylint-2.16.1-py3-none-any.whl", hash = "sha256:bad9d7c36037f6043a1e848a43004dfd5ea5ceb05815d713ba56ca4503a9fe37"}, + {file = "pylint-2.16.1.tar.gz", hash = "sha256:ffe7fa536bb38ba35006a7c8a6d2efbfdd3d95bbf21199cad31f76b1c50aaf30"}, ] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -4090,8 +4091,8 @@ sphinxcontrib-devhelp = [ {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] sphinxcontrib-htmlhelp = [ - {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, - {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, + {file = "sphinxcontrib-htmlhelp-2.0.1.tar.gz", hash = "sha256:0cbdd302815330058422b98a113195c9249825d681e18f11e8b1f78a2f11efff"}, + {file = "sphinxcontrib_htmlhelp-2.0.1-py3-none-any.whl", hash = "sha256:c38cb46dccf316c79de6e5515e1770414b797162b23cd3d06e67020e1d2a6903"}, ] sphinxcontrib-jsmath = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, @@ -4210,8 +4211,8 @@ tqdm = [ {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, ] traitlets = [ - {file = "traitlets-5.8.1-py3-none-any.whl", hash = "sha256:a1ca5df6414f8b5760f7c5f256e326ee21b581742114545b462b35ffe3f04861"}, - {file = "traitlets-5.8.1.tar.gz", hash = "sha256:32500888f5ff7bbf3b9267ea31748fa657aaf34d56d85e60f91dda7dc7f5785b"}, + {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, + {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, @@ -4250,8 +4251,8 @@ webencodings = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.5.0.tar.gz", hash = "sha256:561ca949e5bbb5d33409a37235db55c279235c78ee407802f1d2314fff8a8536"}, - {file = "websocket_client-1.5.0-py3-none-any.whl", hash = "sha256:fb5d81b95d350f3a54838ebcb4c68a5353bbd1412ae8f068b1e5280faeb13074"}, + {file = "websocket-client-1.5.1.tar.gz", hash = "sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40"}, + {file = "websocket_client-1.5.1-py3-none-any.whl", hash = "sha256:cdf5877568b7e83aa7cf2244ab56a3213de587bbe0ce9d8b9600fc77b455d89e"}, ] werkzeug = [ {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, @@ -4328,6 +4329,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.11.0-py3-none-any.whl", hash = "sha256:83a28fcb75844b5c0cdaf5aa4003c2d728c77e05f5aeabe8e95e56727005fbaa"}, - {file = "zipp-3.11.0.tar.gz", hash = "sha256:a7a22e05929290a67401440b39690ae6563279bced5f314609d9d03798f56766"}, + {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"}, + {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"}, ] From 286de7ed5b6130bd18d09a63a606cf043aedeb01 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 15:41:57 -0700 Subject: [PATCH 119/615] add new component compliant with `upsert` reqs --- tests/data/example.model.csv | 2 ++ tests/data/example.model.jsonld | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index cfe08da33..88ae784a4 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -37,3 +37,5 @@ Check Ages,,,,,TRUE,DataProperty,,,protectAges Check Unique,,,,,TRUE,DataProperty,,,unique error Check Range,,,,,TRUE,DataProperty,,,inRange 50 100 error Check Date,,,,,TRUE,DataProperty,,, +MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, +MockRDB_id,,,,,TRUE,DataProperty,,,int diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index b7396e479..650cd0299 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2895,6 +2895,50 @@ "sms:required": "sms:true", "sms:validationRules": [] }, + { + "@id": "bts:MockRDB", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDB", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:Component" + }, + { + "@id": "bts:MockRDBId" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:MockRDBId", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDBId", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB_id", + "sms:required": "sms:true", + "sms:validationRules": [ + "int" + ] + }, { "@id": "bts:Component", "@type": "rdfs:Class", From d35fe3dbbfcc0807cbf5476b8a818e4ed4d9c927 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 15:42:53 -0700 Subject: [PATCH 120/615] update rdb manifests for new component --- tests/data/mock_manifests/rdb_table_manifest.csv | 10 +++++----- .../data/mock_manifests/rdb_table_manifest_upsert.csv | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index 785ed869a..e547895ba 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,5 +1,5 @@ -Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History -1,Male,1965,Healthy,Patient,, -2,Female,1966,Healthy,Patient,, -3,Male,1967,Healthy,Patient,, -4,Female,1968,Healthy,Patient,, +Component,MockRDB_id +MockRDB,1 +MockRDB,2 +MockRDB,3 +MockRDB,4 diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index ddc2ecf5b..625c1f66f 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,5 +1,5 @@ -Patient_id,Sex,Year of Birth,Diagnosis,Component,Cancer Type,Family History -5,Male,1954,Healthy,Patient,, -6,Female,1955,Healthy,Patient,, -7,Male,1956,Healthy,Patient,, -8,Female,1957,Healthy,Patient,, +Component,MockRDB_id +MockRDB,5 +MockRDB,6 +MockRDB,7 +MockRDB,8 From 7e93e98a999257742589f4bfb4109caf11b72d92 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 15:43:18 -0700 Subject: [PATCH 121/615] update upsert test for new dummy data --- tests/test_store.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index f3950f90e..22ef594ed 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -375,12 +375,12 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId synapse_store.syn.delete(tableId) def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId): - table_manipulation = 'upsert' + table_manipulation = "upsert" - table_name='patient_synapse_storage_manifest_table' + table_name="MockRDB_synapse_storage_manifest_table".lower() manifest_path = "mock_manifests/rdb_table_manifest.csv" replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" - column_of_interest="Patient_id" + column_of_interest="MockRDB_id" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -412,13 +412,13 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) tableId = existing_tables[table_name] # Query table for DaystoFollowUp column - patientIDs = synapse_store.syn.tableQuery( + IDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert patientIDs.max() == 4 - assert patientIDs.size == 4 + assert IDs.max() == 4 + assert IDs.size == 4 # Associate new manifest with files manifestId = synapse_store.associateMetadataWithFiles( @@ -435,12 +435,12 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # Query table for DaystoFollowUp column tableId = existing_tables[table_name] - patientIDs = synapse_store.syn.tableQuery( + IDs = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert patientIDs.max() == 8 - assert patientIDs.size == 8 + assert IDs.max() == 8 + assert IDs.size == 8 # delete table synapse_store.syn.delete(tableId) From f09b7c8dfc54e3146260a37ac64e254823899673 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:17:32 -0700 Subject: [PATCH 122/615] add to help docs --- schematic/help.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schematic/help.py b/schematic/help.py index 746db2ba2..38879f94c 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -117,6 +117,8 @@ "'replace' will remove the rows and columns from the existing table and store the new rows and columns, preserving the name and synID. " "'upsert' will add the new rows to the table and preserve the exisitng rows and columns in the existing table. " "Default value is 'replace'. " + "'upsert' should be used for initial table uploads if users intend to upsert into them at a later time." + "Using 'upsert' at creation will generate the metadata necessary for upsert functionality." ), }, "validate": { From 212dcc5e5852660c486d14c082466ddb1082540f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 6 Feb 2023 16:34:07 -0700 Subject: [PATCH 123/615] update in code documentation --- schematic/store/synapse.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a62b5ecf5..7063570a8 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1629,7 +1629,8 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse - + For upsert functionality to work, primary keys must follow the naming convention of _id + Args: tableToLoad: manifest formatted appropriately for the table tableName: name of the table to be uploaded From df8655454872bfc5f56e0dfdfde781b8833342e1 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 7 Feb 2023 10:51:55 -0500 Subject: [PATCH 124/615] change sheets to worksheets --- schematic/manifest/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 4550b2038..7706863bf 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1604,7 +1604,7 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') writer.book = workbook writer.worksheets = {ws.title: ws for ws in workbook.worksheets} - worksheet = writer.sheets["Sheet1"] + worksheet = writer.worksheets["Sheet1"] # add additional content to the existing spreadsheet additional_df.to_excel(writer, sheet_name = "Sheet1", startrow=1, index = False, header=False) From 30de5391fea4e94c513e2298d86036cdd131d2b7 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 7 Feb 2023 11:51:55 -0500 Subject: [PATCH 125/615] commented out test that involves reading json --- tests/test_api.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index b79f71a84..e61c0e1f2 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -481,10 +481,11 @@ def test_validate_manifest(self, data_model_jsonld, client, json_str, test_manif # test uploading a json file # change data type to patient since the testing json manifest is using Patient component - params["data_type"] = "Patient" - response_json = client.post('http://localhost:3001/v1/model/validate', query_string=params, data={"file_name": (open(test_manifest_json, 'rb'), "test.json")}, headers=headers) - response_dt = json.loads(response_json.data) - assert response_json.status_code == 200 + # WILL DEPRECATE uploading a json file for validation + # params["data_type"] = "Patient" + # response_json = client.post('http://localhost:3001/v1/model/validate', query_string=params, data={"file_name": (open(test_manifest_json, 'rb'), "test.json")}, headers=headers) + # response_dt = json.loads(response_json.data) + # assert response_json.status_code == 200 assert "errors" in response_dt.keys() assert "warnings" in response_dt.keys() @@ -545,6 +546,7 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t "manifest_record_type": "table", "asset_view": "syn44259375", "dataset_id": "syn44259313", + "table_manipulation": "replace" } if json_str: From 61e810fc421b14658bdb9ddd846fcd23b114d993 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Tue, 7 Feb 2023 11:27:51 -0800 Subject: [PATCH 126/615] set pyopenssl = "^23.0.0" --- poetry.lock | 25 +++++++++++++++++++++++-- pyproject.toml | 1 + 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/poetry.lock b/poetry.lock index e8600abfc..63602e01f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1754,6 +1754,21 @@ typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\"" spelling = ["pyenchant (>=3.2,<4.0)"] testutils = ["gitpython (>3)"] +[[package]] +name = "pyopenssl" +version = "23.0.0" +description = "Python wrapper module around the OpenSSL library" +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +cryptography = ">=38.0.0,<40" + +[package.extras] +docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] +test = ["flaky", "pretend", "pytest (>=3.0.1)"] + [[package]] name = "pyparsing" version = "3.0.9" @@ -2619,7 +2634,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "c453989be896b19f387baa64f58dbcd3e4438b0b47a66b92e1dc15b3db4d6f26" +content-hash = "ae7079cb736b90a347ca40996b25cd638583d9955e42209e3c67b2bc4b9f1cff" [metadata.files] alabaster = [ @@ -2994,7 +3009,6 @@ debugpy = [ {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, - {file = "debugpy-1.6.6-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:11a0f3a106f69901e4a9a5683ce943a7a5605696024134b522aa1bfda25b5fec"}, {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, @@ -3556,7 +3570,9 @@ protobuf = [ {file = "protobuf-4.21.12-cp38-cp38-win_amd64.whl", hash = "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30"}, {file = "protobuf-4.21.12-cp39-cp39-win32.whl", hash = "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc"}, {file = "protobuf-4.21.12-cp39-cp39-win_amd64.whl", hash = "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b"}, + {file = "protobuf-4.21.12-py2.py3-none-any.whl", hash = "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5"}, {file = "protobuf-4.21.12-py3-none-any.whl", hash = "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462"}, + {file = "protobuf-4.21.12.tar.gz", hash = "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab"}, ] psutil = [ {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, @@ -3652,6 +3668,10 @@ pylint = [ {file = "pylint-2.16.1-py3-none-any.whl", hash = "sha256:bad9d7c36037f6043a1e848a43004dfd5ea5ceb05815d713ba56ca4503a9fe37"}, {file = "pylint-2.16.1.tar.gz", hash = "sha256:ffe7fa536bb38ba35006a7c8a6d2efbfdd3d95bbf21199cad31f76b1c50aaf30"}, ] +pyopenssl = [ + {file = "pyOpenSSL-23.0.0-py3-none-any.whl", hash = "sha256:df5fc28af899e74e19fccb5510df423581047e10ab6f1f4ba1763ff5fde844c0"}, + {file = "pyOpenSSL-23.0.0.tar.gz", hash = "sha256:c1cc5f86bcacefc84dada7d31175cae1b1518d5f60d3d0bb595a67822a868a6f"}, +] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, {file = "pyparsing-3.0.9.tar.gz", hash = "sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb"}, @@ -3993,6 +4013,7 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, diff --git a/pyproject.toml b/pyproject.toml index e1b13e76b..2bf75490c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,6 +69,7 @@ Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" schematic-db = {version = "^0.0.6", extras = ["synapse"]} +pyopenssl = "^23.0.0" [tool.poetry.dev-dependencies] From 2876148ec62eca680a7f81c7a69d7b9b5609b523 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Tue, 7 Feb 2023 12:08:02 -0800 Subject: [PATCH 127/615] add error message --- schematic/models/validate_attribute.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index cd28614cb..831cca783 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -464,8 +464,11 @@ def generate_content_error( elif val_rule.startswith('inRange'): cross_error_str = ( f"{attribute_name} values in rows {row_num} are out of the specified range." + ) + elif val_rule.startswith('date'): + cross_error_str = ( + f"{attribute_name} values in rows {row_num} are not parsable as dates." ) - logLevel(cross_error_str) error_row = row_num error_message = cross_error_str From e88f4d5b5e86113ff0ea4bde98b93901ec90688b Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Tue, 7 Feb 2023 15:04:24 -0800 Subject: [PATCH 128/615] removed logging --- schematic/models/GE_Helpers.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 6299492b7..d8760eb51 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -418,7 +418,6 @@ def generate_errors( # indices and values cannot be returned else: for i, item in enumerate(self.manifest[errColumn]): - logging.warning(result_dict) observed_type=result_dict['result']['observed_value'] indices.append(i) if isinstance(item,type_dict[observed_type]) else indices values.append(item) if isinstance(item,type_dict[observed_type]) else values From 8d21d328846f937da4e8014515da8a3fa2d07d86 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Tue, 7 Feb 2023 15:15:19 -0800 Subject: [PATCH 129/615] added assertion checking for date error --- tests/test_validation.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_validation.py b/tests/test_validation.py index 82abfac78..83869418b 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -65,6 +65,8 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): rootNode=rootNode ) + logging.warning(errors) + #Check errors assert GenerateError.generate_type_error( val_rule = 'num', @@ -141,6 +143,14 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): sg = sg, )[0] in errors + assert GenerateError.generate_content_error( + val_rule = 'date', + attribute_name = 'Check Date', + sg = sg, + row_num = [2,3,4], + error_val = ['84-43-094', '32-984', 'notADate'], + )[0] in errors + assert GenerateError.generate_content_error( val_rule = 'unique error', attribute_name = 'Check Unique', From b6bc8874d15d90af31fed0be2aa1fc654e1c6954 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:05:58 -0700 Subject: [PATCH 130/615] add param to .yaml --- api/openapi/api.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index d7a032e19..68da4a206 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -311,6 +311,13 @@ paths: type: string enum: ["replace", "upsert"] required: false + - in: query + name: use_schema_label + description: "Store attributes using the schema label (true, default) or store attributes using the display label (false). Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'" + schema: + type: boolean + default: true + required: true operationId: api.routes.submit_manifest_route responses: "200": From 05021740900532163394407ee718a6fdef9e5771 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:06:15 -0700 Subject: [PATCH 131/615] add function to parse booleans --- api/routes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 6a5882f19..46a3e90d3 100644 --- a/api/routes.py +++ b/api/routes.py @@ -161,7 +161,11 @@ def convert_json_file_to_csv(self, file_key): temp_path = save_file(file_key='file_name') return temp_path - +def parse_bool(str_bool): + if str_bool.lower().startswith('t'): + return True + else: + return False def save_file(file_key="csv_file"): ''' From 5535b332a5ef0d218d6049ce8bcbdab68f5ebb0a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 12:06:47 -0700 Subject: [PATCH 132/615] read new param and pass to submission --- api/routes.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 46a3e90d3..0a283e61c 100644 --- a/api/routes.py +++ b/api/routes.py @@ -375,6 +375,8 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None input_token = connexion.request.args["input_token"] + use_schema_label = parse_bool(connexion.request.args["use_schema_label"]) + if not table_manipulation: table_manipulation = "replace" @@ -384,7 +386,15 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None validate_component = data_type manifest_id = metadata_model.submit_metadata_manifest( - path_to_json_ld = schema_url, manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, input_token=input_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules, table_manipulation = table_manipulation) + path_to_json_ld = schema_url, + manifest_path=temp_path, + dataset_id=dataset_id, + validate_component=validate_component, + input_token=input_token, + manifest_record_type = manifest_record_type, + restrict_rules = restrict_rules, + table_manipulation = table_manipulation, + use_schema_label=use_schema_label) return manifest_id From 7e5f7f78bc895d076eb4d7dccf640623ec22262b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:32:24 -0700 Subject: [PATCH 133/615] parse `restrict_rules` as bool --- api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 0a283e61c..1d0d5bdb2 100644 --- a/api/routes.py +++ b/api/routes.py @@ -369,7 +369,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None data_type = connexion.request.args["data_type"] - restrict_rules = connexion.request.args["restrict_rules"] + restrict_rules = parse_bool(connexion.request.args["restrict_rules"]) metadata_model = initalize_metadata_model(schema_url) From 7f68bff77f1c01f620f0fb47d5c0740010cd78c3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 13:43:54 -0700 Subject: [PATCH 134/615] add message and specify false conditon --- api/routes.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 1d0d5bdb2..4ff864f4c 100644 --- a/api/routes.py +++ b/api/routes.py @@ -164,8 +164,12 @@ def convert_json_file_to_csv(self, file_key): def parse_bool(str_bool): if str_bool.lower().startswith('t'): return True - else: + elif str_bool.lower().startswith('f'): return False + else: + raise ValueError( + "String boolean does not appear to be true or false. Please verify input" + ) def save_file(file_key="csv_file"): ''' From 6c8b977ec985b466871fd25ba1ce55fbb5da689e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:26:41 -0700 Subject: [PATCH 135/615] update message --- api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 4ff864f4c..19ccbdd07 100644 --- a/api/routes.py +++ b/api/routes.py @@ -168,7 +168,7 @@ def parse_bool(str_bool): return False else: raise ValueError( - "String boolean does not appear to be true or false. Please verify input" + "String boolean does not appear to be true or false. Please verify input." ) def save_file(file_key="csv_file"): From 83f24ef87cbf5d16fb544c42c30f72015afcae2a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:27:12 -0700 Subject: [PATCH 136/615] update manifest submission api test --- tests/test_api.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0f3c310fb..5d7573084 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -538,7 +538,8 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) @pytest.mark.parametrize("table_manipulation", ["replace", "upsert"]) - def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, table_manipulation): + @pytest.mark.parametrize("use_schema_label", ['true','false']) + def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, table_manipulation, use_schema_label): params = { "input_token": syn_token, "schema_url": data_model_jsonld, @@ -547,7 +548,8 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t "manifest_record_type": "table", "asset_view": "syn44259375", "dataset_id": "syn44259313", - "table_manipulation": table_manipulation + "table_manipulation": table_manipulation, + "use_schema_label": use_schema_label } if json_str: From 5a149fa4458317eefd780be211197f348e2610fe Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:35:08 -0700 Subject: [PATCH 137/615] update cli docs --- schematic/help.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schematic/help.py b/schematic/help.py index 38879f94c..dff2a9214 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -117,8 +117,11 @@ "'replace' will remove the rows and columns from the existing table and store the new rows and columns, preserving the name and synID. " "'upsert' will add the new rows to the table and preserve the exisitng rows and columns in the existing table. " "Default value is 'replace'. " + "Upsert specific requirements: {\n}" "'upsert' should be used for initial table uploads if users intend to upsert into them at a later time." "Using 'upsert' at creation will generate the metadata necessary for upsert functionality." + "Upsert functionality requires primary keys to be specified in the data model and manfiest as _id." + "Currently it is required to use -dl/--use_display_label with table upserts." ), }, "validate": { From e7ad5982b32fe1f00d6f5299942c190bd64b5049 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 14:35:28 -0700 Subject: [PATCH 138/615] update in code docs --- schematic/store/synapse.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 1a6e29b84..21d22e7d1 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1630,8 +1630,11 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse - For upsert functionality to work, primary keys must follow the naming convention of _id - + For upsert functionality to work, primary keys must follow the naming convention of _id + `-tm upsert` should be used for initial table uploads if users intend to upsert into them at a later time; using 'upsert' at creation will generate the metadata necessary for upsert functionality. + Currently it is required to use -dl/--use_display_label with table upserts. + + Args: tableToLoad: manifest formatted appropriately for the table tableName: name of the table to be uploaded From 728855ba9c9cb45ebf00ddc2350505f603a743f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Feb 2023 15:01:43 -0700 Subject: [PATCH 139/615] make param optional --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 68da4a206..327cc6ad9 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -317,7 +317,7 @@ paths: schema: type: boolean default: true - required: true + required: false operationId: api.routes.submit_manifest_route responses: "200": From 5a1f92ab20ee23834077188fa199d502da0c256f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 11:14:16 -0700 Subject: [PATCH 140/615] set default value when 'None' passed in --- api/routes.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 19ccbdd07..40f32f2eb 100644 --- a/api/routes.py +++ b/api/routes.py @@ -379,7 +379,12 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None input_token = connexion.request.args["input_token"] - use_schema_label = parse_bool(connexion.request.args["use_schema_label"]) + + use_schema_label = connexion.request.args["use_schema_label"] + if use_schema_label == 'None': + use_schema_label = True + else: + use_schema_label = parse_bool(use_schema_label) if not table_manipulation: table_manipulation = "replace" From b94bfc2eb0ed88274b9ada7c445d70c3f9af50b6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 11:57:31 -0700 Subject: [PATCH 141/615] only test table replacements with `test_submit_manifest` --- tests/test_api.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 5d7573084..ca8f34cd6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -537,9 +537,8 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): assert response_path.endswith(".csv") @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) - @pytest.mark.parametrize("table_manipulation", ["replace", "upsert"]) @pytest.mark.parametrize("use_schema_label", ['true','false']) - def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, table_manipulation, use_schema_label): + def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label): params = { "input_token": syn_token, "schema_url": data_model_jsonld, @@ -548,7 +547,7 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t "manifest_record_type": "table", "asset_view": "syn44259375", "dataset_id": "syn44259313", - "table_manipulation": table_manipulation, + "table_manipulation": 'replace', "use_schema_label": use_schema_label } From 083b190b63228664718f15c597d302208dc1c17b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 11:59:14 -0700 Subject: [PATCH 142/615] add separate test and fixture for upserts --- tests/test_api.py | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index ca8f34cd6..0c9359a05 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -28,7 +28,12 @@ def client(app, config_path): def test_manifest_csv(helpers): test_manifest_path = helpers.get_data_path("mock_manifests/Valid_Test_Manifest.csv") yield test_manifest_path - + +@pytest.fixture(scope="class") +def test_upsert_manifest_csv(helpers): + test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest.csv") + yield test_upsert_manifest_path + @pytest.fixture(scope="class") def test_manifest_json(helpers): test_manifest_path = helpers.get_data_path("mock_manifests/Example.Patient.manifest.json") @@ -565,7 +570,35 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t # test uploading a csv file response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) assert response_csv.status_code == 200 + + @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) + def test_submit_manifest_upsert(self, client, syn_token, data_model_jsonld, json_str, test_upsert_manifest_csv, ): + params = { + "input_token": syn_token, + "schema_url": data_model_jsonld, + "data_type": "MockRDB", + "restrict_rules": False, + "manifest_record_type": "table", + "asset_view": "syn44259375", + "dataset_id": "syn44259313", + "table_manipulation": 'upsert', + "use_schema_label": False + } + if json_str: + params["json_str"] = json_str + response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) + assert response.status_code == 200 + else: + headers = { + 'Content-Type': "multipart/form-data", + 'Accept': "application/json" + } + params["data_type"] = "MockRDB" + + # test uploading a csv file + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_upsert_manifest_csv, 'rb'), "test.csv")}, headers=headers) + assert response_csv.status_code == 200 @pytest.mark.schematic_api class TestSchemaVisualization: From e77123c692f617b137ea3273765b170a38bcbae4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:29:26 -0700 Subject: [PATCH 143/615] remove `LookupError` exception error is already handled and raised where appropriate in `synapse.getDatasetProject` --- schematic/models/commands.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 18a620661..5f9f14cf5 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -154,11 +154,6 @@ def submit_manifest( logger.error( f"Validation errors resulted while validating with '{validate_component}'." ) - except LookupError: - logger.error( - f"'{dataset_id}' could not be found in the asset view (or file view for Synapse user)" - ) - # prototype based on validateModelManifest() @model.command( From f19e357cf7ae33d7461abca28bdb79ae7b29f511 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:33:33 -0700 Subject: [PATCH 144/615] remove `ValueError` catch error is raised in `Metadata.py.submit_metadata_manifest` --- schematic/models/commands.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 5f9f14cf5..6c4499390 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -146,10 +146,6 @@ def submit_manifest( f"File at '{manifest_path}' was successfully associated " f"with dataset '{dataset_id}'." ) - except ValueError: - logger.error( - f"Component '{validate_component}' is not present in '{jsonld}', or is invalid." - ) except ValidationError: logger.error( f"Validation errors resulted while validating with '{validate_component}'." From 6681e1b11254fed281f28d55516aac1c6cd79628 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:36:07 -0700 Subject: [PATCH 145/615] remove `ValidationError` catch Error is raised and handled in `submit_metadata_manifest` --- schematic/models/commands.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 6c4499390..7c03b4023 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -146,10 +146,6 @@ def submit_manifest( f"File at '{manifest_path}' was successfully associated " f"with dataset '{dataset_id}'." ) - except ValidationError: - logger.error( - f"Validation errors resulted while validating with '{validate_component}'." - ) # prototype based on validateModelManifest() @model.command( From 26a97b9c890b9d9f53317080fd5a012c69505f00 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:38:10 -0700 Subject: [PATCH 146/615] remove try catch block and formatting --- schematic/models/commands.py | 56 ++++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 7c03b4023..fa65c1afa 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -117,35 +117,35 @@ def submit_manifest( inputMModelLocation=jsonld, inputMModelLocationType=model_file_type ) - try: - manifest_id = metadata_model.submit_metadata_manifest( - path_to_json_ld = jsonld, - manifest_path=manifest_path, - dataset_id=dataset_id, - validate_component=validate_component, - manifest_record_type=manifest_record_type, - restrict_rules=restrict_rules, - use_schema_label=use_schema_label, - hide_blanks=hide_blanks, - project_scope=project_scope, - table_manipulation=table_manipulation, - ) - ''' - if censored_manifest_id: - logger.info( - f"File at '{manifest_path}' was censored and successfully associated " - f"with dataset '{dataset_id}'. " - f"An uncensored version has also been associated with dataset '{dataset_id}' " - f"and submitted to the Synapse Access Control Team to begin the process " - f"of adding terms of use or review board approval." - ) - ''' - if manifest_id: - logger.info( - f"File at '{manifest_path}' was successfully associated " - f"with dataset '{dataset_id}'." - ) + manifest_id = metadata_model.submit_metadata_manifest( + path_to_json_ld = jsonld, + manifest_path=manifest_path, + dataset_id=dataset_id, + validate_component=validate_component, + manifest_record_type=manifest_record_type, + restrict_rules=restrict_rules, + use_schema_label=use_schema_label, + hide_blanks=hide_blanks, + project_scope=project_scope, + table_manipulation=table_manipulation, + ) + + ''' + if censored_manifest_id: + logger.info( + f"File at '{manifest_path}' was censored and successfully associated " + f"with dataset '{dataset_id}'. " + f"An uncensored version has also been associated with dataset '{dataset_id}' " + f"and submitted to the Synapse Access Control Team to begin the process " + f"of adding terms of use or review board approval." + ) + ''' + if manifest_id: + logger.info( + f"File at '{manifest_path}' was successfully associated " + f"with dataset '{dataset_id}'." + ) # prototype based on validateModelManifest() @model.command( From 5395e6f04d0af791d35c8cdb351f34e00b5889d5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Feb 2023 14:38:47 -0700 Subject: [PATCH 147/615] remove commented out censored manifest message --- schematic/models/commands.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index fa65c1afa..e9e927136 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -130,17 +130,7 @@ def submit_manifest( project_scope=project_scope, table_manipulation=table_manipulation, ) - - ''' - if censored_manifest_id: - logger.info( - f"File at '{manifest_path}' was censored and successfully associated " - f"with dataset '{dataset_id}'. " - f"An uncensored version has also been associated with dataset '{dataset_id}' " - f"and submitted to the Synapse Access Control Team to begin the process " - f"of adding terms of use or review board approval." - ) - ''' + if manifest_id: logger.info( f"File at '{manifest_path}' was successfully associated " From 6703cb6f679ad67981f0d0a1f4351c331c7a02b1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 09:27:34 -0700 Subject: [PATCH 148/615] fix typo --- schematic/models/GE_Helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index d8760eb51..f785bfe06 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -277,7 +277,7 @@ def build_expectation_suite(self,): meta={ "notes": { "format": "markdown", - "content": "Expect column values to be Unique. **Markdown** `Supported`", + "content": "Expect column values to be within a specified range. **Markdown** `Supported`", }, "validation_rule": rule } From ec80f19b7c10cfb6f1eb9c0955731af2d5a4b0ff Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 09:36:56 -0700 Subject: [PATCH 149/615] raise exception if any in GE results --- schematic/models/GE_Helpers.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index f785bfe06..09643e524 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -408,8 +408,11 @@ def generate_errors( rule = result_dict['expectation_config']['meta']['validation_rule'] + if 'exception_info' in result_dict.keys(): + raise Exception(result_dict['exception_info']['exception_traceback']) + #only some expectations explicitly list unexpected values and indices, read or find if not present - if 'unexpected_index_list' in result_dict['result']: + elif 'unexpected_index_list' in result_dict['result']: indices = result_dict['result']['unexpected_index_list'] values = result_dict['result']['unexpected_list'] From 7b9a450350659c929246cb4680807288e03cb4fd Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 10:11:29 -0700 Subject: [PATCH 150/615] change error message level logic order user specifications supersede whether an attribute is required or not --- schematic/models/validate_attribute.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 831cca783..6a0385018 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -510,25 +510,28 @@ def get_message_level( rule_parts = val_rule.split(" ") rule_info = validation_rule_info() - if not sg.is_node_required(node_display_name=attribute_name): + #set message level to default and change after + if rule_parts[0] != 'schema': + level = rule_info[rule_parts[0]]['default_message_level'] + + # Parse rule for level, set to default if not specified + if rule_parts[-1].lower() == 'error' or rule_parts[0] == 'schema': + level = 'error' + return level + elif rule_parts[-1].lower() == 'warning': + level = 'warning' + return level + + elif not sg.is_node_required(node_display_name=attribute_name): # raise warning if recommended but not required if 'recommended' in val_rule: level = 'warning' # If not required or recommended raise warnings to notify else: level = 'warning' - return level elif sg.is_node_required(node_display_name=attribute_name) and 'recommended' in val_rule: level = None - - - # Parse rule for level, set to default if not specified - if rule_parts[-1].lower() == 'error' or rule_parts[0] == 'schema': - level = 'error' - elif rule_parts[-1].lower() == 'warning': - level = 'warning' - else: - level = rule_info[rule_parts[0]]['default_message_level'] + return level From 29299a2be8d8925a18aafba058d365c4dd869503 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 10:12:06 -0700 Subject: [PATCH 151/615] remove logging statement --- tests/test_validation.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 83869418b..0466a79a9 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -65,8 +65,6 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): rootNode=rootNode ) - logging.warning(errors) - #Check errors assert GenerateError.generate_type_error( val_rule = 'num', From 8098a10079317f345fc898c029439b33343e3091 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 10:14:30 -0700 Subject: [PATCH 152/615] change exception raise logic --- schematic/models/GE_Helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 09643e524..bee4042be 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -408,7 +408,7 @@ def generate_errors( rule = result_dict['expectation_config']['meta']['validation_rule'] - if 'exception_info' in result_dict.keys(): + if 'exception_info' in result_dict.keys() and result_dict['exception_info']['exception_message']: raise Exception(result_dict['exception_info']['exception_traceback']) #only some expectations explicitly list unexpected values and indices, read or find if not present From 99a46dd55640947af515fab550cdfefd4c741087 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 10:14:46 -0700 Subject: [PATCH 153/615] allow mixed type comparisons --- schematic/models/GE_Helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index bee4042be..e1b626d28 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -274,6 +274,7 @@ def build_expectation_suite(self,): args["mostly"]=1.0 args["min_value"]=float(rule.split(" ")[1]) args["max_value"]=float(rule.split(" ")[2]) + args['allow_cross_type_comparisons']=True meta={ "notes": { "format": "markdown", From f8348405fceab1d1dfd158cfd5fc95b797354184 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Feb 2023 10:23:48 -0700 Subject: [PATCH 154/615] allow `None` specification for range rule --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index e1b626d28..54f447bb0 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -272,8 +272,8 @@ def build_expectation_suite(self,): elif base_rule==("inRange"): args["mostly"]=1.0 - args["min_value"]=float(rule.split(" ")[1]) - args["max_value"]=float(rule.split(" ")[2]) + args["min_value"]=float(rule.split(" ")[1]) if rule.split(" ")[1] != 'None' else None + args["max_value"]=float(rule.split(" ")[2]) if rule.split(" ")[2] != 'None' else None args['allow_cross_type_comparisons']=True meta={ "notes": { From 9ac233a3e2ef43f59796695ab6c9295946a76c44 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 13 Feb 2023 11:33:00 -0800 Subject: [PATCH 155/615] add changes to allow all classes to a property to be recorded --- schematic/schemas/df_parser.py | 68 +++++++++++++++++++++++----------- schematic/schemas/explorer.py | 46 +++++++++++++---------- 2 files changed, 73 insertions(+), 41 deletions(-) diff --git a/schematic/schemas/df_parser.py b/schematic/schemas/df_parser.py index d4e6c7081..272b528bf 100644 --- a/schematic/schemas/df_parser.py +++ b/schematic/schemas/df_parser.py @@ -49,7 +49,7 @@ def get_class( se: SchemaExplorer, class_display_name: str, description: str = None, - subclass_of: list = None, + subclass_of: list = [], requires_dependencies: list = None, requires_range: list = None, requires_components: list = None, @@ -98,6 +98,7 @@ def get_class( for sub in subclass_of ] } + else: parent = {"rdfs:subClassOf": [{"@id": "schema:Thing"}]} @@ -151,7 +152,7 @@ def get_class( def get_property( se: SchemaExplorer, property_display_name: str, - property_class_name: str, + property_class_names: list, description: str = None, requires_range: list = None, requires_dependencies: list = None, @@ -164,7 +165,7 @@ def get_property( Args: se: a schema explorer object allowing the traversal and modification of a schema graph property_display_name: human readable label for the schema object/attribute: key characteristic X of the assay, related protocol, or downstream data that we want to record as metadata feature - property_class_name: *schema* label of the class/object that this is a property of + property_class_name: *schema* label of the classes/objects that this is a property of description: definition or a reference containing the definition of attribute X. Preferably provide a source ontology link or code in addition to the definition. requires_range: what is the set/domain of values that this attribute can be assigned to; currently only used to specify primitive types. TODO: extend to reg exp patterns requires_dependencies: important characteristics, if any, of property X that need to be recorded as metadata features given property X is specified. These characteristics are attributes themselves and need to pre-exist in the schema as such @@ -174,7 +175,7 @@ def get_property( Returns: a json schema.org property object """ property_name = se.get_property_label_from_display_name(property_display_name) - + property_attributes = { "@id": "bts:" + property_name, "@type": "rdf:Property", @@ -183,11 +184,17 @@ def get_property( else "TBD", "rdfs:label": property_name, "sms:displayName": property_display_name, - "schema:domainIncludes": { - "@id": "bts:" + se.get_class_label_from_display_name(property_class_name) - }, "schema:isPartOf": {"@id": "http://schema.biothings.io"}, } + + domain_includes = { + "schema:domainIncludes": [ + {"@id": "bts:" + se.get_class_label_from_display_name(val)} + for val in property_class_names + ] + } + property_attributes.update(domain_includes) + if requires_range: value_constraint = { "schema:rangeIncludes": [ @@ -266,6 +273,22 @@ def check_schema_definition(schema_definition: pd.DataFrame) -> bool: "'DependsOn Component', respectively. Switch to the new column names." ) +def _prop_2_classes(properties: dict) -> dict: + + """Create a dictionary linking all properties to their classes. + Args: + properties (dict): attributes and their properties (if applicable) + Returns: + Dictionary linking properties to all the classes in their domain. + """ + prop_2_classes = {} + for record in properties: + if not pd.isnull(record["Properties"]): + props = record["Properties"].strip().split(",") + for pr in props: + prop_2_classes.setdefault(pr.strip(),[]).append(record["Attribute"]) + + return prop_2_classes def create_nx_schema_objects( schema_extension: pd.DataFrame, se: SchemaExplorer @@ -310,14 +333,8 @@ def create_nx_schema_objects( # get both attributes and their properties (if any) properties = schema_extension[["Attribute", "Properties"]].to_dict("records") - # property to class map - prop_2_class = {} - for record in properties: - if not pd.isnull(record["Properties"]): - props = record["Properties"].strip().split(",") - for p in props: - prop_2_class[p.strip()] = record["Attribute"] - + prop_2_classes = _prop_2_classes(properties) + logger.debug("Adding attributes") for attribute in attributes: @@ -326,6 +343,7 @@ def create_nx_schema_objects( required = attribute["Required"] if not attribute["Attribute"] in all_properties: + # Attribute is not a property display_name = attribute["Attribute"] subclass_of = None @@ -353,17 +371,19 @@ def create_nx_schema_objects( print("ATTRIBUTE EXISTS") print(new_class) """ - + else: + # Attribute is a property display_name = attribute["Attribute"] new_property = get_property( se, display_name, - prop_2_class[display_name], + prop_2_classes[display_name], description=attribute["Description"], required=required, ) + # check if attribute doesn't already exist and add it if not attribute_exists(se, new_property["rdfs:label"]): se.add_schema_object_nx(new_property, **rel_dict) @@ -454,16 +474,18 @@ def create_nx_schema_objects( parent = attribute["Attribute"] else: # this attribute is a property, set the parent to the domain class of this attribute + parent = se.get_class_by_property(attribute["Attribute"]) + if not parent: raise ValueError( f"Listed valid value: {val}, for attribute: {attribute['Attribute']} " "must have a class parent. The extension could not be added to the schema." ) - new_class = get_class( - se, val, description=None, subclass_of=[parent] + se, val, description=None, subclass_of=parent ) + # check if attribute doesn't already exist and add it if not attribute_exists(se, new_class["rdfs:label"]): se.add_schema_object_nx(new_class, **rel_dict) @@ -477,11 +499,12 @@ def create_nx_schema_objects( class_info["range"].append( se.get_class_label_from_display_name(val) ) + class_range_edit = get_class( se, attribute["Attribute"], description=attribute["Description"], - subclass_of=[attribute["Parent"]], + subclass_of=attribute["Parent"], requires_dependencies=class_info["dependencies"], requires_range=class_info["range"], required=class_info["required"], @@ -497,6 +520,7 @@ def create_nx_schema_objects( property_info["range"].append( se.get_class_label_from_display_name(val) ) + property_range_edit = get_property( se, attribute["Attribute"], @@ -570,8 +594,8 @@ def create_nx_schema_objects( # get dependencies for this attribute, if any are specified requires_dependencies = attribute["DependsOn"] - if not pd.isnull(requires_dependencies): + if not pd.isnull(requires_dependencies): for dep in requires_dependencies.strip().split(","): # check if dependency is a property or not dep = dep.strip() @@ -761,4 +785,4 @@ def _convert_csv_to_data_model( # specs. into a JSON-LD data model base_se = create_nx_schema_objects(rfc_df, base_se) - return base_se + return base_se \ No newline at end of file diff --git a/schematic/schemas/explorer.py b/schematic/schemas/explorer.py index 5c3000166..ad468cdae 100644 --- a/schematic/schemas/explorer.py +++ b/schematic/schemas/explorer.py @@ -234,21 +234,24 @@ def find_class_specific_properties(self, schema_class): properties = [] for record in self.schema["@graph"]: if record["@type"] == "rdf:Property": - if ( - type(record["schema:domainIncludes"]) == dict - and record["schema:domainIncludes"]["@id"] == schema_uri - ): - properties.append(record["rdfs:label"]) - elif ( - type(record["schema:domainIncludes"]) == list - and [ - item - for item in record["schema:domainIncludes"] - if item["@id"] == schema_uri - ] - != [] - ): - properties.append(record["rdfs:label"]) + try: + if ( + type(record["schema:domainIncludes"]) == dict + and record["schema:domainIncludes"]["@id"] == schema_uri + ): + properties.append(record["rdfs:label"]) + elif ( + type(record["schema:domainIncludes"]) == list + and [ + item + for item in record["schema:domainIncludes"] + if item["@id"] == schema_uri + ] + != [] + ): + properties.append(record["rdfs:label"]) + except: + breakpoint() return properties def find_all_class_properties(self, schema_class, display_as_table=False): @@ -502,10 +505,15 @@ def explore_property(self, schema_property): property_info["description"] = record["rdfs:comment"] property_info["uri"] = curie2uri(record["@id"], namespaces) - p_domain = dict2list(record["schema:domainIncludes"]) - property_info["domain"] = unlist( - [self.uri2label(record["@id"]) for record in p_domain] - ) + if "schema:domainIncludes" in record: + p_domain = dict2list(record["schema:domainIncludes"]) + property_info["domain"] = unlist( + [self.uri2label(record["@id"]) for record in p_domain] + ) + breakpoint() + else: + property_info["domain"] = [] + if "schema:rangeIncludes" in record: p_range = dict2list(record["schema:rangeIncludes"]) property_info["range"] = [ From bf6c237e98c762c37c92bac75cf4337ebf59689c Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 13 Feb 2023 11:33:48 -0800 Subject: [PATCH 156/615] Add changes to explorer to allow all classes to be attached to a property --- schematic/schemas/explorer.py | 67 +++++++++++++++++------------------ 1 file changed, 32 insertions(+), 35 deletions(-) diff --git a/schematic/schemas/explorer.py b/schematic/schemas/explorer.py index ad468cdae..95eb0f1de 100644 --- a/schematic/schemas/explorer.py +++ b/schematic/schemas/explorer.py @@ -234,24 +234,22 @@ def find_class_specific_properties(self, schema_class): properties = [] for record in self.schema["@graph"]: if record["@type"] == "rdf:Property": - try: - if ( - type(record["schema:domainIncludes"]) == dict - and record["schema:domainIncludes"]["@id"] == schema_uri - ): - properties.append(record["rdfs:label"]) - elif ( - type(record["schema:domainIncludes"]) == list - and [ - item - for item in record["schema:domainIncludes"] - if item["@id"] == schema_uri - ] - != [] - ): - properties.append(record["rdfs:label"]) - except: - breakpoint() + if ( + type(record["schema:domainIncludes"]) == dict + and record["schema:domainIncludes"]["@id"] == schema_uri + ): + properties.append(record["rdfs:label"]) + elif ( + type(record["schema:domainIncludes"]) == list + and [ + item + for item in record["schema:domainIncludes"] + if item["@id"] == schema_uri + ] + != [] + ): + + properties.append(record["rdfs:label"]) return properties def find_all_class_properties(self, schema_class, display_as_table=False): @@ -480,13 +478,18 @@ def get_class_by_property(self, property_display_name): for record in self.schema["@graph"]: if record["@type"] == "rdf:Property": if record["rdfs:label"] == schema_property: - p_domain = dict2list(record["schema:domainIncludes"]) - return unlist( - [ - self.uri2label(schema_class["@id"]) - for schema_class in p_domain - ] - ) + p_domain = record["schema:domainIncludes"] + + return [ + self.uri2label(record["@id"]) + for record in p_domain + ] + #return unlist( + # [ + # self.uri2label(schema_class["@id"]) + # for schema_class in p_domain + # ] + #) return None @@ -505,15 +508,9 @@ def explore_property(self, schema_property): property_info["description"] = record["rdfs:comment"] property_info["uri"] = curie2uri(record["@id"], namespaces) - if "schema:domainIncludes" in record: - p_domain = dict2list(record["schema:domainIncludes"]) - property_info["domain"] = unlist( - [self.uri2label(record["@id"]) for record in p_domain] - ) - breakpoint() - else: - property_info["domain"] = [] - + p_domain = record["schema:domainIncludes"] + property_info["domain"] = [self.uri2label(record["@id"]) for record in p_domain] + if "schema:rangeIncludes" in record: p_range = dict2list(record["schema:rangeIncludes"]) property_info["range"] = [ @@ -1038,4 +1035,4 @@ def add_schema_object_nx(self, schema_object: dict, **kwargs: dict) -> None: # update the JSON-LD schema after modifying the networkx graph # validate_class_schema(schema_object) self.schema["@graph"].append(schema_object) - # validate_schema(self.schema) + # validate_schema(self.schema) \ No newline at end of file From 4481cd3e2f6f898c72831bb783c6da4b37bae120 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:56:35 -0700 Subject: [PATCH 157/615] add comment --- schematic/models/GE_Helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 54f447bb0..91e7c7b54 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -274,7 +274,7 @@ def build_expectation_suite(self,): args["mostly"]=1.0 args["min_value"]=float(rule.split(" ")[1]) if rule.split(" ")[1] != 'None' else None args["max_value"]=float(rule.split(" ")[2]) if rule.split(" ")[2] != 'None' else None - args['allow_cross_type_comparisons']=True + args['allow_cross_type_comparisons']=True # TODO Should follow up with issue #980 meta={ "notes": { "format": "markdown", From 4f0dfecce654fbe9d36d661a486473e75bbb9db9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:56:57 -0700 Subject: [PATCH 158/615] add comment for `protect_ages` rule --- schematic/models/GE_Helpers.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 91e7c7b54..01954657e 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -252,6 +252,7 @@ def build_expectation_suite(self,): args["mostly"]=1.0 args["min_value"]=min_age args["max_value"]=max_age + #args['allow_cross_type_comparisons']=True # TODO Can allow after issue #980 is completed meta={ "notes": { "format": "markdown", From ff9c332898e28d6d920c3a2d92640d706efe0e2e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Feb 2023 13:57:06 -0700 Subject: [PATCH 159/615] change error raised --- schematic/models/GE_Helpers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 01954657e..ac1d5e8a3 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -21,6 +21,8 @@ from great_expectations.data_context import BaseDataContext from great_expectations.data_context.types.base import DataContextConfig, DatasourceConfig, FilesystemStoreBackendDefaults from great_expectations.data_context.types.resource_identifiers import ExpectationSuiteIdentifier +from great_expectations.exceptions.exceptions import GreatExpectationsError + from schematic.models.validate_attribute import GenerateError from schematic.schemas.generator import SchemaGenerator @@ -411,7 +413,7 @@ def generate_errors( if 'exception_info' in result_dict.keys() and result_dict['exception_info']['exception_message']: - raise Exception(result_dict['exception_info']['exception_traceback']) + raise GreatExpectationsError(result_dict['exception_info']['exception_traceback']) #only some expectations explicitly list unexpected values and indices, read or find if not present elif 'unexpected_index_list' in result_dict['result']: From 826c8cb3d3dade48e386b13025a806f029b838e6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Feb 2023 15:30:24 -0700 Subject: [PATCH 160/615] simplify `get_message_level` --- schematic/models/validate_attribute.py | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 6a0385018..0f133793c 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -517,22 +517,14 @@ def get_message_level( # Parse rule for level, set to default if not specified if rule_parts[-1].lower() == 'error' or rule_parts[0] == 'schema': level = 'error' - return level elif rule_parts[-1].lower() == 'warning': - level = 'warning' - return level - + level = 'warning' elif not sg.is_node_required(node_display_name=attribute_name): - # raise warning if recommended but not required - if 'recommended' in val_rule: - level = 'warning' - # If not required or recommended raise warnings to notify - else: - level = 'warning' + # If not required raise warnings to notify + level = 'warning' elif sg.is_node_required(node_display_name=attribute_name) and 'recommended' in val_rule: level = None - return level class ValidateAttribute(object): From 5a69940e6807de05d57f87358c411d6dc018cb09 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 13 Feb 2023 15:52:19 -0800 Subject: [PATCH 161/615] pass parent as a list to fix error when parsing example model --- schematic/schemas/df_parser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/schemas/df_parser.py b/schematic/schemas/df_parser.py index 272b528bf..e8fa4a5b5 100644 --- a/schematic/schemas/df_parser.py +++ b/schematic/schemas/df_parser.py @@ -504,7 +504,7 @@ def create_nx_schema_objects( se, attribute["Attribute"], description=attribute["Description"], - subclass_of=attribute["Parent"], + subclass_of=[attribute["Parent"]], requires_dependencies=class_info["dependencies"], requires_range=class_info["range"], required=class_info["required"], From 3e5fd566cf501ae93586c51383572f0cc7c0f8fa Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 14 Feb 2023 12:04:16 -0800 Subject: [PATCH 162/615] Allow correct parsing of property domain in the case that its a dictionary and not a list --- schematic/schemas/explorer.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/schematic/schemas/explorer.py b/schematic/schemas/explorer.py index 95eb0f1de..5938520e8 100644 --- a/schematic/schemas/explorer.py +++ b/schematic/schemas/explorer.py @@ -509,8 +509,11 @@ def explore_property(self, schema_property): property_info["uri"] = curie2uri(record["@id"], namespaces) p_domain = record["schema:domainIncludes"] - property_info["domain"] = [self.uri2label(record["@id"]) for record in p_domain] - + if type(p_domain) == list: + property_info["domain"] = [self.uri2label(record["@id"]) for record in p_domain] + elif type(p_domain) == dict: + property_info["domain"] = [self.uri2label(record["@id"])] + if "schema:rangeIncludes" in record: p_range = dict2list(record["schema:rangeIncludes"]) property_info["range"] = [ From 37f338ec9ed8058918a263db326b1962df398e16 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 14 Feb 2023 12:13:17 -0800 Subject: [PATCH 163/615] change df_parser get_property test expectation/actual and name to match updates to df_parser --- tests/test_schemas.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_schemas.py b/tests/test_schemas.py index 3b65f5c81..bf807789e 100644 --- a/tests/test_schemas.py +++ b/tests/test_schemas.py @@ -94,7 +94,7 @@ def test_get_property(self, helpers): actual = df_parser.get_property( se=se_obj, property_display_name="Test", - property_class_name="Prop_Class", + property_class_names=["Prop_Class"], description="This is a dummy test property", requires_range=["Test_Start", "Test_End"], requires_dependencies=["Test_Dep_1", "Test_Dep_2"], @@ -111,7 +111,7 @@ def test_get_property(self, helpers): "schema:rangeIncludes": [{"@id": "bts:TestStart"}, {"@id": "bts:TestEnd"}], "sms:displayName": "Test", "sms:required": "sms:true", - "schema:domainIncludes": {"@id": "bts:PropClass"}, + "schema:domainIncludes": [{"@id": "bts:PropClass"}], "sms:requiresDependency": [ {"@id": "bts:Test_Dep_1"}, {"@id": "bts:Test_Dep_2"}, From 3121d351b8f97e6ee351e491992466933ad0d0d2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Feb 2023 14:40:17 -0700 Subject: [PATCH 164/615] Update poetry.lock --- poetry.lock | 180 +++++++++++++++++++++++++++++----------------------- 1 file changed, 100 insertions(+), 80 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63602e01f..2062d04d5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -94,7 +94,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.14.1" +version = "2.14.2" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false @@ -339,7 +339,7 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "39.0.0" +version = "39.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -349,12 +349,14 @@ python-versions = ">=3.6" cffi = ">=1.12" [package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1,!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "ruff"] +pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] +test-randomorder = ["pytest-randomly"] +tox = ["tox"] [[package]] name = "dateparser" @@ -554,7 +556,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.76.0" +version = "2.78.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -645,7 +647,7 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= [[package]] name = "great-expectations" -version = "0.15.47" +version = "0.15.48" description = "Always know what to expect from your data." category = "main" optional = false @@ -695,7 +697,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.241)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -710,7 +712,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.241)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -787,7 +789,7 @@ python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.21.1" +version = "6.21.2" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -804,7 +806,7 @@ matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" psutil = "*" -pyzmq = ">=17" +pyzmq = ">=20" tornado = ">=6.1" traitlets = ">=5.4.0" @@ -817,7 +819,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.9.0" +version = "8.10.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -838,7 +840,7 @@ stack-data = "*" traitlets = ">=5" [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.20)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] @@ -848,7 +850,7 @@ notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.20)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] [[package]] name = "ipython-genutils" @@ -1222,7 +1224,7 @@ python-versions = ">=3.6" [[package]] name = "mistune" -version = "2.0.4" +version = "2.0.5" description = "A sane Markdown parser with useful plugins and renderers" category = "main" optional = false @@ -1464,7 +1466,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openpyxl" -version = "3.1.0" +version = "3.1.1" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1481,6 +1483,23 @@ category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "pandarallel" +version = "1.6.4" +description = "An easy to use library to speed up computation (by parallelizing on multi CPUs) with pandas." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +dill = ">=0.3.1" +pandas = ">=1" +psutil = "*" + +[package.extras] +dev = ["numpy", "pytest", "pytest-cov"] +doc = ["mkdocs-material"] + [[package]] name = "pandas" version = "1.5.3" @@ -1565,15 +1584,15 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "2.6.2" +version = "3.0.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1733,14 +1752,14 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.16.1" +version = "2.16.2" description = "python code static checker" category = "main" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.14.1,<=2.16.0-dev0" +astroid = ">=2.14.2,<=2.16.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = {version = ">=0.2", markers = "python_version < \"3.11\""} isort = ">=4.2.5,<6" @@ -1861,11 +1880,11 @@ cli = ["click (>=5.0)"] [[package]] name = "python-json-logger" -version = "2.0.4" +version = "2.0.6" description = "A python library adding a json log formatter" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "pytz" @@ -2152,11 +2171,11 @@ python-versions = "*" [[package]] name = "soupsieve" -version = "2.3.2.post1" +version = "2.4" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "sphinx" @@ -2381,7 +2400,7 @@ tests = ["flake8 (>=3.7.0,<4.0)", "pytest (>=5.0.0,<7.0)", "pytest-mock (>=3.0,< [[package]] name = "tenacity" -version = "8.1.0" +version = "8.2.1" description = "Retry code until it succeeds" category = "main" optional = false @@ -2621,7 +2640,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.12.1" +version = "3.13.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -2634,7 +2653,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "ae7079cb736b90a347ca40996b25cd638583d9955e42209e3c67b2bc4b9f1cff" +content-hash = "75f47aa11de5456da3b9a1bf95eb21c66c064d3d6927972cf754f5d26d198fee" [metadata.files] alabaster = [ @@ -2685,8 +2704,8 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.14.1-py3-none-any.whl", hash = "sha256:23c718921acab5f08cbbbe9293967f1f8fec40c336d19cd75dc12a9ea31d2eb2"}, - {file = "astroid-2.14.1.tar.gz", hash = "sha256:bd1aa4f9915c98e8aaebcd4e71930154d4e8c9aaf05d35ac0a63d1956091ae3f"}, + {file = "astroid-2.14.2-py3-none-any.whl", hash = "sha256:0e0e3709d64fbffd3037e4ff403580550f14471fd3eaae9fa11cc9a5c7901153"}, + {file = "astroid-2.14.2.tar.gz", hash = "sha256:a3cf9f02c53dd259144a7e8f3ccd75d67c9a8c716ef183e0c1f291bc5d7bb3cf"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, @@ -2968,29 +2987,29 @@ coverage = [ {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] cryptography = [ - {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, - {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717"}, - {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df"}, - {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1"}, - {file = "cryptography-39.0.0-cp36-abi3-win32.whl", hash = "sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de"}, - {file = "cryptography-39.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39"}, - {file = "cryptography-39.0.0.tar.gz", hash = "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf"}, + {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"}, + {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"}, + {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"}, + {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"}, + {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"}, + {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"}, + {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"}, ] dateparser = [ {file = "dateparser-1.1.7-py2.py3-none-any.whl", hash = "sha256:fbed8b738a24c9cd7f47c4f2089527926566fe539e1a06125eddba75917b1eef"}, @@ -3009,6 +3028,7 @@ debugpy = [ {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, + {file = "debugpy-1.6.6-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:11a0f3a106f69901e4a9a5683ce943a7a5605696024134b522aa1bfda25b5fec"}, {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, @@ -3076,8 +3096,8 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.76.0.tar.gz", hash = "sha256:1446d8c618191afdb1190296a4f9648955460184c655da2bfa40c2968e6caac6"}, - {file = "google_api_python_client-2.76.0-py2.py3-none-any.whl", hash = "sha256:514326068802f8e8b32c282c2c1f528cf007247ba19470de6d013731985a3d28"}, + {file = "google-api-python-client-2.78.0.tar.gz", hash = "sha256:32d56a7522a338e525b9c664773230fc8ce382204d4b690eec67a3f8d55d9d63"}, + {file = "google_api_python_client-2.78.0-py2.py3-none-any.whl", hash = "sha256:34a7b73048d7573e99130ebba0a390929382690adccf605b188e74585fc94ea6"}, ] google-auth = [ {file = "google-auth-2.16.0.tar.gz", hash = "sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd"}, @@ -3100,8 +3120,8 @@ graphviz = [ {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ - {file = "great_expectations-0.15.47-py3-none-any.whl", hash = "sha256:82bbd508ce77d2dec5989b1b8746539212915343cce69dcdd9b134a35ed62f31"}, - {file = "great_expectations-0.15.47.tar.gz", hash = "sha256:efd7d312d427b9dbb257a042a841076ae962232a649002386bd9408c8a05f30a"}, + {file = "great_expectations-0.15.48-py3-none-any.whl", hash = "sha256:67a8a00ad1b18f3204866a0a836100f00164c0ccfafa08b355b614a64060e264"}, + {file = "great_expectations-0.15.48.tar.gz", hash = "sha256:d14245b707870519587778e53a7b450e837138c1713c406077bede40074f52bb"}, ] greenlet = [ {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, @@ -3190,12 +3210,12 @@ iniconfig = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.21.1-py3-none-any.whl", hash = "sha256:1a04bb359212e23e46adc0116ec82ea128c1e5bd532fde4fbe679787ff36f0cf"}, - {file = "ipykernel-6.21.1.tar.gz", hash = "sha256:a0f8eece39cab1ee352c9b59ec67bbe44d8299f8238e4c16ff7f4cf0052d3378"}, + {file = "ipykernel-6.21.2-py3-none-any.whl", hash = "sha256:430d00549b6aaf49bd0f5393150691edb1815afa62d457ee6b1a66b25cb17874"}, + {file = "ipykernel-6.21.2.tar.gz", hash = "sha256:6e9213484e4ce1fb14267ee435e18f23cc3a0634e635b9fb4ed4677b84e0fdf8"}, ] ipython = [ - {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, - {file = "ipython-8.9.0.tar.gz", hash = "sha256:71618e82e6d59487bea059626e7c79fb4a5b760d1510d02fab1160db6fdfa1f7"}, + {file = "ipython-8.10.0-py3-none-any.whl", hash = "sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345"}, + {file = "ipython-8.10.0.tar.gz", hash = "sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -3378,8 +3398,8 @@ mccabe = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mistune = [ - {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, - {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, + {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, + {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, ] mypy = [ {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, @@ -3482,13 +3502,16 @@ oauthlib = [ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, ] openpyxl = [ - {file = "openpyxl-3.1.0-py2.py3-none-any.whl", hash = "sha256:24d7d361025d186ba91eff58135d50855cf035a84371b891e58fb6eb5125660f"}, - {file = "openpyxl-3.1.0.tar.gz", hash = "sha256:eccedbe1cdd8b2494057e73959b496821141038dbb7eb9266ea59e3f34208231"}, + {file = "openpyxl-3.1.1-py2.py3-none-any.whl", hash = "sha256:a0266e033e65f33ee697254b66116a5793c15fc92daf64711080000df4cfe0a8"}, + {file = "openpyxl-3.1.1.tar.gz", hash = "sha256:f06d44e2c973781068bce5ecf860a09bcdb1c7f5ce1facd5e9aa82c92c93ae72"}, ] packaging = [ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, ] +pandarallel = [ + {file = "pandarallel-1.6.4.tar.gz", hash = "sha256:70091652485050241ffac37c3e94d21732697c63ee4613ae7bf85da076be41f2"}, +] pandas = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:972d8a45395f2a2d26733eb8d0f629b2f90bebe8e8eddbb8829b180c09639572"}, @@ -3543,8 +3566,8 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"}, + {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -3570,9 +3593,7 @@ protobuf = [ {file = "protobuf-4.21.12-cp38-cp38-win_amd64.whl", hash = "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30"}, {file = "protobuf-4.21.12-cp39-cp39-win32.whl", hash = "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc"}, {file = "protobuf-4.21.12-cp39-cp39-win_amd64.whl", hash = "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b"}, - {file = "protobuf-4.21.12-py2.py3-none-any.whl", hash = "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5"}, {file = "protobuf-4.21.12-py3-none-any.whl", hash = "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462"}, - {file = "protobuf-4.21.12.tar.gz", hash = "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab"}, ] psutil = [ {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, @@ -3665,8 +3686,8 @@ pygsheets = [ {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.16.1-py3-none-any.whl", hash = "sha256:bad9d7c36037f6043a1e848a43004dfd5ea5ceb05815d713ba56ca4503a9fe37"}, - {file = "pylint-2.16.1.tar.gz", hash = "sha256:ffe7fa536bb38ba35006a7c8a6d2efbfdd3d95bbf21199cad31f76b1c50aaf30"}, + {file = "pylint-2.16.2-py3-none-any.whl", hash = "sha256:ff22dde9c2128cd257c145cfd51adeff0be7df4d80d669055f24a962b351bbe4"}, + {file = "pylint-2.16.2.tar.gz", hash = "sha256:13b2c805a404a9bf57d002cd5f054ca4d40b0b87542bdaba5e05321ae8262c84"}, ] pyopenssl = [ {file = "pyOpenSSL-23.0.0-py3-none-any.whl", hash = "sha256:df5fc28af899e74e19fccb5510df423581047e10ab6f1f4ba1763ff5fde844c0"}, @@ -3726,8 +3747,8 @@ python-dotenv = [ {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, ] python-json-logger = [ - {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, - {file = "python_json_logger-2.0.4-py3-none-any.whl", hash = "sha256:3b03487b14eb9e4f77e4fc2a023358b5394b82fd89cecf5586259baed57d8c6f"}, + {file = "python-json-logger-2.0.6.tar.gz", hash = "sha256:ed33182c2b438a366775c25c1219ebbd5bd7f71694c644d6b3b3861e19565ae3"}, + {file = "python_json_logger-2.0.6-py3-none-any.whl", hash = "sha256:3af8e5b907b4a5b53cae249205ee3a3d3472bd7ad9ddfaec136eec2f2faf4995"}, ] pytz = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, @@ -4013,7 +4034,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, @@ -4092,8 +4112,8 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] soupsieve = [ - {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, - {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, + {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, + {file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"}, ] sphinx = [ {file = "Sphinx-6.1.3.tar.gz", hash = "sha256:0dac3b698538ffef41716cf97ba26c1c7788dba73ce6f150c1ff5b4720786dd2"}, @@ -4187,8 +4207,8 @@ synapseclient = [ {file = "synapseclient-2.7.0.tar.gz", hash = "sha256:241f170f0e8c8c3735cd73f81711e592a581c55f7a5c4566be7bee82d72a56bc"}, ] tenacity = [ - {file = "tenacity-8.1.0-py3-none-any.whl", hash = "sha256:35525cd47f82830069f0d6b73f7eb83bc5b73ee2fff0437952cedf98b27653ac"}, - {file = "tenacity-8.1.0.tar.gz", hash = "sha256:e48c437fdf9340f5666b92cd7990e96bc5fc955e1298baf4a907e3972067a445"}, + {file = "tenacity-8.2.1-py3-none-any.whl", hash = "sha256:dd1b769ca7002fda992322939feca5bee4fa11f39146b0af14e0b8d9f27ea854"}, + {file = "tenacity-8.2.1.tar.gz", hash = "sha256:c7bb4b86425b977726a7b49971542d4f67baf72096597d283f3ffd01f33b92df"}, ] terminado = [ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, @@ -4350,6 +4370,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"}, - {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"}, + {file = "zipp-3.13.0-py3-none-any.whl", hash = "sha256:e8b2a36ea17df80ffe9e2c4fda3f693c3dad6df1697d3cd3af232db680950b0b"}, + {file = "zipp-3.13.0.tar.gz", hash = "sha256:23f70e964bc11a34cef175bc90ba2914e1e4545ea1e3e2f67c079671883f9cb6"}, ] From cfb4ccdeb64ac716a45107ba236a1e1ed105c1ee Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Feb 2023 15:27:02 -0700 Subject: [PATCH 165/615] store checkpoint name --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index d8760eb51..585db969c 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -342,9 +342,9 @@ def build_checkpoint(self): adds checkpoint to self """ #create manifest checkpoint - checkpoint_name = "manifest_checkpoint" + self.checkpoint_name = "manifest_checkpoint" checkpoint_config={ - "name": checkpoint_name, + "name": self.checkpoint_name, "config_version": 1, "class_name": "SimpleCheckpoint", "validations": [ From ede61d632379612cf73816dc8eb6b9366199ffc7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Feb 2023 15:27:20 -0700 Subject: [PATCH 166/615] use stored checkpoint name --- schematic/models/validate_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index c79931b7a..2f6ba33aa 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -139,7 +139,7 @@ def validate_manifest_rules( #run GE validation results = ge_helpers.context.run_checkpoint( - checkpoint_name="manifest_checkpoint", + checkpoint_name=ge_helpers.checkpoint_name, batch_request={ "runtime_parameters": {"batch_data": manifest}, "batch_identifiers": { From f988aaaff583ff6e655e591b1e14875b6a530147 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Feb 2023 15:27:44 -0700 Subject: [PATCH 167/615] delete checkpoint after GE validation --- schematic/models/validate_manifest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 2f6ba33aa..52e1abad6 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -147,7 +147,9 @@ def validate_manifest_rules( }, }, result_format={'result_format': 'COMPLETE'}, - ) + ) + + ge_helpers.context.delete_checkpoint(ge_helpers.checkpoint_name) #print(results) #results.list_validation_results() From 3234bb99dae3fd77b311f2b01373e1d23a68e4f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Feb 2023 15:28:06 -0700 Subject: [PATCH 168/615] remove comments --- schematic/models/validate_manifest.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 52e1abad6..b08f4c196 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -151,8 +151,6 @@ def validate_manifest_rules( ge_helpers.context.delete_checkpoint(ge_helpers.checkpoint_name) - #print(results) - #results.list_validation_results() validation_results = results.list_validation_results() From c772f1d368c3c4adf3a78b38907abaedddd217f5 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 14 Feb 2023 14:46:39 -0800 Subject: [PATCH 169/615] add updated example.model.jsonld that matches new formatting expectations for domainIncludes --- tests/data/example.model.jsonld | 540 ++++++++++++++++++++++++++++++-- 1 file changed, 520 insertions(+), 20 deletions(-) diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index d3e3bb04c..39de0d418 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2893,7 +2893,9 @@ }, "sms:displayName": "Check Date", "sms:required": "sms:true", - "sms:validationRules": ["date"] + "sms:validationRules": [ + "date" + ] }, { "@id": "bts:MockRDB", @@ -2963,7 +2965,13 @@ "rdfs:label": "Female", "rdfs:subClassOf": [ { - "@id": "bts:Sex" + "@id": "bts:S" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:X" } ], "schema:isPartOf": { @@ -2980,7 +2988,13 @@ "rdfs:label": "Male", "rdfs:subClassOf": [ { - "@id": "bts:Sex" + "@id": "bts:S" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:X" } ], "schema:isPartOf": { @@ -2997,7 +3011,13 @@ "rdfs:label": "Other", "rdfs:subClassOf": [ { - "@id": "bts:Sex" + "@id": "bts:S" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:X" } ], "schema:isPartOf": { @@ -3014,7 +3034,31 @@ "rdfs:label": "Healthy", "rdfs:subClassOf": [ { - "@id": "bts:Diagnosis" + "@id": "bts:D" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:G" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" } ], "schema:isPartOf": { @@ -3031,7 +3075,37 @@ "rdfs:label": "Breast", "rdfs:subClassOf": [ { - "@id": "bts:CancerType" + "@id": "bts:C" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:Y" + }, + { + "@id": "bts:P" + }, + { + "@id": "bts:E" } ], "schema:isPartOf": { @@ -3048,7 +3122,37 @@ "rdfs:label": "Colorectal", "rdfs:subClassOf": [ { - "@id": "bts:CancerType" + "@id": "bts:C" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:Y" + }, + { + "@id": "bts:P" + }, + { + "@id": "bts:E" } ], "schema:isPartOf": { @@ -3065,7 +3169,37 @@ "rdfs:label": "Lung", "rdfs:subClassOf": [ { - "@id": "bts:CancerType" + "@id": "bts:C" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:Y" + }, + { + "@id": "bts:P" + }, + { + "@id": "bts:E" } ], "schema:isPartOf": { @@ -3082,7 +3216,37 @@ "rdfs:label": "Prostate", "rdfs:subClassOf": [ { - "@id": "bts:CancerType" + "@id": "bts:C" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:Y" + }, + { + "@id": "bts:P" + }, + { + "@id": "bts:E" } ], "schema:isPartOf": { @@ -3099,7 +3263,37 @@ "rdfs:label": "Skin", "rdfs:subClassOf": [ { - "@id": "bts:CancerType" + "@id": "bts:C" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:Y" + }, + { + "@id": "bts:P" + }, + { + "@id": "bts:E" } ], "schema:isPartOf": { @@ -3116,7 +3310,43 @@ "rdfs:label": "Malignant", "rdfs:subClassOf": [ { - "@id": "bts:TissueStatus" + "@id": "bts:T" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:T" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:S" } ], "schema:isPartOf": { @@ -3133,7 +3363,37 @@ "rdfs:label": "FASTQ", "rdfs:subClassOf": [ { - "@id": "bts:FileFormat" + "@id": "bts:F" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:F" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:R" + }, + { + "@id": "bts:M" + }, + { + "@id": "bts:A" + }, + { + "@id": "bts:T" } ], "schema:isPartOf": { @@ -3150,7 +3410,40 @@ "rdfs:label": "GRCh37", "rdfs:subClassOf": [ { - "@id": "bts:GenomeBuild" + "@id": "bts:G" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:M" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:B" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:D" } ], "schema:isPartOf": { @@ -3167,7 +3460,40 @@ "rdfs:label": "GRCh38", "rdfs:subClassOf": [ { - "@id": "bts:GenomeBuild" + "@id": "bts:G" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:M" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:B" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:D" } ], "schema:isPartOf": { @@ -3184,7 +3510,40 @@ "rdfs:label": "GRCm38", "rdfs:subClassOf": [ { - "@id": "bts:GenomeBuild" + "@id": "bts:G" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:M" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:B" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:D" } ], "schema:isPartOf": { @@ -3201,7 +3560,40 @@ "rdfs:label": "GRCm39", "rdfs:subClassOf": [ { - "@id": "bts:GenomeBuild" + "@id": "bts:G" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:N" + }, + { + "@id": "bts:O" + }, + { + "@id": "bts:M" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:B" + }, + { + "@id": "bts:U" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:D" } ], "schema:isPartOf": { @@ -3218,7 +3610,34 @@ "rdfs:label": "Ab", "rdfs:subClassOf": [ { - "@id": "bts:CheckList" + "@id": "bts:C" + }, + { + "@id": "bts:H" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:K" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:T" } ], "schema:isPartOf": { @@ -3235,7 +3654,34 @@ "rdfs:label": "Cd", "rdfs:subClassOf": [ { - "@id": "bts:CheckList" + "@id": "bts:C" + }, + { + "@id": "bts:H" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:K" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:T" } ], "schema:isPartOf": { @@ -3252,7 +3698,34 @@ "rdfs:label": "Ef", "rdfs:subClassOf": [ { - "@id": "bts:CheckList" + "@id": "bts:C" + }, + { + "@id": "bts:H" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:K" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:T" } ], "schema:isPartOf": { @@ -3269,7 +3742,34 @@ "rdfs:label": "Gh", "rdfs:subClassOf": [ { - "@id": "bts:CheckList" + "@id": "bts:C" + }, + { + "@id": "bts:H" + }, + { + "@id": "bts:E" + }, + { + "@id": "bts:C" + }, + { + "@id": "bts:K" + }, + { + "@id": "bts:" + }, + { + "@id": "bts:L" + }, + { + "@id": "bts:I" + }, + { + "@id": "bts:S" + }, + { + "@id": "bts:T" } ], "schema:isPartOf": { From 2b0e31b17eeb9e9a7777c4e11d01b044e52a6e70 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 15 Feb 2023 10:41:43 -0800 Subject: [PATCH 170/615] make sure get_class subclass_of is submitted as a list --- schematic/schemas/df_parser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/schemas/df_parser.py b/schematic/schemas/df_parser.py index e8fa4a5b5..c107e1bbb 100644 --- a/schematic/schemas/df_parser.py +++ b/schematic/schemas/df_parser.py @@ -98,7 +98,6 @@ def get_class( for sub in subclass_of ] } - else: parent = {"rdfs:subClassOf": [{"@id": "schema:Thing"}]} @@ -483,7 +482,7 @@ def create_nx_schema_objects( "must have a class parent. The extension could not be added to the schema." ) new_class = get_class( - se, val, description=None, subclass_of=parent + se, val, description=None, subclass_of=[parent] ) # check if attribute doesn't already exist and add it From 8e38f7e79fc50cc73aff4afbdead2ef68d4de901 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 15 Feb 2023 10:44:52 -0800 Subject: [PATCH 171/615] update example.model.jsonld after latest fix --- tests/data/example.model.jsonld | 536 ++------------------------------ 1 file changed, 19 insertions(+), 517 deletions(-) diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index 39de0d418..77e138f29 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2965,13 +2965,7 @@ "rdfs:label": "Female", "rdfs:subClassOf": [ { - "@id": "bts:S" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:X" + "@id": "bts:Sex" } ], "schema:isPartOf": { @@ -2988,13 +2982,7 @@ "rdfs:label": "Male", "rdfs:subClassOf": [ { - "@id": "bts:S" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:X" + "@id": "bts:Sex" } ], "schema:isPartOf": { @@ -3011,13 +2999,7 @@ "rdfs:label": "Other", "rdfs:subClassOf": [ { - "@id": "bts:S" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:X" + "@id": "bts:Sex" } ], "schema:isPartOf": { @@ -3034,31 +3016,7 @@ "rdfs:label": "Healthy", "rdfs:subClassOf": [ { - "@id": "bts:D" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:G" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" + "@id": "bts:Diagnosis" } ], "schema:isPartOf": { @@ -3075,37 +3033,7 @@ "rdfs:label": "Breast", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:Y" - }, - { - "@id": "bts:P" - }, - { - "@id": "bts:E" + "@id": "bts:CancerType" } ], "schema:isPartOf": { @@ -3122,37 +3050,7 @@ "rdfs:label": "Colorectal", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:Y" - }, - { - "@id": "bts:P" - }, - { - "@id": "bts:E" + "@id": "bts:CancerType" } ], "schema:isPartOf": { @@ -3169,37 +3067,7 @@ "rdfs:label": "Lung", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:Y" - }, - { - "@id": "bts:P" - }, - { - "@id": "bts:E" + "@id": "bts:CancerType" } ], "schema:isPartOf": { @@ -3216,37 +3084,7 @@ "rdfs:label": "Prostate", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:Y" - }, - { - "@id": "bts:P" - }, - { - "@id": "bts:E" + "@id": "bts:CancerType" } ], "schema:isPartOf": { @@ -3263,37 +3101,7 @@ "rdfs:label": "Skin", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:Y" - }, - { - "@id": "bts:P" - }, - { - "@id": "bts:E" + "@id": "bts:CancerType" } ], "schema:isPartOf": { @@ -3310,43 +3118,7 @@ "rdfs:label": "Malignant", "rdfs:subClassOf": [ { - "@id": "bts:T" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:T" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:S" + "@id": "bts:TissueStatus" } ], "schema:isPartOf": { @@ -3363,37 +3135,7 @@ "rdfs:label": "FASTQ", "rdfs:subClassOf": [ { - "@id": "bts:F" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:F" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:R" - }, - { - "@id": "bts:M" - }, - { - "@id": "bts:A" - }, - { - "@id": "bts:T" + "@id": "bts:FileFormat" } ], "schema:isPartOf": { @@ -3410,40 +3152,7 @@ "rdfs:label": "GRCh37", "rdfs:subClassOf": [ { - "@id": "bts:G" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:M" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:B" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:D" + "@id": "bts:GenomeBuild" } ], "schema:isPartOf": { @@ -3460,40 +3169,7 @@ "rdfs:label": "GRCh38", "rdfs:subClassOf": [ { - "@id": "bts:G" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:M" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:B" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:D" + "@id": "bts:GenomeBuild" } ], "schema:isPartOf": { @@ -3510,40 +3186,7 @@ "rdfs:label": "GRCm38", "rdfs:subClassOf": [ { - "@id": "bts:G" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:M" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:B" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:D" + "@id": "bts:GenomeBuild" } ], "schema:isPartOf": { @@ -3560,40 +3203,7 @@ "rdfs:label": "GRCm39", "rdfs:subClassOf": [ { - "@id": "bts:G" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:N" - }, - { - "@id": "bts:O" - }, - { - "@id": "bts:M" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:B" - }, - { - "@id": "bts:U" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:D" + "@id": "bts:GenomeBuild" } ], "schema:isPartOf": { @@ -3610,34 +3220,7 @@ "rdfs:label": "Ab", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:H" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:K" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:T" + "@id": "bts:CheckList" } ], "schema:isPartOf": { @@ -3654,34 +3237,7 @@ "rdfs:label": "Cd", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:H" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:K" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:T" + "@id": "bts:CheckList" } ], "schema:isPartOf": { @@ -3698,34 +3254,7 @@ "rdfs:label": "Ef", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:H" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:K" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:T" + "@id": "bts:CheckList" } ], "schema:isPartOf": { @@ -3742,34 +3271,7 @@ "rdfs:label": "Gh", "rdfs:subClassOf": [ { - "@id": "bts:C" - }, - { - "@id": "bts:H" - }, - { - "@id": "bts:E" - }, - { - "@id": "bts:C" - }, - { - "@id": "bts:K" - }, - { - "@id": "bts:" - }, - { - "@id": "bts:L" - }, - { - "@id": "bts:I" - }, - { - "@id": "bts:S" - }, - { - "@id": "bts:T" + "@id": "bts:CheckList" } ], "schema:isPartOf": { From c493700f9c9d055b9c0377bbc63b1041ecf18e2f Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 15 Feb 2023 11:06:19 -0800 Subject: [PATCH 172/615] save attribute parent as list, and submit sublcass of as is, without conversion --- schematic/schemas/df_parser.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/schemas/df_parser.py b/schematic/schemas/df_parser.py index c107e1bbb..a2eaceb36 100644 --- a/schematic/schemas/df_parser.py +++ b/schematic/schemas/df_parser.py @@ -470,7 +470,7 @@ def create_nx_schema_objects( # determine parent class of the new value class # if this attribute is not a property, set it as a parent class if not attribute["Attribute"] in all_properties: - parent = attribute["Attribute"] + parent = [attribute["Attribute"]] else: # this attribute is a property, set the parent to the domain class of this attribute @@ -482,7 +482,7 @@ def create_nx_schema_objects( "must have a class parent. The extension could not be added to the schema." ) new_class = get_class( - se, val, description=None, subclass_of=[parent] + se, val, description=None, subclass_of=parent ) # check if attribute doesn't already exist and add it From ee9108c70c31661a684c2e9bdcf3b2f2d6547e76 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:57:04 -0700 Subject: [PATCH 173/615] update allowable python versions in readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index b3fccd45e..2f2c00b4a 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ SCHEMATIC is an acronym for _Schema Engine for Manifest Ingress and Curation_. T # Installation ## Installation Requirements -* Python 3.7.1 or higher +* Python version 3.9.0≤x<3.11.0 Note: You need to be a registered and certified user on [`synapse.org`](https://www.synapse.org/), and also have the right permissions to download the Google credentials files from Synapse. From 677f6c28417970eed02b1a79be20b1bb337ca206 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Feb 2023 13:58:39 -0700 Subject: [PATCH 174/615] update api package versions --- api/README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/api/README.md b/api/README.md index 1dbf7ff46..a6e352ff3 100644 --- a/api/README.md +++ b/api/README.md @@ -35,9 +35,9 @@ http://localhost:3001/v1/ui/ To resolve: Make sure that the following libraries have the correct version: -* itsdangerous version: 1.1.0 -* jinja2 version: 2.11.3 -* markupsafe version: 2.0.1 +* itsdangerous version: ^2.0.0 +* jinja2 version: >2.11.3 +* markupsafe version: ^2.1.0 ## Notes for using schematic features and API endpoints utilizing Google Services (e.g. manifest generation): Before trying out the API endpoints, please make sure that you have obtained `credentials.json`, `schematic_service_account_creds.json`, and `token.pickle`. (Instructions can be found in schematic/README.md) @@ -75,4 +75,4 @@ Note: if the dataset_id you provided is invalid, it will generate an empty manif For the patient manifest, "Family History" column only accepts a list. The details of the validation rules (based on the example data model) could be found [here](https://github.com/Sage-Bionetworks/schematic/blob/develop/tests/data/example.model.csv) -After execution, you should be able to see your manifest.csv get uploaded to your test folder on Synapse. The execution should return the synapse ID of your submitted manifest. \ No newline at end of file +After execution, you should be able to see your manifest.csv get uploaded to your test folder on Synapse. The execution should return the synapse ID of your submitted manifest. From d116461cf54ed8c49f533c2672d28f625177cb50 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Feb 2023 14:01:17 -0700 Subject: [PATCH 175/615] update current authors --- pyproject.toml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2bf75490c..23e95127c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,10 +4,11 @@ version = "22.3.2" description = "Package for biomedical data model and metadata ingress management" authors = [ "Milen Nikolov ", - "Sujay Patil ", + "Lingling Peng ", + "Mialy Defelice ", + "Gianna Jordan ", "Bruno Grande ", "Robert Allaway ", - "Xengie Doan ", ] readme = "README.md" From a990b1fe4de69767727521045f868d09bef1746a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 16 Feb 2023 09:29:55 -0700 Subject: [PATCH 176/615] make none spec case insensitive --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index ac1d5e8a3..22e6507c9 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -275,8 +275,8 @@ def build_expectation_suite(self,): elif base_rule==("inRange"): args["mostly"]=1.0 - args["min_value"]=float(rule.split(" ")[1]) if rule.split(" ")[1] != 'None' else None - args["max_value"]=float(rule.split(" ")[2]) if rule.split(" ")[2] != 'None' else None + args["min_value"]=float(rule.split(" ")[1]) if rule.split(" ")[1].lower() != 'none' else None + args["max_value"]=float(rule.split(" ")[2]) if rule.split(" ")[2].lower() != 'none' else None args['allow_cross_type_comparisons']=True # TODO Should follow up with issue #980 meta={ "notes": { From 0d14f327b02a821a910c6621a321c09d9fdef207 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 12:39:13 -0500 Subject: [PATCH 177/615] add uwsgi and modify file location --- docker-compose.yml | 45 +++++--- poetry.lock | 112 +++++++++++++------- pyproject.toml | 1 + run_api.py | 4 +- schematic_api/Dockerfile | 72 +++++++++++++ {api => schematic_api/api}/README.md | 0 {api => schematic_api/api}/__init__.py | 10 +- schematic_api/api/__main__.py | 19 ++++ {api => schematic_api/api}/openapi/api.yaml | 48 ++++----- {api => schematic_api/api}/routes.py | 0 schematic_api/docker-entrypoint.sh | 9 ++ uwsgi.ini | 21 ++++ 12 files changed, 258 insertions(+), 83 deletions(-) create mode 100644 schematic_api/Dockerfile rename {api => schematic_api/api}/README.md (100%) rename {api => schematic_api/api}/__init__.py (86%) create mode 100644 schematic_api/api/__main__.py rename {api => schematic_api/api}/openapi/api.yaml (95%) rename {api => schematic_api/api}/routes.py (100%) create mode 100644 schematic_api/docker-entrypoint.sh create mode 100644 uwsgi.ini diff --git a/docker-compose.yml b/docker-compose.yml index f6e15a901..49ee2b225 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,17 +1,34 @@ version: "3.9" services: - schematic: - build: . - container_name: schematic - entrypoint: python /usr/src/app/run_api.py + # schematic: + # build: + # dockerfile: Dockerfile + # container_name: schematic + # entrypoint: python /usr/src/app/run_api.py + # ports: + # - "3001:3001" + # volumes: + # - .:/schematic + # working_dir: /schematic + # environment: + # APP_HOST: "0.0.0.0" + # APP_PORT: "3001" + # SCHEMATIC_CONFIG: /schematic/config.yml + # SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" + # GE_HOME: /usr/src/app/great_expectations/ + schematic-aws: + build: + context: ../schematic + dockerfile: schematic_api/Dockerfile + container_name: schematic-api-aws + image: sagebionetworks/schematic-aws-api:latest + restart: always + env_file: + - .env + networks: + - schematic ports: - - "3001:3001" - volumes: - - .:/schematic - working_dir: /schematic - environment: - APP_HOST: "0.0.0.0" - APP_PORT: "3001" - SCHEMATIC_CONFIG: /schematic/config.yml - SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" - GE_HOME: /usr/src/app/great_expectations/ + - "${SERVER_PORT}:7080" +networks: + schematic: + name: schematic \ No newline at end of file diff --git a/poetry.lock b/poetry.lock index 63602e01f..a37b321a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -128,11 +128,12 @@ optional = false python-versions = ">=3.6" [package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] +cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] +tests_no_zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] [[package]] name = "babel" @@ -411,7 +412,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "dill" @@ -583,7 +584,7 @@ six = ">=1.9.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] -enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +enterprise_cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0dev)"] @@ -691,9 +692,9 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] arrow = ["feather-format (>=0.4.1)", "pyarrow"] athena = ["pyathena (>=1.11)", "sqlalchemy (>=1.3.18,<2.0.0)"] -aws-secrets = ["boto3 (==1.17.106)"] +aws_secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] -azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] +azure_secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] @@ -723,7 +724,7 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] -docs = ["Sphinx", "docutils (<0.18)"] +docs = ["docutils (<0.18)", "sphinx"] test = ["objgraph", "psutil"] [[package]] @@ -767,7 +768,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flake8 (<5)", "flufl-flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "inflection" @@ -809,7 +810,7 @@ tornado = ">=6.1" traitlets = ">=5.4.0" [package.extras] -cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +cov = ["coverage", "curio", "matplotlib", "pytest-cov", "trio"] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] pyqt5 = ["pyqt5"] pyside6 = ["pyside6"] @@ -848,7 +849,7 @@ notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.20)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test_extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.20)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] [[package]] name = "ipython-genutils" @@ -946,7 +947,7 @@ python-versions = ">=3.7" [package.extras] test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async_generator", "trio"] +trio = ["async-generator", "trio"] [[package]] name = "jinja2" @@ -1158,7 +1159,7 @@ six = "*" [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] +testing = ["backports-unittest-mock", "collective-checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] [[package]] name = "lazy-object-proxy" @@ -1302,7 +1303,7 @@ traitlets = ">=5.3" [package.extras] dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient", "sphinx (>=1.7)", "sphinx-book-theme"] test = ["ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] @@ -1332,9 +1333,9 @@ tinycss2 = "*" traitlets = ">=5.0" [package.extras] -all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] +all = ["nbconvert"] docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert[qtpng]"] +qtpdf = ["nbconvert"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] @@ -1974,7 +1975,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-oauthlib" @@ -2084,7 +2085,7 @@ python-versions = "<3.12,>=3.8" numpy = ">=1.19.5,<1.27.0" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing-extensions"] doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] @@ -2109,8 +2110,8 @@ optional = false python-versions = "*" [package.extras] -nativelib = ["pyobjc-framework-Cocoa", "pywin32"] -objc = ["pyobjc-framework-Cocoa"] +nativelib = ["pyobjc-framework-cocoa", "pywin32"] +objc = ["pyobjc-framework-cocoa"] win32 = ["pywin32"] [[package]] @@ -2123,8 +2124,8 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -2290,21 +2291,21 @@ aiomysql = ["aiomysql", "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)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] +mariadb_connector = ["mariadb (>=1.0.1,!=1.1.2)"] mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] +mssql_pymssql = ["pymssql"] +mssql_pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] -mysql-connector = ["mysql-connector-python"] +mysql_connector = ["mysql-connector-python"] oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] -postgresql-psycopg2binary = ["psycopg2-binary"] -postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql_asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] +postgresql_psycopg2binary = ["psycopg2-binary"] +postgresql_psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql", "pymysql (<1)"] -sqlcipher = ["sqlcipher3_binary"] +sqlcipher = ["sqlcipher3-binary"] [[package]] name = "sqlalchemy-utils" @@ -2326,8 +2327,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports-zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test_all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports-zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -2419,7 +2420,7 @@ python-versions = ">=3.7" webencodings = ">=0.4" [package.extras] -doc = ["sphinx", "sphinx_rtd_theme"] +doc = ["sphinx", "sphinx-rtd-theme"] test = ["flake8", "isort", "pytest"] [[package]] @@ -2520,7 +2521,7 @@ pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] +devenv = ["black", "pyroma", "pytest-cov", "zest-releaser"] test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] [[package]] @@ -2555,6 +2556,14 @@ brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)", "brotlipy (>=0.6.0)"] secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "pyOpenSSL (>=0.14)", "urllib3-secure-extra"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] +[[package]] +name = "uwsgi" +version = "2.0.21" +description = "The uWSGI server" +category = "main" +optional = false +python-versions = "*" + [[package]] name = "wcwidth" version = "0.2.6" @@ -2629,12 +2638,12 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco-functools", "jaraco-itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "ae7079cb736b90a347ca40996b25cd638583d9955e42209e3c67b2bc4b9f1cff" +content-hash = "872d97349a189c1806c885328a05734d84d6964eef2f764a33ac67368c2eaf93" [metadata.files] alabaster = [ @@ -3599,12 +3608,34 @@ pure-eval = [ {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] pyasn1 = [ + {file = "pyasn1-0.4.8-py2.4.egg", hash = "sha256:fec3e9d8e36808a28efb59b489e4528c10ad0f480e57dcc32b4de5c9d8c9fdf3"}, + {file = "pyasn1-0.4.8-py2.5.egg", hash = "sha256:0458773cfe65b153891ac249bcf1b5f8f320b7c2ce462151f8fa74de8934becf"}, + {file = "pyasn1-0.4.8-py2.6.egg", hash = "sha256:5c9414dcfede6e441f7e8f81b43b34e834731003427e5b09e4e00e3172a10f00"}, + {file = "pyasn1-0.4.8-py2.7.egg", hash = "sha256:6e7545f1a61025a4e58bb336952c5061697da694db1cae97b116e9c46abcf7c8"}, {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, + {file = "pyasn1-0.4.8-py3.1.egg", hash = "sha256:78fa6da68ed2727915c4767bb386ab32cdba863caa7dbe473eaae45f9959da86"}, + {file = "pyasn1-0.4.8-py3.2.egg", hash = "sha256:08c3c53b75eaa48d71cf8c710312316392ed40899cb34710d092e96745a358b7"}, + {file = "pyasn1-0.4.8-py3.3.egg", hash = "sha256:03840c999ba71680a131cfaee6fab142e1ed9bbd9c693e285cc6aca0d555e576"}, + {file = "pyasn1-0.4.8-py3.4.egg", hash = "sha256:7ab8a544af125fb704feadb008c99a88805126fb525280b2270bb25cc1d78a12"}, + {file = "pyasn1-0.4.8-py3.5.egg", hash = "sha256:e89bf84b5437b532b0803ba5c9a5e054d21fec423a89952a74f87fa2c9b7bce2"}, + {file = "pyasn1-0.4.8-py3.6.egg", hash = "sha256:014c0e9976956a08139dc0712ae195324a75e142284d5f87f1a87ee1b068a359"}, + {file = "pyasn1-0.4.8-py3.7.egg", hash = "sha256:99fcc3c8d804d1bc6d9a099921e39d827026409a58f2a720dcdb89374ea0c776"}, {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, ] pyasn1-modules = [ {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, + {file = "pyasn1_modules-0.2.8-py2.4.egg", hash = "sha256:0fe1b68d1e486a1ed5473f1302bd991c1611d319bba158e98b106ff86e1d7199"}, + {file = "pyasn1_modules-0.2.8-py2.5.egg", hash = "sha256:fe0644d9ab041506b62782e92b06b8c68cca799e1a9636ec398675459e031405"}, + {file = "pyasn1_modules-0.2.8-py2.6.egg", hash = "sha256:a99324196732f53093a84c4369c996713eb8c89d360a496b599fb1a9c47fc3eb"}, + {file = "pyasn1_modules-0.2.8-py2.7.egg", hash = "sha256:0845a5582f6a02bb3e1bde9ecfc4bfcae6ec3210dd270522fee602365430c3f8"}, {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.2.8-py3.1.egg", hash = "sha256:f39edd8c4ecaa4556e989147ebf219227e2cd2e8a43c7e7fcb1f1c18c5fd6a3d"}, + {file = "pyasn1_modules-0.2.8-py3.2.egg", hash = "sha256:b80486a6c77252ea3a3e9b1e360bc9cf28eaac41263d173c032581ad2f20fe45"}, + {file = "pyasn1_modules-0.2.8-py3.3.egg", hash = "sha256:65cebbaffc913f4fe9e4808735c95ea22d7a7775646ab690518c056784bc21b4"}, + {file = "pyasn1_modules-0.2.8-py3.4.egg", hash = "sha256:15b7c67fabc7fc240d87fb9aabf999cf82311a6d6fb2c70d00d3d0604878c811"}, + {file = "pyasn1_modules-0.2.8-py3.5.egg", hash = "sha256:426edb7a5e8879f1ec54a1864f16b882c2837bfd06eee62f2c982315ee2473ed"}, + {file = "pyasn1_modules-0.2.8-py3.6.egg", hash = "sha256:cbac4bc38d117f2a49aeedec4407d23e8866ea4ac27ff2cf7fb3e5b570df19e0"}, + {file = "pyasn1_modules-0.2.8-py3.7.egg", hash = "sha256:c29a5e5cc7a3f05926aff34e097e84f8589cd790ce0ed41b67aed6857b26aafd"}, ] pycodestyle = [ {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, @@ -4259,6 +4290,9 @@ urllib3 = [ {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, ] +uwsgi = [ + {file = "uwsgi-2.0.21.tar.gz", hash = "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9"}, +] wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, diff --git a/pyproject.toml b/pyproject.toml index 2bf75490c..45f83e832 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,6 +70,7 @@ pdoc = "^12.2.0" dateparser = "^1.1.4" schematic-db = {version = "^0.0.6", extras = ["synapse"]} pyopenssl = "^23.0.0" +uWSGI = "^2.0.21" [tool.poetry.dev-dependencies] diff --git a/run_api.py b/run_api.py index f2a24a192..e89de1092 100755 --- a/run_api.py +++ b/run_api.py @@ -2,7 +2,7 @@ # import our application # Run our application -from api import create_app +from schematic_api.api import create_app from flask_cors import CORS import os @@ -15,4 +15,4 @@ # Launch app app = create_app() CORS(app, resources={r"*": {"origins": "*"}}) - app.run(host=host, port=port, debug=True) + app.run(host=host, port=port, debug=False) \ No newline at end of file diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile new file mode 100644 index 000000000..cade1c9db --- /dev/null +++ b/schematic_api/Dockerfile @@ -0,0 +1,72 @@ +## For aws deployments +FROM python:3.10.9-slim-bullseye + +SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] + +# set APP_PORT to 80 +ENV PYTHONFAULTHANDLER=1 \ + PYTHONUNBUFFERED=1 \ + PYTHONHASHSEED=random \ + PIP_NO_CACHE_DIR=off \ + PIP_DISABLE_PIP_VERSION_CHECK=on \ + PIP_DEFAULT_TIMEOUT=200 \ + POETRY_VERSION=1.2.0 \ + APP_PORT=80 \ + APP_DIR=/opt/app \ + SERVER_PROTOCOL=http:// \ + SERVER_DOMAIN=localhost \ + SERVER_PORT=7080 + +# RUN apt-get autoclean && apt-get -y autoremove + +RUN apt-get update -qq -y \ + && apt-get install --no-install-recommends -qq -y \ + build-essential \ + gosu \ + libpcre3 \ + libpcre3-dev \ + python3-dev \ + libopenblas-dev \ + gfortran \ + && apt-get -y autoclean \ + && apt-get -y autoremove \ + && rm -rf /var/lib/apt/lists/* + + +# remove libtiff5 for security reasons +# RUN apt remove -y libtiff5 +WORKDIR ${APP_DIR} +RUN chown www-data:www-data /opt/app/ + +# install poetry +RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" + +# copy relevant files and run poetry install +COPY ./pyproject.toml ./poetry.lock ./uwsgi.ini ./config.yml ./run_api.py ./ +RUN poetry config virtualenvs.create false +RUN poetry install --no-interaction --no-ansi --no-root + +# copy schematic_api folder +COPY schematic_api ./schematic_api + +# copy great_expectations folder +COPY great_expectations ./great_expectations +RUN chown -R www-data:www-data /opt/app/great_expectations/ + +# copy schematic +COPY schematic ./schematic + +# change permission +WORKDIR /var/www/ +RUN chown www-data:www-data /var/www/ + +WORKDIR / +COPY schematic_api/docker-entrypoint.sh ./ +RUN chmod +x docker-entrypoint.sh + +EXPOSE 7080 + +ENTRYPOINT ["/docker-entrypoint.sh"] + +# Run server in production mode +CMD ["uwsgi", "--ini", "uwsgi.ini", "--lazy", "--http", ":7080"] \ No newline at end of file diff --git a/api/README.md b/schematic_api/api/README.md similarity index 100% rename from api/README.md rename to schematic_api/api/README.md diff --git a/api/__init__.py b/schematic_api/api/__init__.py similarity index 86% rename from api/__init__.py rename to schematic_api/api/__init__.py index fe8fd1777..82bad7e9b 100644 --- a/api/__init__.py +++ b/schematic_api/api/__init__.py @@ -4,16 +4,16 @@ from schematic import CONFIG - def create_app(): connexionapp = connexion.FlaskApp(__name__, specification_dir="openapi/") - connexionapp.add_api("api.yaml") + connexionapp.add_api("api.yaml", arguments={"title": "Schematic REST API"}, pythonic_params=True) + # get the underlying Flask app instance app = connexionapp.app # path to config.yml file saved as a Flask config variable - default_config = os.path.abspath(os.path.join(__file__, "../../config.yml")) + default_config = os.path.abspath(os.path.join(__file__, "../../../config.yml")) schematic_config = os.environ.get("SCHEMATIC_CONFIG", default_config) schematic_config_content = os.environ.get("SCHEMATIC_CONFIG_CONTENT") @@ -32,8 +32,10 @@ def create_app(): return app +app = create_app() + # def route_code(): # import flask_schematic as sc # sc.method1() -# +# \ No newline at end of file diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py new file mode 100644 index 000000000..50257abeb --- /dev/null +++ b/schematic_api/api/__main__.py @@ -0,0 +1,19 @@ +import os +import connexion +from schematic import CONFIG +from flask_cors import CORS +from schematic_api.api import app + + +def main(): + # Get app configuration + host = os.environ.get("APP_HOST", "0.0.0.0") + port = os.environ.get("APP_PORT", "3001") + port = int(port) + + # Launch app + CORS(app, resources={r"*": {"origins": "*"}}) + app.run(host=host, port=port, debug=False) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml similarity index 95% rename from api/openapi/api.yaml rename to schematic_api/api/openapi/api.yaml index 327cc6ad9..409ef61a2 100644 --- a/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -85,7 +85,7 @@ paths: enum: ["excel", "google_sheet", "dataframe (only if getting existing manifests)"] description: If "excel" gets selected, this approach would avoid sending metadata to Google sheet APIs; if "google_sheet" gets selected, this would return a Google sheet URL. This parameter could potentially override sheet_url parameter. required: false - operationId: api.routes.get_manifest_route + operationId: schematic_api.api.routes.get_manifest_route responses: "200": description: Googlesheet link created OR an excel file gets returned OR pandas dataframe gets returned @@ -142,7 +142,7 @@ paths: nullable: true description: Fill in if you want to change the filename of the downloaded manifest. required: false - operationId: api.routes.download_manifest + operationId: schematic_api.api.routes.download_manifest responses: "200": description: A manifest gets downloaded and local file path of the manifest gets returned. @@ -202,7 +202,7 @@ paths: "Family History": "Breast, Lung", }]' - operationId: api.routes.validate_manifest_route + operationId: schematic_api.api.routes.validate_manifest_route responses: "200": description: Manifest Validated @@ -318,7 +318,7 @@ paths: type: boolean default: true required: false - operationId: api.routes.submit_manifest_route + operationId: schematic_api.api.routes.submit_manifest_route responses: "200": description: Manifest ID (e.g. Synapse ID if your asset management platform is Synapse) @@ -357,7 +357,7 @@ paths: default: false description: if False return component requirements as a list; if True return component requirements as a dependency graph (i.e. a DAG) required: true - operationId: api.routes.get_component_requirements + operationId: schematic_api.api.routes.get_component_requirements responses: "200": description: A list of required components associated with the source component. @@ -412,7 +412,7 @@ paths: nullable: true description: If true, this would return an Excel spreadsheet.(This approach would avoid sending metadata to Google sheet APIs) required: false - operationId: api.routes.populate_manifest_route + operationId: schematic_api.api.routes.populate_manifest_route responses: "200": description: Googlesheet link created @@ -428,7 +428,7 @@ paths: get: summary: Get datatype of attributes in manifest description: Get datatype of attributes in manifest - operationId: api.routes.get_manifest_datatype + operationId: schematic_api.api.routes.get_manifest_datatype parameters: - in: query name: input_token @@ -465,7 +465,7 @@ paths: get: summary: Get all storage projects the current user has access to description: Gets all storage projects the current user has access to, within the scope of the 'storageFileview' attribute. - operationId: api.routes.get_storage_projects + operationId: schematic_api.api.routes.get_storage_projects parameters: - in: query name: input_token @@ -494,7 +494,7 @@ paths: get: summary: Gets all datasets in folder under a given storage project that the current user has access to. description: Gets all datasets in folder under a given storage project that the current user has access to. - operationId: api.routes.get_storage_projects_datasets + operationId: schematic_api.api.routes.get_storage_projects_datasets parameters: - in: query name: input_token @@ -531,7 +531,7 @@ paths: get: summary: Get all files in a given dataset folder description: Get all files in a given dataset folder - operationId: api.routes.get_files_storage_dataset + operationId: schematic_api.api.routes.get_files_storage_dataset parameters: - in: query name: input_token @@ -584,7 +584,7 @@ paths: get: summary: Retrieve asset view table as a dataframe. description: Retrieve asset view table as a dataframe. - operationId: api.routes.get_asset_view_table + operationId: schematic_api.api.routes.get_asset_view_table parameters: - in: query name: input_token @@ -621,7 +621,7 @@ paths: get: summary: Gets all metadata manifest files across all datasets in a specified project. description: Gets all metadata manifest files across all datasets in a specified project. - operationId: api.routes.get_project_manifests + operationId: schematic_api.api.routes.get_project_manifests parameters: - in: query name: input_token @@ -669,7 +669,7 @@ paths: get: summary: Return schema as a pickle file description: Return schema as a pickle file - operationId: api.routes.get_schema_pickle + operationId: schematic_api.api.routes.get_schema_pickle parameters: - in: query name: schema_url @@ -695,7 +695,7 @@ paths: get: summary: Find properties specifically associated with a given class description: Find properties specifically associated with a given class - operationId: api.routes.find_class_specific_properties + operationId: schematic_api.api.routes.find_class_specific_properties parameters: - in: query name: schema_url @@ -724,7 +724,7 @@ paths: get: summary: Get a subgraph containing all edges of a given type (aka relationship) description: Get a subgraph containing all edges of a given type (aka relationship) - operationId: api.routes.get_subgraph_by_edge_type + operationId: schematic_api.api.routes.get_subgraph_by_edge_type parameters: - in: query name: schema_url @@ -764,7 +764,7 @@ paths: get: summary: Check if a node is required or not description: Check if a node is required or not - operationId: api.routes.get_if_node_required + operationId: schematic_api.api.routes.get_if_node_required parameters: - in: query name: schema_url @@ -794,7 +794,7 @@ paths: get: summary: Get display names for nodes labels in a list. description: et display names for nodes labels in a list. - operationId: api.routes.get_nodes_display_names + operationId: schematic_api.api.routes.get_nodes_display_names parameters: - in: query name: schema_url @@ -827,7 +827,7 @@ paths: get: summary: Get validation rules for a given node description: Get validation rules for a given node - operationId: api.routes.get_node_validation_rules + operationId: schematic_api.api.routes.get_node_validation_rules parameters: - in: query name: schema_url @@ -857,7 +857,7 @@ paths: get: summary: Get the immediate dependencies that are related to a given source node description: Get the immediate dependencies that are related to a given source node - operationId: api.routes.get_node_dependencies + operationId: schematic_api.api.routes.get_node_dependencies parameters: - in: query name: schema_url @@ -903,7 +903,7 @@ paths: get: summary: Converts a given display name string into a proper property label string description: Converts a given display name string into a proper property label string - operationId: api.routes.get_property_label_from_display_name + operationId: schematic_api.api.routes.get_property_label_from_display_name parameters: - in: query name: schema_url @@ -940,7 +940,7 @@ paths: get: summary: Get all the valid values that are associated with a node label. description: Get all the valid values that are associated with a node label. - operationId: api.routes.get_node_range + operationId: schematic_api.api.routes.get_node_range parameters: - in: query name: schema_url @@ -978,7 +978,7 @@ paths: summary: Get layers of tangled tree. description: >- Get tangled tree node layers to display for a given data model and figure type - operationId: api.routes.get_viz_tangled_tree_layers + operationId: schematic_api.api.routes.get_viz_tangled_tree_layers parameters: - in: query name: schema_url @@ -1010,7 +1010,7 @@ paths: summary: Get text to display on tangled tree. description: >- Get tangled tree plain or higlighted text to display for a given data model, text formatting and figure type - operationId: api.routes.get_viz_tangled_tree_text + operationId: schematic_api.api.routes.get_viz_tangled_tree_text parameters: - in: query name: schema_url @@ -1051,7 +1051,7 @@ paths: description: >- Get all the attributes associated with a data model formatted as a dataframe (stored as a JSON String) for use in Observable visualization. - operationId: api.routes.get_viz_attributes_explorer + operationId: schematic_api.api.routes.get_viz_attributes_explorer parameters: - in: query name: schema_url diff --git a/api/routes.py b/schematic_api/api/routes.py similarity index 100% rename from api/routes.py rename to schematic_api/api/routes.py diff --git a/schematic_api/docker-entrypoint.sh b/schematic_api/docker-entrypoint.sh new file mode 100644 index 000000000..e031eda92 --- /dev/null +++ b/schematic_api/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash +set -e + +if [ "$1" = 'uwsgi' ] || [ "$1" = 'python' ]; then + cd ${APP_DIR} + exec gosu www-data "$@" +fi + +exec "$@" \ No newline at end of file diff --git a/uwsgi.ini b/uwsgi.ini new file mode 100644 index 000000000..7cb272d9c --- /dev/null +++ b/uwsgi.ini @@ -0,0 +1,21 @@ +[uwsgi] +# The variables http and *-socket are passed as command line arguments and +# must not be specified in this file. +; wsgi-file = /opt/app/run_api.py +wsgi-file = /opt/app/schematic_api/api/__main__.py +callable = app +uid = www-data +gid = www-data +processes = 1 # Number of concurrent processes / workers +threads = 1 # Number of threads per process +master = true +chmod-sock = 660 +vacuum = true +die-on-term = true +thunder-lock = true +http-keepalive = true +#harakiri = 300 +harakiri-verbose = true +http-timeout = 300 # for testing +uwsgi_read_timeout = 300 # for testing +uwsgi_send_timeout = 300 # for testing \ No newline at end of file From 0bfafc56f329a746510a14bf59b6574c453b86fe Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 12:59:22 -0500 Subject: [PATCH 178/615] turned data type to optional on submit endpoint --- schematic_api/api/openapi/api.yaml | 3 +-- schematic_api/api/routes.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index 409ef61a2..7abdca856 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -249,9 +249,8 @@ paths: schema: type: string nullable: true - description: Data Model Component + description: Data Model Component. If not being provided, validation will be skipped. example: Patient - required: true - in: query name: dataset_id schema: diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 40f32f2eb..d0e8c130a 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -358,7 +358,7 @@ def validate_manifest_route(schema_url, data_type, json_str=None): return res_dict -def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None, table_manipulation=None): +def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None, table_manipulation=None, data_type=None): # call config_handler() config_handler(asset_view = asset_view) @@ -371,8 +371,6 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None dataset_id = connexion.request.args["dataset_id"] - data_type = connexion.request.args["data_type"] - restrict_rules = parse_bool(connexion.request.args["restrict_rules"]) metadata_model = initalize_metadata_model(schema_url) From 5fcc8797d8fda5e62ed73d1f85ffd560e1808fc7 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 13:01:38 -0500 Subject: [PATCH 179/615] update path of test --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0c9359a05..17755e5bf 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,6 +1,6 @@ import pytest -from api import create_app +from schematic_api.api import create_app import configparser import json import os From f40418c3594b1a79d07b0b32af2602f2c85dd8b8 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 13:05:44 -0500 Subject: [PATCH 180/615] update file path in workflow --- .github/workflows/docker_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 6c951e44d..4e5b35ce7 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - file: dev.Dockerfile + file: file: schematic_api/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file From 38c2889eb6b87b7af1263090410ac8452f83810c Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 13:19:54 -0500 Subject: [PATCH 181/615] remove duplicated param --- .github/workflows/docker_build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 4e5b35ce7..4232a5161 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -43,7 +43,7 @@ jobs: - name: Build and push Docker image uses: docker/build-push-action@ad44023a93711e3deb337508980b4b5e9bcdc5dc with: - file: file: schematic_api/Dockerfile + file: schematic_api/Dockerfile push: true tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} \ No newline at end of file From ba63eec4c2605e1beceb8355cab1bfcedefe4a12 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 13:32:15 -0500 Subject: [PATCH 182/615] remove _query_fileview in getDatasetProject --- schematic/store/synapse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 21d22e7d1..cbe443138 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1405,7 +1405,6 @@ def getDatasetProject(self, datasetId: str) -> str: str: The Synapse ID for the parent project. """ - self._query_fileview() # Subset main file view dataset_index = self.storageFileviewTable["id"] == datasetId From 4137f543c2b9b40e1573d30592d4293bd6c12827 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Feb 2023 16:04:17 -0500 Subject: [PATCH 183/615] add cprofile decorator and print out output if functions are running on AWS --- schematic_api/api/routes.py | 74 +++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index d0e8c130a..998b98312 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -26,7 +26,12 @@ from schematic.utils.df_utils import load_df import pickle from flask import send_from_directory - +from cProfile import Profile +from pstats import Stats +from functools import wraps +from pstats import SortKey +import pstats +import io # def before_request(var1, var2): # # Do stuff before your route executes # pass @@ -34,6 +39,64 @@ # # Do stuff after your route executes # pass +def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): + """ + The function was initially taken from: https://towardsdatascience.com/how-to-profile-your-code-in-python-e70c834fad89 + A time profiler decorator. + Inspired by and modified the profile decorator of Giampaolo Rodola: + http://code.activestate.com/recipes/577817-profile-decorator/ + Args: + output_file: str or None. Default is None + Path of the output file. If only name of the file is given, it's + saved in the current directory. + If it's None, the name of the decorated function is used. + sort_by: str or SortKey enum or tuple/list of str/SortKey enum + Sorting criteria for the Stats object. + For a list of valid string and SortKey refer to: + https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats + lines_to_print: int or None + Number of lines to print. Default (None) is for all the lines. + This is useful in reducing the size of the printout, especially + that sorting by 'cumulative', the time consuming operations + are printed toward the top of the file. + strip_dirs: bool + Whether to remove the leading path info from file names. + This is also useful in reducing the size of the printout + Returns: + Profile of the decorated function + """ + + def inner(func): + @wraps(func) + def wrapper(*args, **kwargs): + _output_file = output_file or func.__name__ + '.prof' + pr = Profile() + pr.enable() + retval = func(*args, **kwargs) + pr.disable() + pr.dump_stats(_output_file) + + #if we are running the functions on AWS: + if "SECRETS_MANAGER_SECRETS" in os.environ: + ps = pstats.Stats(pr) + # limit this to 30 line for now otherwise it will be too long for AWS log + ps.sort_stats('cumulative').print_stats(30) + else: + with open(_output_file, 'w') as f: + ps = pstats.Stats(pr, stream=f) + if strip_dirs: + ps.strip_dirs() + if isinstance(sort_by, (tuple, list)): + ps.sort_stats(*sort_by) + else: + ps.sort_stats(sort_by) + ps.print_stats(lines_to_print) + return retval + + return wrapper + + return inner + def config_handler(asset_view=None): path_to_config = app.config["SCHEMATIC_CONFIG"] @@ -329,7 +392,8 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None return all_results - +#####profile validate manifest route function +@profile(sort_by='cumulative', strip_dirs=True) def validate_manifest_route(schema_url, data_type, json_str=None): # call config_handler() config_handler() @@ -357,7 +421,8 @@ def validate_manifest_route(schema_url, data_type, json_str=None): return res_dict - +#####profile validate manifest route function +@profile(sort_by='cumulative', strip_dirs=True) def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None, table_manipulation=None, data_type=None): # call config_handler() config_handler(asset_view = asset_view) @@ -505,7 +570,8 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): layers = tangled_tree.get_tangled_tree_layers(save_file=False) return layers[0] - + +@profile(sort_by='cumulative', strip_dirs=True) def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) From 4b4f2a6f3afebf653499e2ac6c519fa26334a572 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 17 Feb 2023 15:56:51 -0500 Subject: [PATCH 184/615] increase buffer size to a higher limit to deal with long token --- uwsgi.ini | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/uwsgi.ini b/uwsgi.ini index 7cb272d9c..77eaca10b 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -18,4 +18,5 @@ http-keepalive = true harakiri-verbose = true http-timeout = 300 # for testing uwsgi_read_timeout = 300 # for testing -uwsgi_send_timeout = 300 # for testing \ No newline at end of file +uwsgi_send_timeout = 300 # for testing +buffer-size = 32768 # for dealing with long token in DCA and DFA \ No newline at end of file From 43ff9fb4c6fa5b36ee7444b6f7dc906b3fbe0d79 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 20 Feb 2023 09:36:49 -0700 Subject: [PATCH 185/615] lock `schematic-db` to version `0.0.6` --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 23e95127c..308af09c9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -69,7 +69,7 @@ openpyxl = "^3.0.9" Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" -schematic-db = {version = "^0.0.6", extras = ["synapse"]} +schematic-db = {version = "0.0.6", extras = ["synapse"]} pyopenssl = "^23.0.0" From cc6c47512361bcbd46a6bb6940eea28f6ae70ccf Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 20 Feb 2023 11:37:25 -0700 Subject: [PATCH 186/615] regen .lock --- poetry.lock | 339 ++++++++++++++++++++++++++-------------------------- 1 file changed, 170 insertions(+), 169 deletions(-) diff --git a/poetry.lock b/poetry.lock index 63602e01f..251bb6b9b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -94,7 +94,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.14.1" +version = "2.14.2" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false @@ -339,7 +339,7 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "39.0.0" +version = "39.0.1" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -349,12 +349,14 @@ python-versions = ">=3.6" cffi = ">=1.12" [package.extras] -docs = ["sphinx (>=1.6.5,!=1.8.0,!=3.1.0,!=3.1.1,!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "ruff"] +pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-subtests", "pytest-xdist", "pytz"] +test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] +test-randomorder = ["pytest-randomly"] +tox = ["tox"] [[package]] name = "dateparser" @@ -554,7 +556,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.76.0" +version = "2.78.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -569,7 +571,7 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.16.0" +version = "2.16.1" description = "Google Authentication Library" category = "main" optional = false @@ -645,7 +647,7 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= [[package]] name = "great-expectations" -version = "0.15.47" +version = "0.15.49" description = "Always know what to expect from your data." category = "main" optional = false @@ -676,7 +678,7 @@ pandas = [ {version = ">=1.1.3", markers = "python_version == \"3.9\""}, {version = ">=1.3.0", markers = "python_version >= \"3.10\""}, ] -pydantic = ">=1.0,<2.0" +pydantic = ">=1.10.4,<2.0" pyparsing = ">=2.4" python-dateutil = ">=2.8.1" pytz = ">=2021.3" @@ -695,7 +697,7 @@ aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] -dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] +dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black[jupyter] (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==1.0.0)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=6.2.0)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.246)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] excel = ["openpyxl (>=3.0.7)", "xlrd (>=1.1.0,<2.0.0)"] gcp = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] @@ -710,7 +712,7 @@ snowflake = ["snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1. spark = ["pyspark (>=2.3.2)"] sqlalchemy = ["sqlalchemy (>=1.3.18,<2.0.0)"] teradata = ["sqlalchemy (>=1.3.18,<2.0.0)", "teradatasqlalchemy (==17.0.0.1)"] -test = ["black (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "isort (==5.10.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==0.991)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=5.3.5)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.236)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] +test = ["black[jupyter] (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==1.0.0)", "nbconvert (>=5)", "pre-commit (>=2.21.0)", "pyfakefs (>=4.5.1)", "pytest (>=6.2.0)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.246)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "sqlalchemy (>=1.3.18,<2.0.0)"] trino = ["sqlalchemy (>=1.3.18,<2.0.0)", "trino (>=0.310.0,!=0.316.0)"] vertica = ["sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-vertica-python (>=0.5.10)"] @@ -787,7 +789,7 @@ python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.21.1" +version = "6.21.2" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -804,7 +806,7 @@ matplotlib-inline = ">=0.1" nest-asyncio = "*" packaging = "*" psutil = "*" -pyzmq = ">=17" +pyzmq = ">=20" tornado = ">=6.1" traitlets = ">=5.4.0" @@ -817,7 +819,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.9.0" +version = "8.10.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -838,7 +840,7 @@ stack-data = "*" traitlets = ">=5" [package.extras] -all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.20)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] black = ["black"] doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] kernel = ["ipykernel"] @@ -848,7 +850,7 @@ notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.20)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] [[package]] name = "ipython-genutils" @@ -1007,7 +1009,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jupyter-client" -version = "8.0.2" +version = "8.0.3" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -1065,7 +1067,7 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= [[package]] name = "jupyter-server" -version = "2.2.1" +version = "2.3.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false @@ -1222,7 +1224,7 @@ python-versions = ">=3.6" [[package]] name = "mistune" -version = "2.0.4" +version = "2.0.5" description = "A sane Markdown parser with useful plugins and renderers" category = "main" optional = false @@ -1256,7 +1258,7 @@ python-versions = ">=3.5" [[package]] name = "nbclassic" -version = "0.5.1" +version = "0.5.2" description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false @@ -1269,7 +1271,7 @@ ipython-genutils = "*" jinja2 = "*" jupyter-client = ">=6.1.1" jupyter-core = ">=4.6.1" -jupyter-server = ">=1.17.0" +jupyter-server = ">=1.8" nbconvert = ">=5" nbformat = "*" nest-asyncio = ">=1.5" @@ -1464,7 +1466,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openpyxl" -version = "3.1.0" +version = "3.1.1" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1565,15 +1567,15 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "2.6.2" +version = "3.0.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=5.3)", "sphinx-autodoc-typehints (>=1.19.5)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1611,7 +1613,7 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.21.12" +version = "4.22.0" description = "" category = "main" optional = false @@ -1684,7 +1686,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.10.4" +version = "1.10.5" description = "Data validation and settings management using python type hints" category = "main" optional = false @@ -1733,14 +1735,14 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.16.1" +version = "2.16.2" description = "python code static checker" category = "main" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.14.1,<=2.16.0-dev0" +astroid = ">=2.14.2,<=2.16.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = {version = ">=0.2", markers = "python_version < \"3.11\""} isort = ">=4.2.5,<6" @@ -1861,11 +1863,11 @@ cli = ["click (>=5.0)"] [[package]] name = "python-json-logger" -version = "2.0.4" +version = "2.0.6" description = "A python library adding a json log formatter" category = "main" optional = false -python-versions = ">=3.5" +python-versions = ">=3.6" [[package]] name = "pytz" @@ -2074,7 +2076,7 @@ synapse = ["synapseclient (>=2.6.0,<3.0.0)"] [[package]] name = "scipy" -version = "1.10.0" +version = "1.10.1" description = "Fundamental algorithms for scientific computing in Python" category = "main" optional = false @@ -2152,11 +2154,11 @@ python-versions = "*" [[package]] name = "soupsieve" -version = "2.3.2.post1" +version = "2.4" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "sphinx" @@ -2381,7 +2383,7 @@ tests = ["flake8 (>=3.7.0,<4.0)", "pytest (>=5.0.0,<7.0)", "pytest-mock (>=3.0,< [[package]] name = "tenacity" -version = "8.1.0" +version = "8.2.1" description = "Retry code until it succeeds" category = "main" optional = false @@ -2493,7 +2495,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.4.0" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -2621,7 +2623,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.12.1" +version = "3.14.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -2634,7 +2636,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "ae7079cb736b90a347ca40996b25cd638583d9955e42209e3c67b2bc4b9f1cff" +content-hash = "14b64119a9b97799266275d25ce0c7a9be94d918fbfeb388fabc73cfb3cf1014" [metadata.files] alabaster = [ @@ -2685,8 +2687,8 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.14.1-py3-none-any.whl", hash = "sha256:23c718921acab5f08cbbbe9293967f1f8fec40c336d19cd75dc12a9ea31d2eb2"}, - {file = "astroid-2.14.1.tar.gz", hash = "sha256:bd1aa4f9915c98e8aaebcd4e71930154d4e8c9aaf05d35ac0a63d1956091ae3f"}, + {file = "astroid-2.14.2-py3-none-any.whl", hash = "sha256:0e0e3709d64fbffd3037e4ff403580550f14471fd3eaae9fa11cc9a5c7901153"}, + {file = "astroid-2.14.2.tar.gz", hash = "sha256:a3cf9f02c53dd259144a7e8f3ccd75d67c9a8c716ef183e0c1f291bc5d7bb3cf"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, @@ -2968,29 +2970,29 @@ coverage = [ {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, ] cryptography = [ - {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:c52a1a6f81e738d07f43dab57831c29e57d21c81a942f4602fac7ee21b27f288"}, - {file = "cryptography-39.0.0-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:80ee674c08aaef194bc4627b7f2956e5ba7ef29c3cc3ca488cf15854838a8f72"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:887cbc1ea60786e534b00ba8b04d1095f4272d380ebd5f7a7eb4cc274710fad9"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f97109336df5c178ee7c9c711b264c502b905c2d2a29ace99ed761533a3460f"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a6915075c6d3a5e1215eab5d99bcec0da26036ff2102a1038401d6ef5bef25b"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:76c24dd4fd196a80f9f2f5405a778a8ca132f16b10af113474005635fe7e066c"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:bae6c7f4a36a25291b619ad064a30a07110a805d08dc89984f4f441f6c1f3f96"}, - {file = "cryptography-39.0.0-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:875aea1039d78557c7c6b4db2fe0e9d2413439f4676310a5f269dd342ca7a717"}, - {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f6c0db08d81ead9576c4d94bbb27aed8d7a430fa27890f39084c2d0e2ec6b0df"}, - {file = "cryptography-39.0.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f3ed2d864a2fa1666e749fe52fb8e23d8e06b8012e8bd8147c73797c506e86f1"}, - {file = "cryptography-39.0.0-cp36-abi3-win32.whl", hash = "sha256:f671c1bb0d6088e94d61d80c606d65baacc0d374e67bf895148883461cd848de"}, - {file = "cryptography-39.0.0-cp36-abi3-win_amd64.whl", hash = "sha256:e324de6972b151f99dc078defe8fb1b0a82c6498e37bff335f5bc6b1e3ab5a1e"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:754978da4d0457e7ca176f58c57b1f9de6556591c19b25b8bcce3c77d314f5eb"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ee1fd0de9851ff32dbbb9362a4d833b579b4a6cc96883e8e6d2ff2a6bc7104f"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:fec8b932f51ae245121c4671b4bbc030880f363354b2f0e0bd1366017d891458"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:407cec680e811b4fc829de966f88a7c62a596faa250fc1a4b520a0355b9bc190"}, - {file = "cryptography-39.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7dacfdeee048814563eaaec7c4743c8aea529fe3dd53127313a792f0dadc1773"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad04f413436b0781f20c52a661660f1e23bcd89a0e9bb1d6d20822d048cf2856"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50386acb40fbabbceeb2986332f0287f50f29ccf1497bae31cf5c3e7b4f4b34f"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:e5d71c5d5bd5b5c3eebcf7c5c2bb332d62ec68921a8c593bea8c394911a005ce"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:844ad4d7c3850081dffba91cdd91950038ee4ac525c575509a42d3fc806b83c8"}, - {file = "cryptography-39.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:e0a05aee6a82d944f9b4edd6a001178787d1546ec7c6223ee9a848a7ade92e39"}, - {file = "cryptography-39.0.0.tar.gz", hash = "sha256:f964c7dcf7802d133e8dbd1565914fa0194f9d683d82411989889ecd701e8adf"}, + {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"}, + {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"}, + {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"}, + {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"}, + {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"}, + {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"}, + {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"}, + {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"}, + {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"}, + {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"}, ] dateparser = [ {file = "dateparser-1.1.7-py2.py3-none-any.whl", hash = "sha256:fbed8b738a24c9cd7f47c4f2089527926566fe539e1a06125eddba75917b1eef"}, @@ -3009,6 +3011,7 @@ debugpy = [ {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, + {file = "debugpy-1.6.6-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:11a0f3a106f69901e4a9a5683ce943a7a5605696024134b522aa1bfda25b5fec"}, {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, @@ -3076,12 +3079,12 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.76.0.tar.gz", hash = "sha256:1446d8c618191afdb1190296a4f9648955460184c655da2bfa40c2968e6caac6"}, - {file = "google_api_python_client-2.76.0-py2.py3-none-any.whl", hash = "sha256:514326068802f8e8b32c282c2c1f528cf007247ba19470de6d013731985a3d28"}, + {file = "google-api-python-client-2.78.0.tar.gz", hash = "sha256:32d56a7522a338e525b9c664773230fc8ce382204d4b690eec67a3f8d55d9d63"}, + {file = "google_api_python_client-2.78.0-py2.py3-none-any.whl", hash = "sha256:34a7b73048d7573e99130ebba0a390929382690adccf605b188e74585fc94ea6"}, ] google-auth = [ - {file = "google-auth-2.16.0.tar.gz", hash = "sha256:ed7057a101af1146f0554a769930ac9de506aeca4fd5af6543ebe791851a9fbd"}, - {file = "google_auth-2.16.0-py2.py3-none-any.whl", hash = "sha256:5045648c821fb72384cdc0e82cc326df195f113a33049d9b62b74589243d2acc"}, + {file = "google-auth-2.16.1.tar.gz", hash = "sha256:5fd170986bce6bfd7bb5c845c4b8362edb1e0cba901e062196e83f8bb5d5d32c"}, + {file = "google_auth-2.16.1-py2.py3-none-any.whl", hash = "sha256:75d76ea857df65938e1f71dcbcd7d0cd48e3f80b34b8870ba229c9292081f7ef"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -3100,8 +3103,8 @@ graphviz = [ {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ - {file = "great_expectations-0.15.47-py3-none-any.whl", hash = "sha256:82bbd508ce77d2dec5989b1b8746539212915343cce69dcdd9b134a35ed62f31"}, - {file = "great_expectations-0.15.47.tar.gz", hash = "sha256:efd7d312d427b9dbb257a042a841076ae962232a649002386bd9408c8a05f30a"}, + {file = "great_expectations-0.15.49-py3-none-any.whl", hash = "sha256:0fcdc81a9488e3f7a9bc9e219dcfa0fc0bd20f5f0398dfde47d2f26d269744e3"}, + {file = "great_expectations-0.15.49.tar.gz", hash = "sha256:66445c4e83e8863ec7b31aa906bd7b33e3c20e80ec76e6a57ef90d419e0fa3b4"}, ] greenlet = [ {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, @@ -3190,12 +3193,12 @@ iniconfig = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.21.1-py3-none-any.whl", hash = "sha256:1a04bb359212e23e46adc0116ec82ea128c1e5bd532fde4fbe679787ff36f0cf"}, - {file = "ipykernel-6.21.1.tar.gz", hash = "sha256:a0f8eece39cab1ee352c9b59ec67bbe44d8299f8238e4c16ff7f4cf0052d3378"}, + {file = "ipykernel-6.21.2-py3-none-any.whl", hash = "sha256:430d00549b6aaf49bd0f5393150691edb1815afa62d457ee6b1a66b25cb17874"}, + {file = "ipykernel-6.21.2.tar.gz", hash = "sha256:6e9213484e4ce1fb14267ee435e18f23cc3a0634e635b9fb4ed4677b84e0fdf8"}, ] ipython = [ - {file = "ipython-8.9.0-py3-none-any.whl", hash = "sha256:9c207b0ef2d276d1bfcfeb9a62804336abbe4b170574ea061500952319b1d78c"}, - {file = "ipython-8.9.0.tar.gz", hash = "sha256:71618e82e6d59487bea059626e7c79fb4a5b760d1510d02fab1160db6fdfa1f7"}, + {file = "ipython-8.10.0-py3-none-any.whl", hash = "sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345"}, + {file = "ipython-8.10.0.tar.gz", hash = "sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -3246,8 +3249,8 @@ jsonschema = [ {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] jupyter-client = [ - {file = "jupyter_client-8.0.2-py3-none-any.whl", hash = "sha256:c53731eb590b68839b0ce04bf46ff8c4f03278f5d9fe5c3b0f268a57cc2bd97e"}, - {file = "jupyter_client-8.0.2.tar.gz", hash = "sha256:47ac9f586dbcff4d79387ec264faf0fdeb5f14845fa7345fd7d1e378f8096011"}, + {file = "jupyter_client-8.0.3-py3-none-any.whl", hash = "sha256:be48ac6bd659cbbddb7a674cf06b3b8afbf53f228253cf58bde604c03bd487b0"}, + {file = "jupyter_client-8.0.3.tar.gz", hash = "sha256:ed65498bea6d876ef9d8da3e0db3dd33c5d129f5b2645f56ae03993782966bd0"}, ] jupyter-core = [ {file = "jupyter_core-5.2.0-py3-none-any.whl", hash = "sha256:4bdc2928c37f6917130c667d8b8708f20aee539d8283c6be72aabd2a4b4c83b0"}, @@ -3258,8 +3261,8 @@ jupyter-events = [ {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, ] jupyter-server = [ - {file = "jupyter_server-2.2.1-py3-none-any.whl", hash = "sha256:854fb7d49f6b7f545d4f8354172b004dcda887ba0699def7112daf785ba3c9ce"}, - {file = "jupyter_server-2.2.1.tar.gz", hash = "sha256:5afb8a0cdfee37d02d69bdf470ae9cbb1dee5d4788f9bc6cc8e54bd8c83fb096"}, + {file = "jupyter_server-2.3.0-py3-none-any.whl", hash = "sha256:b15078954120886d580e19d1746e2b62a3dc7bd082cb4716115c25fcd7061b00"}, + {file = "jupyter_server-2.3.0.tar.gz", hash = "sha256:29d6657bfb160b0e39b9030d67f33f918a188f2eba28065314a933b327fef872"}, ] jupyter-server-terminals = [ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, @@ -3378,8 +3381,8 @@ mccabe = [ {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] mistune = [ - {file = "mistune-2.0.4-py2.py3-none-any.whl", hash = "sha256:182cc5ee6f8ed1b807de6b7bb50155df7b66495412836b9a74c8fbdfc75fe36d"}, - {file = "mistune-2.0.4.tar.gz", hash = "sha256:9ee0a66053e2267aba772c71e06891fa8f1af6d4b01d5e84e267b4570d4d9808"}, + {file = "mistune-2.0.5-py2.py3-none-any.whl", hash = "sha256:bad7f5d431886fcbaf5f758118ecff70d31f75231b34024a1341120340a65ce8"}, + {file = "mistune-2.0.5.tar.gz", hash = "sha256:0246113cb2492db875c6be56974a7c893333bf26cd92891c85f63151cee09d34"}, ] mypy = [ {file = "mypy-0.982-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5085e6f442003fa915aeb0a46d4da58128da69325d8213b4b35cc7054090aed5"}, @@ -3412,8 +3415,8 @@ mypy-extensions = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] nbclassic = [ - {file = "nbclassic-0.5.1-py3-none-any.whl", hash = "sha256:32c235e1f22f4048f3b877d354c198202898797cf9c2085856827598cead001b"}, - {file = "nbclassic-0.5.1.tar.gz", hash = "sha256:8e8ffce7582bb7a4baf11fa86a3d88b184e8e7df78eed4ead69f15aa4fc0e323"}, + {file = "nbclassic-0.5.2-py3-none-any.whl", hash = "sha256:6403a996562dadefa7fee9c49e17b663b5fd508241de5df655b90011cf3342d9"}, + {file = "nbclassic-0.5.2.tar.gz", hash = "sha256:40f11bbcc59e8956c3d5ef132dec8e5a853e893ecf831e791d54da0d8a50d79d"}, ] nbclient = [ {file = "nbclient-0.7.2-py3-none-any.whl", hash = "sha256:d97ac6257de2794f5397609df754fcbca1a603e94e924eb9b99787c031ae2e7c"}, @@ -3482,8 +3485,8 @@ oauthlib = [ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, ] openpyxl = [ - {file = "openpyxl-3.1.0-py2.py3-none-any.whl", hash = "sha256:24d7d361025d186ba91eff58135d50855cf035a84371b891e58fb6eb5125660f"}, - {file = "openpyxl-3.1.0.tar.gz", hash = "sha256:eccedbe1cdd8b2494057e73959b496821141038dbb7eb9266ea59e3f34208231"}, + {file = "openpyxl-3.1.1-py2.py3-none-any.whl", hash = "sha256:a0266e033e65f33ee697254b66116a5793c15fc92daf64711080000df4cfe0a8"}, + {file = "openpyxl-3.1.1.tar.gz", hash = "sha256:f06d44e2c973781068bce5ecf860a09bcdb1c7f5ce1facd5e9aa82c92c93ae72"}, ] packaging = [ {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, @@ -3543,8 +3546,8 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-2.6.2-py3-none-any.whl", hash = "sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490"}, - {file = "platformdirs-2.6.2.tar.gz", hash = "sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2"}, + {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"}, + {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -3559,20 +3562,19 @@ prompt-toolkit = [ {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, ] protobuf = [ - {file = "protobuf-4.21.12-cp310-abi3-win32.whl", hash = "sha256:b135410244ebe777db80298297a97fbb4c862c881b4403b71bac9d4107d61fd1"}, - {file = "protobuf-4.21.12-cp310-abi3-win_amd64.whl", hash = "sha256:89f9149e4a0169cddfc44c74f230d7743002e3aa0b9472d8c28f0388102fc4c2"}, - {file = "protobuf-4.21.12-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:299ea899484ee6f44604deb71f424234f654606b983cb496ea2a53e3c63ab791"}, - {file = "protobuf-4.21.12-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:d1736130bce8cf131ac7957fa26880ca19227d4ad68b4888b3be0dea1f95df97"}, - {file = "protobuf-4.21.12-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:78a28c9fa223998472886c77042e9b9afb6fe4242bd2a2a5aced88e3f4422aa7"}, - {file = "protobuf-4.21.12-cp37-cp37m-win32.whl", hash = "sha256:3d164928ff0727d97022957c2b849250ca0e64777ee31efd7d6de2e07c494717"}, - {file = "protobuf-4.21.12-cp37-cp37m-win_amd64.whl", hash = "sha256:f45460f9ee70a0ec1b6694c6e4e348ad2019275680bd68a1d9314b8c7e01e574"}, - {file = "protobuf-4.21.12-cp38-cp38-win32.whl", hash = "sha256:6ab80df09e3208f742c98443b6166bcb70d65f52cfeb67357d52032ea1ae9bec"}, - {file = "protobuf-4.21.12-cp38-cp38-win_amd64.whl", hash = "sha256:1f22ac0ca65bb70a876060d96d914dae09ac98d114294f77584b0d2644fa9c30"}, - {file = "protobuf-4.21.12-cp39-cp39-win32.whl", hash = "sha256:27f4d15021da6d2b706ddc3860fac0a5ddaba34ab679dc182b60a8bb4e1121cc"}, - {file = "protobuf-4.21.12-cp39-cp39-win_amd64.whl", hash = "sha256:237216c3326d46808a9f7c26fd1bd4b20015fb6867dc5d263a493ef9a539293b"}, - {file = "protobuf-4.21.12-py2.py3-none-any.whl", hash = "sha256:a53fd3f03e578553623272dc46ac2f189de23862e68565e83dde203d41b76fc5"}, - {file = "protobuf-4.21.12-py3-none-any.whl", hash = "sha256:b98d0148f84e3a3c569e19f52103ca1feacdac0d2df8d6533cf983d1fda28462"}, - {file = "protobuf-4.21.12.tar.gz", hash = "sha256:7cd532c4566d0e6feafecc1059d04c7915aec8e182d1cf7adee8b24ef1e2e6ab"}, + {file = "protobuf-4.22.0-cp310-abi3-win32.whl", hash = "sha256:b2fea9dc8e3c0f32c38124790ef16cba2ee0628fe2022a52e435e1117bfef9b1"}, + {file = "protobuf-4.22.0-cp310-abi3-win_amd64.whl", hash = "sha256:a33a273d21852f911b8bda47f39f4383fe7c061eb1814db2c76c9875c89c2491"}, + {file = "protobuf-4.22.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e894e9ae603e963f0842498c4cd5d39c6a60f0d7e4c103df50ee939564298658"}, + {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:7c535d126e7dcc714105ab20b418c4fedbd28f8b8afc42b7350b1e317bbbcc71"}, + {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:86c3d20428b007537ba6792b475c0853bba7f66b1f60e610d913b77d94b486e4"}, + {file = "protobuf-4.22.0-cp37-cp37m-win32.whl", hash = "sha256:1669cb7524221a8e2d9008d0842453dbefdd0fcdd64d67672f657244867635fb"}, + {file = "protobuf-4.22.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ab4d043865dd04e6b09386981fe8f80b39a1e46139fb4a3c206229d6b9f36ff6"}, + {file = "protobuf-4.22.0-cp38-cp38-win32.whl", hash = "sha256:29288813aacaa302afa2381db1d6e0482165737b0afdf2811df5fa99185c457b"}, + {file = "protobuf-4.22.0-cp38-cp38-win_amd64.whl", hash = "sha256:e474b63bab0a2ea32a7b26a4d8eec59e33e709321e5e16fb66e766b61b82a95e"}, + {file = "protobuf-4.22.0-cp39-cp39-win32.whl", hash = "sha256:47d31bdf58222dd296976aa1646c68c6ee80b96d22e0a3c336c9174e253fd35e"}, + {file = "protobuf-4.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:c27f371f0159feb70e6ea52ed7e768b3f3a4c5676c1900a7e51a24740381650e"}, + {file = "protobuf-4.22.0-py3-none-any.whl", hash = "sha256:c3325803095fb4c2a48649c321d2fbde59f8fbfcb9bfc7a86df27d112831c571"}, + {file = "protobuf-4.22.0.tar.gz", hash = "sha256:652d8dfece122a24d98eebfef30e31e455d300efa41999d1182e015984ac5930"}, ] psutil = [ {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, @@ -3615,42 +3617,42 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.10.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5635de53e6686fe7a44b5cf25fcc419a0d5e5c1a1efe73d49d48fe7586db854"}, - {file = "pydantic-1.10.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6dc1cc241440ed7ca9ab59d9929075445da6b7c94ced281b3dd4cfe6c8cff817"}, - {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51bdeb10d2db0f288e71d49c9cefa609bca271720ecd0c58009bd7504a0c464c"}, - {file = "pydantic-1.10.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cec42b95dbb500a1f7120bdf95c401f6abb616bbe8785ef09887306792e66e"}, - {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:8775d4ef5e7299a2f4699501077a0defdaac5b6c4321173bcb0f3c496fbadf85"}, - {file = "pydantic-1.10.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:572066051eeac73d23f95ba9a71349c42a3e05999d0ee1572b7860235b850cc6"}, - {file = "pydantic-1.10.4-cp310-cp310-win_amd64.whl", hash = "sha256:7feb6a2d401f4d6863050f58325b8d99c1e56f4512d98b11ac64ad1751dc647d"}, - {file = "pydantic-1.10.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:39f4a73e5342b25c2959529f07f026ef58147249f9b7431e1ba8414a36761f53"}, - {file = "pydantic-1.10.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:983e720704431a6573d626b00662eb78a07148c9115129f9b4351091ec95ecc3"}, - {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75d52162fe6b2b55964fbb0af2ee58e99791a3138588c482572bb6087953113a"}, - {file = "pydantic-1.10.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fdf8d759ef326962b4678d89e275ffc55b7ce59d917d9f72233762061fd04a2d"}, - {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:05a81b006be15655b2a1bae5faa4280cf7c81d0e09fcb49b342ebf826abe5a72"}, - {file = "pydantic-1.10.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d88c4c0e5c5dfd05092a4b271282ef0588e5f4aaf345778056fc5259ba098857"}, - {file = "pydantic-1.10.4-cp311-cp311-win_amd64.whl", hash = "sha256:6a05a9db1ef5be0fe63e988f9617ca2551013f55000289c671f71ec16f4985e3"}, - {file = "pydantic-1.10.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:887ca463c3bc47103c123bc06919c86720e80e1214aab79e9b779cda0ff92a00"}, - {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdf88ab63c3ee282c76d652fc86518aacb737ff35796023fae56a65ced1a5978"}, - {file = "pydantic-1.10.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a48f1953c4a1d9bd0b5167ac50da9a79f6072c63c4cef4cf2a3736994903583e"}, - {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a9f2de23bec87ff306aef658384b02aa7c32389766af3c5dee9ce33e80222dfa"}, - {file = "pydantic-1.10.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:cd8702c5142afda03dc2b1ee6bc358b62b3735b2cce53fc77b31ca9f728e4bc8"}, - {file = "pydantic-1.10.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6e7124d6855b2780611d9f5e1e145e86667eaa3bd9459192c8dc1a097f5e9903"}, - {file = "pydantic-1.10.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b53e1d41e97063d51a02821b80538053ee4608b9a181c1005441f1673c55423"}, - {file = "pydantic-1.10.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:55b1625899acd33229c4352ce0ae54038529b412bd51c4915349b49ca575258f"}, - {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:301d626a59edbe5dfb48fcae245896379a450d04baeed50ef40d8199f2733b06"}, - {file = "pydantic-1.10.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f9d649892a6f54a39ed56b8dfd5e08b5f3be5f893da430bed76975f3735d15"}, - {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d7b5a3821225f5c43496c324b0d6875fde910a1c2933d726a743ce328fbb2a8c"}, - {file = "pydantic-1.10.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f2f7eb6273dd12472d7f218e1fef6f7c7c2f00ac2e1ecde4db8824c457300416"}, - {file = "pydantic-1.10.4-cp38-cp38-win_amd64.whl", hash = "sha256:4b05697738e7d2040696b0a66d9f0a10bec0efa1883ca75ee9e55baf511909d6"}, - {file = "pydantic-1.10.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a9a6747cac06c2beb466064dda999a13176b23535e4c496c9d48e6406f92d42d"}, - {file = "pydantic-1.10.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:eb992a1ef739cc7b543576337bebfc62c0e6567434e522e97291b251a41dad7f"}, - {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:990406d226dea0e8f25f643b370224771878142155b879784ce89f633541a024"}, - {file = "pydantic-1.10.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e82a6d37a95e0b1b42b82ab340ada3963aea1317fd7f888bb6b9dfbf4fff57c"}, - {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9193d4f4ee8feca58bc56c8306bcb820f5c7905fd919e0750acdeeeef0615b28"}, - {file = "pydantic-1.10.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2b3ce5f16deb45c472dde1a0ee05619298c864a20cded09c4edd820e1454129f"}, - {file = "pydantic-1.10.4-cp39-cp39-win_amd64.whl", hash = "sha256:9cbdc268a62d9a98c56e2452d6c41c0263d64a2009aac69246486f01b4f594c4"}, - {file = "pydantic-1.10.4-py3-none-any.whl", hash = "sha256:4948f264678c703f3877d1c8877c4e3b2e12e549c57795107f08cf70c6ec7774"}, - {file = "pydantic-1.10.4.tar.gz", hash = "sha256:b9a3859f24eb4e097502a3be1fb4b2abb79b6103dd9e2e0edb70613a4459a648"}, + {file = "pydantic-1.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5920824fe1e21cbb3e38cf0f3dd24857c8959801d1031ce1fac1d50857a03bfb"}, + {file = "pydantic-1.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3bb99cf9655b377db1a9e47fa4479e3330ea96f4123c6c8200e482704bf1eda2"}, + {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2185a3b3d98ab4506a3f6707569802d2d92c3a7ba3a9a35683a7709ea6c2aaa2"}, + {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f582cac9d11c227c652d3ce8ee223d94eb06f4228b52a8adaafa9fa62e73d5c9"}, + {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c9e5b778b6842f135902e2d82624008c6a79710207e28e86966cd136c621bfee"}, + {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72ef3783be8cbdef6bca034606a5de3862be6b72415dc5cb1fb8ddbac110049a"}, + {file = "pydantic-1.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:45edea10b75d3da43cfda12f3792833a3fa70b6eee4db1ed6aed528cef17c74e"}, + {file = "pydantic-1.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:63200cd8af1af2c07964546b7bc8f217e8bda9d0a2ef0ee0c797b36353914984"}, + {file = "pydantic-1.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:305d0376c516b0dfa1dbefeae8c21042b57b496892d721905a6ec6b79494a66d"}, + {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd326aff5d6c36f05735c7c9b3d5b0e933b4ca52ad0b6e4b38038d82703d35b"}, + {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bb0452d7b8516178c969d305d9630a3c9b8cf16fcf4713261c9ebd465af0d73"}, + {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9a9d9155e2a9f38b2eb9374c88f02fd4d6851ae17b65ee786a87d032f87008f8"}, + {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f836444b4c5ece128b23ec36a446c9ab7f9b0f7981d0d27e13a7c366ee163f8a"}, + {file = "pydantic-1.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:8481dca324e1c7b715ce091a698b181054d22072e848b6fc7895cd86f79b4449"}, + {file = "pydantic-1.10.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87f831e81ea0589cd18257f84386bf30154c5f4bed373b7b75e5cb0b5d53ea87"}, + {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ce1612e98c6326f10888df951a26ec1a577d8df49ddcaea87773bfbe23ba5cc"}, + {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58e41dd1e977531ac6073b11baac8c013f3cd8706a01d3dc74e86955be8b2c0c"}, + {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6a4b0aab29061262065bbdede617ef99cc5914d1bf0ddc8bcd8e3d7928d85bd6"}, + {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:36e44a4de37b8aecffa81c081dbfe42c4d2bf9f6dff34d03dce157ec65eb0f15"}, + {file = "pydantic-1.10.5-cp37-cp37m-win_amd64.whl", hash = "sha256:261f357f0aecda005934e413dfd7aa4077004a174dafe414a8325e6098a8e419"}, + {file = "pydantic-1.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b429f7c457aebb7fbe7cd69c418d1cd7c6fdc4d3c8697f45af78b8d5a7955760"}, + {file = "pydantic-1.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:663d2dd78596c5fa3eb996bc3f34b8c2a592648ad10008f98d1348be7ae212fb"}, + {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51782fd81f09edcf265823c3bf43ff36d00db246eca39ee765ef58dc8421a642"}, + {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c428c0f64a86661fb4873495c4fac430ec7a7cef2b8c1c28f3d1a7277f9ea5ab"}, + {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:76c930ad0746c70f0368c4596020b736ab65b473c1f9b3872310a835d852eb19"}, + {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3257bd714de9db2102b742570a56bf7978e90441193acac109b1f500290f5718"}, + {file = "pydantic-1.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:f5bee6c523d13944a1fdc6f0525bc86dbbd94372f17b83fa6331aabacc8fd08e"}, + {file = "pydantic-1.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:532e97c35719f137ee5405bd3eeddc5c06eb91a032bc755a44e34a712420daf3"}, + {file = "pydantic-1.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ca9075ab3de9e48b75fa8ccb897c34ccc1519177ad8841d99f7fd74cf43be5bf"}, + {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd46a0e6296346c477e59a954da57beaf9c538da37b9df482e50f836e4a7d4bb"}, + {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3353072625ea2a9a6c81ad01b91e5c07fa70deb06368c71307529abf70d23325"}, + {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3f9d9b2be177c3cb6027cd67fbf323586417868c06c3c85d0d101703136e6b31"}, + {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b473d00ccd5c2061fd896ac127b7755baad233f8d996ea288af14ae09f8e0d1e"}, + {file = "pydantic-1.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:5f3bc8f103b56a8c88021d481410874b1f13edf6e838da607dcb57ecff9b4594"}, + {file = "pydantic-1.10.5-py3-none-any.whl", hash = "sha256:7c5b94d598c90f2f46b3a983ffb46ab806a67099d118ae0da7ef21a2a4033b28"}, + {file = "pydantic-1.10.5.tar.gz", hash = "sha256:9e337ac83686645a46db0e825acceea8e02fca4062483f40e9ae178e8bd1103a"}, ] pyflakes = [ {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, @@ -3665,8 +3667,8 @@ pygsheets = [ {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.16.1-py3-none-any.whl", hash = "sha256:bad9d7c36037f6043a1e848a43004dfd5ea5ceb05815d713ba56ca4503a9fe37"}, - {file = "pylint-2.16.1.tar.gz", hash = "sha256:ffe7fa536bb38ba35006a7c8a6d2efbfdd3d95bbf21199cad31f76b1c50aaf30"}, + {file = "pylint-2.16.2-py3-none-any.whl", hash = "sha256:ff22dde9c2128cd257c145cfd51adeff0be7df4d80d669055f24a962b351bbe4"}, + {file = "pylint-2.16.2.tar.gz", hash = "sha256:13b2c805a404a9bf57d002cd5f054ca4d40b0b87542bdaba5e05321ae8262c84"}, ] pyopenssl = [ {file = "pyOpenSSL-23.0.0-py3-none-any.whl", hash = "sha256:df5fc28af899e74e19fccb5510df423581047e10ab6f1f4ba1763ff5fde844c0"}, @@ -3726,8 +3728,8 @@ python-dotenv = [ {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, ] python-json-logger = [ - {file = "python-json-logger-2.0.4.tar.gz", hash = "sha256:764d762175f99fcc4630bd4853b09632acb60a6224acb27ce08cd70f0b1b81bd"}, - {file = "python_json_logger-2.0.4-py3-none-any.whl", hash = "sha256:3b03487b14eb9e4f77e4fc2a023358b5394b82fd89cecf5586259baed57d8c6f"}, + {file = "python-json-logger-2.0.6.tar.gz", hash = "sha256:ed33182c2b438a366775c25c1219ebbd5bd7f71694c644d6b3b3861e19565ae3"}, + {file = "python_json_logger-2.0.6-py3-none-any.whl", hash = "sha256:3af8e5b907b4a5b53cae249205ee3a3d3472bd7ad9ddfaec136eec2f2faf4995"}, ] pytz = [ {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, @@ -4013,7 +4015,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, @@ -4045,27 +4046,27 @@ schematic-db = [ {file = "schematic_db-0.0.6.tar.gz", hash = "sha256:d3505850fb7c23d5c2dd1ad2147cfb29ab86eaf72bf71b390f7707545576bb88"}, ] scipy = [ - {file = "scipy-1.10.0-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:b901b423c91281a974f6cd1c36f5c6c523e665b5a6d5e80fcb2334e14670eefd"}, - {file = "scipy-1.10.0-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:16ba05d3d1b9f2141004f3f36888e05894a525960b07f4c2bfc0456b955a00be"}, - {file = "scipy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:151f066fe7d6653c3ffefd489497b8fa66d7316e3e0d0c0f7ff6acca1b802809"}, - {file = "scipy-1.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f9ea0a37aca111a407cb98aa4e8dfde6e5d9333bae06dfa5d938d14c80bb5c3"}, - {file = "scipy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:27e548276b5a88b51212b61f6dda49a24acf5d770dff940bd372b3f7ced8c6c2"}, - {file = "scipy-1.10.0-cp311-cp311-macosx_10_15_x86_64.whl", hash = "sha256:42ab8b9e7dc1ebe248e55f54eea5307b6ab15011a7883367af48dd781d1312e4"}, - {file = "scipy-1.10.0-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:e096b062d2efdea57f972d232358cb068413dc54eec4f24158bcbb5cb8bddfd8"}, - {file = "scipy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df25a28bd22c990b22129d3c637fd5c3be4b7c94f975dca909d8bab3309b694"}, - {file = "scipy-1.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ad449db4e0820e4b42baccefc98ec772ad7818dcbc9e28b85aa05a536b0f1a2"}, - {file = "scipy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:6faf86ef7717891195ae0537e48da7524d30bc3b828b30c9b115d04ea42f076f"}, - {file = "scipy-1.10.0-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:4bd0e3278126bc882d10414436e58fa3f1eca0aa88b534fcbf80ed47e854f46c"}, - {file = "scipy-1.10.0-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:38bfbd18dcc69eeb589811e77fae552fa923067fdfbb2e171c9eac749885f210"}, - {file = "scipy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ab2a58064836632e2cec31ca197d3695c86b066bc4818052b3f5381bfd2a728"}, - {file = "scipy-1.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd7a30970c29d9768a7164f564d1fbf2842bfc77b7d114a99bc32703ce0bf48"}, - {file = "scipy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:9b878c671655864af59c108c20e4da1e796154bd78c0ed6bb02bc41c84625686"}, - {file = "scipy-1.10.0-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:3afcbddb4488ac950ce1147e7580178b333a29cd43524c689b2e3543a080a2c8"}, - {file = "scipy-1.10.0-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:6e4497e5142f325a5423ff5fda2fff5b5d953da028637ff7c704378c8c284ea7"}, - {file = "scipy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:441cab2166607c82e6d7a8683779cb89ba0f475b983c7e4ab88f3668e268c143"}, - {file = "scipy-1.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0490dc499fe23e4be35b8b6dd1e60a4a34f0c4adb30ac671e6332446b3cbbb5a"}, - {file = "scipy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:954ff69d2d1bf666b794c1d7216e0a746c9d9289096a64ab3355a17c7c59db54"}, - {file = "scipy-1.10.0.tar.gz", hash = "sha256:c8b3cbc636a87a89b770c6afc999baa6bcbb01691b5ccbbc1b1791c7c0a07540"}, + {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, + {file = "scipy-1.10.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:4b3f429188c66603a1a5c549fb414e4d3bdc2a24792e061ffbd607d3d75fd84e"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1553b5dcddd64ba9a0d95355e63fe6c3fc303a8fd77c7bc91e77d61363f7433f"}, + {file = "scipy-1.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c0ff64b06b10e35215abce517252b375e580a6125fd5fdf6421b98efbefb2d2"}, + {file = "scipy-1.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:fae8a7b898c42dffe3f7361c40d5952b6bf32d10c4569098d276b4c547905ee1"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f1564ea217e82c1bbe75ddf7285ba0709ecd503f048cb1236ae9995f64217bd"}, + {file = "scipy-1.10.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:d925fa1c81b772882aa55bcc10bf88324dadb66ff85d548c71515f6689c6dac5"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaea0a6be54462ec027de54fca511540980d1e9eea68b2d5c1dbfe084797be35"}, + {file = "scipy-1.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a35c4242ec5f292c3dd364a7c71a61be87a3d4ddcc693372813c0b73c9af1d"}, + {file = "scipy-1.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:43b8e0bcb877faf0abfb613d51026cd5cc78918e9530e375727bf0625c82788f"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5678f88c68ea866ed9ebe3a989091088553ba12c6090244fdae3e467b1139c35"}, + {file = "scipy-1.10.1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:39becb03541f9e58243f4197584286e339029e8908c46f7221abeea4b749fa88"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bce5869c8d68cf383ce240e44c1d9ae7c06078a9396df68ce88a1230f93a30c1"}, + {file = "scipy-1.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07c3457ce0b3ad5124f98a86533106b643dd811dd61b548e78cf4c8786652f6f"}, + {file = "scipy-1.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:049a8bbf0ad95277ffba9b3b7d23e5369cc39e66406d60422c8cfef40ccc8415"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cd9f1027ff30d90618914a64ca9b1a77a431159df0e2a195d8a9e8a04c78abf9"}, + {file = "scipy-1.10.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:79c8e5a6c6ffaf3a2262ef1be1e108a035cf4f05c14df56057b64acc5bebffb6"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:51af417a000d2dbe1ec6c372dfe688e041a7084da4fdd350aeb139bd3fb55353"}, + {file = "scipy-1.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b4735d6c28aad3cdcf52117e0e91d6b39acd4272f3f5cd9907c24ee931ad601"}, + {file = "scipy-1.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:7ff7f37b1bf4417baca958d254e8e2875d0cc23aaadbe65b3d5b3077b0eb23ea"}, + {file = "scipy-1.10.1.tar.gz", hash = "sha256:2cf9dfb80a7b4589ba4c40ce7588986d6d5cebc5457cad2c2880f6bc2d42f3a5"}, ] secretstorage = [ {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, @@ -4092,8 +4093,8 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] soupsieve = [ - {file = "soupsieve-2.3.2.post1-py3-none-any.whl", hash = "sha256:3b2503d3c7084a42b1ebd08116e5f81aadfaea95863628c80a3b774a11b7c759"}, - {file = "soupsieve-2.3.2.post1.tar.gz", hash = "sha256:fc53893b3da2c33de295667a0e19f078c14bf86544af307354de5fcf12a3f30d"}, + {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, + {file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"}, ] sphinx = [ {file = "Sphinx-6.1.3.tar.gz", hash = "sha256:0dac3b698538ffef41716cf97ba26c1c7788dba73ce6f150c1ff5b4720786dd2"}, @@ -4187,8 +4188,8 @@ synapseclient = [ {file = "synapseclient-2.7.0.tar.gz", hash = "sha256:241f170f0e8c8c3735cd73f81711e592a581c55f7a5c4566be7bee82d72a56bc"}, ] tenacity = [ - {file = "tenacity-8.1.0-py3-none-any.whl", hash = "sha256:35525cd47f82830069f0d6b73f7eb83bc5b73ee2fff0437952cedf98b27653ac"}, - {file = "tenacity-8.1.0.tar.gz", hash = "sha256:e48c437fdf9340f5666b92cd7990e96bc5fc955e1298baf4a907e3972067a445"}, + {file = "tenacity-8.2.1-py3-none-any.whl", hash = "sha256:dd1b769ca7002fda992322939feca5bee4fa11f39146b0af14e0b8d9f27ea854"}, + {file = "tenacity-8.2.1.tar.gz", hash = "sha256:c7bb4b86425b977726a7b49971542d4f67baf72096597d283f3ffd01f33b92df"}, ] terminado = [ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, @@ -4236,8 +4237,8 @@ traitlets = [ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ - {file = "typing_extensions-4.4.0-py3-none-any.whl", hash = "sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e"}, - {file = "typing_extensions-4.4.0.tar.gz", hash = "sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] tzdata = [ {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, @@ -4350,6 +4351,6 @@ wrapt = [ {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, ] zipp = [ - {file = "zipp-3.12.1-py3-none-any.whl", hash = "sha256:6c4fe274b8f85ec73c37a8e4e3fa00df9fb9335da96fb789e3b96b318e5097b3"}, - {file = "zipp-3.12.1.tar.gz", hash = "sha256:a3cac813d40993596b39ea9e93a18e8a2076d5c378b8bc88ec32ab264e04ad02"}, + {file = "zipp-3.14.0-py3-none-any.whl", hash = "sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7"}, + {file = "zipp-3.14.0.tar.gz", hash = "sha256:9e5421e176ef5ab4c0ad896624e87a7b2f07aca746c9b2aa305952800cb8eecb"}, ] From d063b11d9364b68265f963503c41fb4e5528a3ce Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 20 Feb 2023 17:19:42 -0500 Subject: [PATCH 187/615] remove profiling in code --- schematic_api/api/routes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 998b98312..3720d0f08 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -393,7 +393,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None return all_results #####profile validate manifest route function -@profile(sort_by='cumulative', strip_dirs=True) +#@profile(sort_by='cumulative', strip_dirs=True) def validate_manifest_route(schema_url, data_type, json_str=None): # call config_handler() config_handler() @@ -422,7 +422,7 @@ def validate_manifest_route(schema_url, data_type, json_str=None): return res_dict #####profile validate manifest route function -@profile(sort_by='cumulative', strip_dirs=True) +#@profile(sort_by='cumulative', strip_dirs=True) def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None, json_str=None, table_manipulation=None, data_type=None): # call config_handler() config_handler(asset_view = asset_view) @@ -571,7 +571,7 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -@profile(sort_by='cumulative', strip_dirs=True) +#@profile(sort_by='cumulative', strip_dirs=True) def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) From 73b3d3bb6d7dd0b06a2c426d7b1480fcedae3c37 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 22 Feb 2023 11:41:10 -0700 Subject: [PATCH 188/615] use `try: finally` to always delete checkpoint --- schematic/models/validate_manifest.py | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index b08f4c196..708c7033f 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -137,19 +137,20 @@ def validate_manifest_rules( ge_helpers.build_expectation_suite() ge_helpers.build_checkpoint() - #run GE validation - results = ge_helpers.context.run_checkpoint( - checkpoint_name=ge_helpers.checkpoint_name, - batch_request={ - "runtime_parameters": {"batch_data": manifest}, - "batch_identifiers": { - "default_identifier_name": "manifestID" + try: + #run GE validation + results = ge_helpers.context.run_checkpoint( + checkpoint_name=ge_helpers.checkpoint_name, + batch_request={ + "runtime_parameters": {"batch_data": manifest}, + "batch_identifiers": { + "default_identifier_name": "manifestID" + }, }, - }, - result_format={'result_format': 'COMPLETE'}, - ) - - ge_helpers.context.delete_checkpoint(ge_helpers.checkpoint_name) + result_format={'result_format': 'COMPLETE'}, + ) + finally: + ge_helpers.context.delete_checkpoint(ge_helpers.checkpoint_name) validation_results = results.list_validation_results() From 581f4d1896c2fc02d25beb3221a05bdefa0230f8 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 23 Feb 2023 16:01:06 -0500 Subject: [PATCH 189/615] fix column header in new pandas version and avoid sending metadata to google --- schematic/manifest/generator.py | 54 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 493f08961..27f6ee092 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1322,6 +1322,7 @@ def set_dataframe_by_url( sh.default_parse = False # update spreadsheet with given manifest starting at top-left cell + wb.set_dataframe(manifest_df, (1, 1)) # update validation rules (i.e. no validation rules) for out of schema columns, if any @@ -1462,13 +1463,12 @@ def export_sheet_to_excel(self, title: str = None, manifest_url : str = None, ou return output_excel_file_path - def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, manifest_url: str = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None): + def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None): """ handle the logic between sheet_url parameter and output_format parameter to determine the type of output to return Args: output_format: Determines if Google sheet URL, pandas dataframe, or Excel spreadsheet gets returned. sheet_url (Will be deprecated): a boolean ; determine if a pandas dataframe or a google sheet url gets return - manifest_url: Google sheet URL populated with metadata empty_manifest_url: Google sheet URL that leads to an empty manifest dataframe: the pandas dataframe that contains the metadata that needs to be populated to an empty manifest output_path: Determines the output path of the exported manifest (only relevant if returning an excel spreadsheet) @@ -1479,7 +1479,9 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st if not output_format: # if the sheet_url parameter gets set to True, return a google sheet url if sheet_url: - return manifest_url + # populate google sheet with dataframe + manifest_sh = self.set_dataframe_by_url(empty_manifest_url, dataframe) + return manifest_sh.url # else, return a pandas dataframe else: return dataframe @@ -1490,8 +1492,10 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st # if the output type gets set to "excel", return an excel spreadsheet elif output_format == "excel": # export the manifest url to excel - output_file_path = self.export_sheet_to_excel(title = self.title, manifest_url = empty_manifest_url, output_location = output_path) + # note: the manifest url being used here is an empty manifest url that only contains column header + # export manifest that only contains column headers to Excel + output_file_path = self.export_sheet_to_excel(title = self.title, manifest_url = empty_manifest_url, output_location = output_path) if not os.path.exists(output_file_path): logger.error(f'Export to Excel spreadsheet fail. Please make sure that file path {output_file_path} is valid') @@ -1499,9 +1503,10 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st self.populate_existing_excel_spreadsheet(output_file_path, dataframe) return output_file_path - # for all other cases, return a google sheet url + # for all other cases, return a google sheet url after populating the dataframe else: - return manifest_url + manifest_sh = self.set_dataframe_by_url(empty_manifest_url, dataframe) + return manifest_sh.url def get_manifest( self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None, input_token: str = None @@ -1554,12 +1559,9 @@ def get_manifest( # TODO: Update or remove the warning in self.__init__() if # you change the behavior here based on self.use_annotations - - # populate empty manifest with content from downloaded/existing manifest - manifest_sh = self.set_dataframe_by_url(empty_manifest_url, manifest_record[1]) # determine the format of manifest - result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, manifest_url = manifest_sh.url, empty_manifest_url=empty_manifest_url, dataframe = manifest_record[1]) + result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_record[1]) return result # Generate empty template and optionally fill in with annotations @@ -1583,7 +1585,7 @@ def get_manifest( manifest_url, manifest_df = self.get_manifest_with_annotations(annotations) # determine the format of manifest that gets return - result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, manifest_url = manifest_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_df) + result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_df) return result def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, additional_df: pd.DataFrame = None): @@ -1605,22 +1607,20 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a out_of_schema_columns_lst = list(out_of_schema_columns) # initalize excel writer - writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') - writer.worksheets = {ws.title: ws for ws in workbook.worksheets} - worksheet = writer.worksheets["Sheet1"] - - # add additional content to the existing spreadsheet - additional_df.to_excel(writer, sheet_name = "Sheet1", startrow=1, index = False, header=False) - - # if there are new columns, add them to the end of spreadsheet - if len(out_of_schema_columns_lst) > 0: - for i, col_name in enumerate(out_of_schema_columns_lst): - col_index = len(workbook_headers) + 1 + i - worksheet.cell(row=1, column=col_index).value = col_name - - # save and close - writer.save() - writer.close() + with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer: + + # writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') + writer.worksheets = {ws.title: ws for ws in workbook.worksheets} + worksheet = writer.worksheets["Sheet1"] + + # add additional content to the existing spreadsheet + additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) + + # if there are new columns, add them to the end of spreadsheet + if len(out_of_schema_columns_lst) > 0: + for i, col_name in enumerate(out_of_schema_columns_lst): + col_index = len(workbook_headers) + 1 + i + worksheet.cell(row=1, column=col_index).value = col_name def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. From 7ea6395cc268db639381956b676a96553b76ce3b Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 23 Feb 2023 16:15:09 -0500 Subject: [PATCH 190/615] remove old comment --- schematic/manifest/generator.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 27f6ee092..c1c22b71c 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1609,7 +1609,6 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a # initalize excel writer with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer: - # writer = pd.ExcelWriter(existing_excel_path, engine='openpyxl') writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.worksheets["Sheet1"] From 7d10bc6f85f93ee6abd659bef9ca0d5175083180 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Feb 2023 14:47:27 -0500 Subject: [PATCH 191/615] update .ini to avoid write error --- uwsgi.ini | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/uwsgi.ini b/uwsgi.ini index 77eaca10b..b4641ccea 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -19,4 +19,8 @@ harakiri-verbose = true http-timeout = 300 # for testing uwsgi_read_timeout = 300 # for testing uwsgi_send_timeout = 300 # for testing -buffer-size = 32768 # for dealing with long token in DCA and DFA \ No newline at end of file +buffer-size = 32768 # for dealing with long token in DCA and DFA +# for dealing with OSError: write error +ignore-sigpipe=true +ignore-write-errors=true +disable-write-exception=true \ No newline at end of file From fee0a451ab15c3db69bfee77611b2ff614ea893e Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Feb 2023 16:16:33 -0500 Subject: [PATCH 192/615] allow cors on given routes --- schematic_api/api/__main__.py | 4 ++-- schematic_api/api/routes.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index 50257abeb..ea710081d 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -12,8 +12,8 @@ def main(): port = int(port) # Launch app - CORS(app, resources={r"*": {"origins": "*"}}) - app.run(host=host, port=port, debug=False) + # CORS(app, resources={r"*": {"origins": "*"}}) + app.run(host=host, port=port, debug=True) if __name__ == "__main__": main() \ No newline at end of file diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 3720d0f08..bfd256e42 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -38,6 +38,7 @@ # def after_request(var1, var2): # # Do stuff after your route executes # pass +from flask_cors import cross_origin def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): """ @@ -534,6 +535,7 @@ def get_component_requirements(schema_url, source_component, as_graph): return req_components +@cross_origin() def get_viz_attributes_explorer(schema_url): # call config_handler() config_handler() @@ -544,6 +546,7 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv +@cross_origin() def get_viz_tangled_tree_text(schema_url, figure_type, text_format): temp_path_to_jsonld = get_temp_jsonld(schema_url) @@ -556,6 +559,7 @@ def get_viz_tangled_tree_text(schema_url, figure_type, text_format): return text_df +@cross_origin() def get_viz_tangled_tree_layers(schema_url, figure_type): # call config_handler() @@ -571,7 +575,7 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -#@profile(sort_by='cumulative', strip_dirs=True) +@profile(sort_by='cumulative', strip_dirs=True) def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) From 6d2313c5ade016ad3b4fa00cff66b49779da35e3 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Feb 2023 16:22:56 -0500 Subject: [PATCH 193/615] remove changes of debug option --- schematic_api/api/__main__.py | 2 +- schematic_api/api/routes.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index ea710081d..8081a7578 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -13,7 +13,7 @@ def main(): # Launch app # CORS(app, resources={r"*": {"origins": "*"}}) - app.run(host=host, port=port, debug=True) + app.run(host=host, port=port, debug=False) if __name__ == "__main__": main() \ No newline at end of file diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index bfd256e42..62a849843 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -575,7 +575,7 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -@profile(sort_by='cumulative', strip_dirs=True) +#@profile(sort_by='cumulative', strip_dirs=True) def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) From d5a1566df24bfbe27ee9cfcf66d1cc129b94e38d Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Feb 2023 16:38:51 -0500 Subject: [PATCH 194/615] remove CORS in run_api.py --- run_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_api.py b/run_api.py index e89de1092..ed36c7d81 100755 --- a/run_api.py +++ b/run_api.py @@ -14,5 +14,5 @@ # Launch app app = create_app() - CORS(app, resources={r"*": {"origins": "*"}}) + #CORS(app, resources={r"*": {"origins": "*"}}) app.run(host=host, port=port, debug=False) \ No newline at end of file From 71b8f1e6e8135a0ae07397d289ee2a49ecd393aa Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Feb 2023 17:33:53 -0500 Subject: [PATCH 195/615] add domain --- schematic_api/api/routes.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 62a849843..1dce4718f 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -535,7 +535,7 @@ def get_component_requirements(schema_url, source_component, as_graph): return req_components -@cross_origin() +@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) def get_viz_attributes_explorer(schema_url): # call config_handler() config_handler() @@ -546,7 +546,7 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv -@cross_origin() +@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) def get_viz_tangled_tree_text(schema_url, figure_type, text_format): temp_path_to_jsonld = get_temp_jsonld(schema_url) @@ -559,7 +559,7 @@ def get_viz_tangled_tree_text(schema_url, figure_type, text_format): return text_df -@cross_origin() +@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) def get_viz_tangled_tree_layers(schema_url, figure_type): # call config_handler() From 31bb73356b4e953a5f84faf6491226cf1e190ebd Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 27 Feb 2023 14:32:06 -0800 Subject: [PATCH 196/615] Add new manifet_record_type, add to commands.py and help --- schematic/help.py | 6 ++++-- schematic/models/commands.py | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/schematic/help.py b/schematic/help.py index dff2a9214..1ca2660d5 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -107,9 +107,11 @@ "If not, annotations with blank values will be displayed." ), "manifest_record_type":( - "Specify the way the manifest should be store as on Synapse. Options are 'entity', 'table' and " + "Specify the way the manifest should be store as on Synapse. Options are 'entity', 'table', 'manifest' and " "'both'. 'entity' will store the manifest as a csv and create Synapse files for each row in the manifest. " - "'table' will store the manifest as a table and a csv on Synapse. 'both' will do both of the options specified above. " + "'table' will store the manifest as a table and a csv on Synapse. " + "'manifest' will store the manifest as a csv only on Synapse." + "'both' will do both of the options specified above." "Default value is 'table'." ), "table_manipulation":( diff --git a/schematic/models/commands.py b/schematic/models/commands.py index e9e927136..0bbb17615 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -80,7 +80,7 @@ def model(ctx, config): # use as `schematic model ...` "--manifest_record_type", "-mrt", default='both', - type=click.Choice(['table', 'entity', 'both'], case_sensitive=True), + type=click.Choice(['table', 'entity', 'both', 'manifest'], case_sensitive=True), help=query_dict(model_commands, ("model", "submit", "manifest_record_type"))) @click.option( "-rr", From 27e6b280d475c7ad81a7180f82ad9a2edd811ed0 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 27 Feb 2023 14:33:19 -0800 Subject: [PATCH 197/615] remove mrt type check since this is dealt with in CLI and API --- schematic/store/synapse.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 21d22e7d1..9ea269785 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1123,17 +1123,7 @@ def associateMetadataWithFiles( FileNotFoundError: Manifest file does not exist at provided path. """ - - # Check that record type provided matches expected input. - manifest_record_types = ['entity', 'table', 'both'] - try: - manifest_record_type in manifest_record_types - except ValueError as err: - raise ValueError( - f"manifest_record_type provided: {manifest_record_type}, is not one of the accepted " - f"types: {manifest_record_types}" - ) from err - + # read new manifest csv try: load_args={ From bb9f80a30ee9e7e955000aad394f8e83a7f475ca Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 27 Feb 2023 14:34:20 -0800 Subject: [PATCH 198/615] add new mrt option to api --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 327cc6ad9..2dc3ae737 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,7 +263,7 @@ paths: name: manifest_record_type schema: type: string - enum: [ "table", "entity", "both"] + enum: [ "table", "entity", "manifest", "both"] description: Manifest storage type. example: 'table' - in: query From f99ba523bdc6fbf0a3740bc5a344eb4c648cf1a2 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 3 Mar 2023 20:13:24 -0800 Subject: [PATCH 199/615] WIP: add functionality to store csv without entities, light refactor --- schematic/store/synapse.py | 401 ++++++++++++++++++++++++++++++------- 1 file changed, 334 insertions(+), 67 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 9ea269785..69847bcb4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -893,7 +893,7 @@ def buildDB(self, return manifest_table_id - def uplodad_manifest_file(self, manifest, metadataManifestPath, datasetId, restrict_manifest, component_name = ''): + def upload_manifest_file(self, manifest, metadataManifestPath, datasetId, restrict_manifest, component_name = ''): # Update manifest to have the new entityId column manifest.to_csv(metadataManifestPath, index=False) @@ -949,7 +949,6 @@ def format_row_annotations(self, se, sg, row, entityId, useSchemaLabel, hideBlan v = v[0:472] + "[truncatedByDataCuratorApp]" metadataSyn[keySyn] = v - # set annotation(s) for the various objects/items in a dataset on Synapse annos = self.syn.get_annotations(entityId) csv_list_regex=comma_separated_list_regex() @@ -961,12 +960,15 @@ def format_row_annotations(self, se, sg, row, entityId, useSchemaLabel, hideBlan annos.pop(anno_k) if anno_k in annos.keys() else annos # Otherwise save annotation as approrpriate else: - if isinstance(anno_v,float) and np.isnan(anno_v): - annos[anno_k] = "" - elif isinstance(anno_v,str) and re.fullmatch(csv_list_regex, anno_v) and rule_in_rule_list('list', sg.get_node_validation_rules(anno_k)): - annos[anno_k] = anno_v.split(",") - else: - annos[anno_k] = anno_v + try: + if isinstance(anno_v,float) and np.isnan(anno_v): + annos[anno_k] = "" + elif isinstance(anno_v,str) and re.fullmatch(csv_list_regex, anno_v) and rule_in_rule_list('list', sg.get_node_validation_rules(anno_k)): + annos[anno_k] = anno_v.split(",") + else: + annos[anno_k] = anno_v + except: + breakpoint() return annos @@ -1066,7 +1068,7 @@ def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPa entityId = row["entityId"] # Load manifest to synapse as a CSV File - manifest_synapse_file_id = self.uplodad_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest) + manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest) # Get annotations for the file manifest. manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) @@ -1091,39 +1093,15 @@ def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPa return manifest_synapse_table_id ''' - def associateMetadataWithFiles( - self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'both', - useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', - ) -> str: - """Associate metadata with files in a storage dataset already on Synapse. - Upload metadataManifest in the storage dataset folder on Synapse as well. Return synapseId of the uploaded manifest file. - - If this is a new manifest there could be no Synapse entities associated with the rows of this manifest - this may be due to data type (e.g. clinical data) being tabular - and not requiring files; to utilize uniform interfaces downstream - (i.e. fileviews), a Synapse entity (a folder) is created for each row - and an entity column is added to the manifest containing the resulting - entity IDs; a table is also created at present as an additional interface - for downstream query and interaction with the data. - + def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: + """Helper function to read in provided manifest as a pandas DataFrame for subsequent downstream processing. Args: - metadataManifestPath: path to csv containing a validated metadata manifest. - The manifest should include a column entityId containing synapse IDs of files/entities to be associated with metadata, if that is applicable to the dataset type. - Some datasets, e.g. clinical data, do not contain file id's, but data is stored in a table: one row per item. - In this case, the system creates a file on Synapse for each row in the table (e.g. patient, biospecimen) and associates the columnset data as metadata/annotations to his file. - datasetId: synapse ID of folder containing the dataset - useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. - manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. - hideBlanks: Default is false. Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + metadataManifestPath (str): path where manifest is stored Returns: - manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. - + manifest(pd.DataFrame): Manifest loaded as a pandas dataframe Raises: - ValueError: manifest_record_type is not 'entity', 'table' or 'both' FileNotFoundError: Manifest file does not exist at provided path. - """ - # read new manifest csv try: load_args={ @@ -1134,7 +1112,15 @@ def associateMetadataWithFiles( raise FileNotFoundError( f"No manifest file was found at this path: {metadataManifestPath}" ) from err + return manifest + def _add_id_columns_to_manifest(self, manifest): + """Helper function to add UUID and entityId columns to the manifest if they do not already exist, Fill UUID values per row. + Args: + Manifest loaded as a pd.Dataframe + Returns (pd.DataFrame): + Manifest df with new Uuid and EntityId columns (and UUID values) if they were not already present. + """ # Add uuid for table updates and fill. if not "Uuid" in manifest.columns: manifest["Uuid"] = '' @@ -1152,9 +1138,15 @@ def associateMetadataWithFiles( else: manifest["entityId"].fillna("", inplace=True) - # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations - se = SchemaExplorer() + return manifest + def _generate_table_name(self, manifest): + """Helper function to generate a table name for upload to synapse. + Args: + Manifest loaded as a pd.Dataframe + Returns: + table_name (str): Name of the table to load + """ # Create table name here. if 'Component' in manifest.columns: component_name = manifest['Component'][0].lower() @@ -1162,27 +1154,68 @@ def associateMetadataWithFiles( else: component_name = '' table_name = 'synapse_storage_manifest_table' + return table_name, component_name - # If specified, upload manifest as a table and get the SynID and manifest - if manifest_record_type == 'table' or manifest_record_type == 'both': - manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( - se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation=table_manipulation,) - - # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed - # also set metadata for each synapse entity as Synapse annotations + def add_annotations(self, se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks): + """Helper function to format and add annotations to entities in Synapse. + Args: + se: schemaExplorer object, + schemaGenerator: schemaGenerator Object. + row: current row of manifest being processed + entityId (str): synapseId of entity to add annotations to + useSchemaLabel (bool): Flag to use schema label instead of display name + hideBlanks: Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + Returns: + Annotations are added to entities in Synapse, no return. + """ + # Format annotations for Synapse + annos = self.format_row_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) + + if annos: + # Store annotations for an entity folder + self.syn.set_annotations(annos) + return + + def _create_entity_id(self, idx, row, manifest, datasetId): + """Helper function to generate an entityId and add it to the appropriate row in the manifest. + Args: + row: current row of manifest being processed + manifest (pd.DataFrame): loaded df containing user supplied data. + datasetId (str): synapse ID of folder containing the dataset + + Returns: + manifest (pd.DataFrame): manifest with entityId added to the appropriate row + entityId (str): Generated Entity Id. + + """ + rowEntity = Folder(str(uuid.uuid4()), parent=datasetId) + rowEntity = self.syn.store(rowEntity) + entityId = rowEntity["id"] + row["entityId"] = entityId + manifest.loc[idx, "entityId"] = entityId + return manifest, entityId + + def add_entities( + self, + se, + schemaGenerator, + manifest, + manifest_record_type, + datasetId, + useSchemaLabel, + hideBlanks, + manifest_synapse_table_id='' + ): + '''Depending on upload type add Ids to entity row. + ''' for idx, row in manifest.iterrows(): if not row["entityId"] and (manifest_record_type == 'entity' or manifest_record_type == 'both'): - # no entity exists for this row - # so create one - rowEntity = Folder(str(uuid.uuid4()), parent=datasetId) - rowEntity = self.syn.store(rowEntity) - entityId = rowEntity["id"] - row["entityId"] = entityId - manifest.loc[idx, "entityId"] = entityId + manifest, entityId = self._create_entity_id(idx, row, manifest, datasetId) elif not row["entityId"] and manifest_record_type == 'table': # If not using entityIds, fill with manifest_table_id so row["entityId"] = manifest_synapse_table_id + manifest.loc[idx, "entityId"] = manifest_synapse_table_id entityId = '' else: # get the entity id corresponding to this row @@ -1190,15 +1223,103 @@ def associateMetadataWithFiles( # Adding annotations to connected files. if entityId: - # Format annotations for Synapse - annos = self.format_row_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) + self.add_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) + return manifest - if annos: - # Store annotations for an entity folder - self.syn.set_annotations(annos) + + def upload_manifest_as_table( + self, + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + table_name, + component_name, + restrict, + manifest_record_type, + useSchemaLabel, + hideBlanks, + table_manipulation, + ): + """Upload manifest to Synapse as a table and csv. + Args: + #se: schema explorer object + manifest (pd.DataFrame): loaded df containing user supplied data. + datasetId (str): synapse ID of folder containing the dataset + restrict_manifest(bool): Default is false. Flag for censored data. + table_name (str): Generated to name the table being uploaded. + useSchemaLabel (bool): True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + table_malnipulation (str): Default is 'replace'. Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. + Return: + manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. + """ + + # Upload manifest as a table, get the ID and updated manifest. + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + se, + manifest, + datasetId, + table_name, + restrict, + useSchemaLabel, + table_manipulation) + + manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) # Load manifest to synapse as a CSV File - manifest_synapse_file_id = self.uplodad_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest, component_name = component_name) + manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict, component_name = component_name) + + # Set annotations for the file manifest. + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) + self.syn.set_annotations(manifest_annotations) + logger.info("Associated manifest file with dataset on Synapse.") + + # Update manifest Synapse table with new entity id column. + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + se, + manifest, + datasetId, + table_name, + restrict, + useSchemaLabel=useSchemaLabel, + table_manipulation='update',) + + # Set annotations for the table manifest + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) + self.syn.set_annotations(manifest_annotations) + return manifest_synapse_file_id + + def upload_manifest_as_csv( + self, + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + restrict, + manifest_record_type, + useSchemaLabel, + hideBlanks, + component_name, + with_entities = False,): + + """Upload manifest to Synapse as a csv only. + Args: + manifest (pd.DataFrame): loaded df containing user supplied data. + metadataManifestPath: path to csv containing a validated metadata manifest. + datasetId (str): synapse ID of folder containing the dataset + restrict_manifest(bool): Default is false. Flag for censored data. + component_name (str): Name of component the manifest represents. If no component is ''. + Return: + manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. + """ + if with_entities: + manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks) + + # Load manifest to synapse as a CSV File + manifest_synapse_file_id = self.upload_manifest_file(manifest, + metadataManifestPath, datasetId, restrict, component_name = component_name) # Set annotations for the file manifest. manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) @@ -1206,15 +1327,161 @@ def associateMetadataWithFiles( logger.info("Associated manifest file with dataset on Synapse.") - if manifest_record_type == 'table' or manifest_record_type == 'both': - # Update manifest Synapse table with new entity id column. - - manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( - se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,table_manipulation='update',) + return manifest_synapse_file_id + + def upload_manifest_combo( + self, + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + table_name, + component_name, + restrict, + manifest_record_type, + useSchemaLabel, + hideBlanks, + table_manipulation, + ): + """Upload manifest to Synapse as a table and CSV with entities. + + """ + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + se, + manifest, + datasetId, + table_name, + restrict, + useSchemaLabel=useSchemaLabel, + table_manipulation=table_manipulation,) + + + manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) + + # Load manifest to synapse as a CSV File + manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict, component_name) + + # Set annotations for the file manifest. + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) + self.syn.set_annotations(manifest_annotations) + logger.info("Associated manifest file with dataset on Synapse.") + + # Update manifest Synapse table with new entity id column. + manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( + se, + manifest, + datasetId, + table_name, + restrict, + useSchemaLabel=useSchemaLabel, + table_manipulation='update',) + + # Set annotations for the table manifest + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) + self.syn.set_annotations(manifest_annotations) + return manifest_synapse_file_id + + def associateMetadataWithFiles( + self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'both', + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', + ) -> str: + """Associate metadata with files in a storage dataset already on Synapse. + Upload metadataManifest in the storage dataset folder on Synapse as well. Return synapseId of the uploaded manifest file. + + If this is a new manifest there could be no Synapse entities associated with the rows of this manifest + this may be due to data type (e.g. clinical data) being tabular + and not requiring files; to utilize uniform interfaces downstream + (i.e. fileviews), a Synapse entity (a folder) is created for each row + and an entity column is added to the manifest containing the resulting + entity IDs; a table is also created at present as an additional interface + for downstream query and interaction with the data. + + Args: + metadataManifestPath: path to csv containing a validated metadata manifest. + The manifest should include a column entityId containing synapse IDs of files/entities to be associated with metadata, if that is applicable to the dataset type. + Some datasets, e.g. clinical data, do not contain file id's, but data is stored in a table: one row per item. + In this case, the system creates a file on Synapse for each row in the table (e.g. patient, biospecimen) and associates the columnset data as metadata/annotations to his file. + datasetId: synapse ID of folder containing the dataset + manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks: Default is false. Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + restrict_manifest (bool): Default is false. Flag for censored data. + table_malnipulation (str): Default is 'replace'. Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. + Returns: + manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. + + + """ + + # Read new manifest CSV: + manifest = self._read_manifest(metadataManifestPath) + manifest = self._add_id_columns_to_manifest(manifest) + + # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations + se = SchemaExplorer() - # Set annotations for the table manifest - manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) - self.syn.set_annotations(manifest_annotations) + table_name, component_name = self._generate_table_name(manifest) + + # Upload manifest to synapse based on user input (manifest_record_type) + if manifest_record_type == "table": + manifest_synapse_file_id = self.upload_manifest_as_table( + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + table_name, + component_name, + restrict=restrict_manifest, + useSchemaLabel=useSchemaLabel, + hideBlanks=hideBlanks, + manifest_record_type=manifest_record_type, + table_manipulation=table_manipulation, + ) + if manifest_record_type == "entity": + manifest_synapse_file_id = self.upload_manifest_as_csv( + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + restrict=restrict_manifest, + useSchemaLabel=useSchemaLabel, + hideBlanks=hideBlanks, + manifest_record_type=manifest_record_type, + component_name = component_name, + with_entities=True, + ) + if manifest_record_type == "both": + manifest_synapse_file_id = self.upload_manifest_combo( + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + table_name, + component_name, + restrict=restrict_manifest, + useSchemaLabel=useSchemaLabel, + hideBlanks=hideBlanks, + manifest_record_type=manifest_record_type, + table_manipulation=table_manipulation, + ) + if manifest_record_type == "manifest": + manifest_synapse_file_id = self.upload_manifest_as_csv( + se, + schemaGenerator, + manifest, + metadataManifestPath, + datasetId, + restrict=restrict_manifest, + useSchemaLabel=useSchemaLabel, + hideBlanks=hideBlanks, + manifest_record_type=manifest_record_type, + component_name = component_name, + with_entities = False, + ) return manifest_synapse_file_id From 15806197c54600bafddf78024f6c150b90d09e66 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Sat, 4 Mar 2023 21:45:35 -0800 Subject: [PATCH 200/615] WIP: change name of manifest_record_types options --- api/openapi/api.yaml | 2 +- schematic/help.py | 10 +++--- schematic/models/commands.py | 4 +-- schematic/store/synapse.py | 64 ++++++++++++++++++++++-------------- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 2dc3ae737..df8dd5497 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,7 +263,7 @@ paths: name: manifest_record_type schema: type: string - enum: [ "table", "entity", "manifest", "both"] + enum: [ "table", "file", "file_w_entites", "combo"] description: Manifest storage type. example: 'table' - in: query diff --git a/schematic/help.py b/schematic/help.py index 1ca2660d5..1fd309bc4 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -107,12 +107,12 @@ "If not, annotations with blank values will be displayed." ), "manifest_record_type":( - "Specify the way the manifest should be store as on Synapse. Options are 'entity', 'table', 'manifest' and " - "'both'. 'entity' will store the manifest as a csv and create Synapse files for each row in the manifest. " + "Specify the way the manifest should be store as on Synapse. Options are 'file', 'file_w_entities', 'table' and " + "'combo'. 'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. " "'table' will store the manifest as a table and a csv on Synapse. " - "'manifest' will store the manifest as a csv only on Synapse." - "'both' will do both of the options specified above." - "Default value is 'table'." + "'file' will store the manifest as a csv only on Synapse." + "'combo' will perform the options file_with_entites and table in combination." + "Default value is 'combo'." ), "table_manipulation":( "Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. " diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 0bbb17615..2206e17e9 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -79,8 +79,8 @@ def model(ctx, config): # use as `schematic model ...` @click.option( "--manifest_record_type", "-mrt", - default='both', - type=click.Choice(['table', 'entity', 'both', 'manifest'], case_sensitive=True), + default='combo', + type=click.Choice(['table', 'file', 'file_w_entities', 'combo'], case_sensitive=True), help=query_dict(model_commands, ("model", "submit", "manifest_record_type"))) @click.option( "-rr", diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 69847bcb4..507356600 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1153,10 +1153,10 @@ def _generate_table_name(self, manifest): table_name = component_name + '_synapse_storage_manifest_table' else: component_name = '' - table_name = 'synapse_storage_manifest_table' + tabsle_name = 'synapse_storage_manifest_table' return table_name, component_name - def add_annotations(self, se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks): + def _add_annotations(self, se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks): """Helper function to format and add annotations to entities in Synapse. Args: se: schemaExplorer object, @@ -1206,11 +1206,22 @@ def add_entities( hideBlanks, manifest_synapse_table_id='' ): - '''Depending on upload type add Ids to entity row. + '''Depending on upload type add Ids to entityId row. Add anotations to connected files. + Args: + se: Schema Explorer Object + schemaGenerator: SchemaGenerator object + manifest (pd.DataFrame): loaded df containing user supplied data. + manifest_record_type: + datasetId: + useSchemaLabel: + hideBlanks: + manifest_synapse_table_id: Default is an empty string ''. + Returns + ''' for idx, row in manifest.iterrows(): - if not row["entityId"] and (manifest_record_type == 'entity' or - manifest_record_type == 'both'): + if not row["entityId"] and (manifest_record_type == 'file_w_entities' or + manifest_record_type == 'combo'): manifest, entityId = self._create_entity_id(idx, row, manifest, datasetId) elif not row["entityId"] and manifest_record_type == 'table': # If not using entityIds, fill with manifest_table_id so @@ -1223,7 +1234,7 @@ def add_entities( # Adding annotations to connected files. if entityId: - self.add_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) + self._add_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) return manifest @@ -1245,13 +1256,18 @@ def upload_manifest_as_table( ): """Upload manifest to Synapse as a table and csv. Args: - #se: schema explorer object + se: SchemaExplorer object + schemaGenerator: SchemaGenerator Object manifest (pd.DataFrame): loaded df containing user supplied data. datasetId (str): synapse ID of folder containing the dataset restrict_manifest(bool): Default is false. Flag for censored data. table_name (str): Generated to name the table being uploaded. - useSchemaLabel (bool): True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. - table_malnipulation (str): Default is 'replace'. Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. + component_name (str): Name of the component manifest that is currently being uploaded. + restrict (bool): Flag for censored data. + manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks: Default is false -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + table_malnipulation (str): Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. Return: manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. """ @@ -1383,7 +1399,7 @@ def upload_manifest_combo( return manifest_synapse_file_id def associateMetadataWithFiles( - self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'both', + self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'combo', useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', ) -> str: """Associate metadata with files in a storage dataset already on Synapse. @@ -1403,7 +1419,7 @@ def associateMetadataWithFiles( Some datasets, e.g. clinical data, do not contain file id's, but data is stored in a table: one row per item. In this case, the system creates a file on Synapse for each row in the table (e.g. patient, biospecimen) and associates the columnset data as metadata/annotations to his file. datasetId: synapse ID of folder containing the dataset - manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + manifest_record_type: Default value is 'combo'. valid values are 'file', 'file_w_entities', 'table' or 'combo'. 'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest.'table' will store the manifest as a table and a csv on Synapse. 'file' will store the manifest as a csv only on Synapse. 'combo' will perform the options file_with_entites and table in combination. useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. hideBlanks: Default is false. Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. restrict_manifest (bool): Default is false. Flag for censored data. @@ -1439,8 +1455,8 @@ def associateMetadataWithFiles( manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, ) - if manifest_record_type == "entity": - manifest_synapse_file_id = self.upload_manifest_as_csv( + elif manifest_record_type == "file": + manifest_synapse_file_id = self.upload_manifest_as_csv( se, schemaGenerator, manifest, @@ -1451,38 +1467,38 @@ def associateMetadataWithFiles( hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, component_name = component_name, - with_entities=True, + with_entities = False, ) - if manifest_record_type == "both": - manifest_synapse_file_id = self.upload_manifest_combo( + + elif manifest_record_type == "file_w_entities": + manifest_synapse_file_id = self.upload_manifest_as_csv( se, schemaGenerator, manifest, metadataManifestPath, datasetId, - table_name, - component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, - table_manipulation=table_manipulation, + component_name = component_name, + with_entities=True, ) - if manifest_record_type == "manifest": - manifest_synapse_file_id = self.upload_manifest_as_csv( + elif manifest_record_type == "combo": + manifest_synapse_file_id = self.upload_manifest_combo( se, schemaGenerator, manifest, metadataManifestPath, datasetId, + table_name, + component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, - component_name = component_name, - with_entities = False, + table_manipulation=table_manipulation, ) - return manifest_synapse_file_id def getTableAnnotations(self, table_id:str): From 2b644bcbf95cd3e0f3d4763ed5bc6f182eff678e Mon Sep 17 00:00:00 2001 From: Lingling <55448354+linglp@users.noreply.github.com> Date: Mon, 6 Mar 2023 11:10:53 -0500 Subject: [PATCH 201/615] updated to use domain names Co-authored-by: Thomas Schaffter --- schematic_api/api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 1dce4718f..62dd1018f 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -559,7 +559,7 @@ def get_viz_tangled_tree_text(schema_url, figure_type, text_format): return text_df -@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) +@cross_origin(["http://localhost", "https://sage-bionetworks.github.io"]) def get_viz_tangled_tree_layers(schema_url, figure_type): # call config_handler() From f3c64a03ecbebfc364d3919c960c5dc884bb7e09 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 6 Mar 2023 11:22:40 -0500 Subject: [PATCH 202/615] use domain name --- schematic_api/api/routes.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 62dd1018f..d907ac84a 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -535,7 +535,7 @@ def get_component_requirements(schema_url, source_component, as_graph): return req_components -@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) +@cross_origin(["http://localhost", "https://sage-bionetworks.github.io"]) def get_viz_attributes_explorer(schema_url): # call config_handler() config_handler() @@ -546,7 +546,7 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv -@cross_origin(["http://localhost:8000/main.html", "https://sage-bionetworks.github.io/schema_visualization/"]) +@cross_origin(["http://localhost", "https://sage-bionetworks.github.io"]) def get_viz_tangled_tree_text(schema_url, figure_type, text_format): temp_path_to_jsonld = get_temp_jsonld(schema_url) From bc4b2667bc7209f96ec71c8e80796b3e7125981d Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Mon, 6 Mar 2023 14:37:51 -0800 Subject: [PATCH 203/615] cleanup formatting, add docstrings --- api/openapi/api.yaml | 2 +- schematic/store/synapse.py | 60 ++++++++++++++++++++++++-------------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index df8dd5497..91f3daada 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,7 +263,7 @@ paths: name: manifest_record_type schema: type: string - enum: [ "table", "file", "file_w_entites", "combo"] + enum: ["table", "file", "file_w_entites", "combo"] description: Manifest storage type. example: 'table' - in: query diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 507356600..86fcd497c 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1146,6 +1146,7 @@ def _generate_table_name(self, manifest): Manifest loaded as a pd.Dataframe Returns: table_name (str): Name of the table to load + component_name (str): Name of the manifest component (if applicable) """ # Create table name here. if 'Component' in manifest.columns: @@ -1211,12 +1212,13 @@ def add_entities( se: Schema Explorer Object schemaGenerator: SchemaGenerator object manifest (pd.DataFrame): loaded df containing user supplied data. - manifest_record_type: - datasetId: - useSchemaLabel: - hideBlanks: - manifest_synapse_table_id: Default is an empty string ''. - Returns + manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + datasetId (str): synapse ID of folder containing the dataset + useSchemaLabel (bool): Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks (bool): Default is false -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + manifest_synapse_table_id (str): Default is an empty string ''. + Returns: + manifest (pd.DataFrame): modified to add entitiyId as appropriate. ''' for idx, row in manifest.iterrows(): @@ -1237,8 +1239,6 @@ def add_entities( self._add_annotations(se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks) return manifest - - def upload_manifest_as_table( self, se, @@ -1259,19 +1259,18 @@ def upload_manifest_as_table( se: SchemaExplorer object schemaGenerator: SchemaGenerator Object manifest (pd.DataFrame): loaded df containing user supplied data. + metadataManifestPath: path to csv containing a validated metadata manifest. datasetId (str): synapse ID of folder containing the dataset - restrict_manifest(bool): Default is false. Flag for censored data. table_name (str): Generated to name the table being uploaded. component_name (str): Name of the component manifest that is currently being uploaded. restrict (bool): Flag for censored data. - manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. - useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. - hideBlanks: Default is false -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + manifest_record_type (str): valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + useSchemaLabel(bool): Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks (bool): Default is False -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. table_malnipulation (str): Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. Return: manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. - """ - + """ # Upload manifest as a table, get the ID and updated manifest. manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( se, @@ -1319,16 +1318,21 @@ def upload_manifest_as_csv( hideBlanks, component_name, with_entities = False,): - """Upload manifest to Synapse as a csv only. Args: + se: SchemaExplorer object + schemaGenerator: SchemaGenerator Object manifest (pd.DataFrame): loaded df containing user supplied data. metadataManifestPath: path to csv containing a validated metadata manifest. datasetId (str): synapse ID of folder containing the dataset - restrict_manifest(bool): Default is false. Flag for censored data. - component_name (str): Name of component the manifest represents. If no component is ''. + restrict (bool): Flag for censored data. + manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + useSchemaLabel (bool): Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks (bool): Default is False -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + table_malnipulation (str): Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. + with_entities (bool): Default is False - Flag to indicate whether to create entityIds and add annotations. Return: - manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. + manifest_synapse_file_id (str): SynID of manifest csv uploaded to synapse. """ if with_entities: manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks) @@ -1361,7 +1365,21 @@ def upload_manifest_combo( table_manipulation, ): """Upload manifest to Synapse as a table and CSV with entities. - + Args: + se: SchemaExplorer object + schemaGenerator: SchemaGenerator Object + manifest (pd.DataFrame): loaded df containing user supplied data. + metadataManifestPath: path to csv containing a validated metadata manifest. + datasetId (str): synapse ID of folder containing the dataset + table_name (str): Generated to name the table being uploaded. + component_name (str): Name of the component manifest that is currently being uploaded. + restrict (bool): Flag for censored data. + manifest_record_type: valid values are 'entity', 'table' or 'both'. Specifies whether to create entity ids and folders for each row in a manifest, a Synapse table to house the entire manifest or do both. + useSchemaLabel (bool): Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. + hideBlanks (bool): Default is False -Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. + table_malnipulation (str): Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. + Return: + manifest_synapse_file_id (str): SynID of manifest csv uploaded to synapse. """ manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( se, @@ -1372,7 +1390,6 @@ def upload_manifest_combo( useSchemaLabel=useSchemaLabel, table_manipulation=table_manipulation,) - manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) # Load manifest to synapse as a CSV File @@ -1414,6 +1431,7 @@ def associateMetadataWithFiles( for downstream query and interaction with the data. Args: + schemaGenerator: SchemaGenerator Object metadataManifestPath: path to csv containing a validated metadata manifest. The manifest should include a column entityId containing synapse IDs of files/entities to be associated with metadata, if that is applicable to the dataset type. Some datasets, e.g. clinical data, do not contain file id's, but data is stored in a table: one row per item. @@ -1426,8 +1444,6 @@ def associateMetadataWithFiles( table_malnipulation (str): Default is 'replace'. Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. Returns: manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. - - """ # Read new manifest CSV: From 112f91cfd70d907ce2e556c655d33262f4a6571d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 12:13:01 -0700 Subject: [PATCH 204/615] add time logging to commands.py --- schematic/models/commands.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index e9e927136..43f7893a9 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -15,6 +15,7 @@ from schematic.exceptions import MissingConfigValueError from schematic import CONFIG +import time logger = logging.getLogger(__name__) click_log.basic_config(logger) @@ -108,7 +109,7 @@ def submit_manifest( """ Running CLI with manifest validation (optional) and submission options. """ - + jsonld = get_from_config(CONFIG.DATA, ("model", "input", "location")) model_file_type = get_from_config(CONFIG.DATA, ("model", "input", "file_type")) @@ -137,6 +138,7 @@ def submit_manifest( f"with dataset '{dataset_id}'." ) + # prototype based on validateModelManifest() @model.command( "validate", @@ -197,7 +199,7 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules ("model", "input", "validation_schema"), allow_none=True, ) - + t = time.time() jsonld = get_from_config(CONFIG.DATA, ("model", "input", "location")) model_file_type = get_from_config(CONFIG.DATA, ("model", "input", "file_type")) @@ -218,3 +220,7 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules ) else: click.echo(errors) + + logger.info( + f"Total elapsed time {time.time()-t} seconds" + ) From beb2526fa98b1b8edba57e172964f85ac7bae1dc Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 12:13:38 -0700 Subject: [PATCH 205/615] add time logging to validate_manifest_rules --- schematic/models/validate_manifest.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 708c7033f..7e101433c 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -24,6 +24,8 @@ from schematic.utils.validate_rules_utils import validation_rule_info from schematic.utils.validate_utils import rule_in_rule_list + +from time import time logger = logging.getLogger(__name__) class ValidateManifest(object): @@ -125,6 +127,7 @@ def validate_manifest_rules( warnings = [] if not restrict_rules: + t_GE = time() #operations necessary to set up and run ge suite validation ge_helpers=GreatExpectationsHelpers( sg=sg, @@ -162,13 +165,15 @@ def validate_manifest_rules( validation_results = validation_results, validation_types = validation_types, sg = sg, - ) + ) + logging.info(f"GE Elaplsed time {time()-t_GE}") else: - logging.info("Great Expetations suite will not be utilized.") - + logger.info("Great Expetations suite will not be utilized.") + t_err=time() regex_re=re.compile('regex.*') for col in manifest.columns: + # remove trailing/leading whitespaces from manifest manifest.applymap(lambda x: x.strip() if isinstance(x, str) else x) validation_rules = sg.get_node_validation_rules(col) @@ -188,7 +193,7 @@ def validate_manifest_rules( validation_type = rule.split(" ")[0] if rule_in_rule_list(rule,unimplemented_expectations) or (rule_in_rule_list(rule,in_house_rules) and restrict_rules): if not rule_in_rule_list(rule,in_house_rules): - logging.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") + logger.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") continue #Validate for each individual validation rule. @@ -214,7 +219,7 @@ def validate_manifest_rules( errors.extend(vr_errors) if vr_warnings: warnings.extend(vr_warnings) - + logging.info(f"Errors elapsed time {time()-t_err}") return manifest, errors, warnings def validate_manifest_values(self, manifest, jsonSchema, sg From 14ccaf3edf9c0ac823076d00b3028c7268c13472 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 12:14:02 -0700 Subject: [PATCH 206/615] add time logging to load_df --- schematic/utils/df_utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index fc0f6f48e..de05d0a66 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -5,7 +5,7 @@ from copy import deepcopy import dateparser as dp import datetime as dt - +from time import time logger = logging.getLogger(__name__) @@ -23,13 +23,15 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): Returns: a processed dataframe for manifests or unprocessed df for data models """ #Read CSV to df as type specified in kwargs + t_load_df = time() org_df = pd.read_csv(file_path, keep_default_na = True, encoding='utf8', **load_args) if preserve_raw_input: #only trim if not data model csv if not data_model: org_df=trim_commas_df(org_df) - + + logging.info(f"Load Eplased time {time()-t_load_df}") return org_df else: @@ -51,6 +53,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): #Store values that were entered as ints and dates processed_df=processed_df.mask(ints != False, other = ints) + logging.info(f"Load Eplased time {time()-t_load_df}") return processed_df From d9d8276ed667c25aab43806847b63ed9a754bf10 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 7 Mar 2023 14:18:22 -0500 Subject: [PATCH 207/615] add param to control if GE gets used --- api/openapi/api.yaml | 7 +++++++ api/routes.py | 8 ++++++-- tests/test_api.py | 6 ++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 327cc6ad9..d1d1570c3 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -185,6 +185,13 @@ paths: description: Data Model Component example: Patient required: true + - in: query + name: restrict_rules + schema: + type: boolean + default: false + description: If True, validation suite will only run with in-house validation rule. If False, the Great Expectations suite will be utilized and all rules will be available. + required: false - in: query name: json_str required: false diff --git a/api/routes.py b/api/routes.py index 40f32f2eb..7b45df5ce 100644 --- a/api/routes.py +++ b/api/routes.py @@ -330,10 +330,14 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None return all_results -def validate_manifest_route(schema_url, data_type, json_str=None): +def validate_manifest_route(schema_url, data_type, restrict_rules=None, json_str=None): # call config_handler() config_handler() + #If restrict_rules parameter is set to None, then default it to False + if not restrict_rules: + restrict_rules = False + #Get path to temp file where manifest file contents will be saved jsc = JsonConverter() @@ -350,7 +354,7 @@ def validate_manifest_route(schema_url, data_type, json_str=None): ) errors, warnings = metadata_model.validateModelManifest( - manifestPath=temp_path, rootNode=data_type + manifestPath=temp_path, rootNode=data_type, restrict_rules=restrict_rules ) res_dict = {"errors": errors, "warnings": warnings} diff --git a/tests/test_api.py b/tests/test_api.py index 0c9359a05..b0ddbb7f5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -455,12 +455,14 @@ def test_populate_manifest(self, client, data_model_jsonld, test_manifest_csv): # should return a list with one google sheet link assert isinstance(response_dt[0], str) assert response_dt[0].startswith("https://docs.google.com/") - + + @pytest.mark.parametrize("restrict_rules", [False, True, None]) @pytest.mark.parametrize("json_str", [None, '[{"Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung"}]']) - def test_validate_manifest(self, data_model_jsonld, client, json_str, test_manifest_csv, test_manifest_json): + def test_validate_manifest(self, data_model_jsonld, client, json_str, restrict_rules, test_manifest_csv): params = { "schema_url": data_model_jsonld, + "restrict_rules": restrict_rules } if json_str: From 5e0ecee03258cc34af5b0761ed7e5138063b4cb6 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 7 Mar 2023 14:34:14 -0500 Subject: [PATCH 208/615] added restrict rules param --- schematic_api/api/openapi/api.yaml | 6 ++++++ schematic_api/api/routes.py | 6 +++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index 7abdca856..b9344157d 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -185,6 +185,12 @@ paths: description: Data Model Component example: Patient required: true + - in: query + name: restrict_rules + schema: + type: boolean + default: false + description: If True, validation suite will only run with in-house validation rule. If False, the Great Expectations suite will be utilized and all rules will be available. - in: query name: json_str required: false diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 3720d0f08..27dc67055 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -394,7 +394,11 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None #####profile validate manifest route function #@profile(sort_by='cumulative', strip_dirs=True) -def validate_manifest_route(schema_url, data_type, json_str=None): +def validate_manifest_route(schema_url, data_type, restrict_rules=None, json_str=None): + # if restrict rules is set to None, default it to False + if not restrict_rules: + restrict_rules=False + # call config_handler() config_handler() From c40cfd883b9e78fe026e56be3074386900f0d711 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:05:53 -0700 Subject: [PATCH 209/615] set root logger in `models.commands` --- schematic/models/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index e9e927136..5133695f0 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -15,7 +15,7 @@ from schematic.exceptions import MissingConfigValueError from schematic import CONFIG -logger = logging.getLogger(__name__) +logger = logging.getLogger() click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options From def0f2a6e3f6a136371f129b6ba6980aac52e318 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:06:29 -0700 Subject: [PATCH 210/615] set root logger in `manifest.commands` --- schematic/manifest/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index 7107a0aff..a6a85e9fe 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -15,7 +15,7 @@ from schematic.utils.google_api_utils import export_manifest_csv, export_manifest_excel, export_manifest_drive_service from schematic.store.synapse import SynapseStorage -logger = logging.getLogger(__name__) +logger = logging.getLogger() click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options From eaf889e3fa3a1e9df8fc1052c4524d56bd03d0a3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 13:06:54 -0700 Subject: [PATCH 211/615] set root logger in `schemas.commands` --- schematic/schemas/commands.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/schemas/commands.py b/schematic/schemas/commands.py index 3e4ee7b8c..c43527029 100644 --- a/schematic/schemas/commands.py +++ b/schematic/schemas/commands.py @@ -10,7 +10,7 @@ from schematic.utils.cli_utils import query_dict from schematic.help import schema_commands -logger = logging.getLogger(__name__) +logger = logging.getLogger() click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options From da982f42fca63a0e6c68b1558db7dd26a9a9c270 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:10:40 -0700 Subject: [PATCH 212/615] set logger name/scope to `schematic` --- schematic/manifest/commands.py | 2 +- schematic/models/commands.py | 2 +- schematic/schemas/commands.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index a6a85e9fe..975e8ddae 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -15,7 +15,7 @@ from schematic.utils.google_api_utils import export_manifest_csv, export_manifest_excel, export_manifest_drive_service from schematic.store.synapse import SynapseStorage -logger = logging.getLogger() +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 5133695f0..c4a96509c 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -15,7 +15,7 @@ from schematic.exceptions import MissingConfigValueError from schematic import CONFIG -logger = logging.getLogger() +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options diff --git a/schematic/schemas/commands.py b/schematic/schemas/commands.py index c43527029..13ff2e2c2 100644 --- a/schematic/schemas/commands.py +++ b/schematic/schemas/commands.py @@ -10,7 +10,7 @@ from schematic.utils.cli_utils import query_dict from schematic.help import schema_commands -logger = logging.getLogger() +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options From cc3fa5cecef45522d4e0f29d697d0b20274110e2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:18:45 -0700 Subject: [PATCH 213/615] switch from `info` to `debug` log level for time --- schematic/models/commands.py | 2 +- schematic/models/validate_manifest.py | 4 ++-- schematic/utils/df_utils.py | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 43f7893a9..8bcb7e031 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -221,6 +221,6 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules else: click.echo(errors) - logger.info( + logger.debug( f"Total elapsed time {time.time()-t} seconds" ) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 7e101433c..c38ee0718 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -166,7 +166,7 @@ def validate_manifest_rules( validation_types = validation_types, sg = sg, ) - logging.info(f"GE Elaplsed time {time()-t_GE}") + logger.debug(f"GE Elaplsed time {time()-t_GE}") else: logger.info("Great Expetations suite will not be utilized.") @@ -219,7 +219,7 @@ def validate_manifest_rules( errors.extend(vr_errors) if vr_warnings: warnings.extend(vr_warnings) - logging.info(f"Errors elapsed time {time()-t_err}") + logger.debug(f"Errors elapsed time {time()-t_err}") return manifest, errors, warnings def validate_manifest_values(self, manifest, jsonSchema, sg diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index de05d0a66..327e8ffc4 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -31,7 +31,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): if not data_model: org_df=trim_commas_df(org_df) - logging.info(f"Load Eplased time {time()-t_load_df}") + logger.debug(f"Load Eplased time {time()-t_load_df}") return org_df else: @@ -53,7 +53,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): #Store values that were entered as ints and dates processed_df=processed_df.mask(ints != False, other = ints) - logging.info(f"Load Eplased time {time()-t_load_df}") + logger.debug(f"Load Eplased time {time()-t_load_df}") return processed_df From 89a9783c67a9b4605dca21cb43135af4ab2bca40 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:20:00 -0700 Subject: [PATCH 214/615] change scope of logger init from cli changes will be merged to develop in separate PR --- schematic/manifest/commands.py | 2 +- schematic/models/commands.py | 2 +- schematic/schemas/commands.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index 7107a0aff..975e8ddae 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -15,7 +15,7 @@ from schematic.utils.google_api_utils import export_manifest_csv, export_manifest_excel, export_manifest_drive_service from schematic.store.synapse import SynapseStorage -logger = logging.getLogger(__name__) +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 8bcb7e031..e51045557 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -16,7 +16,7 @@ from schematic import CONFIG import time -logger = logging.getLogger(__name__) +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options diff --git a/schematic/schemas/commands.py b/schematic/schemas/commands.py index 3e4ee7b8c..13ff2e2c2 100644 --- a/schematic/schemas/commands.py +++ b/schematic/schemas/commands.py @@ -10,7 +10,7 @@ from schematic.utils.cli_utils import query_dict from schematic.help import schema_commands -logger = logging.getLogger(__name__) +logger = logging.getLogger('schematic') click_log.basic_config(logger) CONTEXT_SETTINGS = dict(help_option_names=["--help", "-h"]) # help options From ef57e241517fdbb7db109196373b81a26ad3db73 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:57:21 -0700 Subject: [PATCH 215/615] add time for in house and indiv rules --- schematic/models/validate_manifest.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index c38ee0718..1ad35c9a0 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -196,6 +196,7 @@ def validate_manifest_rules( logger.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") continue + t_indiv_rule=time() #Validate for each individual validation rule. validation_method = getattr( ValidateAttribute, validation_types[validation_type]['type'] @@ -219,7 +220,8 @@ def validate_manifest_rules( errors.extend(vr_errors) if vr_warnings: warnings.extend(vr_warnings) - logger.debug(f"Errors elapsed time {time()-t_err}") + logger.debug(f"Rule {rule} elapsed time: {time()-t_indiv_rule}") + logger.debug(f"In House validation elapsed time {time()-t_err}") return manifest, errors, warnings def validate_manifest_values(self, manifest, jsonSchema, sg From 498037b0051334b307104f9c778de675713796b5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:02:24 -0700 Subject: [PATCH 216/615] utilize `perf_counter` --- schematic/models/commands.py | 6 +++--- schematic/models/validate_manifest.py | 14 +++++++------- schematic/utils/df_utils.py | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index e51045557..6aaf8020a 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -15,7 +15,7 @@ from schematic.exceptions import MissingConfigValueError from schematic import CONFIG -import time +from time import perf_counter logger = logging.getLogger('schematic') click_log.basic_config(logger) @@ -199,7 +199,7 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules ("model", "input", "validation_schema"), allow_none=True, ) - t = time.time() + t_validate = perf_counter() jsonld = get_from_config(CONFIG.DATA, ("model", "input", "location")) model_file_type = get_from_config(CONFIG.DATA, ("model", "input", "file_type")) @@ -222,5 +222,5 @@ def validate_manifest(ctx, manifest_path, data_type, json_schema, restrict_rules click.echo(errors) logger.debug( - f"Total elapsed time {time.time()-t} seconds" + f"Total elapsed time {perf_counter()-t_validate} seconds" ) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 1ad35c9a0..e07790e89 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -25,7 +25,7 @@ from schematic.utils.validate_utils import rule_in_rule_list -from time import time +from time import perf_counter logger = logging.getLogger(__name__) class ValidateManifest(object): @@ -127,7 +127,7 @@ def validate_manifest_rules( warnings = [] if not restrict_rules: - t_GE = time() + t_GE = perf_counter() #operations necessary to set up and run ge suite validation ge_helpers=GreatExpectationsHelpers( sg=sg, @@ -166,11 +166,11 @@ def validate_manifest_rules( validation_types = validation_types, sg = sg, ) - logger.debug(f"GE Elaplsed time {time()-t_GE}") + logger.debug(f"GE Elaplsed time {perf_counter()-t_GE}") else: logger.info("Great Expetations suite will not be utilized.") - t_err=time() + t_err=perf_counter() regex_re=re.compile('regex.*') for col in manifest.columns: @@ -196,7 +196,7 @@ def validate_manifest_rules( logger.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") continue - t_indiv_rule=time() + t_indiv_rule=perf_counter() #Validate for each individual validation rule. validation_method = getattr( ValidateAttribute, validation_types[validation_type]['type'] @@ -220,8 +220,8 @@ def validate_manifest_rules( errors.extend(vr_errors) if vr_warnings: warnings.extend(vr_warnings) - logger.debug(f"Rule {rule} elapsed time: {time()-t_indiv_rule}") - logger.debug(f"In House validation elapsed time {time()-t_err}") + logger.debug(f"Rule {rule} elapsed time: {perf_counter()-t_indiv_rule}") + logger.debug(f"In House validation elapsed time {perf_counter()-t_err}") return manifest, errors, warnings def validate_manifest_values(self, manifest, jsonSchema, sg diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 327e8ffc4..556f9f03a 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -5,7 +5,7 @@ from copy import deepcopy import dateparser as dp import datetime as dt -from time import time +from time import perf_counter logger = logging.getLogger(__name__) @@ -23,7 +23,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): Returns: a processed dataframe for manifests or unprocessed df for data models """ #Read CSV to df as type specified in kwargs - t_load_df = time() + t_load_df = perf_counter() org_df = pd.read_csv(file_path, keep_default_na = True, encoding='utf8', **load_args) if preserve_raw_input: @@ -31,7 +31,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): if not data_model: org_df=trim_commas_df(org_df) - logger.debug(f"Load Eplased time {time()-t_load_df}") + logger.debug(f"Load Eplased time {perf_counter()-t_load_df}") return org_df else: @@ -53,7 +53,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): #Store values that were entered as ints and dates processed_df=processed_df.mask(ints != False, other = ints) - logger.debug(f"Load Eplased time {time()-t_load_df}") + logger.debug(f"Load Eplased time {perf_counter()-t_load_df}") return processed_df From d63e980d6fed0f50ec5e4891f964dfd3080af0a7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 7 Mar 2023 16:09:01 -0700 Subject: [PATCH 217/615] add timing to cross manifest functions --- schematic/models/validate_attribute.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 0f133793c..0ebb32c5c 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -22,6 +22,9 @@ from schematic.utils.validate_utils import (comma_separated_list_regex, parse_str_series_to_list) + +from time import perf_counter + logger = logging.getLogger(__name__) class GenerateError: @@ -543,7 +546,7 @@ class ValidateAttribute(object): """ def get_target_manifests(target_component, project_scope: List): - + t_manifest_search = perf_counter() target_manifest_IDs=[] target_dataset_IDs=[] @@ -567,6 +570,7 @@ def get_target_manifests(target_component, project_scope: List): target_manifest_IDs.append(target_dataset[1][0]) target_dataset_IDs.append(target_dataset[0][0]) + logger.debug(f"Cross manifest gathering elapsed time {perf_counter()-t_manifest_search}") return synStore, target_manifest_IDs, target_dataset_IDs def list_validation( @@ -900,6 +904,7 @@ def cross_validation( #Get IDs of manifests with target component synStore, target_manifest_IDs, target_dataset_IDs = ValidateAttribute.get_target_manifests(target_component,project_scope) + t_cross_manifest = perf_counter() #Read each manifest for target_manifest_ID, target_dataset_ID in zip(target_manifest_IDs,target_dataset_IDs): entity = synStore.getDatasetManifest( @@ -1016,6 +1021,7 @@ def cross_validation( warnings.append(vr_warnings) + logger.debug(f"cross manfiest validation time {perf_counter()-t_cross_manifest}") return errors, warnings From b85144d21fe8fbd345a6ae52cd68bfb74da3c13d Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 8 Mar 2023 12:06:34 -0800 Subject: [PATCH 218/615] fix typo --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 91f3daada..2d46bef62 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,7 +263,7 @@ paths: name: manifest_record_type schema: type: string - enum: ["table", "file", "file_w_entites", "combo"] + enum: ["table", "file", "file_w_entities", "combo"] description: Manifest storage type. example: 'table' - in: query From 1b68bb31ad200d0c755643fd0b9691ad26a953e4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 09:31:07 -0700 Subject: [PATCH 219/615] update tests to ensure correct error format --- tests/test_validation.py | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 0466a79a9..26162ed76 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -76,17 +76,17 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): assert GenerateError.generate_type_error( val_rule = 'int', - row_num = 3, + row_num = '3', attribute_name = 'Check Int', - invalid_entry = 5.63, + invalid_entry = '5.63', sg = sg, )[0] in errors assert GenerateError.generate_type_error( val_rule = 'str', - row_num = 3, + row_num = '3', attribute_name = 'Check String', - invalid_entry = 94, + invalid_entry = '94', sg = sg, )[0] in errors @@ -145,7 +145,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'date', attribute_name = 'Check Date', sg = sg, - row_num = [2,3,4], + row_num = ['2','3','4'], error_val = ['84-43-094', '32-984', 'notADate'], )[0] in errors @@ -153,7 +153,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'unique error', attribute_name = 'Check Unique', sg = sg, - row_num = [2,3,4], + row_num = ['2','3','4'], error_val = ['str1'], )[0] in errors @@ -161,8 +161,8 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'inRange 50 100 error', attribute_name = 'Check Range', sg = sg, - row_num = [3], - error_val = [30], + row_num = ['3'], + error_val = ['30'], )[0] in errors #check warnings @@ -176,8 +176,8 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'protectAges', attribute_name = 'Check Ages', sg = sg, - row_num = [2,3], - error_val = [6549,32851], + row_num = ['2','3'], + error_val = ['6549','32851'], )[1] in warnings assert GenerateError.generate_cross_warning( @@ -193,7 +193,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'matchAtLeastOne MockComponent.checkMatchatLeastvalues value', row_num = '[3]', attribute_name = 'Check Match at Least values', - invalid_entry = '[51100]', + invalid_entry = ['51100'], sg = sg, )[1] in warnings @@ -214,9 +214,9 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): assert GenerateError.generate_cross_warning( val_rule = 'matchExactlyOne MockComponent.checkMatchExactlyvalues MockComponent.checkMatchExactlyvalues value', - row_num = '[2, 3, 4]', + row_num = ['2', '3', '4'], attribute_name='Check Match Exactly values', - invalid_entry = '[71738, 98085, 210065]', + invalid_entry = ['71738', '98085', '210065'], sg = sg, )[1] in warnings @@ -314,16 +314,16 @@ def test_in_house_validation(self,helpers,sg,metadataModel): val_rule = 'matchAtLeastOne', row_num = '[3]', attribute_name='Check Match at Least', - invalid_entry = '[7163]', + invalid_entry = ['7163'], missing_manifest_ID = ['syn27600110', 'syn29381803'], sg = sg, )[1] in warnings assert GenerateError.generate_cross_warning( val_rule = 'matchAtLeastOne MockComponent.checkMatchatLeastvalues value', - row_num = '[3]', + row_num = ['3'], attribute_name = 'Check Match at Least values', - invalid_entry = '[51100]', + invalid_entry = ['51100'], sg = sg, )[1] in warnings @@ -344,9 +344,9 @@ def test_in_house_validation(self,helpers,sg,metadataModel): assert GenerateError.generate_cross_warning( val_rule = 'matchExactlyOne MockComponent.checkMatchExactlyvalues MockComponent.checkMatchExactlyvalues value', - row_num = '[2, 3, 4]', + row_num = ['2', '3', '4'], attribute_name='Check Match Exactly values', - invalid_entry = '[71738, 98085, 210065]', + invalid_entry = ['71738', '98085', '210065'], sg = sg, )[1] in warnings From 3db78057f8ce56ea76b4a1ca94899b6f537a2f14 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 09:38:21 -0700 Subject: [PATCH 220/615] update missed input --- tests/test_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 26162ed76..36e51a137 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -312,7 +312,7 @@ def test_in_house_validation(self,helpers,sg,metadataModel): #Check Warnings assert GenerateError.generate_cross_warning( val_rule = 'matchAtLeastOne', - row_num = '[3]', + row_num = ['3'], attribute_name='Check Match at Least', invalid_entry = ['7163'], missing_manifest_ID = ['syn27600110', 'syn29381803'], From 8bce116da0a10da2ce96d3162a7c5d1dc0b6c986 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:50:37 -0700 Subject: [PATCH 221/615] add functions to parse error parts apporpriately --- schematic/utils/validate_utils.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/schematic/utils/validate_utils.py b/schematic/utils/validate_utils.py index 3b2fbf022..5264d73da 100644 --- a/schematic/utils/validate_utils.py +++ b/schematic/utils/validate_utils.py @@ -5,6 +5,7 @@ from schematic.utils.io_utils import load_json from schematic import CONFIG, LOADER from typing import List +import numpy as np def validate_schema(schema): """Validate schema against schema.org standard""" @@ -65,4 +66,20 @@ def parse_str_series_to_list(col: pd.Series): lambda x: [s.strip() for s in str(x).split(",")] ) - return col \ No newline at end of file + return col + +def np_array_to_str_list(np_array): + """ + Parse a numpy array of ints to a list of strings + """ + return np.char.mod('%d', np_array).tolist() + +def iterable_to_str_list(iterable): + "Parse an iterable into a list of strings" + strlist = [] + + for element in iterable: + strlist.append(str(element)) + + return strlist + \ No newline at end of file From 555dc22b3062042b506f9fc66d20de0a093614dd Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:51:26 -0700 Subject: [PATCH 222/615] generate cross manifest warnings according to standard --- schematic/models/validate_attribute.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 0f133793c..42466af5d 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -20,7 +20,10 @@ from schematic.store.synapse import SynapseStorage from schematic.utils.validate_rules_utils import validation_rule_info from schematic.utils.validate_utils import (comma_separated_list_regex, - parse_str_series_to_list) + parse_str_series_to_list, + np_array_to_str_list, + iterable_to_str_list, + ) logger = logging.getLogger(__name__) @@ -950,11 +953,12 @@ def cross_validation( if val_rule.__contains__('matchAtLeastOne') and not missing_values.empty: missing_rows = missing_values.index.to_numpy() + 2 + missing_rows = np_array_to_str_list(missing_rows) vr_errors, vr_warnings = GenerateError.generate_cross_warning( val_rule = val_rule, - row_num = str(list(missing_rows)), + row_num = missing_rows, attribute_name = source_attribute, - invalid_entry = str(missing_values.values.tolist()), + invalid_entry = iterable_to_str_list(missing_values), sg = sg, ) if vr_errors: @@ -964,11 +968,12 @@ def cross_validation( elif val_rule.__contains__('matchExactlyOne') and (duplicated_values.any() or missing_values.any()): invalid_values = pd.merge(duplicated_values,missing_values,how='outer') invalid_rows = pd.merge(duplicated_values,missing_values,how='outer',left_index=True,right_index=True).index.to_numpy() + 2 + invalid_rows = np_array_to_str_list(invalid_rows) vr_errors, vr_warnings = GenerateError.generate_cross_warning( val_rule = val_rule, - row_num = str(list(invalid_rows)), + row_num = invalid_rows, attribute_name = source_attribute, - invalid_entry = str(pd.Series(invalid_values.squeeze()).values.tolist()), + invalid_entry = iterable_to_str_list(invalid_values.squeeze()), sg = sg, ) if vr_errors: @@ -987,15 +992,14 @@ def cross_validation( missing_rows.append(missing_entry.index[0]+2) missing_values.append(missing_entry.values[0]) - missing_rows=list(set(missing_rows)) - missing_values=list(set(missing_values)) - #print(missing_rows,missing_values) - + missing_rows=iterable_to_str_list(set(missing_rows)) + missing_values=iterable_to_str_list(set(missing_values)) + vr_errors, vr_warnings = GenerateError.generate_cross_warning( val_rule = val_rule, - row_num = str(missing_rows), + row_num = missing_rows, attribute_name = source_attribute, - invalid_entry = str(missing_values), + invalid_entry = missing_values, missing_manifest_ID = missing_manifest_IDs, sg = sg, ) From 8bda43075c82cb0e61909fddbc9240d805aeb790 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:52:23 -0700 Subject: [PATCH 223/615] make list error row string --- schematic/models/validate_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 708c7033f..bce019d63 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -233,7 +233,7 @@ def validate_manifest_values(self, manifest, jsonSchema, sg for i, annotation in enumerate(annotations): v = Draft7Validator(jsonSchema) for error in sorted(v.iter_errors(annotation), key=exceptions.relevance): - errorRow = i + 2 + errorRow = str(i + 2) errorCol = error.path[-1] if len(error.path) > 0 else "Wrong schema" errorColName = error.path[0] if len(error.path) > 0 else "Wrong schema" errorMsg = error.message[0:500] From e9ca8f66ba9676561cc9be26eb11d6c90dd3a2d0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 10:55:50 -0700 Subject: [PATCH 224/615] fix missed input change to type string --- tests/test_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 36e51a137..4204df0fb 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -68,7 +68,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): #Check errors assert GenerateError.generate_type_error( val_rule = 'num', - row_num = 3, + row_num = '3', attribute_name = 'Check Num', invalid_entry = 'c', sg = sg, From 1aa6e6781f33bb296acec03c734d445c650e6f45 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:15:03 -0700 Subject: [PATCH 225/615] cast type error row and entries to str --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index afbe98ba3..8ea001555 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -434,9 +434,9 @@ def generate_errors( for row, value in zip(indices,values): vr_errors, vr_warnings = GenerateError.generate_type_error( val_rule = rule, - row_num = row+2, + row_num = str(row+2), attribute_name = errColumn, - invalid_entry = value, + invalid_entry = str(value), sg = sg, ) if vr_errors: From 277ddc13e83e29db0d28f637ed6a279c39b41016 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:15:17 -0700 Subject: [PATCH 226/615] cast regex error row to str --- schematic/models/GE_Helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 8ea001555..74677df02 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -449,7 +449,7 @@ def generate_errors( vr_errors, vr_warnings = GenerateError.generate_regex_error( val_rule= rule, reg_expression = expression, - row_num = row+2, + row_num = str(row+2), module_to_call = 'match', attribute_name = errColumn, invalid_entry = value, From 4755a6aeee4b744594aeaf3e6ce24c1c0c59b789 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:15:50 -0700 Subject: [PATCH 227/615] cast content error rows to type str update age censoring mechanism to account for str values --- schematic/models/GE_Helpers.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 74677df02..aee9a90dd 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -26,7 +26,7 @@ from schematic.models.validate_attribute import GenerateError from schematic.schemas.generator import SchemaGenerator -from schematic.utils.validate_utils import rule_in_rule_list +from schematic.utils.validate_utils import rule_in_rule_list, np_array_to_str_list logger = logging.getLogger(__name__) @@ -463,7 +463,7 @@ def generate_errors( vr_errors, vr_warnings = GenerateError.generate_content_error( val_rule = rule, attribute_name = errColumn, - row_num = list(np.array(indices)+2), + row_num = np_array_to_str_list(np.array(indices)+2), error_val = values, sg = self.sg ) @@ -515,10 +515,13 @@ def censor_ages( name of column containing ages Returns: updates self.manifest with censored ages - + TODO: Speed up conversion from str list to int list """ + censor_rows = [] - censor_rows = list(np.array(message[0]) - 2) + for row in message[0]: + censor_rows.append(int(row) - 2) + self.manifest.loc[censor_rows,(col)] = 'age censored' # update the manifest file, so that ages are censored From e57ae82a3d657a4f3ec3984968859a7ca71e968d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:22:18 -0700 Subject: [PATCH 228/615] cast content invalid values to str list --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index aee9a90dd..be9cd210c 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -26,7 +26,7 @@ from schematic.models.validate_attribute import GenerateError from schematic.schemas.generator import SchemaGenerator -from schematic.utils.validate_utils import rule_in_rule_list, np_array_to_str_list +from schematic.utils.validate_utils import rule_in_rule_list, np_array_to_str_list, iterable_to_str_list logger = logging.getLogger(__name__) @@ -464,7 +464,7 @@ def generate_errors( val_rule = rule, attribute_name = errColumn, row_num = np_array_to_str_list(np.array(indices)+2), - error_val = values, + error_val = iterable_to_str_list(values), sg = self.sg ) if vr_errors: From f2f1669acd5e258b060be267bc3cb2f890e5cd41 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:24:32 -0700 Subject: [PATCH 229/615] update missed input --- tests/test_validation.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 4204df0fb..9e23a9393 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -184,7 +184,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): val_rule = 'matchAtLeastOne', row_num = '[3]', attribute_name='Check Match at Least', - invalid_entry = '[7163]', + invalid_entry = ['7163'], missing_manifest_ID = ['syn27600110', 'syn29381803'], sg = sg, )[1] in warnings From 784d3c1aa105d37b6149f8e22626ea73bddec740 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:28:23 -0700 Subject: [PATCH 230/615] fix other missed inputs --- tests/test_validation.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 9e23a9393..531d2b354 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -182,7 +182,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): assert GenerateError.generate_cross_warning( val_rule = 'matchAtLeastOne', - row_num = '[3]', + row_num = ['3'], attribute_name='Check Match at Least', invalid_entry = ['7163'], missing_manifest_ID = ['syn27600110', 'syn29381803'], @@ -191,7 +191,7 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): assert GenerateError.generate_cross_warning( val_rule = 'matchAtLeastOne MockComponent.checkMatchatLeastvalues value', - row_num = '[3]', + row_num = ['3'], attribute_name = 'Check Match at Least values', invalid_entry = ['51100'], sg = sg, From fd6d8d7ad01b82672b3d80e8f977bb30be41f294 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 12:43:46 -0700 Subject: [PATCH 231/615] add timing for JSON Schema validation --- schematic/models/validate_manifest.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index e07790e89..255db9de9 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -226,7 +226,8 @@ def validate_manifest_rules( def validate_manifest_values(self, manifest, jsonSchema, sg ) -> (List[List[str]], List[List[str]]): - + t_json_schema = perf_counter() + errors = [] warnings = [] col_attr = {} # save the mapping between column index and attribute name @@ -252,7 +253,7 @@ def validate_manifest_values(self, manifest, jsonSchema, sg errors.append(val_errors) if val_warnings: warnings.append(val_warnings) - + logger.debug(f"JSON Schema validation elapsed time {perf_counter()-t_json_schema}") return errors, warnings From 6e72330030e4b33b81dbb31fa930ef88adafbe45 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 13:19:14 -0700 Subject: [PATCH 232/615] remove unused input --- schematic/store/synapse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 86fcd497c..a9c997d9e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -762,7 +762,6 @@ def uploadDB(self, table_name: str, restrict: bool = False, useSchemaLabel: bool = True, - existingTableId: str = None, table_manipulation: str = 'replace', ): """ From 2eaceef48c0458aff4ede9c500932b9f98a042f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 13:19:39 -0700 Subject: [PATCH 233/615] fix typo --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a9c997d9e..906d992ab 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1153,7 +1153,7 @@ def _generate_table_name(self, manifest): table_name = component_name + '_synapse_storage_manifest_table' else: component_name = '' - tabsle_name = 'synapse_storage_manifest_table' + table_name = 'synapse_storage_manifest_table' return table_name, component_name def _add_annotations(self, se, schemaGenerator, row, entityId, useSchemaLabel, hideBlanks): From f6276bb6f50750e9e6eb462dc18de95c95ae3b52 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 9 Mar 2023 20:50:04 -0800 Subject: [PATCH 234/615] fix mrt reference --- tests/test_store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 22ef594ed..908e0689f 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -125,7 +125,7 @@ def test_annotation_submission(self, synapse_store, helpers, config): schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = 'syn34295552', - manifest_record_type = 'entity', + manifest_record_type = 'file_w_entities', useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, From c8d2fedc1b905166f9bebfe139c525b14cdad7d2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 09:40:26 -0700 Subject: [PATCH 235/615] fix typo in debug message --- schematic/models/validate_attribute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 0ebb32c5c..9047d2e8d 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -1021,7 +1021,7 @@ def cross_validation( warnings.append(vr_warnings) - logger.debug(f"cross manfiest validation time {perf_counter()-t_cross_manifest}") + logger.debug(f"cross manifest validation time {perf_counter()-t_cross_manifest}") return errors, warnings From 2892793b48c73bb50f4dc3090d73b2edfe5c5ebb Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 09:41:12 -0700 Subject: [PATCH 236/615] fix type in GE debug message --- schematic/models/validate_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 255db9de9..cba4f365b 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -166,7 +166,7 @@ def validate_manifest_rules( validation_types = validation_types, sg = sg, ) - logger.debug(f"GE Elaplsed time {perf_counter()-t_GE}") + logger.debug(f"GE elapsed time {perf_counter()-t_GE}") else: logger.info("Great Expetations suite will not be utilized.") From aa742e927a3d0c417db40f0c3c212da17ef7bf49 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:11:59 -0700 Subject: [PATCH 237/615] log validation messages to correct logger --- schematic/models/validate_attribute.py | 30 +++++++++++++------------- schematic/models/validate_manifest.py | 8 +++---- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 0f133793c..56af9eba7 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -48,7 +48,7 @@ def generate_schema_error(row_num: str, attribute_name: str, error_msg: str, inv #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -82,7 +82,7 @@ def generate_list_error( - row_num: the row the error occurred on. - attribute_name: the attribute the error occurred on. Returns: - Logging.error. + logger.error. Errors: List[str] Error details for further storage. """ @@ -98,7 +98,7 @@ def generate_list_error( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -143,7 +143,7 @@ def generate_regex_error( module_to_call: re module specified in the schema attribute_name: str, attribute being validated Returns: - Logging.error. + logger.error. Errors: List[str] Error details for further storage. """ error_list = [] @@ -158,7 +158,7 @@ def generate_regex_error( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -193,7 +193,7 @@ def generate_type_error( row_num: str, row where the error was detected attribute_name: str, attribute being validated Returns: - Logging.error. + logger.error. Errors: List[str] Error details for further storage. """ @@ -209,7 +209,7 @@ def generate_type_error( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -257,7 +257,7 @@ def generate_url_error( attribute_name: str, attribute being validated argument: str, argument being validated. Returns: - Logging.error. + logger.error. Errors: List[str] Error details for further storage. """ @@ -273,7 +273,7 @@ def generate_url_error( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -337,7 +337,7 @@ def generate_cross_warning( invalid_entry: str, value present in source manifest that is missing in the target row_num: row in source manifest with value missing in target manifests Returns: - Logging.error. + logger.error. Errors: List[str] Error details for further storage. """ error_list = [] @@ -352,7 +352,7 @@ def generate_cross_warning( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -415,7 +415,7 @@ def generate_content_error( error_val: value duplicated Returns: - Logging.error or Logging.warning. + logger.error or logger.warning. Message: List[str] Error|Warning details for further storage. """ error_list = [] @@ -431,7 +431,7 @@ def generate_content_error( #if a message needs to be raised, get the approrpiate function to do so if raises: - logLevel = getattr(logging,raises) + logLevel = getattr(logger,raises) else: return error_list, warning_list @@ -644,7 +644,7 @@ def regex_validation( Returns: - This function will return errors when the user input value does not match schema specifications. - Logging.error. + logger.error. Errors: List[str] Error details for further storage. TODO: move validation to convert step. @@ -728,7 +728,7 @@ def type_validation( Returns: -This function will return errors when the user input value does not match schema specifications. - Logging.error. + logger.error. Errors: List[str] Error details for further storage. TODO: Convert all inputs to .lower() just to prevent any entry errors. diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index 708c7033f..4a0cb455d 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -47,7 +47,7 @@ def get_multiple_types_error( f"For attribute {attribute_name}, the provided validation rules ({validation_rules}) ." f"have too many entries. We currently only specify two rules ('list :: another_rule')." ) - logging.error(error_str) + logger.error(error_str) error_message = error_str error_val = f"Multiple Rules: too many rules" if error_type == "list_not_first": @@ -55,7 +55,7 @@ def get_multiple_types_error( f"For attribute {attribute_name}, the provided validation rules ({validation_rules}) are improperly " f"specified. 'list' must be first." ) - logging.error(error_str) + logger.error(error_str) error_message = error_str error_val = f"Multiple Rules: list not first" return ["NA", error_col, error_message, error_val] @@ -164,7 +164,7 @@ def validate_manifest_rules( sg = sg, ) else: - logging.info("Great Expetations suite will not be utilized.") + logger.info("Great Expetations suite will not be utilized.") regex_re=re.compile('regex.*') @@ -188,7 +188,7 @@ def validate_manifest_rules( validation_type = rule.split(" ")[0] if rule_in_rule_list(rule,unimplemented_expectations) or (rule_in_rule_list(rule,in_house_rules) and restrict_rules): if not rule_in_rule_list(rule,in_house_rules): - logging.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") + logger.warning(f"Validation rule {rule.split(' ')[0]} has not been implemented in house and cannnot be validated without Great Expectations.") continue #Validate for each individual validation rule. From 9afb46268db76a46eed6f1336c878987e36cbf7b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 10:15:01 -0700 Subject: [PATCH 238/615] update docstrings --- schematic/models/validate_attribute.py | 38 ++++++++++++++++---------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 56af9eba7..341b47616 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -82,8 +82,9 @@ def generate_list_error( - row_num: the row the error occurred on. - attribute_name: the attribute the error occurred on. Returns: - logger.error. - Errors: List[str] Error details for further storage. + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] @@ -143,8 +144,9 @@ def generate_regex_error( module_to_call: re module specified in the schema attribute_name: str, attribute being validated Returns: - logger.error. - Errors: List[str] Error details for further storage. + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] warning_list = [] @@ -193,8 +195,9 @@ def generate_type_error( row_num: str, row where the error was detected attribute_name: str, attribute being validated Returns: - logger.error. - Errors: List[str] Error details for further storage. + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] @@ -257,8 +260,9 @@ def generate_url_error( attribute_name: str, attribute being validated argument: str, argument being validated. Returns: - logger.error. - Errors: List[str] Error details for further storage. + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] @@ -337,8 +341,9 @@ def generate_cross_warning( invalid_entry: str, value present in source manifest that is missing in the target row_num: row in source manifest with value missing in target manifests Returns: - logger.error. - Errors: List[str] Error details for further storage. + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] warning_list = [] @@ -416,7 +421,8 @@ def generate_content_error( Returns: logger.error or logger.warning. - Message: List[str] Error|Warning details for further storage. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ error_list = [] warning_list = [] @@ -580,7 +586,9 @@ def list_validation( - manifest_col: pd.core.series.Series, column for a given attribute Returns: - manifest_col: Input values in manifest arere-formatted to a list - - Error log, error list + logger.error or logger.warning. + Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. """ # For each 'list' (input as a string with a , delimiter) entered, @@ -644,8 +652,9 @@ def regex_validation( Returns: - This function will return errors when the user input value does not match schema specifications. - logger.error. + logger.error or logger.warning. Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. TODO: move validation to convert step. """ @@ -728,8 +737,9 @@ def type_validation( Returns: -This function will return errors when the user input value does not match schema specifications. - logger.error. + logger.error or logger.warning. Errors: List[str] Error details for further storage. + warnings: List[str] Warning details for further storage. TODO: Convert all inputs to .lower() just to prevent any entry errors. """ From 82c0e8dc769e6b57b5b11befe82640078d3ff9a4 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 10 Mar 2023 13:46:11 -0500 Subject: [PATCH 239/615] add restrict rules control to manifest validate --- schematic_api/api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 4626594b5..3d39c3c2d 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -419,7 +419,7 @@ def validate_manifest_route(schema_url, data_type, restrict_rules=None, json_str ) errors, warnings = metadata_model.validateModelManifest( - manifestPath=temp_path, rootNode=data_type + manifestPath=temp_path, rootNode=data_type, restrict_rules=restrict_rules ) res_dict = {"errors": errors, "warnings": warnings} From ed6ccaea501eba82db1b1d251180f536d6a86bcf Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 12:01:41 -0700 Subject: [PATCH 240/615] fix typo in `df_utils.py` --- schematic/utils/df_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 556f9f03a..745da900c 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -31,7 +31,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): if not data_model: org_df=trim_commas_df(org_df) - logger.debug(f"Load Eplased time {perf_counter()-t_load_df}") + logger.debug(f"Load Elapsed time {perf_counter()-t_load_df}") return org_df else: From fefebe702866c73549842ab5ee4699fb95ad372a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 10 Mar 2023 12:02:26 -0700 Subject: [PATCH 241/615] fix typo --- schematic/utils/df_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 745da900c..382fed34a 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -53,7 +53,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): #Store values that were entered as ints and dates processed_df=processed_df.mask(ints != False, other = ints) - logger.debug(f"Load Eplased time {perf_counter()-t_load_df}") + logger.debug(f"Load Elapsed time {perf_counter()-t_load_df}") return processed_df From 2e724906da0fda5640d8ba7785b2fe752e3a0cc8 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 10 Mar 2023 14:25:29 -0800 Subject: [PATCH 242/615] move to using more kwargs --- schematic/store/synapse.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 906d992ab..0075b2153 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1461,9 +1461,9 @@ def associateMetadataWithFiles( schemaGenerator, manifest, metadataManifestPath, - datasetId, - table_name, - component_name, + datasetId=datasetId, + table_name=table_name, + component_name=component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, @@ -1476,7 +1476,7 @@ def associateMetadataWithFiles( schemaGenerator, manifest, metadataManifestPath, - datasetId, + datasetId=datasetId, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, @@ -1491,7 +1491,7 @@ def associateMetadataWithFiles( schemaGenerator, manifest, metadataManifestPath, - datasetId, + datasetId=datasetId, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, @@ -1505,9 +1505,9 @@ def associateMetadataWithFiles( schemaGenerator, manifest, metadataManifestPath, - datasetId, - table_name, - component_name, + datasetId=datasetId, + table_name=table_name, + component_name=component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, From 8b9d791bdb2d9d546ead719035cb9726b789cbbd Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Fri, 10 Mar 2023 22:56:03 -0800 Subject: [PATCH 243/615] add additional submit manifest tests --- tests/test_api.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0c9359a05..eee206856 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -543,19 +543,50 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) @pytest.mark.parametrize("use_schema_label", ['true','false']) - def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label): + @pytest.mark.parametrize("manifest_record_type", ['table', 'file']) + def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label, manifest_record_type): params = { "input_token": syn_token, "schema_url": data_model_jsonld, "data_type": "Patient", "restrict_rules": False, - "manifest_record_type": "table", + "manifest_record_type": manifest_record_type, "asset_view": "syn44259375", "dataset_id": "syn44259313", "table_manipulation": 'replace', "use_schema_label": use_schema_label } + if json_str: + params["json_str"] = json_str + response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) + assert response.status_code == 200 + else: + headers = { + 'Content-Type': "multipart/form-data", + 'Accept': "application/json" + } + params["data_type"] = "MockComponent" + + # test uploading a csv file + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) + assert response_csv.status_code == 200 + + @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) + @pytest.mark.parametrize("manifest_record_type", ['file_w_entities', 'combo']) + def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, manifest_record_type): + params = { + "input_token": syn_token, + "schema_url": data_model_jsonld, + "data_type": "Patient", + "restrict_rules": False, + "manifest_record_type": manifest_record_type, + "asset_view": "syn44259375", + "dataset_id": "syn44259313", + "table_manipulation": 'replace', + "use_schema_label": True + } + if json_str: params["json_str"] = json_str response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) @@ -570,6 +601,7 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t # test uploading a csv file response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) assert response_csv.status_code == 200 + @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) def test_submit_manifest_upsert(self, client, syn_token, data_model_jsonld, json_str, test_upsert_manifest_csv, ): From a5d24f255fb0cefeaeaf939c18637a64be8519b7 Mon Sep 17 00:00:00 2001 From: linglp Date: Sun, 12 Mar 2023 00:40:58 -0500 Subject: [PATCH 244/615] add functions to calculate size of cache and clear cache --- schematic/store/synapse.py | 23 +++++++++++++++++++++-- schematic/utils/general.py | 30 +++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index cbe443138..73a9c4fe8 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -16,7 +16,7 @@ import re import synapseclient from time import sleep - +from ..utils.general import get_dir_size, convert_size from synapseclient import ( Synapse, File, @@ -50,6 +50,7 @@ from schematic.exceptions import MissingConfigValueError, AccessCredentialsError from schematic import CONFIG +import datetime logger = logging.getLogger(__name__) @@ -100,14 +101,32 @@ def __init__( self._query_fileview() + def _purge_synapse_cache(self): + # try clearing the cache + # scan a directory and check size of files + if os.path.exists("/var/www/.synapseCache"): + #nbytes = sum(d.stat().st_size for d in os.scandir('/var/www/.synapseCache') if d.is_file()) + nbytes = get_dir_size("/var/www/.synapseCache") + # if 19.5 GB has already been taken, purge cache prior to today + if nbytes >= 20937965568: + c = self.syn.core.cache.Cache() + today = datetime.strftime(datetime.utcnow(), '%s') + c.purge(before_date = int(today)) + else: + # print remaining ephemeral storage on AWS + remaining_space = 21474836480 - nbytes + converted_space = convert_size(remaining_space) + print(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache.') + def _query_fileview(self): + self._purge_synapse_cache() try: self.storageFileview = CONFIG["synapse"]["master_fileview"] self.manifest = CONFIG["synapse"]["manifest_basename"] if self.project_scope: self.storageFileviewTable = self.syn.tableQuery( f"SELECT * FROM {self.storageFileview} WHERE projectId IN {tuple(self.project_scope + [''])}" - ).asDataFrame() + , resultsAs="rowset").asDataFrame() else: # get data in administrative fileview for this pipeline self.storageFileviewTable = self.syn.tableQuery( diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 6c49ae7ff..a13bc18c1 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -1,6 +1,7 @@ # allows specifying explicit variable types from typing import Any, Dict, Optional, Text - +import os +import math def find_duplicates(_list): """Find duplicate items in a list""" @@ -26,3 +27,30 @@ def unlist(_list): return _list[0] else: return _list + +def get_dir_size(path='.'): + ''' + calculate total size of a directory + args: + path: path to a folder or directory + ''' + total = 0 + with os.scandir(path) as it: + for entry in it: + if entry.is_file(): + total += entry.stat().st_size + elif entry.is_dir(): + total += get_dir_size(entry.path) + return total + +def convert_size(size_bytes): + ''' + convert bytes to a human readable format + ''' + if size_bytes == 0: + return "0B" + size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") + i = int(math.floor(math.log(size_bytes, 1024))) + p = math.pow(1024, i) + s = round(size_bytes / p, 2) + return "%s %s" % (s, size_name[i]) \ No newline at end of file From 42abb84d08a39247d947b563180decaac07e365a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 09:37:59 -0700 Subject: [PATCH 245/615] re-order imports --- schematic/models/commands.py | 2 +- schematic/models/validate_attribute.py | 3 +-- schematic/models/validate_manifest.py | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 6aaf8020a..0e4754444 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -3,6 +3,7 @@ from gc import callbacks import logging import sys +from time import perf_counter import click import click_log @@ -15,7 +16,6 @@ from schematic.exceptions import MissingConfigValueError from schematic import CONFIG -from time import perf_counter logger = logging.getLogger('schematic') click_log.basic_config(logger) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index c0c3dccec..563a4559f 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -3,6 +3,7 @@ import re import sys import time +from time import perf_counter from os import getenv # allows specifying explicit variable types from typing import Any, Dict, List, Optional, Text @@ -23,8 +24,6 @@ parse_str_series_to_list) -from time import perf_counter - logger = logging.getLogger(__name__) class GenerateError: diff --git a/schematic/models/validate_manifest.py b/schematic/models/validate_manifest.py index fbbc30524..fbab2e2a6 100644 --- a/schematic/models/validate_manifest.py +++ b/schematic/models/validate_manifest.py @@ -9,6 +9,7 @@ import pandas as pd import re import sys +from time import perf_counter # allows specifying explicit variable types from typing import Any, Dict, Optional, Text, List @@ -24,8 +25,6 @@ from schematic.utils.validate_rules_utils import validation_rule_info from schematic.utils.validate_utils import rule_in_rule_list - -from time import perf_counter logger = logging.getLogger(__name__) class ValidateManifest(object): From 0a373f1dcf6634ce861861c3389595bac6e4518e Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 14:00:45 -0400 Subject: [PATCH 246/615] remove old comment and remove "rowset" option --- schematic/store/synapse.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 73a9c4fe8..d7d90eba1 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -105,7 +105,6 @@ def _purge_synapse_cache(self): # try clearing the cache # scan a directory and check size of files if os.path.exists("/var/www/.synapseCache"): - #nbytes = sum(d.stat().st_size for d in os.scandir('/var/www/.synapseCache') if d.is_file()) nbytes = get_dir_size("/var/www/.synapseCache") # if 19.5 GB has already been taken, purge cache prior to today if nbytes >= 20937965568: @@ -126,7 +125,7 @@ def _query_fileview(self): if self.project_scope: self.storageFileviewTable = self.syn.tableQuery( f"SELECT * FROM {self.storageFileview} WHERE projectId IN {tuple(self.project_scope + [''])}" - , resultsAs="rowset").asDataFrame() + ).asDataFrame() else: # get data in administrative fileview for this pipeline self.storageFileviewTable = self.syn.tableQuery( From 439a0a0ce2e6b26cdc10637de9417dd2578ea323 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 15:44:31 -0400 Subject: [PATCH 247/615] use synapse function to get root directory of synapse cache --- schematic/store/synapse.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d7d90eba1..57a18fe13 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -104,8 +104,9 @@ def __init__( def _purge_synapse_cache(self): # try clearing the cache # scan a directory and check size of files - if os.path.exists("/var/www/.synapseCache"): - nbytes = get_dir_size("/var/www/.synapseCache") + root_dir = self.syn.cache.cache_root_dir + if os.path.exists(root_dir): + nbytes = get_dir_size(root_dir) # if 19.5 GB has already been taken, purge cache prior to today if nbytes >= 20937965568: c = self.syn.core.cache.Cache() From 70ace9335f8c456a199b2a46e9410d1d270a6afb Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:01:41 -0400 Subject: [PATCH 248/615] add comment related to os.scandir --- schematic/utils/general.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index a13bc18c1..4b3966490 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -35,6 +35,8 @@ def get_dir_size(path='.'): path: path to a folder or directory ''' total = 0 + # Example usage of os.scandir could be found here: https://docs.python.org/3/library/os.html#os.scandir + # Technically, scandir.close() is called automatically. But it is still advisible to call it explicitly or use the with statement. with os.scandir(path) as it: for entry in it: if entry.is_file(): From f6e047556ee2576c94fd1ec64d6e2bf4f4941141 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:04:04 -0400 Subject: [PATCH 249/615] correct typo --- schematic/utils/general.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 4b3966490..1292ca974 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -36,7 +36,7 @@ def get_dir_size(path='.'): ''' total = 0 # Example usage of os.scandir could be found here: https://docs.python.org/3/library/os.html#os.scandir - # Technically, scandir.close() is called automatically. But it is still advisible to call it explicitly or use the with statement. + # Technically, scandir.close() is called automatically. But it is still advisable to call it explicitly or use the with statement. with os.scandir(path) as it: for entry in it: if entry.is_file(): From 8886eacc5c94904476d6eb192fff9bac64ca89c7 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:20:12 -0400 Subject: [PATCH 250/615] change parameter in get_dir_size to be optional and required --- schematic/utils/general.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 1292ca974..0f0bd1b02 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -28,7 +28,7 @@ def unlist(_list): else: return _list -def get_dir_size(path='.'): +def get_dir_size(path): ''' calculate total size of a directory args: From d7d6480cd52d70714692ca43e6c838df619a1829 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:22:25 -0400 Subject: [PATCH 251/615] use f string --- schematic/utils/general.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 0f0bd1b02..780804922 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -55,4 +55,4 @@ def convert_size(size_bytes): i = int(math.floor(math.log(size_bytes, 1024))) p = math.pow(1024, i) s = round(size_bytes / p, 2) - return "%s %s" % (s, size_name[i]) \ No newline at end of file + return f"{s} {size_name[i]})" \ No newline at end of file From 5dc4c9fa6bd24f304cf91b82951b8159a46b1e7f Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:40:44 -0400 Subject: [PATCH 252/615] add comments and typing for function convert_size --- schematic/utils/general.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 780804922..b7846af7a 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -45,14 +45,17 @@ def get_dir_size(path): total += get_dir_size(entry.path) return total -def convert_size(size_bytes): +def convert_size(size_bytes: int): ''' convert bytes to a human readable format ''' if size_bytes == 0: return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") - i = int(math.floor(math.log(size_bytes, 1024))) - p = math.pow(1024, i) - s = round(size_bytes / p, 2) - return f"{s} {size_name[i]})" \ No newline at end of file + # calculate the log of size (in bytes) to base 1024 and run it down to the nearest integer + index = int(math.floor(math.log(size_bytes, 1024))) + # return the value of 1024 raised to the power of index + power_cal_index = math.pow(1024, index) + #convert bytes to a different unit if applicable + size_bytes_converted = round(size_bytes / power_cal_index, 2) + return f"{size_bytes_converted} {size_name[index]})" \ No newline at end of file From 9d7637cdf5f0d26a4aa6980c90fe8d7aea5feeb2 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:44:01 -0400 Subject: [PATCH 253/615] import datetime to the top --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 57a18fe13..c4ac7dfbc 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1,3 +1,4 @@ +import datetime from copy import deepcopy import os import uuid # used to generate unique names for entities @@ -16,7 +17,7 @@ import re import synapseclient from time import sleep -from ..utils.general import get_dir_size, convert_size +from schematic.utils.general import get_dir_size, convert_size from synapseclient import ( Synapse, File, @@ -50,7 +51,6 @@ from schematic.exceptions import MissingConfigValueError, AccessCredentialsError from schematic import CONFIG -import datetime logger = logging.getLogger(__name__) From 842195f08e24086becf9c40a4f599ce0c1f6cb0c Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 16:45:43 -0400 Subject: [PATCH 254/615] change bariable name --- schematic/utils/general.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index b7846af7a..7cbbb2a74 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -53,9 +53,9 @@ def convert_size(size_bytes: int): return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") # calculate the log of size (in bytes) to base 1024 and run it down to the nearest integer - index = int(math.floor(math.log(size_bytes, 1024))) + index_int = int(math.floor(math.log(size_bytes, 1024))) # return the value of 1024 raised to the power of index - power_cal_index = math.pow(1024, index) + power_cal = math.pow(1024, index_int) #convert bytes to a different unit if applicable - size_bytes_converted = round(size_bytes / power_cal_index, 2) - return f"{size_bytes_converted} {size_name[index]})" \ No newline at end of file + size_bytes_converted = round(size_bytes / power_cal, 2) + return f"{size_bytes_converted} {size_name[index_int]})" \ No newline at end of file From 5b6fc144a8f5d75206fd70da57db2f70f694b5db Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:48:55 -0700 Subject: [PATCH 255/615] switch conversion to set location --- schematic/models/GE_Helpers.py | 2 +- schematic/models/validate_attribute.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index be9cd210c..464311535 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -464,7 +464,7 @@ def generate_errors( val_rule = rule, attribute_name = errColumn, row_num = np_array_to_str_list(np.array(indices)+2), - error_val = iterable_to_str_list(values), + error_val = iterable_to_str_list(set(values)), sg = self.sg ) if vr_errors: diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index cd68066fa..4702288b7 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -486,10 +486,10 @@ def generate_content_error( #return error and empty list for warnings if raises == 'error': - error_list = [error_row, error_col, error_message, set(error_val)] + error_list = [error_row, error_col, error_message, error_val] #return warning and empty list for errors elif raises == 'warning': - warning_list = [error_row, error_col, error_message, set(error_val)] + warning_list = [error_row, error_col, error_message, error_val] return error_list, warning_list From b61558b8da2c0d773a0b629eff6036db40188bf1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:53:10 -0700 Subject: [PATCH 256/615] remove conversion in cross_error_str --- schematic/models/validate_attribute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 4702288b7..99a148be5 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -464,7 +464,7 @@ def generate_content_error( elif val_rule.startswith('unique'): cross_error_str = ( - f"Column {attribute_name} has the duplicate value(s) {set(error_val)} in rows: {row_num}." + f"Column {attribute_name} has the duplicate value(s) {error_val} in rows: {row_num}." ) elif val_rule.startswith('protectAges'): From 23adfcb77b4de673d0155670de58dd1557283a05 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 13:54:23 -0700 Subject: [PATCH 257/615] correct variable name --- schematic/models/validate_attribute.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 99a148be5..ff03576bb 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -448,11 +448,11 @@ def generate_content_error( #log warning or error message if val_rule.startswith('recommended'): - cross_error_str = ( + content_error_str = ( f"Column {attribute_name} is recommended but empty." ) - logLevel(cross_error_str) - error_message = cross_error_str + logLevel(content_error_str) + error_message = content_error_str if raises == 'error': error_list = [error_col, error_message] @@ -463,26 +463,26 @@ def generate_content_error( return error_list, warning_list elif val_rule.startswith('unique'): - cross_error_str = ( + content_error_str = ( f"Column {attribute_name} has the duplicate value(s) {error_val} in rows: {row_num}." ) elif val_rule.startswith('protectAges'): - cross_error_str = ( + content_error_str = ( f"Column {attribute_name} contains ages that should be censored in rows: {row_num}." ) elif val_rule.startswith('inRange'): - cross_error_str = ( + content_error_str = ( f"{attribute_name} values in rows {row_num} are out of the specified range." ) elif val_rule.startswith('date'): - cross_error_str = ( + content_error_str = ( f"{attribute_name} values in rows {row_num} are not parsable as dates." ) - logLevel(cross_error_str) + logLevel(content_error_str) error_row = row_num - error_message = cross_error_str + error_message = content_error_str #return error and empty list for warnings if raises == 'error': From 9af7d2b6155de8b932523adb339864cd86fa0726 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 13 Mar 2023 17:38:39 -0400 Subject: [PATCH 258/615] add comment related to purge synapse cache --- schematic/store/synapse.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c4ac7dfbc..d02ff19fa 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -102,6 +102,9 @@ def __init__( self._query_fileview() def _purge_synapse_cache(self): + ''' + Purge synapse cache if it exceeds 19.5 GB + ''' # try clearing the cache # scan a directory and check size of files root_dir = self.syn.cache.cache_root_dir From b755d93552fad63d923eefefeff306673ad50046 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:50:10 -0700 Subject: [PATCH 259/615] Revert "switch conversion to set location" This reverts commit 5b6fc144a8f5d75206fd70da57db2f70f694b5db. --- schematic/models/GE_Helpers.py | 2 +- schematic/models/validate_attribute.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 464311535..be9cd210c 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -464,7 +464,7 @@ def generate_errors( val_rule = rule, attribute_name = errColumn, row_num = np_array_to_str_list(np.array(indices)+2), - error_val = iterable_to_str_list(set(values)), + error_val = iterable_to_str_list(values), sg = self.sg ) if vr_errors: diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index ff03576bb..b2a4ef79b 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -486,10 +486,10 @@ def generate_content_error( #return error and empty list for warnings if raises == 'error': - error_list = [error_row, error_col, error_message, error_val] + error_list = [error_row, error_col, error_message, set(error_val)] #return warning and empty list for errors elif raises == 'warning': - warning_list = [error_row, error_col, error_message, error_val] + warning_list = [error_row, error_col, error_message, set(error_val)] return error_list, warning_list From 62feb7e0fc3a90974ae4f6557d5f9c10a59d5440 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 14:51:19 -0700 Subject: [PATCH 260/615] revert error str conversion --- schematic/models/validate_attribute.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index b2a4ef79b..6ad610934 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -464,7 +464,7 @@ def generate_content_error( elif val_rule.startswith('unique'): content_error_str = ( - f"Column {attribute_name} has the duplicate value(s) {error_val} in rows: {row_num}." + f"Column {attribute_name} has the duplicate value(s) {set(error_val)} in rows: {row_num}." ) elif val_rule.startswith('protectAges'): From 6a14270cbf55596ed453ffc796d4017fc52c5eb3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:26:14 -0700 Subject: [PATCH 261/615] switch conversion in content error gen method --- schematic/models/validate_attribute.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 6ad610934..05cea5c90 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -432,7 +432,9 @@ def generate_content_error( error_list = [] warning_list = [] error_col = attribute_name # Attribute name - + if error_val: + error_val = iterable_to_str_list(set(error_val)) + #Determine which, if any, message to raise raises = GenerateError.get_message_level( val_rule=val_rule, @@ -464,7 +466,7 @@ def generate_content_error( elif val_rule.startswith('unique'): content_error_str = ( - f"Column {attribute_name} has the duplicate value(s) {set(error_val)} in rows: {row_num}." + f"Column {attribute_name} has the duplicate value(s) {error_val} in rows: {row_num}." ) elif val_rule.startswith('protectAges'): @@ -486,10 +488,10 @@ def generate_content_error( #return error and empty list for warnings if raises == 'error': - error_list = [error_row, error_col, error_message, set(error_val)] + error_list = [error_row, error_col, error_message, error_val] #return warning and empty list for errors elif raises == 'warning': - warning_list = [error_row, error_col, error_message, set(error_val)] + warning_list = [error_row, error_col, error_message, error_val] return error_list, warning_list From f6ba4c8b4c639f64c48892e45cc9b4e0c4049a42 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:26:49 -0700 Subject: [PATCH 262/615] rm pass statements --- schematic/models/GE_Helpers.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index be9cd210c..3801360ca 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -471,12 +471,12 @@ def generate_errors( errors.append(vr_errors) if rule.startswith('protectAges'): self.censor_ages(vr_errors,errColumn) - pass + if vr_warnings: warnings.append(vr_warnings) if rule.startswith('protectAges'): self.censor_ages(vr_warnings,errColumn) - pass + return errors, warnings From 421c93daf80de858dc3c566f62e8a21266f02484 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 14 Mar 2023 13:51:25 -0400 Subject: [PATCH 263/615] update purge funct; clear cache an hour earlier --- schematic/store/synapse.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d02ff19fa..31fd564ef 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1,4 +1,4 @@ -import datetime +from datetime import datetime, timedelta from copy import deepcopy import os import uuid # used to generate unique names for entities @@ -108,13 +108,14 @@ def _purge_synapse_cache(self): # try clearing the cache # scan a directory and check size of files root_dir = self.syn.cache.cache_root_dir + cache = self.syn.cache if os.path.exists(root_dir): nbytes = get_dir_size(root_dir) - # if 19.5 GB has already been taken, purge cache prior to today + # if 19.5 GB has already been taken, purge cache before an hour if nbytes >= 20937965568: - c = self.syn.core.cache.Cache() - today = datetime.strftime(datetime.utcnow(), '%s') - c.purge(before_date = int(today)) + an_hour_earlier = datetime.strftime(datetime.utcnow()- timedelta(hours = 1), '%s') + num_of_deleted_files = cache.purge(before_date = int(an_hour_earlier)) + print(f'{num_of_deleted_files} number of files have been deleted from {root_dir}') else: # print remaining ephemeral storage on AWS remaining_space = 21474836480 - nbytes @@ -135,10 +136,11 @@ def _query_fileview(self): self.storageFileviewTable = self.syn.tableQuery( "SELECT * FROM " + self.storageFileview ).asDataFrame() + except AttributeError: raise AttributeError("storageFileview attribute has not been set.") except SynapseHTTPError: - raise AccessCredentialsError(self.storageFileview) + raise AccessCredentialsError(self.storageFileview) @staticmethod def login(token=None, access_token=None, input_token=None): From 53aee677e14b80a181f7557638e1d1b5cbd3db62 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 12:01:11 -0700 Subject: [PATCH 264/615] update tests with 3 errors to be compatible with unordered sets --- tests/test_validation.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 531d2b354..fe73561ed 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -141,13 +141,16 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): sg = sg, )[0] in errors - assert GenerateError.generate_content_error( + + date_err = GenerateError.generate_content_error( val_rule = 'date', attribute_name = 'Check Date', sg = sg, row_num = ['2','3','4'], error_val = ['84-43-094', '32-984', 'notADate'], - )[0] in errors + )[0] + error_in_list = [date_err[2] in error for error in errors] + assert any(error_in_list) assert GenerateError.generate_content_error( val_rule = 'unique error', @@ -211,14 +214,18 @@ def test_invalid_manifest(self,helpers,sg,metadataModel): matching_manifests = ['syn29862066', 'syn27648165'], sg = sg, )[1] in warnings - - assert GenerateError.generate_cross_warning( + + + cross_warning = GenerateError.generate_cross_warning( val_rule = 'matchExactlyOne MockComponent.checkMatchExactlyvalues MockComponent.checkMatchExactlyvalues value', row_num = ['2', '3', '4'], attribute_name='Check Match Exactly values', invalid_entry = ['71738', '98085', '210065'], sg = sg, - )[1] in warnings + )[1] + warning_in_list = [cross_warning[1] in warning for warning in warnings] + assert any(warning_in_list) + From 2d122804979416d8f8a780c24fdcb92687faa1b7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 11:17:49 -0700 Subject: [PATCH 265/615] add benchmark test and fixture --- tests/test_api.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index d6bc222ee..f81118ca2 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -29,6 +29,11 @@ def test_manifest_csv(helpers): test_manifest_path = helpers.get_data_path("mock_manifests/Valid_Test_Manifest.csv") yield test_manifest_path +@pytest.fixture(scope="class") +def test_invalid_manifest_csv(helpers): + test_invalid_manifest_path = helpers.get_data_frame("mock_manifests/Invalid_Test_Manifest.csv", preserve_raw_input=False) + yield test_invalid_manifest_path + @pytest.fixture(scope="class") def test_upsert_manifest_csv(helpers): test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest.csv") @@ -655,8 +660,17 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 +@pytest.mark.schematic_api +class ValidationBenchmark: + def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest_csv, ): + + + + + + assert True From 478bc7df13cd670f8e588944cceeb7643fca866f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 11:54:15 -0700 Subject: [PATCH 266/615] rename test class --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index f81118ca2..f28b8a606 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -661,7 +661,7 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso @pytest.mark.schematic_api -class ValidationBenchmark: +class TestValidationBenchmark: def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest_csv, ): From 69c742cb5a16230d91263e06c21d324a8ae59ce7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 12:40:03 -0700 Subject: [PATCH 267/615] Add parametrization function for attributes --- tests/test_api.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index f28b8a606..a20b1848b 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -7,6 +7,7 @@ import pandas as pd import re +from schematic.schemas.generator import SchemaGenerator ''' To run the tests, you have to keep API running locally first by doing `python3 run_api.py` @@ -49,6 +50,17 @@ def data_model_jsonld(): data_model_jsonld ="https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld" yield data_model_jsonld +def get_MockComponent_attribute(): + """ + Yield all of the mock conponent attributes one at a time + """ + sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld") + attributes=sg.get_node_dependencies('MockComponent') + attributes.remove('Component') + + for MockComponent_attribute in attributes: + yield MockComponent_attribute + @pytest.fixture(scope="class") def syn_token(config): synapse_config_path = config.SYNAPSE_CONFIG_PATH From 206970600230b570bb47ef9bde58ba7cc776ffd2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 12:40:18 -0700 Subject: [PATCH 268/615] parameterize test --- tests/test_api.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index a20b1848b..8cc84254c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -673,9 +673,9 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso @pytest.mark.schematic_api -class TestValidationBenchmark: - def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest_csv, ): - +class TestValidationBenchmark(): + @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) + def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest_csv, MockComponent_attribute ): From 946ba2e460f5c7a9c5874af07e804a6edf8548c6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 12:56:58 -0700 Subject: [PATCH 269/615] update data model for date attribute --- tests/data/example.model.csv | 2 +- tests/data/example.model.jsonld | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index a2d93da25..9b056b065 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -18,7 +18,7 @@ CRAM,,,"Genome Build, Genome FASTA",,FALSE,ValidValue,,, CSV/TSV,,,Genome Build,,FALSE,ValidValue,,, Genome Build,,"GRCh37, GRCh38, GRCm38, GRCm39",,,TRUE,DataProperty,,, Genome FASTA,,,,,TRUE,DataProperty,,, -MockComponent,,,"Component, Check List, Check Regex List, Check Regex Single, Check Regex Format, Check Num, Check Float, Check Int, Check String, Check URL,Check Match at Least, Check Match at Least values, Check Match Exactly, Check Match Exactly values, Check Recommended, Check Ages, Check Unique, Check Range",,FALSE,DataType,,, +MockComponent,,,"Component, Check List, Check Regex List, Check Regex Single, Check Regex Format, Check Num, Check Float, Check Int, Check String, Check URL,Check Match at Least, Check Match at Least values, Check Match Exactly, Check Match Exactly values, Check Recommended, Check Ages, Check Unique, Check Range, Check Date",,FALSE,DataType,,, Check List,,"ab, cd, ef, gh",,,TRUE,DataProperty,,,list strict Check Regex List,,,,,TRUE,DataProperty,,,list strict::regex match [a-f] Check Regex Single,,,,,TRUE,DataProperty,,,regex search [a-f] diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index 77e138f29..b9f3fb0de 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2536,6 +2536,9 @@ }, { "@id": "bts:CheckRange" + }, + { + "@id": "bts:CheckDate" } ], "sms:validationRules": [] From 88f911345a4084f8e9d52bf2a202252e8c8bbc89 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:07:45 -0700 Subject: [PATCH 270/615] WIP create large manifest for benchmarking --- tests/test_api.py | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 8cc84254c..d55d9ec1e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -6,7 +6,7 @@ import os import pandas as pd import re - +from math import ceil from schematic.schemas.generator import SchemaGenerator ''' @@ -31,9 +31,9 @@ def test_manifest_csv(helpers): yield test_manifest_path @pytest.fixture(scope="class") -def test_invalid_manifest_csv(helpers): - test_invalid_manifest_path = helpers.get_data_frame("mock_manifests/Invalid_Test_Manifest.csv", preserve_raw_input=False) - yield test_invalid_manifest_path +def test_invalid_manifest(helpers): + test_invalid_manifest = helpers.get_data_frame("mock_manifests/Invalid_Test_Manifest.csv", preserve_raw_input=False) + yield test_invalid_manifest @pytest.fixture(scope="class") def test_upsert_manifest_csv(helpers): @@ -675,13 +675,17 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso @pytest.mark.schematic_api class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) - def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest_csv, MockComponent_attribute ): - - - - - - + def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): + target_rows = 1000 + # Isolate single attribute of interest, keep `Component` column + single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] + # Extend to ~1000 rows in size to for performance test + multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) + large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) + # Convert manfiest to JSON for api endpoint + manifest_json = large_manfiest.to_json(orient='split',index=False) + + assert True From 9b05201e9b2f5670179b0fdb701d2a8d431283c8 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 8 Mar 2023 13:16:08 -0700 Subject: [PATCH 271/615] add TODO note --- tests/test_api.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_api.py b/tests/test_api.py index d55d9ec1e..38309ed9d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -53,6 +53,7 @@ def data_model_jsonld(): def get_MockComponent_attribute(): """ Yield all of the mock conponent attributes one at a time + TODO: pull in jsonld from fixture """ sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld") attributes=sg.get_node_dependencies('MockComponent') From 8152edec3458b405fae3ce2d9fe39f60ac08645f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 09:17:14 -0700 Subject: [PATCH 272/615] add manifest validation to tests --- tests/test_api.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 38309ed9d..df33a7a51 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -687,6 +687,17 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma manifest_json = large_manfiest.to_json(orient='split',index=False) + + params = { + "schema_url": data_model_jsonld, + "json_str": manifest_json, + "data_type": "MockComponent" + } + + response = client.post('http://localhost:3001/v1/model/validate', query_string=params) + response_dt = json.loads(response.data) + assert response.status_code == 200 + assert True From e8cf00791d7793f75346f864d2715e8192e38488 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 9 Mar 2023 09:17:49 -0700 Subject: [PATCH 273/615] TEMP WIP validate reg size manifest --- tests/test_api.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index df33a7a51..6648e2cb0 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -59,6 +59,8 @@ def get_MockComponent_attribute(): attributes=sg.get_node_dependencies('MockComponent') attributes.remove('Component') + #yield attributes[-1] + for MockComponent_attribute in attributes: yield MockComponent_attribute @@ -680,12 +682,12 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma target_rows = 1000 # Isolate single attribute of interest, keep `Component` column single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] - # Extend to ~1000 rows in size to for performance test - multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) - large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) - # Convert manfiest to JSON for api endpoint - manifest_json = large_manfiest.to_json(orient='split',index=False) - + # # Extend to ~1000 rows in size to for performance test + # multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) + # large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) + # # Convert manfiest to JSON for api endpoint + # manifest_json = large_manfiest.to_json(orient='split',index=False) + manifest_json = single_attribute_manfiest.to_json() params = { From 8339aa87b224dbe45242eb23028f0bf31994a11b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:28:43 -0700 Subject: [PATCH 274/615] implement `timeit` --- tests/test_api.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 6648e2cb0..43fb0d767 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -7,6 +7,8 @@ import pandas as pd import re from math import ceil +import timeit + from schematic.schemas.generator import SchemaGenerator ''' @@ -680,6 +682,8 @@ class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): target_rows = 1000 + endpoint_url = 'http://localhost:3001/v1/model/validate' + # Isolate single attribute of interest, keep `Component` column single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] # # Extend to ~1000 rows in size to for performance test @@ -689,18 +693,21 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma # manifest_json = large_manfiest.to_json(orient='split',index=False) manifest_json = single_attribute_manfiest.to_json() - params = { "schema_url": data_model_jsonld, "json_str": manifest_json, "data_type": "MockComponent" } - response = client.post('http://localhost:3001/v1/model/validate', query_string=params) - response_dt = json.loads(response.data) - assert response.status_code == 200 + benchmark_test = """ + def run_endpoint(client,endpoint_url,params): + response = client.post(endpoint_url, query_string=params) + """ + + results = timeit.repeat(stmt=benchmark_test, repeat = 5) - assert True + assert min(results) < 5 + From 404b48da971055138d4a3a1cd11e034949e493af Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:35:47 -0700 Subject: [PATCH 275/615] fix indentation error --- tests/test_api.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 43fb0d767..9d5e82b27 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -699,10 +699,7 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma "data_type": "MockComponent" } - benchmark_test = """ - def run_endpoint(client,endpoint_url,params): - response = client.post(endpoint_url, query_string=params) - """ + benchmark_test = """def run_endpoint(client,endpoint_url,params): response = client.post(endpoint_url, query_string=params)""" results = timeit.repeat(stmt=benchmark_test, repeat = 5) From 487e69eb7ac551ef4a67660ffa5c2fdcebbf9409 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:48:55 -0700 Subject: [PATCH 276/615] display fastest response time --- tests/test_api.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 9d5e82b27..352da40e6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -9,8 +9,12 @@ from math import ceil import timeit +import logging from schematic.schemas.generator import SchemaGenerator +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) + ''' To run the tests, you have to keep API running locally first by doing `python3 run_api.py` ''' @@ -702,9 +706,10 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma benchmark_test = """def run_endpoint(client,endpoint_url,params): response = client.post(endpoint_url, query_string=params)""" results = timeit.repeat(stmt=benchmark_test, repeat = 5) - + logger.warning(f"Fastest validation endpiont responise time {min(results)} seconds.") assert min(results) < 5 + From 0d9fd09ded242c8323e64909c9a1d8f2dfd35553 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 10:49:54 -0700 Subject: [PATCH 277/615] formatting --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 352da40e6..b03d5815c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -8,8 +8,8 @@ import re from math import ceil import timeit - import logging + from schematic.schemas.generator import SchemaGenerator logging.basicConfig(level=logging.DEBUG) From f2b22ff180c141b1ad814b3fec1a2d8e719e09f5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:45:12 -0700 Subject: [PATCH 278/615] add timing assertion to test --- tests/test_api.py | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index b03d5815c..fbe84fd48 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -7,9 +7,8 @@ import pandas as pd import re from math import ceil -import timeit import logging - +from time import perf_counter from schematic.schemas.generator import SchemaGenerator logging.basicConfig(level=logging.DEBUG) @@ -65,10 +64,10 @@ def get_MockComponent_attribute(): attributes=sg.get_node_dependencies('MockComponent') attributes.remove('Component') - #yield attributes[-1] + yield attributes[-1] - for MockComponent_attribute in attributes: - yield MockComponent_attribute + # for MockComponent_attribute in attributes: + # yield MockComponent_attribute @pytest.fixture(scope="class") def syn_token(config): @@ -703,11 +702,17 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma "data_type": "MockComponent" } - benchmark_test = """def run_endpoint(client,endpoint_url,params): response = client.post(endpoint_url, query_string=params)""" + t_start = perf_counter() + response = client.post(endpoint_url, query_string=params) + response_time = perf_counter() - t_start + response_dt = json.loads(response.data) + assert response.status_code == 200 + + assert response_time < 5.00 + logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") + + - results = timeit.repeat(stmt=benchmark_test, repeat = 5) - logger.warning(f"Fastest validation endpiont responise time {min(results)} seconds.") - assert min(results) < 5 From 7887ac34f327f30a1de97aa29d26890bd791b825 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 09:56:14 -0700 Subject: [PATCH 279/615] switch to 'records` format for conversion to json use large manfiests --- tests/test_api.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index fbe84fd48..0a9308b6c 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -689,12 +689,12 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma # Isolate single attribute of interest, keep `Component` column single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] - # # Extend to ~1000 rows in size to for performance test - # multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) - # large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) - # # Convert manfiest to JSON for api endpoint - # manifest_json = large_manfiest.to_json(orient='split',index=False) - manifest_json = single_attribute_manfiest.to_json() + # Extend to ~1000 rows in size to for performance test + multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) + large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) + # Convert manfiest to JSON for api endpoint + manifest_json = large_manfiest.to_json(orient='records') + params = { "schema_url": data_model_jsonld, From 553f00f75ae08f80a3162b7a64b865340af65543 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:10:58 -0700 Subject: [PATCH 280/615] add data model for single rule benchmarking attributes are set to not required --- tests/data/example.single_rule.model.jsonld | 3289 +++++++++++++++++++ 1 file changed, 3289 insertions(+) create mode 100644 tests/data/example.single_rule.model.jsonld diff --git a/tests/data/example.single_rule.model.jsonld b/tests/data/example.single_rule.model.jsonld new file mode 100644 index 000000000..2c220f82a --- /dev/null +++ b/tests/data/example.single_rule.model.jsonld @@ -0,0 +1,3289 @@ +{ + "@context": { + "bts": "http://schema.biothings.io/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "schema": "http://schema.org/", + "xsd": "http://www.w3.org/2001/XMLSchema#" + }, + "@graph": [ + { + "@id": "schema:Text", + "@type": [ + "schema:DataType", + "rdfs:Class" + ], + "rdfs:comment": "Data type: Text.", + "rdfs:label": "Text" + }, + { + "@id": "schema:Number", + "@type": [ + "schema:DataType", + "rdfs:Class" + ], + "rdfs:comment": "Data type: Number.", + "rdfs:label": "Number" + }, + { + "@id": "schema:Integer", + "@type": "rdfs:Class", + "rdfs:comment": "Data type: Integer.", + "rdfs:label": "Integer", + "rdfs:subClassOf": { + "@id": "schema:Number" + } + }, + { + "@id": "schema:Thing", + "@type": "rdfs:Class", + "rdfs:comment": "Thing", + "rdfs:label": "Thing", + "schema:isPartOf": { + "@id": "http://schema.org" + } + }, + { + "@id": "bts:BiologicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "BiologicalEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OntologyClass", + "@type": "rdfs:Class", + "rdfs:comment": "a concept or class in an ontology, vocabulary or thesaurus", + "rdfs:label": "OntologyClass", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RelationshipType", + "@type": "rdfs:Class", + "rdfs:comment": "An OWL property used as an edge label", + "rdfs:label": "RelationshipType", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneOntologyClass", + "@type": "rdfs:Class", + "rdfs:comment": "an ontology class that describes a functional aspect of a gene, gene prodoct or complex", + "rdfs:label": "GeneOntologyClass", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OrganismTaxon", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "OrganismTaxon", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OrganismalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A named entity that is either a part of an organism, a whole organism, population or clade of organisms, excluding molecular entities", + "rdfs:label": "OrganismalEntity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:IndividualOrganism", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "IndividualOrganism", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Case", + "@type": "rdfs:Class", + "rdfs:comment": "An individual organism that has a patient role in some clinical context.", + "rdfs:label": "Case", + "rdfs:subClassOf": { + "@id": "bts:IndividualOrganism" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PopulationOfIndividualOrganisms", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PopulationOfIndividualOrganisms", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Biosample", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Biosample", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:DiseaseOrPhenotypicFeature", + "@type": "rdfs:Class", + "rdfs:comment": "Either one of a disease or an individual phenotypic feature. Some knowledge resources such as Monarch treat these as distinct, others such as MESH conflate.", + "rdfs:label": "DiseaseOrPhenotypicFeature", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Disease", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Disease", + "rdfs:subClassOf": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PhenotypicFeature", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PhenotypicFeature", + "rdfs:subClassOf": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Environment", + "@type": "rdfs:Class", + "rdfs:comment": "A feature of the environment of an organism that influences one or more phenotypic features of that organism, potentially mediated by genes", + "rdfs:label": "Environment", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:InformationContentEntity", + "@type": "rdfs:Class", + "rdfs:comment": "a piece of information that typically describes some piece of biology or is used as support.", + "rdfs:label": "InformationContentEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ConfidenceLevel", + "@type": "rdfs:Class", + "rdfs:comment": "Level of confidence in a statement", + "rdfs:label": "ConfidenceLevel", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EvidenceType", + "@type": "rdfs:Class", + "rdfs:comment": "Class of evidence that supports an association", + "rdfs:label": "EvidenceType", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Publication", + "@type": "rdfs:Class", + "rdfs:comment": "Any published piece of information. Can refer to a whole publication, or to a part of it (e.g. a figure, figure legend, or section highlighted by NLP). The scope is intended to be general and include information published on the web as well as journals.", + "rdfs:label": "Publication", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MolecularEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A gene, gene product, small molecule or macromolecule (including protein complex)", + "rdfs:label": "MolecularEntity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ChemicalSubstance", + "@type": "rdfs:Class", + "rdfs:comment": "May be a chemical entity or a formulation with a chemical entity as active ingredient, or a complex material with multiple chemical entities as part", + "rdfs:label": "ChemicalSubstance", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Drug", + "@type": "rdfs:Class", + "rdfs:comment": "A substance intended for use in the diagnosis, cure, mitigation, treatment, or prevention of disease", + "rdfs:label": "Drug", + "rdfs:subClassOf": { + "@id": "bts:ChemicalSubstance" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Metabolite", + "@type": "rdfs:Class", + "rdfs:comment": "Any intermediate or product resulting from metabolism. Includes primary and secondary metabolites.", + "rdfs:label": "Metabolite", + "rdfs:subClassOf": { + "@id": "bts:ChemicalSubstance" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:AnatomicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A subcellular location, cell type or gross anatomical part", + "rdfs:label": "AnatomicalEntity", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:LifeStage", + "@type": "rdfs:Class", + "rdfs:comment": "A stage of development or growth of an organism, including post-natal adult stages", + "rdfs:label": "LifeStage", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PlanetaryEntity", + "@type": "rdfs:Class", + "rdfs:comment": "Any entity or process that exists at the level of the whole planet", + "rdfs:label": "PlanetaryEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EnvironmentalProcess", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "EnvironmentalProcess", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EnvironmentalFeature", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "EnvironmentalFeature", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "Any entity or process that exists in the clinical domain and outside the biological realm. Diseases are placed under biological entities", + "rdfs:label": "ClinicalEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalTrial", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "ClinicalTrial", + "rdfs:subClassOf": { + "@id": "bts:ClinicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalIntervention", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "ClinicalIntervention", + "rdfs:subClassOf": { + "@id": "bts:ClinicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Device", + "@type": "rdfs:Class", + "rdfs:comment": "A thing made or adapted for a particular purpose, especially a piece of mechanical or electronic equipment", + "rdfs:label": "Device", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GenomicEntity", + "@type": "rdfs:Class", + "rdfs:comment": "an entity that can either be directly located on a genome (gene, transcript, exon, regulatory region) or is encoded in a genome (protein)", + "rdfs:label": "GenomicEntity", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Genome", + "@type": "rdfs:Class", + "rdfs:comment": "A genome is the sum of genetic material within a cell or virion.", + "rdfs:label": "Genome", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Transcript", + "@type": "rdfs:Class", + "rdfs:comment": "An RNA synthesized on a DNA or RNA template by an RNA polymerase", + "rdfs:label": "Transcript", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Exon", + "@type": "rdfs:Class", + "rdfs:comment": "A region of the transcript sequence within a gene which is not removed from the primary RNA transcript by RNA splicing", + "rdfs:label": "Exon", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CodingSequence", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "CodingSequence", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MacromolecularMachine", + "@type": "rdfs:Class", + "rdfs:comment": "A union of gene, gene product, and macromolecular complex. These are the basic units of function in a cell. They either carry out individual biological activities, or they encode molecules which do this.", + "rdfs:label": "MacromolecularMachine", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneOrGeneProduct", + "@type": "rdfs:Class", + "rdfs:comment": "a union of genes or gene products. Frequently an identifier for one will be used as proxy for another", + "rdfs:label": "GeneOrGeneProduct", + "rdfs:subClassOf": { + "@id": "bts:MacromolecularMachine" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Gene", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Gene", + "rdfs:subClassOf": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneProduct", + "@type": "rdfs:Class", + "rdfs:comment": "The functional molecular product of a single gene. Gene products are either proteins or functional RNA molecules", + "rdfs:label": "GeneProduct", + "rdfs:subClassOf": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Protein", + "@type": "rdfs:Class", + "rdfs:comment": "A gene product that is composed of a chain of amino acid sequences and is produced by ribosome-mediated translation of mRNA", + "rdfs:label": "Protein", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneProductIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "This is an abstract class that can be mixed in with different kinds of gene products to indicate that the gene product is intended to represent a specific isoform rather than a canonical or reference or generic product. The designation of canonical or reference may be arbitrary, or it may represent the superclass of all isoforms.", + "rdfs:label": "GeneProductIsoform", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ProteinIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "Represents a protein that is a specific isoform of the canonical or reference protein. See https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4114032/", + "rdfs:label": "ProteinIsoform", + "rdfs:subClassOf": { + "@id": "bts:Protein" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RnaProduct", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "RnaProduct", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RnaProductIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "Represents a protein that is a specific isoform of the canonical or reference RNA", + "rdfs:label": "RnaProductIsoform", + "rdfs:subClassOf": { + "@id": "bts:RnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:NoncodingRnaProduct", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "NoncodingRnaProduct", + "rdfs:subClassOf": { + "@id": "bts:RnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Microrna", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Microrna", + "rdfs:subClassOf": { + "@id": "bts:NoncodingRnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MacromolecularComplex", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "MacromolecularComplex", + "rdfs:subClassOf": { + "@id": "bts:MacromolecularMachine" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneFamily", + "@type": "rdfs:Class", + "rdfs:comment": "any grouping of multiple genes or gene products related by common descent", + "rdfs:label": "GeneFamily", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Genotype", + "@type": "rdfs:Class", + "rdfs:comment": "An information content entity that describes a genome by specifying the total variation in genomic sequence and/or gene expression, relative to some extablished background", + "rdfs:label": "Genotype", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Haplotype", + "@type": "rdfs:Class", + "rdfs:comment": "A set of zero or more Alleles on a single instance of a Sequence[VMC]", + "rdfs:label": "Haplotype", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:SequenceVariant", + "@type": "rdfs:Class", + "rdfs:comment": "An allele that varies in its sequence from what is considered the reference allele at that locus.", + "rdfs:label": "SequenceVariant", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:DrugExposure", + "@type": "rdfs:Class", + "rdfs:comment": "A drug exposure is an intake of a particular chemical substance", + "rdfs:label": "DrugExposure", + "rdfs:subClassOf": { + "@id": "bts:Environment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Treatment", + "@type": "rdfs:Class", + "rdfs:comment": "A treatment is targeted at a disease or phenotype and may involve multiple drug 'exposures'", + "rdfs:label": "Treatment", + "rdfs:subClassOf": { + "@id": "bts:Environment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeographicLocation", + "@type": "rdfs:Class", + "rdfs:comment": "a location that can be described in lat/long coordinates", + "rdfs:label": "GeographicLocation", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeographicLocationAtTime", + "@type": "rdfs:Class", + "rdfs:comment": "a location that can be described in lat/long coordinates, for a particular time", + "rdfs:label": "GeographicLocationAtTime", + "rdfs:subClassOf": { + "@id": "bts:GeographicLocation" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Occurrent", + "@type": "rdfs:Class", + "rdfs:comment": "A processual entity", + "rdfs:label": "Occurrent", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:BiologicalProcessOrActivity", + "@type": "rdfs:Class", + "rdfs:comment": "Either an individual molecular activity, or a collection of causally connected molecular activities", + "rdfs:label": "BiologicalProcessOrActivity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MolecularActivity", + "@type": "rdfs:Class", + "rdfs:comment": "An execution of a molecular function carried out by a gene product or macromolecular complex.", + "rdfs:label": "MolecularActivity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcessOrActivity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ActivityAndBehavior", + "@type": "rdfs:Class", + "rdfs:comment": "Activity or behavior of any independent integral living, organization or mechanical actor in the world", + "rdfs:label": "ActivityAndBehavior", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Procedure", + "@type": "rdfs:Class", + "rdfs:comment": "A series of actions conducted in a certain order or manner", + "rdfs:label": "Procedure", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Phenomenon", + "@type": "rdfs:Class", + "rdfs:comment": "a fact or situation that is observed to exist or happen, especially one whose cause or explanation is in question", + "rdfs:label": "Phenomenon", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:BiologicalProcess", + "@type": "rdfs:Class", + "rdfs:comment": "One or more causally connected executions of molecular functions", + "rdfs:label": "BiologicalProcess", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcessOrActivity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Pathway", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Pathway", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcess" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PhysiologicalProcess", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PhysiologicalProcess", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcess" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CellularComponent", + "@type": "rdfs:Class", + "rdfs:comment": "A location in or around a cell", + "rdfs:label": "CellularComponent", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Cell", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Cell", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CellLine", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "CellLine", + "rdfs:subClassOf": { + "@id": "bts:Biosample" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GrossAnatomicalStructure", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "GrossAnatomicalStructure", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ensembl", + "@type": "rdf:Property", + "rdfs:comment": "Ensembl ID for gene, protein or transcript", + "rdfs:label": "ensembl", + "schema:domainIncludes": [ + { + "@id": "bts:Transcript" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:hgnc", + "@type": "rdf:Property", + "rdfs:comment": "HGNC ID for gene", + "rdfs:label": "hgnc", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:entrez", + "@type": "rdf:Property", + "rdfs:comment": "Entrez ID for gene", + "rdfs:label": "entrez", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:refseq", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "refseq", + "schema:domainIncludes": [ + { + "@id": "bts:Transcript" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:omim", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "omim", + "schema:domainIncludes": [ + { + "@id": "bts:Disease" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:umls", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "umls", + "schema:domainIncludes": { + "@id": "bts:Disease" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:homologousTo", + "@type": "rdf:Property", + "rdfs:comment": "Shared ancestry between protein or gene", + "rdfs:label": "homologousTo", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:molecularlyInteractsWith", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "molecularlyInteractsWith", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:geneticallyInteractsWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes whose phenotypic effects are dependent on each other in some way - such that their combined phenotypic effects are the result of some interaction between the activity of their gene products. Examples include epistasis and synthetic lethality.", + "rdfs:label": "geneticallyInteractsWith", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Gene" + } + }, + { + "@id": "bts:affectsAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the amount of the other within a system of interest", + "rdfs:label": "affectsAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the amount of the other within a system of interest", + "rdfs:label": "increasesAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the amount of the other within a system of interest", + "rdfs:label": "decreasesAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the activity of the other within a system of interest", + "rdfs:label": "affectsActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the activity of the other within a system of interest", + "rdfs:label": "increasesActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the activity of the other within a system of interest", + "rdfs:label": "decreasesActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the level of expression of the other within a system of interest", + "rdfs:label": "affectsExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:increasesExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the level of expression of the other within a system of interest", + "rdfs:label": "increasesExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:decreasesExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the level of expression of the other within a system of interest", + "rdfs:label": "decreasesExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:affectsFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the rate or quality of folding of the other ", + "rdfs:label": "affectsFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate or quality of folding of the other ", + "rdfs:label": "increasesFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate or quality of folding of the other ", + "rdfs:label": "decreasesFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the localization of the other within a system of interest", + "rdfs:label": "affectsLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the proper localization of the other within a system of interest", + "rdfs:label": "increasesLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the proper localization of the other within a system of interest", + "rdfs:label": "decreasesLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the metabolic processing of the other within a system of interest", + "rdfs:label": "affectsMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of metabolic processing of the other within a system of interest", + "rdfs:label": "increasesMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of metabolic processing of the other within a system of interest", + "rdfs:label": "decreasesMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads changes in the molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "affectsMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads to increased molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "increasesMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads to decreased molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "decreasesMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of chemical synthesis of the other", + "rdfs:label": "affectsSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of chemical synthesis of the other", + "rdfs:label": "increasesSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of chemical synthesis of the other", + "rdfs:label": "decreasesSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of degradation of the other within a system of interest", + "rdfs:label": "affectsDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of degradation of the other within a system of interest", + "rdfs:label": "increasesDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of degradation of the other within a system of interest", + "rdfs:label": "decreasesDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity impacts the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "affectsMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:increasesMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity increases the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "increasesMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:decreasesMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity decreases the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "decreasesMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:affectsResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "affectsResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "increasesResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "decreasesResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity impacts the splicing of the mRNA", + "rdfs:label": "affectsSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:increasesSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity increases the proper splicing of the mRNA", + "rdfs:label": "increasesSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:decreasesSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity decreases the proper splicing of the mRNA", + "rdfs:label": "decreasesSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:affectsStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the stability of the other within a system of interest", + "rdfs:label": "affectsStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the stability of the other within a system of interest", + "rdfs:label": "increasesStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the stability of the other within a system of interest", + "rdfs:label": "decreasesStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "affectsTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "increasesTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "decreasesTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "affectsSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "increasesSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "decreasesSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "affectsUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "increasesUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "decreasesUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:regulates,ProcessToProcess", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "regulates,ProcessToProcess", + "schema:domainIncludes": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Occurrent" + } + }, + { + "@id": "bts:regulates,EntityToEntity", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "regulates,EntityToEntity", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:hasGeneProduct", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene and a transcribed and/or translated product generated from it", + "rdfs:label": "hasGeneProduct", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneProduct" + } + }, + { + "@id": "bts:inPathwayWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are part of in the same biological pathway", + "rdfs:label": "inPathwayWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:inComplexWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are part of (or code for products that are part of) in the same macromolecular complex", + "rdfs:label": "inComplexWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:inCellPopulationWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are expressed in the same cell type or population ", + "rdfs:label": "inCellPopulationWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:geneAssociatedWithCondition", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene and a disease or phenotypic feature that the gene or its alleles/products may influence, contribute to, or correlate with", + "rdfs:label": "geneAssociatedWithCondition", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:treats", + "@type": "rdf:Property", + "rdfs:comment": "holds between a therapeutic procedure or chemical substance and a disease or phenotypic feature that it is used to treat", + "rdfs:label": "treats", + "schema:domainIncludes": { + "@id": "bts:Treatment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:correlatedWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between a disease or phenotypic feature and a measurable molecular entity that is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "correlatedWith", + "schema:domainIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:hasBiomarker", + "@type": "rdf:Property", + "rdfs:comment": "holds between a disease or phenotypic feature and a measurable molecular entity that is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "hasBiomarker", + "schema:domainIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:biomarkerFor", + "@type": "rdf:Property", + "rdfs:comment": "holds between a measurable molecular entity and a disease or phenotypic feature, where the entity is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "biomarkerFor", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:expressedIn", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene or gene product and an anatomical entity in which it is expressed", + "rdfs:label": "expressedIn", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:AnatomicalEntity" + } + }, + { + "@id": "bts:expresses", + "@type": "rdf:Property", + "rdfs:comment": "holds between an anatomical entity and gene or gene product that is expressed there", + "rdfs:label": "expresses", + "schema:domainIncludes": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:hasPhenotype", + "@type": "rdf:Property", + "rdfs:comment": "holds between a biological entity and a phenotype, where a phenotype is construed broadly as any kind of quality of an organism part, a collection of these qualities, or a change in quality or qualities (e.g. abnormally increased temperature). ", + "rdfs:label": "hasPhenotype", + "schema:domainIncludes": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:precedes", + "@type": "rdf:Property", + "rdfs:comment": "holds between two processes, where one completes before the other begins", + "rdfs:label": "precedes", + "schema:domainIncludes": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Occurrent" + } + }, + { + "@id": "bts:subclassOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two classes where the domain class is a specialization of the range class", + "rdfs:label": "subclassOf", + "schema:domainIncludes": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:OntologyClass" + } + }, + { + "@id": "bts:Patient", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Patient", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Patient", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:PatientID" + }, + { + "@id": "bts:Sex" + }, + { + "@id": "bts:YearofBirth" + }, + { + "@id": "bts:Diagnosis" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:PatientID", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "PatientID", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Patient ID", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:Sex", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Sex", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Female" + }, + { + "@id": "bts:Male" + }, + { + "@id": "bts:Other" + } + ], + "sms:displayName": "Sex", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:YearofBirth", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "YearofBirth", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Year of Birth", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Diagnosis", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Diagnosis", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Healthy" + }, + { + "@id": "bts:Cancer" + } + ], + "sms:displayName": "Diagnosis", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:Cancer", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Cancer", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Cancer", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:CancerType" + }, + { + "@id": "bts:FamilyHistory" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CancerType", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CancerType", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Breast" + }, + { + "@id": "bts:Colorectal" + }, + { + "@id": "bts:Lung" + }, + { + "@id": "bts:Prostate" + }, + { + "@id": "bts:Skin" + } + ], + "sms:displayName": "Cancer Type", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:FamilyHistory", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FamilyHistory", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Breast" + }, + { + "@id": "bts:Colorectal" + }, + { + "@id": "bts:Lung" + }, + { + "@id": "bts:Prostate" + }, + { + "@id": "bts:Skin" + } + ], + "sms:displayName": "Family History", + "sms:required": "sms:true", + "sms:validationRules": [ + "list strict" + ] + }, + { + "@id": "bts:Biospecimen", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Biospecimen", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Biospecimen", + "sms:required": "sms:false", + "sms:requiresComponent": [ + { + "@id": "bts:Patient" + } + ], + "sms:requiresDependency": [ + { + "@id": "bts:SampleID" + }, + { + "@id": "bts:PatientID" + }, + { + "@id": "bts:TissueStatus" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:SampleID", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "SampleID", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Sample ID", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:TissueStatus", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "TissueStatus", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Healthy" + }, + { + "@id": "bts:Malignant" + } + ], + "sms:displayName": "Tissue Status", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:BulkRNA-seqAssay", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "BulkRNA-seqAssay", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Bulk RNA-seq Assay", + "sms:required": "sms:false", + "sms:requiresComponent": [ + { + "@id": "bts:Biospecimen" + } + ], + "sms:requiresDependency": [ + { + "@id": "bts:Filename" + }, + { + "@id": "bts:SampleID" + }, + { + "@id": "bts:FileFormat" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:Filename", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Filename", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Filename", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:FileFormat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FileFormat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:FASTQ" + }, + { + "@id": "bts:BAM" + }, + { + "@id": "bts:CRAM" + }, + { + "@id": "bts:CSV/TSV" + } + ], + "sms:displayName": "File Format", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:BAM", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "BAM", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "BAM", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CRAM", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CRAM", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "CRAM", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + }, + { + "@id": "bts:GenomeFASTA" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CSV/TSV", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CSV/TSV", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "CSV/TSV", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:GenomeBuild", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GenomeBuild", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:GRCh37" + }, + { + "@id": "bts:GRCh38" + }, + { + "@id": "bts:GRCm38" + }, + { + "@id": "bts:GRCm39" + } + ], + "sms:displayName": "Genome Build", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:GenomeFASTA", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GenomeFASTA", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Genome FASTA", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:MockComponent", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockComponent", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockComponent", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:Component" + }, + { + "@id": "bts:CheckList" + }, + { + "@id": "bts:CheckRegexList" + }, + { + "@id": "bts:CheckRegexSingle" + }, + { + "@id": "bts:CheckRegexFormat" + }, + { + "@id": "bts:CheckNum" + }, + { + "@id": "bts:CheckFloat" + }, + { + "@id": "bts:CheckInt" + }, + { + "@id": "bts:CheckString" + }, + { + "@id": "bts:CheckURL" + }, + { + "@id": "bts:CheckMatchatLeast" + }, + { + "@id": "bts:CheckMatchatLeastvalues" + }, + { + "@id": "bts:CheckMatchExactly" + }, + { + "@id": "bts:CheckMatchExactlyvalues" + }, + { + "@id": "bts:CheckRecommended" + }, + { + "@id": "bts:CheckAges" + }, + { + "@id": "bts:CheckUnique" + }, + { + "@id": "bts:CheckRange" + }, + { + "@id": "bts:CheckDate" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CheckList", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckList", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Ab" + }, + { + "@id": "bts:Cd" + }, + { + "@id": "bts:Ef" + }, + { + "@id": "bts:Gh" + } + ], + "sms:displayName": "Check List", + "sms:required": "sms:false", + "sms:validationRules": [ + "list strict error" + ] + }, + { + "@id": "bts:CheckRegexList", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexList", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex List", + "sms:required": "sms:false", + "sms:validationRules": [ + "list strict error", + "regex match [a-f] error" + ] + }, + { + "@id": "bts:CheckRegexSingle", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexSingle", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex Single", + "sms:required": "sms:false", + "sms:validationRules": [ + "regex search [a-f] error" + ] + }, + { + "@id": "bts:CheckRegexFormat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexFormat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex Format", + "sms:required": "sms:false", + "sms:validationRules": [ + "regex match [a-f] error" + ] + }, + { + "@id": "bts:CheckNum", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckNum", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Num", + "sms:required": "sms:false", + "sms:validationRules": [ + "num error" + ] + }, + { + "@id": "bts:CheckFloat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckFloat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Float", + "sms:required": "sms:false", + "sms:validationRules": [ + "float error" + ] + }, + { + "@id": "bts:CheckInt", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckInt", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Int", + "sms:required": "sms:false", + "sms:validationRules": [ + "int error" + ] + }, + { + "@id": "bts:CheckString", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckString", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check String", + "sms:required": "sms:false", + "sms:validationRules": [ + "str error" + ] + }, + { + "@id": "bts:CheckURL", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckURL", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check URL", + "sms:required": "sms:false", + "sms:validationRules": [ + "url error" + ] + }, + { + "@id": "bts:CheckMatchatLeast", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchatLeast", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match at Least", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchAtLeastOne Patient.PatientID set warning" + ] + }, + { + "@id": "bts:CheckMatchExactly", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchExactly", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match Exactly", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchExactlyOne MockComponent.checkMatchExactly set warning" + ] + }, + { + "@id": "bts:CheckMatchatLeastvalues", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchatLeastvalues", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match at Least values", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchAtLeastOne MockComponent.checkMatchatLeastvalues value warning" + ] + }, + { + "@id": "bts:CheckMatchExactlyvalues", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchExactlyvalues", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match Exactly values", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchExactlyOne MockComponent.checkMatchExactlyvalues value warning" + ] + }, + { + "@id": "bts:CheckRecommended", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRecommended", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Recommended", + "sms:required": "sms:false", + "sms:validationRules": [ + "recommended warning" + ] + }, + { + "@id": "bts:CheckAges", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckAges", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Ages", + "sms:required": "sms:false", + "sms:validationRules": [ + "protectAges warning" + ] + }, + { + "@id": "bts:CheckUnique", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckUnique", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Unique", + "sms:required": "sms:false", + "sms:validationRules": [ + "unique error" + ] + }, + { + "@id": "bts:CheckRange", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRange", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Range", + "sms:required": "sms:false", + "sms:validationRules": [ + "inRange 50 100 error" + ] + }, + { + "@id": "bts:CheckDate", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckDate", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Date", + "sms:required": "sms:false", + "sms:validationRules": [ + "date error" + ] + }, + { + "@id": "bts:MockRDB", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDB", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:Component" + }, + { + "@id": "bts:MockRDBId" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:MockRDBId", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDBId", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB_id", + "sms:required": "sms:true", + "sms:validationRules": [ + "int" + ] + }, + { + "@id": "bts:Component", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Component", + "rdfs:subClassOf": [ + { + "@id": "bts:Patient" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Component", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Female", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Female", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Female", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Male", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Male", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Male", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Other", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Other", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Other", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Healthy", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Healthy", + "rdfs:subClassOf": [ + { + "@id": "bts:Diagnosis" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Healthy", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Breast", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Breast", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Breast", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Colorectal", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Colorectal", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Colorectal", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Lung", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Lung", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Lung", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Prostate", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Prostate", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Prostate", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Skin", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Skin", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Skin", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Malignant", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Malignant", + "rdfs:subClassOf": [ + { + "@id": "bts:TissueStatus" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Malignant", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:FASTQ", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FASTQ", + "rdfs:subClassOf": [ + { + "@id": "bts:FileFormat" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "FASTQ", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCh37", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCh37", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCh37", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCh38", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCh38", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCh38", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCm38", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCm38", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCm38", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCm39", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCm39", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCm39", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Ab", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Ab", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "ab", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Cd", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Cd", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "cd", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Ef", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Ef", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "ef", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Gh", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Gh", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "gh", + "sms:required": "sms:false", + "sms:validationRules": [] + } + ], + "@id": "http://schema.biothings.io/#0.1" +} \ No newline at end of file From dbf86e74696c340df1aae5fbf11f8432cbb37705 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:35:04 -0700 Subject: [PATCH 281/615] use new benchmarking data model --- tests/test_api.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0a9308b6c..791674104 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -55,12 +55,17 @@ def data_model_jsonld(): data_model_jsonld ="https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld" yield data_model_jsonld +@pytest.fixture(scope="class") +def benchmark_data_model_jsonld(): + benchmark_data_model_jsonld = "https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop-validation-api-tests/tests/data/example.single_rule.model.jsonld" + yield benchmark_data_model_jsonld + def get_MockComponent_attribute(): """ Yield all of the mock conponent attributes one at a time TODO: pull in jsonld from fixture """ - sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld") + sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop-validation-api-tests/tests/data/example.single_rule.model.jsonld") attributes=sg.get_node_dependencies('MockComponent') attributes.remove('Component') @@ -683,7 +688,7 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso @pytest.mark.schematic_api class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) - def test_validation_performance(self, data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): + def test_validation_performance(self, benchmark_data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): target_rows = 1000 endpoint_url = 'http://localhost:3001/v1/model/validate' @@ -696,8 +701,8 @@ def test_validation_performance(self, data_model_jsonld, client, test_invalid_ma manifest_json = large_manfiest.to_json(orient='records') - params = { - "schema_url": data_model_jsonld, + params = { + "schema_url": benchmark_data_model_jsonld, "json_str": manifest_json, "data_type": "MockComponent" } From 5ff44ed4c5f22d46c92b5af3f907b84daa04608d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:36:32 -0700 Subject: [PATCH 282/615] set error rate to about 33% except for `Check Match Exactly values` --- tests/test_api.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 791674104..d93491c4b 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -692,8 +692,18 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ target_rows = 1000 endpoint_url = 'http://localhost:3001/v1/model/validate' + if MockComponent_attribute == 'Check Ages': + test_invalid_manifest[MockComponent_attribute][0] = '6550' + elif MockComponent_attribute == 'Check Date': + test_invalid_manifest[MockComponent_attribute][0] = 'October 21 2022' + test_invalid_manifest[MockComponent_attribute][2] = 'October 21 2022' + elif MockComponent_attribute == 'Check Unique': + test_invalid_manifest[MockComponent_attribute][0] = 'str2' + + # Isolate single attribute of interest, keep `Component` column single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] + # Extend to ~1000 rows in size to for performance test multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) From c2e26172946c83995fcabd0c49726ab03e78f45c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 14 Mar 2023 11:37:33 -0700 Subject: [PATCH 283/615] update attribute yielding function --- tests/test_api.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index d93491c4b..6510cac0a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -69,10 +69,8 @@ def get_MockComponent_attribute(): attributes=sg.get_node_dependencies('MockComponent') attributes.remove('Component') - yield attributes[-1] - - # for MockComponent_attribute in attributes: - # yield MockComponent_attribute + for MockComponent_attribute in attributes: + yield MockComponent_attribute @pytest.fixture(scope="class") def syn_token(config): From 92995a8559486fb9879be89a9e8ebcbffc32a576 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 14 Mar 2023 12:12:00 -0700 Subject: [PATCH 284/615] handle case where user does not submit a mrt --- api/routes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/api/routes.py b/api/routes.py index 40f32f2eb..d392f5f44 100644 --- a/api/routes.py +++ b/api/routes.py @@ -389,6 +389,9 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None if not table_manipulation: table_manipulation = "replace" + if not manifest_record_type: + manifest_record_type = "combo" + if data_type == 'None': validate_component = None else: From 20d7486673fb5a23471b12446f954531684aeaa8 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 14 Mar 2023 12:21:00 -0700 Subject: [PATCH 285/615] added additional documentation for manifest_record_type to api.yaml --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 2d46bef62..b30035d55 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -264,7 +264,7 @@ paths: schema: type: string enum: ["table", "file", "file_w_entities", "combo"] - description: Manifest storage type. + description: Manifest storage type, will default to "combo" if none selected.'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. 'table' will store the manifest as a table and a csv on Synapse. 'file' will store the manifest as a csv only on Synapse. 'combo' will perform the options file_with_entites and table in combination. example: 'table' - in: query name: restrict_rules From bbf0cc62b33a5841d7c7afcf0c3af766b71316c2 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 14 Mar 2023 23:47:46 -0400 Subject: [PATCH 286/615] add download manifest using manifest id funct and set debut to true --- run_api.py | 2 +- schematic/store/synapse.py | 46 +++++++++++++++++++++++++++++++++-- schematic_api/api/__main__.py | 2 +- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/run_api.py b/run_api.py index ed36c7d81..5b7118412 100755 --- a/run_api.py +++ b/run_api.py @@ -15,4 +15,4 @@ # Launch app app = create_app() #CORS(app, resources={r"*": {"origins": "*"}}) - app.run(host=host, port=port, debug=False) \ No newline at end of file + app.run(host=host, port=port, debug=True) \ No newline at end of file diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index cbe443138..a0753841d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -336,6 +336,47 @@ def getFilesInStorageDataset( return file_list + def _get_censored_manifest_id_(self, datasetId, ): + """ + Get censored manifest id + """ + manifest_syn_id=manifest[censored]["id"][0] + return + + @staticmethod + def download_manifest(self, manifest_syn_id: str, donwload_manifest: bool = True): + """ + Donwload a manifest based on a given manifest id. If a user does not have access to uncensored manifest, we have + to use censor manifest instead + Args: + manifest_syn_id: syn id of a manifest + download_manifest: boolean + """ + # enables retrying if user does not have access to uncensored manifest + # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location + while True: + try: + if 'manifest_folder' in CONFIG['synapse'].keys(): + manifest_data = self.syn.get( + manifest_syn_id, + downloadLocation=CONFIG["synapse"]["manifest_folder"], + ifcollision="overwrite.local", + ) + break + # if no manifest folder is set, download to cache + else: + manifest_data = self.syn.get( + manifest_syn_id, + ) + break + # If user does not have access to uncensored manifest, use censored instead + except(SynapseUnmetAccessRestrictions): + print('handling censored manifest') + # manifest_syn_id=manifest[censored]["id"][0] + + return manifest_data + + @staticmethod def getDatasetManifest( self, datasetId: str, downloadFile: bool = False, newManifestName: str='', ) -> List[str]: @@ -371,6 +412,7 @@ def getDatasetManifest( else: # retrieve data from synapse + # if a censored manifest exists for this dataset censored = manifest['name'].str.contains(censored_regex) if any(censored): @@ -386,7 +428,7 @@ def getDatasetManifest( # if the downloadFile option is set to True if downloadFile: - # enables retrying if user does not have access to uncensored manifest + # # enables retrying if user does not have access to uncensored manifest while True: # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location try: @@ -403,7 +445,7 @@ def getDatasetManifest( manifest_syn_id, ) break - # If user does not have access to uncensored manifest, use censored instead + # If user does not have access to uncensored manifest, use censored instead except(SynapseUnmetAccessRestrictions): manifest_syn_id=manifest[censored]["id"][0] diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index 8081a7578..ea710081d 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -13,7 +13,7 @@ def main(): # Launch app # CORS(app, resources={r"*": {"origins": "*"}}) - app.run(host=host, port=port, debug=False) + app.run(host=host, port=port, debug=True) if __name__ == "__main__": main() \ No newline at end of file From 2a727ea4ea049df1bcc9d337bec69ef526d251f2 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 00:22:43 -0400 Subject: [PATCH 287/615] change print to logger --- schematic/__init__.py | 1 + schematic/store/synapse.py | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/schematic/__init__.py b/schematic/__init__.py index ef5eaba35..9ec34deb0 100644 --- a/schematic/__init__.py +++ b/schematic/__init__.py @@ -20,6 +20,7 @@ # Suppress INFO-level logging from some dependencies logging.getLogger("keyring").setLevel(logging.ERROR) logging.getLogger("rdflib").setLevel(logging.ERROR) +logging.getLogger("synapse").setLevel(logging.INFO) logger = logging.getLogger(__name__) click_log.basic_config(logger) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 31fd564ef..b0f48a520 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -52,7 +52,7 @@ from schematic import CONFIG -logger = logging.getLogger(__name__) +logger = logging.getLogger("Synapse storage") class SynapseStorage(BaseStorage): """Implementation of Storage interface for datasets/files stored on Synapse. @@ -115,12 +115,12 @@ def _purge_synapse_cache(self): if nbytes >= 20937965568: an_hour_earlier = datetime.strftime(datetime.utcnow()- timedelta(hours = 1), '%s') num_of_deleted_files = cache.purge(before_date = int(an_hour_earlier)) - print(f'{num_of_deleted_files} number of files have been deleted from {root_dir}') + logger.info(f'{num_of_deleted_files} number of files have been deleted from {root_dir}') else: # print remaining ephemeral storage on AWS remaining_space = 21474836480 - nbytes converted_space = convert_size(remaining_space) - print(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache.') + logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache.') def _query_fileview(self): self._purge_synapse_cache() From 01c6c5eccfa47c4b6c6af5fbefc4ed55850b62c9 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 11:48:48 -0400 Subject: [PATCH 288/615] purge cache for every 7 gb --- schematic/store/synapse.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index b0f48a520..ecb5a4ff6 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -103,7 +103,7 @@ def __init__( def _purge_synapse_cache(self): ''' - Purge synapse cache if it exceeds 19.5 GB + Purge synapse cache if it exceeds 7 GB ''' # try clearing the cache # scan a directory and check size of files @@ -111,16 +111,16 @@ def _purge_synapse_cache(self): cache = self.syn.cache if os.path.exists(root_dir): nbytes = get_dir_size(root_dir) - # if 19.5 GB has already been taken, purge cache before an hour - if nbytes >= 20937965568: - an_hour_earlier = datetime.strftime(datetime.utcnow()- timedelta(hours = 1), '%s') - num_of_deleted_files = cache.purge(before_date = int(an_hour_earlier)) + # if 7 GB has already been taken, purge cache before 15 min + if nbytes >= 7516192768: + minutes_earlier = datetime.strftime(datetime.utcnow()- timedelta(minutes = 15), '%s') + num_of_deleted_files = cache.purge(before_date = int(minutes_earlier)) logger.info(f'{num_of_deleted_files} number of files have been deleted from {root_dir}') else: # print remaining ephemeral storage on AWS remaining_space = 21474836480 - nbytes converted_space = convert_size(remaining_space) - logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache.') + logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') def _query_fileview(self): self._purge_synapse_cache() From 48af47358717efd4b42bcb485a56a24c1415646a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:34:07 -0700 Subject: [PATCH 289/615] switch indexing for updating manifests --- tests/test_api.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 6510cac0a..454da3776 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -691,12 +691,12 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ endpoint_url = 'http://localhost:3001/v1/model/validate' if MockComponent_attribute == 'Check Ages': - test_invalid_manifest[MockComponent_attribute][0] = '6550' + test_invalid_manifest.loc[0,MockComponent_attribute] = '6550' elif MockComponent_attribute == 'Check Date': - test_invalid_manifest[MockComponent_attribute][0] = 'October 21 2022' - test_invalid_manifest[MockComponent_attribute][2] = 'October 21 2022' + test_invalid_manifest.loc[0,MockComponent_attribute] = 'October 21 2022' + test_invalid_manifest.loc[2,MockComponent_attribute] = 'October 21 2022' elif MockComponent_attribute == 'Check Unique': - test_invalid_manifest[MockComponent_attribute][0] = 'str2' + test_invalid_manifest.loc[0,MockComponent_attribute] = 'str2' # Isolate single attribute of interest, keep `Component` column From 319c5a3746722726cef5c30f29a9f2a35b85c567 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:44:25 -0700 Subject: [PATCH 290/615] move log message --- tests/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 454da3776..875f30da7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -719,11 +719,11 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ response = client.post(endpoint_url, query_string=params) response_time = perf_counter() - t_start response_dt = json.loads(response.data) - assert response.status_code == 200 - assert response_time < 5.00 logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") + assert response.status_code == 200 + assert response_time < 5.00 From 6c17486b755a3c7af039885690800b72da646333 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:44:39 -0700 Subject: [PATCH 291/615] Update test_api.py --- tests/test_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 875f30da7..528eff6fa 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -719,7 +719,6 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ response = client.post(endpoint_url, query_string=params) response_time = perf_counter() - t_start response_dt = json.loads(response.data) - assert response_time < 5.00 logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") assert response.status_code == 200 From 0fa08cfc19224a34022420f278eaab2c1db57487 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 09:55:15 -0700 Subject: [PATCH 292/615] remove variable --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 528eff6fa..165daa46f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -718,7 +718,7 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ t_start = perf_counter() response = client.post(endpoint_url, query_string=params) response_time = perf_counter() - t_start - response_dt = json.loads(response.data) + logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") assert response.status_code == 200 From 9874c15b65e376626e677debaaacf7b329c735b6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 10:03:27 -0700 Subject: [PATCH 293/615] switch error enforcement location --- tests/test_api.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 165daa46f..2ebc3427a 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -690,18 +690,18 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ target_rows = 1000 endpoint_url = 'http://localhost:3001/v1/model/validate' + # Isolate single attribute of interest, keep `Component` column + single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] + if MockComponent_attribute == 'Check Ages': - test_invalid_manifest.loc[0,MockComponent_attribute] = '6550' + single_attribute_manfiest.loc[0,MockComponent_attribute] = '6550' elif MockComponent_attribute == 'Check Date': - test_invalid_manifest.loc[0,MockComponent_attribute] = 'October 21 2022' - test_invalid_manifest.loc[2,MockComponent_attribute] = 'October 21 2022' + single_attribute_manfiest.loc[0,MockComponent_attribute] = 'October 21 2022' + single_attribute_manfiest.loc[2,MockComponent_attribute] = 'October 21 2022' elif MockComponent_attribute == 'Check Unique': - test_invalid_manifest.loc[0,MockComponent_attribute] = 'str2' + single_attribute_manfiest.loc[0,MockComponent_attribute] = 'str2' - # Isolate single attribute of interest, keep `Component` column - single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] - # Extend to ~1000 rows in size to for performance test multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) From 4cafc2103180d05bc1698ae04f5bf45264d0826c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 10:03:52 -0700 Subject: [PATCH 294/615] add docstring and comments --- tests/test_api.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 2ebc3427a..2ef3b4ba5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -687,12 +687,24 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) def test_validation_performance(self, benchmark_data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): + """ + Test to benchamrk performance of validation rules on large manifests + Test loads the invalid_test_manifest.csv and isolates one attribute at a time + it then enforces an error rate of 33% in the attribute (except in the case of Match Exactly Values) + the single attribute manifest is then extended to be ~1000 rows to see performance on a large manfiest + the manifest is passed to the validation endpoint, and the response time of the endpoint is measured + Target response time for all rules is under 5.00 seconds with a successful api response + """ + + # Number of rows to target for large manfiest target_rows = 1000 + # URL of validtion endpoint endpoint_url = 'http://localhost:3001/v1/model/validate' # Isolate single attribute of interest, keep `Component` column single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] + # Enforce error rate of 33% in the manfiest before extension if MockComponent_attribute == 'Check Ages': single_attribute_manfiest.loc[0,MockComponent_attribute] = '6550' elif MockComponent_attribute == 'Check Date': @@ -701,26 +713,27 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ elif MockComponent_attribute == 'Check Unique': single_attribute_manfiest.loc[0,MockComponent_attribute] = 'str2' - - # Extend to ~1000 rows in size to for performance test + # Extend to ~1000 rows in size for performance test multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) + # Convert manfiest to JSON for api endpoint manifest_json = large_manfiest.to_json(orient='records') - + # Set paramters for endpoint params = { "schema_url": benchmark_data_model_jsonld, "json_str": manifest_json, "data_type": "MockComponent" } + # Run and time endpoint t_start = perf_counter() response = client.post(endpoint_url, query_string=params) response_time = perf_counter() - t_start + # Log and check time and ensure successful response logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") - assert response.status_code == 200 assert response_time < 5.00 From d2e9993bc896e46d711481bb0c65da5f45fd3c9f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 10:11:22 -0700 Subject: [PATCH 295/615] switch to lower log level --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 2ef3b4ba5..1e064adf5 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -11,7 +11,7 @@ from time import perf_counter from schematic.schemas.generator import SchemaGenerator -logging.basicConfig(level=logging.DEBUG) +logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) ''' From 5aafccb9e8acb35e30f720b29545bf71a42c1f0b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 10:12:37 -0700 Subject: [PATCH 296/615] update imports --- tests/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 1e064adf5..ec3450b68 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -4,12 +4,12 @@ import configparser import json import os -import pandas as pd import re from math import ceil import logging from time import perf_counter -from schematic.schemas.generator import SchemaGenerator +import pandas as pd # third party library import +from schematic.schemas.generator import SchemaGenerator #Local application/library specific imports. logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) From ae8eef2fd833faf3ec3a76e88306e43ff26bf2b3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 11:39:28 -0700 Subject: [PATCH 297/615] revert error enforcement commit --- tests/test_api.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index ec3450b68..707c00db6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -701,19 +701,19 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ # URL of validtion endpoint endpoint_url = 'http://localhost:3001/v1/model/validate' - # Isolate single attribute of interest, keep `Component` column - single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] - - # Enforce error rate of 33% in the manfiest before extension if MockComponent_attribute == 'Check Ages': - single_attribute_manfiest.loc[0,MockComponent_attribute] = '6550' + test_invalid_manifest.loc[0,MockComponent_attribute] = '6550' elif MockComponent_attribute == 'Check Date': - single_attribute_manfiest.loc[0,MockComponent_attribute] = 'October 21 2022' - single_attribute_manfiest.loc[2,MockComponent_attribute] = 'October 21 2022' + test_invalid_manifest.loc[0,MockComponent_attribute] = 'October 21 2022' + test_invalid_manifest.loc[2,MockComponent_attribute] = 'October 21 2022' elif MockComponent_attribute == 'Check Unique': - single_attribute_manfiest.loc[0,MockComponent_attribute] = 'str2' + test_invalid_manifest.loc[0,MockComponent_attribute] = 'str2' + + + # Isolate single attribute of interest, keep `Component` column + single_attribute_manfiest = test_invalid_manifest[['Component', MockComponent_attribute]] - # Extend to ~1000 rows in size for performance test + # Extend to ~1000 rows in size to for performance test multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) From b10b5dfc6d8a40ed6135e58a86d2dbb183fdcea9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 11:58:32 -0700 Subject: [PATCH 298/615] switch from JSON string to CSV --- tests/test_api.py | 41 ++++++++++++++++++++++++++--------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 707c00db6..3f5bccf0d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -686,7 +686,7 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso @pytest.mark.schematic_api class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) - def test_validation_performance(self, benchmark_data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): + def test_validation_performance(self, helpers, benchmark_data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): """ Test to benchamrk performance of validation rules on large manifests Test loads the invalid_test_manifest.csv and isolates one attribute at a time @@ -701,6 +701,18 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ # URL of validtion endpoint endpoint_url = 'http://localhost:3001/v1/model/validate' + # Set paramters for endpoint + params = { + "schema_url": benchmark_data_model_jsonld, + "data_type": "MockComponent", + + } + headers = { + 'Content-Type': "multipart/form-data", + 'Accept': "application/json" + } + + # Enforce error rate when possible if MockComponent_attribute == 'Check Ages': test_invalid_manifest.loc[0,MockComponent_attribute] = '6550' elif MockComponent_attribute == 'Check Date': @@ -717,20 +729,19 @@ def test_validation_performance(self, benchmark_data_model_jsonld, client, test_ multi_factor = ceil(target_rows/single_attribute_manfiest.shape[0]) large_manfiest = pd.concat([single_attribute_manfiest]*multi_factor, ignore_index = True) - # Convert manfiest to JSON for api endpoint - manifest_json = large_manfiest.to_json(orient='records') - - # Set paramters for endpoint - params = { - "schema_url": benchmark_data_model_jsonld, - "json_str": manifest_json, - "data_type": "MockComponent" - } - - # Run and time endpoint - t_start = perf_counter() - response = client.post(endpoint_url, query_string=params) - response_time = perf_counter() - t_start + try: + # Convert manfiest to csv for api endpoint + large_manifest_path = helpers.get_data_path('mock_manifests/large_manifest_test.csv') + large_manfiest.to_csv(large_manifest_path, index=False) + + # Run and time endpoint + t_start = perf_counter() + #response = client.post(endpoint_url, query_string=params) + response = client.post(endpoint_url, query_string=params, data={"file_name": (open(large_manifest_path, 'rb'), "large_test.csv")}, headers=headers) + response_time = perf_counter() - t_start + finally: + # Remove temp manfiest + os.remove(large_manifest_path) # Log and check time and ensure successful response logger.warning(f"validation endpiont response time {round(response_time,2)} seconds.") From 490d8d505d21dc427e96de812f97955856da4197 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 15:55:26 -0400 Subject: [PATCH 299/615] add _get_manifest_id function, modify download manifest and simplify getDatasetManifest --- schematic/store/synapse.py | 129 +++++++++++++++++-------------------- 1 file changed, 60 insertions(+), 69 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a0753841d..55c0bd3c2 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -336,47 +336,69 @@ def getFilesInStorageDataset( return file_list - def _get_censored_manifest_id_(self, datasetId, ): - """ - Get censored manifest id - """ - manifest_syn_id=manifest[censored]["id"][0] - return + def _get_manifest_id(self, manifest: pd.DataFrame): + """If both censored and uncensored manifests are present, return uncensored manifest; if only one manifest is present, return manifest id of that manifest; if more than two manifests are present, return the manifest id of the first one. + Args: + manifest: a dataframe that contains annotation of manifests metadata + """ + censored_regex=re.compile('.*censored.*') + censored = manifest['name'].str.contains(censored_regex) + if any(censored): + # Try to use uncensored manifest first + not_censored=~censored + if any(not_censored): + manifest_syn_id=manifest[not_censored]["id"][0] + # if only censored manifests are available, just use the first censored manifest + else: + manifest_syn_id = manifest["id"][0] + + #otherwise, use the first (implied only) version that exists + else: + manifest_syn_id = manifest["id"][0] + + # check if user has access to the manifest without download it + try: + self.syn.get(manifest_syn_id, downloadFile=False) + # if user ends up not having access to the manifest returned, switch back to use censored manifest + except(SynapseUnmetAccessRestrictions): + manifest_syn_id=manifest[censored]["id"][0] + + return manifest_syn_id @staticmethod - def download_manifest(self, manifest_syn_id: str, donwload_manifest: bool = True): + def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True): """ - Donwload a manifest based on a given manifest id. If a user does not have access to uncensored manifest, we have - to use censor manifest instead + Donwload a manifest based on a given manifest id. Args: manifest_syn_id: syn id of a manifest download_manifest: boolean """ + # enables retrying if user does not have access to uncensored manifest # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location - while True: - try: - if 'manifest_folder' in CONFIG['synapse'].keys(): - manifest_data = self.syn.get( - manifest_syn_id, - downloadLocation=CONFIG["synapse"]["manifest_folder"], - ifcollision="overwrite.local", - ) - break - # if no manifest folder is set, download to cache - else: - manifest_data = self.syn.get( - manifest_syn_id, - ) - break - # If user does not have access to uncensored manifest, use censored instead - except(SynapseUnmetAccessRestrictions): - print('handling censored manifest') - # manifest_syn_id=manifest[censored]["id"][0] - + while donwload_manifest: + if 'manifest_folder' in CONFIG['synapse'].keys(): + try: + manifest_data = syn.get( + manifest_syn_id, + downloadLocation=CONFIG["synapse"]["manifest_folder"], + ifcollision="overwrite.local", + ) + break + except(SynapseUnmetAccessRestrictions): + raise(f"You don't have access to the requested resource: {manifest_syn_id}") + # if no manifest folder is set, download to cache + ### TO DO: Deprecate the following? + else: + try: + manifest_data = syn.get( + manifest_syn_id, + ) + break + except(SynapseUnmetAccessRestrictions): + raise(f"You don't have access to the requested resource: {manifest_syn_id}") return manifest_data - @staticmethod def getDatasetManifest( self, datasetId: str, downloadFile: bool = False, newManifestName: str='', ) -> List[str]: @@ -395,7 +417,11 @@ def getDatasetManifest( # get a list of files containing the manifest for this dataset (if any) all_files = self.storageFileviewTable + # construct regex based on manifest basename in the config manifest_re=re.compile(os.path.basename(self.manifest)+".*.[tc]sv") + + # search manifest based on given manifest basename regex above + # and return a dataframe containing annotation of manifests manifest = all_files[ (all_files['name'].str.contains(manifest_re,regex=True)) & (all_files["parentId"] == datasetId) @@ -410,45 +436,10 @@ def getDatasetManifest( # if there is an exisiting manifest else: - # retrieve data from synapse - - - # if a censored manifest exists for this dataset - censored = manifest['name'].str.contains(censored_regex) - if any(censored): - # Try to use uncensored manifest first - not_censored=~censored - if any(not_censored): - manifest_syn_id=manifest[not_censored]["id"][0] - - #otherwise, use the first (implied only) version that exists - else: - manifest_syn_id = manifest["id"][0] - - - # if the downloadFile option is set to True - if downloadFile: - # # enables retrying if user does not have access to uncensored manifest - while True: - # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location - try: - if 'manifest_folder' in CONFIG['synapse'].keys(): - manifest_data = self.syn.get( - manifest_syn_id, - downloadLocation=CONFIG["synapse"]["manifest_folder"], - ifcollision="overwrite.local", - ) - break - # if no manifest folder is set, download to cache - else: - manifest_data = self.syn.get( - manifest_syn_id, - ) - break - # If user does not have access to uncensored manifest, use censored instead - except(SynapseUnmetAccessRestrictions): - manifest_syn_id=manifest[censored]["id"][0] - + manifest_syn_id = self._get_manifest_id(manifest) + if downloadFile: + manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, donwload_manifest=True) + # Rename manifest file if indicated by user. if newManifestName: if os.path.exists(manifest_data['path']): From 6c9d714474cdd7b3914b513869aede505341009d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 13:42:44 -0700 Subject: [PATCH 300/615] rm comment --- tests/test_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 3f5bccf0d..0172e69dc 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -736,7 +736,6 @@ def test_validation_performance(self, helpers, benchmark_data_model_jsonld, clie # Run and time endpoint t_start = perf_counter() - #response = client.post(endpoint_url, query_string=params) response = client.post(endpoint_url, query_string=params, data={"file_name": (open(large_manifest_path, 'rb'), "large_test.csv")}, headers=headers) response_time = perf_counter() - t_start finally: From c6d96f93e17b80afc3bcd8cddb3b3f303ba32c0d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 15 Mar 2023 15:18:51 -0700 Subject: [PATCH 301/615] target `develop` branch for benchmark model --- tests/test_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0172e69dc..c6a641485 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -57,7 +57,7 @@ def data_model_jsonld(): @pytest.fixture(scope="class") def benchmark_data_model_jsonld(): - benchmark_data_model_jsonld = "https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop-validation-api-tests/tests/data/example.single_rule.model.jsonld" + benchmark_data_model_jsonld = "https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.single_rule.model.jsonld" yield benchmark_data_model_jsonld def get_MockComponent_attribute(): @@ -65,7 +65,7 @@ def get_MockComponent_attribute(): Yield all of the mock conponent attributes one at a time TODO: pull in jsonld from fixture """ - sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop-validation-api-tests/tests/data/example.single_rule.model.jsonld") + sg = SchemaGenerator("https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.single_rule.model.jsonld") attributes=sg.get_node_dependencies('MockComponent') attributes.remove('Component') From f9e7471a30fe740749a1a8a23f494b247fcaac1d Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 18:21:38 -0400 Subject: [PATCH 302/615] set variable for big bytes number --- schematic/store/synapse.py | 18 +++++++++++++----- schematic/utils/general.py | 11 ++++++++++- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index ecb5a4ff6..8229ca36a 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -17,7 +17,7 @@ import re import synapseclient from time import sleep -from schematic.utils.general import get_dir_size, convert_size +from schematic.utils.general import get_dir_size, convert_size, convert_gb_to_bytes from synapseclient import ( Synapse, File, @@ -105,21 +105,29 @@ def _purge_synapse_cache(self): ''' Purge synapse cache if it exceeds 7 GB ''' + # define the root directory + # set maximum synapse cache allowed + # set maximum ephemeral stroage allowed on AWS + root_dir = "/var/www/.synapseCache/" + maximum_storage_allowed_cache_gb = 7 + maximum_storage_allowed_cache_bytes = convert_gb_to_bytes(maximum_storage_allowed_cache_gb) + total_ephemeral_storag_gb = 20 + total_ephemeral_storage_bytes = convert_gb_to_bytes(total_ephemeral_storag_gb) + # try clearing the cache # scan a directory and check size of files - root_dir = self.syn.cache.cache_root_dir cache = self.syn.cache if os.path.exists(root_dir): nbytes = get_dir_size(root_dir) # if 7 GB has already been taken, purge cache before 15 min - if nbytes >= 7516192768: + if nbytes >= maximum_storage_allowed_cache_bytes: minutes_earlier = datetime.strftime(datetime.utcnow()- timedelta(minutes = 15), '%s') num_of_deleted_files = cache.purge(before_date = int(minutes_earlier)) logger.info(f'{num_of_deleted_files} number of files have been deleted from {root_dir}') else: - # print remaining ephemeral storage on AWS - remaining_space = 21474836480 - nbytes + remaining_space = total_ephemeral_storage_bytes - nbytes converted_space = convert_size(remaining_space) + print(f'Estimated {remaining_space} bytes (which is approximately {converted_space}') logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') def _query_fileview(self): diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 7cbbb2a74..6843d0087 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -58,4 +58,13 @@ def convert_size(size_bytes: int): power_cal = math.pow(1024, index_int) #convert bytes to a different unit if applicable size_bytes_converted = round(size_bytes / power_cal, 2) - return f"{size_bytes_converted} {size_name[index_int]})" \ No newline at end of file + return f"{size_bytes_converted} {size_name[index_int]})" + +def convert_gb_to_bytes(gb: int): + ''' + convert gb to bytes + args: + gb: integer + ''' + bytes_to_return = gb * 1024 * 1024 * 1024 + return bytes_to_return \ No newline at end of file From f1b3fcf18cffa6867d2795846ab12dbd06f8e911 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 18:22:01 -0400 Subject: [PATCH 303/615] set logger as "synapse storage" --- schematic/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/__init__.py b/schematic/__init__.py index 9ec34deb0..cca9173b5 100644 --- a/schematic/__init__.py +++ b/schematic/__init__.py @@ -20,7 +20,7 @@ # Suppress INFO-level logging from some dependencies logging.getLogger("keyring").setLevel(logging.ERROR) logging.getLogger("rdflib").setLevel(logging.ERROR) -logging.getLogger("synapse").setLevel(logging.INFO) +logging.getLogger("Synapse storage").setLevel(logging.INFO) logger = logging.getLogger(__name__) click_log.basic_config(logger) From cacbe6597544cc2cb1b05fd984e7b14c3424824e Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 15 Mar 2023 18:22:42 -0400 Subject: [PATCH 304/615] remove print statement --- schematic/store/synapse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 8229ca36a..60a8cfd92 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -127,7 +127,6 @@ def _purge_synapse_cache(self): else: remaining_space = total_ephemeral_storage_bytes - nbytes converted_space = convert_size(remaining_space) - print(f'Estimated {remaining_space} bytes (which is approximately {converted_space}') logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') def _query_fileview(self): From bfc76fd313ab816aea218f93477b44d3242f0f7d Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 15 Mar 2023 15:26:20 -0700 Subject: [PATCH 305/615] remove breakpoint used during a debugging session --- schematic/store/synapse.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 0075b2153..e7c9fb2e6 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -959,15 +959,12 @@ def format_row_annotations(self, se, sg, row, entityId, useSchemaLabel, hideBlan annos.pop(anno_k) if anno_k in annos.keys() else annos # Otherwise save annotation as approrpriate else: - try: - if isinstance(anno_v,float) and np.isnan(anno_v): - annos[anno_k] = "" - elif isinstance(anno_v,str) and re.fullmatch(csv_list_regex, anno_v) and rule_in_rule_list('list', sg.get_node_validation_rules(anno_k)): - annos[anno_k] = anno_v.split(",") - else: - annos[anno_k] = anno_v - except: - breakpoint() + if isinstance(anno_v,float) and np.isnan(anno_v): + annos[anno_k] = "" + elif isinstance(anno_v,str) and re.fullmatch(csv_list_regex, anno_v) and rule_in_rule_list('list', sg.get_node_validation_rules(anno_k)): + annos[anno_k] = anno_v.split(",") + else: + annos[anno_k] = anno_v return annos From 8da29372cb2da899b73be09eb0d5bbf3377670c5 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 10:55:06 -0400 Subject: [PATCH 306/615] edit doc string --- schematic/utils/general.py | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 6843d0087..2fc2bc357 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -28,12 +28,12 @@ def unlist(_list): else: return _list -def get_dir_size(path): - ''' - calculate total size of a directory - args: - path: path to a folder or directory - ''' +def get_dir_size(path: str): + """calculate total size of a directory + Args: + path: path to a folder + return: total size of a directory + """ total = 0 # Example usage of os.scandir could be found here: https://docs.python.org/3/library/os.html#os.scandir # Technically, scandir.close() is called automatically. But it is still advisable to call it explicitly or use the with statement. @@ -46,9 +46,11 @@ def get_dir_size(path): return total def convert_size(size_bytes: int): - ''' - convert bytes to a human readable format - ''' + """convert bytes to a human readable format + Args: + size_bytes: total byte sizes + return: a string that indicates bytes in a different format + """ if size_bytes == 0: return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") @@ -61,10 +63,10 @@ def convert_size(size_bytes: int): return f"{size_bytes_converted} {size_name[index_int]})" def convert_gb_to_bytes(gb: int): - ''' - convert gb to bytes - args: - gb: integer - ''' + """convert gb to bytes + Args: + gb: number of gb + return: total number of bytes + """ bytes_to_return = gb * 1024 * 1024 * 1024 return bytes_to_return \ No newline at end of file From 97a0fe4041569b609ff49b75d8637984510d4a0a Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 10:55:43 -0400 Subject: [PATCH 307/615] add comments; move location of variables --- schematic/store/synapse.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 60a8cfd92..f88f88dbd 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -101,23 +101,25 @@ def __init__( self._query_fileview() - def _purge_synapse_cache(self): + def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): ''' - Purge synapse cache if it exceeds 7 GB + Purge synapse cache if it exceeds 7GB + Args: + root_dir: directory of the .synapseCache function + Returns: + if size of cache reaches 7GB, return the number of files that get deleted + otherwise, return the total remaining space (assuming total ephemeral storage is 20GB on AWS ) ''' - # define the root directory - # set maximum synapse cache allowed - # set maximum ephemeral stroage allowed on AWS - root_dir = "/var/www/.synapseCache/" - maximum_storage_allowed_cache_gb = 7 - maximum_storage_allowed_cache_bytes = convert_gb_to_bytes(maximum_storage_allowed_cache_gb) - total_ephemeral_storag_gb = 20 - total_ephemeral_storage_bytes = convert_gb_to_bytes(total_ephemeral_storag_gb) - # try clearing the cache # scan a directory and check size of files cache = self.syn.cache if os.path.exists(root_dir): + # set maximum synapse cache allowed + # set maximum ephemeral stroage allowed on AWS + maximum_storage_allowed_cache_gb = 7 + maximum_storage_allowed_cache_bytes = convert_gb_to_bytes(maximum_storage_allowed_cache_gb) + total_ephemeral_storag_gb = 20 + total_ephemeral_storage_bytes = convert_gb_to_bytes(total_ephemeral_storag_gb) nbytes = get_dir_size(root_dir) # if 7 GB has already been taken, purge cache before 15 min if nbytes >= maximum_storage_allowed_cache_bytes: From 51f1bc50c419e601463ffe49e690dfff50aa1d6c Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 10:57:24 -0400 Subject: [PATCH 308/615] edit doc string --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index f88f88dbd..83bcd56b3 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -102,14 +102,14 @@ def __init__( self._query_fileview() def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): - ''' + """ Purge synapse cache if it exceeds 7GB Args: root_dir: directory of the .synapseCache function Returns: if size of cache reaches 7GB, return the number of files that get deleted otherwise, return the total remaining space (assuming total ephemeral storage is 20GB on AWS ) - ''' + """ # try clearing the cache # scan a directory and check size of files cache = self.syn.cache From b2da90bd6ef06d81f26b71f2eaccd6cf8ccf060a Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 12:51:52 -0400 Subject: [PATCH 309/615] add manifest download endpoint and add functions to handle renaming a manifest after downloading --- schematic/store/synapse.py | 52 +++++++++++++++++------------- schematic_api/api/openapi/api.yaml | 44 +++++++++++++++++++++++-- schematic_api/api/routes.py | 23 ++++++++++++- 3 files changed, 92 insertions(+), 27 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 55c0bd3c2..c83091fc7 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -336,10 +336,13 @@ def getFilesInStorageDataset( return file_list - def _get_manifest_id(self, manifest: pd.DataFrame): + def _get_manifest_id(self, manifest: pd.DataFrame) -> str: """If both censored and uncensored manifests are present, return uncensored manifest; if only one manifest is present, return manifest id of that manifest; if more than two manifests are present, return the manifest id of the first one. Args: manifest: a dataframe that contains annotation of manifests metadata + + Return: + manifest_syn_id: id of a given censored or uncensored manifest """ censored_regex=re.compile('.*censored.*') censored = manifest['name'].str.contains(censored_regex) @@ -356,7 +359,7 @@ def _get_manifest_id(self, manifest: pd.DataFrame): else: manifest_syn_id = manifest["id"][0] - # check if user has access to the manifest without download it + # check if user has access to the manifest without downloading it try: self.syn.get(manifest_syn_id, downloadFile=False) # if user ends up not having access to the manifest returned, switch back to use censored manifest @@ -366,16 +369,20 @@ def _get_manifest_id(self, manifest: pd.DataFrame): return manifest_syn_id @staticmethod - def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True): + def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, newManifestName=""): """ Donwload a manifest based on a given manifest id. Args: manifest_syn_id: syn id of a manifest - download_manifest: boolean + download_manifest: boolean + newManifestName: new name of a manifest that gets downloaded + Return: + manifest_data: synapse entity file object """ # enables retrying if user does not have access to uncensored manifest # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location + manifest_data = "" while donwload_manifest: if 'manifest_folder' in CONFIG['synapse'].keys(): try: @@ -396,7 +403,22 @@ def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True) ) break except(SynapseUnmetAccessRestrictions): - raise(f"You don't have access to the requested resource: {manifest_syn_id}") + raise(f"You don't have access to the requested resource: {manifest_syn_id}") + # Rename manifest file if indicated by user. + if newManifestName: + if os.path.exists(manifest_data['path']): + # Rename the file we just made to the new name + new_manifest_filename = newManifestName + '.csv' + #new_manifest_path_name = manifest_data['path'].replace(manifest['name'][0], new_manifest_filename) + dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) + new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) + print('new manifeset path name', new_manifest_path_name) + os.rename(manifest_data['path'], new_manifest_path_name) + + # Update file names/paths in manifest_data + manifest_data['name'] = new_manifest_filename + manifest_data['filename'] = new_manifest_filename + manifest_data['path'] = new_manifest_path_name return manifest_data def getDatasetManifest( @@ -407,6 +429,7 @@ def getDatasetManifest( Args: datasetId: synapse ID of a storage dataset. downloadFile: boolean argument indicating if manifest file in dataset should be downloaded or not. + newManifestName: new name of a manifest that gets downloaded Returns: manifest_syn_id (String): Synapse ID of exisiting manifest file. @@ -438,24 +461,7 @@ def getDatasetManifest( else: manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: - manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, donwload_manifest=True) - - # Rename manifest file if indicated by user. - if newManifestName: - if os.path.exists(manifest_data['path']): - # Rename the file we just made to the new name - new_manifest_filename = newManifestName + '.csv' - new_manifest_path_name = manifest_data['path'].replace(manifest['name'][0], new_manifest_filename) - os.rename(manifest_data['path'], new_manifest_path_name) - - # Update file names/paths in manifest_data - manifest_data['name'] = new_manifest_filename - manifest_data['filename'] = new_manifest_filename - manifest_data['path'] = new_manifest_path_name - - return manifest_data - - + manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, donwload_manifest=True, newManifestName=newManifestName) return manifest_syn_id def getDataTypeFromManifest(self, manifestId:str): diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index b9344157d..092b92a31 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -101,8 +101,46 @@ paths: - Manifest Operations /manifest/download: get: - summary: Endpoint to download an existing manifest - description: Endpoint to download an existing manifest + summary: Endpoint to download an existing manifest by using a manifest id + description: Endpoint to download an existing manifest by using a manifest id + parameters: + - in: query + name: input_token + schema: + type: string + nullable: false + description: Token + example: Token + required: true + - in: query + name: manifest_id + schema: + type: string + nullable: true + description: manifest id + example: syn51078535 + required: true + - in: query + name: new_manifest_name + schema: + type: string + nullable: true + description: Fill in if you want to change the filename of the downloaded manifest. + required: false + operationId: schematic_api.api.routes.download_manifest + responses: + "200": + description: A manifest gets downloaded and local file path of the manifest gets returned. + content: + text/csv: + schema: + type: string + tags: + - Manifest Operations + /dataset/manifest/download: + get: + summary: Endpoint to download an existing manifest by using a dataset id + description: Endpoint to download an existing manifest by using a dataset id parameters: - in: query name: input_token @@ -142,7 +180,7 @@ paths: nullable: true description: Fill in if you want to change the filename of the downloaded manifest. required: false - operationId: schematic_api.api.routes.download_manifest + operationId: schematic_api.api.routes.download_dataset_manifest responses: "200": description: A manifest gets downloaded and local file path of the manifest gets returned. diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 3d39c3c2d..8001e8e56 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -579,8 +579,29 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] +def download_manifest(input_token, manifest_id, new_manifest_name=''): + # call config_handler() + config_handler() + + # use Synapse Storage + store = SynapseStorage(input_token=input_token) + + # try logging in to asset store + try: + syn = store.login(input_token=input_token) + except: + raise("Failed to log in to asset store. Please check your credentials") + manifest_data = store.download_manifest(syn, manifest_id, True, new_manifest_name) + try: + #return local file path + manifest_local_file_path = manifest_data['path'] + except: + raise(f"Failed to download manifest {manifest_id}") + + return manifest_local_file_path + #@profile(sort_by='cumulative', strip_dirs=True) -def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): +def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) From b6a92ee644ea71e5a4f11c1961c14218c8106afa Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 13:18:40 -0400 Subject: [PATCH 310/615] remove print statement --- schematic/store/synapse.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c83091fc7..c45e1e6b2 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -375,7 +375,7 @@ def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, Args: manifest_syn_id: syn id of a manifest download_manifest: boolean - newManifestName: new name of a manifest that gets downloaded + newManifestName: new name of a manifest that gets downloaded. Return: manifest_data: synapse entity file object """ @@ -412,7 +412,6 @@ def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, #new_manifest_path_name = manifest_data['path'].replace(manifest['name'][0], new_manifest_filename) dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) - print('new manifeset path name', new_manifest_path_name) os.rename(manifest_data['path'], new_manifest_path_name) # Update file names/paths in manifest_data From 967d849177159bea00bdb6101533eb05ba0c669d Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 16 Mar 2023 11:28:16 -0700 Subject: [PATCH 311/615] Update naming of manifest_record_types --- api/openapi/api.yaml | 4 ++-- api/routes.py | 2 +- schematic/help.py | 12 ++++++------ schematic/models/commands.py | 4 ++-- schematic/store/synapse.py | 30 ++++++++++++++++-------------- tests/test_api.py | 13 ++++++++----- tests/test_store.py | 12 ++++++------ 7 files changed, 41 insertions(+), 36 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index b30035d55..6ef7e3800 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,8 +263,8 @@ paths: name: manifest_record_type schema: type: string - enum: ["table", "file", "file_w_entities", "combo"] - description: Manifest storage type, will default to "combo" if none selected.'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. 'table' will store the manifest as a table and a csv on Synapse. 'file' will store the manifest as a csv only on Synapse. 'combo' will perform the options file_with_entites and table in combination. + enum: ["file_only", "file_w_entities", "table_and_file", "table_file_and_entities"] + description: Manifest storage type, will default to "table_file_and_entities" if none selected.'file_and_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. 'table_and_file' will store the manifest as a table and a csv on Synapse. 'file_only' will store the manifest as a csv only on Synapse. 'table_file_and_entities' will perform the options file_with_entites and table in combination. example: 'table' - in: query name: restrict_rules diff --git a/api/routes.py b/api/routes.py index d392f5f44..82bae3b1e 100644 --- a/api/routes.py +++ b/api/routes.py @@ -390,7 +390,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None table_manipulation = "replace" if not manifest_record_type: - manifest_record_type = "combo" + manifest_record_type = "table_file_and_entities" if data_type == 'None': validate_component = None diff --git a/schematic/help.py b/schematic/help.py index 1fd309bc4..679421048 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -107,12 +107,12 @@ "If not, annotations with blank values will be displayed." ), "manifest_record_type":( - "Specify the way the manifest should be store as on Synapse. Options are 'file', 'file_w_entities', 'table' and " - "'combo'. 'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. " - "'table' will store the manifest as a table and a csv on Synapse. " - "'file' will store the manifest as a csv only on Synapse." - "'combo' will perform the options file_with_entites and table in combination." - "Default value is 'combo'." + "Specify the way the manifest should be store as on Synapse. Options are 'file_only', 'file_and_entities', 'table_and_file' and " + "'table_file_and_entities'. 'file_and_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. " + "'table_and_file' will store the manifest as a table and a csv on Synapse. " + "'file_only' will store the manifest as a csv only on Synapse." + "'table_file_and_entities' will perform the options file_with_entites and table in combination." + "Default value is 'table_file_and_entities'." ), "table_manipulation":( "Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. " diff --git a/schematic/models/commands.py b/schematic/models/commands.py index 2206e17e9..30da359f5 100644 --- a/schematic/models/commands.py +++ b/schematic/models/commands.py @@ -79,8 +79,8 @@ def model(ctx, config): # use as `schematic model ...` @click.option( "--manifest_record_type", "-mrt", - default='combo', - type=click.Choice(['table', 'file', 'file_w_entities', 'combo'], case_sensitive=True), + default='table_file_and_entities', + type=click.Choice(['table_and_file', 'file_only', 'file_and_entities', 'table_file_and_entities'], case_sensitive=True), help=query_dict(model_commands, ("model", "submit", "manifest_record_type"))) @click.option( "-rr", diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index e7c9fb2e6..addaad697 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1412,7 +1412,7 @@ def upload_manifest_combo( return manifest_synapse_file_id def associateMetadataWithFiles( - self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'combo', + self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'table_file_and_entities', useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', ) -> str: """Associate metadata with files in a storage dataset already on Synapse. @@ -1433,7 +1433,7 @@ def associateMetadataWithFiles( Some datasets, e.g. clinical data, do not contain file id's, but data is stored in a table: one row per item. In this case, the system creates a file on Synapse for each row in the table (e.g. patient, biospecimen) and associates the columnset data as metadata/annotations to his file. datasetId: synapse ID of folder containing the dataset - manifest_record_type: Default value is 'combo'. valid values are 'file', 'file_w_entities', 'table' or 'combo'. 'file_w_entities' will store the manifest as a csv and create Synapse files for each row in the manifest.'table' will store the manifest as a table and a csv on Synapse. 'file' will store the manifest as a csv only on Synapse. 'combo' will perform the options file_with_entites and table in combination. + manifest_record_type: Default value is 'table_file_and_entities'. valid values are 'file_only', 'file_and_entities', 'table_and_file' or 'table_file_and_entities'. 'file_and_entities' will store the manifest as a csv and create Synapse files for each row in the manifest.'table_and_file' will store the manifest as a table and a csv on Synapse. 'file_only' will store the manifest as a csv only on Synapse. 'table_file_and_entities' will perform the options file_with_entites and table in combination. useSchemaLabel: Default is True - use the schema label. If False, uses the display label from the schema. Attribute display names in the schema must not only include characters that are not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'. hideBlanks: Default is false. Boolean flag that does not upload annotation keys with blank values when true. Uploads Annotation keys with empty string values when false. restrict_manifest (bool): Default is false. Flag for censored data. @@ -1452,37 +1452,37 @@ def associateMetadataWithFiles( table_name, component_name = self._generate_table_name(manifest) # Upload manifest to synapse based on user input (manifest_record_type) - if manifest_record_type == "table": - manifest_synapse_file_id = self.upload_manifest_as_table( + + if manifest_record_type == "file_only": + manifest_synapse_file_id = self.upload_manifest_as_csv( se, schemaGenerator, manifest, metadataManifestPath, datasetId=datasetId, - table_name=table_name, - component_name=component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, - table_manipulation=table_manipulation, + component_name = component_name, + with_entities = False, ) - elif manifest_record_type == "file": - manifest_synapse_file_id = self.upload_manifest_as_csv( + elif manifest_record_type == "table_and_file": + manifest_synapse_file_id = self.upload_manifest_as_table( se, schemaGenerator, manifest, metadataManifestPath, datasetId=datasetId, + table_name=table_name, + component_name=component_name, restrict=restrict_manifest, useSchemaLabel=useSchemaLabel, hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, - component_name = component_name, - with_entities = False, + table_manipulation=table_manipulation, ) - - elif manifest_record_type == "file_w_entities": + elif manifest_record_type == "file_and_entities": manifest_synapse_file_id = self.upload_manifest_as_csv( se, schemaGenerator, @@ -1496,7 +1496,7 @@ def associateMetadataWithFiles( component_name = component_name, with_entities=True, ) - elif manifest_record_type == "combo": + elif manifest_record_type == "table_file_and_entities": manifest_synapse_file_id = self.upload_manifest_combo( se, schemaGenerator, @@ -1511,6 +1511,8 @@ def associateMetadataWithFiles( manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, ) + else: + raise ValueError("Please enter a valid manifest_record_type.") return manifest_synapse_file_id def getTableAnnotations(self, table_id:str): diff --git a/tests/test_api.py b/tests/test_api.py index eee206856..87176317e 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -543,7 +543,7 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) @pytest.mark.parametrize("use_schema_label", ['true','false']) - @pytest.mark.parametrize("manifest_record_type", ['table', 'file']) + @pytest.mark.parametrize("manifest_record_type", ['table_and_file', 'file_only']) def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label, manifest_record_type): params = { "input_token": syn_token, @@ -569,11 +569,11 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t params["data_type"] = "MockComponent" # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) assert response_csv.status_code == 200 @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) - @pytest.mark.parametrize("manifest_record_type", ['file_w_entities', 'combo']) + @pytest.mark.parametrize("manifest_record_type", ['file_and_entities', 'table_file_and_entities']) def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, manifest_record_type): params = { "input_token": syn_token, @@ -599,8 +599,11 @@ def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, params["data_type"] = "MockComponent" # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) - assert response_csv.status_code == 200 + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) + try: + assert response_csv.status_code == 200 + except: + breakpoint() @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) diff --git a/tests/test_store.py b/tests/test_store.py index 908e0689f..7e48d2b4a 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -125,7 +125,7 @@ def test_annotation_submission(self, synapse_store, helpers, config): schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = 'syn34295552', - manifest_record_type = 'file_w_entities', + manifest_record_type = 'file_and_entities', useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, @@ -294,7 +294,7 @@ def test_createTable(self, helpers, synapse_store, config, projectId, datasetId) schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = datasetId, - manifest_record_type = 'table', + manifest_record_type = 'table_and_file', useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, @@ -333,7 +333,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = datasetId, - manifest_record_type = 'table', + manifest_record_type = 'table_and_file', useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, @@ -355,7 +355,7 @@ def test_replaceTable(self, helpers, synapse_store, config, projectId, datasetId schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(replacement_manifest_path), datasetId = datasetId, - manifest_record_type = 'table', + manifest_record_type = 'table_and_file', useSchemaLabel = True, hideBlanks = True, restrict_manifest = False, @@ -400,7 +400,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(manifest_path), datasetId = datasetId, - manifest_record_type = 'table', + manifest_record_type = 'table_and_file', useSchemaLabel = False, hideBlanks = True, restrict_manifest = False, @@ -425,7 +425,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) schemaGenerator = sg, metadataManifestPath = helpers.get_data_path(replacement_manifest_path), datasetId = datasetId, - manifest_record_type = 'table', + manifest_record_type = 'table_and_file', useSchemaLabel = False, hideBlanks = True, restrict_manifest = False, From 20c435e07e5e713dc3520543b7dda56713d895a1 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 14:55:51 -0400 Subject: [PATCH 312/615] add log; remove old code; return manifest_data --- schematic/store/synapse.py | 4 ++-- schematic_api/api/routes.py | 9 ++++++--- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c45e1e6b2..88227053f 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -450,10 +450,10 @@ def getDatasetManifest( ] manifest = manifest[["id", "name"]] - censored_regex=re.compile('.*censored.*') # if there is no pre-exisiting manifest in the specified dataset if manifest.empty: + logger.warning(f"Could not find a manifest that fits basename {self.manifest} in asset view and dataset {datasetId}") return "" # if there is an exisiting manifest @@ -461,7 +461,7 @@ def getDatasetManifest( manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, donwload_manifest=True, newManifestName=newManifestName) - return manifest_syn_id + return manifest_data def getDataTypeFromManifest(self, manifestId:str): """Fetch a manifest and return data types of all columns diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 8001e8e56..c361988a4 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -596,7 +596,7 @@ def download_manifest(input_token, manifest_id, new_manifest_name=''): #return local file path manifest_local_file_path = manifest_data['path'] except: - raise(f"Failed to download manifest {manifest_id}") + raise(f"Failed to download manifest: {manifest_id}") return manifest_local_file_path @@ -612,9 +612,12 @@ def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_ manifest_data = store.getDatasetManifest(datasetId=dataset_id, downloadFile=True, newManifestName=new_manifest_name) #return local file path - manifest_local_file_path = manifest_data['path'] + try: + manifest_local_file_path = manifest_data['path'] + except: + raise(f'Failed to download manifest from dataset: {dataset_id}') - # return a json (if as_json = True) + #return a json (if as_json = True) if as_json: manifest_csv = pd.read_csv(manifest_local_file_path) manifest_json = json.loads(manifest_csv.to_json(orient="records")) From d6a8cd1de72eb7d37cfcd19fbcce6c4e872a69d0 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 16 Mar 2023 12:10:30 -0700 Subject: [PATCH 313/615] fix missed naming updates, and remove debugging break --- api/openapi/api.yaml | 4 ++-- schematic/store/synapse.py | 6 +++--- tests/test_api.py | 5 +---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 6ef7e3800..63d301126 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -263,9 +263,9 @@ paths: name: manifest_record_type schema: type: string - enum: ["file_only", "file_w_entities", "table_and_file", "table_file_and_entities"] + enum: ["file_only", "file_and_entities", "table_and_file", "table_file_and_entities"] description: Manifest storage type, will default to "table_file_and_entities" if none selected.'file_and_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. 'table_and_file' will store the manifest as a table and a csv on Synapse. 'file_only' will store the manifest as a csv only on Synapse. 'table_file_and_entities' will perform the options file_with_entites and table in combination. - example: 'table' + example: 'table_and_file' - in: query name: restrict_rules schema: diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index addaad697..a20480a44 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1218,10 +1218,10 @@ def add_entities( ''' for idx, row in manifest.iterrows(): - if not row["entityId"] and (manifest_record_type == 'file_w_entities' or - manifest_record_type == 'combo'): + if not row["entityId"] and (manifest_record_type == 'file_and_entities' or + manifest_record_type == 'table_file_and_entities'): manifest, entityId = self._create_entity_id(idx, row, manifest, datasetId) - elif not row["entityId"] and manifest_record_type == 'table': + elif not row["entityId"] and manifest_record_type == 'table_and_file': # If not using entityIds, fill with manifest_table_id so row["entityId"] = manifest_synapse_table_id manifest.loc[idx, "entityId"] = manifest_synapse_table_id diff --git a/tests/test_api.py b/tests/test_api.py index 87176317e..8375f4aac 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -600,10 +600,7 @@ def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, # test uploading a csv file response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) - try: - assert response_csv.status_code == 200 - except: - breakpoint() + assert response_csv.status_code == 200 @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) From 4de626112786eb595155d6ddd0e163a070ad84c3 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 16:56:02 -0400 Subject: [PATCH 314/615] add tests for getting manifest id and downloading manifest --- tests/data/test_config.yml | 1 + tests/test_store.py | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/tests/data/test_config.yml b/tests/data/test_config.yml index 82631ec11..ed35422d9 100644 --- a/tests/data/test_config.yml +++ b/tests/data/test_config.yml @@ -7,6 +7,7 @@ definitions: synapse: master_fileview: "syn23643253" manifest_basename: "data/manifests/synapse_storage_manifest" + manifest_folder: 'manifests' model: input: diff --git a/tests/test_store.py b/tests/test_store.py index 22ef594ed..55bf6ccf1 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -444,3 +444,41 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) assert IDs.size == 8 # delete table synapse_store.syn.delete(tableId) + + +class TestDownloadManifest: + @pytest.mark.parametrize("datasetFileView", [{"id": ["syn51203973", "syn51203943"], "name": ["synapse_storage_manifest.csv", "synapse_storage_manifest_censored.csv"]}, {"id": ["syn51203973"], "name": ["synapse_storage_manifest.csv"]}, {"id": ["syn51203943"], "name": ["synapse_storage_manifest_censored.csv"]}]) + def test_get_manifest_id(self, synapse_store, datasetFileView): + # rows that contain the censored manifest + datasetFileViewDataFrame = pd.DataFrame(datasetFileView) + row_censored = datasetFileViewDataFrame.loc[datasetFileViewDataFrame['name'] == "synapse_storage_manifest_censored.csv"] + if len(row_censored) > 0: + censored_manifest_id = row_censored['id'].values[0] + # rows that contain the uncensored manifest + row_uncensored = datasetFileViewDataFrame.loc[datasetFileViewDataFrame['name'] == "synapse_storage_manifest.csv"] + if len(row_uncensored) > 0: + uncensored_manifest_id = row_uncensored['id'].values[0] + + # get id of the uncensored manifest + manifest_syn_id = synapse_store._get_manifest_id(datasetFileViewDataFrame) + + # if there are both censored and uncensored manifests, return only id of uncensored manifest + if len(row_uncensored) > 0: + assert manifest_syn_id == uncensored_manifest_id + # if only censored manifests are present, return only id of censored manifest + elif len(row_uncensored) == 0 and len(row_censored) > 0: + assert manifest_syn_id == censored_manifest_id + + @pytest.mark.parametrize("newManifestName",["", "Example"]) + def test_download_manifest(self, config, synapse_store, newManifestName): + # test the download function by downloading a manifest + manifest_data = synapse_store.download_manifest(synapse_store.syn, "syn51203973", True, newManifestName) + assert os.path.exists(manifest_data['path']) + + if not newManifestName: + assert manifest_data["name"] == "synapse_storage_manifest.csv" + else: + assert manifest_data["name"] == "Example.csv" + + # clean up + os.remove(manifest_data['path']) From 240e4c32f7f74c5418488ba9cbe8731eba7372ab Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 18:18:19 -0400 Subject: [PATCH 315/615] add test for getDatasetManifest --- tests/test_store.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/test_store.py b/tests/test_store.py index 55bf6ccf1..c527bf7ab 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -197,6 +197,16 @@ def test_getDatasetProject(self, dataset_id, synapse_store): with pytest.raises(PermissionError): synapse_store.getDatasetProject("syn12345678") + def test_getDatasetManifest(self, synapse_store): + # get a test manifest + manifest_data = synapse_store.getDatasetManifest("syn51204502", True) + + #make sure the file gets downloaded + assert manifest_data['name'] == "synapse_storage_manifest_censored.csv" + assert os.path.exists(manifest_data['path']) + + # clean up + os.remove(manifest_data['path']) class TestDatasetFileView: def test_init(self, dataset_id, dataset_fileview, synapse_store): @@ -482,3 +492,9 @@ def test_download_manifest(self, config, synapse_store, newManifestName): # clean up os.remove(manifest_data['path']) + + # @pytest.mark.parametrize("newManifestName",["", "Example"]) + # def test_getDatasetManifest(self, config, synapse_store, newManifestName, datasetId): + # synapse_store.get_ + + From 8442bb6281884943d2d0a3a7588b35e1764a19e2 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 18:18:43 -0400 Subject: [PATCH 316/615] default manifest_data to an empty str --- schematic/store/synapse.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 88227053f..e13926f83 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -435,6 +435,7 @@ def getDatasetManifest( manifest_data (synapseclient.entity.File): Synapse entity if downloadFile is True. "" (String): No pre-exisiting manifest in dataset. """ + manifest_data = "" # get a list of files containing the manifest for this dataset (if any) all_files = self.storageFileviewTable From 6640360eb82ce7ecd84a48d86b42226f1e98083b Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 16 Mar 2023 18:19:01 -0400 Subject: [PATCH 317/615] edit test_config.yml --- tests/data/test_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/data/test_config.yml b/tests/data/test_config.yml index ed35422d9..72c1dbf9c 100644 --- a/tests/data/test_config.yml +++ b/tests/data/test_config.yml @@ -6,7 +6,7 @@ definitions: synapse: master_fileview: "syn23643253" - manifest_basename: "data/manifests/synapse_storage_manifest" + manifest_basename: "synapse_storage_manifest" manifest_folder: 'manifests' model: From d5e82bca8e75b0079ac0bcf2be61a4c599a6f787 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 20 Mar 2023 09:56:48 -0700 Subject: [PATCH 318/615] Create example.single_rule.model.jsonld --- tests/data/example.single_rule.model.jsonld | 3289 +++++++++++++++++++ 1 file changed, 3289 insertions(+) create mode 100644 tests/data/example.single_rule.model.jsonld diff --git a/tests/data/example.single_rule.model.jsonld b/tests/data/example.single_rule.model.jsonld new file mode 100644 index 000000000..2c220f82a --- /dev/null +++ b/tests/data/example.single_rule.model.jsonld @@ -0,0 +1,3289 @@ +{ + "@context": { + "bts": "http://schema.biothings.io/", + "rdf": "http://www.w3.org/1999/02/22-rdf-syntax-ns#", + "rdfs": "http://www.w3.org/2000/01/rdf-schema#", + "schema": "http://schema.org/", + "xsd": "http://www.w3.org/2001/XMLSchema#" + }, + "@graph": [ + { + "@id": "schema:Text", + "@type": [ + "schema:DataType", + "rdfs:Class" + ], + "rdfs:comment": "Data type: Text.", + "rdfs:label": "Text" + }, + { + "@id": "schema:Number", + "@type": [ + "schema:DataType", + "rdfs:Class" + ], + "rdfs:comment": "Data type: Number.", + "rdfs:label": "Number" + }, + { + "@id": "schema:Integer", + "@type": "rdfs:Class", + "rdfs:comment": "Data type: Integer.", + "rdfs:label": "Integer", + "rdfs:subClassOf": { + "@id": "schema:Number" + } + }, + { + "@id": "schema:Thing", + "@type": "rdfs:Class", + "rdfs:comment": "Thing", + "rdfs:label": "Thing", + "schema:isPartOf": { + "@id": "http://schema.org" + } + }, + { + "@id": "bts:BiologicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "BiologicalEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OntologyClass", + "@type": "rdfs:Class", + "rdfs:comment": "a concept or class in an ontology, vocabulary or thesaurus", + "rdfs:label": "OntologyClass", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RelationshipType", + "@type": "rdfs:Class", + "rdfs:comment": "An OWL property used as an edge label", + "rdfs:label": "RelationshipType", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneOntologyClass", + "@type": "rdfs:Class", + "rdfs:comment": "an ontology class that describes a functional aspect of a gene, gene prodoct or complex", + "rdfs:label": "GeneOntologyClass", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OrganismTaxon", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "OrganismTaxon", + "rdfs:subClassOf": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:OrganismalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A named entity that is either a part of an organism, a whole organism, population or clade of organisms, excluding molecular entities", + "rdfs:label": "OrganismalEntity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:IndividualOrganism", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "IndividualOrganism", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Case", + "@type": "rdfs:Class", + "rdfs:comment": "An individual organism that has a patient role in some clinical context.", + "rdfs:label": "Case", + "rdfs:subClassOf": { + "@id": "bts:IndividualOrganism" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PopulationOfIndividualOrganisms", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PopulationOfIndividualOrganisms", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Biosample", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Biosample", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:DiseaseOrPhenotypicFeature", + "@type": "rdfs:Class", + "rdfs:comment": "Either one of a disease or an individual phenotypic feature. Some knowledge resources such as Monarch treat these as distinct, others such as MESH conflate.", + "rdfs:label": "DiseaseOrPhenotypicFeature", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Disease", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Disease", + "rdfs:subClassOf": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PhenotypicFeature", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PhenotypicFeature", + "rdfs:subClassOf": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Environment", + "@type": "rdfs:Class", + "rdfs:comment": "A feature of the environment of an organism that influences one or more phenotypic features of that organism, potentially mediated by genes", + "rdfs:label": "Environment", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:InformationContentEntity", + "@type": "rdfs:Class", + "rdfs:comment": "a piece of information that typically describes some piece of biology or is used as support.", + "rdfs:label": "InformationContentEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ConfidenceLevel", + "@type": "rdfs:Class", + "rdfs:comment": "Level of confidence in a statement", + "rdfs:label": "ConfidenceLevel", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EvidenceType", + "@type": "rdfs:Class", + "rdfs:comment": "Class of evidence that supports an association", + "rdfs:label": "EvidenceType", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Publication", + "@type": "rdfs:Class", + "rdfs:comment": "Any published piece of information. Can refer to a whole publication, or to a part of it (e.g. a figure, figure legend, or section highlighted by NLP). The scope is intended to be general and include information published on the web as well as journals.", + "rdfs:label": "Publication", + "rdfs:subClassOf": { + "@id": "bts:InformationContentEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MolecularEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A gene, gene product, small molecule or macromolecule (including protein complex)", + "rdfs:label": "MolecularEntity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ChemicalSubstance", + "@type": "rdfs:Class", + "rdfs:comment": "May be a chemical entity or a formulation with a chemical entity as active ingredient, or a complex material with multiple chemical entities as part", + "rdfs:label": "ChemicalSubstance", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Drug", + "@type": "rdfs:Class", + "rdfs:comment": "A substance intended for use in the diagnosis, cure, mitigation, treatment, or prevention of disease", + "rdfs:label": "Drug", + "rdfs:subClassOf": { + "@id": "bts:ChemicalSubstance" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Metabolite", + "@type": "rdfs:Class", + "rdfs:comment": "Any intermediate or product resulting from metabolism. Includes primary and secondary metabolites.", + "rdfs:label": "Metabolite", + "rdfs:subClassOf": { + "@id": "bts:ChemicalSubstance" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:AnatomicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "A subcellular location, cell type or gross anatomical part", + "rdfs:label": "AnatomicalEntity", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:LifeStage", + "@type": "rdfs:Class", + "rdfs:comment": "A stage of development or growth of an organism, including post-natal adult stages", + "rdfs:label": "LifeStage", + "rdfs:subClassOf": { + "@id": "bts:OrganismalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PlanetaryEntity", + "@type": "rdfs:Class", + "rdfs:comment": "Any entity or process that exists at the level of the whole planet", + "rdfs:label": "PlanetaryEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EnvironmentalProcess", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "EnvironmentalProcess", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:EnvironmentalFeature", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "EnvironmentalFeature", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalEntity", + "@type": "rdfs:Class", + "rdfs:comment": "Any entity or process that exists in the clinical domain and outside the biological realm. Diseases are placed under biological entities", + "rdfs:label": "ClinicalEntity", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalTrial", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "ClinicalTrial", + "rdfs:subClassOf": { + "@id": "bts:ClinicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ClinicalIntervention", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "ClinicalIntervention", + "rdfs:subClassOf": { + "@id": "bts:ClinicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Device", + "@type": "rdfs:Class", + "rdfs:comment": "A thing made or adapted for a particular purpose, especially a piece of mechanical or electronic equipment", + "rdfs:label": "Device", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GenomicEntity", + "@type": "rdfs:Class", + "rdfs:comment": "an entity that can either be directly located on a genome (gene, transcript, exon, regulatory region) or is encoded in a genome (protein)", + "rdfs:label": "GenomicEntity", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Genome", + "@type": "rdfs:Class", + "rdfs:comment": "A genome is the sum of genetic material within a cell or virion.", + "rdfs:label": "Genome", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Transcript", + "@type": "rdfs:Class", + "rdfs:comment": "An RNA synthesized on a DNA or RNA template by an RNA polymerase", + "rdfs:label": "Transcript", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Exon", + "@type": "rdfs:Class", + "rdfs:comment": "A region of the transcript sequence within a gene which is not removed from the primary RNA transcript by RNA splicing", + "rdfs:label": "Exon", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CodingSequence", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "CodingSequence", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MacromolecularMachine", + "@type": "rdfs:Class", + "rdfs:comment": "A union of gene, gene product, and macromolecular complex. These are the basic units of function in a cell. They either carry out individual biological activities, or they encode molecules which do this.", + "rdfs:label": "MacromolecularMachine", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneOrGeneProduct", + "@type": "rdfs:Class", + "rdfs:comment": "a union of genes or gene products. Frequently an identifier for one will be used as proxy for another", + "rdfs:label": "GeneOrGeneProduct", + "rdfs:subClassOf": { + "@id": "bts:MacromolecularMachine" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Gene", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Gene", + "rdfs:subClassOf": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneProduct", + "@type": "rdfs:Class", + "rdfs:comment": "The functional molecular product of a single gene. Gene products are either proteins or functional RNA molecules", + "rdfs:label": "GeneProduct", + "rdfs:subClassOf": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Protein", + "@type": "rdfs:Class", + "rdfs:comment": "A gene product that is composed of a chain of amino acid sequences and is produced by ribosome-mediated translation of mRNA", + "rdfs:label": "Protein", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneProductIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "This is an abstract class that can be mixed in with different kinds of gene products to indicate that the gene product is intended to represent a specific isoform rather than a canonical or reference or generic product. The designation of canonical or reference may be arbitrary, or it may represent the superclass of all isoforms.", + "rdfs:label": "GeneProductIsoform", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ProteinIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "Represents a protein that is a specific isoform of the canonical or reference protein. See https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4114032/", + "rdfs:label": "ProteinIsoform", + "rdfs:subClassOf": { + "@id": "bts:Protein" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RnaProduct", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "RnaProduct", + "rdfs:subClassOf": { + "@id": "bts:GeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:RnaProductIsoform", + "@type": "rdfs:Class", + "rdfs:comment": "Represents a protein that is a specific isoform of the canonical or reference RNA", + "rdfs:label": "RnaProductIsoform", + "rdfs:subClassOf": { + "@id": "bts:RnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:NoncodingRnaProduct", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "NoncodingRnaProduct", + "rdfs:subClassOf": { + "@id": "bts:RnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Microrna", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Microrna", + "rdfs:subClassOf": { + "@id": "bts:NoncodingRnaProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MacromolecularComplex", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "MacromolecularComplex", + "rdfs:subClassOf": { + "@id": "bts:MacromolecularMachine" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeneFamily", + "@type": "rdfs:Class", + "rdfs:comment": "any grouping of multiple genes or gene products related by common descent", + "rdfs:label": "GeneFamily", + "rdfs:subClassOf": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Genotype", + "@type": "rdfs:Class", + "rdfs:comment": "An information content entity that describes a genome by specifying the total variation in genomic sequence and/or gene expression, relative to some extablished background", + "rdfs:label": "Genotype", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Haplotype", + "@type": "rdfs:Class", + "rdfs:comment": "A set of zero or more Alleles on a single instance of a Sequence[VMC]", + "rdfs:label": "Haplotype", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:SequenceVariant", + "@type": "rdfs:Class", + "rdfs:comment": "An allele that varies in its sequence from what is considered the reference allele at that locus.", + "rdfs:label": "SequenceVariant", + "rdfs:subClassOf": { + "@id": "bts:GenomicEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:DrugExposure", + "@type": "rdfs:Class", + "rdfs:comment": "A drug exposure is an intake of a particular chemical substance", + "rdfs:label": "DrugExposure", + "rdfs:subClassOf": { + "@id": "bts:Environment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Treatment", + "@type": "rdfs:Class", + "rdfs:comment": "A treatment is targeted at a disease or phenotype and may involve multiple drug 'exposures'", + "rdfs:label": "Treatment", + "rdfs:subClassOf": { + "@id": "bts:Environment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeographicLocation", + "@type": "rdfs:Class", + "rdfs:comment": "a location that can be described in lat/long coordinates", + "rdfs:label": "GeographicLocation", + "rdfs:subClassOf": { + "@id": "bts:PlanetaryEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GeographicLocationAtTime", + "@type": "rdfs:Class", + "rdfs:comment": "a location that can be described in lat/long coordinates, for a particular time", + "rdfs:label": "GeographicLocationAtTime", + "rdfs:subClassOf": { + "@id": "bts:GeographicLocation" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Occurrent", + "@type": "rdfs:Class", + "rdfs:comment": "A processual entity", + "rdfs:label": "Occurrent", + "rdfs:subClassOf": { + "@id": "schema:Thing" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:BiologicalProcessOrActivity", + "@type": "rdfs:Class", + "rdfs:comment": "Either an individual molecular activity, or a collection of causally connected molecular activities", + "rdfs:label": "BiologicalProcessOrActivity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:MolecularActivity", + "@type": "rdfs:Class", + "rdfs:comment": "An execution of a molecular function carried out by a gene product or macromolecular complex.", + "rdfs:label": "MolecularActivity", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcessOrActivity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ActivityAndBehavior", + "@type": "rdfs:Class", + "rdfs:comment": "Activity or behavior of any independent integral living, organization or mechanical actor in the world", + "rdfs:label": "ActivityAndBehavior", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Procedure", + "@type": "rdfs:Class", + "rdfs:comment": "A series of actions conducted in a certain order or manner", + "rdfs:label": "Procedure", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Phenomenon", + "@type": "rdfs:Class", + "rdfs:comment": "a fact or situation that is observed to exist or happen, especially one whose cause or explanation is in question", + "rdfs:label": "Phenomenon", + "rdfs:subClassOf": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:BiologicalProcess", + "@type": "rdfs:Class", + "rdfs:comment": "One or more causally connected executions of molecular functions", + "rdfs:label": "BiologicalProcess", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcessOrActivity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Pathway", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Pathway", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcess" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:PhysiologicalProcess", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "PhysiologicalProcess", + "rdfs:subClassOf": { + "@id": "bts:BiologicalProcess" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CellularComponent", + "@type": "rdfs:Class", + "rdfs:comment": "A location in or around a cell", + "rdfs:label": "CellularComponent", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:Cell", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "Cell", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:CellLine", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "CellLine", + "rdfs:subClassOf": { + "@id": "bts:Biosample" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:GrossAnatomicalStructure", + "@type": "rdfs:Class", + "rdfs:comment": null, + "rdfs:label": "GrossAnatomicalStructure", + "rdfs:subClassOf": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + } + }, + { + "@id": "bts:ensembl", + "@type": "rdf:Property", + "rdfs:comment": "Ensembl ID for gene, protein or transcript", + "rdfs:label": "ensembl", + "schema:domainIncludes": [ + { + "@id": "bts:Transcript" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:hgnc", + "@type": "rdf:Property", + "rdfs:comment": "HGNC ID for gene", + "rdfs:label": "hgnc", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:entrez", + "@type": "rdf:Property", + "rdfs:comment": "Entrez ID for gene", + "rdfs:label": "entrez", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:refseq", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "refseq", + "schema:domainIncludes": [ + { + "@id": "bts:Transcript" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:omim", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "omim", + "schema:domainIncludes": [ + { + "@id": "bts:Disease" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Integer" + } + }, + { + "@id": "bts:umls", + "@type": "rdf:Property", + "rdfs:comment": "Refseq ID for gene, protein or transcript", + "rdfs:label": "umls", + "schema:domainIncludes": { + "@id": "bts:Disease" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "schema:Text" + } + }, + { + "@id": "bts:homologousTo", + "@type": "rdf:Property", + "rdfs:comment": "Shared ancestry between protein or gene", + "rdfs:label": "homologousTo", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:molecularlyInteractsWith", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "molecularlyInteractsWith", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:geneticallyInteractsWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes whose phenotypic effects are dependent on each other in some way - such that their combined phenotypic effects are the result of some interaction between the activity of their gene products. Examples include epistasis and synthetic lethality.", + "rdfs:label": "geneticallyInteractsWith", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Gene" + } + }, + { + "@id": "bts:affectsAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the amount of the other within a system of interest", + "rdfs:label": "affectsAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the amount of the other within a system of interest", + "rdfs:label": "increasesAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesAbundanceOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the amount of the other within a system of interest", + "rdfs:label": "decreasesAbundanceOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the activity of the other within a system of interest", + "rdfs:label": "affectsActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the activity of the other within a system of interest", + "rdfs:label": "increasesActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesActivityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the activity of the other within a system of interest", + "rdfs:label": "decreasesActivityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the level of expression of the other within a system of interest", + "rdfs:label": "affectsExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:increasesExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the level of expression of the other within a system of interest", + "rdfs:label": "increasesExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:decreasesExpressionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the level of expression of the other within a system of interest", + "rdfs:label": "decreasesExpressionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:affectsFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the rate or quality of folding of the other ", + "rdfs:label": "affectsFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate or quality of folding of the other ", + "rdfs:label": "increasesFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesFoldingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate or quality of folding of the other ", + "rdfs:label": "decreasesFoldingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one changes the localization of the other within a system of interest", + "rdfs:label": "affectsLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the proper localization of the other within a system of interest", + "rdfs:label": "increasesLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesLocalizationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the proper localization of the other within a system of interest", + "rdfs:label": "decreasesLocalizationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the metabolic processing of the other within a system of interest", + "rdfs:label": "affectsMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of metabolic processing of the other within a system of interest", + "rdfs:label": "increasesMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesMetabolicProcessingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of metabolic processing of the other within a system of interest", + "rdfs:label": "decreasesMetabolicProcessingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads changes in the molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "affectsMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads to increased molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "increasesMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesMolecularModificationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one leads to decreased molecular modification(s) of the other (e.g. via post-translational modifications of proteins such as the addition of phosphoryl group, or via redox reaction that adds or subtracts electrons)", + "rdfs:label": "decreasesMolecularModificationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of chemical synthesis of the other", + "rdfs:label": "affectsSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of chemical synthesis of the other", + "rdfs:label": "increasesSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesSynthesisOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of chemical synthesis of the other", + "rdfs:label": "decreasesSynthesisOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of degradation of the other within a system of interest", + "rdfs:label": "affectsDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of degradation of the other within a system of interest", + "rdfs:label": "increasesDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesDegradationOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of degradation of the other within a system of interest", + "rdfs:label": "decreasesDegradationOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity impacts the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "affectsMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:increasesMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity increases the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "increasesMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:decreasesMutationRateOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and a genomic entity where the action or effect of the molecular entity decreases the rate of mutation of the genomic entity within a system of interest", + "rdfs:label": "decreasesMutationRateOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GenomicEntity" + } + }, + { + "@id": "bts:affectsResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "affectsResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "increasesResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesResponseTo", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the susceptibility of a biological entity or system (e.g. an organism, cell, cellular component, macromolecular machine, biological or pathological process) to the other", + "rdfs:label": "decreasesResponseTo", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity impacts the splicing of the mRNA", + "rdfs:label": "affectsSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:increasesSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity increases the proper splicing of the mRNA", + "rdfs:label": "increasesSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:decreasesSplicingOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between a molecular entity and an mRNA where the action or effect of the molecular entity decreases the proper splicing of the mRNA", + "rdfs:label": "decreasesSplicingOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Transcript" + } + }, + { + "@id": "bts:affectsStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the stability of the other within a system of interest", + "rdfs:label": "affectsStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the stability of the other within a system of interest", + "rdfs:label": "increasesStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesStabilityOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the stability of the other within a system of interest", + "rdfs:label": "decreasesStabilityOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "affectsTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "increasesTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesTransportOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of transport of the other across some boundary in a system of interest", + "rdfs:label": "decreasesTransportOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "affectsSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "increasesSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesSecretionOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of secretion of the other out of a cell, gland, or organ", + "rdfs:label": "decreasesSecretionOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:affectsUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one impacts the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "affectsUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:increasesUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one increases the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "increasesUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:decreasesUptakeOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two molecular entities where the action or effect of one decreases the rate of uptake of the other into of a cell, gland, or organ", + "rdfs:label": "decreasesUptakeOf", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:regulates,ProcessToProcess", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "regulates,ProcessToProcess", + "schema:domainIncludes": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Occurrent" + } + }, + { + "@id": "bts:regulates,EntityToEntity", + "@type": "rdf:Property", + "rdfs:comment": null, + "rdfs:label": "regulates,EntityToEntity", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:hasGeneProduct", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene and a transcribed and/or translated product generated from it", + "rdfs:label": "hasGeneProduct", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneProduct" + } + }, + { + "@id": "bts:inPathwayWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are part of in the same biological pathway", + "rdfs:label": "inPathwayWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:inComplexWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are part of (or code for products that are part of) in the same macromolecular complex", + "rdfs:label": "inComplexWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:inCellPopulationWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between two genes or gene products that are expressed in the same cell type or population ", + "rdfs:label": "inCellPopulationWith", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:geneAssociatedWithCondition", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene and a disease or phenotypic feature that the gene or its alleles/products may influence, contribute to, or correlate with", + "rdfs:label": "geneAssociatedWithCondition", + "schema:domainIncludes": { + "@id": "bts:Gene" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:treats", + "@type": "rdf:Property", + "rdfs:comment": "holds between a therapeutic procedure or chemical substance and a disease or phenotypic feature that it is used to treat", + "rdfs:label": "treats", + "schema:domainIncludes": { + "@id": "bts:Treatment" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:correlatedWith", + "@type": "rdf:Property", + "rdfs:comment": "holds between a disease or phenotypic feature and a measurable molecular entity that is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "correlatedWith", + "schema:domainIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:hasBiomarker", + "@type": "rdf:Property", + "rdfs:comment": "holds between a disease or phenotypic feature and a measurable molecular entity that is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "hasBiomarker", + "schema:domainIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:MolecularEntity" + } + }, + { + "@id": "bts:biomarkerFor", + "@type": "rdf:Property", + "rdfs:comment": "holds between a measurable molecular entity and a disease or phenotypic feature, where the entity is used as an indicator of the presence or state of the disease or feature.", + "rdfs:label": "biomarkerFor", + "schema:domainIncludes": { + "@id": "bts:MolecularEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:expressedIn", + "@type": "rdf:Property", + "rdfs:comment": "holds between a gene or gene product and an anatomical entity in which it is expressed", + "rdfs:label": "expressedIn", + "schema:domainIncludes": { + "@id": "bts:GeneOrGeneProduct" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:AnatomicalEntity" + } + }, + { + "@id": "bts:expresses", + "@type": "rdf:Property", + "rdfs:comment": "holds between an anatomical entity and gene or gene product that is expressed there", + "rdfs:label": "expresses", + "schema:domainIncludes": { + "@id": "bts:AnatomicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:GeneOrGeneProduct" + } + }, + { + "@id": "bts:hasPhenotype", + "@type": "rdf:Property", + "rdfs:comment": "holds between a biological entity and a phenotype, where a phenotype is construed broadly as any kind of quality of an organism part, a collection of these qualities, or a change in quality or qualities (e.g. abnormally increased temperature). ", + "rdfs:label": "hasPhenotype", + "schema:domainIncludes": { + "@id": "bts:BiologicalEntity" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:DiseaseOrPhenotypicFeature" + } + }, + { + "@id": "bts:precedes", + "@type": "rdf:Property", + "rdfs:comment": "holds between two processes, where one completes before the other begins", + "rdfs:label": "precedes", + "schema:domainIncludes": { + "@id": "bts:Occurrent" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:Occurrent" + } + }, + { + "@id": "bts:subclassOf", + "@type": "rdf:Property", + "rdfs:comment": "holds between two classes where the domain class is a specialization of the range class", + "rdfs:label": "subclassOf", + "schema:domainIncludes": { + "@id": "bts:OntologyClass" + }, + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": { + "@id": "bts:OntologyClass" + } + }, + { + "@id": "bts:Patient", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Patient", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Patient", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:PatientID" + }, + { + "@id": "bts:Sex" + }, + { + "@id": "bts:YearofBirth" + }, + { + "@id": "bts:Diagnosis" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:PatientID", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "PatientID", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Patient ID", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:Sex", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Sex", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Female" + }, + { + "@id": "bts:Male" + }, + { + "@id": "bts:Other" + } + ], + "sms:displayName": "Sex", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:YearofBirth", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "YearofBirth", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Year of Birth", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Diagnosis", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Diagnosis", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Healthy" + }, + { + "@id": "bts:Cancer" + } + ], + "sms:displayName": "Diagnosis", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:Cancer", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Cancer", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Cancer", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:CancerType" + }, + { + "@id": "bts:FamilyHistory" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CancerType", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CancerType", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Breast" + }, + { + "@id": "bts:Colorectal" + }, + { + "@id": "bts:Lung" + }, + { + "@id": "bts:Prostate" + }, + { + "@id": "bts:Skin" + } + ], + "sms:displayName": "Cancer Type", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:FamilyHistory", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FamilyHistory", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Breast" + }, + { + "@id": "bts:Colorectal" + }, + { + "@id": "bts:Lung" + }, + { + "@id": "bts:Prostate" + }, + { + "@id": "bts:Skin" + } + ], + "sms:displayName": "Family History", + "sms:required": "sms:true", + "sms:validationRules": [ + "list strict" + ] + }, + { + "@id": "bts:Biospecimen", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Biospecimen", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Biospecimen", + "sms:required": "sms:false", + "sms:requiresComponent": [ + { + "@id": "bts:Patient" + } + ], + "sms:requiresDependency": [ + { + "@id": "bts:SampleID" + }, + { + "@id": "bts:PatientID" + }, + { + "@id": "bts:TissueStatus" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:SampleID", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "SampleID", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Sample ID", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:TissueStatus", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "TissueStatus", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Healthy" + }, + { + "@id": "bts:Malignant" + } + ], + "sms:displayName": "Tissue Status", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:BulkRNA-seqAssay", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "BulkRNA-seqAssay", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Bulk RNA-seq Assay", + "sms:required": "sms:false", + "sms:requiresComponent": [ + { + "@id": "bts:Biospecimen" + } + ], + "sms:requiresDependency": [ + { + "@id": "bts:Filename" + }, + { + "@id": "bts:SampleID" + }, + { + "@id": "bts:FileFormat" + }, + { + "@id": "bts:Component" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:Filename", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Filename", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Filename", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:FileFormat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FileFormat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:FASTQ" + }, + { + "@id": "bts:BAM" + }, + { + "@id": "bts:CRAM" + }, + { + "@id": "bts:CSV/TSV" + } + ], + "sms:displayName": "File Format", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:BAM", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "BAM", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "BAM", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CRAM", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CRAM", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "CRAM", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + }, + { + "@id": "bts:GenomeFASTA" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CSV/TSV", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CSV/TSV", + "rdfs:subClassOf": [ + { + "@id": "bts:ValidValue" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "CSV/TSV", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:GenomeBuild" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:GenomeBuild", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GenomeBuild", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:GRCh37" + }, + { + "@id": "bts:GRCh38" + }, + { + "@id": "bts:GRCm38" + }, + { + "@id": "bts:GRCm39" + } + ], + "sms:displayName": "Genome Build", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:GenomeFASTA", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GenomeFASTA", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Genome FASTA", + "sms:required": "sms:true", + "sms:validationRules": [] + }, + { + "@id": "bts:MockComponent", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockComponent", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockComponent", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:Component" + }, + { + "@id": "bts:CheckList" + }, + { + "@id": "bts:CheckRegexList" + }, + { + "@id": "bts:CheckRegexSingle" + }, + { + "@id": "bts:CheckRegexFormat" + }, + { + "@id": "bts:CheckNum" + }, + { + "@id": "bts:CheckFloat" + }, + { + "@id": "bts:CheckInt" + }, + { + "@id": "bts:CheckString" + }, + { + "@id": "bts:CheckURL" + }, + { + "@id": "bts:CheckMatchatLeast" + }, + { + "@id": "bts:CheckMatchatLeastvalues" + }, + { + "@id": "bts:CheckMatchExactly" + }, + { + "@id": "bts:CheckMatchExactlyvalues" + }, + { + "@id": "bts:CheckRecommended" + }, + { + "@id": "bts:CheckAges" + }, + { + "@id": "bts:CheckUnique" + }, + { + "@id": "bts:CheckRange" + }, + { + "@id": "bts:CheckDate" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:CheckList", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckList", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "schema:rangeIncludes": [ + { + "@id": "bts:Ab" + }, + { + "@id": "bts:Cd" + }, + { + "@id": "bts:Ef" + }, + { + "@id": "bts:Gh" + } + ], + "sms:displayName": "Check List", + "sms:required": "sms:false", + "sms:validationRules": [ + "list strict error" + ] + }, + { + "@id": "bts:CheckRegexList", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexList", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex List", + "sms:required": "sms:false", + "sms:validationRules": [ + "list strict error", + "regex match [a-f] error" + ] + }, + { + "@id": "bts:CheckRegexSingle", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexSingle", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex Single", + "sms:required": "sms:false", + "sms:validationRules": [ + "regex search [a-f] error" + ] + }, + { + "@id": "bts:CheckRegexFormat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRegexFormat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Regex Format", + "sms:required": "sms:false", + "sms:validationRules": [ + "regex match [a-f] error" + ] + }, + { + "@id": "bts:CheckNum", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckNum", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Num", + "sms:required": "sms:false", + "sms:validationRules": [ + "num error" + ] + }, + { + "@id": "bts:CheckFloat", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckFloat", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Float", + "sms:required": "sms:false", + "sms:validationRules": [ + "float error" + ] + }, + { + "@id": "bts:CheckInt", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckInt", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Int", + "sms:required": "sms:false", + "sms:validationRules": [ + "int error" + ] + }, + { + "@id": "bts:CheckString", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckString", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check String", + "sms:required": "sms:false", + "sms:validationRules": [ + "str error" + ] + }, + { + "@id": "bts:CheckURL", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckURL", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check URL", + "sms:required": "sms:false", + "sms:validationRules": [ + "url error" + ] + }, + { + "@id": "bts:CheckMatchatLeast", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchatLeast", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match at Least", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchAtLeastOne Patient.PatientID set warning" + ] + }, + { + "@id": "bts:CheckMatchExactly", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchExactly", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match Exactly", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchExactlyOne MockComponent.checkMatchExactly set warning" + ] + }, + { + "@id": "bts:CheckMatchatLeastvalues", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchatLeastvalues", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match at Least values", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchAtLeastOne MockComponent.checkMatchatLeastvalues value warning" + ] + }, + { + "@id": "bts:CheckMatchExactlyvalues", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckMatchExactlyvalues", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Match Exactly values", + "sms:required": "sms:false", + "sms:validationRules": [ + "matchExactlyOne MockComponent.checkMatchExactlyvalues value warning" + ] + }, + { + "@id": "bts:CheckRecommended", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRecommended", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Recommended", + "sms:required": "sms:false", + "sms:validationRules": [ + "recommended warning" + ] + }, + { + "@id": "bts:CheckAges", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckAges", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Ages", + "sms:required": "sms:false", + "sms:validationRules": [ + "protectAges warning" + ] + }, + { + "@id": "bts:CheckUnique", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckUnique", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Unique", + "sms:required": "sms:false", + "sms:validationRules": [ + "unique error" + ] + }, + { + "@id": "bts:CheckRange", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckRange", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Range", + "sms:required": "sms:false", + "sms:validationRules": [ + "inRange 50 100 error" + ] + }, + { + "@id": "bts:CheckDate", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckDate", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check Date", + "sms:required": "sms:false", + "sms:validationRules": [ + "date error" + ] + }, + { + "@id": "bts:MockRDB", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDB", + "rdfs:subClassOf": [ + { + "@id": "bts:DataType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB", + "sms:required": "sms:false", + "sms:requiresDependency": [ + { + "@id": "bts:Component" + }, + { + "@id": "bts:MockRDBId" + } + ], + "sms:validationRules": [] + }, + { + "@id": "bts:MockRDBId", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockRDBId", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "MockRDB_id", + "sms:required": "sms:true", + "sms:validationRules": [ + "int" + ] + }, + { + "@id": "bts:Component", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Component", + "rdfs:subClassOf": [ + { + "@id": "bts:Patient" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Component", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Female", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Female", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Female", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Male", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Male", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Male", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Other", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Other", + "rdfs:subClassOf": [ + { + "@id": "bts:Sex" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Other", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Healthy", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Healthy", + "rdfs:subClassOf": [ + { + "@id": "bts:Diagnosis" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Healthy", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Breast", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Breast", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Breast", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Colorectal", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Colorectal", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Colorectal", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Lung", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Lung", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Lung", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Prostate", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Prostate", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Prostate", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Skin", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Skin", + "rdfs:subClassOf": [ + { + "@id": "bts:CancerType" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Skin", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Malignant", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Malignant", + "rdfs:subClassOf": [ + { + "@id": "bts:TissueStatus" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Malignant", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:FASTQ", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "FASTQ", + "rdfs:subClassOf": [ + { + "@id": "bts:FileFormat" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "FASTQ", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCh37", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCh37", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCh37", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCh38", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCh38", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCh38", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCm38", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCm38", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCm38", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:GRCm39", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "GRCm39", + "rdfs:subClassOf": [ + { + "@id": "bts:GenomeBuild" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "GRCm39", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Ab", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Ab", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "ab", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Cd", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Cd", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "cd", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Ef", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Ef", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "ef", + "sms:required": "sms:false", + "sms:validationRules": [] + }, + { + "@id": "bts:Gh", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "Gh", + "rdfs:subClassOf": [ + { + "@id": "bts:CheckList" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "gh", + "sms:required": "sms:false", + "sms:validationRules": [] + } + ], + "@id": "http://schema.biothings.io/#0.1" +} \ No newline at end of file From 3a65d4b1c345ee6c88a1f34215cc9678086adc11 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 20 Mar 2023 13:37:23 -0400 Subject: [PATCH 319/615] fix bug --if only censored manifest is available, use censored manifest --- schematic/store/synapse.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 21d22e7d1..bec5f9425 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -378,6 +378,9 @@ def getDatasetManifest( not_censored=~censored if any(not_censored): manifest_syn_id=manifest[not_censored]["id"][0] + # If only censored manifests are available, use the first censored manifest + else: + manifest_syn_id=manifest["id"][0] #otherwise, use the first (implied only) version that exists else: From 893a8352e11409ec1e7dc328f82222c64d209fea Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 20 Mar 2023 22:15:02 -0400 Subject: [PATCH 320/615] fix modifying cell --- schematic/manifest/generator.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index c1c22b71c..2f36ae568 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1593,6 +1593,8 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a Args: existing_excel_path: path of an existing excel spreadsheet additional_df: additional dataframe + Return: + added new dataframe to the existing excel path. ''' # load workbook workbook = load_workbook(existing_excel_path) @@ -1612,14 +1614,15 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.worksheets["Sheet1"] - # add additional content to the existing spreadsheet - additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) - # if there are new columns, add them to the end of spreadsheet + # Note: previously, we tried looping through the out of schema columns and use worksheet.cell to modify a particular cell. But that functionality is no longer working. if len(out_of_schema_columns_lst) > 0: - for i, col_name in enumerate(out_of_schema_columns_lst): - col_index = len(workbook_headers) + 1 + i - worksheet.cell(row=1, column=col_index).value = col_name + df_additional_headers = pd.DataFrame(columns=out_of_schema_columns_lst) + start_col_index = len(workbook_headers) + df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index = False, header=True) + + # add additional content to the existing spreadsheet + additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. From 5c2f025a2959a08cc630474560a88b40d85cc14e Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 20 Mar 2023 22:16:39 -0400 Subject: [PATCH 321/615] add test manifest and tests --- .../test_bulkRNAseq_manifest.xlsx | Bin 0 -> 4979 bytes tests/test_manifest.py | 44 ++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx diff --git a/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx b/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..73a603bb46974e99e8cd766ff0cb777f65f56179 GIT binary patch literal 4979 zcmZ`-1ymGm+g?gqSVE9Sx?8%XTPazjmyncB374*2Qb}o)Sdb3sM!G>l8UdwT0f}$b z^MAhbzu(N6XU?26*FE=h&E48+Xy_yW000Z%QQ@wyXw;4uf_$n(UWCZY%Gpxe)!D_3 z$K1t*+uPAWBTfUigO~8Zwd&5IlimRxAKhf$O2417@O`M2yl3cz|D*Q!1&Jlzm`2h8 z!!8Cdp|Gx^=fHj?KrOCfr~Jg5yGl$Hc7`-E!#>f(b2eR!6_mYbW~Ax@!|4~)do^NP zRLw%GY&#`&p)WJsQ=js&o~GI#$A!)`)7CnlnPapjo?~eLr7va@W721&o`Wa=0Pvss zS~|Oee=1x6)6nYV#S6P0Nb=hil%>ioPtC~;gLE+x*0CPeMs3PR>NEvvfogA~3&$P) zIIS$3WM(HOk}4qN(~0&Gsvouiucl>23r5 zW~nb(TN}~SHsecl_D}7TREpX1ts7ah!pp;)yU+Q5lmvMSX==O2)mzW3D>%_0K+{;< zR_$Q=w~}O0Y91`h%ro&<>7y76H1mPv@Q}hV)9Yz})W3;&Wt_o4cnbi?U;zM#k;HgA z@VMK89l^g>zMs_W8-d*BMM$21g^zmMARKXf?g!Ua6T8`YE>ypQ>}%470u5swe5_!Q zz*eREgo7#g`w1G2=@RIiJ3odMl(x1-e2%|xTWp6#BprF1&G9TuH`Vbhtr+k#0%dvc z7QqkNa0=8-YK-gvogxAK#6+DRL!zm)f=<|r=)|rvEV!uVgp&`hKTB;Gl%Yr`6Vgv$c`8_f3OoTr6FD5uyfJ6 zrcuNv-Hxudr#901_Pt}{%0VIh0ZAB*Du}!ZQY?Oaaj{IpVNZWV*M4@)z`VPlBgM+v zp|?ow;CQqP75a)!Q&vaji9>6?EOvFC-Kfv?eUh~JiR6|mfRPtrPw?drV)85H# zhh-TO)Wk$XNw~LU!%`WUiQb4l*H9+D;wYHE%9xNjNaA5USB1sfRWTH~GY@SGP_!$; zDLuk%$0dBPFwQcBaHwFE)TlO;Rf_ZwyQTvgIAdH|SqG3qPRio$eG1o_JHfTj-ayQZ zh1u^r|9%H|U=s(SV8!jkSOv8_Zao9j3wc+cH zBb?IHtX&@BhjKkOFWgab8qy{j$Q>|J@U`JYGH1L_m?6NXeIgpPr04|d`ccj|KO@M^ zYH8p))Yq#EPh^`F&2HPfw3W&_+&`aVguv4tb1~e3ss&fcGS**24;-*}VQ*W3n6L+R zC&0o{L|Jl_PCJjjsV2{Cz#CZWB|z&t@Emt3&XF?-)2-?uTmktySGCWzNi8+ZBC02q zA6ztP2JysgBoe4=y-nZC41?$H(`adaqU zFboq#d5u1 zGAUV2CaHLw_iBZvD%>sIx4uK6^xANm=8S(?)MY_z3C(1am{UIgd3!)qR1mPlqNNe8 zb;gt-UhQ`nOqYH!y^xPsT*337EHNsu;s8pkVfxc1+_H=Tod}x7lUS4$R+jb5^Wpgf z86M;1Sc@!&E2L2fOhuQ9#^N~3PRVRYFHGXwBJc&NU>GKRuWIk-t!v^)e7yRKU(wMO z_h~=673J>)Qpt6+mV(Txuh0Mh^4|%>%h}c5%@z!HcjNhW`;|pv6CIrw=m>jTaaJ!? zDeQK2=Tb7POnzACC6_MP6J=YHtQd>T?AFmj!>toi5u{$2t=E!(xge)45WpfZrdDc; zOUH`?vRrMJ-`a88Vb*T+u1dQH=#x0+J5A`Ah1e^9pd$NVG-o%>6PUS{(PMA-58r!~ zzl)*8$`8ZO_$qW4QXa~XJZ7n@K=u8MN@)CS{7o{-E~(Mx>wX`f0FVYTO!ML)@2Nm~ zxAk;H)Aq+1(d@1?na;3W2;Ly>2ie_X5_TV{h@-lEm_%Ltk=|$Nq`DNE&Emk4wE2v{ zjnXhhL|Tf-$M&3}5oacD#{PS5BD`ejT<c5Wrn#EIqbyn_nz~G3@>X9AROb`q6ZJCG{W!fk)QALpHp*Em{pnV_(IC19vEzV zwmIYB>KN5Z%%)*!eR-v1JH5MjlykBEso}(=B`z|uiX&DF5$+BGOHPcU5A{!J)O*(j zqWOhas1?9rSQ`8b2Oe$RXy&c5`H95KD?7q>0&o1w?}&KpB2)mt5f=c!|NSrB+R_Mg4`ibY8+s(k{#-4Q-ubx%~U%s>$uK;O~ZL3foJ*_1g%uvQgZBd%~^pZm3bn_aWEB>!A1QhwHEU*%$fQo^o_p7eXX% zU5?v(DpI72M1&dabd-dpR+s}*$)8piK<-c5SFJGn&%j(FPkRC4kffQzV2i3RuiQR< z_A^9Jm}%+By>Q>7Z+Q>y?LM;fZ9gDzc|^J3;d>>mkkNd;$IDAmNODYF3e$J%KvSJ#91%91OAQO4TjYGuJ0mSEU*U zGI~1%62(XN#(YV}v8fF*Z7Ir4>i~P=`kh+s$!N1v2Pv`Rl9}!7nd@JhfqCpBO*9pE zp3N`@cIp_DOxWGBkrTdXOLsJ$57_TUM|Yuw^Y#gkzHh~fu)=@_5i$nA%%P=i3;~z% zK4sg@sLG1DeXqJAuah1(yEb04KQ^DJGk+1|6DT@)SOWH@MPdbU{m!sU8sDe zvla3Yxb=}+d9S))mR%=^*x5EZTcFx?Ru&hWK=8FEmD@srLl1A4@tnR;8Q`5gn_1Sg zTtjvtH5slPLFnkWSwhauW2Qc?PN(TQb+-$Z6CBuXqgyrD3y0(z%4vCL8iT65(cH5j z0k!L)k0UsfX_@fSy^A8DgTfET-{_#ZN(wHVC$N0=XwM|LRMuik{&9h&MYZ?x_Vw{- zF^S|^YbI|&Rt}WfeCBX>Vl&|FO z`yfE2wanvKO)j#$Dudyp!8r7{r;l{=-YJNjEr-rpE1lHKzc_mQ_T>I+{^;9WSvlN# zIsD7xJ23K*^#|!1-B#*vm^;mIISnsi!eg6FOK15JOYgfs6r_=&%+mR(P)5RE^fN#< za&|+%jA0$9;!5y-qizi7fRLXl#JNXRT5Ez>^>UdBa>{qx+nP7!8!iftjEyA1Jwme@V-7hU2nm-@m{%u79yK9YQNK$_w38wf> z?r%f-C&j;vss<)``vosvD4b{mKwdnVgIdU4N=gPOhi{-7@*f&7y#vKlb`|U;vtk441UE}k2n)yM4L_nTf zcJWm^iGjWa(&0}&?i(}+jVRTZ(XX8BuHM*WdYBx961l+{WFr6B34-LEo!r4r?xwmv zE?~DOKdq=Napb2J^_UiX_IN5F;v%!l9mBELh70L>lDC;{;q2}lzwl1=btQhXT3!$0 zyW0g*Nu4G72QeE-eII!e+EAIPphUwktSkl(Wlf^%!pw+=HLjSe&l~&+*}YM`zwmy1m28;e}FJ#MT6Y>KV9}F_@ Date: Mon, 20 Mar 2023 22:40:32 -0400 Subject: [PATCH 322/615] create dummy test and clean up --- tests/test_manifest.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 5a5cf29bb..e03a0ac3d 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -1,4 +1,5 @@ import os +import shutil import logging import pytest @@ -195,18 +196,22 @@ def test_get_missing_columns(self, manifest_generator, wb_headers, manifest_colu assert "column four" not in missing_columns @pytest.mark.parametrize("additional_df_dict", [{'test one column': ['a', 'b'], 'test two column': ['c', 'd']}, None]) - def test_populate_existing_excel_spreadsheet(self,simple_manifest_generator,simple_test_manifest_excel, additional_df_dict): - generator = simple_manifest_generator + def test_populate_existing_excel_spreadsheet(self, manifest_generator,simple_test_manifest_excel, additional_df_dict): + generator, use_annotations, data_type = manifest_generator if additional_df_dict: additional_test_df = pd.DataFrame(additional_df_dict) else: additional_test_df = pd.DataFrame() + + # copy the existing excel file + dummy_output_path = "tests/data/mock_manifests/dummy_output.xlsx" + shutil.copy(simple_test_manifest_excel, dummy_output_path) # added new content to an existing excel spreadsheet if applicable - generator.populate_existing_excel_spreadsheet(simple_test_manifest_excel, additional_test_df) + generator.populate_existing_excel_spreadsheet(dummy_output_path, additional_test_df) # read the new excel spreadsheet and see if columns have been added - new_df = pd.read_excel(simple_test_manifest_excel) + new_df = pd.read_excel(dummy_output_path) # if we are not adding any additional content if additional_test_df.empty: @@ -215,12 +220,9 @@ def test_populate_existing_excel_spreadsheet(self,simple_manifest_generator,simp else: # new columns get added assert not new_df[["test one column", "test two column"]].empty - - # lastly, drop the dataframe that get added and revert the testing manifest back to normal - df_revert = new_df.drop(columns=additional_test_df.columns, axis=1) - writer = pd.ExcelWriter(simple_test_manifest_excel) - df_revert.to_excel(writer, sheet_name = 'Sheet1', index=False) - writer.save() + # remove file + os.remove(dummy_output_path) + From 5ae41623a386e77e252f6eef7839ef6e320bcad3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 21 Mar 2023 10:45:56 -0700 Subject: [PATCH 323/615] change suffix of temp file --- api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index c87d5b819..2c2bad567 100644 --- a/api/routes.py +++ b/api/routes.py @@ -198,7 +198,7 @@ def initalize_metadata_model(schema_url): def get_temp_jsonld(schema_url): # retrieve a JSON-LD via URL and store it in a temporary location with urllib.request.urlopen(schema_url) as response: - with tempfile.NamedTemporaryFile(delete=False, suffix=".jsonld") as tmp_file: + with tempfile.NamedTemporaryFile(delete=False, suffix=".model.jsonld") as tmp_file: shutil.copyfileobj(response, tmp_file) # get path to temporary JSON-LD file From a03aafb81e125de9607e3d92f02caf49a968a5b4 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 21 Mar 2023 16:35:54 -0400 Subject: [PATCH 324/615] clear old comment --- tests/test_store.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index c527bf7ab..e9e7b9a6c 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -493,8 +493,3 @@ def test_download_manifest(self, config, synapse_store, newManifestName): # clean up os.remove(manifest_data['path']) - # @pytest.mark.parametrize("newManifestName",["", "Example"]) - # def test_getDatasetManifest(self, config, synapse_store, newManifestName, datasetId): - # synapse_store.get_ - - From 7dc60c68ba4aabbe4801668b153440d5ee4a40d6 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 21 Mar 2023 16:49:07 -0400 Subject: [PATCH 325/615] delete old code --- schematic/store/synapse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 7734e1631..40a85dbc9 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -460,7 +460,6 @@ def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, if os.path.exists(manifest_data['path']): # Rename the file we just made to the new name new_manifest_filename = newManifestName + '.csv' - #new_manifest_path_name = manifest_data['path'].replace(manifest['name'][0], new_manifest_filename) dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) os.rename(manifest_data['path'], new_manifest_path_name) From e89dcb09a7337ee463358cc8adc1790637794aff Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 21 Mar 2023 17:14:49 -0400 Subject: [PATCH 326/615] remove while loop --- schematic/store/synapse.py | 41 ++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 40a85dbc9..0f93002d0 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -420,12 +420,11 @@ def _get_manifest_id(self, manifest: pd.DataFrame) -> str: return manifest_syn_id @staticmethod - def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, newManifestName=""): + def download_manifest(syn, manifest_syn_id: str, newManifestName=""): """ Donwload a manifest based on a given manifest id. Args: manifest_syn_id: syn id of a manifest - download_manifest: boolean newManifestName: new name of a manifest that gets downloaded. Return: manifest_data: synapse entity file object @@ -434,27 +433,25 @@ def download_manifest(syn, manifest_syn_id: str, donwload_manifest: bool = True, # enables retrying if user does not have access to uncensored manifest # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location manifest_data = "" - while donwload_manifest: - if 'manifest_folder' in CONFIG['synapse'].keys(): - try: - manifest_data = syn.get( - manifest_syn_id, - downloadLocation=CONFIG["synapse"]["manifest_folder"], - ifcollision="overwrite.local", - ) - break - except(SynapseUnmetAccessRestrictions): - raise(f"You don't have access to the requested resource: {manifest_syn_id}") + if 'manifest_folder' in CONFIG['synapse'].keys(): + try: + manifest_data = syn.get( + manifest_syn_id, + downloadLocation=CONFIG["synapse"]["manifest_folder"], + ifcollision="overwrite.local", + ) + except(SynapseUnmetAccessRestrictions): + raise(f"You don't have access to the requested resource: {manifest_syn_id}") # if no manifest folder is set, download to cache ### TO DO: Deprecate the following? - else: - try: - manifest_data = syn.get( - manifest_syn_id, - ) - break - except(SynapseUnmetAccessRestrictions): - raise(f"You don't have access to the requested resource: {manifest_syn_id}") + else: + try: + manifest_data = syn.get( + manifest_syn_id, + ) + + except(SynapseUnmetAccessRestrictions): + raise(f"You don't have access to the requested resource: {manifest_syn_id}") # Rename manifest file if indicated by user. if newManifestName: if os.path.exists(manifest_data['path']): @@ -511,7 +508,7 @@ def getDatasetManifest( else: manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: - manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, donwload_manifest=True, newManifestName=newManifestName) + manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, newManifestName=newManifestName) return manifest_data def getDataTypeFromManifest(self, manifestId:str): From 8874f15f02c27be14b9013543b60f88b0f634b94 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 11:58:03 -0400 Subject: [PATCH 327/615] fix except statement --- schematic/store/synapse.py | 12 ++++++------ schematic_api/api/routes.py | 18 +++++++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 5ef3a5f9d..d006b9d57 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -440,18 +440,18 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): downloadLocation=CONFIG["synapse"]["manifest_folder"], ifcollision="overwrite.local", ) - except(SynapseUnmetAccessRestrictions): - raise(f"You don't have access to the requested resource: {manifest_syn_id}") - # if no manifest folder is set, download to cache - ### TO DO: Deprecate the following? + except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: + logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") + # if no manifest folder is set, download to cache + ### TO DO: Deprecate the following? else: try: manifest_data = syn.get( manifest_syn_id, ) - except(SynapseUnmetAccessRestrictions): - raise(f"You don't have access to the requested resource: {manifest_syn_id}") + except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: + logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") # Rename manifest file if indicated by user. if newManifestName: if os.path.exists(manifest_data['path']): diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 3b3b5c785..a2dee2cfc 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -4,7 +4,7 @@ import tempfile import shutil import urllib.request - +import logging import connexion from connexion.decorators.uri_parsing import Swagger2URIParser from flask import current_app as app @@ -19,6 +19,7 @@ from schematic.schemas.generator import SchemaGenerator from schematic.schemas.explorer import SchemaExplorer from schematic.store.synapse import SynapseStorage +from synapseclient.core.exceptions import SynapseHTTPError, SynapseAuthenticationError, SynapseUnmetAccessRestrictions from flask_cors import CORS, cross_origin from schematic.schemas.explorer import SchemaExplorer import pandas as pd @@ -40,6 +41,9 @@ # pass from flask_cors import cross_origin +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.DEBUG) + def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): """ The function was initially taken from: https://towardsdatascience.com/how-to-profile-your-code-in-python-e70c834fad89 @@ -618,15 +622,15 @@ def download_manifest(input_token, manifest_id, new_manifest_name=''): # try logging in to asset store try: syn = store.login(input_token=input_token) - except: - raise("Failed to log in to asset store. Please check your credentials") - manifest_data = store.download_manifest(syn, manifest_id, True, new_manifest_name) + except Exception: + raise SynapseAuthenticationError try: + manifest_data = store.download_manifest(syn, manifest_id, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] - except: - raise(f"Failed to download manifest: {manifest_id}") - + except Exception: + logger.error(f"Failed to download manifest: {manifest_id}") + raise Exception(f"Failed to download manifest: {manifest_id}") return manifest_local_file_path #@profile(sort_by='cumulative', strip_dirs=True) From 28c6499ff6d0517e00675fe557ad3e15b2f8b7ff Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 13:52:49 -0400 Subject: [PATCH 328/615] add tests --- schematic_api/api/openapi/api.yaml | 4 ++++ schematic_api/api/routes.py | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index a77a0dec5..cc506e666 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -135,6 +135,10 @@ paths: text/csv: schema: type: string + "403": + description: You don't have access to the requested resources. + "500": + description: Please check schematic log tags: - Manifest Operations /dataset/manifest/download: diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index a2dee2cfc..87aa1b0fa 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -613,6 +613,15 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] def download_manifest(input_token, manifest_id, new_manifest_name=''): + """ + Donwload a manifest based on a given manifest id. + Args: + input_token: token of asset store + manifest_syn_id: syn id of a manifest + newManifestName: new name of a manifest that gets downloaded. + Return: + file path of the downloaded manifest + """ # call config_handler() config_handler() From dc4623f78b3f62f878f0f622efc392b213e78ceb Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 13:53:15 -0400 Subject: [PATCH 329/615] add test --- tests/test_api.py | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 95e7d61d2..04ce62cca 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -10,6 +10,7 @@ from time import perf_counter import pandas as pd # third party library import from schematic.schemas.generator import SchemaGenerator #Local application/library specific imports. +from pathlib import Path logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -576,9 +577,37 @@ def test_get_datatype_manifest(self, client, syn_token): "Year of Birth": "Int64", "entityId": "string"} + @pytest.mark.parametrize("manifest_id",["syn51156998"]) + @pytest.mark.parametrize("new_manifest_name",["Example", None]) + def test_manifest_download(self, client, syn_token, manifest_id, new_manifest_name): + params = { + "input_token": syn_token, + "manifest_id": manifest_id, + "new_manifest_name": new_manifest_name + + } + + response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) + assert response.status_code == 200 + file_path = response.data.decode() + + assert os.path.exists(file_path) + file_base_name = os.path.basename(file_path) + file_name = os.path.splitext(file_base_name)[0] + + if new_manifest_name: + assert file_name == new_manifest_name + + # delete files + try: + os.remove(file_path) + except: + pass + + @pytest.mark.parametrize("as_json", [None, True, False]) @pytest.mark.parametrize("new_manifest_name", [None, "Test"]) - def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): + def test_dataset_manifest_download(self, client, as_json, syn_token, new_manifest_name): params = { "input_token": syn_token, "asset_view": "syn28559058", @@ -587,7 +616,7 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): "new_manifest_name": new_manifest_name } - response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) + response = client.get('http://localhost:3001/v1/dataset/manifest/download', query_string = params) assert response.status_code == 200 response_dt = response.data From 12055ea6e82c012fc91a38c7327cbe43a6077f8f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 22 Mar 2023 11:40:12 -0700 Subject: [PATCH 330/615] add test for component visualization --- tests/test_api.py | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 7471389cb..035de55c9 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -714,6 +714,47 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 + def test_visualize_component(self, client, data_model_jsonld): + response_body = """ + b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\r\n + Patient ID,Patient ID,PatientID,TBD,True,,,,Patient\r\n + Component,Component,Component,TBD,False,,,,Patient\r\n + Sex,Sex,Sex,TBD,True,,"[\'Female\', \'Other\', \'Male\']",,Patient\r\n + Year of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\r\n + Diagnosis,Diagnosis,Diagnosis,TBD,True,,"[\'Healthy\', \'Cancer\']",,Patient\r\n + """ + + ex_response_body = """ + b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\r\n + Patient ID,Patient ID,PatientID,TBD,True,,,,Biospecimen\r\n + Tissue Status,Tissue Status,TissueStatus,TBD,True,,"[\'Malignant\', \'Healthy\']",,Biospecimen\r\n + Component,Component,Component,TBD,False,,,,Biospecimen\r\n + Sample ID,Sample ID,SampleID,TBD,True,,,,Biospecimen\r\n + Patient ID,Patient ID,PatientID,TBD,True,,,,Patient\r\n + Sex,Sex,Sex,TBD,True,,"[\'Female\', \'Other\', \'Male\']",,Patient\r\n + Year of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\r\n + Component,Component,Component,TBD,False,,,,Patient\r\n + Diagnosis,Diagnosis,Diagnosis,TBD,True,,"[\'Healthy\', \'Cancer\']",,Patient\r\n + Family History,Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient\r\n + Cancer Type,Cancer Type,CancerType,TBD,False,True,"[\'Colorectal\', \'Lung\', \'Breast\', \'Prostate\', \'Skin\', \'\']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient\r\n + Filename,Filename,Filename,TBD,True,,,,BulkRNA-seqAssay\r\n + Component,Component,Component,TBD,False,,,,BulkRNA-seqAssay\r\n + File Format,File Format,FileFormat,TBD,True,,"[\'CRAM\', \'CSV/TSV\', \'BAM\', \'FASTQ\']",,BulkRNA-seqAssay\r\n + Sample ID,Sample ID,SampleID,TBD,True,,,,BulkRNA-seqAssay\r\n + Genome Build,Genome Build,GenomeBuild,TBD,False,True,"[\'GRCm38\', \'GRCm39\', \'GRCh37\', \'GRCh38\', \'\']"," If File Format is ""CRAM"" OR ""CSV/TSV"" OR ""BAM"" then ""Genome Build"" is required",BulkRNA-seqAssay\r\n + Genome FASTA,Genome FASTA,GenomeFASTA,TBD,False,True,," If File Format is ""CRAM"" then ""Genome FASTA"" is required",BulkRNA-seqAssay\r\n' + """ + + params = { + "schema_url": data_model_jsonld, + "component": "Patient" + } + + response = client.get("http://localhost:3001/v1/visualize/component", query_string = params) + + assert response.status_code == 200 + assert response.response[0] == response_body + @pytest.mark.schematic_api class TestValidationBenchmark(): From a926f802c6849a36a2a7459dd65078f3dde9e872 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 22 Mar 2023 11:53:30 -0700 Subject: [PATCH 331/615] add endpoint and function --- api/openapi/api.yaml | 36 +++++++++++++++++++++++++++++++++++- api/routes.py | 9 +++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index fcc2811f9..8ed7ff929 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -1151,4 +1151,38 @@ paths: schema: type: string tags: - - Visualization Operations \ No newline at end of file + - Visualization Operations + /visualize/component: + get: + summary: Get an attributes table for a specific component of a data model, as a CSV (JSON String) + description: >- + Get all the attributes associated with a specific data model component formatted as a + dataframe (stored as a JSON String). + operationId: api.routes.get_viz_component_attributes_explorer + parameters: + - in: query + name: schema_url + schema: + type: string + description: Data Model URL + example: >- + https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld + required: true + - in: query + name: component + schema: + type: string + description: Component of the data model to explore + example: >- + Patient + required: true + responses: + "200": + description: Returns a CSV as a JSON String. + content: + text/csv: + schema: + type: string + tags: + - Visualization Operations + \ No newline at end of file diff --git a/api/routes.py b/api/routes.py index 2c2bad567..5d6327682 100644 --- a/api/routes.py +++ b/api/routes.py @@ -510,6 +510,15 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv +def get_viz_component_attributes_explorer(schema_url): + # call config_handler() + config_handler() + + temp_path_to_jsonld = get_temp_jsonld(schema_url) + + + return + def get_viz_tangled_tree_text(schema_url, figure_type, text_format): temp_path_to_jsonld = get_temp_jsonld(schema_url) From d51a47edf2db7cfea67a5d88904fbae34e4629d3 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 15:52:41 -0400 Subject: [PATCH 332/615] remove unused lib --- tests/test_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 04ce62cca..e81bc41a6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -10,7 +10,6 @@ from time import perf_counter import pandas as pd # third party library import from schematic.schemas.generator import SchemaGenerator #Local application/library specific imports. -from pathlib import Path logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) From a00dc920358233982628ccf0a722fe5b5b2e61da Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 16:18:43 -0400 Subject: [PATCH 333/615] add as_json parameter --- schematic_api/api/openapi/api.yaml | 7 +++++++ schematic_api/api/routes.py | 21 ++++++++++++++++----- 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index cc506e666..4320274a7 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -127,6 +127,13 @@ paths: nullable: true description: Fill in if you want to change the filename of the downloaded manifest. required: false + - in: query + name: as_json + schema: + type: boolean + default: True + description: if True return the manifest in JSON format. Default to True + required: false operationId: schematic_api.api.routes.download_manifest responses: "200": diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 87aa1b0fa..d8c5e7b5b 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -238,7 +238,15 @@ def parse_bool(str_bool): raise ValueError( "String boolean does not appear to be true or false. Please verify input." ) - + +def return_as_json(manifest_local_file_path): + manifest_csv = pd.read_csv(manifest_local_file_path) + try: + manifest_json = json.loads(manifest_csv.to_json(orient="records")) + return manifest_json + except Exception: + raise Exception(f"Fail to return the manifest as a json") + def save_file(file_key="csv_file"): ''' input: @@ -612,13 +620,14 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -def download_manifest(input_token, manifest_id, new_manifest_name=''): +def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=True): """ Donwload a manifest based on a given manifest id. Args: input_token: token of asset store manifest_syn_id: syn id of a manifest newManifestName: new name of a manifest that gets downloaded. + as_json: boolean; If true, return a manifest as a json. Default to True Return: file path of the downloaded manifest """ @@ -640,6 +649,9 @@ def download_manifest(input_token, manifest_id, new_manifest_name=''): except Exception: logger.error(f"Failed to download manifest: {manifest_id}") raise Exception(f"Failed to download manifest: {manifest_id}") + if as_json: + manifest_json = return_as_json(manifest_local_file_path) + return manifest_json return manifest_local_file_path #@profile(sort_by='cumulative', strip_dirs=True) @@ -660,9 +672,8 @@ def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_ raise(f'Failed to download manifest from dataset: {dataset_id}') #return a json (if as_json = True) - if as_json: - manifest_csv = pd.read_csv(manifest_local_file_path) - manifest_json = json.loads(manifest_csv.to_json(orient="records")) + if as_json: + manifest_json = return_as_json(manifest_local_file_path) return manifest_json return manifest_local_file_path From a958c64f395b136dc1a3dd3c971083bdba44113c Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 16:19:02 -0400 Subject: [PATCH 334/615] check entity type --- schematic/store/synapse.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d006b9d57..361f90e4c 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -433,6 +433,11 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): # enables retrying if user does not have access to uncensored manifest # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location manifest_data = "" + # check the type of synapse entity type + type_entity = syn.checkEntityType(manifest_syn_id) + if type_entity != "file": + logger.error('You are using a wrong entity type. Please try downloading with manifest id') + raise ('You are using a wrong entity type. Please try downloading with manifest id') if 'manifest_folder' in CONFIG['synapse'].keys(): try: manifest_data = syn.get( @@ -440,6 +445,7 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): downloadLocation=CONFIG["synapse"]["manifest_folder"], ifcollision="overwrite.local", ) + print('manifest data', manifest_data) except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") # if no manifest folder is set, download to cache From 112f79a7c23253dbb31fb1981a13bcdfba164e80 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 16:21:43 -0400 Subject: [PATCH 335/615] edit comment --- schematic/store/synapse.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 361f90e4c..70231ef9d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -130,6 +130,8 @@ def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): remaining_space = total_ephemeral_storage_bytes - nbytes converted_space = convert_size(remaining_space) logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') + + @staticmethod def checkEntityType(self, syn_id): """ Check the entity type of a synapse entity @@ -433,7 +435,8 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): # enables retrying if user does not have access to uncensored manifest # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location manifest_data = "" - # check the type of synapse entity type + + # check the type of entity type_entity = syn.checkEntityType(manifest_syn_id) if type_entity != "file": logger.error('You are using a wrong entity type. Please try downloading with manifest id') From 4cdd25a6b8ef4085612b51fc8f4284ad48e7a7d6 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 17:38:06 -0400 Subject: [PATCH 336/615] fix test --- tests/test_store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 74f3b78d9..2aefce536 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -482,7 +482,7 @@ def test_get_manifest_id(self, synapse_store, datasetFileView): @pytest.mark.parametrize("newManifestName",["", "Example"]) def test_download_manifest(self, config, synapse_store, newManifestName): # test the download function by downloading a manifest - manifest_data = synapse_store.download_manifest(synapse_store.syn, "syn51203973", True, newManifestName) + manifest_data = synapse_store.download_manifest(synapse_store.syn, "syn51203973", newManifestName) assert os.path.exists(manifest_data['path']) if not newManifestName: From 39335189b4bd8a87140431c119bc84d6429a2b6c Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 17:38:31 -0400 Subject: [PATCH 337/615] fix typo; as_json default to true for api --- schematic_api/api/routes.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index d8c5e7b5b..6c0d193b9 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -620,9 +620,9 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=True): +def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=None): """ - Donwload a manifest based on a given manifest id. + Download a manifest based on a given manifest id. Args: input_token: token of asset store manifest_syn_id: syn id of a manifest @@ -637,6 +637,10 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr # use Synapse Storage store = SynapseStorage(input_token=input_token) + # default as_json to True + if not as_json: + as_json=True + # try logging in to asset store try: syn = store.login(input_token=input_token) From 59cefabbc289086a0597b6e1475b9c2f0fdf7197 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 22 Mar 2023 17:40:50 -0400 Subject: [PATCH 338/615] add entity type checking --- schematic/store/synapse.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 70231ef9d..650cf3f3d 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -437,10 +437,13 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): manifest_data = "" # check the type of entity - type_entity = syn.checkEntityType(manifest_syn_id) - if type_entity != "file": - logger.error('You are using a wrong entity type. Please try downloading with manifest id') - raise ('You are using a wrong entity type. Please try downloading with manifest id') + entity_name = syn.get(manifest_syn_id, downloadFile=False) + entity_type = str(type(entity_name)) + if entity_type != "": + logger.error(f'You are using entity type: {entity_type}. Please try using a file') + raise (f'You are using a wrong entity type: {entity_type}. Please try using a file') + + # download a manifest if 'manifest_folder' in CONFIG['synapse'].keys(): try: manifest_data = syn.get( @@ -448,7 +451,6 @@ def download_manifest(syn, manifest_syn_id: str, newManifestName=""): downloadLocation=CONFIG["synapse"]["manifest_folder"], ifcollision="overwrite.local", ) - print('manifest data', manifest_data) except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") # if no manifest folder is set, download to cache From 69df2b52bb5ec5fdf8ae428d72f33882ee15a619 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 23 Mar 2023 10:21:08 -0400 Subject: [PATCH 339/615] update test; modify as_json --- schematic_api/api/routes.py | 5 +++-- tests/test_api.py | 44 ++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 12 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 6c0d193b9..4cda01035 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -638,7 +638,7 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=No store = SynapseStorage(input_token=input_token) # default as_json to True - if not as_json: + if as_json is None: as_json=True # try logging in to asset store @@ -656,7 +656,8 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=No if as_json: manifest_json = return_as_json(manifest_local_file_path) return manifest_json - return manifest_local_file_path + else: + return manifest_local_file_path #@profile(sort_by='cumulative', strip_dirs=True) def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): diff --git a/tests/test_api.py b/tests/test_api.py index e81bc41a6..d98ecbb98 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -576,30 +576,54 @@ def test_get_datatype_manifest(self, client, syn_token): "Year of Birth": "Int64", "entityId": "string"} - @pytest.mark.parametrize("manifest_id",["syn51156998"]) + # small manifest: syn51078535; big manifest: syn51156998 + @pytest.mark.parametrize("manifest_id",["syn51156998", "syn51156998"]) @pytest.mark.parametrize("new_manifest_name",["Example", None]) - def test_manifest_download(self, client, syn_token, manifest_id, new_manifest_name): + @pytest.mark.parametrize("as_json",[True, False, None]) + def test_manifest_download(self, config, client, syn_token, manifest_id, new_manifest_name, as_json): params = { "input_token": syn_token, "manifest_id": manifest_id, - "new_manifest_name": new_manifest_name + "new_manifest_name": new_manifest_name, + "as_json": as_json } response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) assert response.status_code == 200 - file_path = response.data.decode() - assert os.path.exists(file_path) - file_base_name = os.path.basename(file_path) - file_name = os.path.splitext(file_base_name)[0] + # if as_json is set to True or as_json is not defined + if as_json or as_json is None: + response_dta = json.loads(response.data) + if manifest_id == "syn51078535": + assert response_dta[0]["Component"] == "BulkRNA-seqAssay" + assert response_dta[0]["File Format"] == "CSV/TSV" + else: + assert response_dta[0]["Component"] == "Biospecimen" + + current_work_dir = os.getcwd() + folder_test_manifests = config["synapse"]["manifest_folder"] + folder_dir = os.path.join(current_work_dir, folder_test_manifests) + if new_manifest_name: + file_name = os.path.join(folder_dir, new_manifest_name + '.' + 'csv') + else: + file_name = os.path.join(folder_dir,config["synapse"]["manifest_basename"] + '.csv') + + else: + data = response.data.decode() + assert os.path.exists(data) + file_base_name = os.path.basename(data) + file_name = os.path.splitext(file_base_name)[0] + + if new_manifest_name: + assert file_name == new_manifest_name - if new_manifest_name: - assert file_name == new_manifest_name + file_name = data + # delete files try: - os.remove(file_path) + os.remove(file_name) except: pass From 852a9094c2096b8482e4548e930a2d551825327d Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 23 Mar 2023 11:17:47 -0400 Subject: [PATCH 340/615] add service account creds --- env.example | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 env.example diff --git a/env.example b/env.example new file mode 100644 index 000000000..d3f721107 --- /dev/null +++ b/env.example @@ -0,0 +1,5 @@ +# API server +SERVER_PROTOCOL=http:// +SERVER_DOMAIN=localhost +SERVER_PORT=7080 +SERVICE_ACCOUNT_CREDS='Provide service account creds' \ No newline at end of file From f47cec05515d32fad565f5174401efb1a40939b4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:04:51 -0700 Subject: [PATCH 341/615] return someting from empty route --- api/routes.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/routes.py b/api/routes.py index 5d6327682..da4867676 100644 --- a/api/routes.py +++ b/api/routes.py @@ -517,7 +517,7 @@ def get_viz_component_attributes_explorer(schema_url): temp_path_to_jsonld = get_temp_jsonld(schema_url) - return + return True def get_viz_tangled_tree_text(schema_url, figure_type, text_format): From 34e4a293803479914e8692497a4384a52f8d452a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:41:25 -0700 Subject: [PATCH 342/615] separate attribute parsing to its own method --- .../visualization/attributes_explorer.py | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index 9a219dc48..ca6923b9b 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -59,17 +59,37 @@ def parse_attributes(self, save_file=True): for the provided data model for all components in the data model. Dataframe is saved locally as a csv if save_file == True, or returned if save_file == False. - Raises: - ValueError: - If unable hits an error while attempting to get conditional requirements. - This error is likely to be found if there is a mismatch in naming. + ''' # get all components component_dg = self.sg.se.get_digraph_by_edge_type('requiresComponent') components = component_dg.nodes() + # For each data type to be loaded gather all attribtes the user would # have to provide. + return self._parse_attributes(components, save_file) + + def _parse_attributes(self, components, save_file = True): + ''' + Args: save_file (bool): + True: merged_df is saved locally to output_path. + False: merged_df is returned. + components (list): + list of components to parse attributes for + Returns: + merged_df (pd.DataFrame): dataframe containing data relating to attributes + for the provided data model for all components in the data model. + Dataframe is saved locally as a csv if save_file == True, or returned if + save_file == False. + Raises: + ValueError: + If unable hits an error while attempting to get conditional requirements. + This error is likely to be found if there is a mismatch in naming. + ''' + + # For each data type to be loaded gather all attribtes the user would + # have to provide. df_store = [] for component in components: data_dict = {} From 753de8eef760871d70ecf60dea039103fd6d08db Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 10:43:27 -0700 Subject: [PATCH 343/615] fix docstring --- schematic/visualization/attributes_explorer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index ca6923b9b..7376a720e 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -79,7 +79,7 @@ def _parse_attributes(self, components, save_file = True): Returns: merged_df (pd.DataFrame): dataframe containing data relating to attributes - for the provided data model for all components in the data model. + for the provided data model for specified components in the data model. Dataframe is saved locally as a csv if save_file == True, or returned if save_file == False. Raises: From a2ed3360c6e3df328052ce02cb600ec038faba33 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 23 Mar 2023 14:32:28 -0400 Subject: [PATCH 344/615] return manifest id if download is False --- schematic/store/synapse.py | 3 ++- tests/test_store.py | 17 +++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 650cf3f3d..d19b2db5e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -520,7 +520,8 @@ def getDatasetManifest( manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, newManifestName=newManifestName) - return manifest_data + return manifest_data + return manifest_syn_id def getDataTypeFromManifest(self, manifestId:str): """Fetch a manifest and return data types of all columns diff --git a/tests/test_store.py b/tests/test_store.py index 2aefce536..24a110231 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -197,16 +197,21 @@ def test_getDatasetProject(self, dataset_id, synapse_store): with pytest.raises(PermissionError): synapse_store.getDatasetProject("syn12345678") - def test_getDatasetManifest(self, synapse_store): + @pytest.mark.parametrize("downloadFile", [True, False]) + def test_getDatasetManifest(self, synapse_store, downloadFile): # get a test manifest - manifest_data = synapse_store.getDatasetManifest("syn51204502", True) + manifest_data = synapse_store.getDatasetManifest("syn51204502", downloadFile) #make sure the file gets downloaded - assert manifest_data['name'] == "synapse_storage_manifest_censored.csv" - assert os.path.exists(manifest_data['path']) + if downloadFile: + assert manifest_data['name'] == "synapse_storage_manifest_censored.csv" + assert os.path.exists(manifest_data['path']) + # clean up + os.remove(manifest_data['path']) + else: + # return manifest id + assert manifest_data == "syn51204513" - # clean up - os.remove(manifest_data['path']) class TestDatasetFileView: def test_init(self, dataset_id, dataset_fileview, synapse_store): From 409ee269cbbd86700f4384718f301e23fe3b293e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:54:50 -0700 Subject: [PATCH 345/615] change target response body --- tests/test_api.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 035de55c9..0169ec626 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -715,14 +715,7 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 def test_visualize_component(self, client, data_model_jsonld): - response_body = """ - b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\r\n - Patient ID,Patient ID,PatientID,TBD,True,,,,Patient\r\n - Component,Component,Component,TBD,False,,,,Patient\r\n - Sex,Sex,Sex,TBD,True,,"[\'Female\', \'Other\', \'Male\']",,Patient\r\n - Year of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\r\n - Diagnosis,Diagnosis,Diagnosis,TBD,True,,"[\'Healthy\', \'Cancer\']",,Patient\r\n - """ + response_body = """b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\\r\\nSex,Sex,Sex,TBD,True,,"[\\'Other\\', \\'Male\\', \\'Female\\']",,Patient\\r\\nDiagnosis,Diagnosis,Diagnosis,TBD,True,,"[\\'Cancer\\', \\'Healthy\\']",,Patient\\r\\nPatient ID,Patient ID,PatientID,TBD,True,,,,Patient\\r\\nComponent,Component,Component,TBD,False,,,,Patient\\r\\nYear of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\\r\\nFamily History,Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient\\r\\nCancer Type,Cancer Type,CancerType,TBD,False,True,"[\\'Colorectal\\', \\'Lung\\', \\'Breast\\', \\'Skin\\', \\'Prostate\\', \\'\\']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient\\r\\n'""" ex_response_body = """ b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\r\n From c9f3e594d3069c967849594c7d9ee770d8dfd6e7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:55:06 -0700 Subject: [PATCH 346/615] convert response to string --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 0169ec626..eddbcbd98 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -746,7 +746,7 @@ def test_visualize_component(self, client, data_model_jsonld): response = client.get("http://localhost:3001/v1/visualize/component", query_string = params) assert response.status_code == 200 - assert response.response[0] == response_body + assert str(response.response[0]) == response_body @pytest.mark.schematic_api From 59621e82e6d6568e17006245fb38a1cf8de94790 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 11:58:25 -0700 Subject: [PATCH 347/615] remove temp reference string --- tests/test_api.py | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index eddbcbd98..2ec349bff 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -717,27 +717,6 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso def test_visualize_component(self, client, data_model_jsonld): response_body = """b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\\r\\nSex,Sex,Sex,TBD,True,,"[\\'Other\\', \\'Male\\', \\'Female\\']",,Patient\\r\\nDiagnosis,Diagnosis,Diagnosis,TBD,True,,"[\\'Cancer\\', \\'Healthy\\']",,Patient\\r\\nPatient ID,Patient ID,PatientID,TBD,True,,,,Patient\\r\\nComponent,Component,Component,TBD,False,,,,Patient\\r\\nYear of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\\r\\nFamily History,Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient\\r\\nCancer Type,Cancer Type,CancerType,TBD,False,True,"[\\'Colorectal\\', \\'Lung\\', \\'Breast\\', \\'Skin\\', \\'Prostate\\', \\'\\']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient\\r\\n'""" - ex_response_body = """ - b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\r\n - Patient ID,Patient ID,PatientID,TBD,True,,,,Biospecimen\r\n - Tissue Status,Tissue Status,TissueStatus,TBD,True,,"[\'Malignant\', \'Healthy\']",,Biospecimen\r\n - Component,Component,Component,TBD,False,,,,Biospecimen\r\n - Sample ID,Sample ID,SampleID,TBD,True,,,,Biospecimen\r\n - Patient ID,Patient ID,PatientID,TBD,True,,,,Patient\r\n - Sex,Sex,Sex,TBD,True,,"[\'Female\', \'Other\', \'Male\']",,Patient\r\n - Year of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\r\n - Component,Component,Component,TBD,False,,,,Patient\r\n - Diagnosis,Diagnosis,Diagnosis,TBD,True,,"[\'Healthy\', \'Cancer\']",,Patient\r\n - Family History,Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient\r\n - Cancer Type,Cancer Type,CancerType,TBD,False,True,"[\'Colorectal\', \'Lung\', \'Breast\', \'Prostate\', \'Skin\', \'\']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient\r\n - Filename,Filename,Filename,TBD,True,,,,BulkRNA-seqAssay\r\n - Component,Component,Component,TBD,False,,,,BulkRNA-seqAssay\r\n - File Format,File Format,FileFormat,TBD,True,,"[\'CRAM\', \'CSV/TSV\', \'BAM\', \'FASTQ\']",,BulkRNA-seqAssay\r\n - Sample ID,Sample ID,SampleID,TBD,True,,,,BulkRNA-seqAssay\r\n - Genome Build,Genome Build,GenomeBuild,TBD,False,True,"[\'GRCm38\', \'GRCm39\', \'GRCh37\', \'GRCh38\', \'\']"," If File Format is ""CRAM"" OR ""CSV/TSV"" OR ""BAM"" then ""Genome Build"" is required",BulkRNA-seqAssay\r\n - Genome FASTA,Genome FASTA,GenomeFASTA,TBD,False,True,," If File Format is ""CRAM"" then ""Genome FASTA"" is required",BulkRNA-seqAssay\r\n' - """ - params = { "schema_url": data_model_jsonld, "component": "Patient" From 252fb577bbd99ecb34cc92a8a91650f2b3f54ebe Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 15:43:50 -0700 Subject: [PATCH 348/615] add new method for endpoint functionality --- schematic/visualization/attributes_explorer.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index 7376a720e..78015ce42 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -68,6 +68,24 @@ def parse_attributes(self, save_file=True): # For each data type to be loaded gather all attribtes the user would # have to provide. return self._parse_attributes(components, save_file) + + def parse_component_attributes(self, component=None, save_file=True,): + ''' + Args: save_file (bool): + True: merged_df is saved locally to output_path. + False: merged_df is returned. + + Returns: + merged_df (pd.DataFrame): dataframe containing data relating to attributes + for the provided data model for the specified component in the data model. + Dataframe is saved locally as a csv if save_file == True, or returned if + save_file == False. + ''' + + if not component: + raise ValueError("You must provide a component to visualize.") + else: + return self._parse_attributes([component], save_file) def _parse_attributes(self, components, save_file = True): ''' From 2a4f9bff6a89ccda65dab71d7e788e9be54a1ae4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 15:44:13 -0700 Subject: [PATCH 349/615] use new method --- api/routes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/api/routes.py b/api/routes.py index da4867676..ffe6bc0d1 100644 --- a/api/routes.py +++ b/api/routes.py @@ -510,14 +510,15 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv -def get_viz_component_attributes_explorer(schema_url): +def get_viz_component_attributes_explorer(schema_url, component): # call config_handler() config_handler() temp_path_to_jsonld = get_temp_jsonld(schema_url) + attributes_csv = AttributesExplorer(temp_path_to_jsonld).parse_component_attributes(component, save_file=False) - return True + return attributes_csv def get_viz_tangled_tree_text(schema_url, figure_type, text_format): From bb2a8af5dabef19d67bf72093e85f5ed5fba62f2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 15:59:50 -0700 Subject: [PATCH 350/615] remove response body check --- tests/test_api.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 2ec349bff..ad2490e53 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -715,8 +715,6 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 def test_visualize_component(self, client, data_model_jsonld): - response_body = """b',Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component\\r\\nSex,Sex,Sex,TBD,True,,"[\\'Other\\', \\'Male\\', \\'Female\\']",,Patient\\r\\nDiagnosis,Diagnosis,Diagnosis,TBD,True,,"[\\'Cancer\\', \\'Healthy\\']",,Patient\\r\\nPatient ID,Patient ID,PatientID,TBD,True,,,,Patient\\r\\nComponent,Component,Component,TBD,False,,,,Patient\\r\\nYear of Birth,Year of Birth,YearofBirth,TBD,False,,,,Patient\\r\\nFamily History,Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient\\r\\nCancer Type,Cancer Type,CancerType,TBD,False,True,"[\\'Colorectal\\', \\'Lung\\', \\'Breast\\', \\'Skin\\', \\'Prostate\\', \\'\\']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient\\r\\n'""" - params = { "schema_url": data_model_jsonld, "component": "Patient" @@ -725,7 +723,6 @@ def test_visualize_component(self, client, data_model_jsonld): response = client.get("http://localhost:3001/v1/visualize/component", query_string = params) assert response.status_code == 200 - assert str(response.response[0]) == response_body @pytest.mark.schematic_api From 8cb680583a46139fa0a48d571649030cfe375008 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 23 Mar 2023 16:05:12 -0700 Subject: [PATCH 351/615] parameterize component --- tests/test_api.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index ad2490e53..735807a6b 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -714,10 +714,11 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 - def test_visualize_component(self, client, data_model_jsonld): + @pytest.mark.parametrize("component", ["Patient", "MockComponent"]) + def test_visualize_component(self, client, data_model_jsonld,component): params = { "schema_url": data_model_jsonld, - "component": "Patient" + "component": component } response = client.get("http://localhost:3001/v1/visualize/component", query_string = params) From b925350f61a476fc5eda1f070c15a33c685d8806 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 24 Mar 2023 10:04:00 -0700 Subject: [PATCH 352/615] do not index df when converting to csv --- schematic/visualization/attributes_explorer.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index 78015ce42..03f903776 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -200,6 +200,6 @@ def _parse_attributes(self, components, save_file = True): merged_attributes_df = merged_attributes_df[cols] if save_file == True: - return merged_attributes_df.to_csv(os.path.join(self.output_path, self.schema_name + 'attributes_data.vis_data.csv')) + return merged_attributes_df.to_csv(os.path.join(self.output_path, self.schema_name + 'attributes_data.vis_data.csv'), index=False) elif save_file == False: - return merged_attributes_df.to_csv() + return merged_attributes_df.to_csv(index=False) From 9ef3c6dc50b6be20e8b047a5fe8ee6bc39fcd5bb Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Mar 2023 16:00:56 -0400 Subject: [PATCH 353/615] extract manifest download to its own class and edit tests --- schematic/store/synapse.py | 165 ++++++++++++++++++++++--------------- tests/test_store.py | 22 ++++- 2 files changed, 115 insertions(+), 72 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d19b2db5e..72339efee 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -54,6 +54,92 @@ logger = logging.getLogger("Synapse storage") +class ManifestDownload(object): + def _download_manifest_to_folder(self, syn, manifest_id): + """ + try downloading a manifest to local cache or a given folder + manifest + Args: + manifest_id: id of a manifest + Return: + manifest_data: A new Synapse Entity object of the appropriate type + """ + if CONFIG["synapse"]["manifest_folder"]: + manifest_data = syn.get( + manifest_id, + downloadLocation=CONFIG["synapse"]["manifest_folder"], + ifcollision="overwrite.local", + ) + else: + manifest_data = syn.get( + manifest_id, + ) + return manifest_data + + def _entity_type_checking(self, syn, manifest_id): + """ + check the entity type of the id that needs to be downloaded + Args: + manifest_id: id of a manifest + Return: + entity_type: type of the manifest being returned + """ + # check the type of entity + entity_name = syn.get(manifest_id, downloadFile=False) + entity_type = str(type(entity_name)) + if entity_type != "": + logger.error(f'You are using entity type: {entity_type}. Please try using a file') + + @staticmethod + def download_manifest(self, syn, manifest_id: str, newManifestName="", manifest_df=None): + """ + Donwload a manifest based on a given manifest id. + Args: + manifest_id: id of a manifest + newManifestName(optional): new name of a manifest that gets downloaded. + manifest_df(optional): a dataframe containing name and id of manifests in a given asset view + Return: + manifest_data: synapse entity file object + """ + + # enables retrying if user does not have access to uncensored manifest + # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location + manifest_data = "" + + # entity type checking + self._entity_type_checking(syn, manifest_id) + + # download a manifest + try: + manifest_data = self._download_manifest_to_folder(syn, manifest_id) + except(SynapseUnmetAccessRestrictions, SynapseAuthenticationError): + if not manifest_df.empty: + censored_regex=re.compile('.*censored.*') + censored = manifest_df['name'].str.contains(censored_regex) + new_manifest_id=manifest_df[censored]["id"][0] + try: + manifest_data = self._download_manifest_to_folder(syn, new_manifest_id) + except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: + logger.error(f"You don't have access to the requested resource: {manifest_id}") + raise (f"You don't have access to the requested resource: {manifest_id}") + + else: + logger.error(f"You don't have access to the requested resource: {manifest_id}") + + if newManifestName: + if os.path.exists(manifest_data['path']): + # Rename the file we just made to the new name + new_manifest_filename = newManifestName + '.csv' + dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) + new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) + os.rename(manifest_data['path'], new_manifest_path_name) + + # Update file names/paths in manifest_data + manifest_data['name'] = new_manifest_filename + manifest_data['filename'] = new_manifest_filename + manifest_data['path'] = new_manifest_path_name + return manifest_data + class SynapseStorage(BaseStorage): """Implementation of Storage interface for datasets/files stored on Synapse. Provides utilities to list files in a specific project; update files annotations, create fileviews, etc. @@ -392,7 +478,7 @@ def getFilesInStorageDataset( def _get_manifest_id(self, manifest: pd.DataFrame) -> str: """If both censored and uncensored manifests are present, return uncensored manifest; if only one manifest is present, return manifest id of that manifest; if more than two manifests are present, return the manifest id of the first one. Args: - manifest: a dataframe that contains annotation of manifests metadata + manifest: a dataframe contains name and id of manifests in a given asset view Return: manifest_syn_id: id of a given censored or uncensored manifest @@ -412,72 +498,8 @@ def _get_manifest_id(self, manifest: pd.DataFrame) -> str: else: manifest_syn_id = manifest["id"][0] - # check if user has access to the manifest without downloading it - try: - self.syn.get(manifest_syn_id, downloadFile=False) - # if user ends up not having access to the manifest returned, switch back to use censored manifest - except(SynapseUnmetAccessRestrictions): - manifest_syn_id=manifest[censored]["id"][0] - return manifest_syn_id - @staticmethod - def download_manifest(syn, manifest_syn_id: str, newManifestName=""): - """ - Donwload a manifest based on a given manifest id. - Args: - manifest_syn_id: syn id of a manifest - newManifestName: new name of a manifest that gets downloaded. - Return: - manifest_data: synapse entity file object - """ - - # enables retrying if user does not have access to uncensored manifest - # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location - manifest_data = "" - - # check the type of entity - entity_name = syn.get(manifest_syn_id, downloadFile=False) - entity_type = str(type(entity_name)) - if entity_type != "": - logger.error(f'You are using entity type: {entity_type}. Please try using a file') - raise (f'You are using a wrong entity type: {entity_type}. Please try using a file') - - # download a manifest - if 'manifest_folder' in CONFIG['synapse'].keys(): - try: - manifest_data = syn.get( - manifest_syn_id, - downloadLocation=CONFIG["synapse"]["manifest_folder"], - ifcollision="overwrite.local", - ) - except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") - # if no manifest folder is set, download to cache - ### TO DO: Deprecate the following? - else: - try: - manifest_data = syn.get( - manifest_syn_id, - ) - - except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - logger.error(f"You don't have access to the requested resource: {manifest_syn_id}") - # Rename manifest file if indicated by user. - if newManifestName: - if os.path.exists(manifest_data['path']): - # Rename the file we just made to the new name - new_manifest_filename = newManifestName + '.csv' - dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) - new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) - os.rename(manifest_data['path'], new_manifest_path_name) - - # Update file names/paths in manifest_data - manifest_data['name'] = new_manifest_filename - manifest_data['filename'] = new_manifest_filename - manifest_data['path'] = new_manifest_path_name - return manifest_data - def getDatasetManifest( self, datasetId: str, downloadFile: bool = False, newManifestName: str='', ) -> List[str]: @@ -502,7 +524,7 @@ def getDatasetManifest( manifest_re=re.compile(os.path.basename(self.manifest)+".*.[tc]sv") # search manifest based on given manifest basename regex above - # and return a dataframe containing annotation of manifests + # and return a dataframe containing name and id of manifests in a given asset view manifest = all_files[ (all_files['name'].str.contains(manifest_re,regex=True)) & (all_files["parentId"] == datasetId) @@ -519,7 +541,10 @@ def getDatasetManifest( else: manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: - manifest_data = self.download_manifest(self.syn, manifest_syn_id=manifest_syn_id, newManifestName=newManifestName) + md = ManifestDownload() + manifest_data = ManifestDownload.download_manifest(md, self.syn, manifest_id=manifest_syn_id, newManifestName=newManifestName, manifest_df=manifest) + if manifest_data == "": + logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data return manifest_syn_id @@ -653,7 +678,11 @@ def getProjectManifests(self, projectId: str) -> List[str]: ) manifest_info = self.getDatasetManifest(datasetId,downloadFile=True) - manifest_name = manifest_info["properties"]["name"] + try: + manifest_name = manifest_info["properties"]["name"] + except: + print('dataset id', datasetId) + print('manifest info', manifest_info) manifest_path = manifest_info["path"] manifest_df = load_df(manifest_path) diff --git a/tests/test_store.py b/tests/test_store.py index 24a110231..5f8b46d32 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -11,7 +11,7 @@ from schematic.models.metadata import MetadataModel from schematic.store.base import BaseStorage -from schematic.store.synapse import SynapseStorage, DatasetFileView +from schematic.store.synapse import SynapseStorage, DatasetFileView, ManifestDownload from schematic.utils.cli_utils import get_from_config from schematic.schemas.generator import SchemaGenerator from synapseclient.core.exceptions import SynapseHTTPError @@ -29,6 +29,10 @@ def synapse_store(): synapse_store = SynapseStorage() yield synapse_store +@pytest.fixture +def manifestDownload(): + md = ManifestDownload() + yield md @pytest.fixture def dataset_fileview(dataset_id, synapse_store): @@ -70,7 +74,6 @@ def datasetId(synapse_store, projectId, helpers): yield datasetId synapse_store.syn.delete(datasetId) - def raise_final_error(retry_state): return retry_state.outcome.result() @@ -485,9 +488,9 @@ def test_get_manifest_id(self, synapse_store, datasetFileView): assert manifest_syn_id == censored_manifest_id @pytest.mark.parametrize("newManifestName",["", "Example"]) - def test_download_manifest(self, config, synapse_store, newManifestName): + def test_download_manifest(self, config, synapse_store, manifestDownload, newManifestName): # test the download function by downloading a manifest - manifest_data = synapse_store.download_manifest(synapse_store.syn, "syn51203973", newManifestName) + manifest_data = manifestDownload.download_manifest(manifestDownload, synapse_store.syn, "syn51203973", newManifestName) assert os.path.exists(manifest_data['path']) if not newManifestName: @@ -498,3 +501,14 @@ def test_download_manifest(self, config, synapse_store, newManifestName): # clean up os.remove(manifest_data['path']) + @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078"]) + def test_entity_type_checking(self, manifestDownload, synapse_store, entity_id, caplog): + manifestDownload._entity_type_checking(synapse_store.syn, entity_id) + if entity_id == "syn27600053": + for record in caplog.records: + assert "Please try using a file" in record.message + + + + + From ae75133f944d687d6145f9ba1c8180b20cf33d32 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 24 Mar 2023 13:19:16 -0700 Subject: [PATCH 354/615] update test for removed col --- tests/test_viz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_viz.py b/tests/test_viz.py index 954f45df5..0d9b52512 100644 --- a/tests/test_viz.py +++ b/tests/test_viz.py @@ -37,7 +37,7 @@ class TestVisualization: def test_ae(self, helpers, attributes_explorer): attributes_str = attributes_explorer.parse_attributes(save_file=False) - df = pd.read_csv(StringIO(attributes_str)).drop(columns=['Unnamed: 0']) + df = pd.read_csv(StringIO(attributes_str)) # For the attributes df define expected columns expect_col_names = ['Attribute', 'Label', 'Description', From ad4b9e5f7ae0a4dda2b09ee2cb32bade0a36bede Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Mar 2023 17:41:51 -0400 Subject: [PATCH 355/615] modify class used for manifest download --- schematic_api/api/routes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 4cda01035..739f23355 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -18,7 +18,7 @@ from schematic.models.metadata import MetadataModel from schematic.schemas.generator import SchemaGenerator from schematic.schemas.explorer import SchemaExplorer -from schematic.store.synapse import SynapseStorage +from schematic.store.synapse import SynapseStorage, ManifestDownload from synapseclient.core.exceptions import SynapseHTTPError, SynapseAuthenticationError, SynapseUnmetAccessRestrictions from flask_cors import CORS, cross_origin from schematic.schemas.explorer import SchemaExplorer @@ -647,7 +647,8 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=No except Exception: raise SynapseAuthenticationError try: - manifest_data = store.download_manifest(syn, manifest_id, new_manifest_name) + md = ManifestDownload() + manifest_data = ManifestDownload.download_manifest(md, syn, manifest_id, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] except Exception: From 722cc94d15ebe763f66c2570b33d89734ed321fb Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Mar 2023 23:08:50 -0400 Subject: [PATCH 356/615] add test for get empty manifest --- schematic/manifest/generator.py | 12 +++---- tests/test_manifest.py | 56 ++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 7 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 2f36ae568..5a84c23ba 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -181,13 +181,13 @@ def _create_empty_manifest_spreadsheet(self, title): ) else: + spreadsheet_body = { + 'properties': { + 'title': title + }} + # if no template, create an empty spreadsheet - spreadsheet = ( - self.sheet_service.spreadsheets() - .create(body=spreadsheet, fields="spreadsheetId") - .execute() - ) - spreadsheet_id = spreadsheet.get("spreadsheetId") + spreadsheet_id = self.sheet_service.spreadsheets().create(body=spreadsheet_body, fields="spreadsheetId").execute().get("spreadsheetId") return spreadsheet_id diff --git a/tests/test_manifest.py b/tests/test_manifest.py index e03a0ac3d..09c60290e 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -6,6 +6,9 @@ from schematic.manifest.generator import ManifestGenerator from schematic.schemas.generator import SchemaGenerator import pandas as pd +from unittest.mock import Mock +from unittest.mock import patch +from unittest.mock import MagicMock logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -50,6 +53,13 @@ def manifest_generator(helpers, request): def simple_test_manifest_excel(helpers): yield helpers.get_data_path("mock_manifests/test_bulkRNAseq_manifest.xlsx") +@pytest.fixture +def mock_create_blank_google_sheet(): + 'Mock creating a new google sheet' + er = Mock() + er.return_value = "mock_spreadsheet_id" + yield er + @pytest.fixture(params=[True, False], ids=["sheet_url", "data_frame"]) def manifest(dataset_id, manifest_generator, request): @@ -65,6 +75,7 @@ def manifest(dataset_id, manifest_generator, request): class TestManifestGenerator: + def test_init(self, helpers): generator = ManifestGenerator( @@ -179,10 +190,51 @@ def test_get_manifest_excel(self, helpers, sheet_url, output_format, dataset_id) assert manifest.startswith("https://docs.google.com/spreadsheets/") # Clean-up - if type(manifest) is str and os.path.exists(manifest): os.remove(manifest) + # test all the functions used under get_manifest + @pytest.mark.parametrize("template_id", [["not provided"]]) + def test_create_empty_manifest_spreadsheet(self, config, manifest_generator, template_id): + ''' + Create an empty manifest spreadsheet regardless if master_template_id is provided + Note: _create_empty_manifest_spreadsheet calls _gdrive_copy_file. If there's no template id provided in config, this function will create a new manifest + ''' + generator, use_annotations, data_type = manifest_generator + + mock_spreadsheet = MagicMock() + + title="Example" + + if template_id == "provided": + # mock _gdrive_copy_file function + with patch('schematic.manifest.generator.ManifestGenerator._gdrive_copy_file') as MockClass: + instance = MockClass.return_value + instance.method.return_value = 'mock google sheet id' + + spreadsheet_id = generator._create_empty_manifest_spreadsheet(title=title) + assert spreadsheet_id == "mock google sheet id" + + else: + # overwrite test config so that we could test the case when manifest_template_id is not provided + config["style"]["google_manifest"]["master_template_id"] = "" + + mock_spreadsheet = Mock() + mock_execute = Mock() + + + # Chain the mocks together + mock_spreadsheet.create.return_value = mock_spreadsheet + mock_spreadsheet.execute.return_value = mock_execute + mock_execute.get.return_value = "mock id" + mock_create = Mock(return_value=mock_spreadsheet) + + with patch.object(generator.sheet_service, "spreadsheets", mock_create): + + spreadsheet_id = generator._create_empty_manifest_spreadsheet(title) + assert spreadsheet_id == "mock id" + + @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) def test_get_missing_columns(self, manifest_generator, wb_headers, manifest_columns): @@ -195,6 +247,8 @@ def test_get_missing_columns(self, manifest_generator, wb_headers, manifest_colu else: assert "column four" not in missing_columns + + @pytest.mark.parametrize("additional_df_dict", [{'test one column': ['a', 'b'], 'test two column': ['c', 'd']}, None]) def test_populate_existing_excel_spreadsheet(self, manifest_generator,simple_test_manifest_excel, additional_df_dict): generator, use_annotations, data_type = manifest_generator From d120320645b11a5dbcb9cf1c2a84622c841ed2b2 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 24 Mar 2023 23:11:02 -0400 Subject: [PATCH 357/615] add condition --- tests/test_manifest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 09c60290e..8fa181cf1 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -194,7 +194,7 @@ def test_get_manifest_excel(self, helpers, sheet_url, output_format, dataset_id) os.remove(manifest) # test all the functions used under get_manifest - @pytest.mark.parametrize("template_id", [["not provided"]]) + @pytest.mark.parametrize("template_id", [["provided", "not provided"]]) def test_create_empty_manifest_spreadsheet(self, config, manifest_generator, template_id): ''' Create an empty manifest spreadsheet regardless if master_template_id is provided From c2b0fd96b9bb0a551f56f76766f26764dab177a0 Mon Sep 17 00:00:00 2001 From: linglp Date: Sat, 25 Mar 2023 20:47:09 -0400 Subject: [PATCH 358/615] add test for _get_json_schema --- tests/test_manifest.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 8fa181cf1..561a59e31 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -234,6 +234,29 @@ def test_create_empty_manifest_spreadsheet(self, config, manifest_generator, tem spreadsheet_id = generator._create_empty_manifest_spreadsheet(title) assert spreadsheet_id == "mock id" + @pytest.mark.parametrize("schema_path_provided", [True, False]) + def test_get_json_schema(self, manifest_generator, helpers, schema_path_provided): + ''' + Open json schema as a dictionary + ''' + generator, use_annotations, data_type = manifest_generator + + if schema_path_provided: + json_schema_path = helpers.get_data_path("example.model.jsonld") + json_schema = generator._get_json_schema(json_schema_filepath=json_schema_path) + + else: + mock_json_schema = Mock() + mock_json_schema.return_value = "mock json ld" + with patch.object(SchemaGenerator, "get_json_schema_requirements",mock_json_schema): + json_schema = generator._get_json_schema(json_schema_filepath=None) + assert json_schema == "mock json ld" + + assert type(json_schema) == str + + + + @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) From ac0d62726f19c29ab152dcd0a5d2b4a330f7a546 Mon Sep 17 00:00:00 2001 From: linglp Date: Sat, 25 Mar 2023 21:43:54 -0400 Subject: [PATCH 359/615] switch to use simple_manifest_generator --- tests/test_manifest.py | 36 +++++++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 561a59e31..879e6ffb9 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -47,7 +47,10 @@ def manifest_generator(helpers, request): os.remove(helpers.get_data_path(f"example.{data_type}.schema.json")) except FileNotFoundError: pass - +@pytest.fixture +def simple_manifest_generator(manifest_generator): + generator, use_annotations, data_type = manifest_generator + yield generator @pytest.fixture def simple_test_manifest_excel(helpers): @@ -195,12 +198,12 @@ def test_get_manifest_excel(self, helpers, sheet_url, output_format, dataset_id) # test all the functions used under get_manifest @pytest.mark.parametrize("template_id", [["provided", "not provided"]]) - def test_create_empty_manifest_spreadsheet(self, config, manifest_generator, template_id): + def test_create_empty_manifest_spreadsheet(self, config, simple_manifest_generator, template_id): ''' Create an empty manifest spreadsheet regardless if master_template_id is provided Note: _create_empty_manifest_spreadsheet calls _gdrive_copy_file. If there's no template id provided in config, this function will create a new manifest ''' - generator, use_annotations, data_type = manifest_generator + generator = simple_manifest_generator mock_spreadsheet = MagicMock() @@ -235,11 +238,11 @@ def test_create_empty_manifest_spreadsheet(self, config, manifest_generator, tem assert spreadsheet_id == "mock id" @pytest.mark.parametrize("schema_path_provided", [True, False]) - def test_get_json_schema(self, manifest_generator, helpers, schema_path_provided): + def test_get_json_schema(self, simple_manifest_generator, helpers, schema_path_provided): ''' Open json schema as a dictionary ''' - generator, use_annotations, data_type = manifest_generator + generator = simple_manifest_generator if schema_path_provided: json_schema_path = helpers.get_data_path("example.model.jsonld") @@ -255,13 +258,28 @@ def test_get_json_schema(self, manifest_generator, helpers, schema_path_provided assert type(json_schema) == str + def test_gather_all_fields(self, simple_manifest_generator): + ''' + gather all fields is a wrapper around three functions: _get_required_metadata_fields, _gather_dependency_requirements + and _get_additional_metadata + ''' + generator = simple_manifest_generator + with patch('schematic.manifest.generator.ManifestGenerator._get_required_metadata_fields') as MockClass: + MockClass.return_value = "mock required metadata fields" + with patch('schematic.manifest.generator.ManifestGenerator._gather_dependency_requirements') as MockRequirement: + MockRequirement.return_value = "mock required metadata fields" + with patch('schematic.manifest.generator.ManifestGenerator._get_additional_metadata') as MockAdditionalData: + MockAdditionalData.return_value = "mock required metadata fields" + required_metadata = generator._gather_all_fields("mock fields", "mock json schema") + assert required_metadata == "mock required metadata fields" + @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) - def test_get_missing_columns(self, manifest_generator, wb_headers, manifest_columns): - generator, use_annotations, data_type = manifest_generator + def test_get_missing_columns(self, simple_manifest_generator, wb_headers, manifest_columns): + generator = simple_manifest_generator manifest_test_df = pd.DataFrame(columns = manifest_columns) missing_columns = generator._get_missing_columns(wb_headers, manifest_test_df) @@ -273,8 +291,8 @@ def test_get_missing_columns(self, manifest_generator, wb_headers, manifest_colu @pytest.mark.parametrize("additional_df_dict", [{'test one column': ['a', 'b'], 'test two column': ['c', 'd']}, None]) - def test_populate_existing_excel_spreadsheet(self, manifest_generator,simple_test_manifest_excel, additional_df_dict): - generator, use_annotations, data_type = manifest_generator + def test_populate_existing_excel_spreadsheet(self, simple_manifest_generator, simple_test_manifest_excel, additional_df_dict): + generator = simple_manifest_generator if additional_df_dict: additional_test_df = pd.DataFrame(additional_df_dict) else: From 55c458fda407150e9e0478d4ea9d8d304561646d Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 10:44:09 -0400 Subject: [PATCH 360/615] add comment for testing create_empty_gs --- tests/test_manifest.py | 54 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 4 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 879e6ffb9..3d750a473 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -2,13 +2,15 @@ import shutil import logging import pytest - -from schematic.manifest.generator import ManifestGenerator -from schematic.schemas.generator import SchemaGenerator import pandas as pd from unittest.mock import Mock from unittest.mock import patch from unittest.mock import MagicMock +from schematic.manifest.generator import ManifestGenerator +from schematic.schemas.generator import SchemaGenerator +from schematic.utils.google_api_utils import execute_google_api_requests + + logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -91,6 +93,11 @@ def test_init(self, helpers): assert generator.root is None assert type(generator.sg) is SchemaGenerator + # Define the function to be called instead of my_func + def mock_google_api_execution(): + print('mock google api execution') + + @pytest.mark.google_credentials_needed def test_get_manifest_first_time(self, manifest): @@ -275,7 +282,46 @@ def test_gather_all_fields(self, simple_manifest_generator): assert required_metadata == "mock required metadata fields" - + + + #@patch("schematic.utils.google_api_utils.execute_google_api_requests") + # @patch("schematic.manifest.generator.ManifestGenerator._create_requests_body") + # @patch("schematic.manifest.generator.ManifestGenerator._set_permissions") + # @patch("schematic.manifest.generator.ManifestGenerator._gs_add_additional_metadata") + # @patch("schematic.manifest.generator.ManifestGenerator._gs_add_and_format_columns") + # def test_create_empty_gs(self, mock_format_columns, mock_add_metadata, mock_set_perms, mock_request_body,simple_manifest_generator): + # ''' + # Create an empty manifest using specifications from the json schema. + # ''' + + # # Create the mock object + # mock_my_func = MagicMock() + + # self.sheet_service = Mock() + + # spreadsheet_id = "example_sheet_id" + + # mock_format_columns.return_value = ("add_format_cols_response", ["field1", "field2"]) + # mock_add_metadata.return_value = "add_metadata_response" + # mock_set_perms.return_value = "set_perms_response" + # mock_request_body.return_value = "mock request body" + # #mock_execute.return_value = "mock response" + + # required_metadata_fields = "mock required metadata" + # json_schema = "mock json schema string" + # spreadsheet_id = "mock_spreadsheet_id" + + # def mock_return(): + # return "mock haha" + + # with patch('schematic.manifest.generator.utils.google_api_utils.execute_google_api_requests', new=mock_return): + # response = simple_manifest_generator._create_empty_gs( + # required_metadata_fields, + # json_schema, + # spreadsheet_id, + # ) + + @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) def test_get_missing_columns(self, simple_manifest_generator, wb_headers, manifest_columns): From 466bb33c9f89d9a062b84f8df2a9ed0ebfa9a128 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 14:42:57 -0400 Subject: [PATCH 361/615] move entity checking as a separate function --- schematic/store/synapse.py | 50 +++++++++++++++--------------- schematic/utils/general.py | 29 ++++++++++++++++- schematic_api/api/openapi/api.yaml | 8 ----- schematic_api/api/routes.py | 12 +++---- 4 files changed, 59 insertions(+), 40 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 72339efee..f6379b7ff 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -51,6 +51,7 @@ from schematic.exceptions import MissingConfigValueError, AccessCredentialsError from schematic import CONFIG +from schematic.utils.general import entity_type_checking logger = logging.getLogger("Synapse storage") @@ -82,12 +83,11 @@ def _entity_type_checking(self, syn, manifest_id): Args: manifest_id: id of a manifest Return: - entity_type: type of the manifest being returned + if the entity type is wrong, raise an error """ # check the type of entity - entity_name = syn.get(manifest_id, downloadFile=False) - entity_type = str(type(entity_name)) - if entity_type != "": + entity_type = entity_type_checking(syn, manifest_id) + if entity_type != "file": logger.error(f'You are using entity type: {entity_type}. Please try using a file') @staticmethod @@ -106,9 +106,9 @@ def download_manifest(self, syn, manifest_id: str, newManifestName="", manifest_ # pass synID to synapseclient.Synapse.get() method to download (and overwrite) file to a location manifest_data = "" - # entity type checking + # check entity type self._entity_type_checking(syn, manifest_id) - + # download a manifest try: manifest_data = self._download_manifest_to_folder(syn, manifest_id) @@ -217,25 +217,25 @@ def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): converted_space = convert_size(remaining_space) logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') - @staticmethod - def checkEntityType(self, syn_id): - """ - Check the entity type of a synapse entity - return: type of synapse entity - """ - entity = self.syn.get(syn_id) - type_entity = str(type(entity)) - - if type_entity == "": - return "asset view" - elif type_entity == "": - return "folder" - elif type_entity == "": - return "file" - elif type_entity == "": - return "project" - else: - return type_entity + # @staticmethod + # def checkEntityType(self, syn_id): + # """ + # Check the entity type of a synapse entity + # return: type of synapse entity + # """ + # entity = self.syn.get(syn_id) + # type_entity = str(type(entity)) + + # if type_entity == "": + # return "asset view" + # elif type_entity == "": + # return "folder" + # elif type_entity == "": + # return "file" + # elif type_entity == "": + # return "project" + # else: + # return type_entity def _query_fileview(self): self._purge_synapse_cache() diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 2fc2bc357..d451cc108 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -69,4 +69,31 @@ def convert_gb_to_bytes(gb: int): return: total number of bytes """ bytes_to_return = gb * 1024 * 1024 * 1024 - return bytes_to_return \ No newline at end of file + return bytes_to_return + + +def entity_type_checking(syn, manifest_id): + """ + check the entity type of the id that needs to be downloaded + Args: + manifest_id: id of a manifest + Return: + type_entity: type of the manifest being returned + """ + # check the type of entity + try: + entity_name = syn.get(manifest_id, downloadFile=False) + except: + raise(f'Here: {manifest_id}') + type_entity = str(type(entity_name)) + + if type_entity == "": + return "asset view" + elif type_entity == "": + return "folder" + elif type_entity == "": + return "file" + elif type_entity == "": + return "project" + else: + return type_entity \ No newline at end of file diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index 4320274a7..d6e3358d4 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -734,14 +734,6 @@ paths: description: Token example: Token required: true - - in: query - name: asset_view - schema: - type: string - nullable: false - description: ID of view listing all project data assets. For example, for Synapse this would be the Synapse ID of the fileview listing all data assets for a given project.(i.e. master_fileview in config.yml) - example: syn23643253 - required: true - in: query name: entity_id schema: diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 739f23355..f34c61274 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -40,6 +40,7 @@ # # Do stuff after your route executes # pass from flask_cors import cross_origin +from schematic.utils.general import entity_type_checking logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) @@ -563,15 +564,14 @@ def check_if_files_in_assetview(input_token, asset_view, entity_id): return if_exists -def check_entity_type(input_token, asset_view, entity_id): +def check_entity_type(input_token, entity_id): # call config handler - config_handler(asset_view=asset_view) + config_handler() - # use Synapse Storage - store = SynapseStorage(input_token=input_token) + syn = SynapseStorage.login(access_token = input_token) + entity_type = entity_type_checking(syn, entity_id) - entity_type = store.checkEntityType(entity_id) - return entity_type + return entity_type def get_component_requirements(schema_url, source_component, as_graph): metadata_model = initalize_metadata_model(schema_url) From 45e5b3e1ca60d8558db13a2d054515e3b20f8a3f Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 15:17:19 -0400 Subject: [PATCH 362/615] add test --- tests/test_utils.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/tests/test_utils.py b/tests/test_utils.py index 038c82b09..3a5de25bb 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -20,11 +20,23 @@ MissingConfigAndArgumentValueError, ) from schematic import LOADER +from schematic.store.synapse import SynapseStorage +from schematic.utils.general import entity_type_checking logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) +@pytest.fixture +def synapse_store(): + access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") + if access_token: + synapse_store = SynapseStorage(access_token=access_token) + else: + synapse_store = SynapseStorage() + yield synapse_store + + class TestGeneral: def test_find_duplicates(self): @@ -50,6 +62,19 @@ def test_dict2list_with_list(self): test_list = general.dict2list(mock_list) assert test_list == mock_list + @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078", "syn23643253", "syn30988314"]) + def test_check_entity_type(self, synapse_store, entity_id): + syn = synapse_store.syn + entity_type = entity_type_checking(syn, entity_id) + if entity_id == "syn27600053": + assert entity_type == "folder" + elif entity_id == "syn29862078": + assert entity_type == "file" + elif entity_id == "syn23643253": + assert entity_type == "asset view" + elif entity_id == "syn30988314": + assert entity_type == "folder" + class TestCliUtils: def test_query_dict(self): From 5dfc8cd4daff51192c0500d86dc2eef277aacca5 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 15:19:41 -0400 Subject: [PATCH 363/615] remove old comment --- schematic/store/synapse.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index f6379b7ff..b48468649 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -216,26 +216,6 @@ def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): remaining_space = total_ephemeral_storage_bytes - nbytes converted_space = convert_size(remaining_space) logger.info(f'Estimated {remaining_space} bytes (which is approximately {converted_space}) remained in ephemeral storage after calculating size of .synapseCache excluding OS') - - # @staticmethod - # def checkEntityType(self, syn_id): - # """ - # Check the entity type of a synapse entity - # return: type of synapse entity - # """ - # entity = self.syn.get(syn_id) - # type_entity = str(type(entity)) - - # if type_entity == "": - # return "asset view" - # elif type_entity == "": - # return "folder" - # elif type_entity == "": - # return "file" - # elif type_entity == "": - # return "project" - # else: - # return type_entity def _query_fileview(self): self._purge_synapse_cache() From dae10db990b7e89e46360e1207521fed7b1d19c2 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 15:21:31 -0400 Subject: [PATCH 364/615] remove asset_view in test --- tests/test_api.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index d98ecbb98..c801727db 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -179,7 +179,6 @@ def test_get_storage_projects(self, syn_token, client): def test_get_entity_type(self, syn_token, client, entity_id): params = { "input_token": syn_token, - "asset_view": "syn23643253", "entity_id": entity_id } response = client.get("http://localhost:3001/v1/storage/entity/type", query_string = params) From 4d54a20ea71c8bff73a1c6fc38836b92ec7dd10e Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 15:28:12 -0400 Subject: [PATCH 365/615] add logging error --- schematic/store/synapse.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index b48468649..eb87ab86e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -661,8 +661,7 @@ def getProjectManifests(self, projectId: str) -> List[str]: try: manifest_name = manifest_info["properties"]["name"] except: - print('dataset id', datasetId) - print('manifest info', manifest_info) + logger.error(f'Failed to download manifests from {datasetId}') manifest_path = manifest_info["path"] manifest_df = load_df(manifest_path) From 05d2dede44e31121067cecdc1b2a9313860de7e1 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 27 Mar 2023 15:45:03 -0400 Subject: [PATCH 366/615] add comment about syn --- schematic/store/synapse.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index eb87ab86e..437e746e1 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -61,6 +61,7 @@ def _download_manifest_to_folder(self, syn, manifest_id): try downloading a manifest to local cache or a given folder manifest Args: + syn: an object of type synapseclient. manifest_id: id of a manifest Return: manifest_data: A new Synapse Entity object of the appropriate type @@ -81,6 +82,7 @@ def _entity_type_checking(self, syn, manifest_id): """ check the entity type of the id that needs to be downloaded Args: + syn: an object of type synapseclient. manifest_id: id of a manifest Return: if the entity type is wrong, raise an error @@ -95,6 +97,7 @@ def download_manifest(self, syn, manifest_id: str, newManifestName="", manifest_ """ Donwload a manifest based on a given manifest id. Args: + syn: an object of type synapseclient. manifest_id: id of a manifest newManifestName(optional): new name of a manifest that gets downloaded. manifest_df(optional): a dataframe containing name and id of manifests in a given asset view From 35bf1bd4842955088afd3cd38dba6c280ef8951f Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 29 Mar 2023 15:28:16 -0400 Subject: [PATCH 367/615] added dataclass --- schematic/store/synapse.py | 50 +++++++++++++++++++------------------ schematic_api/api/routes.py | 4 +-- tests/test_store.py | 19 ++++++++------ 3 files changed, 40 insertions(+), 33 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 437e746e1..43f2c85e9 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -6,6 +6,7 @@ import atexit import logging import secrets +from dataclasses import dataclass # allows specifying explicit variable types from typing import Dict, List, Tuple, Sequence, Union @@ -55,50 +56,50 @@ logger = logging.getLogger("Synapse storage") +@dataclass class ManifestDownload(object): - def _download_manifest_to_folder(self, syn, manifest_id): + """ + syn: an object of type synapseclient. + manifest_id: id of a manifest + """ + syn: synapseclient.Synapse + manifest_id: str + + def _download_manifest_to_folder(self): """ try downloading a manifest to local cache or a given folder manifest - Args: - syn: an object of type synapseclient. - manifest_id: id of a manifest Return: manifest_data: A new Synapse Entity object of the appropriate type """ if CONFIG["synapse"]["manifest_folder"]: - manifest_data = syn.get( - manifest_id, + manifest_data = self.syn.get( + self.manifest_id, downloadLocation=CONFIG["synapse"]["manifest_folder"], ifcollision="overwrite.local", ) else: - manifest_data = syn.get( - manifest_id, + manifest_data = self.syn.get( + self.manifest_id, ) return manifest_data - def _entity_type_checking(self, syn, manifest_id): + def _entity_type_checking(self): """ check the entity type of the id that needs to be downloaded - Args: - syn: an object of type synapseclient. - manifest_id: id of a manifest Return: if the entity type is wrong, raise an error """ # check the type of entity - entity_type = entity_type_checking(syn, manifest_id) + entity_type = entity_type_checking(self.syn, self.manifest_id) if entity_type != "file": logger.error(f'You are using entity type: {entity_type}. Please try using a file') @staticmethod - def download_manifest(self, syn, manifest_id: str, newManifestName="", manifest_df=None): + def download_manifest(self, newManifestName="", manifest_df=None): """ Donwload a manifest based on a given manifest id. Args: - syn: an object of type synapseclient. - manifest_id: id of a manifest newManifestName(optional): new name of a manifest that gets downloaded. manifest_df(optional): a dataframe containing name and id of manifests in a given asset view Return: @@ -110,24 +111,25 @@ def download_manifest(self, syn, manifest_id: str, newManifestName="", manifest_ manifest_data = "" # check entity type - self._entity_type_checking(syn, manifest_id) + self._entity_type_checking() # download a manifest try: - manifest_data = self._download_manifest_to_folder(syn, manifest_id) + manifest_data = self._download_manifest_to_folder() except(SynapseUnmetAccessRestrictions, SynapseAuthenticationError): + # if asset view is provided if not manifest_df.empty: censored_regex=re.compile('.*censored.*') censored = manifest_df['name'].str.contains(censored_regex) new_manifest_id=manifest_df[censored]["id"][0] try: - manifest_data = self._download_manifest_to_folder(syn, new_manifest_id) + manifest_data = self._download_manifest_to_folder() except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - logger.error(f"You don't have access to the requested resource: {manifest_id}") - raise (f"You don't have access to the requested resource: {manifest_id}") + logger.error(f"You don't have access to the requested resource: {self.manifest_id}") + raise (f"You don't have access to the requested resource: {self.manifest_id}") else: - logger.error(f"You don't have access to the requested resource: {manifest_id}") + logger.error(f"You don't have access to the requested resource: {self.manifest_id}") if newManifestName: if os.path.exists(manifest_data['path']): @@ -524,8 +526,8 @@ def getDatasetManifest( else: manifest_syn_id = self._get_manifest_id(manifest) if downloadFile: - md = ManifestDownload() - manifest_data = ManifestDownload.download_manifest(md, self.syn, manifest_id=manifest_syn_id, newManifestName=newManifestName, manifest_df=manifest) + md = ManifestDownload(self.syn, manifest_id=manifest_syn_id) + manifest_data = ManifestDownload.download_manifest(md, newManifestName=newManifestName, manifest_df=manifest) if manifest_data == "": logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index f34c61274..90cc474d2 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -647,8 +647,8 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=No except Exception: raise SynapseAuthenticationError try: - md = ManifestDownload() - manifest_data = ManifestDownload.download_manifest(md, syn, manifest_id, new_manifest_name) + md = ManifestDownload(syn, manifest_id) + manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] except Exception: diff --git a/tests/test_store.py b/tests/test_store.py index 5f8b46d32..24fa4cb4e 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -30,8 +30,12 @@ def synapse_store(): yield synapse_store @pytest.fixture -def manifestDownload(): - md = ManifestDownload() +def test_download_manifest_id(): + yield "syn51203973" + +@pytest.fixture +def mock_manifest_download(synapse_store, test_download_manifest_id): + md = ManifestDownload(synapse_store.syn, test_download_manifest_id) yield md @pytest.fixture @@ -488,9 +492,9 @@ def test_get_manifest_id(self, synapse_store, datasetFileView): assert manifest_syn_id == censored_manifest_id @pytest.mark.parametrize("newManifestName",["", "Example"]) - def test_download_manifest(self, config, synapse_store, manifestDownload, newManifestName): + def test_download_manifest(self, config, mock_manifest_download, newManifestName): # test the download function by downloading a manifest - manifest_data = manifestDownload.download_manifest(manifestDownload, synapse_store.syn, "syn51203973", newManifestName) + manifest_data = mock_manifest_download.download_manifest(mock_manifest_download, newManifestName) assert os.path.exists(manifest_data['path']) if not newManifestName: @@ -502,11 +506,12 @@ def test_download_manifest(self, config, synapse_store, manifestDownload, newMan os.remove(manifest_data['path']) @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078"]) - def test_entity_type_checking(self, manifestDownload, synapse_store, entity_id, caplog): - manifestDownload._entity_type_checking(synapse_store.syn, entity_id) + def test_entity_type_checking(self, synapse_store, entity_id, caplog): + md = ManifestDownload(synapse_store.syn, entity_id) + md._entity_type_checking() if entity_id == "syn27600053": for record in caplog.records: - assert "Please try using a file" in record.message + assert "You are using entity type: folder. Please try using a file" in record.message From f633af6ec436d2a33ab80addda576fe7207dfe5f Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 29 Mar 2023 15:53:49 -0400 Subject: [PATCH 368/615] update from logger.debug to logger.error --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 43f2c85e9..9b4559d49 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -519,7 +519,7 @@ def getDatasetManifest( # if there is no pre-exisiting manifest in the specified dataset if manifest.empty: - logger.warning(f"Could not find a manifest that fits basename {self.manifest} in asset view and dataset {datasetId}") + logger.error(f"Could not find a manifest that fits basename {self.manifest} in asset view and dataset {datasetId}") return "" # if there is an exisiting manifest @@ -529,7 +529,7 @@ def getDatasetManifest( md = ManifestDownload(self.syn, manifest_id=manifest_syn_id) manifest_data = ManifestDownload.download_manifest(md, newManifestName=newManifestName, manifest_df=manifest) if manifest_data == "": - logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") + logger.error(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data return manifest_syn_id From 3fee99c49976fdb62905f1a4f08e72dc28e70dab Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 29 Mar 2023 22:40:32 -0400 Subject: [PATCH 369/615] add more details when downloading a censored manifest that we have access --- schematic/store/synapse.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 9b4559d49..6cc986ed0 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -117,16 +117,17 @@ def download_manifest(self, newManifestName="", manifest_df=None): try: manifest_data = self._download_manifest_to_folder() except(SynapseUnmetAccessRestrictions, SynapseAuthenticationError): - # if asset view is provided + # if there's an error getting an uncensored manifest, try getting the censored manifest if not manifest_df.empty: censored_regex=re.compile('.*censored.*') censored = manifest_df['name'].str.contains(censored_regex) new_manifest_id=manifest_df[censored]["id"][0] + old_requested_manifest_id = self.manifest_id + self.manifest_id = new_manifest_id try: manifest_data = self._download_manifest_to_folder() except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - logger.error(f"You don't have access to the requested resource: {self.manifest_id}") - raise (f"You don't have access to the requested resource: {self.manifest_id}") + logger.error(f"You don't have access to the requested resource: {old_requested_manifest_id} and {new_manifest_id}") else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") @@ -510,6 +511,7 @@ def getDatasetManifest( # search manifest based on given manifest basename regex above # and return a dataframe containing name and id of manifests in a given asset view + print('data set id', datasetId) manifest = all_files[ (all_files['name'].str.contains(manifest_re,regex=True)) & (all_files["parentId"] == datasetId) @@ -519,7 +521,7 @@ def getDatasetManifest( # if there is no pre-exisiting manifest in the specified dataset if manifest.empty: - logger.error(f"Could not find a manifest that fits basename {self.manifest} in asset view and dataset {datasetId}") + logger.warning(f"Could not find a manifest that fits basename {self.manifest} in asset view and dataset {datasetId}") return "" # if there is an exisiting manifest @@ -529,7 +531,7 @@ def getDatasetManifest( md = ManifestDownload(self.syn, manifest_id=manifest_syn_id) manifest_data = ManifestDownload.download_manifest(md, newManifestName=newManifestName, manifest_df=manifest) if manifest_data == "": - logger.error(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") + logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data return manifest_syn_id From edb4646445844a6d660849b0963a67166c43e1e4 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 29 Mar 2023 22:59:20 -0400 Subject: [PATCH 370/615] rename funct to entity_type_mapping --- schematic/store/synapse.py | 4 ++-- schematic/utils/general.py | 13 ++++++++----- schematic_api/api/routes.py | 4 ++-- tests/test_utils.py | 4 ++-- 4 files changed, 14 insertions(+), 11 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 6cc986ed0..c48074206 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -52,7 +52,7 @@ from schematic.exceptions import MissingConfigValueError, AccessCredentialsError from schematic import CONFIG -from schematic.utils.general import entity_type_checking +from schematic.utils.general import entity_type_mapping logger = logging.getLogger("Synapse storage") @@ -91,7 +91,7 @@ def _entity_type_checking(self): if the entity type is wrong, raise an error """ # check the type of entity - entity_type = entity_type_checking(self.syn, self.manifest_id) + entity_type = entity_type_mapping(self.syn, self.manifest_id) if entity_type != "file": logger.error(f'You are using entity type: {entity_type}. Please try using a file') diff --git a/schematic/utils/general.py b/schematic/utils/general.py index d451cc108..ff6a469d0 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -2,6 +2,9 @@ from typing import Any, Dict, Optional, Text import os import math +import logging + +logger = logging.getLogger(__name__) def find_duplicates(_list): """Find duplicate items in a list""" @@ -72,19 +75,19 @@ def convert_gb_to_bytes(gb: int): return bytes_to_return -def entity_type_checking(syn, manifest_id): +def entity_type_mapping(syn, entity_id): """ - check the entity type of the id that needs to be downloaded + Return the entity type of manifest Args: - manifest_id: id of a manifest + entity: id of an entity Return: type_entity: type of the manifest being returned """ # check the type of entity try: - entity_name = syn.get(manifest_id, downloadFile=False) + entity_name = syn.get(entity_id, downloadFile=False) except: - raise(f'Here: {manifest_id}') + logger.error(f'cannot get {syn} from asset store. Please make sure that {entity_id} exists') type_entity = str(type(entity_name)) if type_entity == "": diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 90cc474d2..25a299e2f 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -40,7 +40,7 @@ # # Do stuff after your route executes # pass from flask_cors import cross_origin -from schematic.utils.general import entity_type_checking +from schematic.utils.general import entity_type_mapping logger = logging.getLogger(__name__) logging.basicConfig(level=logging.DEBUG) @@ -569,7 +569,7 @@ def check_entity_type(input_token, entity_id): config_handler() syn = SynapseStorage.login(access_token = input_token) - entity_type = entity_type_checking(syn, entity_id) + entity_type = entity_type_mapping(syn, entity_id) return entity_type diff --git a/tests/test_utils.py b/tests/test_utils.py index 3a5de25bb..caea0d45f 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -21,7 +21,7 @@ ) from schematic import LOADER from schematic.store.synapse import SynapseStorage -from schematic.utils.general import entity_type_checking +from schematic.utils.general import entity_type_mapping logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) @@ -65,7 +65,7 @@ def test_dict2list_with_list(self): @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078", "syn23643253", "syn30988314"]) def test_check_entity_type(self, synapse_store, entity_id): syn = synapse_store.syn - entity_type = entity_type_checking(syn, entity_id) + entity_type = entity_type_mapping(syn, entity_id) if entity_id == "syn27600053": assert entity_type == "folder" elif entity_id == "syn29862078": From 31849a0f4590aad2c803e1d588834c0d6cbed27d Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 10:36:19 -0400 Subject: [PATCH 371/615] add TODO; add isinstance; --- schematic/store/synapse.py | 27 ++++++++++++++------------- schematic/utils/general.py | 20 ++++++++++++-------- schematic_api/api/__main__.py | 2 +- tests/test_utils.py | 5 +++++ 4 files changed, 32 insertions(+), 22 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c48074206..34e09e6f7 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -72,6 +72,7 @@ def _download_manifest_to_folder(self): Return: manifest_data: A new Synapse Entity object of the appropriate type """ + # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config if CONFIG["synapse"]["manifest_folder"]: manifest_data = self.syn.get( self.manifest_id, @@ -132,18 +133,17 @@ def download_manifest(self, newManifestName="", manifest_df=None): else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") - if newManifestName: - if os.path.exists(manifest_data['path']): - # Rename the file we just made to the new name - new_manifest_filename = newManifestName + '.csv' - dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) - new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) - os.rename(manifest_data['path'], new_manifest_path_name) - - # Update file names/paths in manifest_data - manifest_data['name'] = new_manifest_filename - manifest_data['filename'] = new_manifest_filename - manifest_data['path'] = new_manifest_path_name + if newManifestName and os.path.exists(manifest_data['path']): + # Rename the file we just made to the new name + new_manifest_filename = newManifestName + '.csv' + dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) + new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) + os.rename(manifest_data['path'], new_manifest_path_name) + + # Update file names/paths in manifest_data + manifest_data['name'] = new_manifest_filename + manifest_data['filename'] = new_manifest_filename + manifest_data['path'] = new_manifest_path_name return manifest_data class SynapseStorage(BaseStorage): @@ -511,7 +511,6 @@ def getDatasetManifest( # search manifest based on given manifest basename regex above # and return a dataframe containing name and id of manifests in a given asset view - print('data set id', datasetId) manifest = all_files[ (all_files['name'].str.contains(manifest_re,regex=True)) & (all_files["parentId"] == datasetId) @@ -530,6 +529,8 @@ def getDatasetManifest( if downloadFile: md = ManifestDownload(self.syn, manifest_id=manifest_syn_id) manifest_data = ManifestDownload.download_manifest(md, newManifestName=newManifestName, manifest_df=manifest) + ## TO DO: revisit how downstream code handle manifest_data. If the downstream code would break when manifest_data is an empty string, + ## then we should catch the error here without returning an empty string. if manifest_data == "": logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data diff --git a/schematic/utils/general.py b/schematic/utils/general.py index ff6a469d0..e0674a0e7 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -4,6 +4,10 @@ import math import logging +from synapseclient.core.exceptions import SynapseHTTPError +from synapseclient.table import EntityViewSchema +from synapseclient.entity import File, Folder, Project + logger = logging.getLogger(__name__) def find_duplicates(_list): @@ -86,17 +90,17 @@ def entity_type_mapping(syn, entity_id): # check the type of entity try: entity_name = syn.get(entity_id, downloadFile=False) - except: - logger.error(f'cannot get {syn} from asset store. Please make sure that {entity_id} exists') - type_entity = str(type(entity_name)) + except SynapseHTTPError as e: + logger.error(f'cannot get {entity_id} from asset store. Please make sure that {entity_id} exists') + raise SynapseHTTPError(f'cannot get {entity_id} from asset store. Please make sure that {entity_id} exists') from e - if type_entity == "": + if isinstance(entity_name, EntityViewSchema): return "asset view" - elif type_entity == "": + elif isinstance(entity_name, Folder): return "folder" - elif type_entity == "": + elif isinstance(entity_name, File): return "file" - elif type_entity == "": + elif isinstance(entity_name, Project): return "project" else: - return type_entity \ No newline at end of file + return entity_name \ No newline at end of file diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index ea710081d..9e65a1b9e 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -12,7 +12,7 @@ def main(): port = int(port) # Launch app - # CORS(app, resources={r"*": {"origins": "*"}}) + #TO DO: add a flag --debug to control debug parameter app.run(host=host, port=port, debug=True) if __name__ == "__main__": diff --git a/tests/test_utils.py b/tests/test_utils.py index caea0d45f..1a9da5a68 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -7,6 +7,7 @@ import pytest from pandas.testing import assert_frame_equal +from synapseclient.core.exceptions import SynapseHTTPError from schematic.schemas.explorer import SchemaExplorer from schematic.schemas import df_parser @@ -65,6 +66,7 @@ def test_dict2list_with_list(self): @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078", "syn23643253", "syn30988314"]) def test_check_entity_type(self, synapse_store, entity_id): syn = synapse_store.syn + entity_type = entity_type_mapping(syn, entity_id) if entity_id == "syn27600053": assert entity_type == "folder" @@ -74,6 +76,9 @@ def test_check_entity_type(self, synapse_store, entity_id): assert entity_type == "asset view" elif entity_id == "syn30988314": assert entity_type == "folder" + # test with an invalid entity id + with pytest.raises(SynapseHTTPError) as exception_info: + entity_type_mapping(syn, "syn123456") class TestCliUtils: From a82c37830f4cdcf1908733f7420a7f5ac040f608 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 10:42:47 -0400 Subject: [PATCH 372/615] add TO DO comment --- run_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/run_api.py b/run_api.py index 5b7118412..633592b4e 100755 --- a/run_api.py +++ b/run_api.py @@ -14,5 +14,5 @@ # Launch app app = create_app() - #CORS(app, resources={r"*": {"origins": "*"}}) + #TO DO: add a flag --debug to control debug parameter app.run(host=host, port=port, debug=True) \ No newline at end of file From e64a25f1de022b8abd3a5f5eae63a36fc9ae95a5 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 10:44:20 -0400 Subject: [PATCH 373/615] return concreteType --- schematic/utils/general.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index e0674a0e7..ac1178bc0 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -103,4 +103,5 @@ def entity_type_mapping(syn, entity_id): elif isinstance(entity_name, Project): return "project" else: - return entity_name \ No newline at end of file + # if there's no matching type, return concreteType + return entity_name.concreteType \ No newline at end of file From bb542ad8bfbfefd62c0ac33c3238989f41fe70a9 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 10:48:56 -0400 Subject: [PATCH 374/615] lint general.py --- schematic/utils/general.py | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index ac1178bc0..d964ec96e 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -10,6 +10,7 @@ logger = logging.getLogger(__name__) + def find_duplicates(_list): """Find duplicate items in a list""" return set([x for x in _list if _list.count(x) > 1]) @@ -35,15 +36,16 @@ def unlist(_list): else: return _list + def get_dir_size(path: str): """calculate total size of a directory - Args: - path: path to a folder + Args: + path: path to a folder return: total size of a directory """ total = 0 # Example usage of os.scandir could be found here: https://docs.python.org/3/library/os.html#os.scandir - # Technically, scandir.close() is called automatically. But it is still advisable to call it explicitly or use the with statement. + # Technically, scandir.close() is called automatically. But it is still advisable to call it explicitly or use the with statement. with os.scandir(path) as it: for entry in it: if entry.is_file(): @@ -52,6 +54,7 @@ def get_dir_size(path: str): total += get_dir_size(entry.path) return total + def convert_size(size_bytes: int): """convert bytes to a human readable format Args: @@ -59,16 +62,17 @@ def convert_size(size_bytes: int): return: a string that indicates bytes in a different format """ if size_bytes == 0: - return "0B" + return "0B" size_name = ("B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB") # calculate the log of size (in bytes) to base 1024 and run it down to the nearest integer index_int = int(math.floor(math.log(size_bytes, 1024))) # return the value of 1024 raised to the power of index power_cal = math.pow(1024, index_int) - #convert bytes to a different unit if applicable + # convert bytes to a different unit if applicable size_bytes_converted = round(size_bytes / power_cal, 2) return f"{size_bytes_converted} {size_name[index_int]})" + def convert_gb_to_bytes(gb: int): """convert gb to bytes Args: @@ -83,16 +87,20 @@ def entity_type_mapping(syn, entity_id): """ Return the entity type of manifest Args: - entity: id of an entity - Return: + entity: id of an entity + Return: type_entity: type of the manifest being returned """ # check the type of entity - try: + try: entity_name = syn.get(entity_id, downloadFile=False) - except SynapseHTTPError as e: - logger.error(f'cannot get {entity_id} from asset store. Please make sure that {entity_id} exists') - raise SynapseHTTPError(f'cannot get {entity_id} from asset store. Please make sure that {entity_id} exists') from e + except SynapseHTTPError as e: + logger.error( + f"cannot get {entity_id} from asset store. Please make sure that {entity_id} exists" + ) + raise SynapseHTTPError( + f"cannot get {entity_id} from asset store. Please make sure that {entity_id} exists" + ) from e if isinstance(entity_name, EntityViewSchema): return "asset view" @@ -102,6 +110,6 @@ def entity_type_mapping(syn, entity_id): return "file" elif isinstance(entity_name, Project): return "project" - else: + else: # if there's no matching type, return concreteType - return entity_name.concreteType \ No newline at end of file + return entity_name.concreteType From d59fa34143d5afbcbd96ac013428f31be7180a89 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 12:48:00 -0400 Subject: [PATCH 375/615] add indentation; edit testg --- schematic/manifest/generator.py | 5 +++-- tests/test_manifest.py | 11 +++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 5a84c23ba..f02a261db 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1556,6 +1556,7 @@ def get_manifest( # Populate empty template with existing manifest if manifest_record: + print('did i get manifest record', manifest_record) # TODO: Update or remove the warning in self.__init__() if # you change the behavior here based on self.use_annotations @@ -1621,8 +1622,8 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a start_col_index = len(workbook_headers) df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index = False, header=True) - # add additional content to the existing spreadsheet - additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) + # add additional content to the existing spreadsheet + additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 3d750a473..6d938c438 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -336,7 +336,7 @@ def test_get_missing_columns(self, simple_manifest_generator, wb_headers, manife - @pytest.mark.parametrize("additional_df_dict", [{'test one column': ['a', 'b'], 'test two column': ['c', 'd']}, None]) + @pytest.mark.parametrize("additional_df_dict", [{"Filename": ['a', 'b'], "Sample ID": ['a', 'b'], "File Format": ['a', 'b'], "Component": ['a', 'b'], "Genome Build": ['a', 'b'], "Genome FASTA": ['a', 'b'], "test_one_column": ['a', 'b'], "test_two_column": ['c', 'd']}, None]) def test_populate_existing_excel_spreadsheet(self, simple_manifest_generator, simple_test_manifest_excel, additional_df_dict): generator = simple_manifest_generator if additional_df_dict: @@ -356,14 +356,17 @@ def test_populate_existing_excel_spreadsheet(self, simple_manifest_generator, si # if we are not adding any additional content if additional_test_df.empty: + # make sure that new content also gets added assert len(new_df.columns) == 6 # we should be able to see new columns get added else: # new columns get added - assert not new_df[["test one column", "test two column"]].empty + assert not new_df[["test_one_column", "test_two_column"]].empty + assert len(new_df.test_one_column.value_counts()) > 0 + assert len(new_df.test_two_column.value_counts()) > 0 - # remove file - os.remove(dummy_output_path) + # remove file + os.remove(dummy_output_path) From 4f4f44c1476e58e8b52e2b67f1fffde73f8ab7ef Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 13:00:19 -0400 Subject: [PATCH 376/615] update syntax --- schematic/manifest/generator.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index f02a261db..a625f6a57 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1617,10 +1617,10 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a # if there are new columns, add them to the end of spreadsheet # Note: previously, we tried looping through the out of schema columns and use worksheet.cell to modify a particular cell. But that functionality is no longer working. - if len(out_of_schema_columns_lst) > 0: + if out_of_schema_columns_lst: df_additional_headers = pd.DataFrame(columns=out_of_schema_columns_lst) start_col_index = len(workbook_headers) - df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index = False, header=True) + df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index=False, header=True) # add additional content to the existing spreadsheet additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) From 16523b23152c17fbafe55ef280d618cb26ca540a Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 13:03:41 -0400 Subject: [PATCH 377/615] add TODO --- schematic/manifest/generator.py | 3 +-- tests/test_manifest.py | 39 +-------------------------------- 2 files changed, 2 insertions(+), 40 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index a625f6a57..8c2eac8aa 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1474,6 +1474,7 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st output_path: Determines the output path of the exported manifest (only relevant if returning an excel spreadsheet) return: a pandas dataframe, file path of an excel spreadsheet, or a google sheet URL """ + ## TO DO: deprecate sheet_url parameter and simplify the logic here # check if output_format parameter gets set. If not, check the sheet_url parameter if not output_format: @@ -1556,8 +1557,6 @@ def get_manifest( # Populate empty template with existing manifest if manifest_record: - print('did i get manifest record', manifest_record) - # TODO: Update or remove the warning in self.__init__() if # you change the behavior here based on self.use_annotations diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 6d938c438..a0c236815 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -282,44 +282,7 @@ def test_gather_all_fields(self, simple_manifest_generator): assert required_metadata == "mock required metadata fields" - - - #@patch("schematic.utils.google_api_utils.execute_google_api_requests") - # @patch("schematic.manifest.generator.ManifestGenerator._create_requests_body") - # @patch("schematic.manifest.generator.ManifestGenerator._set_permissions") - # @patch("schematic.manifest.generator.ManifestGenerator._gs_add_additional_metadata") - # @patch("schematic.manifest.generator.ManifestGenerator._gs_add_and_format_columns") - # def test_create_empty_gs(self, mock_format_columns, mock_add_metadata, mock_set_perms, mock_request_body,simple_manifest_generator): - # ''' - # Create an empty manifest using specifications from the json schema. - # ''' - - # # Create the mock object - # mock_my_func = MagicMock() - - # self.sheet_service = Mock() - - # spreadsheet_id = "example_sheet_id" - - # mock_format_columns.return_value = ("add_format_cols_response", ["field1", "field2"]) - # mock_add_metadata.return_value = "add_metadata_response" - # mock_set_perms.return_value = "set_perms_response" - # mock_request_body.return_value = "mock request body" - # #mock_execute.return_value = "mock response" - - # required_metadata_fields = "mock required metadata" - # json_schema = "mock json schema string" - # spreadsheet_id = "mock_spreadsheet_id" - - # def mock_return(): - # return "mock haha" - - # with patch('schematic.manifest.generator.utils.google_api_utils.execute_google_api_requests', new=mock_return): - # response = simple_manifest_generator._create_empty_gs( - # required_metadata_fields, - # json_schema, - # spreadsheet_id, - # ) + # TO DO: add tests for: test_create_empty_gs @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) From ed20c53873a3244eb0123aaec1bf623ed2d7fca5 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 13:06:10 -0400 Subject: [PATCH 378/615] remove unsused fixture --- tests/test_manifest.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index a0c236815..e665e40a0 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -93,11 +93,6 @@ def test_init(self, helpers): assert generator.root is None assert type(generator.sg) is SchemaGenerator - # Define the function to be called instead of my_func - def mock_google_api_execution(): - print('mock google api execution') - - @pytest.mark.google_credentials_needed def test_get_manifest_first_time(self, manifest): From ac833970a7a0ef86bf1fea7f274b4ed13614b3ff Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 31 Mar 2023 18:36:04 -0400 Subject: [PATCH 379/615] update to use parameterize correctly in test and change entity_name to entity and return concreteType when no matching exists --- schematic/utils/general.py | 14 +++++++------- tests/test_utils.py | 18 +++++++----------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index d964ec96e..06c86662c 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -87,13 +87,13 @@ def entity_type_mapping(syn, entity_id): """ Return the entity type of manifest Args: - entity: id of an entity + entity_id: id of an entity Return: type_entity: type of the manifest being returned """ # check the type of entity try: - entity_name = syn.get(entity_id, downloadFile=False) + entity = syn.get(entity_id, downloadFile=False) except SynapseHTTPError as e: logger.error( f"cannot get {entity_id} from asset store. Please make sure that {entity_id} exists" @@ -102,14 +102,14 @@ def entity_type_mapping(syn, entity_id): f"cannot get {entity_id} from asset store. Please make sure that {entity_id} exists" ) from e - if isinstance(entity_name, EntityViewSchema): + if isinstance(entity, EntityViewSchema): return "asset view" - elif isinstance(entity_name, Folder): + elif isinstance(entity, Folder): return "folder" - elif isinstance(entity_name, File): + elif isinstance(entity, File): return "file" - elif isinstance(entity_name, Project): + elif isinstance(entity, Project): return "project" else: # if there's no matching type, return concreteType - return entity_name.concreteType + return entity.concreteType diff --git a/tests/test_utils.py b/tests/test_utils.py index 1a9da5a68..157b975a4 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -63,24 +63,20 @@ def test_dict2list_with_list(self): test_list = general.dict2list(mock_list) assert test_list == mock_list - @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078", "syn23643253", "syn30988314"]) - def test_check_entity_type(self, synapse_store, entity_id): + @pytest.mark.parametrize("entity_id,expected_type", [("syn27600053","folder"), ("syn29862078", "file"), ("syn23643253", "asset view"), ("syn30988314", "folder"), ("syn51182432", "org.sagebionetworks.repo.model.table.TableEntity")]) + def test_entity_type_mapping(self, synapse_store, entity_id, expected_type): syn = synapse_store.syn entity_type = entity_type_mapping(syn, entity_id) - if entity_id == "syn27600053": - assert entity_type == "folder" - elif entity_id == "syn29862078": - assert entity_type == "file" - elif entity_id == "syn23643253": - assert entity_type == "asset view" - elif entity_id == "syn30988314": - assert entity_type == "folder" + assert entity_type == expected_type + + def test_entity_type_mapping_invalid_entity_id(self, synapse_store): + syn = synapse_store.syn + # test with an invalid entity id with pytest.raises(SynapseHTTPError) as exception_info: entity_type_mapping(syn, "syn123456") - class TestCliUtils: def test_query_dict(self): From 1f0e1d3da5554a511ae21c25a13b97f9a7dbbd30 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 3 Apr 2023 11:30:06 -0400 Subject: [PATCH 380/615] avoid key error; catch error when failing to download manifestls --- schematic/store/synapse.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 34e09e6f7..bf7f93680 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -133,7 +133,7 @@ def download_manifest(self, newManifestName="", manifest_df=None): else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") - if newManifestName and os.path.exists(manifest_data['path']): + if newManifestName and os.path.exists(manifest_data.get('path')): # Rename the file we just made to the new name new_manifest_filename = newManifestName + '.csv' dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) @@ -666,10 +666,11 @@ def getProjectManifests(self, projectId: str) -> List[str]: ) manifest_info = self.getDatasetManifest(datasetId,downloadFile=True) - try: - manifest_name = manifest_info["properties"]["name"] - except: - logger.error(f'Failed to download manifests from {datasetId}') + manifest_name = manifest_info["properties"].get("name", "") + + if not manifest_name: + logger.error(f'Failed to download manifests from {datasetId}') + manifest_path = manifest_info["path"] manifest_df = load_df(manifest_path) From 576ae811632556bf4ec0a2922025dfb9cb0ee37b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 3 Apr 2023 10:09:05 -0700 Subject: [PATCH 381/615] add flag to control index dropping --- api/openapi/api.yaml | 6 ++++++ api/routes.py | 4 ++-- schematic/visualization/attributes_explorer.py | 10 +++++----- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 8ed7ff929..09c89b9cf 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -1176,6 +1176,12 @@ paths: example: >- Patient required: true + - in: query + name: include_index + schema: + type: boolean + default: false + required: true responses: "200": description: Returns a CSV as a JSON String. diff --git a/api/routes.py b/api/routes.py index ffe6bc0d1..8623c28e5 100644 --- a/api/routes.py +++ b/api/routes.py @@ -510,13 +510,13 @@ def get_viz_attributes_explorer(schema_url): return attributes_csv -def get_viz_component_attributes_explorer(schema_url, component): +def get_viz_component_attributes_explorer(schema_url, component, include_index): # call config_handler() config_handler() temp_path_to_jsonld = get_temp_jsonld(schema_url) - attributes_csv = AttributesExplorer(temp_path_to_jsonld).parse_component_attributes(component, save_file=False) + attributes_csv = AttributesExplorer(temp_path_to_jsonld).parse_component_attributes(component, save_file=False, include_index=include_index) return attributes_csv diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index 03f903776..8fee3e596 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -69,7 +69,7 @@ def parse_attributes(self, save_file=True): # have to provide. return self._parse_attributes(components, save_file) - def parse_component_attributes(self, component=None, save_file=True,): + def parse_component_attributes(self, component=None, save_file=True, include_index=True): ''' Args: save_file (bool): True: merged_df is saved locally to output_path. @@ -85,9 +85,9 @@ def parse_component_attributes(self, component=None, save_file=True,): if not component: raise ValueError("You must provide a component to visualize.") else: - return self._parse_attributes([component], save_file) + return self._parse_attributes([component], save_file, include_index) - def _parse_attributes(self, components, save_file = True): + def _parse_attributes(self, components, save_file=True, include_index=True): ''' Args: save_file (bool): True: merged_df is saved locally to output_path. @@ -200,6 +200,6 @@ def _parse_attributes(self, components, save_file = True): merged_attributes_df = merged_attributes_df[cols] if save_file == True: - return merged_attributes_df.to_csv(os.path.join(self.output_path, self.schema_name + 'attributes_data.vis_data.csv'), index=False) + return merged_attributes_df.to_csv(os.path.join(self.output_path, self.schema_name + 'attributes_data.vis_data.csv'), index=include_index) elif save_file == False: - return merged_attributes_df.to_csv(index=False) + return merged_attributes_df.to_csv(index=include_index) From 92b62b251a0b5bc7416c4759d5797fc78fe3582d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 3 Apr 2023 10:09:31 -0700 Subject: [PATCH 382/615] Revert "update test for removed col" This reverts commit ae75133f944d687d6145f9ba1c8180b20cf33d32. --- tests/test_viz.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_viz.py b/tests/test_viz.py index 0d9b52512..954f45df5 100644 --- a/tests/test_viz.py +++ b/tests/test_viz.py @@ -37,7 +37,7 @@ class TestVisualization: def test_ae(self, helpers, attributes_explorer): attributes_str = attributes_explorer.parse_attributes(save_file=False) - df = pd.read_csv(StringIO(attributes_str)) + df = pd.read_csv(StringIO(attributes_str)).drop(columns=['Unnamed: 0']) # For the attributes df define expected columns expect_col_names = ['Attribute', 'Label', 'Description', From aceefc6aae7d4fa4ad835cde8df4666c9213e40e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:16:00 -0700 Subject: [PATCH 383/615] update test --- tests/test_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 735807a6b..00a75bc44 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -718,7 +718,8 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso def test_visualize_component(self, client, data_model_jsonld,component): params = { "schema_url": data_model_jsonld, - "component": component + "component": component, + "include_index": False } response = client.get("http://localhost:3001/v1/visualize/component", query_string = params) From ddfb7588711469aae92f4a2c5ccc2365c15a73c1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:25:41 -0700 Subject: [PATCH 384/615] add description to flag --- api/openapi/api.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 09c89b9cf..cbbf3ce51 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -1181,6 +1181,7 @@ paths: schema: type: boolean default: false + description: Whether to include the indexes of the datafram in the returned JSON string (true) or not (false). required: true responses: "200": From bb7a59c11e5835551a0800afad80d54d497ab372 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 3 Apr 2023 14:48:41 -0700 Subject: [PATCH 385/615] add example response --- api/openapi/api.yaml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index cbbf3ce51..3d67663e4 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -1190,6 +1190,21 @@ paths: text/csv: schema: type: string + example: Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component + + Component,Component,TBD,False,,,,Patient + + Patient ID,PatientID,TBD,True,,,,Patient + + Year of Birth,YearofBirth,TBD,False,,,,Patient + + Sex,Sex,TBD,True,,"['Female', 'Other', 'Male']",,Patient + + Diagnosis,Diagnosis,TBD,True,,"['Cancer', 'Healthy']",,Patient + + Cancer Type,CancerType,TBD,False,True,"['Lung', 'Skin', 'Colorectal', 'Breast', 'Prostate', '']"," If Diagnosis is ""Cancer"" then ""Cancer Type"" is required",Patient + + Family History,FamilyHistory,TBD,False,True,," If Diagnosis is ""Cancer"" then ""Family History"" is required",Patient tags: - Visualization Operations \ No newline at end of file From a0a6c33075d199b886014fb1db8fd805d031654e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:49:00 -0700 Subject: [PATCH 386/615] add NA rule to `validation_rule_info` --- schematic/utils/validate_rules_utils.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 70a3437c8..c723905da 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -104,6 +104,11 @@ def validation_rule_info(): 'type': "content_validation", 'complementary_rules': ['int','float','num','protectAges'], 'default_message_level': 'error'}, + "IsNA": { + 'arguments':(0, 1), + 'type': "content_validation", + 'complementary_rules': ['int', 'float', 'num', 'str'], + 'default_message_level': 'warning'}, } return rule_dict From d4386e5cc22adc9e5160aa3dce88b40c15fd5187 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:49:45 -0700 Subject: [PATCH 387/615] remove complementary rules --- schematic/utils/validate_rules_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index c723905da..5f5011dd6 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -107,7 +107,7 @@ def validation_rule_info(): "IsNA": { 'arguments':(0, 1), 'type': "content_validation", - 'complementary_rules': ['int', 'float', 'num', 'str'], + 'complementary_rules': None, 'default_message_level': 'warning'}, } From f4b901f13d31932336994c5e3ab9ec06b0a8a26d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:52:02 -0700 Subject: [PATCH 388/615] add new mock attribute to schema --- tests/data/example.model.csv | 3 ++- tests/data/example.model.jsonld | 22 ++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index 9b056b065..94cfa0c84 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -18,7 +18,7 @@ CRAM,,,"Genome Build, Genome FASTA",,FALSE,ValidValue,,, CSV/TSV,,,Genome Build,,FALSE,ValidValue,,, Genome Build,,"GRCh37, GRCh38, GRCm38, GRCm39",,,TRUE,DataProperty,,, Genome FASTA,,,,,TRUE,DataProperty,,, -MockComponent,,,"Component, Check List, Check Regex List, Check Regex Single, Check Regex Format, Check Num, Check Float, Check Int, Check String, Check URL,Check Match at Least, Check Match at Least values, Check Match Exactly, Check Match Exactly values, Check Recommended, Check Ages, Check Unique, Check Range, Check Date",,FALSE,DataType,,, +MockComponent,,,"Component, Check List, Check Regex List, Check Regex Single, Check Regex Format, Check Num, Check Float, Check Int, Check String, Check URL,Check Match at Least, Check Match at Least values, Check Match Exactly, Check Match Exactly values, Check Recommended, Check Ages, Check Unique, Check Range, Check Date, Check NA",,FALSE,DataType,,, Check List,,"ab, cd, ef, gh",,,TRUE,DataProperty,,,list strict Check Regex List,,,,,TRUE,DataProperty,,,list strict::regex match [a-f] Check Regex Single,,,,,TRUE,DataProperty,,,regex search [a-f] @@ -37,5 +37,6 @@ Check Ages,,,,,TRUE,DataProperty,,,protectAges Check Unique,,,,,TRUE,DataProperty,,,unique error Check Range,,,,,TRUE,DataProperty,,,inRange 50 100 error Check Date,,,,,TRUE,DataProperty,,,date +Check NA,,,,,TRUE,DataProperty,,,IsNA MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, MockRDB_id,,,,,TRUE,DataProperty,,,int diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index b9f3fb0de..1dc044a8f 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2539,6 +2539,9 @@ }, { "@id": "bts:CheckDate" + }, + { + "@id": "bts:CheckNA" } ], "sms:validationRules": [] @@ -2900,6 +2903,25 @@ "date" ] }, + { + "@id": "bts:CheckNA", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckNA", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check NA", + "sms:required": "sms:true", + "sms:validationRules": [ + "IsNA" + ] + }, { "@id": "bts:MockRDB", "@type": "rdfs:Class", From 298ec61a1f23a45f4e8fb2f1f4dba8310ad4f50c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 10:58:12 -0700 Subject: [PATCH 389/615] update test manifests --- tests/data/mock_manifests/Invalid_Test_Manifest.csv | 8 ++++---- tests/data/mock_manifests/Valid_Test_Manifest.csv | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/data/mock_manifests/Invalid_Test_Manifest.csv b/tests/data/mock_manifests/Invalid_Test_Manifest.csv index 5a4fbd99c..34490d3ce 100644 --- a/tests/data/mock_manifests/Invalid_Test_Manifest.csv +++ b/tests/data/mock_manifests/Invalid_Test_Manifest.csv @@ -1,4 +1,4 @@ -Component,Check List,Check Regex List,Check Regex Format,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date -MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32-984 -MockComponent,invalid list values,ab cd ef,m,q,c,99,5.63,94,http://googlef.com/,7163,51100,9965,71738,,32851,str1,30,notADate -MockComponent,"ab,cd","ab,cd,ef",b,b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,8085,8085,1738,210065,,6550,str1,90,84-43-094 +Component,Check List,Check Regex List,Check Regex Format,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date,Check NA +MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32-984,Not Applicable +MockComponent,invalid list values,ab cd ef,m,q,c,99,5.63,94,http://googlef.com/,7163,51100,9965,71738,,32851,str1,30,notADate,3489249023 +MockComponent,"ab,cd","ab,cd,ef",b,b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,8085,8085,1738,210065,,6550,str1,90,84-43-094,Not Applicable diff --git a/tests/data/mock_manifests/Valid_Test_Manifest.csv b/tests/data/mock_manifests/Valid_Test_Manifest.csv index 97b736efd..7d07791f0 100644 --- a/tests/data/mock_manifests/Valid_Test_Manifest.csv +++ b/tests/data/mock_manifests/Valid_Test_Manifest.csv @@ -1,5 +1,5 @@ -Component,Check List,Check Regex List,Check Regex Single,Check Regex Format,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date -MockComponent,"ab,cd","a,c,f",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,8085,,6571,str1,75,2022-10-21 -MockComponent,"ab,cd","a,c,f",e,b,71,58.4,3,valid,https://www.google.com/,9965,9965,9965,9965,,6571,str2,80,October 21 2022 -MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,8085,8085,1738,1738,present,32849,str3,95,10/21/2022 -MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,79,79,7,7,,32849,str4,55,21/10/2022 +Component,Check List,Check Regex List,Check Regex Single,Check Regex Format,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date,Check NA +MockComponent,"ab,cd","a,c,f",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,8085,,6571,str1,75,10/21/2022,Not Applicable +MockComponent,"ab,cd","a,c,f",e,b,71,58.4,3,valid,https://www.google.com/,9965,9965,9965,9965,,6571,str2,80,October 21 2022,Not Applicable +MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,8085,8085,1738,1738,present,32849,str3,95,10/21/2022,Not Applicable +MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,79,79,7,7,,32849,str4,55,21/10/2022,Not Applicable From 30d70224823948aa39729f7ff37e967ae60e4ed1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 11:05:05 -0700 Subject: [PATCH 390/615] add functionality for `IsNa` rule --- schematic/models/GE_Helpers.py | 14 +++++++++++++- schematic/models/validate_attribute.py | 4 ++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/schematic/models/GE_Helpers.py b/schematic/models/GE_Helpers.py index 3801360ca..73ad20709 100644 --- a/schematic/models/GE_Helpers.py +++ b/schematic/models/GE_Helpers.py @@ -134,7 +134,8 @@ def build_expectation_suite(self,): "protectAges": "expect_column_values_to_be_between", "unique": "expect_column_values_to_be_unique", "inRange": "expect_column_values_to_be_between", - + "IsNA": "expect_column_values_to_match_regex_list", + # To be implemented rules with possible expectations #"list": "expect_column_values_to_not_match_regex_list", #"regex": "expect_column_values_to_match_regex", @@ -285,6 +286,17 @@ def build_expectation_suite(self,): }, "validation_rule": rule } + + elif base_rule==("IsNA"): + args["mostly"]=1.0 + args["regex_list"]=['Not Applicable'] + meta={ + "notes": { + "format": "markdown", + "content": "Expect column values to be marked Not Applicable. **Markdown** `Supported`", + }, + "validation_rule": rule + } #add expectation for attribute to suite self.add_expectation( diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 05cea5c90..49d451d2f 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -482,6 +482,10 @@ def generate_content_error( content_error_str = ( f"{attribute_name} values in rows {row_num} are not parsable as dates." ) + elif val_rule.startswith('IsNA'): + content_error_str = ( + f"{attribute_name} values in rows {row_num} are not marked as 'Not Applicable'." + ) logLevel(content_error_str) error_row = row_num error_message = content_error_str From c68be43a4cfdd859b00ac0e2a9e7ea6cae9310f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 4 Apr 2023 12:04:38 -0700 Subject: [PATCH 391/615] update rule args allowed/reqd --- schematic/utils/validate_rules_utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 5f5011dd6..5eab97627 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -105,7 +105,7 @@ def validation_rule_info(): 'complementary_rules': ['int','float','num','protectAges'], 'default_message_level': 'error'}, "IsNA": { - 'arguments':(0, 1), + 'arguments':(1, 0), 'type': "content_validation", 'complementary_rules': None, 'default_message_level': 'warning'}, From a6069c4ba916f224b89ef83d24a1425e28fd6f03 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 5 Apr 2023 12:05:04 -0700 Subject: [PATCH 392/615] update docstrings --- schematic/visualization/attributes_explorer.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schematic/visualization/attributes_explorer.py b/schematic/visualization/attributes_explorer.py index 8fee3e596..0b18ab092 100644 --- a/schematic/visualization/attributes_explorer.py +++ b/schematic/visualization/attributes_explorer.py @@ -74,6 +74,8 @@ def parse_component_attributes(self, component=None, save_file=True, include_ind Args: save_file (bool): True: merged_df is saved locally to output_path. False: merged_df is returned. + include_index (bool): + Whether to include the index in the returned dataframe (True) or not (False) Returns: merged_df (pd.DataFrame): dataframe containing data relating to attributes @@ -94,6 +96,8 @@ def _parse_attributes(self, components, save_file=True, include_index=True): False: merged_df is returned. components (list): list of components to parse attributes for + include_index (bool): + Whether to include the index in the returned dataframe (True) or not (False) Returns: merged_df (pd.DataFrame): dataframe containing data relating to attributes From 9efb57462d2e1f54f1f6dfd5dca995528519fe54 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 5 Apr 2023 14:19:33 -0700 Subject: [PATCH 393/615] add assertions to check response text --- tests/test_api.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index 00a75bc44..75b6fb004 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -726,6 +726,10 @@ def test_visualize_component(self, client, data_model_jsonld,component): assert response.status_code == 200 + if component == "Patient": + assert "Patient ID,PatientID,TBD,True,,,,Patient" in response.text + elif component == "MockComponent": + assert "Component,Component,TBD,False,MockComponent" in response.text @pytest.mark.schematic_api class TestValidationBenchmark(): From c091d1ceba3c7dcacfdf39d8de6fe87c116470c0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:47:00 -0700 Subject: [PATCH 394/615] update testing components and test assertions --- tests/test_api.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 75b6fb004..09d9bb3fe 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -714,7 +714,7 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 - @pytest.mark.parametrize("component", ["Patient", "MockComponent"]) + @pytest.mark.parametrize("component", ["Patient", "BulkRNA-seqAssay"]) def test_visualize_component(self, client, data_model_jsonld,component): params = { "schema_url": data_model_jsonld, @@ -726,10 +726,11 @@ def test_visualize_component(self, client, data_model_jsonld,component): assert response.status_code == 200 + assert "Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component" in response.text if component == "Patient": assert "Patient ID,PatientID,TBD,True,,,,Patient" in response.text - elif component == "MockComponent": - assert "Component,Component,TBD,False,MockComponent" in response.text + elif component == "BulkRNA-seqAssay": + assert "Component,Component,Component,TBD,False,,,,BulkRNA-seqAssay" in response.text @pytest.mark.schematic_api class TestValidationBenchmark(): From 13ec78a68eadd10bf36123b0a875a295f30a357c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 09:57:46 -0700 Subject: [PATCH 395/615] add `parse_component_attributes` test --- tests/test_viz.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/test_viz.py b/tests/test_viz.py index 954f45df5..df344ad6e 100644 --- a/tests/test_viz.py +++ b/tests/test_viz.py @@ -52,6 +52,29 @@ def test_ae(self, helpers, attributes_explorer): assert actual_column_names == expect_col_names assert actual_components == expected_components + @pytest.mark.parametrize("component", ["Patient", "BulkRNA-seqAssay"]) + def test_ce(self, component, attributes_explorer): + """ + Test the output of parse_component_attributes + """ + # get attributes string + component_attributes_str = attributes_explorer.parse_component_attributes(component=component,save_file=False, include_index=False) + # convert to dataframe + component_attributes = pd.read_csv(StringIO(component_attributes_str)) + + # For the attributes df define expected columns + expect_col_names = ['Attribute', 'Label', 'Description', + 'Required', 'Cond_Req', 'Valid Values', 'Conditional Requirements', + 'Component'] + + actual_column_names = component_attributes.columns.tolist() + + # assert all columns are present + assert actual_column_names == expect_col_names + # assert all attributes belong to the same component + assert (component_attributes.Component == component).all() + + def test_text(self, helpers, tangled_tree): text_format = 'plain' From 53bf1d7072ab4afc72c586081d4bc1129ab3f51d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:48:34 -0700 Subject: [PATCH 396/615] update rule combos --- schematic/utils/validate_rules_utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 5eab97627..1ae81943f 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -22,19 +22,19 @@ def validation_rule_info(): "int": { 'arguments':(1, 0), 'type': "type_validation", - 'complementary_rules': ['inRange',], + 'complementary_rules': ['inRange', 'IsNA'], 'default_message_level': 'error'}, "float": { 'arguments':(1, 0), 'type': "type_validation", - 'complementary_rules': ['inRange',], + 'complementary_rules': ['inRange', 'IsNA'], 'default_message_level': 'error'}, "num": { 'arguments':(1, 0), 'type': "type_validation", - 'complementary_rules': ['inRange',], + 'complementary_rules': ['inRange', 'IsNA'], 'default_message_level': 'error'}, "str": { @@ -104,10 +104,11 @@ def validation_rule_info(): 'type': "content_validation", 'complementary_rules': ['int','float','num','protectAges'], 'default_message_level': 'error'}, + "IsNA": { 'arguments':(1, 0), 'type': "content_validation", - 'complementary_rules': None, + 'complementary_rules': ['int', 'float', 'num', ], 'default_message_level': 'warning'}, } From 7f4e82f2521b6054dbf2a90f44ccc1c662b0c747 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:48:52 -0700 Subject: [PATCH 397/615] update data model with new combo --- tests/data/example.model.csv | 2 +- tests/data/example.model.jsonld | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index 94cfa0c84..eec328eae 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -37,6 +37,6 @@ Check Ages,,,,,TRUE,DataProperty,,,protectAges Check Unique,,,,,TRUE,DataProperty,,,unique error Check Range,,,,,TRUE,DataProperty,,,inRange 50 100 error Check Date,,,,,TRUE,DataProperty,,,date -Check NA,,,,,TRUE,DataProperty,,,IsNA +Check NA,,,,,TRUE,DataProperty,,,int::IsNA MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, MockRDB_id,,,,,TRUE,DataProperty,,,int diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index 1dc044a8f..b8b1c5d1b 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2919,6 +2919,7 @@ "sms:displayName": "Check NA", "sms:required": "sms:true", "sms:validationRules": [ + "int", "IsNA" ] }, From bc56a7a73d7e446ffb9a1e80d98eae3197d101c4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 10:49:47 -0700 Subject: [PATCH 398/615] update test manifests --- tests/data/mock_manifests/Invalid_Test_Manifest.csv | 4 ++-- tests/data/mock_manifests/Valid_Test_Manifest.csv | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/data/mock_manifests/Invalid_Test_Manifest.csv b/tests/data/mock_manifests/Invalid_Test_Manifest.csv index 34490d3ce..fcd84fa7f 100644 --- a/tests/data/mock_manifests/Invalid_Test_Manifest.csv +++ b/tests/data/mock_manifests/Invalid_Test_Manifest.csv @@ -1,4 +1,4 @@ Component,Check List,Check Regex List,Check Regex Format,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date,Check NA -MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32-984,Not Applicable -MockComponent,invalid list values,ab cd ef,m,q,c,99,5.63,94,http://googlef.com/,7163,51100,9965,71738,,32851,str1,30,notADate,3489249023 +MockComponent,"ab,cd","ab,cd,ef",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,98085,,6549,str1,70,32-984,7 +MockComponent,invalid list values,ab cd ef,m,q,c,99,5.63,94,http://googlef.com/,7163,51100,9965,71738,,32851,str1,30,notADate,9.5 MockComponent,"ab,cd","ab,cd,ef",b,b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,8085,8085,1738,210065,,6550,str1,90,84-43-094,Not Applicable diff --git a/tests/data/mock_manifests/Valid_Test_Manifest.csv b/tests/data/mock_manifests/Valid_Test_Manifest.csv index 7d07791f0..a3d061026 100644 --- a/tests/data/mock_manifests/Valid_Test_Manifest.csv +++ b/tests/data/mock_manifests/Valid_Test_Manifest.csv @@ -1,5 +1,5 @@ Component,Check List,Check Regex List,Check Regex Single,Check Regex Format,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match at Least values,Check Match Exactly,Check Match Exactly values,Check Recommended,Check Ages,Check Unique,Check Range,Check Date,Check NA MockComponent,"ab,cd","a,c,f",a,a,6,99.65,7,valid,https://www.google.com/,1738,1738,8085,8085,,6571,str1,75,10/21/2022,Not Applicable -MockComponent,"ab,cd","a,c,f",e,b,71,58.4,3,valid,https://www.google.com/,9965,9965,9965,9965,,6571,str2,80,October 21 2022,Not Applicable +MockComponent,"ab,cd","a,c,f",e,b,71,58.4,3,valid,https://www.google.com/,9965,9965,9965,9965,,6571,str2,80,October 21 2022,8 MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,8085,8085,1738,1738,present,32849,str3,95,10/21/2022,Not Applicable -MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,79,79,7,7,,32849,str4,55,21/10/2022,Not Applicable +MockComponent,"ab,cd","b,d,f",b,c,6.5,62.3,2,valid,https://www.google.com/,79,79,7,7,,32849,str4,55,21/10/2022,695 From 9ad5fd19d6228aff4333f3e98d7467e602799788 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:01:36 -0700 Subject: [PATCH 399/615] remove messaging for `IsNA` rule --- schematic/models/validate_attribute.py | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 49d451d2f..b88f2973b 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -482,20 +482,17 @@ def generate_content_error( content_error_str = ( f"{attribute_name} values in rows {row_num} are not parsable as dates." ) - elif val_rule.startswith('IsNA'): - content_error_str = ( - f"{attribute_name} values in rows {row_num} are not marked as 'Not Applicable'." - ) - logLevel(content_error_str) - error_row = row_num - error_message = content_error_str - #return error and empty list for warnings - if raises == 'error': - error_list = [error_row, error_col, error_message, error_val] - #return warning and empty list for errors - elif raises == 'warning': - warning_list = [error_row, error_col, error_message, error_val] + if val_rule != "IsNA": + logLevel(content_error_str) + error_row = row_num + error_message = content_error_str + #return error and empty list for warnings + if raises == 'error': + error_list = [error_row, error_col, error_message, error_val] + #return warning and empty list for errors + elif raises == 'warning': + warning_list = [error_row, error_col, error_message, error_val] return error_list, warning_list From 9b803204ddb74cc0dcff288b463f8b5453a98286 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:10:43 -0700 Subject: [PATCH 400/615] update tests for new rule --- tests/test_validation.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_validation.py b/tests/test_validation.py index fe73561ed..9e9ed941e 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -263,6 +263,14 @@ def test_in_house_validation(self,helpers,sg,metadataModel): invalid_entry = '94', sg = sg, )[0] in errors + + assert GenerateError.generate_type_error( + val_rule = 'int', + row_num = '3', + attribute_name = 'Check NA', + invalid_entry = '9.5', + sg = sg, + )[0] in errors assert GenerateError.generate_list_error( val_rule = 'list strict', From f16117c13269a81133d7174436e84f2cd21cd54d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:12:09 -0700 Subject: [PATCH 401/615] add bespoke logic for `::IsNA` combo --- schematic/models/validate_attribute.py | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index b88f2973b..e5af52311 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -24,6 +24,7 @@ parse_str_series_to_list, np_array_to_str_list, iterable_to_str_list, + rule_in_rule_list, ) @@ -225,19 +226,22 @@ def generate_type_error( f"On row {row_num} the attribute {attribute_name} " f"does not contain the proper value type {val_rule}." ) - logLevel(type_error_str) error_row = row_num # index row of the manifest where the error presented. error_col = attribute_name # Attribute name error_message = type_error_str error_val = invalid_entry - - #return error and empty list for warnings - if raises == 'error': - error_list = [error_row, error_col, error_message, error_val] - #return warning and empty list for errors - elif raises == 'warning': - warning_list = [error_row, error_col, error_message, error_val] + # If IsNA rule is being used to allow `Not Applicable` entries, do not log a message + if error_val.lower() == 'not applicable' and rule_in_rule_list('IsNA', sg.get_node_validation_rules(sg.get_node_label(attribute_name))): + pass + else: + logLevel(type_error_str) + #return error and empty list for warnings + if raises == 'error': + error_list = [error_row, error_col, error_message, error_val] + #return warning and empty list for errors + elif raises == 'warning': + warning_list = [error_row, error_col, error_message, error_val] return error_list, warning_list From 314cdbbb3aafe6752c15f97f9778f56df154053e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:15:14 -0700 Subject: [PATCH 402/615] update single rule model --- tests/data/example.single_rule.model.jsonld | 23 +++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/tests/data/example.single_rule.model.jsonld b/tests/data/example.single_rule.model.jsonld index 2c220f82a..484ef2317 100644 --- a/tests/data/example.single_rule.model.jsonld +++ b/tests/data/example.single_rule.model.jsonld @@ -2539,6 +2539,9 @@ }, { "@id": "bts:CheckDate" + }, + { + "@id": "bts:CheckNA" } ], "sms:validationRules": [] @@ -2900,6 +2903,26 @@ "date error" ] }, + { + "@id": "bts:CheckNA", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "CheckNA", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Check NA", + "sms:required": "sms:false", + "sms:validationRules": [ + "int error", + "IsNA" + ] + }, { "@id": "bts:MockRDB", "@type": "rdfs:Class", From b1f57481212910ec859a7465c53883afdb683ae1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:32:45 -0700 Subject: [PATCH 403/615] Update Rule_Combo_Manifest.csv --- tests/data/mock_manifests/Rule_Combo_Manifest.csv | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/data/mock_manifests/Rule_Combo_Manifest.csv b/tests/data/mock_manifests/Rule_Combo_Manifest.csv index 2698df519..d42115759 100644 --- a/tests/data/mock_manifests/Rule_Combo_Manifest.csv +++ b/tests/data/mock_manifests/Rule_Combo_Manifest.csv @@ -1,5 +1,5 @@ -Component,Check List,Check Regex List,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match Exactly,Check Recommended,Check Ages,Check Unique,Check Range -MockComponent,"valid,list,values","a,c,f",a,6,99.65,7,valid,https://www.google.com/,https://www.google.com/,https://github.com/Sage-Bionetworks/schematic,,6571,1,75 -MockComponent,"valid,list,values","a,c,f",e,71,58.4,3,valid,https://www.google.com/,https://www.google.com/,https://github.com/Sage-Bionetworks/schematic,,6571,2,80 -MockComponent,"valid,list,values","b,d,f",b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,https://github.com/Sage-Bionetworks/schematic,https://www.google.com/,present,32849,3,95 -MockComponent,"valid,list,values","b,d,f",b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,https://github.com/Sage-Bionetworks/schematic,https://www.google.com/,,32849,4,55 +Component,Check List,Check Regex List,Check Regex Single,Check Num,Check Float,Check Int,Check String,Check URL,Check Match at Least,Check Match Exactly,Check Recommended,Check Ages,Check Unique,Check Range,Check NA +MockComponent,"valid,list,values","a,c,f",a,6,99.65,7,valid,https://www.google.com/,https://www.google.com/,https://github.com/Sage-Bionetworks/schematic,,6571,1,75,9.5 +MockComponent,"valid,list,values","a,c,f",e,71,58.4,3,valid,https://www.google.com/,https://www.google.com/,https://github.com/Sage-Bionetworks/schematic,,6571,2,80,9 +MockComponent,"valid,list,values","b,d,f",b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,https://github.com/Sage-Bionetworks/schematic,https://www.google.com/,present,32849,3,95,Not Applicable +MockComponent,"valid,list,values","b,d,f",b,6.5,62.3,2,valid,https://github.com/Sage-Bionetworks/schematic,https://github.com/Sage-Bionetworks/schematic,https://www.google.com/,,32849,4,55,Not Applicable From db20b2926b3b637e63eb2a5bd7fd66f566a3d773 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 11:33:11 -0700 Subject: [PATCH 404/615] update rule combo tests for `IsNA` combos --- tests/test_validation.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index 9e9ed941e..e46306fd1 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -375,11 +375,15 @@ def test_rule_combinations(self, helpers, sg, base_rule, second_rule, metadataMo manifestPath = helpers.get_data_path("mock_manifests/Rule_Combo_Manifest.csv") manifest = helpers.get_data_frame(manifestPath) + # adjust rules and arguments as necessary for testing combinations for attribute in sg.se.schema['@graph']: #Doing it in a loop becasue of sg.se.edit_class design if 'sms:validationRules' in attribute and attribute['sms:validationRules']: + # remove default combination for attribute's reules + if attribute['sms:displayName'] == 'Check NA': + attribute['sms:validationRules'].remove('int') + + # Add rule args if necessary if base_rule in attribute['sms:validationRules'] or re.match(rule_regex, attribute['sms:validationRules'][0]): - - #Add rule args if necessary if second_rule.startswith('matchAtLeastOne') or second_rule.startswith('matchExactlyOne'): rule_args = f" MockComponent.{attribute['rdfs:label']} Patient.PatientID" elif second_rule.startswith('inRange'): @@ -390,8 +394,9 @@ def test_rule_combinations(self, helpers, sg, base_rule, second_rule, metadataMo rule_args = '' attribute['sms:validationRules'].append(second_rule + rule_args) - sg.se.edit_class(attribute) - break + + sg.se.edit_class(attribute) + break target_column=attribute['sms:displayName'] for col in manifest.columns: From eb915226ad3016bf51fa0934e339ab8f85e590dc Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 15:45:09 -0400 Subject: [PATCH 405/615] change docker file to add nginx --- docker-compose.yml | 4 +- main.py | 19 ++++++++++ schematic_api/Dockerfile | 81 +++++++++++++++++++--------------------- 3 files changed, 60 insertions(+), 44 deletions(-) create mode 100644 main.py diff --git a/docker-compose.yml b/docker-compose.yml index 49ee2b225..4ff12ad4b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -27,8 +27,8 @@ services: - .env networks: - schematic - ports: - - "${SERVER_PORT}:7080" + ports: + - "${SERVER_PORT}:80" networks: schematic: name: schematic \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 000000000..8081a7578 --- /dev/null +++ b/main.py @@ -0,0 +1,19 @@ +import os +import connexion +from schematic import CONFIG +from flask_cors import CORS +from schematic_api.api import app + + +def main(): + # Get app configuration + host = os.environ.get("APP_HOST", "0.0.0.0") + port = os.environ.get("APP_PORT", "3001") + port = int(port) + + # Launch app + # CORS(app, resources={r"*": {"origins": "*"}}) + app.run(host=host, port=port, debug=False) + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index cade1c9db..6d5616bcd 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -1,7 +1,4 @@ -## For aws deployments -FROM python:3.10.9-slim-bullseye - -SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] +FROM tiangolo/uwsgi-nginx-flask:python3.10 # set APP_PORT to 80 ENV PYTHONFAULTHANDLER=1 \ @@ -11,38 +8,38 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ POETRY_VERSION=1.2.0 \ - APP_PORT=80 \ - APP_DIR=/opt/app \ - SERVER_PROTOCOL=http:// \ - SERVER_DOMAIN=localhost \ - SERVER_PORT=7080 - -# RUN apt-get autoclean && apt-get -y autoremove - -RUN apt-get update -qq -y \ - && apt-get install --no-install-recommends -qq -y \ - build-essential \ - gosu \ - libpcre3 \ - libpcre3-dev \ - python3-dev \ - libopenblas-dev \ - gfortran \ - && apt-get -y autoclean \ - && apt-get -y autoremove \ - && rm -rf /var/lib/apt/lists/* - - -# remove libtiff5 for security reasons -# RUN apt remove -y libtiff5 -WORKDIR ${APP_DIR} -RUN chown www-data:www-data /opt/app/ + APP_DIR=/app \ + UWSGI_INI=/app/uwsgi.ini \ + NGINX_WORKER_PROCESSES=1 + +# Note: +# The starting number of uWSGI processes is controlled by the variable UWSGI_CHEAPER, by default set to 2. +# The maximum number of uWSGI processes is controlled by the variable UWSGI_PROCESSES, by default set to 16 +# NGINX_MAX_UPLOAD is set to 0 by default that allows unlimited upload file sizes + + # install poetry RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" +# set work directory +WORKDIR ${APP_DIR} +RUN chown www-data:www-data ${APP_DIR} + +# remove the old uwsgi.ini and main.py +RUN rm -rf ${APP_DIR}/main.py +RUN rm -rf ${APP_DIR}/uwsgi.ini + # copy relevant files and run poetry install -COPY ./pyproject.toml ./poetry.lock ./uwsgi.ini ./config.yml ./run_api.py ./ +COPY ./uwsgi.ini ./ + +# create a separate folder called app +RUN mkdir app +WORKDIR ${APP_DIR}/app + +# copy other files to app/app +# Note: run_api.py is not needed +COPY ./pyproject.toml ./poetry.lock ./config.yml ./main.py ./ RUN poetry config virtualenvs.create false RUN poetry install --no-interaction --no-ansi --no-root @@ -51,7 +48,15 @@ COPY schematic_api ./schematic_api # copy great_expectations folder COPY great_expectations ./great_expectations -RUN chown -R www-data:www-data /opt/app/great_expectations/ + +# copy tests folder because some endpoints by default download to the tests folder +COPY tests ./tests + +# change permission +RUN chown -R www-data:www-data ${APP_DIR}/app + +# allow downloading to synapse cache +RUN chown -R www-data:www-data /root # copy schematic COPY schematic ./schematic @@ -60,13 +65,5 @@ COPY schematic ./schematic WORKDIR /var/www/ RUN chown www-data:www-data /var/www/ -WORKDIR / -COPY schematic_api/docker-entrypoint.sh ./ -RUN chmod +x docker-entrypoint.sh - -EXPOSE 7080 - -ENTRYPOINT ["/docker-entrypoint.sh"] - -# Run server in production mode -CMD ["uwsgi", "--ini", "uwsgi.ini", "--lazy", "--http", ":7080"] \ No newline at end of file +# change work directory back +WORKDIR ${APP_DIR}/app \ No newline at end of file From fdffeb8122a6aedfc9bedce20f9b917878be9ca9 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 15:50:22 -0400 Subject: [PATCH 406/615] specify module in init --- uwsgi.ini | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/uwsgi.ini b/uwsgi.ini index b4641ccea..c0f6dd5de 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -2,14 +2,16 @@ # The variables http and *-socket are passed as command line arguments and # must not be specified in this file. ; wsgi-file = /opt/app/run_api.py -wsgi-file = /opt/app/schematic_api/api/__main__.py +wsgi-file = /app/app/schematic_api/api/__main__.py +module = app.main callable = app uid = www-data gid = www-data processes = 1 # Number of concurrent processes / workers threads = 1 # Number of threads per process master = true -chmod-sock = 660 +#socket = schematic.sock +#chmod-sock = 664 # clean up the socket when the process stops vacuum = true die-on-term = true thunder-lock = true From 31f9bce1d002867881aa5d0b2c1bfe29476338d0 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 16:00:00 -0400 Subject: [PATCH 407/615] remove docker-entrypoint.sh --- schematic_api/docker-entrypoint.sh | 9 --------- 1 file changed, 9 deletions(-) delete mode 100644 schematic_api/docker-entrypoint.sh diff --git a/schematic_api/docker-entrypoint.sh b/schematic_api/docker-entrypoint.sh deleted file mode 100644 index e031eda92..000000000 --- a/schematic_api/docker-entrypoint.sh +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env bash -set -e - -if [ "$1" = 'uwsgi' ] || [ "$1" = 'python' ]; then - cd ${APP_DIR} - exec gosu www-data "$@" -fi - -exec "$@" \ No newline at end of file From e3634763e642f385631a04bd6842fb1a9d76b048 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 16:08:22 -0400 Subject: [PATCH 408/615] delete old code --- uwsgi.ini | 2 -- 1 file changed, 2 deletions(-) diff --git a/uwsgi.ini b/uwsgi.ini index c0f6dd5de..9642873c0 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -10,8 +10,6 @@ gid = www-data processes = 1 # Number of concurrent processes / workers threads = 1 # Number of threads per process master = true -#socket = schematic.sock -#chmod-sock = 664 # clean up the socket when the process stops vacuum = true die-on-term = true thunder-lock = true From 85850012dab600329dad881feaf37c792da4eb01 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 16:33:47 -0400 Subject: [PATCH 409/615] clean up file path --- schematic_api/Dockerfile | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index 6d5616bcd..2f6501494 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -8,7 +8,8 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ POETRY_VERSION=1.2.0 \ - APP_DIR=/app \ + APP_PARENT_DIR=/app \ + APP_DIR=/app/app \ UWSGI_INI=/app/uwsgi.ini \ NGINX_WORKER_PROCESSES=1 @@ -23,19 +24,19 @@ ENV PYTHONFAULTHANDLER=1 \ RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" # set work directory -WORKDIR ${APP_DIR} -RUN chown www-data:www-data ${APP_DIR} +WORKDIR ${APP_PARENT_DIR} +RUN chown www-data:www-data ${APP_PARENT_DIR} # remove the old uwsgi.ini and main.py -RUN rm -rf ${APP_DIR}/main.py -RUN rm -rf ${APP_DIR}/uwsgi.ini +RUN rm -rf ${APP_PARENT_DIR}/main.py +RUN rm -rf ${APP_PARENT_DIR}/uwsgi.ini # copy relevant files and run poetry install COPY ./uwsgi.ini ./ # create a separate folder called app RUN mkdir app -WORKDIR ${APP_DIR}/app +WORKDIR ${APP_DIR} # copy other files to app/app # Note: run_api.py is not needed @@ -53,7 +54,7 @@ COPY great_expectations ./great_expectations COPY tests ./tests # change permission -RUN chown -R www-data:www-data ${APP_DIR}/app +RUN chown -R www-data:www-data ${APP_DIR} # allow downloading to synapse cache RUN chown -R www-data:www-data /root @@ -66,4 +67,4 @@ WORKDIR /var/www/ RUN chown www-data:www-data /var/www/ # change work directory back -WORKDIR ${APP_DIR}/app \ No newline at end of file +WORKDIR ${APP_DIR} \ No newline at end of file From ada1dd4a1165060aa207bd26bd663c403a844695 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 6 Apr 2023 16:36:30 -0400 Subject: [PATCH 410/615] clear old comment --- uwsgi.ini | 1 - 1 file changed, 1 deletion(-) diff --git a/uwsgi.ini b/uwsgi.ini index 9642873c0..50b5b14d6 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -1,7 +1,6 @@ [uwsgi] # The variables http and *-socket are passed as command line arguments and # must not be specified in this file. -; wsgi-file = /opt/app/run_api.py wsgi-file = /app/app/schematic_api/api/__main__.py module = app.main callable = app From 4b24a3f24163da109a1c35da14b65d0960ccd655 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 14:10:03 -0700 Subject: [PATCH 411/615] add `content_error_str` for `IsNA` rule message will not be logged. To be used in the refactor --- schematic/models/validate_attribute.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index e5af52311..50094aadc 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -486,6 +486,10 @@ def generate_content_error( content_error_str = ( f"{attribute_name} values in rows {row_num} are not parsable as dates." ) + elif val_rule.startswith('IsNA'): + content_error_str = ( + f"{attribute_name} values in rows {row_num} are not marked as 'Not Applicable'." + ) if val_rule != "IsNA": logLevel(content_error_str) From 0fa25ae40ff1f75dc312301334b227492a9e10ac Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 6 Apr 2023 14:13:45 -0700 Subject: [PATCH 412/615] Update test_validation.py --- tests/test_validation.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/tests/test_validation.py b/tests/test_validation.py index e46306fd1..1f9e68e69 100644 --- a/tests/test_validation.py +++ b/tests/test_validation.py @@ -381,6 +381,10 @@ def test_rule_combinations(self, helpers, sg, base_rule, second_rule, metadataMo # remove default combination for attribute's reules if attribute['sms:displayName'] == 'Check NA': attribute['sms:validationRules'].remove('int') + + # update class + sg.se.edit_class(attribute) + break # Add rule args if necessary if base_rule in attribute['sms:validationRules'] or re.match(rule_regex, attribute['sms:validationRules'][0]): @@ -394,9 +398,10 @@ def test_rule_combinations(self, helpers, sg, base_rule, second_rule, metadataMo rule_args = '' attribute['sms:validationRules'].append(second_rule + rule_args) - - sg.se.edit_class(attribute) - break + + # update class + sg.se.edit_class(attribute) + break target_column=attribute['sms:displayName'] for col in manifest.columns: From 56ef11ca52b39b9412342386538411ee8dbc7363 Mon Sep 17 00:00:00 2001 From: linglp Date: Sun, 9 Apr 2023 11:14:38 -0400 Subject: [PATCH 413/615] raise specific error message; and set as_json as True --- schematic_api/api/routes.py | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 25a299e2f..145480839 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -1,5 +1,6 @@ from email import generator import os +from json.decoder import JSONDecodeError import shutil import tempfile import shutil @@ -19,7 +20,7 @@ from schematic.schemas.generator import SchemaGenerator from schematic.schemas.explorer import SchemaExplorer from schematic.store.synapse import SynapseStorage, ManifestDownload -from synapseclient.core.exceptions import SynapseHTTPError, SynapseAuthenticationError, SynapseUnmetAccessRestrictions +from synapseclient.core.exceptions import SynapseHTTPError, SynapseAuthenticationError, SynapseUnmetAccessRestrictions, SynapseNoCredentialsError, SynapseTimeoutError from flask_cors import CORS, cross_origin from schematic.schemas.explorer import SchemaExplorer import pandas as pd @@ -243,10 +244,10 @@ def parse_bool(str_bool): def return_as_json(manifest_local_file_path): manifest_csv = pd.read_csv(manifest_local_file_path) try: - manifest_json = json.loads(manifest_csv.to_json(orient="records")) + manifest_json = manifest_csv.to_dict(orient="records") return manifest_json - except Exception: - raise Exception(f"Fail to return the manifest as a json") + except JSONDecodeError: + raise (f"Fail to return the manifest as a json") def save_file(file_key="csv_file"): ''' @@ -620,7 +621,7 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=None): +def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=True): """ Download a manifest based on a given manifest id. Args: @@ -637,23 +638,23 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=No # use Synapse Storage store = SynapseStorage(input_token=input_token) - # default as_json to True - if as_json is None: - as_json=True - # try logging in to asset store try: syn = store.login(input_token=input_token) - except Exception: - raise SynapseAuthenticationError + + except SynapseAuthenticationError: + raise("Your credentials are not valid. Please provide a valid synapse token") + except SynapseTimeoutError: + raise("Time out waiting for synapse to respond") + except SynapseHTTPError as e: + raise(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") try: md = ManifestDownload(syn, manifest_id) manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] - except Exception: - logger.error(f"Failed to download manifest: {manifest_id}") - raise Exception(f"Failed to download manifest: {manifest_id}") + except KeyError: + raise (f"Failed to download manifest: {manifest_id}") if as_json: manifest_json = return_as_json(manifest_local_file_path) return manifest_json @@ -674,7 +675,7 @@ def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_ #return local file path try: manifest_local_file_path = manifest_data['path'] - except: + except KeyError: raise(f'Failed to download manifest from dataset: {dataset_id}') #return a json (if as_json = True) From 0f8106e8cb9264db68527dffb8c01e410aa663db Mon Sep 17 00:00:00 2001 From: linglp Date: Sun, 9 Apr 2023 14:02:41 -0400 Subject: [PATCH 414/615] update parameterize; update test --- schematic/store/synapse.py | 7 +++++-- tests/test_api.py | 42 ++++++++++++++++++++------------------ 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index bf7f93680..efea25a42 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -136,8 +136,11 @@ def download_manifest(self, newManifestName="", manifest_df=None): if newManifestName and os.path.exists(manifest_data.get('path')): # Rename the file we just made to the new name new_manifest_filename = newManifestName + '.csv' - dir_name = os.path.dirname(os.path.abspath(new_manifest_filename)) - new_manifest_path_name = os.path.join(dir_name, new_manifest_filename) + + # get location of existing manifest. The manifest that will be renamed should live in the same folder as existing manifest. + parent_folder = os.path.dirname(manifest_data.get('path')) + + new_manifest_path_name = os.path.join(parent_folder, new_manifest_filename) os.rename(manifest_data['path'], new_manifest_path_name) # Update file names/paths in manifest_data diff --git a/tests/test_api.py b/tests/test_api.py index c801727db..ee1c6ecbf 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -576,10 +576,10 @@ def test_get_datatype_manifest(self, client, syn_token): "entityId": "string"} # small manifest: syn51078535; big manifest: syn51156998 - @pytest.mark.parametrize("manifest_id",["syn51156998", "syn51156998"]) - @pytest.mark.parametrize("new_manifest_name",["Example", None]) - @pytest.mark.parametrize("as_json",[True, False, None]) - def test_manifest_download(self, config, client, syn_token, manifest_id, new_manifest_name, as_json): + @pytest.mark.parametrize("manifest_id, expected_component, expected_file_name", [("syn51078535", "BulkRNA-seqAssay", "synapse_storage_manifest.csv"), ("syn51156998", "Biospecimen", "synapse_storage_manifest_biospecimen.csv")]) + @pytest.mark.parametrize("new_manifest_name",[None,"Example.csv"]) + @pytest.mark.parametrize("as_json",[None,True,False]) + def test_manifest_download(self, config, client, syn_token, manifest_id, new_manifest_name, as_json, expected_component, expected_file_name): params = { "input_token": syn_token, "manifest_id": manifest_id, @@ -591,38 +591,40 @@ def test_manifest_download(self, config, client, syn_token, manifest_id, new_man response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) assert response.status_code == 200 - # if as_json is set to True or as_json is not defined + # if as_json is set to True or as_json is not defined, then a json gets returned if as_json or as_json is None: response_dta = json.loads(response.data) - if manifest_id == "syn51078535": - assert response_dta[0]["Component"] == "BulkRNA-seqAssay" - assert response_dta[0]["File Format"] == "CSV/TSV" - else: - assert response_dta[0]["Component"] == "Biospecimen" + + # check if the correct manifest gets downloaded + assert response_dta[0]["Component"] == expected_component current_work_dir = os.getcwd() folder_test_manifests = config["synapse"]["manifest_folder"] folder_dir = os.path.join(current_work_dir, folder_test_manifests) + + # if a manfiest gets renamed, get new manifest file path if new_manifest_name: - file_name = os.path.join(folder_dir, new_manifest_name + '.' + 'csv') + manifest_file_path = os.path.join(folder_dir, new_manifest_name + '.' + 'csv') + # if a manifest does not get renamed, get existing manifest file path else: - file_name = os.path.join(folder_dir,config["synapse"]["manifest_basename"] + '.csv') + manifest_file_path = os.path.join(folder_dir,expected_file_name) else: - data = response.data.decode() - assert os.path.exists(data) - file_base_name = os.path.basename(data) + # manifest file path gets returned + manifest_file_path = response.data.decode() + + file_base_name = os.path.basename(manifest_file_path) file_name = os.path.splitext(file_base_name)[0] if new_manifest_name: assert file_name == new_manifest_name - file_name = data - - - # delete files + # make sure file gets correctly downloaded + assert os.path.exists(manifest_file_path) + + #delete files try: - os.remove(file_name) + os.remove(manifest_file_path) except: pass From a3dd341573bafb42f8a0c5daca04e8a797611cdc Mon Sep 17 00:00:00 2001 From: linglp Date: Sun, 9 Apr 2023 14:03:01 -0400 Subject: [PATCH 415/615] add to do --- schematic_api/api/openapi/api.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index d6e3358d4..a1e78da70 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -9,6 +9,7 @@ info: servers: - url: /v1 +# TO DO: refactor query parameters and remove input_token paths: /manifest/generate: get: From 0bd017fd5b5f5bbc704e8bb64fee5a8275d44a71 Mon Sep 17 00:00:00 2001 From: Lingling <55448354+linglp@users.noreply.github.com> Date: Mon, 10 Apr 2023 04:17:10 +0000 Subject: [PATCH 416/615] update exception --- schematic/store/synapse.py | 1 - schematic_api/api/routes.py | 19 +++++++++---------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index efea25a42..0feecbc67 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -129,7 +129,6 @@ def download_manifest(self, newManifestName="", manifest_df=None): manifest_data = self._download_manifest_to_folder() except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: logger.error(f"You don't have access to the requested resource: {old_requested_manifest_id} and {new_manifest_id}") - else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 145480839..125a5c870 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -246,8 +246,8 @@ def return_as_json(manifest_local_file_path): try: manifest_json = manifest_csv.to_dict(orient="records") return manifest_json - except JSONDecodeError: - raise (f"Fail to return the manifest as a json") + except JSONDecodeError as e: + raise (f"Fail to return the manifest as a json") from e def save_file(file_key="csv_file"): ''' @@ -641,20 +641,19 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr # try logging in to asset store try: syn = store.login(input_token=input_token) - - except SynapseAuthenticationError: - raise("Your credentials are not valid. Please provide a valid synapse token") - except SynapseTimeoutError: - raise("Time out waiting for synapse to respond") + except SynapseAuthenticationError as e: + raise("Your credentials are not valid. Please provide a valid synapse token") from e + except SynapseTimeoutError as e: + raise("Time out waiting for synapse to respond") from e except SynapseHTTPError as e: - raise(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") + raise(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") from e try: md = ManifestDownload(syn, manifest_id) manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] - except KeyError: - raise (f"Failed to download manifest: {manifest_id}") + except KeyError as e: + raise (f"Failed to download manifest: {manifest_id}") from e if as_json: manifest_json = return_as_json(manifest_local_file_path) return manifest_json From 184474100f76514a42da638829f9a0c0161c11ff Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 10 Apr 2023 09:50:44 -0700 Subject: [PATCH 417/615] parameterize expected output --- tests/test_api.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index 09d9bb3fe..18447e196 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -714,8 +714,8 @@ def test_visualize_tangled_tree_layers(self, client, figure_type, data_model_jso assert response.status_code == 200 - @pytest.mark.parametrize("component", ["Patient", "BulkRNA-seqAssay"]) - def test_visualize_component(self, client, data_model_jsonld,component): + @pytest.mark.parametrize("component, response_text", [("Patient", "Component,Component,TBD,False,,,,Patient"), ("BulkRNA-seqAssay", "Component,Component,TBD,False,,,,BulkRNA-seqAssay")]) + def test_visualize_component(self, client, data_model_jsonld,component, response_text): params = { "schema_url": data_model_jsonld, "component": component, @@ -727,10 +727,7 @@ def test_visualize_component(self, client, data_model_jsonld,component): assert response.status_code == 200 assert "Attribute,Label,Description,Required,Cond_Req,Valid Values,Conditional Requirements,Component" in response.text - if component == "Patient": - assert "Patient ID,PatientID,TBD,True,,,,Patient" in response.text - elif component == "BulkRNA-seqAssay": - assert "Component,Component,Component,TBD,False,,,,BulkRNA-seqAssay" in response.text + assert response_text in response.text @pytest.mark.schematic_api class TestValidationBenchmark(): From b51e610b33ca10906c8d2c8b845b64b3ee09d705 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:42:05 -0700 Subject: [PATCH 418/615] remove check for too many rules or invalid combo --- schematic/utils/validate_rules_utils.py | 43 ++----------------------- 1 file changed, 2 insertions(+), 41 deletions(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 70a3437c8..d36546624 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -115,13 +115,6 @@ def get_error(validation_rules: list, multiple validation rules. ''' error_col = attribute_name # Attribute name - if error_type == 'too_many_rules': - error_str = (f"The {input_filetype}, has an error in the validation rule " - f"for the attribute: {attribute_name}, the provided validation rules ({validation_rules}) ." - f"have too many entries. We currently only allow for pairs of rules to be used at the same time.") - logging.error(error_str) - error_message = error_str - error_val = f"Multiple Rules: too many rules" if error_type == 'delimiter': error_str = (f"The {input_filetype}, has an error in the validation rule " @@ -160,17 +153,6 @@ def get_error(validation_rules: list, logging.error(error_str) error_message = error_str error_val = f"Incorrect num arguments." - - if error_type == 'invalid_rule_combination': - first_type=validation_rules[0].split(' ')[0] - second_type=validation_rule_info()[first_type]['complementary_rules'] - - error_str = (f"The {input_filetype}, has an error in the validation rule " - f"for the attribute: {attribute_name}, the provided validation rules ({'::'.join(validation_rules)}) are not " - f"a valid combination of rules. The validation rule [{first_type}] may only be used with rules of type {second_type}.") - logging.error(error_str) - error_message = error_str - error_val = f"Invalid rule combination." return ['NA', error_col, error_message, error_val] @@ -226,37 +208,16 @@ def validate_schema_rules(validation_rules, attribute, input_filetype): locating the source of the error. Validation Rules Formatting rules: - Multiple Rules: - max of 2 rules Single Rules: - Additional arg + Specified with the correct required arguments with no more than what is allowed ''' # Specify all the validation types and whether they currently # allow users to pass additional arguments (when used on their own), and if there is # a set number of arguments required. errors = [] - rule_info = validation_rule_info() - num_validation_rules = len(validation_rules) - - - # Check for edge case that user has entered more than 2 rules, - # throw an error if they have. - if num_validation_rules > 2: - errors.append(get_error(validation_rules, attribute, - error_type = 'too_many_rules', input_filetype=input_filetype)) - - elif num_validation_rules == 2: - first_rule, second_rule = validation_rules - first_type = first_rule.split(" ")[0] - second_type = second_rule.split(" ")[0] - - # validate rule combination - if second_type not in rule_info[first_type]['complementary_rules']: - errors.append(get_error(validation_rules, attribute, - error_type = 'invalid_rule_combination', input_filetype=input_filetype)) - # validate each rule individually in the combo + # validate each individual rule for rule in validation_rules: errors.extend(validate_single_rule(rule, attribute, input_filetype)) From df19778c02c69800b86b2bf9a967f1aa1e645a1f Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 10 Apr 2023 14:46:29 -0700 Subject: [PATCH 419/615] reorder errors --- schematic/utils/validate_rules_utils.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index d36546624..759016b20 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -168,8 +168,11 @@ def validate_single_rule(validation_rule, attribute, input_filetype): rule_type = validation_rule_with_args[0] + if ':' in validation_rule: + errors.append(get_error(validation_rule, attribute, + error_type = 'delimiter', input_filetype=input_filetype)) # Check that the rule is actually a valid rule type. - if rule_type not in validation_types.keys(): + elif rule_type not in validation_types.keys(): errors.append(get_error(validation_rule, attribute, error_type = 'not_rule', input_filetype=input_filetype)) @@ -195,10 +198,6 @@ def validate_single_rule(validation_rule, attribute, input_filetype): errors.append(get_error(validation_rule, attribute, error_type = 'incorrect_num_args', input_filetype=input_filetype)) - - if ':' in validation_rule: - errors.append(get_error(validation_rule, attribute, - error_type = 'delimiter', input_filetype=input_filetype)) return errors def validate_schema_rules(validation_rules, attribute, input_filetype): From a8e2e0b9bacc0e3d801b8302288b9a227b2ec429 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 10 Apr 2023 15:04:02 -0700 Subject: [PATCH 420/615] clean --- schematic/utils/validate_rules_utils.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 759016b20..46230e902 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -210,17 +210,12 @@ def validate_schema_rules(validation_rules, attribute, input_filetype): Single Rules: Specified with the correct required arguments with no more than what is allowed ''' - # Specify all the validation types and whether they currently - # allow users to pass additional arguments (when used on their own), and if there is - # a set number of arguments required. - errors = [] # validate each individual rule for rule in validation_rules: errors.extend(validate_single_rule(rule, - attribute, input_filetype)) - + attribute, input_filetype)) if errors: raise ValidationError( From cfbc57c1585d70e9023cf837b25792c4f7e215a5 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 11 Apr 2023 10:39:14 -0400 Subject: [PATCH 421/615] change raising exception syntax; --- schematic_api/api/routes.py | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 125a5c870..fd626b40f 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -246,8 +246,12 @@ def return_as_json(manifest_local_file_path): try: manifest_json = manifest_csv.to_dict(orient="records") return manifest_json - except JSONDecodeError as e: - raise (f"Fail to return the manifest as a json") from e + except JSONDecodeError as e: + logger.error("Json data is not formatted correctly", e) + raise(e) + except ValueError as e: + logger.error('Failed to return the downloaded manifest as a json', e) + raise(e) def save_file(file_key="csv_file"): ''' @@ -637,16 +641,18 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr # use Synapse Storage store = SynapseStorage(input_token=input_token) - # try logging in to asset store try: syn = store.login(input_token=input_token) except SynapseAuthenticationError as e: - raise("Your credentials are not valid. Please provide a valid synapse token") from e + logger.error(f'Your credentials are not valid. Please provide a valid synapse token') + raise e except SynapseTimeoutError as e: - raise("Time out waiting for synapse to respond") from e + logger.error("Time out waiting for synapse to respond") + raise e except SynapseHTTPError as e: - raise(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") from e + logger.error(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") + raise(e) try: md = ManifestDownload(syn, manifest_id) manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) From d75a46f3796981097ddc587b0f69dd6add93d3de Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 11 Apr 2023 10:57:10 -0400 Subject: [PATCH 422/615] add TO DO --- tests/test_api.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_api.py b/tests/test_api.py index ee1c6ecbf..90e52cb6f 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,6 +18,8 @@ To run the tests, you have to keep API running locally first by doing `python3 run_api.py` ''' +## TO DO: Clean up url and use a global variable SERVER_URL + @pytest.fixture(scope="class") def app(): app = create_app() From 76ffaba4ad25ea405eef3128beb434f41b712874 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 11 Apr 2023 09:12:49 -0700 Subject: [PATCH 423/615] update docstring, comments --- schematic/utils/validate_rules_utils.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/schematic/utils/validate_rules_utils.py b/schematic/utils/validate_rules_utils.py index 46230e902..249f16822 100644 --- a/schematic/utils/validate_rules_utils.py +++ b/schematic/utils/validate_rules_utils.py @@ -158,8 +158,14 @@ def get_error(validation_rules: list, def validate_single_rule(validation_rule, attribute, input_filetype): ''' - TODO:reformat validation_types from validate_manifest to document the - arguments allowed. Keep in that location and pull into this function. + Perform validation for a single rule to ensure it is specified correctly with an appropriate number of arguments + Inputs: + validation_rule: single rule being validated + attribute: attribute validation rule was specified for + input_filetype: filetype of model input + + Returns: + errors: List of errors ''' errors = [] validation_types = validation_rule_info() @@ -168,6 +174,7 @@ def validate_single_rule(validation_rule, attribute, input_filetype): rule_type = validation_rule_with_args[0] + # ensure rules are not delimited incorrectly if ':' in validation_rule: errors.append(get_error(validation_rule, attribute, error_type = 'delimiter', input_filetype=input_filetype)) @@ -175,7 +182,7 @@ def validate_single_rule(validation_rule, attribute, input_filetype): elif rule_type not in validation_types.keys(): errors.append(get_error(validation_rule, attribute, error_type = 'not_rule', input_filetype=input_filetype)) - + # if the rule is indeed a rule and formatted correctly, check that arguments are appropriate else: arguments_allowed, arguments_required = validation_types[rule_type]['arguments'] # Remove any fixed args from our calc. From dd458c21fd340ebd163e6cec064e624b10b5300a Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:35:28 -0700 Subject: [PATCH 424/615] added mypy, updated black --- poetry.lock | 4 ++-- pyproject.toml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 251bb6b9b..7a1615457 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2636,7 +2636,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "14b64119a9b97799266275d25ce0c7a9be94d918fbfeb388fabc73cfb3cf1014" +content-hash = "2e8922a96ef8a1b786b1783705fcec76e70f6d39965388ccc6076046a022de0f" [metadata.files] alabaster = [ @@ -3011,7 +3011,6 @@ debugpy = [ {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, - {file = "debugpy-1.6.6-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:11a0f3a106f69901e4a9a5683ce943a7a5605696024134b522aa1bfda25b5fec"}, {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, @@ -4015,6 +4014,7 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, diff --git a/pyproject.toml b/pyproject.toml index 308af09c9..2882f5713 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -79,7 +79,8 @@ pytest-cov = "^4.0.0" pytest-mock = "^3.5.1" flake8 = "^6.0.0" python-dotenv = "^0.21.0" -black = {version = "^22.6.0", allow-prereleases = true} +black = "^22.6.0" +mypy = "^0.982" [tool.black] From 464dccd045878819b48e518d2293f576204c827a Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:35:47 -0700 Subject: [PATCH 425/615] formatted for black and mypy --- .github/workflows/test.yml | 64 ++++++++++++++++++++++---------------- schematic/exceptions.py | 22 +++++++------ 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3437bf14b..b5ef076b0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: steps: #---------------------------------------------- - # check-out repo and set-up python + # check-out repo and set-up python #---------------------------------------------- - name: Check out repository uses: actions/checkout@v2 @@ -45,19 +45,19 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - + #---------------------------------------------- - # install & configure poetry + # install & configure poetry #---------------------------------------------- - name: Install Poetry run: | curl -sSL https://install.python-poetry.org \ | python3 - --version ${{ env.POETRY_VERSION }}; - poetry config virtualenvs.create true; - poetry config virtualenvs.in-project true; + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; #---------------------------------------------- - # load cached venv if cache exists + # load cached venv if cache exists #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies @@ -67,21 +67,21 @@ jobs: key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- - # install dependencies if cache does not exist + # install dependencies if cache does not exist #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root - + + #---------------------------------------------- + # install your root project, if required #---------------------------------------------- - # install your root project, if required - #---------------------------------------------- - name: Install library run: poetry install --no-interaction - + #---------------------------------------------- # perform linting - #---------------------------------------------- + #---------------------------------------------- # Disabled until we agree to turn it on # - name: Lint with flake8 # run: | @@ -90,18 +90,30 @@ jobs: # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - #---------------------------------------------- - # check formatting - #---------------------------------------------- - # Disabled until we agree to turn it on - # - name: Code formatting with black - # run: | - # # run black in check mode - # # if files are not formatted correctly, the build will not go through - # black . --check - #---------------------------------------------- - # run test suite - #---------------------------------------------- + ---------------------------------------------- + check formatting + ---------------------------------------------- + - name: Code formatting with black + run: | + # run black in check mode + # if files are not formatted correctly, the build will not go through + # ran only on certain files for now + black schematic/exceptions.py --check + + ---------------------------------------------- + type checking/enforcement + ---------------------------------------------- + - name: Type checking with mypy + run: | + # run mypy + # ran only on certain files for now + # if files are not formatted correctly, the build will not go through + # mypy . + mypy --disallow-untyped-defs schematic/exceptions.py + + ---------------------------------------------- + run test suite + ---------------------------------------------- - name: Run regular tests and rule combination tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -110,7 +122,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or schematic_api or table_operations)" - + - name: Run tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -120,7 +132,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or rule_combos or schematic_api or table_operations)" - + - name: Upload pytest test results uses: actions/upload-artifact@v2 with: diff --git a/schematic/exceptions.py b/schematic/exceptions.py index 4aff3fef9..321cb4282 100644 --- a/schematic/exceptions.py +++ b/schematic/exceptions.py @@ -1,3 +1,4 @@ +"""Schematic Exceptions""" from typing import Any, Sequence @@ -12,7 +13,7 @@ class MissingConfigValueError(Exception): message. """ - def __init__(self, config_keys: Sequence[Any], message: str = None) -> str: + def __init__(self, config_keys: Sequence[Any], message: str = None) -> None: config_keys_str = " > ".join(config_keys) self.message = ( "The configuration value corresponding to the argument " @@ -25,9 +26,10 @@ def __init__(self, config_keys: Sequence[Any], message: str = None) -> str: super().__init__(self.message) - def __str__(self): + def __str__(self) -> str: return f"{self.message}" + class WrongEntityTypeError(Exception): """Exception raised when the entity type is not desired @@ -37,8 +39,9 @@ class WrongEntityTypeError(Exception): Returns: message. - """ - def __init__(self, syn_id: str, message: str = None) -> str: + """ + + def __init__(self, syn_id: str, message: str = None) -> None: self.message = ( f"'{syn_id}'' is not a desired entity type" "Please ensure that you put in the right syn_id" @@ -49,9 +52,10 @@ def __init__(self, syn_id: str, message: str = None) -> str: super().__init__(self.message) - def __str__(self): + def __str__(self) -> str: return f"{self.message}" + class MissingConfigAndArgumentValueError(Exception): """Exception raised when configuration value not provided in config file. @@ -66,7 +70,7 @@ class MissingConfigAndArgumentValueError(Exception): def __init__( self, arg_name: str, config_keys: Sequence[Any], message: str = None - ) -> str: + ) -> None: config_keys_str = " > ".join(config_keys) self.message = ( f"The value corresponding to the CLI argument '--{arg_name}'" @@ -80,7 +84,7 @@ def __init__( super().__init__(self.message) - def __str__(self): + def __str__(self) -> str: return f"{self.message}" @@ -95,7 +99,7 @@ class AccessCredentialsError(Exception): message. """ - def __init__(self, project: str, message: str = None) -> str: + def __init__(self, project: str, message: str = None) -> None: self.message = ( f"Your access to '{project}'' could not be resolved. " "Please check your credentials and try again." @@ -106,5 +110,5 @@ def __init__(self, project: str, message: str = None) -> str: super().__init__(self.message) - def __str__(self): + def __str__(self) -> str: return f"{self.message}" From 53a544c6808bfe88c323ba24bc5f5a69e730d7d4 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:42:36 -0700 Subject: [PATCH 426/615] revert test --- .github/workflows/test.yml | 64 ++++++++++++++++---------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b5ef076b0..3437bf14b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -36,7 +36,7 @@ jobs: steps: #---------------------------------------------- - # check-out repo and set-up python + # check-out repo and set-up python #---------------------------------------------- - name: Check out repository uses: actions/checkout@v2 @@ -45,19 +45,19 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - + #---------------------------------------------- - # install & configure poetry + # install & configure poetry #---------------------------------------------- - name: Install Poetry run: | curl -sSL https://install.python-poetry.org \ | python3 - --version ${{ env.POETRY_VERSION }}; - poetry config virtualenvs.create true; - poetry config virtualenvs.in-project true; + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; #---------------------------------------------- - # load cached venv if cache exists + # load cached venv if cache exists #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies @@ -67,21 +67,21 @@ jobs: key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- - # install dependencies if cache does not exist + # install dependencies if cache does not exist #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root - - #---------------------------------------------- - # install your root project, if required + #---------------------------------------------- + # install your root project, if required + #---------------------------------------------- - name: Install library run: poetry install --no-interaction - + #---------------------------------------------- # perform linting - #---------------------------------------------- + #---------------------------------------------- # Disabled until we agree to turn it on # - name: Lint with flake8 # run: | @@ -90,30 +90,18 @@ jobs: # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - ---------------------------------------------- - check formatting - ---------------------------------------------- - - name: Code formatting with black - run: | - # run black in check mode - # if files are not formatted correctly, the build will not go through - # ran only on certain files for now - black schematic/exceptions.py --check - - ---------------------------------------------- - type checking/enforcement - ---------------------------------------------- - - name: Type checking with mypy - run: | - # run mypy - # ran only on certain files for now - # if files are not formatted correctly, the build will not go through - # mypy . - mypy --disallow-untyped-defs schematic/exceptions.py - - ---------------------------------------------- - run test suite - ---------------------------------------------- + #---------------------------------------------- + # check formatting + #---------------------------------------------- + # Disabled until we agree to turn it on + # - name: Code formatting with black + # run: | + # # run black in check mode + # # if files are not formatted correctly, the build will not go through + # black . --check + #---------------------------------------------- + # run test suite + #---------------------------------------------- - name: Run regular tests and rule combination tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -122,7 +110,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or schematic_api or table_operations)" - + - name: Run tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -132,7 +120,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or rule_combos or schematic_api or table_operations)" - + - name: Upload pytest test results uses: actions/upload-artifact@v2 with: From 55903fff7a5e679bd9bfcb0b7d935a59ea71af22 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:43:49 -0700 Subject: [PATCH 427/615] removed whitespace --- .github/workflows/test.yml | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3437bf14b..4f1eb1e3a 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ name: Test schematic on: push: branches: ['main'] - pull_request: + pull_request: branches: ['*'] workflow_dispatch: # Allow manually triggering the workflow concurrency: @@ -16,8 +16,8 @@ concurrency: # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag - # {{ github.event.pull_request.number}}: get PR number - # {{ github.sha }}: full commit sha + # {{ github.event.pull_request.number}}: get PR number + # {{ github.sha }}: full commit sha # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml group: >- ${{ github.workflow }}-${{ github.ref_type }}- @@ -36,7 +36,7 @@ jobs: steps: #---------------------------------------------- - # check-out repo and set-up python + # check-out repo and set-up python #---------------------------------------------- - name: Check out repository uses: actions/checkout@v2 @@ -45,19 +45,19 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - + #---------------------------------------------- - # install & configure poetry + # install & configure poetry #---------------------------------------------- - name: Install Poetry run: | curl -sSL https://install.python-poetry.org \ | python3 - --version ${{ env.POETRY_VERSION }}; - poetry config virtualenvs.create true; - poetry config virtualenvs.in-project true; + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; #---------------------------------------------- - # load cached venv if cache exists + # load cached venv if cache exists #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies @@ -67,21 +67,21 @@ jobs: key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- - # install dependencies if cache does not exist + # install dependencies if cache does not exist #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root - + + #---------------------------------------------- + # install your root project, if required #---------------------------------------------- - # install your root project, if required - #---------------------------------------------- - name: Install library run: poetry install --no-interaction - + #---------------------------------------------- # perform linting - #---------------------------------------------- + #---------------------------------------------- # Disabled until we agree to turn it on # - name: Lint with flake8 # run: | @@ -100,7 +100,7 @@ jobs: # # if files are not formatted correctly, the build will not go through # black . --check #---------------------------------------------- - # run test suite + # run test suite #---------------------------------------------- - name: Run regular tests and rule combination tests env: @@ -110,7 +110,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or schematic_api or table_operations)" - + - name: Run tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -120,7 +120,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or rule_combos or schematic_api or table_operations)" - + - name: Upload pytest test results uses: actions/upload-artifact@v2 with: From 9107ed4a042791372dd6f0543f66ab84050bdd66 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:46:04 -0700 Subject: [PATCH 428/615] added back in mypy and black --- .github/workflows/test.yml | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4f1eb1e3a..aa6345274 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -93,12 +93,25 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- - # Disabled until we agree to turn it on - # - name: Code formatting with black - # run: | - # # run black in check mode - # # if files are not formatted correctly, the build will not go through - # black . --check + - name: Code formatting with black + run: | + # run black in check mode + # if files are not formatted correctly, the build will not go through + # ran only on certain files for now + black schematic/exceptions.py --check + + #---------------------------------------------- + # type checking/enforcement + #---------------------------------------------- + - name: Type checking with mypy + run: | + # run mypy + # ran only on certain files for now + # if files are not formatted correctly, the build will not go through + # mypy . + mypy --disallow-untyped-defs schematic/exceptions.py + + #---------------------------------------------- # run test suite #---------------------------------------------- From 17e7c1733a926729a0c40526ec462e4520d3a667 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:49:43 -0700 Subject: [PATCH 429/615] redid black section --- .github/workflows/test.yml | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aa6345274..2eda99367 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -90,27 +90,14 @@ jobs: # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + #---------------------------------------------- # check formatting #---------------------------------------------- + # Disabled until we agree to turn it on - name: Code formatting with black run: | - # run black in check mode - # if files are not formatted correctly, the build will not go through - # ran only on certain files for now - black schematic/exceptions.py --check - - #---------------------------------------------- - # type checking/enforcement - #---------------------------------------------- - - name: Type checking with mypy - run: | - # run mypy - # ran only on certain files for now - # if files are not formatted correctly, the build will not go through - # mypy . - mypy --disallow-untyped-defs schematic/exceptions.py - + black . --check #---------------------------------------------- # run test suite From 47953b338d37b3334cf146d18710b26cb2920c4a Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:53:32 -0700 Subject: [PATCH 430/615] redo black testing --- .github/workflows/test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2eda99367..beadaf449 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,10 +94,8 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- - # Disabled until we agree to turn it on - name: Code formatting with black - run: | - black . --check + run: poetry run black . #---------------------------------------------- # run test suite From 2588446f371604bb8224988e2e70542fb67585af Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:56:00 -0700 Subject: [PATCH 431/615] commented out black --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index beadaf449..0d30c3002 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,8 +94,8 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- - - name: Code formatting with black - run: poetry run black . + #- name: Code formatting with black + # run: poetry run black . #---------------------------------------------- # run test suite From c5b5e3ff32382856bcf3b005fc9a2a5b7c1a7c0a Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:57:17 -0700 Subject: [PATCH 432/615] revert worklfow --- .github/workflows/test.yml | 47 +++++++++++++++++++------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0d30c3002..ee91b4bdb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,7 +8,7 @@ name: Test schematic on: push: branches: ['main'] - pull_request: + pull_request: branches: ['*'] workflow_dispatch: # Allow manually triggering the workflow concurrency: @@ -16,8 +16,8 @@ concurrency: # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag - # {{ github.event.pull_request.number}}: get PR number - # {{ github.sha }}: full commit sha + # {{ github.event.pull_request.number}}: get PR number + # {{ github.sha }}: full commit sha # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml group: >- ${{ github.workflow }}-${{ github.ref_type }}- @@ -36,7 +36,7 @@ jobs: steps: #---------------------------------------------- - # check-out repo and set-up python + # check-out repo and set-up python #---------------------------------------------- - name: Check out repository uses: actions/checkout@v2 @@ -45,19 +45,18 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - + #---------------------------------------------- - # install & configure poetry + # install & configure poetry #---------------------------------------------- - name: Install Poetry run: | curl -sSL https://install.python-poetry.org \ | python3 - --version ${{ env.POETRY_VERSION }}; - poetry config virtualenvs.create true; - poetry config virtualenvs.in-project true; - + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; #---------------------------------------------- - # load cached venv if cache exists + # load cached venv if cache exists #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies @@ -67,21 +66,21 @@ jobs: key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- - # install dependencies if cache does not exist + # install dependencies if cache does not exist #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root - - #---------------------------------------------- - # install your root project, if required + #---------------------------------------------- + # install your root project, if required + #---------------------------------------------- - name: Install library run: poetry install --no-interaction - + #---------------------------------------------- # perform linting - #---------------------------------------------- + #---------------------------------------------- # Disabled until we agree to turn it on # - name: Lint with flake8 # run: | @@ -90,15 +89,17 @@ jobs: # # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide # flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics - #---------------------------------------------- # check formatting #---------------------------------------------- - #- name: Code formatting with black - # run: poetry run black . - + # Disabled until we agree to turn it on + # - name: Code formatting with black + # run: | + # # run black in check mode + # # if files are not formatted correctly, the build will not go through + # black . --check #---------------------------------------------- - # run test suite + # run test suite #---------------------------------------------- - name: Run regular tests and rule combination tests env: @@ -108,7 +109,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or schematic_api or table_operations)" - + - name: Run tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -118,7 +119,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or rule_combos or schematic_api or table_operations)" - + - name: Upload pytest test results uses: actions/upload-artifact@v2 with: From 5d88320f172b30b8d3d6a1a7fc01b4bcadc19ac1 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:58:07 -0700 Subject: [PATCH 433/615] remove comments --- .github/workflows/test.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee91b4bdb..324105e77 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -92,12 +92,10 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- - # Disabled until we agree to turn it on # - name: Code formatting with black # run: | - # # run black in check mode - # # if files are not formatted correctly, the build will not go through # black . --check + #---------------------------------------------- # run test suite #---------------------------------------------- From a1a7d0b039b0da7fc36b10c66bec753d6d48e7d2 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 12:59:11 -0700 Subject: [PATCH 434/615] revert worklfow --- .github/workflows/test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 324105e77..ee91b4bdb 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -92,10 +92,12 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- + # Disabled until we agree to turn it on # - name: Code formatting with black # run: | + # # run black in check mode + # # if files are not formatted correctly, the build will not go through # black . --check - #---------------------------------------------- # run test suite #---------------------------------------------- From f9d37751cd4d37ccf25c8f4c35108761e6340d60 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:01:33 -0700 Subject: [PATCH 435/615] add black --- .github/workflows/test.yml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ee91b4bdb..2eaeeaefd 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -92,12 +92,10 @@ jobs: #---------------------------------------------- # check formatting #---------------------------------------------- - # Disabled until we agree to turn it on - # - name: Code formatting with black - # run: | - # # run black in check mode - # # if files are not formatted correctly, the build will not go through - # black . --check + - name: Code formatting with black + run: | + black . --check + #---------------------------------------------- # run test suite #---------------------------------------------- From ba66c531319c8659c2bfdc8484a6c176eb0e73ce Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:01:49 -0700 Subject: [PATCH 436/615] add black --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2eaeeaefd..2d158f1fc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,7 +94,7 @@ jobs: #---------------------------------------------- - name: Code formatting with black run: | - black . --check + black schematic/exceptions.py --check #---------------------------------------------- # run test suite From bb9400c55ba09846d4b8ad60031fd2391f0c636c Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:08:58 -0700 Subject: [PATCH 437/615] use poetry with black --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2d158f1fc..d479c1550 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -94,7 +94,7 @@ jobs: #---------------------------------------------- - name: Code formatting with black run: | - black schematic/exceptions.py --check + poetry run black schematic/exceptions.py --check #---------------------------------------------- # run test suite From 971269e0f18148ba63e6d4d0bba86f01aa4a65a1 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:15:27 -0700 Subject: [PATCH 438/615] isntall all extras --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index d479c1550..704ce2523 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -70,7 +70,7 @@ jobs: #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' - run: poetry install --no-interaction --no-root + run: poetry install --no-interaction --no-root --all-extras #---------------------------------------------- # install your root project, if required From d2688bebd9222bb0854a85e34eca9b3f4b70377b Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:25:57 -0700 Subject: [PATCH 439/615] add mypy checking --- .github/workflows/test.yml | 55 +++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 704ce2523..1ca0f68f3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -8,16 +8,16 @@ name: Test schematic on: push: branches: ['main'] - pull_request: + pull_request: branches: ['*'] workflow_dispatch: # Allow manually triggering the workflow concurrency: - # cancel the current running workflow from the same branch, PR when a new workflow is triggered + # cancel the current running workflow from the same branch, PR when a new workflow is triggered # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows - # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag - # {{ github.event.pull_request.number}}: get PR number - # {{ github.sha }}: full commit sha + # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag + # {{ github.event.pull_request.number}}: get PR number + # {{ github.sha }}: full commit sha # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml group: >- ${{ github.workflow }}-${{ github.ref_type }}- @@ -36,7 +36,7 @@ jobs: steps: #---------------------------------------------- - # check-out repo and set-up python + # check-out repo and set-up python #---------------------------------------------- - name: Check out repository uses: actions/checkout@v2 @@ -45,18 +45,18 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - + #---------------------------------------------- - # install & configure poetry + # install & configure poetry #---------------------------------------------- - name: Install Poetry run: | curl -sSL https://install.python-poetry.org \ | python3 - --version ${{ env.POETRY_VERSION }}; - poetry config virtualenvs.create true; - poetry config virtualenvs.in-project true; + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; #---------------------------------------------- - # load cached venv if cache exists + # load cached venv if cache exists #---------------------------------------------- - name: Load cached venv id: cached-poetry-dependencies @@ -66,21 +66,21 @@ jobs: key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} #---------------------------------------------- - # install dependencies if cache does not exist + # install dependencies if cache does not exist #---------------------------------------------- - name: Install dependencies if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' run: poetry install --no-interaction --no-root --all-extras - + + #---------------------------------------------- + # install your root project, if required #---------------------------------------------- - # install your root project, if required - #---------------------------------------------- - name: Install library run: poetry install --no-interaction - + #---------------------------------------------- # perform linting - #---------------------------------------------- + #---------------------------------------------- # Disabled until we agree to turn it on # - name: Lint with flake8 # run: | @@ -94,10 +94,23 @@ jobs: #---------------------------------------------- - name: Code formatting with black run: | - poetry run black schematic/exceptions.py --check + # ran only on certain files for now + # add here when checked + poetry run black schematic/exceptions.py schematic/loader.py --check #---------------------------------------------- - # run test suite + # type checking/enforcement + #---------------------------------------------- + - name: Type checking with mypy + run: | + # ran only on certain files for now + # add here when checked + # mypy . + # add here when enforced + mypy --disallow-untyped-defs schematic/exceptions.py schematic/loader.py + + #---------------------------------------------- + # run test suite #---------------------------------------------- - name: Run regular tests and rule combination tests env: @@ -107,7 +120,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or schematic_api or table_operations)" - + - name: Run tests env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} @@ -117,7 +130,7 @@ jobs: source .venv/bin/activate; pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ -m "not (google_credentials_needed or rule_combos or schematic_api or table_operations)" - + - name: Upload pytest test results uses: actions/upload-artifact@v2 with: From 7d54d4223bea0e492b88af7c6b908965c20c2e7c Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:26:12 -0700 Subject: [PATCH 440/615] check loader.py --- schematic/loader.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/schematic/loader.py b/schematic/loader.py index d4a05c06a..794be4165 100644 --- a/schematic/loader.py +++ b/schematic/loader.py @@ -1,3 +1,6 @@ +"""Loader""" +from typing import Any +from collections.abc import Iterable from errno import ENOENT from os import pathsep from re import split @@ -17,19 +20,19 @@ class InvalidResourceError(Exception): that did not exist or was malformed. """ - def __init__(self, namespace, requested_uri): + def __init__(self, namespace: str, requested_uri: str) -> None: self.namespace = namespace self.requested_uri = requested_uri self.message = "Resource does not exist or is declared incorrectly" self.errno = ENOENT super(InvalidResourceError, self).__init__(self.message) - def __str__(self): + def __str__(self) -> str: return '{}({}), "{}" of {}'.format( self.message, self.errno, self.requested_uri, self.namespace ) - def __repr__(self): + def __repr__(self) -> str: return self.__str__() @@ -45,7 +48,7 @@ class Loader(object): located in a single place the uri's will be prefixed automatically by the loader. """ - def __init__(self, namespace, **opts): + def __init__(self, namespace: str, **opts: Any) -> None: self.namespace = namespace self.prefix = opts.get("prefix", "") self.local = opts.get("local", False) @@ -53,7 +56,7 @@ def __init__(self, namespace, **opts): if not self.local: self.namespace = split(r"\.|\\|\/", self.namespace)[0] - def _resolve(self, uri): + def _resolve(self, uri: str) -> tuple[str, str]: resource_uri = "/".join([self.prefix] + uri.split(pathsep)) ns = self.namespace @@ -62,7 +65,7 @@ def _resolve(self, uri): return ns, resource_uri - def read(self, uri): + def read(self, uri: str) -> Any: """ Read entire contents of resource. Same as open('path...').read() @@ -72,7 +75,7 @@ def read(self, uri): ns, uri = self._resolve(uri) return resource_string(ns, uri) - def open(self, uri): + def open(self, uri: str) -> Any: """ Open a file object like handle to the resource. Same as open('path...') @@ -82,7 +85,7 @@ def open(self, uri): ns, uri = self._resolve(uri) return resource_stream(ns, uri) - def filename(self, uri): + def filename(self, uri: str) -> str: """ Return the "most correct" filename for a resource. Same as os.path.normpath('path...') @@ -92,7 +95,7 @@ def filename(self, uri): ns, uri = self._resolve(uri) return resource_filename(ns, uri) - def list(self, url): + def list(self, url: str) -> Iterable[str]: """ Return a list of all resources within the given URL From edd3bb3b8148f5f6a849547b4e03d7b268ec0db8 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:31:02 -0700 Subject: [PATCH 441/615] ran black on help.py --- .github/workflows/test.yml | 4 ++-- schematic/help.py | 31 +++++++++++++++++-------------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1ca0f68f3..a08f999ae 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,7 +96,7 @@ jobs: run: | # ran only on certain files for now # add here when checked - poetry run black schematic/exceptions.py schematic/loader.py --check + poetry run black schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py --check #---------------------------------------------- # type checking/enforcement @@ -107,7 +107,7 @@ jobs: # add here when checked # mypy . # add here when enforced - mypy --disallow-untyped-defs schematic/exceptions.py schematic/loader.py + mypy --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py #---------------------------------------------- # run test suite diff --git a/schematic/help.py b/schematic/help.py index 679421048..a4b21c1a9 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -36,7 +36,9 @@ "to the metadata manifest file. If not it will produce a pandas dataframe for the same." ), "output_csv": ("Path to where the CSV manifest template should be stored."), - "output_xlsx": ("Path to where the Excel manifest template should be stored."), + "output_xlsx": ( + "Path to where the Excel manifest template should be stored." + ), "use_annotations": ( "This is a boolean flag. If flag is provided when command line utility is executed, it will prepopulate template " "with existing annotations from Synapse." @@ -47,7 +49,7 @@ "as a value for the `(model > input > validation_schema)` key." ), "alphabetize_valid_values": ( - "Specify to alphabetize valid attribute values either ascending (a) or descending (d)." + "Specify to alphabetize valid attribute values either ascending (a) or descending (d)." "Optional" ), }, @@ -102,19 +104,19 @@ "(--use_display_label). Attribute display names in the schema must not only include characters that are " "not accepted by Synapse. Annotation names may only contain: letters, numbers, '_' and '.'" ), - "hide_blanks":( + "hide_blanks": ( "This is a boolean flag. If flag is provided when command line utility is executed, annotations with blank values will be hidden from a dataset's annotation list in Synaspe." "If not, annotations with blank values will be displayed." ), - "manifest_record_type":( + "manifest_record_type": ( "Specify the way the manifest should be store as on Synapse. Options are 'file_only', 'file_and_entities', 'table_and_file' and " "'table_file_and_entities'. 'file_and_entities' will store the manifest as a csv and create Synapse files for each row in the manifest. " "'table_and_file' will store the manifest as a table and a csv on Synapse. " "'file_only' will store the manifest as a csv only on Synapse." "'table_file_and_entities' will perform the options file_with_entites and table in combination." "Default value is 'table_file_and_entities'." - ), - "table_manipulation":( + ), + "table_manipulation": ( "Specify the way the manifest tables should be store as on Synapse when one with the same name already exists. Options are 'replace' and 'upsert'. " "'replace' will remove the rows and columns from the existing table and store the new rows and columns, preserving the name and synID. " "'upsert' will add the new rows to the table and preserve the exisitng rows and columns in the existing table. " @@ -124,7 +126,7 @@ "Using 'upsert' at creation will generate the metadata necessary for upsert functionality." "Upsert functionality requires primary keys to be specified in the data model and manfiest as _id." "Currently it is required to use -dl/--use_display_label with table upserts." - ), + ), }, "validate": { "short_help": ("Validation of manifest files."), @@ -142,7 +144,7 @@ "You can either explicitly pass the `.json` file here or provide it in the `config.yml` file " "as a value for the `(model > input > validation_schema)` key." ), - "restrict_rules":( + "restrict_rules": ( "This is a boolean flag. If flag is provided when command line utility is executed, validation suite will only run with in-house validation rules, " "and Great Expectations rules and suite will not be utilized." "If not, the Great Expectations suite will be utilized and all rules will be available." @@ -189,11 +191,12 @@ "Specify the path to the `config.yml` using this option. This is a required argument." ), "tangled_tree": { - "figure_type": ("Specify the type of schema visualization to make. Either 'dependency' or 'component'." - ), - "text_format": ("Specify the type of text to gather for tangled tree visualization, either 'plain' or 'highlighted'." - ), - } + "figure_type": ( + "Specify the type of schema visualization to make. Either 'dependency' or 'component'." + ), + "text_format": ( + "Specify the type of text to gather for tangled tree visualization, either 'plain' or 'highlighted'." + ), + }, } - } From d015ab26dec0246aab105af342746515c69c6446 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:31:44 -0700 Subject: [PATCH 442/615] fix mypy test --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a08f999ae..1747debb2 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,9 +105,9 @@ jobs: run: | # ran only on certain files for now # add here when checked - # mypy . + # poetry run mypy . # add here when enforced - mypy --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py + poetry run mypy --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py #---------------------------------------------- # run test suite From 4cea521261c09650f49c94417e3de84e3918f304 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:43:49 -0700 Subject: [PATCH 443/615] add line to install type libs --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1747debb2..3bb2268be 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,6 +103,8 @@ jobs: #---------------------------------------------- - name: Type checking with mypy run: | + # install type libraries for some packages + poetry run mypy --install-types --non-interactive ./ # ran only on certain files for now # add here when checked # poetry run mypy . From d70ad2da45c538e6a565ea9bbdd16f0dc6f73843 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 13:52:31 -0700 Subject: [PATCH 444/615] mypy on configuration.py --- .github/workflows/test.yml | 4 ++-- pyproject.toml | 1 - schematic/configuration.py | 24 +++++++++++++----------- 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3bb2268be..448f46210 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -96,7 +96,7 @@ jobs: run: | # ran only on certain files for now # add here when checked - poetry run black schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py --check + poetry run black schematic/configuration.py schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py --check #---------------------------------------------- # type checking/enforcement @@ -107,7 +107,7 @@ jobs: poetry run mypy --install-types --non-interactive ./ # ran only on certain files for now # add here when checked - # poetry run mypy . + poetry run mypy schematic/configuration.py # add here when enforced poetry run mypy --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py diff --git a/pyproject.toml b/pyproject.toml index 2882f5713..c917ec589 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -85,7 +85,6 @@ mypy = "^0.982" [tool.black] line-length = 88 -target-version = ['py37'] include = '\.pyi?$' exclude = ''' diff --git a/schematic/configuration.py b/schematic/configuration.py index 85c7bd2a8..b6ff6da02 100644 --- a/schematic/configuration.py +++ b/schematic/configuration.py @@ -1,3 +1,4 @@ +from typing import Optional import os import yaml @@ -9,7 +10,6 @@ def __init__(self): # entire configuration data self.DATA = None - def __getattribute__(self, name): value = super().__getattribute__(name) if value is None and "SCHEMATIC_CONFIG_CONTENT" in os.environ: @@ -18,7 +18,11 @@ def __getattribute__(self, name): elif value is None and "SCHEMATIC_CONFIG" in os.environ: self.load_config_from_env() value = super().__getattribute__(name) - elif value is None and "SCHEMATIC_CONFIG" not in os.environ and "SCHEMATIC_CONFIG_CONTENT" not in os.environ: + elif ( + value is None + and "SCHEMATIC_CONFIG" not in os.environ + and "SCHEMATIC_CONFIG_CONTENT" not in os.environ + ): raise AttributeError( "The '%s' configuration field was accessed, but it hasn't been " "set yet, presumably because the schematic.CONFIG.load_config() " @@ -38,8 +42,8 @@ def get(self, key, default): value = default return value - def load_config_content(self, str_yaml: str) -> dict: - try: + def load_config_content(self, str_yaml: str) -> Optional[dict]: + try: config_data = yaml.safe_load(str_yaml) except yaml.YAMLError as exc: print(exc) @@ -47,7 +51,7 @@ def load_config_content(self, str_yaml: str) -> dict: return config_data @staticmethod - def load_yaml(file_path: str) -> dict: + def load_yaml(file_path: str) -> Optional[dict]: with open(file_path, "r") as stream: try: config_data = yaml.safe_load(stream) @@ -82,16 +86,14 @@ def load_config_from_env(self): def load_config_content_from_env(self): schematic_config_content = os.environ["SCHEMATIC_CONFIG_CONTENT"] - print( - 'Loading content of config file: %s' % schematic_config_content - ) + print("Loading content of config file: %s" % schematic_config_content) config_content_yaml = self.load_config_content(schematic_config_content) self.DATA = config_content_yaml return self.DATA - def load_config(self, config_path=None, asset_view=None): + def load_config(self, config_path=None, asset_view=None): # If config_path is None, try loading from environment if config_path is None and "SCHEMATIC_CONFIG" in os.environ: return self.load_config_from_env() @@ -108,8 +110,8 @@ def load_config(self, config_path=None, asset_view=None): self.DATA = self.load_yaml(config_path) self.CONFIG_PATH = config_path # handle user input (for API endpoints) - if asset_view: - self.DATA['synapse']['master_fileview'] = asset_view + if asset_view: + self.DATA["synapse"]["master_fileview"] = asset_view # Return self.DATA as a side-effect return self.DATA From 08ce6d237a10ca8a7b9802dded11c4c0d48d11cf Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 14:02:44 -0700 Subject: [PATCH 445/615] fixed mypy --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 448f46210..9e58ba98e 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -104,7 +104,7 @@ jobs: - name: Type checking with mypy run: | # install type libraries for some packages - poetry run mypy --install-types --non-interactive ./ + poetry run mypy --install-types --non-interactive # ran only on certain files for now # add here when checked poetry run mypy schematic/configuration.py From 58283ae5b238326256ba1e374941d970b88b88f2 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 14:14:23 -0700 Subject: [PATCH 446/615] redo how install types work --- .github/workflows/test.yml | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9e58ba98e..a7ada97d0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,13 +103,11 @@ jobs: #---------------------------------------------- - name: Type checking with mypy run: | - # install type libraries for some packages - poetry run mypy --install-types --non-interactive # ran only on certain files for now # add here when checked - poetry run mypy schematic/configuration.py + poetry run mypy --install-types schematic/configuration.py # add here when enforced - poetry run mypy --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py + poetry run mypy --install-types --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py #---------------------------------------------- # run test suite From eb60b4a90f56d293ca98cb4cb373780c4b19c995 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 12 Apr 2023 14:22:35 -0700 Subject: [PATCH 447/615] add in non interactive flag --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a7ada97d0..144b69685 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -105,9 +105,9 @@ jobs: run: | # ran only on certain files for now # add here when checked - poetry run mypy --install-types schematic/configuration.py + poetry run mypy --install-types --non-interactive schematic/configuration.py # add here when enforced - poetry run mypy --install-types --disallow-untyped-defs schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py + poetry run mypy --disallow-untyped-defs --install-types --non-interactive schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py #---------------------------------------------- # run test suite From 08c3cbdd44eb6c735ab6f5a8dcb1d161a47f5851 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 13 Apr 2023 16:19:42 -0400 Subject: [PATCH 448/615] add config file and modify docker --- certificate.conf | 18 ++++++++++++++++++ docker-compose.yml | 1 + nginx.conf | 16 ++++++++++++++++ schematic_api/Dockerfile | 38 ++++++++++++++++++++++++++++++++++++-- self-signed.conf | 2 ++ ssl-params.conf | 18 ++++++++++++++++++ 6 files changed, 91 insertions(+), 2 deletions(-) create mode 100644 certificate.conf create mode 100644 nginx.conf create mode 100644 self-signed.conf create mode 100644 ssl-params.conf diff --git a/certificate.conf b/certificate.conf new file mode 100644 index 000000000..4af22c21e --- /dev/null +++ b/certificate.conf @@ -0,0 +1,18 @@ +server { + listen 443 ssl http2 default_server; + listen [::]:443 ssl http2 default_server; + include /etc/nginx/conf.d/self-signed.conf; + include /etc/nginx/conf.d/ssl-params.conf; + server_name 127.0.0.1; + + location / { + try_files $uri @app; + } + location @app { + include uwsgi_params; + uwsgi_pass unix:///tmp/uwsgi.sock; + } + location /static { + alias /app/static; + } +} \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 4ff12ad4b..f0e7d8022 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -29,6 +29,7 @@ services: - schematic ports: - "${SERVER_PORT}:80" + - "443:443" networks: schematic: name: schematic \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 000000000..507f3654e --- /dev/null +++ b/nginx.conf @@ -0,0 +1,16 @@ +server { + listen 80 default_server; + listen [::]:80 default_server; + server_name 127.0.0.1; + location / { + try_files $uri @app; + } + location @app { + include uwsgi_params; + uwsgi_pass unix:///tmp/uwsgi.sock; + } + location /static { + alias /app/static; + } + return 302 https://$server_name$request_uri; +} \ No newline at end of file diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index 2f6501494..5ad9c6f93 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -9,7 +9,9 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_DEFAULT_TIMEOUT=200 \ POETRY_VERSION=1.2.0 \ APP_PARENT_DIR=/app \ + NGINX_CONFIG=/etc/nginx/conf.d \ APP_DIR=/app/app \ + ROOT=/ \ UWSGI_INI=/app/uwsgi.ini \ NGINX_WORKER_PROCESSES=1 @@ -18,7 +20,32 @@ ENV PYTHONFAULTHANDLER=1 \ # The maximum number of uWSGI processes is controlled by the variable UWSGI_PROCESSES, by default set to 16 # NGINX_MAX_UPLOAD is set to 0 by default that allows unlimited upload file sizes - +# run open ssl and generate certificate +RUN apt update && \ + apt-get install openssl && \ + openssl req -x509 -nodes -days 365 \ + -subj "/C=CA/ST=QC/O=Company" \ + -newkey rsa:2048 -keyout /etc/ssl/private/localhost.key \ + -out /etc/ssl/certs/localhost.crt; + +# add dhparam.pem +# this step takes quite some time +RUN openssl dhparam -out /etc/ssl/dhparam.pem 4096 + +# copy config files that handle encryption to docker +WORKDIR ${NGINX_CONFIG} +COPY ./self-signed.conf ./ssl-params.conf ./certificate.conf ./ + + +# copy uwsgi-nginx-entrypoint.sh +# this bash script is used to generate nginx.conf and some other configs +WORKDIR ${ROOT} +COPY ./uwsgi-nginx-entrypoint.sh ./entrypoint2.sh +COPY ./uwsgi-nginx-entrypoint.sh ./uwsgi-nginx-entrypoint2.sh +RUN chmod +x uwsgi-nginx-entrypoint2.sh +RUN chmod +x entrypoint2.sh +RUN chown -R nginx /uwsgi-nginx-entrypoint2.sh +RUN chown -R nginx /entrypoint2.sh # install poetry RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" @@ -67,4 +94,11 @@ WORKDIR /var/www/ RUN chown www-data:www-data /var/www/ # change work directory back -WORKDIR ${APP_DIR} \ No newline at end of file +WORKDIR ${APP_DIR} + +# specify entrypoint again to generate config +ENTRYPOINT ["/entrypoint2.sh"] +CMD ["/start.sh"] + +# Expose ports +EXPOSE 443 diff --git a/self-signed.conf b/self-signed.conf new file mode 100644 index 000000000..75a8db70a --- /dev/null +++ b/self-signed.conf @@ -0,0 +1,2 @@ +ssl_certificate /etc/ssl/certs/localhost.crt; +ssl_certificate_key /etc/ssl/private/localhost.key; \ No newline at end of file diff --git a/ssl-params.conf b/ssl-params.conf new file mode 100644 index 000000000..8ae920484 --- /dev/null +++ b/ssl-params.conf @@ -0,0 +1,18 @@ +ssl_protocols TLSv1.2; +ssl_prefer_server_ciphers on; +ssl_dhparam /etc/ssl/dhparam.pem; +ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384; +ssl_ecdh_curve secp384r1; # Requires nginx >= 1.1.0 +ssl_session_timeout 10m; +ssl_session_cache shared:SSL:10m; +ssl_session_tickets off; # Requires nginx >= 1.5.9 +ssl_stapling on; # Requires nginx >= 1.3.7 +ssl_stapling_verify on; # Requires nginx => 1.3.7 +resolver 8.8.8.8 8.8.4.4 valid=300s; +resolver_timeout 5s; +# Disable strict transport security for now. You can uncomment the following +# line if you understand the implications. +# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload"; +add_header X-Frame-Options DENY; +add_header X-Content-Type-Options nosniff; +add_header X-XSS-Protection "1; mode=block"; \ No newline at end of file From dcea19d3f494b41283035877f929cc95b60a3af0 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 13 Apr 2023 16:48:02 -0400 Subject: [PATCH 449/615] remove nginx.cof --- nginx.conf | 16 ---------------- 1 file changed, 16 deletions(-) delete mode 100644 nginx.conf diff --git a/nginx.conf b/nginx.conf deleted file mode 100644 index 507f3654e..000000000 --- a/nginx.conf +++ /dev/null @@ -1,16 +0,0 @@ -server { - listen 80 default_server; - listen [::]:80 default_server; - server_name 127.0.0.1; - location / { - try_files $uri @app; - } - location @app { - include uwsgi_params; - uwsgi_pass unix:///tmp/uwsgi.sock; - } - location /static { - alias /app/static; - } - return 302 https://$server_name$request_uri; -} \ No newline at end of file From 8a41f69a923b6aebc815e964eb129ecd73feeb33 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 13 Apr 2023 17:06:52 -0400 Subject: [PATCH 450/615] add comment and bash script; --- schematic_api/Dockerfile | 1 + uwsgi-nginx-entrypoint.sh | 52 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 uwsgi-nginx-entrypoint.sh diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index 5ad9c6f93..cb2fbf4e2 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -97,6 +97,7 @@ RUN chown www-data:www-data /var/www/ WORKDIR ${APP_DIR} # specify entrypoint again to generate config +# have to respecify CMD too ENTRYPOINT ["/entrypoint2.sh"] CMD ["/start.sh"] diff --git a/uwsgi-nginx-entrypoint.sh b/uwsgi-nginx-entrypoint.sh new file mode 100644 index 000000000..6c568dd31 --- /dev/null +++ b/uwsgi-nginx-entrypoint.sh @@ -0,0 +1,52 @@ +#! /usr/bin/env sh +set -e + +/uwsgi-nginx-entrypoint.sh + +# Modified from the bash script in the base image. See initial version here: https://github.com/tiangolo/uwsgi-nginx-flask-docker/blob/master/docker-images/entrypoint.sh + +# Get the URL for static files from the environment variable +USE_STATIC_URL=${STATIC_URL:-'/static'} +# Get the absolute path of the static files from the environment variable +USE_STATIC_PATH=${STATIC_PATH:-'/app/static'} +# Get the listen port for Nginx, default to 80 +USE_LISTEN_PORT=${LISTEN_PORT:-80} + +if [ -f /app/nginx.conf ]; then + cp /app/nginx.conf /etc/nginx/nginx.conf +else + content_server='server {\n' + content_server=$content_server" listen ${USE_LISTEN_PORT} default_server;\n" + content_server=$content_server" listen [::]:${USE_LISTEN_PORT} default_server;\n" + content_server=$content_server' server_name 127.0.0.1;\n' + content_server=$content_server' location / {\n' + content_server=$content_server' try_files $uri @app;\n' + content_server=$content_server' }\n' + content_server=$content_server' location @app {\n' + content_server=$content_server' include uwsgi_params;\n' + content_server=$content_server' uwsgi_pass unix:///tmp/uwsgi.sock;\n' + content_server=$content_server' }\n' + content_server=$content_server" location $USE_STATIC_URL {\n" + content_server=$content_server" alias $USE_STATIC_PATH;\n" + content_server=$content_server' }\n' + content_server=$content_server' return 302 https://$server_name$request_uri;\n' + + # If STATIC_INDEX is 1, serve / with /static/index.html directly (or the static URL configured) + if [ "$STATIC_INDEX" = 1 ] ; then + content_server=$content_server' location = / {\n' + content_server=$content_server" index $USE_STATIC_URL/index.html;\n" + content_server=$content_server' }\n' + fi + content_server=$content_server'}\n' + # Save generated server /etc/nginx/conf.d/nginx.conf + printf "$content_server" > /etc/nginx/conf.d/nginx.conf +fi + +# For Alpine: +# Explicitly add installed Python packages and uWSGI Python packages to PYTHONPATH +# Otherwise uWSGI can't import Flask +if [ -n "$ALPINEPYTHON" ] ; then + export PYTHONPATH=$PYTHONPATH:/usr/local/lib/$ALPINEPYTHON/site-packages:/usr/lib/$ALPINEPYTHON/site-packages +fi + +exec "$@" \ No newline at end of file From 721eb9fdd7762ef6bf14233372b34921bf70e74a Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 13 Apr 2023 17:08:40 -0400 Subject: [PATCH 451/615] more comment --- schematic_api/Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index cb2fbf4e2..e7ddc001b 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -37,8 +37,9 @@ WORKDIR ${NGINX_CONFIG} COPY ./self-signed.conf ./ssl-params.conf ./certificate.conf ./ -# copy uwsgi-nginx-entrypoint.sh -# this bash script is used to generate nginx.conf and some other configs +# use custom uwsgi-nginx-entrypoint.sh +# this uwsgi-nginx-entrypoint.sh file is derived from: https://github.com/tiangolo/uwsgi-nginx-flask-docker/blob/master/docker-images/entrypoint.sh +# we have to modify it so that we could generate a different /etc/nginx/conf.d/nginx.conf file WORKDIR ${ROOT} COPY ./uwsgi-nginx-entrypoint.sh ./entrypoint2.sh COPY ./uwsgi-nginx-entrypoint.sh ./uwsgi-nginx-entrypoint2.sh From a06e7318832319881f48fdbf4b90c8a565c741ff Mon Sep 17 00:00:00 2001 From: linglp Date: Sun, 16 Apr 2023 09:20:18 -0400 Subject: [PATCH 452/615] add to config to check health status --- certificate.conf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/certificate.conf b/certificate.conf index 4af22c21e..a6d515072 100644 --- a/certificate.conf +++ b/certificate.conf @@ -15,4 +15,8 @@ server { location /static { alias /app/static; } + location /health { + return 200 'alive'; + add_header Content-Type text/plain; + } } \ No newline at end of file From 7fff1f985af97c6e92d42a4ca5931492657e5a80 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 18 Apr 2023 16:50:23 -0400 Subject: [PATCH 453/615] update yaml --- schematic_api/api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index c582fc23a..b5f0cdf91 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -1157,7 +1157,7 @@ paths: description: >- Get all the attributes associated with a specific data model component formatted as a dataframe (stored as a JSON String). - operationId: api.routes.get_viz_component_attributes_explorer + operationId: schematic_api.api.get_viz_component_attributes_explorer parameters: - in: query name: schema_url From 019ed65d11d907911a8fc7f75e85528b7255d6ba Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 18 Apr 2023 16:54:01 -0400 Subject: [PATCH 454/615] correct yaml path --- schematic_api/api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/openapi/api.yaml b/schematic_api/api/openapi/api.yaml index b5f0cdf91..0b4d670ea 100644 --- a/schematic_api/api/openapi/api.yaml +++ b/schematic_api/api/openapi/api.yaml @@ -1157,7 +1157,7 @@ paths: description: >- Get all the attributes associated with a specific data model component formatted as a dataframe (stored as a JSON String). - operationId: schematic_api.api.get_viz_component_attributes_explorer + operationId: schematic_api.api.routes.get_viz_component_attributes_explorer parameters: - in: query name: schema_url From 69f52840c94d7cbd3e8aa45c2c242963dc25c8ee Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 18 Apr 2023 14:39:28 -0700 Subject: [PATCH 455/615] add method to get credentials --- schematic/store/synapse.py | 55 ++++++++++++++++++++++++++++++++------ 1 file changed, 47 insertions(+), 8 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 792b9ba93..78e2d160a 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1946,6 +1946,50 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No existing_table.drop(columns = ['ROW_ID', 'ROW_VERSION'], inplace = True) return existingTableId + + def _get_schematic_db_creds(synStore): + username = None + authtoken = None + + + # Get access token from environment variable if available + env_access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") + if env_access_token: + authtoken = env_access_token + + # retrive credentials from synapse object + synapse_object_creds = synStore.syn.credentials + if hasattr(synapse_object_creds, 'username'): + username = synapse_object_creds.username + if hasattr(synapse_object_creds, '_token'): + authtoken = synapse_object_creds.secret + + # Try getting creds from .synapseConfig file if it exists + if os.path.exists(CONFIG.SYNAPSE_CONFIG_PATH): + config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) + + # check which credentials are provided in file + if config.has_option('authentication', 'username'): + username = config.get('authentication', 'username') + if config.has_option('authentication', 'authtoken'): + authtoken = config.get('authentication', 'authtoken') + + # raise error if required credentials are not found + if not (username and authtoken): + raise NameError( + "Username or authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" + ) + if not username: + raise NameError( + "Username credentials could not be found in the environment, synapse object, or the .synapseConfig file" + ) + if not username: + raise NameError( + "authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" + ) + + return username, authtoken + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse @@ -1964,16 +2008,11 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non Returns: existingTableId: synID of the already existing table that had its metadata replaced - """ - config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) + """ - if config.has_option('authentication', 'username') and config.has_option('authentication', 'authtoken'): - synConfig = SynapseConfig(config.get('authentication', 'username'), config.get('authentication', 'authtoken'), synStore.getDatasetProject(datasetId) ) - else: - raise KeyError( - "Username or authtoken credentials missing in .synapseConfig" - ) + username, authtoken = TableOperations._get_schematic_db_creds(synStore) + synConfig = SynapseConfig(username, authtoken, synStore.getDatasetProject(datasetId)) synapseDB = SynapseDatabase(synConfig) synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) From a380af32acfdbd6c45283b573b94be3b8a4d5509 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 19 Apr 2023 13:25:59 -0400 Subject: [PATCH 456/615] add test --- tests/test_store.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tests/test_store.py b/tests/test_store.py index 24fa4cb4e..794b5756a 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -505,6 +505,17 @@ def test_download_manifest(self, config, mock_manifest_download, newManifestName # clean up os.remove(manifest_data['path']) + def test_download_access_restricted_manifest(self, synapse_store): + # attempt to download an uncensored manifest that has access restriction. + # if the code works correctly, the censored manifest that does not have access restriction would get downloaded (see: syn29862066) + md = ManifestDownload(synapse_store.syn, "syn29862066") + manifest_data = md.download_manifest(md) + + assert os.path.exists(manifest_data['path']) + + # clean up + os.remove(manifest_data['path']) + @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078"]) def test_entity_type_checking(self, synapse_store, entity_id, caplog): md = ManifestDownload(synapse_store.syn, entity_id) From 26601c9957cfdc4d7b4c2e95fdd009866bcb5318 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 19 Apr 2023 13:38:33 -0400 Subject: [PATCH 457/615] clean up unnecessary log.error --- schematic_api/api/routes.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 1209e7467..488973745 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -655,14 +655,11 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr try: syn = store.login(input_token=input_token) except SynapseAuthenticationError as e: - logger.error(f'Your credentials are not valid. Please provide a valid synapse token') raise e except SynapseTimeoutError as e: - logger.error("Time out waiting for synapse to respond") raise e except SynapseHTTPError as e: - logger.error(f"A Synapse HTTP error occurred. Please see the error status:{e.response.status_code}") - raise(e) + raise e try: md = ManifestDownload(syn, manifest_id) manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) From 9bfcb60acc3f83d6f174296c2928e0b7b6279a11 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 19 Apr 2023 14:18:27 -0700 Subject: [PATCH 458/615] change store dec for manifest migration --- schematic/manifest/commands.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index 975e8ddae..5332abdab 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -255,12 +255,9 @@ def migrate_manifests( """ jsonld = fill_in_from_config("jsonld", jsonld, ("model", "input", "location")) - access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") + full_scope = project_scope + [archive_project] - if access_token: - synStore = SynapseStorage(access_token = access_token, project_scope = full_scope) - else: - synStore = SynapseStorage(project_scope = full_scope) + synStore = SynapseStorage(project_scope = full_scope) for project in project_scope: if not return_entities: From 3b625c0beedce39f2ada0cd6d592c830c1015a72 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 19 Apr 2023 14:20:19 -0700 Subject: [PATCH 459/615] change store dec for `get_target_manifests` --- schematic/models/validate_attribute.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/schematic/models/validate_attribute.py b/schematic/models/validate_attribute.py index 50094aadc..da98b20ef 100644 --- a/schematic/models/validate_attribute.py +++ b/schematic/models/validate_attribute.py @@ -570,11 +570,7 @@ def get_target_manifests(target_component, project_scope: List): target_dataset_IDs=[] #login - access_token = getenv("SYNAPSE_ACCESS_TOKEN") - if access_token: - synStore = SynapseStorage(access_token=access_token,project_scope=project_scope) - else: - synStore = SynapseStorage(project_scope=project_scope) + synStore = SynapseStorage(project_scope=project_scope) #Get list of all projects user has access to projects = synStore.getStorageProjects(project_scope=project_scope) From b1964c2c3dcc32eeb59399f162c25657b78f2678 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 19 Apr 2023 23:11:25 -0400 Subject: [PATCH 460/615] correct except statement --- schematic_api/api/routes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 488973745..4b18653f2 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -687,8 +687,9 @@ def download_dataset_manifest(input_token, dataset_id, asset_view, as_json, new_ #return local file path try: manifest_local_file_path = manifest_data['path'] - except KeyError: - raise(f'Failed to download manifest from dataset: {dataset_id}') + + except KeyError as e: + raise KeyError(f'Failed to download manifest from dataset: {dataset_id}') from e #return a json (if as_json = True) if as_json: From 52ca62d19b599756038fdd79cd2c547f5529d6d9 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 19 Apr 2023 23:51:55 -0400 Subject: [PATCH 461/615] change how error was raised; add test --- schematic/store/synapse.py | 2 +- schematic_api/api/routes.py | 4 ++-- tests/test_api.py | 13 ++++++++++++- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 0feecbc67..9da87dcce 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -119,7 +119,7 @@ def download_manifest(self, newManifestName="", manifest_df=None): manifest_data = self._download_manifest_to_folder() except(SynapseUnmetAccessRestrictions, SynapseAuthenticationError): # if there's an error getting an uncensored manifest, try getting the censored manifest - if not manifest_df.empty: + if manifest_df and not manifest_df.empty: censored_regex=re.compile('.*censored.*') censored = manifest_df['name'].str.contains(censored_regex) new_manifest_id=manifest_df[censored]["id"][0] diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 4b18653f2..d4215a5d2 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -665,8 +665,8 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] - except KeyError as e: - raise (f"Failed to download manifest: {manifest_id}") from e + except (KeyError, TypeError) as e: + raise RuntimeError(f'Failed to download manifest {manifest_id}. An Error occurred: {e}') if as_json: manifest_json = return_as_json(manifest_local_file_path) return manifest_json diff --git a/tests/test_api.py b/tests/test_api.py index 1b22d7884..4883bc8b6 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -629,8 +629,19 @@ def test_manifest_download(self, config, client, syn_token, manifest_id, new_man os.remove(manifest_file_path) except: pass + # test downloading a manifest with access restriction and see if the correct error message got raised + def test_download_invalid_manifest(self, client, syn_token): + params = { + "input_token": syn_token, + "manifest_id": "syn29862078" + } + + response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) + assert response.status_code == 500 + with pytest.raises(RuntimeError) as exc_info: + raise RuntimeError('the runtime error got raised') + assert exc_info.value.args[0] == "the runtime error got raised" - @pytest.mark.parametrize("as_json", [None, True, False]) @pytest.mark.parametrize("new_manifest_name", [None, "Test"]) def test_dataset_manifest_download(self, client, as_json, syn_token, new_manifest_name): From 90f4621201b284b95f5265165a2567ec6835790c Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 20 Apr 2023 00:01:14 -0400 Subject: [PATCH 462/615] change name of test --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 4883bc8b6..dbb5021f7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -630,7 +630,7 @@ def test_manifest_download(self, config, client, syn_token, manifest_id, new_man except: pass # test downloading a manifest with access restriction and see if the correct error message got raised - def test_download_invalid_manifest(self, client, syn_token): + def test_download_access_restricted_manifest(self, client, syn_token): params = { "input_token": syn_token, "manifest_id": "syn29862078" From 84d45ad7618eb593ba7bb2028e4be8c836577135 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 20 Apr 2023 09:27:26 -0400 Subject: [PATCH 463/615] change error type --- schematic_api/api/routes.py | 4 ++-- tests/test_api.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index d4215a5d2..9621cc2b2 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -665,8 +665,8 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) #return local file path manifest_local_file_path = manifest_data['path'] - except (KeyError, TypeError) as e: - raise RuntimeError(f'Failed to download manifest {manifest_id}. An Error occurred: {e}') + except TypeError as e: + raise TypeError(f'Failed to download manifest {manifest_id}.') if as_json: manifest_json = return_as_json(manifest_local_file_path) return manifest_json diff --git a/tests/test_api.py b/tests/test_api.py index dbb5021f7..39fcbb127 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -638,9 +638,9 @@ def test_download_access_restricted_manifest(self, client, syn_token): response = client.get('http://localhost:3001/v1/manifest/download', query_string = params) assert response.status_code == 500 - with pytest.raises(RuntimeError) as exc_info: - raise RuntimeError('the runtime error got raised') - assert exc_info.value.args[0] == "the runtime error got raised" + with pytest.raises(TypeError) as exc_info: + raise TypeError('the type error got raised') + assert exc_info.value.args[0] == "the type error got raised" @pytest.mark.parametrize("as_json", [None, True, False]) @pytest.mark.parametrize("new_manifest_name", [None, "Test"]) From 9d8c0d947e20397379f68d32e7c0fc368c5020d7 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 20 Apr 2023 09:47:30 -0400 Subject: [PATCH 464/615] add typing; simplify error raising; --- schematic/store/synapse.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 9da87dcce..9d9cd3ead 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -97,9 +97,9 @@ def _entity_type_checking(self): logger.error(f'You are using entity type: {entity_type}. Please try using a file') @staticmethod - def download_manifest(self, newManifestName="", manifest_df=None): + def download_manifest(self, newManifestName: str="", manifest_df: pd.DataFrame=pd.DataFrame()) -> File: """ - Donwload a manifest based on a given manifest id. + Download a manifest based on a given manifest id. Args: newManifestName(optional): new name of a manifest that gets downloaded. manifest_df(optional): a dataframe containing name and id of manifests in a given asset view @@ -119,16 +119,15 @@ def download_manifest(self, newManifestName="", manifest_df=None): manifest_data = self._download_manifest_to_folder() except(SynapseUnmetAccessRestrictions, SynapseAuthenticationError): # if there's an error getting an uncensored manifest, try getting the censored manifest - if manifest_df and not manifest_df.empty: + if not manifest_df.empty: censored_regex=re.compile('.*censored.*') censored = manifest_df['name'].str.contains(censored_regex) new_manifest_id=manifest_df[censored]["id"][0] - old_requested_manifest_id = self.manifest_id self.manifest_id = new_manifest_id try: manifest_data = self._download_manifest_to_folder() except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - logger.error(f"You don't have access to the requested resource: {old_requested_manifest_id} and {new_manifest_id}") + raise e else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") From 93ac5eef7fa2d8012313430852ae96a79fc3e950 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 09:42:58 -0700 Subject: [PATCH 465/615] remove duplicate `input_token` param --- api/routes.py | 54 ++++++++++++++++----------------- schematic/manifest/generator.py | 8 ++--- schematic/models/metadata.py | 4 +-- schematic/store/synapse.py | 8 ++--- tests/test_api.py | 28 ++++++++--------- 5 files changed, 49 insertions(+), 53 deletions(-) diff --git a/api/routes.py b/api/routes.py index 8623c28e5..41db39f54 100644 --- a/api/routes.py +++ b/api/routes.py @@ -205,7 +205,7 @@ def get_temp_jsonld(schema_url): return tmp_file.name # @before_request -def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, asset_view = None, output_format=None, title=None, input_token=None): +def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, asset_view = None, output_format=None, title=None, access_token=None): """Get the immediate dependencies that are related to a given source node. Args: schema_url: link to data model in json ld format @@ -214,7 +214,7 @@ def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, output_format: contains three option: "excel", "google_sheet", and "dataframe". if set to "excel", return an excel spreadsheet use_annotations: Whether to use existing annotations during manifest generation asset_view: ID of view listing all project data assets. For example, for Synapse this would be the Synapse ID of the fileview listing all data assets for a given project. - input_token: Token + access_token: Token Returns: Googlesheet URL (if sheet_url is True), or pandas dataframe (if sheet_url is False). """ @@ -260,7 +260,7 @@ def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, ) - def create_single_manifest(data_type, title, dataset_id=None, output_format=None, input_token=None): + def create_single_manifest(data_type, title, dataset_id=None, output_format=None, access_token=None): # create object of type ManifestGenerator manifest_generator = ManifestGenerator( path_to_json_ld=jsonld, @@ -276,7 +276,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None output_format = "dataframe" result = manifest_generator.get_manifest( - dataset_id=dataset_id, sheet_url=True, output_format=output_format, input_token=input_token + dataset_id=dataset_id, sheet_url=True, output_format=output_format, access_token=access_token ) # return an excel file if output_format is set to "excel" @@ -300,7 +300,7 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None else: t = f'Example.{component}.manifest' if output_format != "excel": - result = create_single_manifest(data_type=component, output_format=output_format, title=t, input_token=input_token) + result = create_single_manifest(data_type=component, output_format=output_format, title=t, access_token=access_token) all_results.append(result) else: app.logger.error('Currently we do not support returning multiple files as Excel format at once. Please choose a different output format. ') @@ -315,9 +315,9 @@ def create_single_manifest(data_type, title, dataset_id=None, output_format=None t = title if dataset_ids: # if a dataset_id is provided add this to the function call. - result = create_single_manifest(data_type=dt, dataset_id=dataset_ids[i], output_format=output_format, title=t, input_token=input_token) + result = create_single_manifest(data_type=dt, dataset_id=dataset_ids[i], output_format=output_format, title=t, access_token=access_token) else: - result = create_single_manifest(data_type=dt, output_format=output_format, title=t, input_token=input_token) + result = create_single_manifest(data_type=dt, output_format=output_format, title=t, access_token=access_token) # if output is pandas dataframe or google sheet url if isinstance(result, str) or isinstance(result, pd.DataFrame): @@ -381,7 +381,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None metadata_model = initalize_metadata_model(schema_url) - input_token = connexion.request.args["input_token"] + access_token = connexion.request.args["access_token"] use_schema_label = connexion.request.args["use_schema_label"] @@ -406,7 +406,7 @@ def submit_manifest_route(schema_url, asset_view=None, manifest_record_type=None manifest_path=temp_path, dataset_id=dataset_id, validate_component=validate_component, - input_token=input_token, + access_token=access_token, manifest_record_type = manifest_record_type, restrict_rules = restrict_rules, table_manipulation = table_manipulation, @@ -432,36 +432,36 @@ def populate_manifest_route(schema_url, title=None, data_type=None, return_excel return populated_manifest_link -def get_storage_projects(input_token, asset_view): +def get_storage_projects(access_token, asset_view): # call config handler config_handler(asset_view=asset_view) # use Synapse storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # call getStorageProjects function lst_storage_projects = store.getStorageProjects() return lst_storage_projects -def get_storage_projects_datasets(input_token, asset_view, project_id): +def get_storage_projects_datasets(access_token, asset_view, project_id): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # call getStorageDatasetsInProject function sorted_dataset_lst = store.getStorageDatasetsInProject(projectId = project_id) return sorted_dataset_lst -def get_files_storage_dataset(input_token, asset_view, dataset_id, full_path, file_names=None): +def get_files_storage_dataset(access_token, asset_view, dataset_id, full_path, file_names=None): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # no file names were specified (file_names = ['']) if file_names and not all(file_names): @@ -471,24 +471,24 @@ def get_files_storage_dataset(input_token, asset_view, dataset_id, full_path, fi file_lst = store.getFilesInStorageDataset(datasetId=dataset_id, fileNames=file_names, fullpath=full_path) return file_lst -def check_if_files_in_assetview(input_token, asset_view, entity_id): +def check_if_files_in_assetview(access_token, asset_view, entity_id): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # call function and check if a file or a folder is in asset view if_exists = store.checkIfinAssetView(entity_id) return if_exists -def check_entity_type(input_token, asset_view, entity_id): +def check_entity_type(access_token, asset_view, entity_id): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) entity_type = store.checkEntityType(entity_id) return entity_type @@ -547,12 +547,12 @@ def get_viz_tangled_tree_layers(schema_url, figure_type): return layers[0] -def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest_name=''): +def download_manifest(access_token, dataset_id, asset_view, as_json, new_manifest_name=''): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # download existing file manifest_data = store.getDatasetManifest(datasetId=dataset_id, downloadFile=True, newManifestName=new_manifest_name) @@ -568,12 +568,12 @@ def download_manifest(input_token, dataset_id, asset_view, as_json, new_manifest return manifest_local_file_path -def get_asset_view_table(input_token, asset_view, return_type): +def get_asset_view_table(access_token, asset_view, return_type): # call config handler config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # get file view table file_view_table_df = store.getStorageFileviewTable() @@ -589,24 +589,24 @@ def get_asset_view_table(input_token, asset_view, return_type): return export_path -def get_project_manifests(input_token, project_id, asset_view): +def get_project_manifests(access_token, project_id, asset_view): # use the default asset view from config config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # call getprojectManifest function lst_manifest = store.getProjectManifests(projectId=project_id) return lst_manifest -def get_manifest_datatype(input_token, manifest_id, asset_view): +def get_manifest_datatype(access_token, manifest_id, asset_view): # use the default asset view from config config_handler(asset_view=asset_view) # use Synapse Storage - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) # get data types of an existing manifest manifest_dtypes_dict= store.getDataTypeFromManifest(manifest_id) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 8c2eac8aa..280a8da15 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1510,7 +1510,7 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st return manifest_sh.url def get_manifest( - self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None, input_token: str = None + self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None, access_token: str = None ) -> Union[str, pd.DataFrame]: """Gets manifest for a given dataset on Synapse. TODO: move this function to class MetadatModel (after MetadataModel is refactored) @@ -1520,7 +1520,7 @@ def get_manifest( sheet_url: Determines if googlesheet URL or pandas dataframe should be returned. output_format: Determines if Google sheet URL, pandas dataframe, or Excel spreadsheet gets returned. output_path: Determines the output path of the exported manifest - input_token: Token in .synapseConfig. Since we could not pre-load access_token as an environment variable on AWS, we have to add this variable. + access_token: Token in .synapseConfig. Since we could not pre-load access_token as an environment variable on AWS, we have to add this variable. Returns: Googlesheet URL, pandas dataframe, or an Excel spreadsheet @@ -1542,9 +1542,9 @@ def get_manifest( #TODO: avoid explicitly exposing Synapse store functionality # just instantiate a Store class and let it decide at runtime/config # the store type - if input_token: + if access_token: # for getting an existing manifest on AWS - store = SynapseStorage(input_token=input_token) + store = SynapseStorage(access_token=access_token) else: store = SynapseStorage() diff --git a/schematic/models/metadata.py b/schematic/models/metadata.py index be1cf131b..d10d27151 100644 --- a/schematic/models/metadata.py +++ b/schematic/models/metadata.py @@ -286,7 +286,7 @@ def submit_metadata_manifest( validate_component: str = None, use_schema_label: bool = True, hide_blanks: bool = False, - input_token: str = None, + access_token: str = None, project_scope: List = None, table_manipulation: str = 'replace' ) -> string: @@ -306,7 +306,7 @@ def submit_metadata_manifest( #TODO: avoid explicitly exposing Synapse store functionality # just instantiate a Store class and let it decide at runtime/config # the store type - syn_store = SynapseStorage(input_token = input_token, project_scope = project_scope) + syn_store = SynapseStorage(access_token = access_token, project_scope = project_scope) manifest_id=None censored_manifest_id=None restrict_maniest=False diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 78e2d160a..d54c01a97 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -64,7 +64,6 @@ def __init__( self, token: str = None, # optional parameter retrieved from browser cookie access_token: str = None, - input_token: str = None, project_scope: List = None, ) -> None: """Initializes a SynapseStorage object. @@ -152,12 +151,9 @@ def login(token=None, access_token=None, input_token=None): except synapseclient.core.exceptions.SynapseHTTPError: raise ValueError("Please make sure you are logged into synapse.org.") elif access_token: - syn = synapseclient.Synapse() - syn.default_headers["Authorization"] = f"Bearer {access_token}" - elif input_token: - try: + try: syn = synapseclient.Synapse() - syn.default_headers["Authorization"] = f"Bearer {input_token}" + syn.default_headers["Authorization"] = f"Bearer {access_token}" except synapseclient.core.exceptions.SynapseHTTPError: raise ValueError("No access to resources. Please make sure that your token is correct") else: diff --git a/tests/test_api.py b/tests/test_api.py index 18447e196..fc69d3b7d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -88,7 +88,7 @@ class TestSynapseStorage: @pytest.mark.parametrize("return_type", ["json", "csv"]) def test_get_storage_assets_tables(self, client, syn_token, return_type): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "return_type": return_type } @@ -114,7 +114,7 @@ def test_get_storage_assets_tables(self, client, syn_token, return_type): @pytest.mark.parametrize("file_names", [None, "Sample_A.txt"]) def test_get_dataset_files(self,full_path, file_names, syn_token, client): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "dataset_id": "syn23643250", "full_path": full_path, @@ -142,7 +142,7 @@ def test_get_dataset_files(self,full_path, file_names, syn_token, client): def test_get_storage_project_dataset(self, syn_token, client): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "project_id": "syn26251192" } @@ -155,7 +155,7 @@ def test_get_storage_project_dataset(self, syn_token, client): def test_get_storage_project_manifests(self, syn_token, client): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "project_id": "syn30988314" } @@ -167,7 +167,7 @@ def test_get_storage_project_manifests(self, syn_token, client): def test_get_storage_projects(self, syn_token, client): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253" } @@ -178,7 +178,7 @@ def test_get_storage_projects(self, syn_token, client): @pytest.mark.parametrize("entity_id", ["syn34640850", "syn23643253", "syn24992754"]) def test_get_entity_type(self, syn_token, client, entity_id): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "entity_id": entity_id } @@ -196,7 +196,7 @@ def test_get_entity_type(self, syn_token, client, entity_id): @pytest.mark.parametrize("entity_id", ["syn30988314", "syn27221721"]) def test_if_in_assetview(self, syn_token, client, entity_id): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "entity_id": entity_id } @@ -409,7 +409,7 @@ def test_generate_existing_manifest(self, client, data_model_jsonld, data_type, "title": "Example", "data_type": data_type, "use_annotations": False, - "input_token": None + "access_token": None } if dataset_id: params['dataset_id'] = dataset_id @@ -455,7 +455,7 @@ def test_generate_new_manifest(self, caplog, client, data_model_jsonld, data_typ "data_type": data_type, "use_annotations": False, "dataset_id": None, - "input_token": None + "access_token": None } if output_format: @@ -557,7 +557,7 @@ def test_validate_manifest(self, data_model_jsonld, client, json_str, restrict_r def test_get_datatype_manifest(self, client, syn_token): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn23643253", "manifest_id": "syn27600110" } @@ -580,7 +580,7 @@ def test_get_datatype_manifest(self, client, syn_token): @pytest.mark.parametrize("new_manifest_name", [None, "Test"]) def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): params = { - "input_token": syn_token, + "access_token": syn_token, "asset_view": "syn28559058", "dataset_id": "syn28268700", "as_json": as_json, @@ -606,7 +606,7 @@ def test_manifest_download(self, client, as_json, syn_token, new_manifest_name): @pytest.mark.parametrize("manifest_record_type", ['table_and_file', 'file_only']) def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label, manifest_record_type): params = { - "input_token": syn_token, + "access_token": syn_token, "schema_url": data_model_jsonld, "data_type": "Patient", "restrict_rules": False, @@ -636,7 +636,7 @@ def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, t @pytest.mark.parametrize("manifest_record_type", ['file_and_entities', 'table_file_and_entities']) def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, manifest_record_type): params = { - "input_token": syn_token, + "access_token": syn_token, "schema_url": data_model_jsonld, "data_type": "Patient", "restrict_rules": False, @@ -666,7 +666,7 @@ def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) def test_submit_manifest_upsert(self, client, syn_token, data_model_jsonld, json_str, test_upsert_manifest_csv, ): params = { - "input_token": syn_token, + "access_token": syn_token, "schema_url": data_model_jsonld, "data_type": "MockRDB", "restrict_rules": False, From 69131d413637ab27265f28cfdead029ef5cd981c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 09:55:02 -0700 Subject: [PATCH 466/615] remove `input_token` from syn store methods --- schematic/store/synapse.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d54c01a97..cf2c11173 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -81,7 +81,7 @@ def __init__( syn_store = SynapseStorage() """ - self.syn = self.login(token, access_token, input_token) + self.syn = self.login(token, access_token) self.project_scope = project_scope @@ -137,9 +137,9 @@ def _query_fileview(self): raise AccessCredentialsError(self.storageFileview) @staticmethod - def login(token=None, access_token=None, input_token=None): + def login(token=None, access_token=None): # If no token is provided, try retrieving access token from environment - if not token and not access_token and not input_token: + if not token and not access_token: access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") # login using a token From e27760f5f125b40f4f00f2221e4be0fb5e1310a9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:28:17 -0700 Subject: [PATCH 467/615] add mark for rule benchmark tests --- pyproject.toml | 4 ++++ tests/test_api.py | 1 + 2 files changed, 5 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index c917ec589..f2bcc79af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -132,4 +132,8 @@ markers = [ table operations that pass locally \ but fail on CI due to interactions with Synapse (skipped on GitHub CI) """ + """\ + rule_benchmark: marks tests covering \ + validation rule benchmarking + """ ] diff --git a/tests/test_api.py b/tests/test_api.py index 18447e196..88424b5e7 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -730,6 +730,7 @@ def test_visualize_component(self, client, data_model_jsonld,component, response assert response_text in response.text @pytest.mark.schematic_api +@pytest.mark.rule_benchmark class TestValidationBenchmark(): @pytest.mark.parametrize('MockComponent_attribute', get_MockComponent_attribute()) def test_validation_performance(self, helpers, benchmark_data_model_jsonld, client, test_invalid_manifest, MockComponent_attribute ): From 6e3a17f4e0ac4e5355dd9783ac4ef8ab09d78f2b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:29:44 -0700 Subject: [PATCH 468/615] remove instructions remove instructions necessitating local api running to perform unit tests --- pyproject.toml | 4 ++-- tests/test_api.py | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index f2bcc79af..714b88d3f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -119,8 +119,8 @@ markers = [ Google credentials (skipped on GitHub CI) \ """, """\ - schematic_api: marks tests requiring \ - running API locally (skipped on GitHub CI) + schematic_api: marks tests covering \ + API functionality (skipped on regular GitHub CI test suite) """, """\ rule_combos: marks tests covering \ diff --git a/tests/test_api.py b/tests/test_api.py index 88424b5e7..877cb2b14 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -14,10 +14,6 @@ logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -''' -To run the tests, you have to keep API running locally first by doing `python3 run_api.py` -''' - @pytest.fixture(scope="class") def app(): app = create_app() From 43afe74002832522871a088fed726b2b1b4f9b63 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:37:18 -0700 Subject: [PATCH 469/615] add workflow file for API tests --- .github/workflows/api_test.yml | 110 +++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 .github/workflows/api_test.yml diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml new file mode 100644 index 000000000..67fc07560 --- /dev/null +++ b/.github/workflows/api_test.yml @@ -0,0 +1,110 @@ +# Built from: +# https://docs.github.com/en/actions/guides/building-and-testing-python +# https://github.com/Sage-Bionetworks/challengeutils/blob/master/.github/workflows/pythonapp.yml +# https://github.com/snok/install-poetry#workflows-and-tips + +name: Test schematic + +on: + workflow_dispatch: # Allow manually triggering the workflow + inputs: + perform_benchmarking: + type: boolean + description: perform benchmarking test (True) or skip (False) +concurrency: + # do not cancel the current running workflow from the same branch, PR when a new workflow is triggered + # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group + # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows + # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag + # {{ github.event.pull_request.number}}: get PR number + # {{ github.sha }}: full commit sha + # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml + group: >- + ${{ github.workflow }}-${{ github.ref_type }}- + ${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: false +jobs: + test: + runs-on: ubuntu-latest + env: + POETRY_VERSION: 1.2.0rc1 + strategy: + fail-fast: false + matrix: + python-version: ["3.9", "3.10"] + + steps: + + #---------------------------------------------- + # check-out repo and set-up python + #---------------------------------------------- + - name: Check out repository + uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + #---------------------------------------------- + # install & configure poetry + #---------------------------------------------- + - name: Install Poetry + run: | + curl -sSL https://install.python-poetry.org \ + | python3 - --version ${{ env.POETRY_VERSION }}; + poetry config virtualenvs.create true; + poetry config virtualenvs.in-project true; + #---------------------------------------------- + # load cached venv if cache exists + #---------------------------------------------- + - name: Load cached venv + id: cached-poetry-dependencies + uses: actions/cache@v2 + with: + path: .venv + key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} + + #---------------------------------------------- + # install dependencies if cache does not exist + #---------------------------------------------- + - name: Install dependencies + if: steps.cached-poetry-dependencies.outputs.cache-hit != 'true' + run: poetry install --no-interaction --no-root --all-extras + + #---------------------------------------------- + # install your root project, if required + #---------------------------------------------- + - name: Install library + run: poetry install --no-interaction + + #---------------------------------------------- + # run API test suite + #---------------------------------------------- + - name: Run all API tests + env: + SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} + SERVICE_ACCOUNT_CREDS: ${{ secrets.SERVICE_ACCOUNT_CREDS }} + if: ${{ inputs.perform_benchmarking }} + run: > + source .venv/bin/activate; + pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ + -m "schematic_api" + + - name: Run API tests + Exclude Benchmarks + env: + SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} + SERVICE_ACCOUNT_CREDS: ${{ secrets.SERVICE_ACCOUNT_CREDS }} + if: ${{ false == inputs.perform_benchmarking }} + run: > + source .venv/bin/activate; + pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ + -m "schematic_api and not rule_benchmark" + + - name: Upload pytest test results + uses: actions/upload-artifact@v2 + with: + name: pytest-results-${{ matrix.python-version }} + path: htmlcov + # Use always() to always run this step to publish test results when there are test failures + if: ${{ always() }} From b8f33c12fcf9c5a6ebe33c5ec98f5f0224246657 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:39:13 -0700 Subject: [PATCH 470/615] update workflow name --- .github/workflows/api_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 67fc07560..d90365f18 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -3,7 +3,7 @@ # https://github.com/Sage-Bionetworks/challengeutils/blob/master/.github/workflows/pythonapp.yml # https://github.com/snok/install-poetry#workflows-and-tips -name: Test schematic +name: Test schematic API on: workflow_dispatch: # Allow manually triggering the workflow From 7e27574d8a94183eacc17da5463e24856f28e63c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:43:37 -0700 Subject: [PATCH 471/615] Update api_test.yml --- .github/workflows/api_test.yml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index d90365f18..07f1c5597 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -1,16 +1,15 @@ # Built from: -# https://docs.github.com/en/actions/guides/building-and-testing-python -# https://github.com/Sage-Bionetworks/challengeutils/blob/master/.github/workflows/pythonapp.yml -# https://github.com/snok/install-poetry#workflows-and-tips - +# https://github.com/Sage-Bionetworks/schematic/blob/develop/.github/workflows/test.yml name: Test schematic API on: - workflow_dispatch: # Allow manually triggering the workflow - inputs: - perform_benchmarking: - type: boolean - description: perform benchmarking test (True) or skip (False) + workflow_dispatch: + inputs: + perform_benchmarking: + required: true + type: boolean + description: perform benchmarking test (True) or skip (False) + concurrency: # do not cancel the current running workflow from the same branch, PR when a new workflow is triggered # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group From d346ebcbbcbf794bb4a0124a60524348246a984d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:45:29 -0700 Subject: [PATCH 472/615] Update api_test.yml --- .github/workflows/api_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 07f1c5597..668c5158f 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -1,5 +1,6 @@ # Built from: # https://github.com/Sage-Bionetworks/schematic/blob/develop/.github/workflows/test.yml + name: Test schematic API on: From 2edf62b6eec1386221360c32d6c64c19188508e1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:46:45 -0700 Subject: [PATCH 473/615] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 714b88d3f..a5b0a4ab4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -131,7 +131,7 @@ markers = [ table_operations: marks tests covering \ table operations that pass locally \ but fail on CI due to interactions with Synapse (skipped on GitHub CI) - """ + """, """\ rule_benchmark: marks tests covering \ validation rule benchmarking From a65518d0952e6eb0f89056be89f0ba85dcb29ae4 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:53:06 -0700 Subject: [PATCH 474/615] Update api_test.yml --- .github/workflows/api_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 668c5158f..943eb1bbc 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -39,7 +39,7 @@ jobs: # check-out repo and set-up python #---------------------------------------------- - name: Check out repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 From 23869209782c2c1674f7811c48af8aa4bb3df3bb Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 10:54:33 -0700 Subject: [PATCH 475/615] Update api_test.yml --- .github/workflows/api_test.yml | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 943eb1bbc..085103ba0 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -11,18 +11,6 @@ on: type: boolean description: perform benchmarking test (True) or skip (False) -concurrency: - # do not cancel the current running workflow from the same branch, PR when a new workflow is triggered - # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group - # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows - # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag - # {{ github.event.pull_request.number}}: get PR number - # {{ github.sha }}: full commit sha - # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml - group: >- - ${{ github.workflow }}-${{ github.ref_type }}- - ${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: false jobs: test: runs-on: ubuntu-latest From 8553359d16cba17a558c147c35dda3a8636fe827 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 11:37:56 -0700 Subject: [PATCH 476/615] Revert "Update api_test.yml" This reverts commit a65518d0952e6eb0f89056be89f0ba85dcb29ae4. --- .github/workflows/api_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 085103ba0..818bc5488 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -27,7 +27,7 @@ jobs: # check-out repo and set-up python #---------------------------------------------- - name: Check out repository - uses: actions/checkout@v3 + uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 From 0e6c73547ed8c4fba2a57ae88babb031a648ee71 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 20 Apr 2023 15:23:29 -0400 Subject: [PATCH 477/615] correct type hinting --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 9d9cd3ead..86853f323 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -97,7 +97,7 @@ def _entity_type_checking(self): logger.error(f'You are using entity type: {entity_type}. Please try using a file') @staticmethod - def download_manifest(self, newManifestName: str="", manifest_df: pd.DataFrame=pd.DataFrame()) -> File: + def download_manifest(self, newManifestName: str="", manifest_df: pd.DataFrame=pd.DataFrame()) -> Union[str,File]: """ Download a manifest based on a given manifest id. Args: @@ -489,7 +489,7 @@ def _get_manifest_id(self, manifest: pd.DataFrame) -> str: def getDatasetManifest( self, datasetId: str, downloadFile: bool = False, newManifestName: str='', - ) -> List[str]: + ) -> Union[str, File]: """Gets the manifest associated with a given dataset. Args: From cdabc760ddcc42c759cfbcd7304af8513cd6b1c6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 20 Apr 2023 13:03:06 -0700 Subject: [PATCH 478/615] only use config token if no env var token --- tests/test_api.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index 877cb2b14..5bf8c4fb3 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -76,7 +76,8 @@ def syn_token(config): # try using synapse access token if "SYNAPSE_ACCESS_TOKEN" in os.environ: token=os.environ["SYNAPSE_ACCESS_TOKEN"] - token = config_parser["authentication"]["authtoken"] + else: + token = config_parser["authentication"]["authtoken"] yield token @pytest.mark.schematic_api From d429c9696dba03fea24bd0ec896c821b9e621ef6 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 21 Apr 2023 10:09:58 -0700 Subject: [PATCH 479/615] remove dupe `input_token` from `api.yaml` --- api/openapi/api.yaml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 3d67663e4..2f211d373 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -24,7 +24,7 @@ paths: https://raw.githubusercontent.com/Sage-Bionetworks/schematic/develop/tests/data/example.model.jsonld required: true - in: query - name: input_token + name: access_token schema: type: string description: Token is needed if getting an existing manifest on AWS @@ -105,7 +105,7 @@ paths: description: Endpoint to download an existing manifest parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -281,7 +281,7 @@ paths: description: If True, validation suite will only run with in-house validation rule. If False, the Great Expectations suite will be utilized and all rules will be available. required: true - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -438,7 +438,7 @@ paths: operationId: api.routes.get_manifest_datatype parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -475,7 +475,7 @@ paths: operationId: api.routes.get_storage_projects parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -504,7 +504,7 @@ paths: operationId: api.routes.get_storage_projects_datasets parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -541,7 +541,7 @@ paths: operationId: api.routes.get_files_storage_dataset parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -594,7 +594,7 @@ paths: operationId: api.routes.get_asset_view_table parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -631,7 +631,7 @@ paths: operationId: api.routes.get_project_manifests parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -679,7 +679,7 @@ paths: operationId: api.routes.check_entity_type parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false @@ -717,7 +717,7 @@ paths: operationId: api.routes.check_if_files_in_assetview parameters: - in: query - name: input_token + name: access_token schema: type: string nullable: false From 7df8c7fd6341f34f5de184620db3e6e784bb38e2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 21 Apr 2023 10:53:39 -0700 Subject: [PATCH 480/615] use token to login to synapse --- schematic/store/synapse.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index cf2c11173..67ccbce79 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -154,6 +154,7 @@ def login(token=None, access_token=None): try: syn = synapseclient.Synapse() syn.default_headers["Authorization"] = f"Bearer {access_token}" + syn.login(authToken=access_token, silent = True) except synapseclient.core.exceptions.SynapseHTTPError: raise ValueError("No access to resources. Please make sure that your token is correct") else: From 4f3c7998abb4d0b51859fbaf6d5ef424e3213e25 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 09:15:11 -0700 Subject: [PATCH 481/615] Revert "use token to login to synapse" This reverts commit 7df8c7fd6341f34f5de184620db3e6e784bb38e2. --- schematic/store/synapse.py | 1 - 1 file changed, 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 67ccbce79..cf2c11173 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -154,7 +154,6 @@ def login(token=None, access_token=None): try: syn = synapseclient.Synapse() syn.default_headers["Authorization"] = f"Bearer {access_token}" - syn.login(authToken=access_token, silent = True) except synapseclient.core.exceptions.SynapseHTTPError: raise ValueError("No access to resources. Please make sure that your token is correct") else: From 13e65deff0afdd95e86587b216dbd745ddb21edd Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 10:02:09 -0700 Subject: [PATCH 482/615] get access token from synapse obj header --- schematic/store/synapse.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index cf2c11173..d4ef8138a 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1953,6 +1953,10 @@ def _get_schematic_db_creds(synStore): if env_access_token: authtoken = env_access_token + # Get token from authorization header + if 'Authorization' in synStore.syn.default_headers: + authtoken = synStore.syn.default_headers['Authorization'].split('Bearer ')[-1] + # retrive credentials from synapse object synapse_object_creds = synStore.syn.credentials if hasattr(synapse_object_creds, 'username'): @@ -1970,7 +1974,6 @@ def _get_schematic_db_creds(synStore): if config.has_option('authentication', 'authtoken'): authtoken = config.get('authentication', 'authtoken') - # raise error if required credentials are not found if not (username and authtoken): raise NameError( "Username or authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" From 741d94b06823e62a386d282fbca9b4c456c4ed62 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 11:07:12 -0700 Subject: [PATCH 483/615] update error messages --- schematic/store/synapse.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d4ef8138a..56da808bb 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1974,15 +1974,12 @@ def _get_schematic_db_creds(synStore): if config.has_option('authentication', 'authtoken'): authtoken = config.get('authentication', 'authtoken') - if not (username and authtoken): + # raise error if required credentials are not found + if not username and not authtoken: raise NameError( "Username or authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" ) - if not username: - raise NameError( - "Username credentials could not be found in the environment, synapse object, or the .synapseConfig file" - ) - if not username: + if not authtoken: raise NameError( "authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" ) From d2f57fb98cd13e031fe274c2f1507bfc8e46ba3c Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 25 Apr 2023 15:35:28 -0400 Subject: [PATCH 484/615] change log error statement --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 86853f323..31750b66e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -94,7 +94,7 @@ def _entity_type_checking(self): # check the type of entity entity_type = entity_type_mapping(self.syn, self.manifest_id) if entity_type != "file": - logger.error(f'You are using entity type: {entity_type}. Please try using a file') + logger.error(f'You are using entity type: {entity_type}. Please provide a file ID') @staticmethod def download_manifest(self, newManifestName: str="", manifest_df: pd.DataFrame=pd.DataFrame()) -> Union[str,File]: From 8ff42c342242b04173aff2d045634121fba69b5c Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 25 Apr 2023 16:41:12 -0400 Subject: [PATCH 485/615] update message in test --- tests/test_store.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index 794b5756a..5c8036413 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -522,7 +522,7 @@ def test_entity_type_checking(self, synapse_store, entity_id, caplog): md._entity_type_checking() if entity_id == "syn27600053": for record in caplog.records: - assert "You are using entity type: folder. Please try using a file" in record.message + assert "You are using entity type: folder. Please provide a file ID" in record.message From 0b1c89a4b60afbd1bcaf841909f9de348aa27fb2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 13:43:19 -0700 Subject: [PATCH 486/615] remove dupe import and commented out code --- schematic/store/synapse.py | 78 -------------------------------------- 1 file changed, 78 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 792b9ba93..e28cd2816 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -36,8 +36,6 @@ from synapseutils import walk from synapseutils.copy_functions import changeFileMetaData -import uuid - from schematic_db.synapse.synapse import SynapseConfig from schematic_db.rdb.synapse_database import SynapseDatabase from schematic_db.schema.schema import get_key_attribute @@ -1034,82 +1032,6 @@ def format_manifest_annotations(self, manifest, manifest_synapse_id): annos[annos_k] = annos_v return annos - ''' - def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPath, - useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False): - """ - Purpose: - Works very similarly to associateMetadataWithFiles except takes in the manifest - rather than the manifest path - - """ - - # Add uuid for table updates and fill. - if not "Uuid" in manifest.columns: - manifest["Uuid"] = '' - - for idx,row in manifest.iterrows(): - if not row["Uuid"]: - gen_uuid = uuid.uuid4() - row["Uuid"] = gen_uuid - manifest.loc[idx, 'Uuid'] = gen_uuid - - # add entityId as a column if not already there or - # fill any blanks with an empty string. - if not "entityId" in manifest.columns: - manifest["entityId"] = "" - else: - manifest["entityId"].fillna("", inplace=True) - - # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations - se = SchemaExplorer() - - # Create table name here. - if 'Component' in manifest.columns: - table_name = manifest['Component'][0].lower() + '_synapse_storage_manifest_table' - else: - table_name = 'synapse_storage_manifest_table' - - # Upload manifest as a table and get the SynID and manifest - manifest_synapse_table_id, manifest, table_manifest = self.upload_format_manifest_table( - se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,) - - # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed - # also set metadata for each synapse entity as Synapse annotations - for idx, row in manifest.iterrows(): - if not row["entityId"]: - # If not using entityIds, fill with manifest_table_id so - row["entityId"] = manifest_synapse_table_id - entityId = '' - else: - # get the entity id corresponding to this row - entityId = row["entityId"] - - # Load manifest to synapse as a CSV File - manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest) - - # Get annotations for the file manifest. - manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) - - self.syn.set_annotations(manifest_annotations) - - logger.info("Associated manifest file with dataset on Synapse.") - - # Update manifest Synapse table with new entity id column. - self.make_synapse_table( - table_to_load = table_manifest, - dataset_id = datasetId, - existingTableId = manifest_synapse_table_id, - table_name = table_name, - update_col = 'Uuid', - specify_schema = False, - ) - - # Get annotations for the table manifest - manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) - self.syn.set_annotations(manifest_annotations) - return manifest_synapse_table_id - ''' def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: """Helper function to read in provided manifest as a pandas DataFrame for subsequent downstream processing. From 5197ba1c6ab803e406fbd7edbaf187e3711479e7 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 25 Apr 2023 16:54:01 -0400 Subject: [PATCH 487/615] update to use dataframe.empty syntax --- tests/test_store.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index 5c8036413..762552558 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -474,21 +474,21 @@ def test_get_manifest_id(self, synapse_store, datasetFileView): # rows that contain the censored manifest datasetFileViewDataFrame = pd.DataFrame(datasetFileView) row_censored = datasetFileViewDataFrame.loc[datasetFileViewDataFrame['name'] == "synapse_storage_manifest_censored.csv"] - if len(row_censored) > 0: + if not row_censored.empty > 0: censored_manifest_id = row_censored['id'].values[0] # rows that contain the uncensored manifest row_uncensored = datasetFileViewDataFrame.loc[datasetFileViewDataFrame['name'] == "synapse_storage_manifest.csv"] - if len(row_uncensored) > 0: + if not row_uncensored.empty > 0: uncensored_manifest_id = row_uncensored['id'].values[0] # get id of the uncensored manifest manifest_syn_id = synapse_store._get_manifest_id(datasetFileViewDataFrame) # if there are both censored and uncensored manifests, return only id of uncensored manifest - if len(row_uncensored) > 0: + if not row_uncensored.empty > 0: assert manifest_syn_id == uncensored_manifest_id # if only censored manifests are present, return only id of censored manifest - elif len(row_uncensored) == 0 and len(row_censored) > 0: + elif row_uncensored.empty and not row_censored.empty: assert manifest_syn_id == censored_manifest_id @pytest.mark.parametrize("newManifestName",["", "Example"]) From 685104594cb18ff15585bb80fb4d8fc637fda0ed Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 14:55:52 -0700 Subject: [PATCH 488/615] add attribute to MockRDB component --- tests/data/example.model.csv | 1 + tests/data/example.model.jsonld | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index eec328eae..aeaabd3e5 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -40,3 +40,4 @@ Check Date,,,,,TRUE,DataProperty,,,date Check NA,,,,,TRUE,DataProperty,,,int::IsNA MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, MockRDB_id,,,,,TRUE,DataProperty,,,int +Mock Attribute,,,,,TRUE,DataProperty,,, diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index b8b1c5d1b..974f17964 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2967,6 +2967,23 @@ "int" ] }, + { + "@id": "bts:MockAttribute", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "MockAttribute", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "Mock Attribute", + "sms:required": "sms:true", + "sms:validationRules": [] + }, { "@id": "bts:Component", "@type": "rdfs:Class", From 191708a6f4cf9553762a52021fe263bc6e766332 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 14:56:32 -0700 Subject: [PATCH 489/615] update upsert test manfiests --- tests/data/mock_manifests/rdb_table_manifest.csv | 10 +++++----- .../data/mock_manifests/rdb_table_manifest_upsert.csv | 11 ++++++----- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index e547895ba..6af3c5b3a 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,5 +1,5 @@ -Component,MockRDB_id -MockRDB,1 -MockRDB,2 -MockRDB,3 -MockRDB,4 +Component,MockRDB_id,Mock Attribute +MockRDB,1,Manifest1 +MockRDB,2,Manifest1 +MockRDB,3,Manifest1 +MockRDB,4,Manifest1 diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index 625c1f66f..f22f57f90 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,5 +1,6 @@ -Component,MockRDB_id -MockRDB,5 -MockRDB,6 -MockRDB,7 -MockRDB,8 +Component,MockRDB_id,Mock Attribute +MockRDB,5,Manifest2 +MockRDB,6,Manifest2 +MockRDB,7,Manifest2 +MockRDB,8,Manifest2 +MockRDB,4,Manifest2 From b0f0d19e3a954d8dc4cf9a11036c3118d6895755 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:22:47 -0700 Subject: [PATCH 490/615] update attribute name --- tests/data/example.model.csv | 2 +- tests/data/example.model.jsonld | 2 +- tests/data/mock_manifests/rdb_table_manifest.csv | 2 +- tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index aeaabd3e5..c60f499f1 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -40,4 +40,4 @@ Check Date,,,,,TRUE,DataProperty,,,date Check NA,,,,,TRUE,DataProperty,,,int::IsNA MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, MockRDB_id,,,,,TRUE,DataProperty,,,int -Mock Attribute,,,,,TRUE,DataProperty,,, +MockAttribute,,,,,TRUE,DataProperty,,, diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index 974f17964..87c5dc11c 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2980,7 +2980,7 @@ "schema:isPartOf": { "@id": "http://schema.biothings.io" }, - "sms:displayName": "Mock Attribute", + "sms:displayName": "MockAttribute", "sms:required": "sms:true", "sms:validationRules": [] }, diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index 6af3c5b3a..5892d9487 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,4 +1,4 @@ -Component,MockRDB_id,Mock Attribute +Component,MockRDB_id,MockAttribute MockRDB,1,Manifest1 MockRDB,2,Manifest1 MockRDB,3,Manifest1 diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index f22f57f90..6b158aa0d 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,4 +1,4 @@ -Component,MockRDB_id,Mock Attribute +Component,MockRDB_id,MockAttribute MockRDB,5,Manifest2 MockRDB,6,Manifest2 MockRDB,7,Manifest2 From 83e6387733325921bad9ab31fc66344aa6b06686 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 25 Apr 2023 15:47:15 -0700 Subject: [PATCH 491/615] update tests to verify update functionality --- tests/test_store.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/test_store.py b/tests/test_store.py index 7e48d2b4a..a7afb18c7 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -380,7 +380,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) table_name="MockRDB_synapse_storage_manifest_table".lower() manifest_path = "mock_manifests/rdb_table_manifest.csv" replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" - column_of_interest="MockRDB_id" + column_of_interest="MockRDB_id,MockAttribute" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -412,13 +412,14 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) tableId = existing_tables[table_name] # Query table for DaystoFollowUp column - IDs = synapse_store.syn.tableQuery( + table_query = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert IDs.max() == 4 - assert IDs.size == 4 + assert table_query.MockRDB_id.max() == 4 + assert table_query.MockRDB_id.size == 4 + assert table_query['MockAttribute'][3] == 'Manifest1' # Associate new manifest with files manifestId = synapse_store.associateMetadataWithFiles( @@ -435,12 +436,13 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # Query table for DaystoFollowUp column tableId = existing_tables[table_name] - IDs = synapse_store.syn.tableQuery( + table_query = synapse_store.syn.tableQuery( f"SELECT {column_of_interest} FROM {tableId}" ).asDataFrame().squeeze() # assert max ID is '4' and that there are 4 entries - assert IDs.max() == 8 - assert IDs.size == 8 + assert table_query.MockRDB_id.max() == 8 + assert table_query.MockRDB_id.size == 8 + assert table_query['MockAttribute'][3] == 'Manifest2' # delete table synapse_store.syn.delete(tableId) From 0de9a151090585f47230faa46e8f6011d04573a8 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 26 Apr 2023 11:22:26 -0400 Subject: [PATCH 492/615] delete old docker file used by deployment; added back the old part in docker compose --- dev.Dockerfile | 34 ---------------------------------- docker-compose.yml | 32 ++++++++++++++++---------------- 2 files changed, 16 insertions(+), 50 deletions(-) delete mode 100644 dev.Dockerfile diff --git a/dev.Dockerfile b/dev.Dockerfile deleted file mode 100644 index c9c05ec1e..000000000 --- a/dev.Dockerfile +++ /dev/null @@ -1,34 +0,0 @@ -## For aws deployments -FROM python:3.10.9-slim-bullseye - -# set APP_PORT to 80 to avoid 308 unhealthy target group error -ENV PYTHONFAULTHANDLER=1 \ - PYTHONUNBUFFERED=1 \ - PYTHONHASHSEED=random \ - PIP_NO_CACHE_DIR=off \ - PIP_DISABLE_PIP_VERSION_CHECK=on \ - PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0 \ - APP_PORT=80 - -WORKDIR /usr/src/app - -RUN apt-get update -qqy \ - && apt-get install -qqy \ - libopenblas-dev \ - gfortran - -# remove libtiff5 for security reasons -RUN apt remove -y libtiff5 - -RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" - -COPY pyproject.toml poetry.lock ./ - -RUN poetry config virtualenvs.create false - -RUN poetry install --no-interaction --no-ansi --no-root - -COPY . ./ - -CMD ["python", "/usr/src/app/run_api.py"] \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 49ee2b225..d19326f35 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,21 +1,21 @@ version: "3.9" services: - # schematic: - # build: - # dockerfile: Dockerfile - # container_name: schematic - # entrypoint: python /usr/src/app/run_api.py - # ports: - # - "3001:3001" - # volumes: - # - .:/schematic - # working_dir: /schematic - # environment: - # APP_HOST: "0.0.0.0" - # APP_PORT: "3001" - # SCHEMATIC_CONFIG: /schematic/config.yml - # SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" - # GE_HOME: /usr/src/app/great_expectations/ + schematic: + build: + dockerfile: Dockerfile + container_name: schematic + entrypoint: python /usr/src/app/run_api.py + ports: + - "3001:3001" + volumes: + - .:/schematic + working_dir: /schematic + environment: + APP_HOST: "0.0.0.0" + APP_PORT: "3001" + SCHEMATIC_CONFIG: /schematic/config.yml + SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" + GE_HOME: /usr/src/app/great_expectations/ schematic-aws: build: context: ../schematic From c09414c6f54fd961b5a62f8a530871e04f5cdc28 Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 26 Apr 2023 12:19:38 -0400 Subject: [PATCH 493/615] add documentation --- docker-compose.yml | 2 ++ schematic_api/api/README.md | 15 +++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index d19326f35..27219fed6 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,6 @@ version: "3.9" services: + # run schematic APIs in a docker container without uWSGI schematic: build: dockerfile: Dockerfile @@ -16,6 +17,7 @@ services: SCHEMATIC_CONFIG: /schematic/config.yml SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" GE_HOME: /usr/src/app/great_expectations/ + # run schematic APIs in a docker container with uWSGI schematic-aws: build: context: ../schematic diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index a6e352ff3..66df5f98c 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -1,4 +1,5 @@ ## Setup +There are two ways to run schematic APIs: 1) start a flask server and run your application locally (preferred for external users); 2) build a docker image that allows you to run a container with flask application with uWSGI. To start a local Flask server and test your endpoints: @@ -6,6 +7,20 @@ To start a local Flask server and test your endpoints: source .venv/bin/activate python3 run_api.py ``` +You should be able to see the application running when visiting `http://localhost:3001/v1/ui/` + +To start a docker container that runs flask application with uWSGI: +1) Comment out line 4 to line 19 in `docker-compose.yml`. +2) Create .env file based on env.example. Fill in `service_account_creds.json` +3) Make sure that you have all the dependencies installed, including uWSGI and flask. +4) Build a docker image and spin up docker container `schematic-api-aws` by running: +```bash +docker compose up +``` + +You should be able to see the application running when visiting `http://localhost:7080/v1/ui/` + +By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. ## Notes on installation 1. The warning message: "connexion.options - The swagger_ui directory could not be found." could be addressed by pip installing connexion[swagger-ui]. For Mac users, the command should be: From 83bc4a553340557a2dc5326ed980ea716e45dd1d Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 26 Apr 2023 12:34:41 -0400 Subject: [PATCH 494/615] move profiling to general.py --- schematic/utils/general.py | 63 +++++++++++++++++++++++++- schematic_api/api/routes.py | 89 ++++--------------------------------- 2 files changed, 71 insertions(+), 81 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 2fc2bc357..b97304b93 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -2,6 +2,9 @@ from typing import Any, Dict, Optional, Text import os import math +import pstats +from cProfile import Profile +from functools import wraps def find_duplicates(_list): """Find duplicate items in a list""" @@ -69,4 +72,62 @@ def convert_gb_to_bytes(gb: int): return: total number of bytes """ bytes_to_return = gb * 1024 * 1024 * 1024 - return bytes_to_return \ No newline at end of file + return bytes_to_return + +def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): + """ + The function was initially taken from: https://towardsdatascience.com/how-to-profile-your-code-in-python-e70c834fad89 + A time profiler decorator. + Inspired by and modified the profile decorator of Giampaolo Rodola: + http://code.activestate.com/recipes/577817-profile-decorator/ + Args: + output_file: str or None. Default is None + Path of the output file. If only name of the file is given, it's + saved in the current directory. + If it's None, the name of the decorated function is used. + sort_by: str or SortKey enum or tuple/list of str/SortKey enum + Sorting criteria for the Stats object. + For a list of valid string and SortKey refer to: + https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats + lines_to_print: int or None + Number of lines to print. Default (None) is for all the lines. + This is useful in reducing the size of the printout, especially + that sorting by 'cumulative', the time consuming operations + are printed toward the top of the file. + strip_dirs: bool + Whether to remove the leading path info from file names. + This is also useful in reducing the size of the printout + Returns: + Profile of the decorated function + """ + + def inner(func): + @wraps(func) + def wrapper(*args, **kwargs): + _output_file = output_file or func.__name__ + '.prof' + pr = Profile() + pr.enable() + retval = func(*args, **kwargs) + pr.disable() + pr.dump_stats(_output_file) + + #if we are running the functions on AWS: + if "SECRETS_MANAGER_SECRETS" in os.environ: + ps = pstats.Stats(pr) + # limit this to 30 line for now otherwise it will be too long for AWS log + ps.sort_stats('cumulative').print_stats(30) + else: + with open(_output_file, 'w') as f: + ps = pstats.Stats(pr, stream=f) + if strip_dirs: + ps.strip_dirs() + if isinstance(sort_by, (tuple, list)): + ps.sort_stats(*sort_by) + else: + ps.sort_stats(sort_by) + ps.print_stats(lines_to_print) + return retval + + return wrapper + + return inner \ No newline at end of file diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 83bd3867f..6f39deabc 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -5,13 +5,19 @@ import shutil import urllib.request +import pickle + import connexion from connexion.decorators.uri_parsing import Swagger2URIParser -from flask import current_app as app from werkzeug.debug import DebuggedApplication -from schematic import CONFIG +from flask_cors import cross_origin +from flask import send_from_directory +from flask import current_app as app +import pandas as pd +import json +from schematic import CONFIG from schematic.visualization.attributes_explorer import AttributesExplorer from schematic.visualization.tangled_tree import TangledTree from schematic.manifest.generator import ManifestGenerator @@ -19,85 +25,9 @@ from schematic.schemas.generator import SchemaGenerator from schematic.schemas.explorer import SchemaExplorer from schematic.store.synapse import SynapseStorage -from flask_cors import CORS, cross_origin from schematic.schemas.explorer import SchemaExplorer -import pandas as pd -import json from schematic.utils.df_utils import load_df -import pickle -from flask import send_from_directory -from cProfile import Profile -from pstats import Stats -from functools import wraps -from pstats import SortKey -import pstats -import io -# def before_request(var1, var2): -# # Do stuff before your route executes -# pass -# def after_request(var1, var2): -# # Do stuff after your route executes -# pass -from flask_cors import cross_origin - -def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): - """ - The function was initially taken from: https://towardsdatascience.com/how-to-profile-your-code-in-python-e70c834fad89 - A time profiler decorator. - Inspired by and modified the profile decorator of Giampaolo Rodola: - http://code.activestate.com/recipes/577817-profile-decorator/ - Args: - output_file: str or None. Default is None - Path of the output file. If only name of the file is given, it's - saved in the current directory. - If it's None, the name of the decorated function is used. - sort_by: str or SortKey enum or tuple/list of str/SortKey enum - Sorting criteria for the Stats object. - For a list of valid string and SortKey refer to: - https://docs.python.org/3/library/profile.html#pstats.Stats.sort_stats - lines_to_print: int or None - Number of lines to print. Default (None) is for all the lines. - This is useful in reducing the size of the printout, especially - that sorting by 'cumulative', the time consuming operations - are printed toward the top of the file. - strip_dirs: bool - Whether to remove the leading path info from file names. - This is also useful in reducing the size of the printout - Returns: - Profile of the decorated function - """ - - def inner(func): - @wraps(func) - def wrapper(*args, **kwargs): - _output_file = output_file or func.__name__ + '.prof' - pr = Profile() - pr.enable() - retval = func(*args, **kwargs) - pr.disable() - pr.dump_stats(_output_file) - - #if we are running the functions on AWS: - if "SECRETS_MANAGER_SECRETS" in os.environ: - ps = pstats.Stats(pr) - # limit this to 30 line for now otherwise it will be too long for AWS log - ps.sort_stats('cumulative').print_stats(30) - else: - with open(_output_file, 'w') as f: - ps = pstats.Stats(pr, stream=f) - if strip_dirs: - ps.strip_dirs() - if isinstance(sort_by, (tuple, list)): - ps.sort_stats(*sort_by) - else: - ps.sort_stats(sort_by) - ps.print_stats(lines_to_print) - return retval - - return wrapper - - return inner - +from schematic.utils.general import profile def config_handler(asset_view=None): path_to_config = app.config["SCHEMATIC_CONFIG"] @@ -268,7 +198,6 @@ def get_temp_jsonld(schema_url): # get path to temporary JSON-LD file return tmp_file.name -# @before_request def get_manifest_route(schema_url: str, use_annotations: bool, dataset_ids=None, asset_view = None, output_format=None, title=None, input_token=None): """Get the immediate dependencies that are related to a given source node. Args: From e8b2c8e532889543f3e48a0160170322f71a5644 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:58:31 -0700 Subject: [PATCH 495/615] only re-query fileview if no datasets found --- schematic/store/synapse.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 56da808bb..6858cc826 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1726,6 +1726,15 @@ def getDatasetProject(self, datasetId: str) -> str: dataset_index = self.storageFileviewTable["id"] == datasetId dataset_row = self.storageFileviewTable[dataset_index] + # re-query if nothing found + if len(dataset_row) == 0: + sleep(5) + self._query_fileview() + # Subset main file view + dataset_index = self.storageFileviewTable["id"] == datasetId + dataset_row = self.storageFileviewTable[dataset_index] + + # Return `projectId` for given row if only one found if len(dataset_row) == 1: dataset_project = dataset_row["projectId"].values[0] From 6ce33b246ee51263c12b503f96072e55ed160148 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 26 Apr 2023 10:59:08 -0700 Subject: [PATCH 496/615] remove initial query in `getDatasetProject` --- schematic/store/synapse.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 6858cc826..486e2d002 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1720,13 +1720,11 @@ def getDatasetProject(self, datasetId: str) -> str: str: The Synapse ID for the parent project. """ - self._query_fileview() - # Subset main file view dataset_index = self.storageFileviewTable["id"] == datasetId dataset_row = self.storageFileviewTable[dataset_index] - # re-query if nothing found + # re-query if no datasets found if len(dataset_row) == 0: sleep(5) self._query_fileview() From 61814ae67fa8f490b8e318e6c18c6f4714387a21 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 26 Apr 2023 15:05:11 -0700 Subject: [PATCH 497/615] remove coverage metrics --- .github/workflows/api_test.yml | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 818bc5488..a20c642d8 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -76,8 +76,7 @@ jobs: if: ${{ inputs.perform_benchmarking }} run: > source .venv/bin/activate; - pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ - -m "schematic_api" + pytest -m "schematic_api" - name: Run API tests + Exclude Benchmarks env: @@ -86,13 +85,5 @@ jobs: if: ${{ false == inputs.perform_benchmarking }} run: > source .venv/bin/activate; - pytest --cov-report=term --cov-report=html:htmlcov --cov=schematic/ - -m "schematic_api and not rule_benchmark" - - - name: Upload pytest test results - uses: actions/upload-artifact@v2 - with: - name: pytest-results-${{ matrix.python-version }} - path: htmlcov - # Use always() to always run this step to publish test results when there are test failures - if: ${{ always() }} + pytest -m "schematic_api and not rule_benchmark" + \ No newline at end of file From 45a956f1166ec3facc094f96788c30ce64a1123a Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 10:47:57 -0400 Subject: [PATCH 498/615] added comments in code and updated documentation --- docker-compose.yml | 4 ++-- schematic_api/Dockerfile | 5 ++++- schematic_api/api/README.md | 5 ++--- schematic_api/api/__main__.py | 1 - 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 27219fed6..868d1566d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ version: "3.9" services: - # run schematic APIs in a docker container without uWSGI + #run schematic APIs in a docker container without uWSGI schematic: build: dockerfile: Dockerfile @@ -17,7 +17,7 @@ services: SCHEMATIC_CONFIG: /schematic/config.yml SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" GE_HOME: /usr/src/app/great_expectations/ - # run schematic APIs in a docker container with uWSGI + #run schematic APIs in a docker container with uWSGI schematic-aws: build: context: ../schematic diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index cade1c9db..cc2d30b59 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -3,7 +3,10 @@ FROM python:3.10.9-slim-bullseye SHELL ["/bin/bash", "-euxo", "pipefail", "-c"] -# set APP_PORT to 80 +# set default APP_PORT to 80 +# the environment variables defined here are the default +# and can be overwritten by docker run -e VARIABLE = XX +# or can be overwritten by .env when using docker compose ENV PYTHONFAULTHANDLER=1 \ PYTHONUNBUFFERED=1 \ PYTHONHASHSEED=random \ diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 66df5f98c..610f19a4a 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -7,7 +7,7 @@ To start a local Flask server and test your endpoints: source .venv/bin/activate python3 run_api.py ``` -You should be able to see the application running when visiting `http://localhost:3001/v1/ui/` +If you define `APP_PORT` as `3001` in `docker-compose.yml`, you should be able to see the application running when visiting `http://localhost:3001/v1/ui/` To start a docker container that runs flask application with uWSGI: 1) Comment out line 4 to line 19 in `docker-compose.yml`. @@ -17,8 +17,7 @@ To start a docker container that runs flask application with uWSGI: ```bash docker compose up ``` - -You should be able to see the application running when visiting `http://localhost:7080/v1/ui/` +If you define the value of SERVER_PORT as `7080` in `.env` file, you should be able to see the application running when visiting `http://localhost:7080/v1/ui/` By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index 8081a7578..1aba56e45 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -12,7 +12,6 @@ def main(): port = int(port) # Launch app - # CORS(app, resources={r"*": {"origins": "*"}}) app.run(host=host, port=port, debug=False) if __name__ == "__main__": From 9f5ea94c2e53e63f6dc3fd064b084be96326f981 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 27 Apr 2023 09:20:41 -0700 Subject: [PATCH 499/615] Update poetry.lock --- poetry.lock | 1612 +++++++++++++++++++++++++-------------------------- 1 file changed, 799 insertions(+), 813 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7a1615457..98973c369 100644 --- a/poetry.lock +++ b/poetry.lock @@ -94,7 +94,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.14.2" +version = "2.15.4" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false @@ -121,29 +121,26 @@ test = ["astroid", "pytest"] [[package]] name = "attrs" -version = "22.2.0" +version = "23.1.0" description = "Classes Without Boilerplate" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] -cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs[docs,tests]"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] -tests = ["attrs[tests-no-zope]", "zope.interface"] -tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] [[package]] name = "babel" -version = "2.11.0" +version = "2.12.1" description = "Internationalization utilities" category = "main" optional = false -python-versions = ">=3.6" - -[package.dependencies] -pytz = ">=2015.7" +python-versions = ">=3.7" [[package]] name = "backcall" @@ -155,7 +152,7 @@ python-versions = "*" [[package]] name = "beautifulsoup4" -version = "4.11.2" +version = "4.12.2" description = "Screen-scraping library" category = "main" optional = false @@ -234,11 +231,11 @@ pycparser = "*" [[package]] name = "charset-normalizer" -version = "3.0.1" +version = "3.1.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7.0" [[package]] name = "click" @@ -284,7 +281,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7 [[package]] name = "comm" -version = "0.1.2" +version = "0.1.3" description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." category = "main" optional = false @@ -294,7 +291,9 @@ python-versions = ">=3.6" traitlets = ">=5.3" [package.extras] +lint = ["black (>=22.6.0)", "mdformat (>0.7)", "mdformat-gfm (>=0.3.5)", "ruff (>=0.0.156)"] test = ["pytest"] +typing = ["mypy (>=0.990)"] [[package]] name = "connexion" @@ -325,7 +324,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14 [[package]] name = "coverage" -version = "7.1.0" +version = "7.2.3" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -339,7 +338,7 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "39.0.1" +version = "40.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false @@ -351,16 +350,16 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff", "types-pytz", "types-requests"] +pep8test = ["black", "check-manifest", "mypy", "ruff"] sdist = ["setuptools-rust (>=0.11.4)"] ssh = ["bcrypt (>=3.1.5)"] -test = ["hypothesis (>=1.11.4,!=3.79.2)", "iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist", "pytz"] +test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] test-randomorder = ["pytest-randomly"] tox = ["tox"] [[package]] name = "dateparser" -version = "1.1.7" +version = "1.1.8" description = "Date parsing library designed to parse dates from HTML pages" category = "main" optional = false @@ -379,7 +378,7 @@ langdetect = ["langdetect"] [[package]] name = "debugpy" -version = "1.6.6" +version = "1.6.7" description = "An implementation of the Debug Adapter Protocol for Python" category = "main" optional = false @@ -452,7 +451,7 @@ python-versions = ">=3.6" [[package]] name = "exceptiongroup" -version = "1.1.0" +version = "1.1.1" description = "Backport of PEP 654 (exception groups)" category = "main" optional = false @@ -474,7 +473,7 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.16.2" +version = "2.16.3" description = "Fastest Python implementation of JSON schema" category = "main" optional = false @@ -556,7 +555,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.78.0" +version = "2.86.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -571,7 +570,7 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.16.1" +version = "2.17.3" description = "Google Authentication Library" category = "main" optional = false @@ -620,7 +619,7 @@ tool = ["click (>=6.0.0)"] [[package]] name = "googleapis-common-protos" -version = "1.58.0" +version = "1.59.0" description = "Common protobufs used in Google APIs" category = "main" optional = false @@ -647,7 +646,7 @@ test = ["coverage", "mock (>=4)", "pytest (>=7)", "pytest-cov", "pytest-mock (>= [[package]] name = "great-expectations" -version = "0.15.49" +version = "0.15.50" description = "Always know what to expect from your data." category = "main" optional = false @@ -730,7 +729,7 @@ test = ["objgraph", "psutil"] [[package]] name = "httplib2" -version = "0.21.0" +version = "0.22.0" description = "A comprehensive HTTP client library." category = "main" optional = false @@ -757,7 +756,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "importlib-metadata" -version = "6.0.0" +version = "4.13.0" description = "Read metadata from Python packages" category = "main" optional = false @@ -767,7 +766,7 @@ python-versions = ">=3.7" zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)"] perf = ["ipython"] testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] @@ -789,7 +788,7 @@ python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.21.2" +version = "6.22.0" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -819,7 +818,7 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.10.0" +version = "8.12.0" description = "IPython: Productive Interactive Computing" category = "main" optional = false @@ -834,10 +833,11 @@ jedi = ">=0.16" matplotlib-inline = "*" pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} pickleshare = "*" -prompt-toolkit = ">=3.0.30,<3.1.0" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" pygments = ">=2.4.0" stack-data = "*" traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [package.extras] all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] @@ -862,7 +862,7 @@ python-versions = "*" [[package]] name = "ipywidgets" -version = "8.0.4" +version = "8.0.6" description = "Jupyter interactive widgets" category = "main" optional = false @@ -871,12 +871,12 @@ python-versions = ">=3.7" [package.dependencies] ipykernel = ">=4.5.1" ipython = ">=6.1.0" -jupyterlab-widgets = ">=3.0,<4.0" +jupyterlab-widgets = ">=3.0.7,<3.1.0" traitlets = ">=4.3.1" -widgetsnbextension = ">=4.0,<5.0" +widgetsnbextension = ">=4.0.7,<4.1.0" [package.extras] -test = ["jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] +test = ["ipykernel", "jsonschema", "pytest (>=3.6.0)", "pytest-cov", "pytz"] [[package]] name = "isodate" @@ -1009,7 +1009,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- [[package]] name = "jupyter-client" -version = "8.0.3" +version = "8.2.0" description = "Jupyter protocol implementation and client libraries" category = "main" optional = false @@ -1025,11 +1025,11 @@ traitlets = ">=5.3" [package.extras] docs = ["ipykernel", "myst-parser", "pydata-sphinx-theme", "sphinx (>=4)", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] -test = ["codecov", "coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] +test = ["coverage", "ipykernel (>=6.14)", "mypy", "paramiko", "pre-commit", "pytest", "pytest-cov", "pytest-jupyter[client] (>=0.4.1)", "pytest-timeout"] [[package]] name = "jupyter-core" -version = "5.2.0" +version = "5.3.0" description = "Jupyter core package. A base package on which Jupyter projects rely." category = "main" optional = false @@ -1037,7 +1037,7 @@ python-versions = ">=3.8" [package.dependencies] platformdirs = ">=2.5" -pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} traitlets = ">=5.3" [package.extras] @@ -1067,7 +1067,7 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= [[package]] name = "jupyter-server" -version = "2.3.0" +version = "2.5.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false @@ -1094,7 +1094,7 @@ traitlets = ">=5.6.0" websocket-client = "*" [package.extras] -docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] [[package]] @@ -1123,7 +1123,7 @@ python-versions = ">=3.7" [[package]] name = "jupyterlab-widgets" -version = "3.0.5" +version = "3.0.7" description = "Jupyter interactive widgets for JupyterLab" category = "main" optional = false @@ -1172,7 +1172,7 @@ python-versions = ">=3.7" [[package]] name = "makefun" -version = "1.15.0" +version = "1.15.1" description = "Small library to dynamically create python functions." category = "main" optional = false @@ -1258,7 +1258,7 @@ python-versions = ">=3.5" [[package]] name = "nbclassic" -version = "0.5.2" +version = "0.5.6" description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false @@ -1275,7 +1275,7 @@ jupyter-server = ">=1.8" nbconvert = ">=5" nbformat = "*" nest-asyncio = ">=1.5" -notebook-shim = ">=0.1.0" +notebook-shim = ">=0.2.3" prometheus-client = "*" pyzmq = ">=17" Send2Trash = ">=1.8.0" @@ -1290,7 +1290,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p [[package]] name = "nbclient" -version = "0.7.2" +version = "0.7.4" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "main" optional = false @@ -1304,12 +1304,12 @@ traitlets = ">=5.3" [package.extras] dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme"] -test = ["ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.2.9" +version = "7.3.1" description = "Converting Jupyter Notebooks" category = "main" optional = false @@ -1344,7 +1344,7 @@ webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] name = "nbformat" -version = "5.7.3" +version = "5.8.0" description = "The Jupyter Notebook format" category = "main" optional = false @@ -1385,7 +1385,7 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "notebook" -version = "6.5.2" +version = "6.5.4" description = "A web-based notebook environment for interactive computing" category = "main" optional = false @@ -1416,7 +1416,7 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixs [[package]] name = "notebook-shim" -version = "0.2.2" +version = "0.2.3" description = "A shim layer for notebook traits and config" category = "main" optional = false @@ -1426,11 +1426,11 @@ python-versions = ">=3.7" jupyter-server = ">=1.8,<3" [package.extras] -test = ["pytest", "pytest-console-scripts", "pytest-tornasync"] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] [[package]] name = "numpy" -version = "1.24.2" +version = "1.24.3" description = "Fundamental package for array computing in Python" category = "main" optional = false @@ -1466,7 +1466,7 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] [[package]] name = "openpyxl" -version = "3.1.1" +version = "3.1.2" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" category = "main" optional = false @@ -1477,12 +1477,29 @@ et-xmlfile = "*" [[package]] name = "packaging" -version = "23.0" +version = "23.1" description = "Core utilities for Python packages" category = "main" optional = false python-versions = ">=3.7" +[[package]] +name = "pandarallel" +version = "1.6.4" +description = "An easy to use library to speed up computation (by parallelizing on multi CPUs) with pandas." +category = "main" +optional = false +python-versions = "*" + +[package.dependencies] +dill = ">=0.3.1" +pandas = ">=1" +psutil = "*" + +[package.extras] +dev = ["numpy", "pytest", "pytest-cov"] +doc = ["mkdocs-material"] + [[package]] name = "pandas" version = "1.5.3" @@ -1524,7 +1541,7 @@ testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pathspec" -version = "0.11.0" +version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." category = "main" optional = false @@ -1567,15 +1584,15 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "3.0.0" +version = "3.4.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.2.2)", "pytest (>=7.2.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" @@ -1602,18 +1619,18 @@ twisted = ["twisted"] [[package]] name = "prompt-toolkit" -version = "3.0.36" +version = "3.0.38" description = "Library for building powerful interactive command lines in Python" category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7.0" [package.dependencies] wcwidth = "*" [[package]] name = "protobuf" -version = "4.22.0" +version = "4.22.3" description = "" category = "main" optional = false @@ -1621,7 +1638,7 @@ python-versions = ">=3.7" [[package]] name = "psutil" -version = "5.9.4" +version = "5.9.5" description = "Cross-platform lib for process and system monitoring in Python." category = "main" optional = false @@ -1651,22 +1668,22 @@ tests = ["pytest"] [[package]] name = "pyasn1" -version = "0.4.8" -description = "ASN.1 types and codecs" +version = "0.5.0" +description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" category = "main" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" [[package]] name = "pyasn1-modules" -version = "0.2.8" -description = "A collection of ASN.1-based protocols modules." +version = "0.3.0" +description = "A collection of ASN.1-based protocols modules" category = "main" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" [package.dependencies] -pyasn1 = ">=0.4.6,<0.5.0" +pyasn1 = ">=0.4.6,<0.6.0" [[package]] name = "pycodestyle" @@ -1686,7 +1703,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.10.5" +version = "1.10.7" description = "Data validation and settings management using python type hints" category = "main" optional = false @@ -1709,11 +1726,11 @@ python-versions = ">=3.6" [[package]] name = "pygments" -version = "2.14.0" +version = "2.15.1" description = "Pygments is a syntax highlighting package written in Python." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.extras] plugins = ["importlib-metadata"] @@ -1735,14 +1752,14 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.16.2" +version = "2.17.3" description = "python code static checker" category = "main" optional = false python-versions = ">=3.7.2" [package.dependencies] -astroid = ">=2.14.2,<=2.16.0-dev0" +astroid = ">=2.15.4,<=2.17.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = {version = ">=0.2", markers = "python_version < \"3.11\""} isort = ">=4.2.5,<6" @@ -1758,14 +1775,14 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyopenssl" -version = "23.0.0" +version = "23.1.1" description = "Python wrapper module around the OpenSSL library" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -cryptography = ">=38.0.0,<40" +cryptography = ">=38.0.0,<41" [package.extras] docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] @@ -1792,14 +1809,13 @@ python-versions = ">=3.7" [[package]] name = "pytest" -version = "7.2.1" +version = "7.3.1" description = "pytest: simple powerful testing with Python" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -attrs = ">=19.2.0" colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" @@ -1808,7 +1824,7 @@ pluggy = ">=0.12,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] [[package]] name = "pytest-cov" @@ -1863,7 +1879,7 @@ cli = ["click (>=5.0)"] [[package]] name = "python-json-logger" -version = "2.0.6" +version = "2.0.7" description = "A python library adding a json log formatter" category = "main" optional = false @@ -1871,7 +1887,7 @@ python-versions = ">=3.6" [[package]] name = "pytz" -version = "2022.7.1" +version = "2023.3" description = "World timezone definitions, modern and historical" category = "main" optional = false @@ -1890,7 +1906,7 @@ tzdata = {version = "*", markers = "python_version >= \"3.6\""} [[package]] name = "pywin32" -version = "305" +version = "306" description = "Python for Window Extensions" category = "main" optional = false @@ -1922,7 +1938,7 @@ python-versions = ">=3.6" [[package]] name = "pyzmq" -version = "25.0.0" +version = "25.0.2" description = "Python bindings for 0MQ" category = "main" optional = false @@ -1933,40 +1949,37 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} [[package]] name = "rdflib" -version = "6.2.0" +version = "6.3.2" description = "RDFLib is a Python library for working with RDF, a simple yet powerful language for representing information." category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.7,<4.0" [package.dependencies] -isodate = "*" -pyparsing = "*" -setuptools = "*" +isodate = ">=0.6.0,<0.7.0" +pyparsing = ">=2.1.0,<4" [package.extras] -berkeleydb = ["berkeleydb"] -dev = ["black (==22.6.0)", "flake8", "flakeheaven", "isort", "mypy", "pep8-naming", "types-setuptools"] -docs = ["myst-parser", "sphinx (<6)", "sphinx-autodoc-typehints", "sphinxcontrib-apidoc", "sphinxcontrib-kroki"] -html = ["html5lib"] -networkx = ["networkx"] -tests = ["html5lib", "pytest", "pytest-cov"] +berkeleydb = ["berkeleydb (>=18.1.0,<19.0.0)"] +html = ["html5lib (>=1.0,<2.0)"] +lxml = ["lxml (>=4.3.0,<5.0.0)"] +networkx = ["networkx (>=2.0.0,<3.0.0)"] [[package]] name = "regex" -version = "2022.10.31" +version = "2023.3.23" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" [[package]] name = "requests" -version = "2.28.2" +version = "2.29.0" description = "Python HTTP for Humans." category = "main" optional = false -python-versions = ">=3.7, <4" +python-versions = ">=3.7" [package.dependencies] certifi = ">=2017.4.17" @@ -2104,11 +2117,11 @@ jeepney = ">=0.6" [[package]] name = "send2trash" -version = "1.8.0" -description = "Send file to trash natively under Mac OS X, Windows and Linux." +version = "1.8.2" +description = "Send file to trash natively under Mac OS X, Windows and Linux" category = "main" optional = false -python-versions = "*" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.extras] nativelib = ["pyobjc-framework-Cocoa", "pywin32"] @@ -2154,7 +2167,7 @@ python-versions = "*" [[package]] name = "soupsieve" -version = "2.4" +version = "2.4.1" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = false @@ -2162,7 +2175,7 @@ python-versions = ">=3.7" [[package]] name = "sphinx" -version = "6.1.3" +version = "6.2.1" description = "Python documentation generator" category = "main" optional = false @@ -2172,7 +2185,7 @@ python-versions = ">=3.8" alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18,<0.20" +docutils = ">=0.18.1,<0.20" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" @@ -2190,7 +2203,7 @@ sphinxcontrib-serializinghtml = ">=1.1.5" [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["docutils-stubs", "flake8 (>=3.5.0)", "flake8-simplify", "isort", "mypy (>=0.990)", "ruff", "sphinx-lint", "types-requests"] -test = ["cython", "html5lib", "pytest (>=4.6)"] +test = ["cython", "filelock", "html5lib", "pytest (>=4.6)"] [[package]] name = "sphinx-click" @@ -2278,7 +2291,7 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.46" +version = "1.4.47" description = "Database Abstraction Library" category = "main" optional = false @@ -2362,14 +2375,15 @@ Jinja2 = ">=2.0" [[package]] name = "synapseclient" -version = "2.7.0" +version = "2.7.1" description = "A client for Synapse, a collaborative compute space that allows scientists to share and analyze data together." category = "main" optional = false -python-versions = ">=3.7.*" +python-versions = ">=3.7" [package.dependencies] deprecated = ">=1.2.4,<2.0" +importlib-metadata = "<5.0" keyring = ">=15,<23.5" "keyrings.alt" = {version = "3.1", markers = "sys_platform == \"linux\""} requests = ">=2.22.0,<3.0" @@ -2377,13 +2391,13 @@ requests = ">=2.22.0,<3.0" [package.extras] boto3 = ["boto3 (>=1.7.0,<2.0)"] docs = ["sphinx (>=3.0,<4.0)", "sphinx-argparse (>=0.2,<0.3)"] -pandas = ["pandas (>=0.25.0,<2.0)"] +pandas = ["pandas (>=0.25.0,<1.5)"] pysftp = ["pysftp (>=0.2.8,<0.3)"] tests = ["flake8 (>=3.7.0,<4.0)", "pytest (>=5.0.0,<7.0)", "pytest-mock (>=3.0,<4.0)", "pytest-xdist[psutil] (>=2.2,<3.0.0)"] [[package]] name = "tenacity" -version = "8.2.1" +version = "8.2.2" description = "Retry code until it succeeds" category = "main" optional = false @@ -2442,11 +2456,11 @@ python-versions = ">=3.7" [[package]] name = "tomlkit" -version = "0.11.6" +version = "0.11.8" description = "Style preserving TOML library" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [[package]] name = "toolz" @@ -2458,19 +2472,19 @@ python-versions = ">=3.5" [[package]] name = "tornado" -version = "6.2" +version = "6.3.1" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "main" optional = false -python-versions = ">= 3.7" +python-versions = ">= 3.8" [[package]] name = "tqdm" -version = "4.64.1" +version = "4.65.0" description = "Fast, Extensible Progress Meter" category = "main" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +python-versions = ">=3.7" [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} @@ -2503,7 +2517,7 @@ python-versions = ">=3.7" [[package]] name = "tzdata" -version = "2022.7" +version = "2023.3" description = "Provider of IANA time zone data" category = "main" optional = false @@ -2511,19 +2525,18 @@ python-versions = ">=2" [[package]] name = "tzlocal" -version = "4.2" +version = "4.3" description = "tzinfo object for the local timezone" category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] -test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] +devenv = ["black", "check-manifest", "flake8", "pyroma", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3)", "zest.releaser"] [[package]] name = "uri-template" @@ -2546,7 +2559,7 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.14" +version = "1.26.15" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -2567,12 +2580,16 @@ python-versions = "*" [[package]] name = "webcolors" -version = "1.12" -description = "A library for working with color names and color values formats defined by HTML and CSS." +version = "1.13" +description = "A library for working with the color formats defined by HTML and CSS." category = "main" optional = false python-versions = ">=3.7" +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["pytest", "pytest-cov"] + [[package]] name = "webencodings" version = "0.5.1" @@ -2607,7 +2624,7 @@ watchdog = ["watchdog"] [[package]] name = "widgetsnbextension" -version = "4.0.5" +version = "4.0.7" description = "Jupyter interactive widgets for Jupyter Notebook" category = "main" optional = false @@ -2615,7 +2632,7 @@ python-versions = ">=3.7" [[package]] name = "wrapt" -version = "1.14.1" +version = "1.15.0" description = "Module for decorators, wrappers and monkey patching." category = "main" optional = false @@ -2623,7 +2640,7 @@ python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [[package]] name = "zipp" -version = "3.14.0" +version = "3.15.0" description = "Backport of pathlib-compatible object wrapper for zip files" category = "main" optional = false @@ -2631,12 +2648,12 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "2e8922a96ef8a1b786b1783705fcec76e70f6d39965388ccc6076046a022de0f" +content-hash = "3788ace046f8b51b9e0e14bf53dd8968d8f1f19910b9ff009252f6de9fc465ff" [metadata.files] alabaster = [ @@ -2687,28 +2704,28 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.14.2-py3-none-any.whl", hash = "sha256:0e0e3709d64fbffd3037e4ff403580550f14471fd3eaae9fa11cc9a5c7901153"}, - {file = "astroid-2.14.2.tar.gz", hash = "sha256:a3cf9f02c53dd259144a7e8f3ccd75d67c9a8c716ef183e0c1f291bc5d7bb3cf"}, + {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, + {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, {file = "asttokens-2.2.1.tar.gz", hash = "sha256:4622110b2a6f30b77e1473affaa97e711bc2f07d3f10848420ff1898edbe94f3"}, ] attrs = [ - {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, - {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, + {file = "attrs-23.1.0-py3-none-any.whl", hash = "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04"}, + {file = "attrs-23.1.0.tar.gz", hash = "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015"}, ] babel = [ - {file = "Babel-2.11.0-py3-none-any.whl", hash = "sha256:1ad3eca1c885218f6dce2ab67291178944f810a10a9b5f3cb8382a5a232b64fe"}, - {file = "Babel-2.11.0.tar.gz", hash = "sha256:5ef4b3226b0180dedded4229651c8b0e1a3a6a2837d45a073272f313e4cf97f6"}, + {file = "Babel-2.12.1-py3-none-any.whl", hash = "sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610"}, + {file = "Babel-2.12.1.tar.gz", hash = "sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455"}, ] backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] beautifulsoup4 = [ - {file = "beautifulsoup4-4.11.2-py3-none-any.whl", hash = "sha256:0e79446b10b3ecb499c1556f7e228a53e64a2bfcebd455f370d8927cb5b59e39"}, - {file = "beautifulsoup4-4.11.2.tar.gz", hash = "sha256:bc4bdda6717de5a2987436fb8d72f45dc90dd856bdfd512a1314ce90349a0106"}, + {file = "beautifulsoup4-4.12.2-py3-none-any.whl", hash = "sha256:bd2520ca0d9d7d12694a53d44ac482d181b4ec1888909b035a3dbf40d0f57d4a"}, + {file = "beautifulsoup4-4.12.2.tar.gz", hash = "sha256:492bbc69dca35d12daac71c4db1bfff0c876c00ef4a2ffacce226d4638eb72da"}, ] black = [ {file = "black-22.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9eedd20838bd5d75b80c9f5487dbcb06836a43833a37846cf1d8c1cc01cef59d"}, @@ -2803,94 +2820,81 @@ cffi = [ {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, ] charset-normalizer = [ - {file = "charset-normalizer-3.0.1.tar.gz", hash = "sha256:ebea339af930f8ca5d7a699b921106c6e29c617fe9606fa7baa043c1cdae326f"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:88600c72ef7587fe1708fd242b385b6ed4b8904976d5da0893e31df8b3480cb6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c75ffc45f25324e68ab238cb4b5c0a38cd1c3d7f1fb1f72b5541de469e2247db"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db72b07027db150f468fbada4d85b3b2729a3db39178abf5c543b784c1254539"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62595ab75873d50d57323a91dd03e6966eb79c41fa834b7a1661ed043b2d404d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff6f3db31555657f3163b15a6b7c6938d08df7adbfc9dd13d9d19edad678f1e8"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:772b87914ff1152b92a197ef4ea40efe27a378606c39446ded52c8f80f79702e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70990b9c51340e4044cfc394a81f614f3f90d41397104d226f21e66de668730d"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:292d5e8ba896bbfd6334b096e34bffb56161c81408d6d036a7dfa6929cff8783"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2edb64ee7bf1ed524a1da60cdcd2e1f6e2b4f66ef7c077680739f1641f62f555"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:31a9ddf4718d10ae04d9b18801bd776693487cbb57d74cc3458a7673f6f34639"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:44ba614de5361b3e5278e1241fda3dc1838deed864b50a10d7ce92983797fa76"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:12db3b2c533c23ab812c2b25934f60383361f8a376ae272665f8e48b88e8e1c6"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c512accbd6ff0270939b9ac214b84fb5ada5f0409c44298361b2f5e13f9aed9e"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win32.whl", hash = "sha256:502218f52498a36d6bf5ea77081844017bf7982cdbe521ad85e64cabee1b608b"}, - {file = "charset_normalizer-3.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:601f36512f9e28f029d9481bdaf8e89e5148ac5d89cffd3b05cd533eeb423b59"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0298eafff88c99982a4cf66ba2efa1128e4ddaca0b05eec4c456bbc7db691d8d"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8d0fc946c784ff7f7c3742310cc8a57c5c6dc31631269876a88b809dbeff3d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:87701167f2a5c930b403e9756fab1d31d4d4da52856143b609e30a1ce7160f3c"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14e76c0f23218b8f46c4d87018ca2e441535aed3632ca134b10239dfb6dadd6b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c0a590235ccd933d9892c627dec5bc7511ce6ad6c1011fdf5b11363022746c1"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c7fe7afa480e3e82eed58e0ca89f751cd14d767638e2550c77a92a9e749c317"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79909e27e8e4fcc9db4addea88aa63f6423ebb171db091fb4373e3312cb6d603"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ac7b6a045b814cf0c47f3623d21ebd88b3e8cf216a14790b455ea7ff0135d18"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:72966d1b297c741541ca8cf1223ff262a6febe52481af742036a0b296e35fa5a"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f9d0c5c045a3ca9bedfc35dca8526798eb91a07aa7a2c0fee134c6c6f321cbd7"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:5995f0164fa7df59db4746112fec3f49c461dd6b31b841873443bdb077c13cfc"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4a8fcf28c05c1f6d7e177a9a46a1c52798bfe2ad80681d275b10dcf317deaf0b"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:761e8904c07ad053d285670f36dd94e1b6ab7f16ce62b9805c475b7aa1cffde6"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win32.whl", hash = "sha256:71140351489970dfe5e60fc621ada3e0f41104a5eddaca47a7acb3c1b851d6d3"}, - {file = "charset_normalizer-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:9ab77acb98eba3fd2a85cd160851816bfce6871d944d885febf012713f06659c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:84c3990934bae40ea69a82034912ffe5a62c60bbf6ec5bc9691419641d7d5c9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74292fc76c905c0ef095fe11e188a32ebd03bc38f3f3e9bcb85e4e6db177b7ea"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c95a03c79bbe30eec3ec2b7f076074f4281526724c8685a42872974ef4d36b72"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c39b0e3eac288fedc2b43055cfc2ca7a60362d0e5e87a637beac5d801ef478"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2c707231459e8a4028eabcd3cfc827befd635b3ef72eada84ab13b52e1574d"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93ad6d87ac18e2a90b0fe89df7c65263b9a99a0eb98f0a3d2e079f12a0735837"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:59e5686dd847347e55dffcc191a96622f016bc0ad89105e24c14e0d6305acbc6"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:cd6056167405314a4dc3c173943f11249fa0f1b204f8b51ed4bde1a9cd1834dc"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:083c8d17153ecb403e5e1eb76a7ef4babfc2c48d58899c98fcaa04833e7a2f9a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:f5057856d21e7586765171eac8b9fc3f7d44ef39425f85dbcccb13b3ebea806c"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7eb33a30d75562222b64f569c642ff3dc6689e09adda43a082208397f016c39a"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win32.whl", hash = "sha256:95dea361dd73757c6f1c0a1480ac499952c16ac83f7f5f4f84f0658a01b8ef41"}, - {file = "charset_normalizer-3.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:eaa379fcd227ca235d04152ca6704c7cb55564116f8bc52545ff357628e10602"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3e45867f1f2ab0711d60c6c71746ac53537f1684baa699f4f668d4c6f6ce8e14"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cadaeaba78750d58d3cc6ac4d1fd867da6fc73c88156b7a3212a3cd4819d679d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:911d8a40b2bef5b8bbae2e36a0b103f142ac53557ab421dc16ac4aafee6f53dc"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:503e65837c71b875ecdd733877d852adbc465bd82c768a067badd953bf1bc5a3"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a60332922359f920193b1d4826953c507a877b523b2395ad7bc716ddd386d866"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16a8663d6e281208d78806dbe14ee9903715361cf81f6d4309944e4d1e59ac5b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:a16418ecf1329f71df119e8a65f3aa68004a3f9383821edcb20f0702934d8087"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9d9153257a3f70d5f69edf2325357251ed20f772b12e593f3b3377b5f78e7ef8"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:02a51034802cbf38db3f89c66fb5d2ec57e6fe7ef2f4a44d070a593c3688667b"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:2e396d70bc4ef5325b72b593a72c8979999aa52fb8bcf03f701c1b03e1166918"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:11b53acf2411c3b09e6af37e4b9005cba376c872503c8f28218c7243582df45d"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win32.whl", hash = "sha256:0bf2dae5291758b6f84cf923bfaa285632816007db0330002fa1de38bfcb7154"}, - {file = "charset_normalizer-3.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:2c03cc56021a4bd59be889c2b9257dae13bf55041a3372d3295416f86b295fb5"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:024e606be3ed92216e2b6952ed859d86b4cfa52cd5bc5f050e7dc28f9b43ec42"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4b0d02d7102dd0f997580b51edc4cebcf2ab6397a7edf89f1c73b586c614272c"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:358a7c4cb8ba9b46c453b1dd8d9e431452d5249072e4f56cfda3149f6ab1405e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81d6741ab457d14fdedc215516665050f3822d3e56508921cc7239f8c8e66a58"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8b8af03d2e37866d023ad0ddea594edefc31e827fee64f8de5611a1dbc373174"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9cf4e8ad252f7c38dd1f676b46514f92dc0ebeb0db5552f5f403509705e24753"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e696f0dd336161fca9adbb846875d40752e6eba585843c768935ba5c9960722b"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c22d3fe05ce11d3671297dc8973267daa0f938b93ec716e12e0f6dee81591dc1"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:109487860ef6a328f3eec66f2bf78b0b72400280d8f8ea05f69c51644ba6521a"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:37f8febc8ec50c14f3ec9637505f28e58d4f66752207ea177c1d67df25da5aed"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:f97e83fa6c25693c7a35de154681fcc257c1c41b38beb0304b9c4d2d9e164479"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a152f5f33d64a6be73f1d30c9cc82dfc73cec6477ec268e7c6e4c7d23c2d2291"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:39049da0ffb96c8cbb65cbf5c5f3ca3168990adf3551bd1dee10c48fce8ae820"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win32.whl", hash = "sha256:4457ea6774b5611f4bed5eaa5df55f70abde42364d498c5134b7ef4c6958e20e"}, - {file = "charset_normalizer-3.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:e62164b50f84e20601c1ff8eb55620d2ad25fb81b59e3cd776a1902527a788af"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8eade758719add78ec36dc13201483f8e9b5d940329285edcd5f70c0a9edbd7f"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8499ca8f4502af841f68135133d8258f7b32a53a1d594aa98cc52013fff55678"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3fc1c4a2ffd64890aebdb3f97e1278b0cc72579a08ca4de8cd2c04799a3a22be"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:00d3ffdaafe92a5dc603cb9bd5111aaa36dfa187c8285c543be562e61b755f6b"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2ac1b08635a8cd4e0cbeaf6f5e922085908d48eb05d44c5ae9eabab148512ca"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f6f45710b4459401609ebebdbcfb34515da4fc2aa886f95107f556ac69a9147e"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ae1de54a77dc0d6d5fcf623290af4266412a7c4be0b1ff7444394f03f5c54e3"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3b590df687e3c5ee0deef9fc8c547d81986d9a1b56073d82de008744452d6541"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab5de034a886f616a5668aa5d098af2b5385ed70142090e2a31bcbd0af0fdb3d"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9cb3032517f1627cc012dbc80a8ec976ae76d93ea2b5feaa9d2a5b8882597579"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:608862a7bf6957f2333fc54ab4399e405baad0163dc9f8d99cb236816db169d4"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0f438ae3532723fb6ead77e7c604be7c8374094ef4ee2c5e03a3a17f1fca256c"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:356541bf4381fa35856dafa6a965916e54bed415ad8a24ee6de6e37deccf2786"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win32.whl", hash = "sha256:39cf9ed17fe3b1bc81f33c9ceb6ce67683ee7526e65fde1447c772afc54a1bb8"}, - {file = "charset_normalizer-3.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:0a11e971ed097d24c534c037d298ad32c6ce81a45736d31e0ff0ad37ab437d59"}, - {file = "charset_normalizer-3.0.1-py3-none-any.whl", hash = "sha256:7e189e2e1d3ed2f4aebabd2d5b0f931e883676e51c7624826e0a4e5fe8a0bf24"}, + {file = "charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {file = "charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {file = "charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {file = "charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {file = "charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {file = "charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {file = "charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, ] click = [ {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, @@ -2909,113 +2913,110 @@ colorama = [ {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] comm = [ - {file = "comm-0.1.2-py3-none-any.whl", hash = "sha256:9f3abf3515112fa7c55a42a6a5ab358735c9dccc8b5910a9d8e3ef5998130666"}, - {file = "comm-0.1.2.tar.gz", hash = "sha256:3e2f5826578e683999b93716285b3b1f344f157bf75fa9ce0a797564e742f062"}, + {file = "comm-0.1.3-py3-none-any.whl", hash = "sha256:16613c6211e20223f215fc6d3b266a247b6e2641bf4e0a3ad34cb1aff2aa3f37"}, + {file = "comm-0.1.3.tar.gz", hash = "sha256:a61efa9daffcfbe66fd643ba966f846a624e4e6d6767eda9cf6e993aadaab93e"}, ] connexion = [ {file = "connexion-2.14.2-py2.py3-none-any.whl", hash = "sha256:a73b96a0e07b16979a42cde7c7e26afe8548099e352cf350f80c57185e0e0b36"}, {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3b946bbcd5a8231383450b195cfb58cb01cbe7f8949f5758566b881df4b33baf"}, - {file = "coverage-7.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ec8e767f13be637d056f7e07e61d089e555f719b387a7070154ad80a0ff31801"}, - {file = "coverage-7.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4a5a5879a939cb84959d86869132b00176197ca561c664fc21478c1eee60d75"}, - {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b643cb30821e7570c0aaf54feaf0bfb630b79059f85741843e9dc23f33aaca2c"}, - {file = "coverage-7.1.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32df215215f3af2c1617a55dbdfb403b772d463d54d219985ac7cd3bf124cada"}, - {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:33d1ae9d4079e05ac4cc1ef9e20c648f5afabf1a92adfaf2ccf509c50b85717f"}, - {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:29571503c37f2ef2138a306d23e7270687c0efb9cab4bd8038d609b5c2393a3a"}, - {file = "coverage-7.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:63ffd21aa133ff48c4dff7adcc46b7ec8b565491bfc371212122dd999812ea1c"}, - {file = "coverage-7.1.0-cp310-cp310-win32.whl", hash = "sha256:4b14d5e09c656de5038a3f9bfe5228f53439282abcab87317c9f7f1acb280352"}, - {file = "coverage-7.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:8361be1c2c073919500b6601220a6f2f98ea0b6d2fec5014c1d9cfa23dd07038"}, - {file = "coverage-7.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:da9b41d4539eefd408c46725fb76ecba3a50a3367cafb7dea5f250d0653c1040"}, - {file = "coverage-7.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c5b15ed7644ae4bee0ecf74fee95808dcc34ba6ace87e8dfbf5cb0dc20eab45a"}, - {file = "coverage-7.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d12d076582507ea460ea2a89a8c85cb558f83406c8a41dd641d7be9a32e1274f"}, - {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2617759031dae1bf183c16cef8fcfb3de7617f394c813fa5e8e46e9b82d4222"}, - {file = "coverage-7.1.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4e4881fa9e9667afcc742f0c244d9364d197490fbc91d12ac3b5de0bf2df146"}, - {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9d58885215094ab4a86a6aef044e42994a2bd76a446dc59b352622655ba6621b"}, - {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:ffeeb38ee4a80a30a6877c5c4c359e5498eec095878f1581453202bfacc8fbc2"}, - {file = "coverage-7.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3baf5f126f30781b5e93dbefcc8271cb2491647f8283f20ac54d12161dff080e"}, - {file = "coverage-7.1.0-cp311-cp311-win32.whl", hash = "sha256:ded59300d6330be27bc6cf0b74b89ada58069ced87c48eaf9344e5e84b0072f7"}, - {file = "coverage-7.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:6a43c7823cd7427b4ed763aa7fb63901ca8288591323b58c9cd6ec31ad910f3c"}, - {file = "coverage-7.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a726d742816cb3a8973c8c9a97539c734b3a309345236cd533c4883dda05b8d"}, - {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc7c85a150501286f8b56bd8ed3aa4093f4b88fb68c0843d21ff9656f0009d6a"}, - {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b4198d85a3755d27e64c52f8c95d6333119e49fd001ae5798dac872c95e0f8"}, - {file = "coverage-7.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb726cb861c3117a553f940372a495fe1078249ff5f8a5478c0576c7be12050"}, - {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:51b236e764840a6df0661b67e50697aaa0e7d4124ca95e5058fa3d7cbc240b7c"}, - {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:7ee5c9bb51695f80878faaa5598040dd6c9e172ddcf490382e8aedb8ec3fec8d"}, - {file = "coverage-7.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c31b75ae466c053a98bf26843563b3b3517b8f37da4d47b1c582fdc703112bc3"}, - {file = "coverage-7.1.0-cp37-cp37m-win32.whl", hash = "sha256:3b155caf3760408d1cb903b21e6a97ad4e2bdad43cbc265e3ce0afb8e0057e73"}, - {file = "coverage-7.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2a60d6513781e87047c3e630b33b4d1e89f39836dac6e069ffee28c4786715f5"}, - {file = "coverage-7.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f2cba5c6db29ce991029b5e4ac51eb36774458f0a3b8d3137241b32d1bb91f06"}, - {file = "coverage-7.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beeb129cacea34490ffd4d6153af70509aa3cda20fdda2ea1a2be870dfec8d52"}, - {file = "coverage-7.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c45948f613d5d18c9ec5eaa203ce06a653334cf1bd47c783a12d0dd4fd9c851"}, - {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef382417db92ba23dfb5864a3fc9be27ea4894e86620d342a116b243ade5d35d"}, - {file = "coverage-7.1.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c7c0d0827e853315c9bbd43c1162c006dd808dbbe297db7ae66cd17b07830f0"}, - {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5cdbb5cafcedea04924568d990e20ce7f1945a1dd54b560f879ee2d57226912"}, - {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:9817733f0d3ea91bea80de0f79ef971ae94f81ca52f9b66500c6a2fea8e4b4f8"}, - {file = "coverage-7.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:218fe982371ac7387304153ecd51205f14e9d731b34fb0568181abaf7b443ba0"}, - {file = "coverage-7.1.0-cp38-cp38-win32.whl", hash = "sha256:04481245ef966fbd24ae9b9e537ce899ae584d521dfbe78f89cad003c38ca2ab"}, - {file = "coverage-7.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:8ae125d1134bf236acba8b83e74c603d1b30e207266121e76484562bc816344c"}, - {file = "coverage-7.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2bf1d5f2084c3932b56b962a683074a3692bce7cabd3aa023c987a2a8e7612f6"}, - {file = "coverage-7.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:98b85dd86514d889a2e3dd22ab3c18c9d0019e696478391d86708b805f4ea0fa"}, - {file = "coverage-7.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38da2db80cc505a611938d8624801158e409928b136c8916cd2e203970dde4dc"}, - {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3164d31078fa9efe406e198aecd2a02d32a62fecbdef74f76dad6a46c7e48311"}, - {file = "coverage-7.1.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db61a79c07331e88b9a9974815c075fbd812bc9dbc4dc44b366b5368a2936063"}, - {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ccb092c9ede70b2517a57382a601619d20981f56f440eae7e4d7eaafd1d1d09"}, - {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:33ff26d0f6cc3ca8de13d14fde1ff8efe1456b53e3f0273e63cc8b3c84a063d8"}, - {file = "coverage-7.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d47dd659a4ee952e90dc56c97d78132573dc5c7b09d61b416a9deef4ebe01a0c"}, - {file = "coverage-7.1.0-cp39-cp39-win32.whl", hash = "sha256:d248cd4a92065a4d4543b8331660121b31c4148dd00a691bfb7a5cdc7483cfa4"}, - {file = "coverage-7.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:7ed681b0f8e8bcbbffa58ba26fcf5dbc8f79e7997595bf071ed5430d8c08d6f3"}, - {file = "coverage-7.1.0-pp37.pp38.pp39-none-any.whl", hash = "sha256:755e89e32376c850f826c425ece2c35a4fc266c081490eb0a841e7c1cb0d3bda"}, - {file = "coverage-7.1.0.tar.gz", hash = "sha256:10188fe543560ec4874f974b5305cd1a8bdcfa885ee00ea3a03733464c4ca265"}, + {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"}, + {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"}, + {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"}, + {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"}, + {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"}, + {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"}, + {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"}, + {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"}, + {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"}, + {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"}, + {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"}, + {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"}, + {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"}, + {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"}, + {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"}, + {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"}, + {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"}, + {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"}, + {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"}, + {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"}, + {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"}, + {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"}, + {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"}, + {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"}, + {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"}, + {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"}, + {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"}, + {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"}, + {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"}, + {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"}, + {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"}, ] cryptography = [ - {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:6687ef6d0a6497e2b58e7c5b852b53f62142cfa7cd1555795758934da363a965"}, - {file = "cryptography-39.0.1-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:706843b48f9a3f9b9911979761c91541e3d90db1ca905fd63fee540a217698bc"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:5d2d8b87a490bfcd407ed9d49093793d0f75198a35e6eb1a923ce1ee86c62b41"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83e17b26de248c33f3acffb922748151d71827d6021d98c70e6c1a25ddd78505"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e124352fd3db36a9d4a21c1aa27fd5d051e621845cb87fb851c08f4f75ce8be6"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_24_x86_64.whl", hash = "sha256:5aa67414fcdfa22cf052e640cb5ddc461924a045cacf325cd164e65312d99502"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:35f7c7d015d474f4011e859e93e789c87d21f6f4880ebdc29896a60403328f1f"}, - {file = "cryptography-39.0.1-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f24077a3b5298a5a06a8e0536e3ea9ec60e4c7ac486755e5fb6e6ea9b3500106"}, - {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:f0c64d1bd842ca2633e74a1a28033d139368ad959872533b1bab8c80e8240a0c"}, - {file = "cryptography-39.0.1-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:0f8da300b5c8af9f98111ffd512910bc792b4c77392a9523624680f7956a99d4"}, - {file = "cryptography-39.0.1-cp36-abi3-win32.whl", hash = "sha256:fe913f20024eb2cb2f323e42a64bdf2911bb9738a15dba7d3cce48151034e3a8"}, - {file = "cryptography-39.0.1-cp36-abi3-win_amd64.whl", hash = "sha256:ced4e447ae29ca194449a3f1ce132ded8fcab06971ef5f618605aacaa612beac"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:807ce09d4434881ca3a7594733669bd834f5b2c6d5c7e36f8c00f691887042ad"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c5caeb8188c24888c90b5108a441c106f7faa4c4c075a2bcae438c6e8ca73cef"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4789d1e3e257965e960232345002262ede4d094d1a19f4d3b52e48d4d8f3b885"}, - {file = "cryptography-39.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:96f1157a7c08b5b189b16b47bc9db2332269d6680a196341bf30046330d15388"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:e422abdec8b5fa8462aa016786680720d78bdce7a30c652b7fadf83a4ba35336"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:b0afd054cd42f3d213bf82c629efb1ee5f22eba35bf0eec88ea9ea7304f511a2"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_24_x86_64.whl", hash = "sha256:6f8ba7f0328b79f08bdacc3e4e66fb4d7aab0c3584e0bd41328dce5262e26b2e"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ef8b72fa70b348724ff1218267e7f7375b8de4e8194d1636ee60510aae104cd0"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:aec5a6c9864be7df2240c382740fcf3b96928c46604eaa7f3091f58b878c0bb6"}, - {file = "cryptography-39.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:fdd188c8a6ef8769f148f88f859884507b954cc64db6b52f66ef199bb9ad660a"}, - {file = "cryptography-39.0.1.tar.gz", hash = "sha256:d1f6198ee6d9148405e49887803907fe8962a23e6c6f83ea7d98f1c0de375695"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, + {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, + {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, + {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, ] dateparser = [ - {file = "dateparser-1.1.7-py2.py3-none-any.whl", hash = "sha256:fbed8b738a24c9cd7f47c4f2089527926566fe539e1a06125eddba75917b1eef"}, - {file = "dateparser-1.1.7.tar.gz", hash = "sha256:ff047d9cffad4d3113ead8ec0faf8a7fc43bab7d853ac8715e071312b53c465a"}, + {file = "dateparser-1.1.8-py2.py3-none-any.whl", hash = "sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f"}, + {file = "dateparser-1.1.8.tar.gz", hash = "sha256:86b8b7517efcc558f085a142cdb7620f0921543fcabdb538c8a4c4001d8178e3"}, ] debugpy = [ - {file = "debugpy-1.6.6-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:0ea1011e94416e90fb3598cc3ef5e08b0a4dd6ce6b9b33ccd436c1dffc8cd664"}, - {file = "debugpy-1.6.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dff595686178b0e75580c24d316aa45a8f4d56e2418063865c114eef651a982e"}, - {file = "debugpy-1.6.6-cp310-cp310-win32.whl", hash = "sha256:87755e173fcf2ec45f584bb9d61aa7686bb665d861b81faa366d59808bbd3494"}, - {file = "debugpy-1.6.6-cp310-cp310-win_amd64.whl", hash = "sha256:72687b62a54d9d9e3fb85e7a37ea67f0e803aaa31be700e61d2f3742a5683917"}, - {file = "debugpy-1.6.6-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:78739f77c58048ec006e2b3eb2e0cd5a06d5f48c915e2fc7911a337354508110"}, - {file = "debugpy-1.6.6-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23c29e40e39ad7d869d408ded414f6d46d82f8a93b5857ac3ac1e915893139ca"}, - {file = "debugpy-1.6.6-cp37-cp37m-win32.whl", hash = "sha256:7aa7e103610e5867d19a7d069e02e72eb2b3045b124d051cfd1538f1d8832d1b"}, - {file = "debugpy-1.6.6-cp37-cp37m-win_amd64.whl", hash = "sha256:f6383c29e796203a0bba74a250615ad262c4279d398e89d895a69d3069498305"}, - {file = "debugpy-1.6.6-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:23363e6d2a04d726bbc1400bd4e9898d54419b36b2cdf7020e3e215e1dcd0f8e"}, - {file = "debugpy-1.6.6-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b5d1b13d7c7bf5d7cf700e33c0b8ddb7baf030fcf502f76fc061ddd9405d16c"}, - {file = "debugpy-1.6.6-cp38-cp38-win32.whl", hash = "sha256:70ab53918fd907a3ade01909b3ed783287ede362c80c75f41e79596d5ccacd32"}, - {file = "debugpy-1.6.6-cp38-cp38-win_amd64.whl", hash = "sha256:c05349890804d846eca32ce0623ab66c06f8800db881af7a876dc073ac1c2225"}, - {file = "debugpy-1.6.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771739902b1ae22a120dbbb6bd91b2cae6696c0e318b5007c5348519a4211c6"}, - {file = "debugpy-1.6.6-cp39-cp39-win32.whl", hash = "sha256:549ae0cb2d34fc09d1675f9b01942499751d174381b6082279cf19cdb3c47cbe"}, - {file = "debugpy-1.6.6-cp39-cp39-win_amd64.whl", hash = "sha256:de4a045fbf388e120bb6ec66501458d3134f4729faed26ff95de52a754abddb1"}, - {file = "debugpy-1.6.6-py2.py3-none-any.whl", hash = "sha256:be596b44448aac14eb3614248c91586e2bc1728e020e82ef3197189aae556115"}, - {file = "debugpy-1.6.6.zip", hash = "sha256:b9c2130e1c632540fbf9c2c88341493797ddf58016e7cba02e311de9b0a96b67"}, + {file = "debugpy-1.6.7-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b3e7ac809b991006ad7f857f016fa92014445085711ef111fdc3f74f66144096"}, + {file = "debugpy-1.6.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3876611d114a18aafef6383695dfc3f1217c98a9168c1aaf1a02b01ec7d8d1e"}, + {file = "debugpy-1.6.7-cp310-cp310-win32.whl", hash = "sha256:33edb4afa85c098c24cc361d72ba7c21bb92f501104514d4ffec1fb36e09c01a"}, + {file = "debugpy-1.6.7-cp310-cp310-win_amd64.whl", hash = "sha256:ed6d5413474e209ba50b1a75b2d9eecf64d41e6e4501977991cdc755dc83ab0f"}, + {file = "debugpy-1.6.7-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:38ed626353e7c63f4b11efad659be04c23de2b0d15efff77b60e4740ea685d07"}, + {file = "debugpy-1.6.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:279d64c408c60431c8ee832dfd9ace7c396984fd7341fa3116aee414e7dcd88d"}, + {file = "debugpy-1.6.7-cp37-cp37m-win32.whl", hash = "sha256:dbe04e7568aa69361a5b4c47b4493d5680bfa3a911d1e105fbea1b1f23f3eb45"}, + {file = "debugpy-1.6.7-cp37-cp37m-win_amd64.whl", hash = "sha256:f90a2d4ad9a035cee7331c06a4cf2245e38bd7c89554fe3b616d90ab8aab89cc"}, + {file = "debugpy-1.6.7-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:5224eabbbeddcf1943d4e2821876f3e5d7d383f27390b82da5d9558fd4eb30a9"}, + {file = "debugpy-1.6.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae1123dff5bfe548ba1683eb972329ba6d646c3a80e6b4c06cd1b1dd0205e9b"}, + {file = "debugpy-1.6.7-cp38-cp38-win32.whl", hash = "sha256:9cd10cf338e0907fdcf9eac9087faa30f150ef5445af5a545d307055141dd7a4"}, + {file = "debugpy-1.6.7-cp38-cp38-win_amd64.whl", hash = "sha256:aaf6da50377ff4056c8ed470da24632b42e4087bc826845daad7af211e00faad"}, + {file = "debugpy-1.6.7-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:0679b7e1e3523bd7d7869447ec67b59728675aadfc038550a63a362b63029d2c"}, + {file = "debugpy-1.6.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de86029696e1b3b4d0d49076b9eba606c226e33ae312a57a46dca14ff370894d"}, + {file = "debugpy-1.6.7-cp39-cp39-win32.whl", hash = "sha256:d71b31117779d9a90b745720c0eab54ae1da76d5b38c8026c654f4a066b0130a"}, + {file = "debugpy-1.6.7-cp39-cp39-win_amd64.whl", hash = "sha256:c0ff93ae90a03b06d85b2c529eca51ab15457868a377c4cc40a23ab0e4e552a3"}, + {file = "debugpy-1.6.7-py2.py3-none-any.whl", hash = "sha256:53f7a456bc50706a0eaabecf2d3ce44c4d5010e46dfc65b6b81a518b42866267"}, + {file = "debugpy-1.6.7.zip", hash = "sha256:c4c2f0810fa25323abfdfa36cbbbb24e5c3b1a42cb762782de64439c575d67f2"}, ] decorator = [ {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, @@ -3046,16 +3047,16 @@ et-xmlfile = [ {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"}, ] exceptiongroup = [ - {file = "exceptiongroup-1.1.0-py3-none-any.whl", hash = "sha256:327cbda3da756e2de031a3107b81ab7b3770a602c4d16ca618298c526f4bec1e"}, - {file = "exceptiongroup-1.1.0.tar.gz", hash = "sha256:bcb67d800a4497e1b404c2dd44fca47d3b7a5e5433dbab67f96c1a685cdfdf23"}, + {file = "exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {file = "exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, ] executing = [ {file = "executing-1.2.0-py2.py3-none-any.whl", hash = "sha256:0314a69e37426e3608aada02473b4161d4caf5a4b244d1d0c48072b8fee7bacc"}, {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, ] fastjsonschema = [ - {file = "fastjsonschema-2.16.2-py3-none-any.whl", hash = "sha256:21f918e8d9a1a4ba9c22e09574ba72267a6762d47822db9add95f6454e51cc1c"}, - {file = "fastjsonschema-2.16.2.tar.gz", hash = "sha256:01e366f25d9047816fe3d288cbfc3e10541daf0af2044763f3d0ade42476da18"}, + {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, + {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, ] flake8 = [ {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, @@ -3078,12 +3079,12 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.78.0.tar.gz", hash = "sha256:32d56a7522a338e525b9c664773230fc8ce382204d4b690eec67a3f8d55d9d63"}, - {file = "google_api_python_client-2.78.0-py2.py3-none-any.whl", hash = "sha256:34a7b73048d7573e99130ebba0a390929382690adccf605b188e74585fc94ea6"}, + {file = "google-api-python-client-2.86.0.tar.gz", hash = "sha256:3ca4e93821f4e9ac29b91ab0d9df168b42c8ad0fb8bff65b8c2ccb2d462b0464"}, + {file = "google_api_python_client-2.86.0-py2.py3-none-any.whl", hash = "sha256:0f320190ab9d5bd2fdb0cb894e8e53bb5e17d4888ee8dc4d26ba65ce378409e2"}, ] google-auth = [ - {file = "google-auth-2.16.1.tar.gz", hash = "sha256:5fd170986bce6bfd7bb5c845c4b8362edb1e0cba901e062196e83f8bb5d5d32c"}, - {file = "google_auth-2.16.1-py2.py3-none-any.whl", hash = "sha256:75d76ea857df65938e1f71dcbcd7d0cd48e3f80b34b8870ba229c9292081f7ef"}, + {file = "google-auth-2.17.3.tar.gz", hash = "sha256:ce311e2bc58b130fddf316df57c9b3943c2a7b4f6ec31de9663a9333e4064efc"}, + {file = "google_auth-2.17.3-py2.py3-none-any.whl", hash = "sha256:f586b274d3eb7bd932ea424b1c702a30e0393a2e2bc4ca3eae8263ffd8be229f"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -3094,16 +3095,16 @@ google-auth-oauthlib = [ {file = "google_auth_oauthlib-0.8.0-py2.py3-none-any.whl", hash = "sha256:40cc612a13c3336d5433e94e2adb42a0c88f6feb6c55769e44500fc70043a576"}, ] googleapis-common-protos = [ - {file = "googleapis-common-protos-1.58.0.tar.gz", hash = "sha256:c727251ec025947d545184ba17e3578840fc3a24a0516a020479edab660457df"}, - {file = "googleapis_common_protos-1.58.0-py2.py3-none-any.whl", hash = "sha256:ca3befcd4580dab6ad49356b46bf165bb68ff4b32389f028f1abd7c10ab9519a"}, + {file = "googleapis-common-protos-1.59.0.tar.gz", hash = "sha256:4168fcb568a826a52f23510412da405abd93f4d23ba544bb68d943b14ba3cb44"}, + {file = "googleapis_common_protos-1.59.0-py2.py3-none-any.whl", hash = "sha256:b287dc48449d1d41af0c69f4ea26242b5ae4c3d7249a38b0984c86a4caffff1f"}, ] graphviz = [ {file = "graphviz-0.20.1-py3-none-any.whl", hash = "sha256:587c58a223b51611c0cf461132da386edd896a029524ca61a1462b880bf97977"}, {file = "graphviz-0.20.1.zip", hash = "sha256:8c58f14adaa3b947daf26c19bc1e98c4e0702cdc31cf99153e6f06904d492bf8"}, ] great-expectations = [ - {file = "great_expectations-0.15.49-py3-none-any.whl", hash = "sha256:0fcdc81a9488e3f7a9bc9e219dcfa0fc0bd20f5f0398dfde47d2f26d269744e3"}, - {file = "great_expectations-0.15.49.tar.gz", hash = "sha256:66445c4e83e8863ec7b31aa906bd7b33e3c20e80ec76e6a57ef90d419e0fa3b4"}, + {file = "great_expectations-0.15.50-py3-none-any.whl", hash = "sha256:bda4c6bfe199dc0610273a1c160aab3876583266b1957a34a7edb72b055fd13d"}, + {file = "great_expectations-0.15.50.tar.gz", hash = "sha256:0b00c974410d598a97b4c662d7955d80d6268e35c5f3893ddb546f75432412db"}, ] greenlet = [ {file = "greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, @@ -3168,8 +3169,8 @@ greenlet = [ {file = "greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, ] httplib2 = [ - {file = "httplib2-0.21.0-py3-none-any.whl", hash = "sha256:987c8bb3eb82d3fa60c68699510a692aa2ad9c4bd4f123e51dfb1488c14cdd01"}, - {file = "httplib2-0.21.0.tar.gz", hash = "sha256:fc144f091c7286b82bec71bdbd9b27323ba709cc612568d3000893bfd9cb4b34"}, + {file = "httplib2-0.22.0-py3-none-any.whl", hash = "sha256:14ae0a53c1ba8f3d37e9e27cf37eabb0fb9980f435ba405d546948b009dd64dc"}, + {file = "httplib2-0.22.0.tar.gz", hash = "sha256:d7a10bc5ef5ab08322488bde8c726eeee5c8618723fdb399597ec58f3d82df81"}, ] idna = [ {file = "idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, @@ -3180,8 +3181,8 @@ imagesize = [ {file = "imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a"}, ] importlib-metadata = [ - {file = "importlib_metadata-6.0.0-py3-none-any.whl", hash = "sha256:7efb448ec9a5e313a57655d35aa54cd3e01b7e1fbcf72dce1bf06119420f5bad"}, - {file = "importlib_metadata-6.0.0.tar.gz", hash = "sha256:e354bedeb60efa6affdcc8ae121b73544a7aa74156d047311948f6d711cd378d"}, + {file = "importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, + {file = "importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, ] inflection = [ {file = "inflection-0.5.1-py2.py3-none-any.whl", hash = "sha256:f38b2b640938a4f35ade69ac3d053042959b62a0f1076a5bbaa1b9526605a8a2"}, @@ -3192,20 +3193,20 @@ iniconfig = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.21.2-py3-none-any.whl", hash = "sha256:430d00549b6aaf49bd0f5393150691edb1815afa62d457ee6b1a66b25cb17874"}, - {file = "ipykernel-6.21.2.tar.gz", hash = "sha256:6e9213484e4ce1fb14267ee435e18f23cc3a0634e635b9fb4ed4677b84e0fdf8"}, + {file = "ipykernel-6.22.0-py3-none-any.whl", hash = "sha256:1ae6047c1277508933078163721bbb479c3e7292778a04b4bacf0874550977d6"}, + {file = "ipykernel-6.22.0.tar.gz", hash = "sha256:302558b81f1bc22dc259fb2a0c5c7cf2f4c0bdb21b50484348f7bafe7fb71421"}, ] ipython = [ - {file = "ipython-8.10.0-py3-none-any.whl", hash = "sha256:b38c31e8fc7eff642fc7c597061fff462537cf2314e3225a19c906b7b0d8a345"}, - {file = "ipython-8.10.0.tar.gz", hash = "sha256:b13a1d6c1f5818bd388db53b7107d17454129a70de2b87481d555daede5eb49e"}, + {file = "ipython-8.12.0-py3-none-any.whl", hash = "sha256:1c183bf61b148b00bcebfa5d9b39312733ae97f6dad90d7e9b4d86c8647f498c"}, + {file = "ipython-8.12.0.tar.gz", hash = "sha256:a950236df04ad75b5bc7f816f9af3d74dc118fd42f2ff7e80e8e60ca1f182e2d"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, ] ipywidgets = [ - {file = "ipywidgets-8.0.4-py3-none-any.whl", hash = "sha256:ebb195e743b16c3947fe8827190fb87b4d00979c0fbf685afe4d2c4927059fa1"}, - {file = "ipywidgets-8.0.4.tar.gz", hash = "sha256:c0005a77a47d77889cafed892b58e33b4a2a96712154404c6548ec22272811ea"}, + {file = "ipywidgets-8.0.6-py3-none-any.whl", hash = "sha256:a60bf8d2528997e05ac83fd19ea2fbe65f2e79fbe1b2b35779bdfc46c2941dcc"}, + {file = "ipywidgets-8.0.6.tar.gz", hash = "sha256:de7d779f2045d60de9f6c25f653fdae2dba57898e6a1284494b3ba20b6893bb8"}, ] isodate = [ {file = "isodate-0.6.1-py2.py3-none-any.whl", hash = "sha256:0751eece944162659049d35f4f549ed815792b38793f07cf73381c1c87cbed96"}, @@ -3248,20 +3249,20 @@ jsonschema = [ {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, ] jupyter-client = [ - {file = "jupyter_client-8.0.3-py3-none-any.whl", hash = "sha256:be48ac6bd659cbbddb7a674cf06b3b8afbf53f228253cf58bde604c03bd487b0"}, - {file = "jupyter_client-8.0.3.tar.gz", hash = "sha256:ed65498bea6d876ef9d8da3e0db3dd33c5d129f5b2645f56ae03993782966bd0"}, + {file = "jupyter_client-8.2.0-py3-none-any.whl", hash = "sha256:b18219aa695d39e2ad570533e0d71fb7881d35a873051054a84ee2a17c4b7389"}, + {file = "jupyter_client-8.2.0.tar.gz", hash = "sha256:9fe233834edd0e6c0aa5f05ca2ab4bdea1842bfd2d8a932878212fc5301ddaf0"}, ] jupyter-core = [ - {file = "jupyter_core-5.2.0-py3-none-any.whl", hash = "sha256:4bdc2928c37f6917130c667d8b8708f20aee539d8283c6be72aabd2a4b4c83b0"}, - {file = "jupyter_core-5.2.0.tar.gz", hash = "sha256:1407cdb4c79ee467696c04b76633fc1884015fa109323365a6372c8e890cc83f"}, + {file = "jupyter_core-5.3.0-py3-none-any.whl", hash = "sha256:d4201af84559bc8c70cead287e1ab94aeef3c512848dde077b7684b54d67730d"}, + {file = "jupyter_core-5.3.0.tar.gz", hash = "sha256:6db75be0c83edbf1b7c9f91ec266a9a24ef945da630f3120e1a0046dc13713fc"}, ] jupyter-events = [ {file = "jupyter_events-0.6.3-py3-none-any.whl", hash = "sha256:57a2749f87ba387cd1bfd9b22a0875b889237dbf2edc2121ebb22bde47036c17"}, {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, ] jupyter-server = [ - {file = "jupyter_server-2.3.0-py3-none-any.whl", hash = "sha256:b15078954120886d580e19d1746e2b62a3dc7bd082cb4716115c25fcd7061b00"}, - {file = "jupyter_server-2.3.0.tar.gz", hash = "sha256:29d6657bfb160b0e39b9030d67f33f918a188f2eba28065314a933b327fef872"}, + {file = "jupyter_server-2.5.0-py3-none-any.whl", hash = "sha256:e6bc1e9e96d7c55b9ce9699ff6cb9a910581fe7349e27c40389acb67632e24c0"}, + {file = "jupyter_server-2.5.0.tar.gz", hash = "sha256:9fde612791f716fd34d610cd939704a9639643744751ba66e7ee8fdc9cead07e"}, ] jupyter-server-terminals = [ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, @@ -3272,8 +3273,8 @@ jupyterlab-pygments = [ {file = "jupyterlab_pygments-0.2.2.tar.gz", hash = "sha256:7405d7fde60819d905a9fa8ce89e4cd830e318cdad22a0030f7a901da705585d"}, ] jupyterlab-widgets = [ - {file = "jupyterlab_widgets-3.0.5-py3-none-any.whl", hash = "sha256:a04a42e50231b355b7087e16a818f541e53589f7647144ea0344c4bf16f300e5"}, - {file = "jupyterlab_widgets-3.0.5.tar.gz", hash = "sha256:eeaecdeaf6c03afc960ddae201ced88d5979b4ca9c3891bcb8f6631af705f5ef"}, + {file = "jupyterlab_widgets-3.0.7-py3-none-any.whl", hash = "sha256:c73f8370338ec19f1bec47254752d6505b03601cbd5a67e6a0b184532f73a459"}, + {file = "jupyterlab_widgets-3.0.7.tar.gz", hash = "sha256:c3a50ed5bf528a0c7a869096503af54702f86dda1db469aee1c92dc0c01b43ca"}, ] keyring = [ {file = "keyring-23.4.1-py3-none-any.whl", hash = "sha256:17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca"}, @@ -3322,8 +3323,8 @@ lazy-object-proxy = [ {file = "lazy_object_proxy-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:db1c1722726f47e10e0b5fdbf15ac3b8adb58c091d12b3ab713965795036985f"}, ] makefun = [ - {file = "makefun-1.15.0-py2.py3-none-any.whl", hash = "sha256:d79319f9e71b6825ca163be0afa45cbc5b1215e682efa35b2d355a03c594279c"}, - {file = "makefun-1.15.0.tar.gz", hash = "sha256:5b110e733d94f7a49d8ac27b1e2d40f2bb0501e98c1d825e0d932d26920dd5df"}, + {file = "makefun-1.15.1-py2.py3-none-any.whl", hash = "sha256:a63cfc7b47a539c76d97bd4fdb833c7d0461e759fd1225f580cb4be6200294d4"}, + {file = "makefun-1.15.1.tar.gz", hash = "sha256:40b0f118b6ded0d8d78c78f1eb679b8b6b2462e3c1b3e05fb1b2da8cd46b48a5"}, ] markupsafe = [ {file = "MarkupSafe-2.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3028252424c72b2602a323f70fbf50aa80a5d3aa616ea6add4ba21ae9cc9da4c"}, @@ -3414,20 +3415,20 @@ mypy-extensions = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] nbclassic = [ - {file = "nbclassic-0.5.2-py3-none-any.whl", hash = "sha256:6403a996562dadefa7fee9c49e17b663b5fd508241de5df655b90011cf3342d9"}, - {file = "nbclassic-0.5.2.tar.gz", hash = "sha256:40f11bbcc59e8956c3d5ef132dec8e5a853e893ecf831e791d54da0d8a50d79d"}, + {file = "nbclassic-0.5.6-py3-none-any.whl", hash = "sha256:e3c8b7de80046c4a36a74662a5e325386d345289906c618366d8154e03dc2322"}, + {file = "nbclassic-0.5.6.tar.gz", hash = "sha256:aab53fa1bea084fb6ade5c538b011a4f070c69f88d72878a8e8fb356f152509f"}, ] nbclient = [ - {file = "nbclient-0.7.2-py3-none-any.whl", hash = "sha256:d97ac6257de2794f5397609df754fcbca1a603e94e924eb9b99787c031ae2e7c"}, - {file = "nbclient-0.7.2.tar.gz", hash = "sha256:884a3f4a8c4fc24bb9302f263e0af47d97f0d01fe11ba714171b320c8ac09547"}, + {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, + {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, ] nbconvert = [ - {file = "nbconvert-7.2.9-py3-none-any.whl", hash = "sha256:495638c5e06005f4a5ce828d8a81d28e34f95c20f4384d5d7a22254b443836e7"}, - {file = "nbconvert-7.2.9.tar.gz", hash = "sha256:a42c3ac137c64f70cbe4d763111bf358641ea53b37a01a5c202ed86374af5234"}, + {file = "nbconvert-7.3.1-py3-none-any.whl", hash = "sha256:d2e95904666f1ff77d36105b9de4e0801726f93b862d5b28f69e93d99ad3b19c"}, + {file = "nbconvert-7.3.1.tar.gz", hash = "sha256:78685362b11d2e8058e70196fe83b09abed8df22d3e599cf271f4d39fdc48b9e"}, ] nbformat = [ - {file = "nbformat-5.7.3-py3-none-any.whl", hash = "sha256:22a98a6516ca216002b0a34591af5bcb8072ca6c63910baffc901cfa07fefbf0"}, - {file = "nbformat-5.7.3.tar.gz", hash = "sha256:4b021fca24d3a747bf4e626694033d792d594705829e5e35b14ee3369f9f6477"}, + {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, + {file = "nbformat-5.8.0.tar.gz", hash = "sha256:46dac64c781f1c34dfd8acba16547024110348f9fc7eab0f31981c2a3dc48d1f"}, ] nest-asyncio = [ {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, @@ -3438,42 +3439,42 @@ networkx = [ {file = "networkx-2.8.8.tar.gz", hash = "sha256:230d388117af870fce5647a3c52401fcf753e94720e6ea6b4197a5355648885e"}, ] notebook = [ - {file = "notebook-6.5.2-py3-none-any.whl", hash = "sha256:e04f9018ceb86e4fa841e92ea8fb214f8d23c1cedfde530cc96f92446924f0e4"}, - {file = "notebook-6.5.2.tar.gz", hash = "sha256:c1897e5317e225fc78b45549a6ab4b668e4c996fd03a04e938fe5e7af2bfffd0"}, + {file = "notebook-6.5.4-py3-none-any.whl", hash = "sha256:dd17e78aefe64c768737b32bf171c1c766666a21cc79a44d37a1700771cab56f"}, + {file = "notebook-6.5.4.tar.gz", hash = "sha256:517209568bd47261e2def27a140e97d49070602eea0d226a696f42a7f16c9a4e"}, ] notebook-shim = [ - {file = "notebook_shim-0.2.2-py3-none-any.whl", hash = "sha256:9c6c30f74c4fbea6fce55c1be58e7fd0409b1c681b075dcedceb005db5026949"}, - {file = "notebook_shim-0.2.2.tar.gz", hash = "sha256:090e0baf9a5582ff59b607af523ca2db68ff216da0c69956b62cab2ef4fc9c3f"}, + {file = "notebook_shim-0.2.3-py3-none-any.whl", hash = "sha256:a83496a43341c1674b093bfcebf0fe8e74cbe7eda5fd2bbc56f8e39e1486c0c7"}, + {file = "notebook_shim-0.2.3.tar.gz", hash = "sha256:f69388ac283ae008cd506dda10d0288b09a017d822d5e8c7129a152cbd3ce7e9"}, ] numpy = [ - {file = "numpy-1.24.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eef70b4fc1e872ebddc38cddacc87c19a3709c0e3e5d20bf3954c147b1dd941d"}, - {file = "numpy-1.24.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e8d2859428712785e8a8b7d2b3ef0a1d1565892367b32f915c4a4df44d0e64f5"}, - {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6524630f71631be2dabe0c541e7675db82651eb998496bbe16bc4f77f0772253"}, - {file = "numpy-1.24.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a51725a815a6188c662fb66fb32077709a9ca38053f0274640293a14fdd22978"}, - {file = "numpy-1.24.2-cp310-cp310-win32.whl", hash = "sha256:2620e8592136e073bd12ee4536149380695fbe9ebeae845b81237f986479ffc9"}, - {file = "numpy-1.24.2-cp310-cp310-win_amd64.whl", hash = "sha256:97cf27e51fa078078c649a51d7ade3c92d9e709ba2bfb97493007103c741f1d0"}, - {file = "numpy-1.24.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7de8fdde0003f4294655aa5d5f0a89c26b9f22c0a58790c38fae1ed392d44a5a"}, - {file = "numpy-1.24.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4173bde9fa2a005c2c6e2ea8ac1618e2ed2c1c6ec8a7657237854d42094123a0"}, - {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cecaed30dc14123020f77b03601559fff3e6cd0c048f8b5289f4eeabb0eb281"}, - {file = "numpy-1.24.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a23f8440561a633204a67fb44617ce2a299beecf3295f0d13c495518908e910"}, - {file = "numpy-1.24.2-cp311-cp311-win32.whl", hash = "sha256:e428c4fbfa085f947b536706a2fc349245d7baa8334f0c5723c56a10595f9b95"}, - {file = "numpy-1.24.2-cp311-cp311-win_amd64.whl", hash = "sha256:557d42778a6869c2162deb40ad82612645e21d79e11c1dc62c6e82a2220ffb04"}, - {file = "numpy-1.24.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d0a2db9d20117bf523dde15858398e7c0858aadca7c0f088ac0d6edd360e9ad2"}, - {file = "numpy-1.24.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c72a6b2f4af1adfe193f7beb91ddf708ff867a3f977ef2ec53c0ffb8283ab9f5"}, - {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29e6bd0ec49a44d7690ecb623a8eac5ab8a923bce0bea6293953992edf3a76a"}, - {file = "numpy-1.24.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eabd64ddb96a1239791da78fa5f4e1693ae2dadc82a76bc76a14cbb2b966e96"}, - {file = "numpy-1.24.2-cp38-cp38-win32.whl", hash = "sha256:e3ab5d32784e843fc0dd3ab6dcafc67ef806e6b6828dc6af2f689be0eb4d781d"}, - {file = "numpy-1.24.2-cp38-cp38-win_amd64.whl", hash = "sha256:76807b4063f0002c8532cfeac47a3068a69561e9c8715efdad3c642eb27c0756"}, - {file = "numpy-1.24.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4199e7cfc307a778f72d293372736223e39ec9ac096ff0a2e64853b866a8e18a"}, - {file = "numpy-1.24.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:adbdce121896fd3a17a77ab0b0b5eedf05a9834a18699db6829a64e1dfccca7f"}, - {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:889b2cc88b837d86eda1b17008ebeb679d82875022200c6e8e4ce6cf549b7acb"}, - {file = "numpy-1.24.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f64bb98ac59b3ea3bf74b02f13836eb2e24e48e0ab0145bbda646295769bd780"}, - {file = "numpy-1.24.2-cp39-cp39-win32.whl", hash = "sha256:63e45511ee4d9d976637d11e6c9864eae50e12dc9598f531c035265991910468"}, - {file = "numpy-1.24.2-cp39-cp39-win_amd64.whl", hash = "sha256:a77d3e1163a7770164404607b7ba3967fb49b24782a6ef85d9b5f54126cc39e5"}, - {file = "numpy-1.24.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:92011118955724465fb6853def593cf397b4a1367495e0b59a7e69d40c4eb71d"}, - {file = "numpy-1.24.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9006288bcf4895917d02583cf3411f98631275bc67cce355a7f39f8c14338fa"}, - {file = "numpy-1.24.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:150947adbdfeceec4e5926d956a06865c1c690f2fd902efede4ca6fe2e657c3f"}, - {file = "numpy-1.24.2.tar.gz", hash = "sha256:003a9f530e880cb2cd177cba1af7220b9aa42def9c4afc2a2fc3ee6be7eb2b22"}, + {file = "numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, + {file = "numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, + {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, + {file = "numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, + {file = "numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, + {file = "numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, + {file = "numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, + {file = "numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, + {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, + {file = "numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, + {file = "numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, + {file = "numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, + {file = "numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, + {file = "numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, + {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, + {file = "numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, + {file = "numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, + {file = "numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, + {file = "numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, + {file = "numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, + {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, + {file = "numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, + {file = "numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, + {file = "numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, + {file = "numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, + {file = "numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, ] oauth2client = [ {file = "oauth2client-4.1.3-py2.py3-none-any.whl", hash = "sha256:b8a81cc5d60e2d364f0b1b98f958dbd472887acaf1a5b05e21c28c31a2d6d3ac"}, @@ -3484,12 +3485,15 @@ oauthlib = [ {file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, ] openpyxl = [ - {file = "openpyxl-3.1.1-py2.py3-none-any.whl", hash = "sha256:a0266e033e65f33ee697254b66116a5793c15fc92daf64711080000df4cfe0a8"}, - {file = "openpyxl-3.1.1.tar.gz", hash = "sha256:f06d44e2c973781068bce5ecf860a09bcdb1c7f5ce1facd5e9aa82c92c93ae72"}, + {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, + {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, ] packaging = [ - {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, - {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, + {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, + {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, +] +pandarallel = [ + {file = "pandarallel-1.6.4.tar.gz", hash = "sha256:70091652485050241ffac37c3e94d21732697c63ee4613ae7bf85da076be41f2"}, ] pandas = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, @@ -3529,8 +3533,8 @@ parso = [ {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, ] pathspec = [ - {file = "pathspec-0.11.0-py3-none-any.whl", hash = "sha256:3a66eb970cbac598f9e5ccb5b2cf58930cd8e3ed86d393d541eaf2d8b1705229"}, - {file = "pathspec-0.11.0.tar.gz", hash = "sha256:64d338d4e0914e91c1792321e6907b5a593f1ab1851de7fc269557a21b30ebbc"}, + {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, + {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, ] pdoc = [ {file = "pdoc-12.3.1-py3-none-any.whl", hash = "sha256:c3f24f31286e634de9c76fa6e67bd5c0c5e74360b41dc91e6b82499831eb52d8"}, @@ -3545,8 +3549,8 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-3.0.0-py3-none-any.whl", hash = "sha256:b1d5eb14f221506f50d6604a561f4c5786d9e80355219694a1b244bcd96f4567"}, - {file = "platformdirs-3.0.0.tar.gz", hash = "sha256:8a1228abb1ef82d788f74139988b137e78692984ec7b08eaa6c65f1723af28f9"}, + {file = "platformdirs-3.4.0-py3-none-any.whl", hash = "sha256:01437886022decaf285d8972f9526397bfae2ac55480ed372ed6d9eca048870a"}, + {file = "platformdirs-3.4.0.tar.gz", hash = "sha256:a5e1536e5ea4b1c238a1364da17ff2993d5bd28e15600c2c8224008aff6bbcad"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -3557,39 +3561,39 @@ prometheus-client = [ {file = "prometheus_client-0.16.0.tar.gz", hash = "sha256:a03e35b359f14dd1630898543e2120addfdeacd1a6069c1367ae90fd93ad3f48"}, ] prompt-toolkit = [ - {file = "prompt_toolkit-3.0.36-py3-none-any.whl", hash = "sha256:aa64ad242a462c5ff0363a7b9cfe696c20d55d9fc60c11fd8e632d064804d305"}, - {file = "prompt_toolkit-3.0.36.tar.gz", hash = "sha256:3e163f254bef5a03b146397d7c1963bd3e2812f0964bb9a24e6ec761fd28db63"}, + {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, + {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, ] protobuf = [ - {file = "protobuf-4.22.0-cp310-abi3-win32.whl", hash = "sha256:b2fea9dc8e3c0f32c38124790ef16cba2ee0628fe2022a52e435e1117bfef9b1"}, - {file = "protobuf-4.22.0-cp310-abi3-win_amd64.whl", hash = "sha256:a33a273d21852f911b8bda47f39f4383fe7c061eb1814db2c76c9875c89c2491"}, - {file = "protobuf-4.22.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:e894e9ae603e963f0842498c4cd5d39c6a60f0d7e4c103df50ee939564298658"}, - {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:7c535d126e7dcc714105ab20b418c4fedbd28f8b8afc42b7350b1e317bbbcc71"}, - {file = "protobuf-4.22.0-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:86c3d20428b007537ba6792b475c0853bba7f66b1f60e610d913b77d94b486e4"}, - {file = "protobuf-4.22.0-cp37-cp37m-win32.whl", hash = "sha256:1669cb7524221a8e2d9008d0842453dbefdd0fcdd64d67672f657244867635fb"}, - {file = "protobuf-4.22.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ab4d043865dd04e6b09386981fe8f80b39a1e46139fb4a3c206229d6b9f36ff6"}, - {file = "protobuf-4.22.0-cp38-cp38-win32.whl", hash = "sha256:29288813aacaa302afa2381db1d6e0482165737b0afdf2811df5fa99185c457b"}, - {file = "protobuf-4.22.0-cp38-cp38-win_amd64.whl", hash = "sha256:e474b63bab0a2ea32a7b26a4d8eec59e33e709321e5e16fb66e766b61b82a95e"}, - {file = "protobuf-4.22.0-cp39-cp39-win32.whl", hash = "sha256:47d31bdf58222dd296976aa1646c68c6ee80b96d22e0a3c336c9174e253fd35e"}, - {file = "protobuf-4.22.0-cp39-cp39-win_amd64.whl", hash = "sha256:c27f371f0159feb70e6ea52ed7e768b3f3a4c5676c1900a7e51a24740381650e"}, - {file = "protobuf-4.22.0-py3-none-any.whl", hash = "sha256:c3325803095fb4c2a48649c321d2fbde59f8fbfcb9bfc7a86df27d112831c571"}, - {file = "protobuf-4.22.0.tar.gz", hash = "sha256:652d8dfece122a24d98eebfef30e31e455d300efa41999d1182e015984ac5930"}, + {file = "protobuf-4.22.3-cp310-abi3-win32.whl", hash = "sha256:8b54f56d13ae4a3ec140076c9d937221f887c8f64954673d46f63751209e839a"}, + {file = "protobuf-4.22.3-cp310-abi3-win_amd64.whl", hash = "sha256:7760730063329d42a9d4c4573b804289b738d4931e363ffbe684716b796bde51"}, + {file = "protobuf-4.22.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:d14fc1a41d1a1909998e8aff7e80d2a7ae14772c4a70e4bf7db8a36690b54425"}, + {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:70659847ee57a5262a65954538088a1d72dfc3e9882695cab9f0c54ffe71663b"}, + {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:13233ee2b9d3bd9a5f216c1fa2c321cd564b93d8f2e4f521a85b585447747997"}, + {file = "protobuf-4.22.3-cp37-cp37m-win32.whl", hash = "sha256:ecae944c6c2ce50dda6bf76ef5496196aeb1b85acb95df5843cd812615ec4b61"}, + {file = "protobuf-4.22.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d4b66266965598ff4c291416be429cef7989d8fae88b55b62095a2331511b3fa"}, + {file = "protobuf-4.22.3-cp38-cp38-win32.whl", hash = "sha256:f08aa300b67f1c012100d8eb62d47129e53d1150f4469fd78a29fa3cb68c66f2"}, + {file = "protobuf-4.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:f2f4710543abec186aee332d6852ef5ae7ce2e9e807a3da570f36de5a732d88e"}, + {file = "protobuf-4.22.3-cp39-cp39-win32.whl", hash = "sha256:7cf56e31907c532e460bb62010a513408e6cdf5b03fb2611e4b67ed398ad046d"}, + {file = "protobuf-4.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:e0e630d8e6a79f48c557cd1835865b593d0547dce221c66ed1b827de59c66c97"}, + {file = "protobuf-4.22.3-py3-none-any.whl", hash = "sha256:52f0a78141078077cfe15fe333ac3e3a077420b9a3f5d1bf9b5fe9d286b4d881"}, + {file = "protobuf-4.22.3.tar.gz", hash = "sha256:23452f2fdea754a8251d0fc88c0317735ae47217e0d27bf330a30eec2848811a"}, ] psutil = [ - {file = "psutil-5.9.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c1ca331af862803a42677c120aff8a814a804e09832f166f226bfd22b56feee8"}, - {file = "psutil-5.9.4-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:68908971daf802203f3d37e78d3f8831b6d1014864d7a85937941bb35f09aefe"}, - {file = "psutil-5.9.4-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:3ff89f9b835100a825b14c2808a106b6fdcc4b15483141482a12c725e7f78549"}, - {file = "psutil-5.9.4-cp27-cp27m-win32.whl", hash = "sha256:852dd5d9f8a47169fe62fd4a971aa07859476c2ba22c2254d4a1baa4e10b95ad"}, - {file = "psutil-5.9.4-cp27-cp27m-win_amd64.whl", hash = "sha256:9120cd39dca5c5e1c54b59a41d205023d436799b1c8c4d3ff71af18535728e94"}, - {file = "psutil-5.9.4-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:6b92c532979bafc2df23ddc785ed116fced1f492ad90a6830cf24f4d1ea27d24"}, - {file = "psutil-5.9.4-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:efeae04f9516907be44904cc7ce08defb6b665128992a56957abc9b61dca94b7"}, - {file = "psutil-5.9.4-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:54d5b184728298f2ca8567bf83c422b706200bcbbfafdc06718264f9393cfeb7"}, - {file = "psutil-5.9.4-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:16653106f3b59386ffe10e0bad3bb6299e169d5327d3f187614b1cb8f24cf2e1"}, - {file = "psutil-5.9.4-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54c0d3d8e0078b7666984e11b12b88af2db11d11249a8ac8920dd5ef68a66e08"}, - {file = "psutil-5.9.4-cp36-abi3-win32.whl", hash = "sha256:149555f59a69b33f056ba1c4eb22bb7bf24332ce631c44a319cec09f876aaeff"}, - {file = "psutil-5.9.4-cp36-abi3-win_amd64.whl", hash = "sha256:fd8522436a6ada7b4aad6638662966de0d61d241cb821239b2ae7013d41a43d4"}, - {file = "psutil-5.9.4-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:6001c809253a29599bc0dfd5179d9f8a5779f9dffea1da0f13c53ee568115e1e"}, - {file = "psutil-5.9.4.tar.gz", hash = "sha256:3d7f9739eb435d4b1338944abe23f49584bde5395f27487d2ee25ad9a8774a62"}, + {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ab8ed1a1d77c95453db1ae00a3f9c50227ebd955437bcf2a574ba8adbf6a74d5"}, + {file = "psutil-5.9.5-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:4aef137f3345082a3d3232187aeb4ac4ef959ba3d7c10c33dd73763fbc063da4"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ea8518d152174e1249c4f2a1c89e3e6065941df2fa13a1ab45327716a23c2b48"}, + {file = "psutil-5.9.5-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:acf2aef9391710afded549ff602b5887d7a2349831ae4c26be7c807c0a39fac4"}, + {file = "psutil-5.9.5-cp27-none-win32.whl", hash = "sha256:5b9b8cb93f507e8dbaf22af6a2fd0ccbe8244bf30b1baad6b3954e935157ae3f"}, + {file = "psutil-5.9.5-cp27-none-win_amd64.whl", hash = "sha256:8c5f7c5a052d1d567db4ddd231a9d27a74e8e4a9c3f44b1032762bd7b9fdcd42"}, + {file = "psutil-5.9.5-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:3c6f686f4225553615612f6d9bc21f1c0e305f75d7d8454f9b46e901778e7217"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a7dd9997128a0d928ed4fb2c2d57e5102bb6089027939f3b722f3a210f9a8da"}, + {file = "psutil-5.9.5-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89518112647f1276b03ca97b65cc7f64ca587b1eb0278383017c2a0dcc26cbe4"}, + {file = "psutil-5.9.5-cp36-abi3-win32.whl", hash = "sha256:104a5cc0e31baa2bcf67900be36acde157756b9c44017b86b2c049f11957887d"}, + {file = "psutil-5.9.5-cp36-abi3-win_amd64.whl", hash = "sha256:b258c0c1c9d145a1d5ceffab1134441c4c5113b2417fafff7315a917a026c3c9"}, + {file = "psutil-5.9.5-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c607bb3b57dc779d55e1554846352b4e358c10fff3abf3514a7a6601beebdb30"}, + {file = "psutil-5.9.5.tar.gz", hash = "sha256:5410638e4df39c54d957fc51ce03048acd8e6d60abc0f5107af51e5fb566eb3c"}, ] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, @@ -3600,12 +3604,12 @@ pure-eval = [ {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] pyasn1 = [ - {file = "pyasn1-0.4.8-py2.py3-none-any.whl", hash = "sha256:39c7e2ec30515947ff4e87fb6f456dfc6e84857d34be479c9d4a4ba4bf46aa5d"}, - {file = "pyasn1-0.4.8.tar.gz", hash = "sha256:aef77c9fb94a3ac588e87841208bdec464471d9871bd5050a287cc9a475cd0ba"}, + {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, + {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, ] pyasn1-modules = [ - {file = "pyasn1-modules-0.2.8.tar.gz", hash = "sha256:905f84c712230b2c592c19470d3ca8d552de726050d1d1716282a1f6146be65e"}, - {file = "pyasn1_modules-0.2.8-py2.py3-none-any.whl", hash = "sha256:a50b808ffeb97cb3601dd25981f6b016cbb3d31fbf57a8b8a87428e6158d0c74"}, + {file = "pyasn1_modules-0.3.0-py2.py3-none-any.whl", hash = "sha256:d3ccd6ed470d9ffbc716be08bd90efbd44d0734bc9303818f7336070984a162d"}, + {file = "pyasn1_modules-0.3.0.tar.gz", hash = "sha256:5bd01446b736eb9d31512a30d46c1ac3395d676c6f3cafa4c03eb54b9925631c"}, ] pycodestyle = [ {file = "pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, @@ -3616,62 +3620,62 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5920824fe1e21cbb3e38cf0f3dd24857c8959801d1031ce1fac1d50857a03bfb"}, - {file = "pydantic-1.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3bb99cf9655b377db1a9e47fa4479e3330ea96f4123c6c8200e482704bf1eda2"}, - {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2185a3b3d98ab4506a3f6707569802d2d92c3a7ba3a9a35683a7709ea6c2aaa2"}, - {file = "pydantic-1.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f582cac9d11c227c652d3ce8ee223d94eb06f4228b52a8adaafa9fa62e73d5c9"}, - {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c9e5b778b6842f135902e2d82624008c6a79710207e28e86966cd136c621bfee"}, - {file = "pydantic-1.10.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72ef3783be8cbdef6bca034606a5de3862be6b72415dc5cb1fb8ddbac110049a"}, - {file = "pydantic-1.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:45edea10b75d3da43cfda12f3792833a3fa70b6eee4db1ed6aed528cef17c74e"}, - {file = "pydantic-1.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:63200cd8af1af2c07964546b7bc8f217e8bda9d0a2ef0ee0c797b36353914984"}, - {file = "pydantic-1.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:305d0376c516b0dfa1dbefeae8c21042b57b496892d721905a6ec6b79494a66d"}, - {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd326aff5d6c36f05735c7c9b3d5b0e933b4ca52ad0b6e4b38038d82703d35b"}, - {file = "pydantic-1.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6bb0452d7b8516178c969d305d9630a3c9b8cf16fcf4713261c9ebd465af0d73"}, - {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9a9d9155e2a9f38b2eb9374c88f02fd4d6851ae17b65ee786a87d032f87008f8"}, - {file = "pydantic-1.10.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f836444b4c5ece128b23ec36a446c9ab7f9b0f7981d0d27e13a7c366ee163f8a"}, - {file = "pydantic-1.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:8481dca324e1c7b715ce091a698b181054d22072e848b6fc7895cd86f79b4449"}, - {file = "pydantic-1.10.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87f831e81ea0589cd18257f84386bf30154c5f4bed373b7b75e5cb0b5d53ea87"}, - {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ce1612e98c6326f10888df951a26ec1a577d8df49ddcaea87773bfbe23ba5cc"}, - {file = "pydantic-1.10.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58e41dd1e977531ac6073b11baac8c013f3cd8706a01d3dc74e86955be8b2c0c"}, - {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6a4b0aab29061262065bbdede617ef99cc5914d1bf0ddc8bcd8e3d7928d85bd6"}, - {file = "pydantic-1.10.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:36e44a4de37b8aecffa81c081dbfe42c4d2bf9f6dff34d03dce157ec65eb0f15"}, - {file = "pydantic-1.10.5-cp37-cp37m-win_amd64.whl", hash = "sha256:261f357f0aecda005934e413dfd7aa4077004a174dafe414a8325e6098a8e419"}, - {file = "pydantic-1.10.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b429f7c457aebb7fbe7cd69c418d1cd7c6fdc4d3c8697f45af78b8d5a7955760"}, - {file = "pydantic-1.10.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:663d2dd78596c5fa3eb996bc3f34b8c2a592648ad10008f98d1348be7ae212fb"}, - {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51782fd81f09edcf265823c3bf43ff36d00db246eca39ee765ef58dc8421a642"}, - {file = "pydantic-1.10.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c428c0f64a86661fb4873495c4fac430ec7a7cef2b8c1c28f3d1a7277f9ea5ab"}, - {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:76c930ad0746c70f0368c4596020b736ab65b473c1f9b3872310a835d852eb19"}, - {file = "pydantic-1.10.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:3257bd714de9db2102b742570a56bf7978e90441193acac109b1f500290f5718"}, - {file = "pydantic-1.10.5-cp38-cp38-win_amd64.whl", hash = "sha256:f5bee6c523d13944a1fdc6f0525bc86dbbd94372f17b83fa6331aabacc8fd08e"}, - {file = "pydantic-1.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:532e97c35719f137ee5405bd3eeddc5c06eb91a032bc755a44e34a712420daf3"}, - {file = "pydantic-1.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ca9075ab3de9e48b75fa8ccb897c34ccc1519177ad8841d99f7fd74cf43be5bf"}, - {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd46a0e6296346c477e59a954da57beaf9c538da37b9df482e50f836e4a7d4bb"}, - {file = "pydantic-1.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3353072625ea2a9a6c81ad01b91e5c07fa70deb06368c71307529abf70d23325"}, - {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3f9d9b2be177c3cb6027cd67fbf323586417868c06c3c85d0d101703136e6b31"}, - {file = "pydantic-1.10.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b473d00ccd5c2061fd896ac127b7755baad233f8d996ea288af14ae09f8e0d1e"}, - {file = "pydantic-1.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:5f3bc8f103b56a8c88021d481410874b1f13edf6e838da607dcb57ecff9b4594"}, - {file = "pydantic-1.10.5-py3-none-any.whl", hash = "sha256:7c5b94d598c90f2f46b3a983ffb46ab806a67099d118ae0da7ef21a2a4033b28"}, - {file = "pydantic-1.10.5.tar.gz", hash = "sha256:9e337ac83686645a46db0e825acceea8e02fca4062483f40e9ae178e8bd1103a"}, + {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, + {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, + {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, + {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, + {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, + {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, + {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, + {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, + {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, + {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, + {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, + {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, + {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, + {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, + {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, + {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, + {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, + {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, + {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, + {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, + {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, + {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, + {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, + {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, + {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, + {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, + {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, + {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, + {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, + {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, + {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, + {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, + {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, + {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, + {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, + {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, ] pyflakes = [ {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, {file = "pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] pygments = [ - {file = "Pygments-2.14.0-py3-none-any.whl", hash = "sha256:fa7bd7bd2771287c0de303af8bfdfc731f51bd2c6a47ab69d117138893b82717"}, - {file = "Pygments-2.14.0.tar.gz", hash = "sha256:b3ed06a9e8ac9a9aae5a6f5dbe78a8a58655d17b43b93c078f094ddc476ae297"}, + {file = "Pygments-2.15.1-py3-none-any.whl", hash = "sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1"}, + {file = "Pygments-2.15.1.tar.gz", hash = "sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c"}, ] pygsheets = [ {file = "pygsheets-2.0.6-py3-none-any.whl", hash = "sha256:3338c2eb8990fdee9f463b42a370ec0870c118d607d775471a6dfb8b08f6cd87"}, {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.16.2-py3-none-any.whl", hash = "sha256:ff22dde9c2128cd257c145cfd51adeff0be7df4d80d669055f24a962b351bbe4"}, - {file = "pylint-2.16.2.tar.gz", hash = "sha256:13b2c805a404a9bf57d002cd5f054ca4d40b0b87542bdaba5e05321ae8262c84"}, + {file = "pylint-2.17.3-py3-none-any.whl", hash = "sha256:a6cbb4c6e96eab4a3c7de7c6383c512478f58f88d95764507d84c899d656a89a"}, + {file = "pylint-2.17.3.tar.gz", hash = "sha256:761907349e699f8afdcd56c4fe02f3021ab5b3a0fc26d19a9bfdc66c7d0d5cd5"}, ] pyopenssl = [ - {file = "pyOpenSSL-23.0.0-py3-none-any.whl", hash = "sha256:df5fc28af899e74e19fccb5510df423581047e10ab6f1f4ba1763ff5fde844c0"}, - {file = "pyOpenSSL-23.0.0.tar.gz", hash = "sha256:c1cc5f86bcacefc84dada7d31175cae1b1518d5f60d3d0bb595a67822a868a6f"}, + {file = "pyOpenSSL-23.1.1-py3-none-any.whl", hash = "sha256:9e0c526404a210df9d2b18cd33364beadb0dc858a739b885677bc65e105d4a4c"}, + {file = "pyOpenSSL-23.1.1.tar.gz", hash = "sha256:841498b9bec61623b1b6c47ebbc02367c07d60e0e195f19790817f10cc8db0b7"}, ] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -3707,8 +3711,8 @@ pyrsistent = [ {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, ] pytest = [ - {file = "pytest-7.2.1-py3-none-any.whl", hash = "sha256:c7c6ca206e93355074ae32f7403e8ea12163b1163c976fee7d4d84027c162be5"}, - {file = "pytest-7.2.1.tar.gz", hash = "sha256:d45e0952f3727241918b8fd0f376f5ff6b301cc0777c6f9a556935c92d8a7d42"}, + {file = "pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, + {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, ] pytest-cov = [ {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, @@ -3727,32 +3731,32 @@ python-dotenv = [ {file = "python_dotenv-0.21.1-py3-none-any.whl", hash = "sha256:41e12e0318bebc859fcc4d97d4db8d20ad21721a6aa5047dd59f090391cb549a"}, ] python-json-logger = [ - {file = "python-json-logger-2.0.6.tar.gz", hash = "sha256:ed33182c2b438a366775c25c1219ebbd5bd7f71694c644d6b3b3861e19565ae3"}, - {file = "python_json_logger-2.0.6-py3-none-any.whl", hash = "sha256:3af8e5b907b4a5b53cae249205ee3a3d3472bd7ad9ddfaec136eec2f2faf4995"}, + {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, + {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, ] pytz = [ - {file = "pytz-2022.7.1-py2.py3-none-any.whl", hash = "sha256:78f4f37d8198e0627c5f1143240bb0206b8691d8d7ac6d78fee88b78733f8c4a"}, - {file = "pytz-2022.7.1.tar.gz", hash = "sha256:01a0681c4b9684a28304615eba55d1ab31ae00bf68ec157ec3708a8182dbbcd0"}, + {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, + {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] pytz-deprecation-shim = [ {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, ] pywin32 = [ - {file = "pywin32-305-cp310-cp310-win32.whl", hash = "sha256:421f6cd86e84bbb696d54563c48014b12a23ef95a14e0bdba526be756d89f116"}, - {file = "pywin32-305-cp310-cp310-win_amd64.whl", hash = "sha256:73e819c6bed89f44ff1d690498c0a811948f73777e5f97c494c152b850fad478"}, - {file = "pywin32-305-cp310-cp310-win_arm64.whl", hash = "sha256:742eb905ce2187133a29365b428e6c3b9001d79accdc30aa8969afba1d8470f4"}, - {file = "pywin32-305-cp311-cp311-win32.whl", hash = "sha256:19ca459cd2e66c0e2cc9a09d589f71d827f26d47fe4a9d09175f6aa0256b51c2"}, - {file = "pywin32-305-cp311-cp311-win_amd64.whl", hash = "sha256:326f42ab4cfff56e77e3e595aeaf6c216712bbdd91e464d167c6434b28d65990"}, - {file = "pywin32-305-cp311-cp311-win_arm64.whl", hash = "sha256:4ecd404b2c6eceaca52f8b2e3e91b2187850a1ad3f8b746d0796a98b4cea04db"}, - {file = "pywin32-305-cp36-cp36m-win32.whl", hash = "sha256:48d8b1659284f3c17b68587af047d110d8c44837736b8932c034091683e05863"}, - {file = "pywin32-305-cp36-cp36m-win_amd64.whl", hash = "sha256:13362cc5aa93c2beaf489c9c9017c793722aeb56d3e5166dadd5ef82da021fe1"}, - {file = "pywin32-305-cp37-cp37m-win32.whl", hash = "sha256:a55db448124d1c1484df22fa8bbcbc45c64da5e6eae74ab095b9ea62e6d00496"}, - {file = "pywin32-305-cp37-cp37m-win_amd64.whl", hash = "sha256:109f98980bfb27e78f4df8a51a8198e10b0f347257d1e265bb1a32993d0c973d"}, - {file = "pywin32-305-cp38-cp38-win32.whl", hash = "sha256:9dd98384da775afa009bc04863426cb30596fd78c6f8e4e2e5bbf4edf8029504"}, - {file = "pywin32-305-cp38-cp38-win_amd64.whl", hash = "sha256:56d7a9c6e1a6835f521788f53b5af7912090674bb84ef5611663ee1595860fc7"}, - {file = "pywin32-305-cp39-cp39-win32.whl", hash = "sha256:9d968c677ac4d5cbdaa62fd3014ab241718e619d8e36ef8e11fb930515a1e918"}, - {file = "pywin32-305-cp39-cp39-win_amd64.whl", hash = "sha256:50768c6b7c3f0b38b7fb14dd4104da93ebced5f1a50dc0e834594bff6fbe1271"}, + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, ] pywin32-ctypes = [ {file = "pywin32-ctypes-0.2.0.tar.gz", hash = "sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942"}, @@ -3809,181 +3813,153 @@ pyyaml = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] pyzmq = [ - {file = "pyzmq-25.0.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:2d05d904f03ddf1e0d83d97341354dfe52244a619b5a1440a5f47a5b3451e84e"}, - {file = "pyzmq-25.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a154ef810d44f9d28868be04641f837374a64e7449df98d9208e76c260c7ef1"}, - {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:487305c2a011fdcf3db1f24e8814bb76d23bc4d2f46e145bc80316a59a9aa07d"}, - {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e7b87638ee30ab13230e37ce5331b3e730b1e0dda30120b9eeec3540ed292c8"}, - {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75243e422e85a62f0ab7953dc315452a56b2c6a7e7d1a3c3109ac3cc57ed6b47"}, - {file = "pyzmq-25.0.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:31e523d067ce44a04e876bed3ff9ea1ff8d1b6636d16e5fcace9d22f8c564369"}, - {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8539216173135e9e89f6b1cc392e74e6b935b91e8c76106cf50e7a02ab02efe5"}, - {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:2754fa68da08a854f4816e05160137fa938a2347276471103d31e04bcee5365c"}, - {file = "pyzmq-25.0.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4a1bc30f0c18444d51e9b0d0dd39e3a4e7c53ee74190bebef238cd58de577ea9"}, - {file = "pyzmq-25.0.0-cp310-cp310-win32.whl", hash = "sha256:01d53958c787cfea34091fcb8ef36003dbb7913b8e9f8f62a0715234ebc98b70"}, - {file = "pyzmq-25.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:58fc3ad5e1cfd2e6d24741fbb1e216b388115d31b0ca6670f894187f280b6ba6"}, - {file = "pyzmq-25.0.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:e4bba04ea779a3d7ef25a821bb63fd0939142c88e7813e5bd9c6265a20c523a2"}, - {file = "pyzmq-25.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af1fbfb7ad6ac0009ccee33c90a1d303431c7fb594335eb97760988727a37577"}, - {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:85456f0d8f3268eecd63dede3b99d5bd8d3b306310c37d4c15141111d22baeaf"}, - {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0645b5a2d2a06fd8eb738018490c514907f7488bf9359c6ee9d92f62e844b76f"}, - {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f72ea279b2941a5203e935a4588b9ba8a48aeb9a926d9dfa1986278bd362cb8"}, - {file = "pyzmq-25.0.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:4e295f7928a31ae0f657e848c5045ba6d693fe8921205f408ca3804b1b236968"}, - {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ac97e7d647d5519bcef48dd8d3d331f72975afa5c4496c95f6e854686f45e2d9"}, - {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:656281d496aaf9ca4fd4cea84e6d893e3361057c4707bd38618f7e811759103c"}, - {file = "pyzmq-25.0.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f6116991568aac48b94d6d8aaed6157d407942ea385335a6ed313692777fb9d"}, - {file = "pyzmq-25.0.0-cp311-cp311-win32.whl", hash = "sha256:0282bba9aee6e0346aa27d6c69b5f7df72b5a964c91958fc9e0c62dcae5fdcdc"}, - {file = "pyzmq-25.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:526f884a27e8bba62fe1f4e07c62be2cfe492b6d432a8fdc4210397f8cf15331"}, - {file = "pyzmq-25.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ccb3e1a863222afdbda42b7ca8ac8569959593d7abd44f5a709177d6fa27d266"}, - {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4046d03100aca266e70d54a35694cb35d6654cfbef633e848b3c4a8d64b9d187"}, - {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3100dddcada66ec5940ed6391ebf9d003cc3ede3d320748b2737553019f58230"}, - {file = "pyzmq-25.0.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7877264aa851c19404b1bb9dbe6eed21ea0c13698be1eda3784aab3036d1c861"}, - {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:5049e75cc99db65754a3da5f079230fb8889230cf09462ec972d884d1704a3ed"}, - {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:81f99fb1224d36eb91557afec8cdc2264e856f3464500b55749020ce4c848ef2"}, - {file = "pyzmq-25.0.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:a1cd4a95f176cdc0ee0a82d49d5830f13ae6015d89decbf834c273bc33eeb3d3"}, - {file = "pyzmq-25.0.0-cp36-cp36m-win32.whl", hash = "sha256:926236ca003aec70574754f39703528947211a406f5c6c8b3e50eca04a9e87fc"}, - {file = "pyzmq-25.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:94f0a7289d0f5c80807c37ebb404205e7deb737e8763eb176f4770839ee2a287"}, - {file = "pyzmq-25.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f3f96d452e9580cb961ece2e5a788e64abaecb1232a80e61deffb28e105ff84a"}, - {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:930e6ad4f2eaac31a3d0c2130619d25db754b267487ebc186c6ad18af2a74018"}, - {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e1081d7030a1229c8ff90120346fb7599b54f552e98fcea5170544e7c6725aab"}, - {file = "pyzmq-25.0.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:531866c491aee5a1e967c286cfa470dffac1e2a203b1afda52d62b58782651e9"}, - {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fc7c1421c5b1c916acf3128bf3cc7ea7f5018b58c69a6866d70c14190e600ce9"}, - {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:9a2d5e419bd39a1edb6cdd326d831f0120ddb9b1ff397e7d73541bf393294973"}, - {file = "pyzmq-25.0.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:183e18742be3621acf8908903f689ec520aee3f08449bfd29f583010ca33022b"}, - {file = "pyzmq-25.0.0-cp37-cp37m-win32.whl", hash = "sha256:02f5cb60a7da1edd5591a15efa654ffe2303297a41e1b40c3c8942f8f11fc17c"}, - {file = "pyzmq-25.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:cac602e02341eaaf4edfd3e29bd3fdef672e61d4e6dfe5c1d065172aee00acee"}, - {file = "pyzmq-25.0.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:e14df47c1265356715d3d66e90282a645ebc077b70b3806cf47efcb7d1d630cb"}, - {file = "pyzmq-25.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:293a7c2128690f496057f1f1eb6074f8746058d13588389981089ec45d8fdc77"}, - {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:731b208bc9412deeb553c9519dca47136b5a01ca66667cafd8733211941b17e4"}, - {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b055a1cddf8035966ad13aa51edae5dc8f1bba0b5d5e06f7a843d8b83dc9b66b"}, - {file = "pyzmq-25.0.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17e1cb97d573ea84d7cd97188b42ca6f611ab3ee600f6a75041294ede58e3d20"}, - {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:60ecbfe7669d3808ffa8a7dd1487d6eb8a4015b07235e3b723d4b2a2d4de7203"}, - {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4c25c95416133942280faaf068d0fddfd642b927fb28aaf4ab201a738e597c1e"}, - {file = "pyzmq-25.0.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:be05504af0619d1cffa500af1e0ede69fb683f301003851f5993b5247cc2c576"}, - {file = "pyzmq-25.0.0-cp38-cp38-win32.whl", hash = "sha256:6bf3842af37af43fa953e96074ebbb5315f6a297198f805d019d788a1021dbc8"}, - {file = "pyzmq-25.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:b90bb8dfbbd138558f1f284fecfe328f7653616ff9a972433a00711d9475d1a9"}, - {file = "pyzmq-25.0.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:62b9e80890c0d2408eb42d5d7e1fc62a5ce71be3288684788f74cf3e59ffd6e2"}, - {file = "pyzmq-25.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:484c2c4ee02c1edc07039f42130bd16e804b1fe81c4f428e0042e03967f40c20"}, - {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9ca6db34b26c4d3e9b0728841ec9aa39484eee272caa97972ec8c8e231b20c7e"}, - {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:610d2d112acd4e5501fac31010064a6c6efd716ceb968e443cae0059eb7b86de"}, - {file = "pyzmq-25.0.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3594c0ff604e685d7e907860b61d0e10e46c74a9ffca168f6e9e50ea934ee440"}, - {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c21a5f4e54a807df5afdef52b6d24ec1580153a6bcf0607f70a6e1d9fa74c5c3"}, - {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4725412e27612f0d7d7c2f794d89807ad0227c2fc01dd6146b39ada49c748ef9"}, - {file = "pyzmq-25.0.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4d3d604fe0a67afd1aff906e54da557a5203368a99dcc50a70eef374f1d2abef"}, - {file = "pyzmq-25.0.0-cp39-cp39-win32.whl", hash = "sha256:3670e8c5644768f214a3b598fe46378a4a6f096d5fb82a67dfd3440028460565"}, - {file = "pyzmq-25.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:e99629a976809fe102ef73e856cf4b2660acd82a412a51e80ba2215e523dfd0a"}, - {file = "pyzmq-25.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:66509c48f7446b640eeae24b60c9c1461799a27b1b0754e438582e36b5af3315"}, - {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a9c464cc508177c09a5a6122b67f978f20e2954a21362bf095a0da4647e3e908"}, - {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28bcb2e66224a7ac2843eb632e4109d6b161479e7a2baf24e37210461485b4f1"}, - {file = "pyzmq-25.0.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0e7ef9ac807db50b4eb6f534c5dcc22f998f5dae920cc28873d2c1d080a4fc9"}, - {file = "pyzmq-25.0.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:5050f5c50b58a6e38ccaf9263a356f74ef1040f5ca4030225d1cb1a858c5b7b6"}, - {file = "pyzmq-25.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:2a73af6504e0d2805e926abf136ebf536735a13c22f709be7113c2ec65b4bec3"}, - {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0e8d00228db627ddd1b418c7afd81820b38575f237128c9650365f2dd6ac3443"}, - {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5605621f2181f20b71f13f698944deb26a0a71af4aaf435b34dd90146092d530"}, - {file = "pyzmq-25.0.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6136bfb0e5a9cf8c60c6ac763eb21f82940a77e6758ea53516c8c7074f4ff948"}, - {file = "pyzmq-25.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:0a90b2480a26aef7c13cff18703ba8d68e181facb40f78873df79e6d42c1facc"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00c94fd4c9dd3c95aace0c629a7fa713627a5c80c1819326b642adf6c4b8e2a2"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20638121b0bdc80777ce0ec8c1f14f1ffec0697a1f88f0b564fa4a23078791c4"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6f75b4b8574f3a8a0d6b4b52606fc75b82cb4391471be48ab0b8677c82f9ed4"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cbb885f347eba7ab7681c450dee5b14aed9f153eec224ec0c3f299273d9241f"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c48f257da280b3be6c94e05bd575eddb1373419dbb1a72c3ce64e88f29d1cd6d"}, - {file = "pyzmq-25.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:866eabf7c1315ef2e93e34230db7cbf672e0d7c626b37c11f7e870c8612c3dcc"}, - {file = "pyzmq-25.0.0.tar.gz", hash = "sha256:f330a1a2c7f89fd4b0aa4dcb7bf50243bf1c8da9a2f1efc31daf57a2046b31f2"}, + {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ac178e666c097c8d3deb5097b58cd1316092fc43e8ef5b5fdb259b51da7e7315"}, + {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:659e62e1cbb063151c52f5b01a38e1df6b54feccfa3e2509d44c35ca6d7962ee"}, + {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8280ada89010735a12b968ec3ea9a468ac2e04fddcc1cede59cb7f5178783b9c"}, + {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b5eeb5278a8a636bb0abdd9ff5076bcbb836cd2302565df53ff1fa7d106d54"}, + {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a2e5fe42dfe6b73ca120b97ac9f34bfa8414feb15e00e37415dbd51cf227ef6"}, + {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:827bf60e749e78acb408a6c5af6688efbc9993e44ecc792b036ec2f4b4acf485"}, + {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7b504ae43d37e282301da586529e2ded8b36d4ee2cd5e6db4386724ddeaa6bbc"}, + {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb1f69a0a2a2b1aae8412979dd6293cc6bcddd4439bf07e4758d864ddb112354"}, + {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b9c9cc965cdf28381e36da525dcb89fc1571d9c54800fdcd73e3f73a2fc29bd"}, + {file = "pyzmq-25.0.2-cp310-cp310-win32.whl", hash = "sha256:24abbfdbb75ac5039205e72d6c75f10fc39d925f2df8ff21ebc74179488ebfca"}, + {file = "pyzmq-25.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a821a506822fac55d2df2085a52530f68ab15ceed12d63539adc32bd4410f6e"}, + {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9af0bb0277e92f41af35e991c242c9c71920169d6aa53ade7e444f338f4c8128"}, + {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54a96cf77684a3a537b76acfa7237b1e79a8f8d14e7f00e0171a94b346c5293e"}, + {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88649b19ede1cab03b96b66c364cbbf17c953615cdbc844f7f6e5f14c5e5261c"}, + {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:715cff7644a80a7795953c11b067a75f16eb9fc695a5a53316891ebee7f3c9d5"}, + {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b3f0f066b4f1d17383aae509bacf833ccaf591184a1f3c7a1661c085063ae"}, + {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d488c5c8630f7e782e800869f82744c3aca4aca62c63232e5d8c490d3d66956a"}, + {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:38d9f78d69bcdeec0c11e0feb3bc70f36f9b8c44fc06e5d06d91dc0a21b453c7"}, + {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3059a6a534c910e1d5d068df42f60d434f79e6cc6285aa469b384fa921f78cf8"}, + {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6526d097b75192f228c09d48420854d53dfbc7abbb41b0e26f363ccb26fbc177"}, + {file = "pyzmq-25.0.2-cp311-cp311-win32.whl", hash = "sha256:5c5fbb229e40a89a2fe73d0c1181916f31e30f253cb2d6d91bea7927c2e18413"}, + {file = "pyzmq-25.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed15e3a2c3c2398e6ae5ce86d6a31b452dfd6ad4cd5d312596b30929c4b6e182"}, + {file = "pyzmq-25.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:032f5c8483c85bf9c9ca0593a11c7c749d734ce68d435e38c3f72e759b98b3c9"}, + {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:374b55516393bfd4d7a7daa6c3b36d6dd6a31ff9d2adad0838cd6a203125e714"}, + {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08bfcc21b5997a9be4fefa405341320d8e7f19b4d684fb9c0580255c5bd6d695"}, + {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1a843d26a8da1b752c74bc019c7b20e6791ee813cd6877449e6a1415589d22ff"}, + {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b48616a09d7df9dbae2f45a0256eee7b794b903ddc6d8657a9948669b345f220"}, + {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d4427b4a136e3b7f85516c76dd2e0756c22eec4026afb76ca1397152b0ca8145"}, + {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:26b0358e8933990502f4513c991c9935b6c06af01787a36d133b7c39b1df37fa"}, + {file = "pyzmq-25.0.2-cp36-cp36m-win32.whl", hash = "sha256:c8fedc3ccd62c6b77dfe6f43802057a803a411ee96f14e946f4a76ec4ed0e117"}, + {file = "pyzmq-25.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2da6813b7995b6b1d1307329c73d3e3be2fd2d78e19acfc4eff2e27262732388"}, + {file = "pyzmq-25.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a35960c8b2f63e4ef67fd6731851030df68e4b617a6715dd11b4b10312d19fef"}, + {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2a0b880ab40aca5a878933376cb6c1ec483fba72f7f34e015c0f675c90b20"}, + {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:85762712b74c7bd18e340c3639d1bf2f23735a998d63f46bb6584d904b5e401d"}, + {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:64812f29d6eee565e129ca14b0c785744bfff679a4727137484101b34602d1a7"}, + {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:510d8e55b3a7cd13f8d3e9121edf0a8730b87d925d25298bace29a7e7bc82810"}, + {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b164cc3c8acb3d102e311f2eb6f3c305865ecb377e56adc015cb51f721f1dda6"}, + {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:28fdb9224a258134784a9cf009b59265a9dde79582fb750d4e88a6bcbc6fa3dc"}, + {file = "pyzmq-25.0.2-cp37-cp37m-win32.whl", hash = "sha256:dd771a440effa1c36d3523bc6ba4e54ff5d2e54b4adcc1e060d8f3ca3721d228"}, + {file = "pyzmq-25.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:9bdc40efb679b9dcc39c06d25629e55581e4c4f7870a5e88db4f1c51ce25e20d"}, + {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:1f82906a2d8e4ee310f30487b165e7cc8ed09c009e4502da67178b03083c4ce0"}, + {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21ec0bf4831988af43c8d66ba3ccd81af2c5e793e1bf6790eb2d50e27b3c570a"}, + {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbce982a17c88d2312ec2cf7673985d444f1beaac6e8189424e0a0e0448dbb3"}, + {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e1d2f2d86fc75ed7f8845a992c5f6f1ab5db99747fb0d78b5e4046d041164d2"}, + {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e92ff20ad5d13266bc999a29ed29a3b5b101c21fdf4b2cf420c09db9fb690e"}, + {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edbbf06cc2719889470a8d2bf5072bb00f423e12de0eb9ffec946c2c9748e149"}, + {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77942243ff4d14d90c11b2afd8ee6c039b45a0be4e53fb6fa7f5e4fd0b59da39"}, + {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ab046e9cb902d1f62c9cc0eca055b1d11108bdc271caf7c2171487298f229b56"}, + {file = "pyzmq-25.0.2-cp38-cp38-win32.whl", hash = "sha256:ad761cfbe477236802a7ab2c080d268c95e784fe30cafa7e055aacd1ca877eb0"}, + {file = "pyzmq-25.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8560756318ec7c4c49d2c341012167e704b5a46d9034905853c3d1ade4f55bee"}, + {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ab2c056ac503f25a63f6c8c6771373e2a711b98b304614151dfb552d3d6c81f6"}, + {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cca8524b61c0eaaa3505382dc9b9a3bc8165f1d6c010fdd1452c224225a26689"}, + {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb9f7eae02d3ac42fbedad30006b7407c984a0eb4189a1322241a20944d61e5"}, + {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5eaeae038c68748082137d6896d5c4db7927e9349237ded08ee1bbd94f7361c9"}, + {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a31992a8f8d51663ebf79df0df6a04ffb905063083d682d4380ab8d2c67257c"}, + {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6a979e59d2184a0c8f2ede4b0810cbdd86b64d99d9cc8a023929e40dce7c86cc"}, + {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1f124cb73f1aa6654d31b183810febc8505fd0c597afa127c4f40076be4574e0"}, + {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:65c19a63b4a83ae45d62178b70223adeee5f12f3032726b897431b6553aa25af"}, + {file = "pyzmq-25.0.2-cp39-cp39-win32.whl", hash = "sha256:83d822e8687621bed87404afc1c03d83fa2ce39733d54c2fd52d8829edb8a7ff"}, + {file = "pyzmq-25.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:24683285cc6b7bf18ad37d75b9db0e0fefe58404e7001f1d82bf9e721806daa7"}, + {file = "pyzmq-25.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a4b4261eb8f9ed71f63b9eb0198dd7c934aa3b3972dac586d0ef502ba9ab08b"}, + {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:62ec8d979f56c0053a92b2b6a10ff54b9ec8a4f187db2b6ec31ee3dd6d3ca6e2"}, + {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:affec1470351178e892121b3414c8ef7803269f207bf9bef85f9a6dd11cde264"}, + {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc71111433bd6ec8607a37b9211f4ef42e3d3b271c6d76c813669834764b248"}, + {file = "pyzmq-25.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6fadc60970714d86eff27821f8fb01f8328dd36bebd496b0564a500fe4a9e354"}, + {file = "pyzmq-25.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:269968f2a76c0513490aeb3ba0dc3c77b7c7a11daa894f9d1da88d4a0db09835"}, + {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f7c8b8368e84381ae7c57f1f5283b029c888504aaf4949c32e6e6fb256ec9bf0"}, + {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25e6873a70ad5aa31e4a7c41e5e8c709296edef4a92313e1cd5fc87bbd1874e2"}, + {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b733076ff46e7db5504c5e7284f04a9852c63214c74688bdb6135808531755a3"}, + {file = "pyzmq-25.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a6f6ae12478fdc26a6d5fdb21f806b08fa5403cd02fd312e4cb5f72df078f96f"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:67da1c213fbd208906ab3470cfff1ee0048838365135a9bddc7b40b11e6d6c89"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531e36d9fcd66f18de27434a25b51d137eb546931033f392e85674c7a7cea853"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34a6fddd159ff38aa9497b2e342a559f142ab365576284bc8f77cb3ead1f79c5"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b491998ef886662c1f3d49ea2198055a9a536ddf7430b051b21054f2a5831800"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5d496815074e3e3d183fe2c7fcea2109ad67b74084c254481f87b64e04e9a471"}, + {file = "pyzmq-25.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:56a94ab1d12af982b55ca96c6853db6ac85505e820d9458ac76364c1998972f4"}, + {file = "pyzmq-25.0.2.tar.gz", hash = "sha256:6b8c1bbb70e868dc88801aa532cae6bd4e3b5233784692b786f17ad2962e5149"}, ] rdflib = [ - {file = "rdflib-6.2.0-py3-none-any.whl", hash = "sha256:85c34a86dfc517a41e5f2425a41a0aceacc23983462b32e68610b9fad1383bca"}, - {file = "rdflib-6.2.0.tar.gz", hash = "sha256:62dc3c86d1712db0f55785baf8047f63731fa59b2682be03219cb89262065942"}, + {file = "rdflib-6.3.2-py3-none-any.whl", hash = "sha256:36b4e74a32aa1e4fa7b8719876fb192f19ecd45ff932ea5ebbd2e417a0247e63"}, + {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, ] regex = [ - {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, - {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, - {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, - {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, - {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, - {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, - {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, - {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, - {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, - {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, - {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, - {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, - {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, - {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, - {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, - {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, - {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, + {file = "regex-2023.3.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:845a5e2d84389c4ddada1a9b95c055320070f18bb76512608374aca00d22eca8"}, + {file = "regex-2023.3.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87d9951f5a538dd1d016bdc0dcae59241d15fa94860964833a54d18197fcd134"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae17d3be44c0b3f782c28ae9edd8b47c1f1776d4cabe87edc0b98e1f12b021"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b8eb1e3bca6b48dc721818a60ae83b8264d4089a4a41d62be6d05316ec38e15"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df45fac182ebc3c494460c644e853515cc24f5ad9da05f8ffb91da891bfee879"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7006105b10b59971d3b248ad75acc3651c7e4cf54d81694df5a5130a3c3f7ea"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93f3f1aa608380fe294aa4cb82e2afda07a7598e828d0341e124b8fd9327c715"}, + {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787954f541ab95d8195d97b0b8cf1dc304424adb1e07365967e656b92b38a699"}, + {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20abe0bdf03630fe92ccafc45a599bca8b3501f48d1de4f7d121153350a2f77d"}, + {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11d00c31aeab9a6e0503bc77e73ed9f4527b3984279d997eb145d7c7be6268fd"}, + {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d5bbe0e1511b844794a3be43d6c145001626ba9a6c1db8f84bdc724e91131d9d"}, + {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ea3c0cb56eadbf4ab2277e7a095676370b3e46dbfc74d5c383bd87b0d6317910"}, + {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d895b4c863059a4934d3e874b90998df774644a41b349ebb330f85f11b4ef2c0"}, + {file = "regex-2023.3.23-cp310-cp310-win32.whl", hash = "sha256:9d764514d19b4edcc75fd8cb1423448ef393e8b6cbd94f38cab983ab1b75855d"}, + {file = "regex-2023.3.23-cp310-cp310-win_amd64.whl", hash = "sha256:11d1f2b7a0696dc0310de0efb51b1f4d813ad4401fe368e83c0c62f344429f98"}, + {file = "regex-2023.3.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8a9c63cde0eaa345795c0fdeb19dc62d22e378c50b0bc67bf4667cd5b482d98b"}, + {file = "regex-2023.3.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dd7200b4c27b68cf9c9646da01647141c6db09f48cc5b51bc588deaf8e98a797"}, + {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22720024b90a6ba673a725dcc62e10fb1111b889305d7c6b887ac7466b74bedb"}, + {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b190a339090e6af25f4a5fd9e77591f6d911cc7b96ecbb2114890b061be0ac1"}, + {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e76b6fc0d8e9efa39100369a9b3379ce35e20f6c75365653cf58d282ad290f6f"}, + {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7868b8f218bf69a2a15402fde08b08712213a1f4b85a156d90473a6fb6b12b09"}, + {file = "regex-2023.3.23-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2472428efc4127374f494e570e36b30bb5e6b37d9a754f7667f7073e43b0abdd"}, + {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c37df2a060cb476d94c047b18572ee2b37c31f831df126c0da3cd9227b39253d"}, + {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4479f9e2abc03362df4045b1332d4a2b7885b245a30d4f4b051c4083b97d95d8"}, + {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2396e0678167f2d0c197da942b0b3fb48fee2f0b5915a0feb84d11b6686afe6"}, + {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75f288c60232a5339e0ff2fa05779a5e9c74e9fc085c81e931d4a264501e745b"}, + {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c869260aa62cee21c5eb171a466c0572b5e809213612ef8d495268cd2e34f20d"}, + {file = "regex-2023.3.23-cp311-cp311-win32.whl", hash = "sha256:25f0532fd0c53e96bad84664171969de9673b4131f2297f1db850d3918d58858"}, + {file = "regex-2023.3.23-cp311-cp311-win_amd64.whl", hash = "sha256:5ccfafd98473e007cebf7da10c1411035b7844f0f204015efd050601906dbb53"}, + {file = "regex-2023.3.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6572ff287176c0fb96568adb292674b421fa762153ed074d94b1d939ed92c253"}, + {file = "regex-2023.3.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a610e0adfcb0fc84ea25f6ea685e39e74cbcd9245a72a9a7aab85ff755a5ed27"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086afe222d58b88b62847bdbd92079b4699350b4acab892f88a935db5707c790"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79e29fd62fa2f597a6754b247356bda14b866131a22444d67f907d6d341e10f3"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c07ce8e9eee878a48ebeb32ee661b49504b85e164b05bebf25420705709fdd31"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b036f401895e854de9fefe061518e78d506d8a919cc250dc3416bca03f6f9a"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78ac8dd8e18800bb1f97aad0d73f68916592dddf233b99d2b5cabc562088503a"}, + {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:539dd010dc35af935b32f248099e38447bbffc10b59c2b542bceead2bed5c325"}, + {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9bf4a5626f2a0ea006bf81e8963f498a57a47d58907eaa58f4b3e13be68759d8"}, + {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf86b4328c204c3f315074a61bc1c06f8a75a8e102359f18ce99fbcbbf1951f0"}, + {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2848bf76673c83314068241c8d5b7fa9ad9bed866c979875a0e84039349e8fa7"}, + {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c125a02d22c555e68f7433bac8449992fa1cead525399f14e47c2d98f2f0e467"}, + {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cd1671e9d5ac05ce6aa86874dd8dfa048824d1dbe73060851b310c6c1a201a96"}, + {file = "regex-2023.3.23-cp38-cp38-win32.whl", hash = "sha256:fffe57312a358be6ec6baeb43d253c36e5790e436b7bf5b7a38df360363e88e9"}, + {file = "regex-2023.3.23-cp38-cp38-win_amd64.whl", hash = "sha256:dbb3f87e15d3dd76996d604af8678316ad2d7d20faa394e92d9394dfd621fd0c"}, + {file = "regex-2023.3.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c88e8c226473b5549fe9616980ea7ca09289246cfbdf469241edf4741a620004"}, + {file = "regex-2023.3.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6560776ec19c83f3645bbc5db64a7a5816c9d8fb7ed7201c5bcd269323d88072"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b1fc2632c01f42e06173d8dd9bb2e74ab9b0afa1d698058c867288d2c7a31f3"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdf7ad455f1916b8ea5cdbc482d379f6daf93f3867b4232d14699867a5a13af7"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5fc33b27b1d800fc5b78d7f7d0f287e35079ecabe68e83d46930cf45690e1c8c"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c49552dc938e3588f63f8a78c86f3c9c75301e813bca0bef13bdb4b87ccf364"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e152461e9a0aedec7d37fc66ec0fa635eca984777d3d3c3e36f53bf3d3ceb16e"}, + {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:db034255e72d2995cf581b14bb3fc9c00bdbe6822b49fcd4eef79e1d5f232618"}, + {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:55ae114da21b7a790b90255ea52d2aa3a0d121a646deb2d3c6a3194e722fc762"}, + {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ef3f528fe1cc3d139508fe1b22523745aa77b9d6cb5b0bf277f48788ee0b993f"}, + {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:a81c9ec59ca2303acd1ccd7b9ac409f1e478e40e96f8f79b943be476c5fdb8bb"}, + {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cde09c4fdd070772aa2596d97e942eb775a478b32459e042e1be71b739d08b77"}, + {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3cd9f5dd7b821f141d3a6ca0d5d9359b9221e4f051ca3139320adea9f1679691"}, + {file = "regex-2023.3.23-cp39-cp39-win32.whl", hash = "sha256:7304863f3a652dab5e68e6fb1725d05ebab36ec0390676d1736e0571ebb713ef"}, + {file = "regex-2023.3.23-cp39-cp39-win_amd64.whl", hash = "sha256:54c3fa855a3f7438149de3211738dd9b5f0c733f48b54ae05aa7fce83d48d858"}, + {file = "regex-2023.3.23.tar.gz", hash = "sha256:dc80df325b43ffea5cdea2e3eaa97a44f3dd298262b1c7fe9dbb2a9522b956a7"}, ] requests = [ - {file = "requests-2.28.2-py3-none-any.whl", hash = "sha256:64299f4909223da747622c030b781c0d7811e359c37124b4bd368fb8c6518baa"}, - {file = "requests-2.28.2.tar.gz", hash = "sha256:98b1b2782e3c6c4904938b84c0eb932721069dfdb9134313beff7c83c2df24bf"}, + {file = "requests-2.29.0-py3-none-any.whl", hash = "sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b"}, + {file = "requests-2.29.0.tar.gz", hash = "sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"}, ] requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, @@ -4014,7 +3990,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, @@ -4073,8 +4048,8 @@ secretstorage = [ {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, ] send2trash = [ - {file = "Send2Trash-1.8.0-py3-none-any.whl", hash = "sha256:f20eaadfdb517eaca5ce077640cb261c7d2698385a6a0f072a4a5447fd49fa08"}, - {file = "Send2Trash-1.8.0.tar.gz", hash = "sha256:d2c24762fd3759860a0aff155e45871447ea58d2be6bdd39b5c8f966a0c99c2d"}, + {file = "Send2Trash-1.8.2-py3-none-any.whl", hash = "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679"}, + {file = "Send2Trash-1.8.2.tar.gz", hash = "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312"}, ] setuptools = [ {file = "setuptools-66.1.1-py3-none-any.whl", hash = "sha256:6f590d76b713d5de4e49fe4fbca24474469f53c83632d5d0fd056f7ff7e8112b"}, @@ -4093,12 +4068,12 @@ snowballstemmer = [ {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, ] soupsieve = [ - {file = "soupsieve-2.4-py3-none-any.whl", hash = "sha256:49e5368c2cda80ee7e84da9dbe3e110b70a4575f196efb74e51b94549d921955"}, - {file = "soupsieve-2.4.tar.gz", hash = "sha256:e28dba9ca6c7c00173e34e4ba57448f0688bb681b7c5e8bf4971daafc093d69a"}, + {file = "soupsieve-2.4.1-py3-none-any.whl", hash = "sha256:1c1bfee6819544a3447586c889157365a27e10d88cde3ad3da0cf0ddf646feb8"}, + {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] sphinx = [ - {file = "Sphinx-6.1.3.tar.gz", hash = "sha256:0dac3b698538ffef41716cf97ba26c1c7788dba73ce6f150c1ff5b4720786dd2"}, - {file = "sphinx-6.1.3-py3-none-any.whl", hash = "sha256:807d1cb3d6be87eb78a381c3e70ebd8d346b9a25f3753e9947e866b2786865fc"}, + {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, + {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, ] sphinx-click = [ {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, @@ -4129,47 +4104,47 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.46-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:7001f16a9a8e06488c3c7154827c48455d1c1507d7228d43e781afbc8ceccf6d"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:c7a46639ba058d320c9f53a81db38119a74b8a7a1884df44d09fbe807d028aaf"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-win32.whl", hash = "sha256:c04144a24103135ea0315d459431ac196fe96f55d3213bfd6d39d0247775c854"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27m-win_amd64.whl", hash = "sha256:7b81b1030c42b003fc10ddd17825571603117f848814a344d305262d370e7c34"}, - {file = "SQLAlchemy-1.4.46-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:939f9a018d2ad04036746e15d119c0428b1e557470361aa798e6e7d7f5875be0"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:b7f4b6aa6e87991ec7ce0e769689a977776db6704947e562102431474799a857"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf17ac9a61e7a3f1c7ca47237aac93cabd7f08ad92ac5b96d6f8dea4287fc1"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7f8267682eb41a0584cf66d8a697fef64b53281d01c93a503e1344197f2e01fe"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64cb0ad8a190bc22d2112001cfecdec45baffdf41871de777239da6a28ed74b6"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-win32.whl", hash = "sha256:5f752676fc126edc1c4af0ec2e4d2adca48ddfae5de46bb40adbd3f903eb2120"}, - {file = "SQLAlchemy-1.4.46-cp310-cp310-win_amd64.whl", hash = "sha256:31de1e2c45e67a5ec1ecca6ec26aefc299dd5151e355eb5199cd9516b57340be"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d68e1762997bfebf9e5cf2a9fd0bcf9ca2fdd8136ce7b24bbd3bbfa4328f3e4a"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d112b0f3c1bc5ff70554a97344625ef621c1bfe02a73c5d97cac91f8cd7a41e"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69fac0a7054d86b997af12dc23f581cf0b25fb1c7d1fed43257dee3af32d3d6d"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-win32.whl", hash = "sha256:887865924c3d6e9a473dc82b70977395301533b3030d0f020c38fd9eba5419f2"}, - {file = "SQLAlchemy-1.4.46-cp311-cp311-win_amd64.whl", hash = "sha256:984ee13543a346324319a1fb72b698e521506f6f22dc37d7752a329e9cd00a32"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:9167d4227b56591a4cc5524f1b79ccd7ea994f36e4c648ab42ca995d28ebbb96"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d61e9ecc849d8d44d7f80894ecff4abe347136e9d926560b818f6243409f3c86"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3ec187acf85984263299a3f15c34a6c0671f83565d86d10f43ace49881a82718"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9883f5fae4fd8e3f875adc2add69f8b945625811689a6c65866a35ee9c0aea23"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-win32.whl", hash = "sha256:535377e9b10aff5a045e3d9ada8a62d02058b422c0504ebdcf07930599890eb0"}, - {file = "SQLAlchemy-1.4.46-cp36-cp36m-win_amd64.whl", hash = "sha256:18cafdb27834fa03569d29f571df7115812a0e59fd6a3a03ccb0d33678ec8420"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:a1ad90c97029cc3ab4ffd57443a20fac21d2ec3c89532b084b073b3feb5abff3"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4847f4b1d822754e35707db913396a29d874ee77b9c3c3ef3f04d5a9a6209618"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a99282848b6cae0056b85da17392a26b2d39178394fc25700bcf967e06e97a"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4b1cc7835b39835c75cf7c20c926b42e97d074147c902a9ebb7cf2c840dc4e2"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-win32.whl", hash = "sha256:c522e496f9b9b70296a7675272ec21937ccfc15da664b74b9f58d98a641ce1b6"}, - {file = "SQLAlchemy-1.4.46-cp37-cp37m-win_amd64.whl", hash = "sha256:ae067ab639fa499f67ded52f5bc8e084f045d10b5ac7bb928ae4ca2b6c0429a5"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:e3c1808008124850115a3f7e793a975cfa5c8a26ceeeb9ff9cbb4485cac556df"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d164df3d83d204c69f840da30b292ac7dc54285096c6171245b8d7807185aa"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b33ffbdbbf5446cf36cd4cc530c9d9905d3c2fe56ed09e25c22c850cdb9fac92"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d94682732d1a0def5672471ba42a29ff5e21bb0aae0afa00bb10796fc1e28dd"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-win32.whl", hash = "sha256:f8cb80fe8d14307e4124f6fad64dfd87ab749c9d275f82b8b4ec84c84ecebdbe"}, - {file = "SQLAlchemy-1.4.46-cp38-cp38-win_amd64.whl", hash = "sha256:07e48cbcdda6b8bc7a59d6728bd3f5f574ffe03f2c9fb384239f3789c2d95c2e"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:1b1e5e96e2789d89f023d080bee432e2fef64d95857969e70d3cadec80bd26f0"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3714e5b33226131ac0da60d18995a102a17dddd42368b7bdd206737297823ad"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:955162ad1a931fe416eded6bb144ba891ccbf9b2e49dc7ded39274dd9c5affc5"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6e4cb5c63f705c9d546a054c60d326cbde7421421e2d2565ce3e2eee4e1a01f"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-win32.whl", hash = "sha256:51e1ba2884c6a2b8e19109dc08c71c49530006c1084156ecadfaadf5f9b8b053"}, - {file = "SQLAlchemy-1.4.46-cp39-cp39-win_amd64.whl", hash = "sha256:315676344e3558f1f80d02535f410e80ea4e8fddba31ec78fe390eff5fb8f466"}, - {file = "SQLAlchemy-1.4.46.tar.gz", hash = "sha256:6913b8247d8a292ef8315162a51931e2b40ce91681f1b6f18f697045200c4a30"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:dcfb480bfc9e1fab726003ae00a6bfc67a29bad275b63a4e36d17fe7f13a624e"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28fda5a69d6182589892422c5a9b02a8fd1125787aab1d83f1392aa955bf8d0a"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-win32.whl", hash = "sha256:45e799c1a41822eba6bee4e59b0e38764e1a1ee69873ab2889079865e9ea0e23"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27m-win_amd64.whl", hash = "sha256:10edbb92a9ef611f01b086e271a9f6c1c3e5157c3b0c5ff62310fb2187acbd4a"}, + {file = "SQLAlchemy-1.4.47-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7a4df53472c9030a8ddb1cce517757ba38a7a25699bbcabd57dcc8a5d53f324e"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:511d4abc823152dec49461209607bbfb2df60033c8c88a3f7c93293b8ecbb13d"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbe57f39f531c5d68d5594ea4613daa60aba33bb51a8cc42f96f17bbd6305e8d"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca8ab6748e3ec66afccd8b23ec2f92787a58d5353ce9624dccd770427ee67c82"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299b5c5c060b9fbe51808d0d40d8475f7b3873317640b9b7617c7f988cf59fda"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-win32.whl", hash = "sha256:684e5c773222781775c7f77231f412633d8af22493bf35b7fa1029fdf8066d10"}, + {file = "SQLAlchemy-1.4.47-cp310-cp310-win_amd64.whl", hash = "sha256:2bba39b12b879c7b35cde18b6e14119c5f1a16bd064a48dd2ac62d21366a5e17"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:795b5b9db573d3ed61fae74285d57d396829e3157642794d3a8f72ec2a5c719b"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:989c62b96596b7938cbc032e39431e6c2d81b635034571d6a43a13920852fb65"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b67bda733da1dcdccaf354e71ef01b46db483a4f6236450d3f9a61efdba35a"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-win32.whl", hash = "sha256:9a198f690ac12a3a807e03a5a45df6a30cd215935f237a46f4248faed62e69c8"}, + {file = "SQLAlchemy-1.4.47-cp311-cp311-win_amd64.whl", hash = "sha256:03be6f3cb66e69fb3a09b5ea89d77e4bc942f3bf84b207dba84666a26799c166"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:16ee6fea316790980779268da47a9260d5dd665c96f225d28e7750b0bb2e2a04"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557675e0befafa08d36d7a9284e8761c97490a248474d778373fb96b0d7fd8de"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb2797fee8a7914fb2c3dc7de404d3f96eb77f20fc60e9ee38dc6b0ca720f2c2"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28297aa29e035f29cba6b16aacd3680fbc6a9db682258d5f2e7b49ec215dbe40"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-win32.whl", hash = "sha256:998e782c8d9fd57fa8704d149ccd52acf03db30d7dd76f467fd21c1c21b414fa"}, + {file = "SQLAlchemy-1.4.47-cp36-cp36m-win_amd64.whl", hash = "sha256:dde4d02213f1deb49eaaf8be8a6425948963a7af84983b3f22772c63826944de"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e98ef1babe34f37f443b7211cd3ee004d9577a19766e2dbacf62fce73c76245a"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14a3879853208a242b5913f3a17c6ac0eae9dc210ff99c8f10b19d4a1ed8ed9b"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7120a2f72599d4fed7c001fa1cbbc5b4d14929436135768050e284f53e9fbe5e"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:048509d7f3ac27b83ad82fd96a1ab90a34c8e906e4e09c8d677fc531d12c23c5"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-win32.whl", hash = "sha256:6572d7c96c2e3e126d0bb27bfb1d7e2a195b68d951fcc64c146b94f088e5421a"}, + {file = "SQLAlchemy-1.4.47-cp37-cp37m-win_amd64.whl", hash = "sha256:a6c3929df5eeaf3867724003d5c19fed3f0c290f3edc7911616616684f200ecf"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71d4bf7768169c4502f6c2b0709a02a33703544f611810fb0c75406a9c576ee1"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd45c60cc4f6d68c30d5179e2c2c8098f7112983532897566bb69c47d87127d3"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fdbb8e9d4e9003f332a93d6a37bca48ba8095086c97a89826a136d8eddfc455"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f216a51451a0a0466e082e163591f6dcb2f9ec182adb3f1f4b1fd3688c7582c"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-win32.whl", hash = "sha256:bd988b3362d7e586ef581eb14771bbb48793a4edb6fcf62da75d3f0f3447060b"}, + {file = "SQLAlchemy-1.4.47-cp38-cp38-win_amd64.whl", hash = "sha256:32ab09f2863e3de51529aa84ff0e4fe89a2cb1bfbc11e225b6dbc60814e44c94"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:07764b240645627bc3e82596435bd1a1884646bfc0721642d24c26b12f1df194"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e2a42017984099ef6f56438a6b898ce0538f6fadddaa902870c5aa3e1d82583"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b6d807c76c20b4bc143a49ad47782228a2ac98bdcdcb069da54280e138847fc"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a94632ba26a666e7be0a7d7cc3f7acab622a04259a3aa0ee50ff6d44ba9df0d"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-win32.whl", hash = "sha256:f80915681ea9001f19b65aee715115f2ad310730c8043127cf3e19b3009892dd"}, + {file = "SQLAlchemy-1.4.47-cp39-cp39-win_amd64.whl", hash = "sha256:fc700b862e0a859a37faf85367e205e7acaecae5a098794aff52fdd8aea77b12"}, + {file = "SQLAlchemy-1.4.47.tar.gz", hash = "sha256:95fc02f7fc1f3199aaa47a8a757437134cf618e9d994c84effd53f530c38586f"}, ] sqlalchemy-utils = [ {file = "SQLAlchemy-Utils-0.38.3.tar.gz", hash = "sha256:9f9afba607a40455cf703adfa9846584bf26168a0c5a60a70063b70d65051f4d"}, @@ -4184,12 +4159,12 @@ swagger-ui-bundle = [ {file = "swagger_ui_bundle-0.0.9.tar.gz", hash = "sha256:b462aa1460261796ab78fd4663961a7f6f347ce01760f1303bbbdf630f11f516"}, ] synapseclient = [ - {file = "synapseclient-2.7.0-py3-none-any.whl", hash = "sha256:29f5e3c87474cb2629e9ce77c97e81e80a08f24ec2c5889f9fba14530b8c4bf7"}, - {file = "synapseclient-2.7.0.tar.gz", hash = "sha256:241f170f0e8c8c3735cd73f81711e592a581c55f7a5c4566be7bee82d72a56bc"}, + {file = "synapseclient-2.7.1-py3-none-any.whl", hash = "sha256:c15efaec148dda18faa5a1736846f427713ceaa656178d5e7044fcd87fa8aa05"}, + {file = "synapseclient-2.7.1.tar.gz", hash = "sha256:c6a7d5ff834c825390a0514f3f0020876ea4fb8c863889894b9a636458278d69"}, ] tenacity = [ - {file = "tenacity-8.2.1-py3-none-any.whl", hash = "sha256:dd1b769ca7002fda992322939feca5bee4fa11f39146b0af14e0b8d9f27ea854"}, - {file = "tenacity-8.2.1.tar.gz", hash = "sha256:c7bb4b86425b977726a7b49971542d4f67baf72096597d283f3ffd01f33b92df"}, + {file = "tenacity-8.2.2-py3-none-any.whl", hash = "sha256:2f277afb21b851637e8f52e6a613ff08734c347dc19ade928e519d7d2d8569b0"}, + {file = "tenacity-8.2.2.tar.gz", hash = "sha256:43af037822bd0029025877f3b2d97cc4d7bb0c2991000a3d59d71517c5c969e0"}, ] terminado = [ {file = "terminado-0.17.1-py3-none-any.whl", hash = "sha256:8650d44334eba354dd591129ca3124a6ba42c3d5b70df5051b6921d506fdaeae"}, @@ -4208,29 +4183,29 @@ tomli = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] tomlkit = [ - {file = "tomlkit-0.11.6-py3-none-any.whl", hash = "sha256:07de26b0d8cfc18f871aec595fda24d95b08fef89d147caa861939f37230bf4b"}, - {file = "tomlkit-0.11.6.tar.gz", hash = "sha256:71b952e5721688937fb02cf9d354dbcf0785066149d2855e44531ebdd2b65d73"}, + {file = "tomlkit-0.11.8-py3-none-any.whl", hash = "sha256:8c726c4c202bdb148667835f68d68780b9a003a9ec34167b6c673b38eff2a171"}, + {file = "tomlkit-0.11.8.tar.gz", hash = "sha256:9330fc7faa1db67b541b28e62018c17d20be733177d290a13b24c62d1614e0c3"}, ] toolz = [ {file = "toolz-0.12.0-py3-none-any.whl", hash = "sha256:2059bd4148deb1884bb0eb770a3cde70e7f954cfbbdc2285f1f2de01fd21eb6f"}, {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, ] tornado = [ - {file = "tornado-6.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:20f638fd8cc85f3cbae3c732326e96addff0a15e22d80f049e00121651e82e72"}, - {file = "tornado-6.2-cp37-abi3-macosx_10_9_x86_64.whl", hash = "sha256:87dcafae3e884462f90c90ecc200defe5e580a7fbbb4365eda7c7c1eb809ebc9"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba09ef14ca9893954244fd872798b4ccb2367c165946ce2dd7376aebdde8e3ac"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8150f721c101abdef99073bf66d3903e292d851bee51910839831caba341a75"}, - {file = "tornado-6.2-cp37-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3a2f5999215a3a06a4fc218026cd84c61b8b2b40ac5296a6db1f1451ef04c1e"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:5f8c52d219d4995388119af7ccaa0bcec289535747620116a58d830e7c25d8a8"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_i686.whl", hash = "sha256:6fdfabffd8dfcb6cf887428849d30cf19a3ea34c2c248461e1f7d718ad30b66b"}, - {file = "tornado-6.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:1d54d13ab8414ed44de07efecb97d4ef7c39f7438cf5e976ccd356bebb1b5fca"}, - {file = "tornado-6.2-cp37-abi3-win32.whl", hash = "sha256:5c87076709343557ef8032934ce5f637dbb552efa7b21d08e89ae7619ed0eb23"}, - {file = "tornado-6.2-cp37-abi3-win_amd64.whl", hash = "sha256:e5f923aa6a47e133d1cf87d60700889d7eae68988704e20c75fb2d65677a8e4b"}, - {file = "tornado-6.2.tar.gz", hash = "sha256:9b630419bde84ec666bfd7ea0a4cb2a8a651c2d5cccdbdd1972a0c859dfc3c13"}, + {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:db181eb3df8738613ff0a26f49e1b394aade05034b01200a63e9662f347d4415"}, + {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b4e7b956f9b5e6f9feb643ea04f07e7c6b49301e03e0023eedb01fa8cf52f579"}, + {file = "tornado-6.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661aa8bc0e9d83d757cd95b6f6d1ece8ca9fd1ccdd34db2de381e25bf818233"}, + {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81c17e0cc396908a5e25dc8e9c5e4936e6dfd544c9290be48bd054c79bcad51e"}, + {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27a1cfa9997923f80bdd962b3aab048ac486ad8cfb2f237964f8ab7f7eb824b"}, + {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d7117f3c7ba5d05813b17a1f04efc8e108a1b811ccfddd9134cc68553c414864"}, + {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:ffdce65a281fd708da5a9def3bfb8f364766847fa7ed806821a69094c9629e8a"}, + {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:90f569a35a8ec19bde53aa596952071f445da678ec8596af763b9b9ce07605e6"}, + {file = "tornado-6.3.1-cp38-abi3-win32.whl", hash = "sha256:3455133b9ff262fd0a75630af0a8ee13564f25fb4fd3d9ce239b8a7d3d027bf8"}, + {file = "tornado-6.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:1285f0691143f7ab97150831455d4db17a267b59649f7bd9700282cba3d5e771"}, + {file = "tornado-6.3.1.tar.gz", hash = "sha256:5e2f49ad371595957c50e42dd7e5c14d64a6843a3cf27352b69c706d1b5918af"}, ] tqdm = [ - {file = "tqdm-4.64.1-py2.py3-none-any.whl", hash = "sha256:6fee160d6ffcd1b1c68c65f14c829c22832bc401726335ce92c52d395944a6a1"}, - {file = "tqdm-4.64.1.tar.gz", hash = "sha256:5f4f682a004951c1b450bc753c710e9280c5746ce6ffedee253ddbcbf54cf1e4"}, + {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, + {file = "tqdm-4.65.0.tar.gz", hash = "sha256:1871fb68a86b8fb3b59ca4cdd3dcccbc7e6d613eeed31f4c332531977b89beb5"}, ] traitlets = [ {file = "traitlets-5.9.0-py3-none-any.whl", hash = "sha256:9e6ec080259b9a5940c797d58b613b5e31441c2257b87c2e795c5228ae80d2d8"}, @@ -4241,12 +4216,12 @@ typing-extensions = [ {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] tzdata = [ - {file = "tzdata-2022.7-py2.py3-none-any.whl", hash = "sha256:2b88858b0e3120792a3c0635c23daf36a7d7eeeca657c323da299d2094402a0d"}, - {file = "tzdata-2022.7.tar.gz", hash = "sha256:fe5f866eddd8b96e9fcba978f8e503c909b19ea7efda11e52e39494bad3a7bfa"}, + {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, + {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] tzlocal = [ - {file = "tzlocal-4.2-py3-none-any.whl", hash = "sha256:89885494684c929d9191c57aa27502afc87a579be5cdd3225c77c463ea043745"}, - {file = "tzlocal-4.2.tar.gz", hash = "sha256:ee5842fa3a795f023514ac2d801c4a81d1743bbe642e3940143326b3a00addd7"}, + {file = "tzlocal-4.3-py3-none-any.whl", hash = "sha256:b44c4388f3d34f25862cfbb387578a4d70fec417649da694a132f628a23367e2"}, + {file = "tzlocal-4.3.tar.gz", hash = "sha256:3f21d09e1b2aa9f2dacca12da240ca37de3ba5237a93addfd6d593afe9073355"}, ] uri-template = [ {file = "uri_template-1.2.0-py3-none-any.whl", hash = "sha256:f1699c77b73b925cf4937eae31ab282a86dc885c333f2e942513f08f691fc7db"}, @@ -4257,16 +4232,16 @@ uritemplate = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] urllib3 = [ - {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, - {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, + {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, + {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, ] wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, ] webcolors = [ - {file = "webcolors-1.12-py3-none-any.whl", hash = "sha256:d98743d81d498a2d3eaf165196e65481f0d2ea85281463d856b1e51b09f62dce"}, - {file = "webcolors-1.12.tar.gz", hash = "sha256:16d043d3a08fd6a1b1b7e3e9e62640d09790dce80d2bdd4792a175b35fe794a9"}, + {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, + {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, ] webencodings = [ {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, @@ -4281,76 +4256,87 @@ werkzeug = [ {file = "Werkzeug-2.1.2.tar.gz", hash = "sha256:1ce08e8093ed67d638d63879fd1ba3735817f7a80de3674d293f5984f25fb6e6"}, ] widgetsnbextension = [ - {file = "widgetsnbextension-4.0.5-py3-none-any.whl", hash = "sha256:eaaaf434fb9b08bd197b2a14ffe45ddb5ac3897593d43c69287091e5f3147bf7"}, - {file = "widgetsnbextension-4.0.5.tar.gz", hash = "sha256:003f716d930d385be3fd9de42dd9bf008e30053f73bddde235d14fbeaeff19af"}, + {file = "widgetsnbextension-4.0.7-py3-none-any.whl", hash = "sha256:be3228a73bbab189a16be2d4a3cd89ecbd4e31948bfdc64edac17dcdee3cd99c"}, + {file = "widgetsnbextension-4.0.7.tar.gz", hash = "sha256:ea67c17a7cd4ae358f8f46c3b304c40698bc0423732e3f273321ee141232c8be"}, ] wrapt = [ - {file = "wrapt-1.14.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1b376b3f4896e7930f1f772ac4b064ac12598d1c38d04907e696cc4d794b43d3"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:903500616422a40a98a5a3c4ff4ed9d0066f3b4c951fa286018ecdf0750194ef"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5a9a0d155deafd9448baff28c08e150d9b24ff010e899311ddd63c45c2445e28"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:ddaea91abf8b0d13443f6dac52e89051a5063c7d014710dcb4d4abb2ff811a59"}, - {file = "wrapt-1.14.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:36f582d0c6bc99d5f39cd3ac2a9062e57f3cf606ade29a0a0d6b323462f4dd87"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7ef58fb89674095bfc57c4069e95d7a31cfdc0939e2a579882ac7d55aadfd2a1"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:e2f83e18fe2f4c9e7db597e988f72712c0c3676d337d8b101f6758107c42425b"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:ee2b1b1769f6707a8a445162ea16dddf74285c3964f605877a20e38545c3c462"}, - {file = "wrapt-1.14.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:833b58d5d0b7e5b9832869f039203389ac7cbf01765639c7309fd50ef619e0b1"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:80bb5c256f1415f747011dc3604b59bc1f91c6e7150bd7db03b19170ee06b320"}, - {file = "wrapt-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:07f7a7d0f388028b2df1d916e94bbb40624c59b48ecc6cbc232546706fac74c2"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02b41b633c6261feff8ddd8d11c711df6842aba629fdd3da10249a53211a72c4"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2fe803deacd09a233e4762a1adcea5db5d31e6be577a43352936179d14d90069"}, - {file = "wrapt-1.14.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:257fd78c513e0fb5cdbe058c27a0624c9884e735bbd131935fd49e9fe719d310"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4fcc4649dc762cddacd193e6b55bc02edca674067f5f98166d7713b193932b7f"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11871514607b15cfeb87c547a49bca19fde402f32e2b1c24a632506c0a756656"}, - {file = "wrapt-1.14.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8ad85f7f4e20964db4daadcab70b47ab05c7c1cf2a7c1e51087bfaa83831854c"}, - {file = "wrapt-1.14.1-cp310-cp310-win32.whl", hash = "sha256:a9a52172be0b5aae932bef82a79ec0a0ce87288c7d132946d645eba03f0ad8a8"}, - {file = "wrapt-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:6d323e1554b3d22cfc03cd3243b5bb815a51f5249fdcbb86fda4bf62bab9e164"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:43ca3bbbe97af00f49efb06e352eae40434ca9d915906f77def219b88e85d907"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:6b1a564e6cb69922c7fe3a678b9f9a3c54e72b469875aa8018f18b4d1dd1adf3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:00b6d4ea20a906c0ca56d84f93065b398ab74b927a7a3dbd470f6fc503f95dc3"}, - {file = "wrapt-1.14.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:a85d2b46be66a71bedde836d9e41859879cc54a2a04fad1191eb50c2066f6e9d"}, - {file = "wrapt-1.14.1-cp35-cp35m-win32.whl", hash = "sha256:dbcda74c67263139358f4d188ae5faae95c30929281bc6866d00573783c422b7"}, - {file = "wrapt-1.14.1-cp35-cp35m-win_amd64.whl", hash = "sha256:b21bb4c09ffabfa0e85e3a6b623e19b80e7acd709b9f91452b8297ace2a8ab00"}, - {file = "wrapt-1.14.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:9e0fd32e0148dd5dea6af5fee42beb949098564cc23211a88d799e434255a1f4"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9736af4641846491aedb3c3f56b9bc5568d92b0692303b5a305301a95dfd38b1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5b02d65b9ccf0ef6c34cba6cf5bf2aab1bb2f49c6090bafeecc9cd81ad4ea1c1"}, - {file = "wrapt-1.14.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21ac0156c4b089b330b7666db40feee30a5d52634cc4560e1905d6529a3897ff"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:9f3e6f9e05148ff90002b884fbc2a86bd303ae847e472f44ecc06c2cd2fcdb2d"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6e743de5e9c3d1b7185870f480587b75b1cb604832e380d64f9504a0535912d1"}, - {file = "wrapt-1.14.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:d79d7d5dc8a32b7093e81e97dad755127ff77bcc899e845f41bf71747af0c569"}, - {file = "wrapt-1.14.1-cp36-cp36m-win32.whl", hash = "sha256:81b19725065dcb43df02b37e03278c011a09e49757287dca60c5aecdd5a0b8ed"}, - {file = "wrapt-1.14.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b014c23646a467558be7da3d6b9fa409b2c567d2110599b7cf9a0c5992b3b471"}, - {file = "wrapt-1.14.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:88bd7b6bd70a5b6803c1abf6bca012f7ed963e58c68d76ee20b9d751c74a3248"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5901a312f4d14c59918c221323068fad0540e34324925c8475263841dbdfe68"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d77c85fedff92cf788face9bfa3ebaa364448ebb1d765302e9af11bf449ca36d"}, - {file = "wrapt-1.14.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d649d616e5c6a678b26d15ece345354f7c2286acd6db868e65fcc5ff7c24a77"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7d2872609603cb35ca513d7404a94d6d608fc13211563571117046c9d2bcc3d7"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:ee6acae74a2b91865910eef5e7de37dc6895ad96fa23603d1d27ea69df545015"}, - {file = "wrapt-1.14.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2b39d38039a1fdad98c87279b48bc5dce2c0ca0d73483b12cb72aa9609278e8a"}, - {file = "wrapt-1.14.1-cp37-cp37m-win32.whl", hash = "sha256:60db23fa423575eeb65ea430cee741acb7c26a1365d103f7b0f6ec412b893853"}, - {file = "wrapt-1.14.1-cp37-cp37m-win_amd64.whl", hash = "sha256:709fe01086a55cf79d20f741f39325018f4df051ef39fe921b1ebe780a66184c"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c0ce1e99116d5ab21355d8ebe53d9460366704ea38ae4d9f6933188f327b456"}, - {file = "wrapt-1.14.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e3fb1677c720409d5f671e39bac6c9e0e422584e5f518bfd50aa4cbbea02433f"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642c2e7a804fcf18c222e1060df25fc210b9c58db7c91416fb055897fc27e8cc"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b7c050ae976e286906dd3f26009e117eb000fb2cf3533398c5ad9ccc86867b1"}, - {file = "wrapt-1.14.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef3f72c9666bba2bab70d2a8b79f2c6d2c1a42a7f7e2b0ec83bb2f9e383950af"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:01c205616a89d09827986bc4e859bcabd64f5a0662a7fe95e0d359424e0e071b"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5a0f54ce2c092aaf439813735584b9537cad479575a09892b8352fea5e988dc0"}, - {file = "wrapt-1.14.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2cf71233a0ed05ccdabe209c606fe0bac7379fdcf687f39b944420d2a09fdb57"}, - {file = "wrapt-1.14.1-cp38-cp38-win32.whl", hash = "sha256:aa31fdcc33fef9eb2552cbcbfee7773d5a6792c137b359e82879c101e98584c5"}, - {file = "wrapt-1.14.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1967f46ea8f2db647c786e78d8cc7e4313dbd1b0aca360592d8027b8508e24d"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3232822c7d98d23895ccc443bbdf57c7412c5a65996c30442ebe6ed3df335383"}, - {file = "wrapt-1.14.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:988635d122aaf2bdcef9e795435662bcd65b02f4f4c1ae37fbee7401c440b3a7"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cca3c2cdadb362116235fdbd411735de4328c61425b0aa9f872fd76d02c4e86"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d52a25136894c63de15a35bc0bdc5adb4b0e173b9c0d07a2be9d3ca64a332735"}, - {file = "wrapt-1.14.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40e7bc81c9e2b2734ea4bc1aceb8a8f0ceaac7c5299bc5d69e37c44d9081d43b"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b9b7a708dd92306328117d8c4b62e2194d00c365f18eff11a9b53c6f923b01e3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6a9a25751acb379b466ff6be78a315e2b439d4c94c1e99cb7266d40a537995d3"}, - {file = "wrapt-1.14.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:34aa51c45f28ba7f12accd624225e2b1e5a3a45206aa191f6f9aac931d9d56fe"}, - {file = "wrapt-1.14.1-cp39-cp39-win32.whl", hash = "sha256:dee0ce50c6a2dd9056c20db781e9c1cfd33e77d2d569f5d1d9321c641bb903d5"}, - {file = "wrapt-1.14.1-cp39-cp39-win_amd64.whl", hash = "sha256:dee60e1de1898bde3b238f18340eec6148986da0455d8ba7848d50470a7a32fb"}, - {file = "wrapt-1.14.1.tar.gz", hash = "sha256:380a85cf89e0e69b7cfbe2ea9f765f004ff419f34194018a6827ac0e3edfed4d"}, + {file = "wrapt-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46"}, + {file = "wrapt-1.15.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e"}, + {file = "wrapt-1.15.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923"}, + {file = "wrapt-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7"}, + {file = "wrapt-1.15.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90"}, + {file = "wrapt-1.15.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975"}, + {file = "wrapt-1.15.0-cp310-cp310-win32.whl", hash = "sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1"}, + {file = "wrapt-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7"}, + {file = "wrapt-1.15.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e"}, + {file = "wrapt-1.15.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92"}, + {file = "wrapt-1.15.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98"}, + {file = "wrapt-1.15.0-cp311-cp311-win32.whl", hash = "sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416"}, + {file = "wrapt-1.15.0-cp311-cp311-win_amd64.whl", hash = "sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb"}, + {file = "wrapt-1.15.0-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248"}, + {file = "wrapt-1.15.0-cp35-cp35m-win32.whl", hash = "sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559"}, + {file = "wrapt-1.15.0-cp35-cp35m-win_amd64.whl", hash = "sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639"}, + {file = "wrapt-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364"}, + {file = "wrapt-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418"}, + {file = "wrapt-1.15.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2"}, + {file = "wrapt-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1"}, + {file = "wrapt-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420"}, + {file = "wrapt-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e"}, + {file = "wrapt-1.15.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034"}, + {file = "wrapt-1.15.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653"}, + {file = "wrapt-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0"}, + {file = "wrapt-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145"}, + {file = "wrapt-1.15.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b"}, + {file = "wrapt-1.15.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094"}, + {file = "wrapt-1.15.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7"}, + {file = "wrapt-1.15.0-cp38-cp38-win32.whl", hash = "sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b"}, + {file = "wrapt-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86"}, + {file = "wrapt-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc"}, + {file = "wrapt-1.15.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8"}, + {file = "wrapt-1.15.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9"}, + {file = "wrapt-1.15.0-cp39-cp39-win32.whl", hash = "sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff"}, + {file = "wrapt-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6"}, + {file = "wrapt-1.15.0-py3-none-any.whl", hash = "sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640"}, + {file = "wrapt-1.15.0.tar.gz", hash = "sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a"}, ] zipp = [ - {file = "zipp-3.14.0-py3-none-any.whl", hash = "sha256:188834565033387710d046e3fe96acfc9b5e86cbca7f39ff69cf21a4128198b7"}, - {file = "zipp-3.14.0.tar.gz", hash = "sha256:9e5421e176ef5ab4c0ad896624e87a7b2f07aca746c9b2aa305952800cb8eecb"}, + {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, + {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, ] From d46b518f08438c3679fc8ab208be406f6651c0f0 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 12:49:22 -0400 Subject: [PATCH 500/615] add functions to create temp folders --- schematic/utils/general.py | 18 +++++++++++++++++- tests/test_utils.py | 15 +++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index ab95c3555..c58219d25 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -7,6 +7,8 @@ from cProfile import Profile from functools import wraps +import tempfile + from synapseclient.core.exceptions import SynapseHTTPError from synapseclient.table import EntityViewSchema from synapseclient.entity import File, Folder, Project @@ -114,7 +116,21 @@ def entity_type_mapping(syn, entity_id): else: # if there's no matching type, return concreteType return entity.concreteType - + +def create_temp_folder(path): + """This function creates a temporary directory in the specified directory + Args: + path: a directory path where all the temporary files will live + Returns: returns the absolute pathname of the new directory. + """ + # Create a temporary directory in the specified directory + try: + path = tempfile.mkdtemp(dir=path) + return path + except FileNotFoundError: + raise FileNotFoundError(f'Folder path not found: {path}') + + def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): """ The function was initially taken from: https://towardsdatascience.com/how-to-profile-your-code-in-python-e70c834fad89 diff --git a/tests/test_utils.py b/tests/test_utils.py index 157b975a4..005457a53 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,6 +1,7 @@ import logging import json import os +import shutil import pandas as pd import numpy as np @@ -77,6 +78,20 @@ def test_entity_type_mapping_invalid_entity_id(self, synapse_store): with pytest.raises(SynapseHTTPError) as exception_info: entity_type_mapping(syn, "syn123456") + def test_download_manifest_to_temp_folder(self): + # define temporary folder path + current_dir = os.getcwd() + temp_path = os.path.join(current_dir, 'temp_folder') + + # create a temporary folder to test out + if not os.path.exists(temp_path): + os.mkdir(temp_path) + + path_dir = general.create_temp_folder(temp_path) + assert os.path.exists(path_dir) + shutil.rmtree(path_dir) + shutil.rmtree(temp_path) + class TestCliUtils: def test_query_dict(self): From aeb150ca1ab9cb6376c580f7865fbe74b8b54762 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 12:51:07 -0400 Subject: [PATCH 501/615] download a manifest to a temporary folder on aws --- schematic/store/synapse.py | 20 ++++++++++++++++++-- tests/test_store.py | 9 +++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 31750b66e..ee11740b0 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -7,6 +7,7 @@ import logging import secrets from dataclasses import dataclass +import tempfile # allows specifying explicit variable types from typing import Dict, List, Tuple, Sequence, Union @@ -45,6 +46,7 @@ from schematic_db.schema.schema import get_key_attribute from schematic.utils.df_utils import update_df, load_df +from schematic.utils.general import create_temp_folder from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list from schematic.schemas.explorer import SchemaExplorer from schematic.schemas.generator import SchemaGenerator @@ -73,10 +75,24 @@ def _download_manifest_to_folder(self): manifest_data: A new Synapse Entity object of the appropriate type """ # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config - if CONFIG["synapse"]["manifest_folder"]: + + # on AWS, to avoid overriding manifest, we download the manifest to a temporary folder + if "SECRETS_MANAGER_SECRETS" in os.environ: + temporary_manifest_storage = "/var/tmp/temp_manifest_download" + if not os.path.exists(temporary_manifest_storage): + os.mkdir("/var/tmp/temp_manifest_download") + download_location = create_temp_folder(temporary_manifest_storage) + + elif CONFIG["synapse"]["manifest_folder"]: + download_location=CONFIG["synapse"]["manifest_folder"] + + else: + download_location=None + + if download_location: manifest_data = self.syn.get( self.manifest_id, - downloadLocation=CONFIG["synapse"]["manifest_folder"], + downloadLocation=download_location, ifcollision="overwrite.local", ) else: diff --git a/tests/test_store.py b/tests/test_store.py index 762552558..9a86b9c96 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -516,6 +516,15 @@ def test_download_access_restricted_manifest(self, synapse_store): # clean up os.remove(manifest_data['path']) + def test_download_manifest_on_aws(self, mock_manifest_download, monkeypatch): + # mock AWS environment by providing SECRETS_MANAGER_SECRETS environment variable and attempt to download a manifest + monkeypatch.setenv('SECRETS_MANAGER_SECRETS', 'mock_value') + manifest_data = mock_manifest_download.download_manifest(mock_manifest_download) + + assert os.path.exists(manifest_data['path']) + # clean up + os.remove(manifest_data['path']) + @pytest.mark.parametrize("entity_id", ["syn27600053", "syn29862078"]) def test_entity_type_checking(self, synapse_store, entity_id, caplog): md = ManifestDownload(synapse_store.syn, entity_id) From 4fd58e8629f1266a6812aba0d2cb4db23fc4f2dc Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 13:04:43 -0400 Subject: [PATCH 502/615] change owner --- schematic_api/Dockerfile | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index cc2d30b59..4b6696d78 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -61,7 +61,10 @@ COPY schematic ./schematic # change permission WORKDIR /var/www/ -RUN chown www-data:www-data /var/www/ +#The -R option: make the command recursive, so it will change the owner of all files and subdirectories within a given folder. +RUN chown -R www-data:www-data /var/www/ + +RUN chown -R www-data:www-data /var/tmp/ WORKDIR / COPY schematic_api/docker-entrypoint.sh ./ From edbcab0e5785ed194b87b9428e289a154c847fb5 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:08:18 -0700 Subject: [PATCH 503/615] change test attribute name --- tests/data/example.model.csv | 4 ++-- tests/data/example.model.jsonld | 9 ++++++--- tests/data/mock_manifests/rdb_table_manifest.csv | 2 +- tests/data/mock_manifests/rdb_table_manifest_upsert.csv | 2 +- tests/test_store.py | 6 +++--- 5 files changed, 13 insertions(+), 10 deletions(-) diff --git a/tests/data/example.model.csv b/tests/data/example.model.csv index c60f499f1..1f6c9589c 100644 --- a/tests/data/example.model.csv +++ b/tests/data/example.model.csv @@ -38,6 +38,6 @@ Check Unique,,,,,TRUE,DataProperty,,,unique error Check Range,,,,,TRUE,DataProperty,,,inRange 50 100 error Check Date,,,,,TRUE,DataProperty,,,date Check NA,,,,,TRUE,DataProperty,,,int::IsNA -MockRDB,,,"Component, MockRDB_id",,FALSE,DataType,,, +MockRDB,,,"Component, MockRDB_id, SourceManifest",,FALSE,DataType,,, MockRDB_id,,,,,TRUE,DataProperty,,,int -MockAttribute,,,,,TRUE,DataProperty,,, +SourceManifest,,,,,TRUE,DataProperty,,, diff --git a/tests/data/example.model.jsonld b/tests/data/example.model.jsonld index 87c5dc11c..2d65b72bf 100644 --- a/tests/data/example.model.jsonld +++ b/tests/data/example.model.jsonld @@ -2944,6 +2944,9 @@ }, { "@id": "bts:MockRDBId" + }, + { + "@id": "bts:SourceManifest" } ], "sms:validationRules": [] @@ -2968,10 +2971,10 @@ ] }, { - "@id": "bts:MockAttribute", + "@id": "bts:SourceManifest", "@type": "rdfs:Class", "rdfs:comment": "TBD", - "rdfs:label": "MockAttribute", + "rdfs:label": "SourceManifest", "rdfs:subClassOf": [ { "@id": "bts:DataProperty" @@ -2980,7 +2983,7 @@ "schema:isPartOf": { "@id": "http://schema.biothings.io" }, - "sms:displayName": "MockAttribute", + "sms:displayName": "SourceManifest", "sms:required": "sms:true", "sms:validationRules": [] }, diff --git a/tests/data/mock_manifests/rdb_table_manifest.csv b/tests/data/mock_manifests/rdb_table_manifest.csv index 5892d9487..5becf36e7 100644 --- a/tests/data/mock_manifests/rdb_table_manifest.csv +++ b/tests/data/mock_manifests/rdb_table_manifest.csv @@ -1,4 +1,4 @@ -Component,MockRDB_id,MockAttribute +Component,MockRDB_id,SourceManifest MockRDB,1,Manifest1 MockRDB,2,Manifest1 MockRDB,3,Manifest1 diff --git a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv index 6b158aa0d..007bf86f5 100644 --- a/tests/data/mock_manifests/rdb_table_manifest_upsert.csv +++ b/tests/data/mock_manifests/rdb_table_manifest_upsert.csv @@ -1,4 +1,4 @@ -Component,MockRDB_id,MockAttribute +Component,MockRDB_id,SourceManifest MockRDB,5,Manifest2 MockRDB,6,Manifest2 MockRDB,7,Manifest2 diff --git a/tests/test_store.py b/tests/test_store.py index a7afb18c7..c7908b36a 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -380,7 +380,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) table_name="MockRDB_synapse_storage_manifest_table".lower() manifest_path = "mock_manifests/rdb_table_manifest.csv" replacement_manifest_path = "mock_manifests/rdb_table_manifest_upsert.csv" - column_of_interest="MockRDB_id,MockAttribute" + column_of_interest="MockRDB_id,SourceManifest" # Check if FollowUp table exists if so delete existing_tables = synapse_store.get_table_info(projectId = projectId) @@ -419,7 +419,7 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # assert max ID is '4' and that there are 4 entries assert table_query.MockRDB_id.max() == 4 assert table_query.MockRDB_id.size == 4 - assert table_query['MockAttribute'][3] == 'Manifest1' + assert table_query['SourceManifest'][3] == 'Manifest1' # Associate new manifest with files manifestId = synapse_store.associateMetadataWithFiles( @@ -443,6 +443,6 @@ def test_upsertTable(self, helpers, synapse_store, config, projectId, datasetId) # assert max ID is '4' and that there are 4 entries assert table_query.MockRDB_id.max() == 8 assert table_query.MockRDB_id.size == 8 - assert table_query['MockAttribute'][3] == 'Manifest2' + assert table_query['SourceManifest'][3] == 'Manifest2' # delete table synapse_store.syn.delete(tableId) From de2f0d49f10da37e4faca8073091060067ff9a72 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:08:30 -0700 Subject: [PATCH 504/615] do not delete test datasets --- tests/test_store.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_store.py b/tests/test_store.py index c7908b36a..7edc174cd 100644 --- a/tests/test_store.py +++ b/tests/test_store.py @@ -68,7 +68,6 @@ def datasetId(synapse_store, projectId, helpers): datasetId = synapse_store.syn.store(dataset).id sleep(5) yield datasetId - synapse_store.syn.delete(datasetId) def raise_final_error(retry_state): From 48286211b29a13fb5d97323e5c25cb5ead82563d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:16:04 -0700 Subject: [PATCH 505/615] update endpoint param description --- api/openapi/api.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/openapi/api.yaml b/api/openapi/api.yaml index 2f211d373..85aa3b871 100644 --- a/api/openapi/api.yaml +++ b/api/openapi/api.yaml @@ -256,7 +256,7 @@ paths: schema: type: string nullable: true - description: Data Model Component + description: Data Model Component. Providing a data type will also validate the manfiest against the rules specified for the data type's attributes. example: Patient required: true - in: query From 6bf6abd32c62b03d2e5e49acfea296607e422392 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 27 Apr 2023 10:18:05 -0700 Subject: [PATCH 506/615] change `uuid` name to `id` --- schematic/store/synapse.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index e28cd2816..0b3489bf2 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -853,9 +853,9 @@ def formatDB(self, se, manifest, useSchemaLabel): # Get the column schema col_schema = as_table_columns(table_manifest) - # Set uuid column length to 64 (for some reason not being auto set.) + # Set id column length to 64 (for some reason not being auto set.) for i, col in enumerate(col_schema): - if col['name'] == 'Uuid': + if col['name'] == 'id': col_schema[i]['maximumSize'] = 64 return col_schema, table_manifest @@ -1055,21 +1055,21 @@ def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: return manifest def _add_id_columns_to_manifest(self, manifest): - """Helper function to add UUID and entityId columns to the manifest if they do not already exist, Fill UUID values per row. + """Helper function to add id and entityId columns to the manifest if they do not already exist, Fill id values per row. Args: Manifest loaded as a pd.Dataframe Returns (pd.DataFrame): - Manifest df with new Uuid and EntityId columns (and UUID values) if they were not already present. + Manifest df with new id and EntityId columns (and UUID values) if they were not already present. """ - # Add uuid for table updates and fill. - if not "Uuid" in manifest.columns: - manifest["Uuid"] = '' + # Add id for table updates and fill. + if not "id" in manifest.columns: + manifest["id"] = '' for idx,row in manifest.iterrows(): - if not row["Uuid"]: + if not row["id"]: gen_uuid = str(uuid.uuid4()) - row["Uuid"] = gen_uuid - manifest.loc[idx, 'Uuid'] = gen_uuid + row["id"] = gen_uuid + manifest.loc[idx, 'id'] = gen_uuid # add entityId as a column if not already there or # fill any blanks with an empty string. @@ -1901,7 +1901,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Uuid', restrict: bool = False): + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'id', restrict: bool = False): """ Method to update an existing table with a new column From 1a1553d74289e0863d23335d92bf87269179dda0 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 13:21:42 -0400 Subject: [PATCH 507/615] add typing --- schematic/store/synapse.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index ee11740b0..feb692709 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -45,6 +45,8 @@ from schematic_db.rdb.synapse_database import SynapseDatabase from schematic_db.schema.schema import get_key_attribute +from synapseclient.entity import File + from schematic.utils.df_utils import update_df, load_df from schematic.utils.general import create_temp_folder from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list @@ -67,15 +69,14 @@ class ManifestDownload(object): syn: synapseclient.Synapse manifest_id: str - def _download_manifest_to_folder(self): + def _download_manifest_to_folder(self) -> File: """ try downloading a manifest to local cache or a given folder manifest Return: - manifest_data: A new Synapse Entity object of the appropriate type + manifest_data: synapse file entity """ - # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config - + # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config # on AWS, to avoid overriding manifest, we download the manifest to a temporary folder if "SECRETS_MANAGER_SECRETS" in os.environ: temporary_manifest_storage = "/var/tmp/temp_manifest_download" @@ -101,7 +102,7 @@ def _download_manifest_to_folder(self): ) return manifest_data - def _entity_type_checking(self): + def _entity_type_checking(self) -> str: """ check the entity type of the id that needs to be downloaded Return: From ad2d727f5f6ca329609bc80be4e61320e0cfd364 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 27 Apr 2023 13:28:17 -0400 Subject: [PATCH 508/615] add typing --- schematic/utils/general.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index c58219d25..9ea030236 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -117,10 +117,10 @@ def entity_type_mapping(syn, entity_id): # if there's no matching type, return concreteType return entity.concreteType -def create_temp_folder(path): +def create_temp_folder(path: str) -> str: """This function creates a temporary directory in the specified directory Args: - path: a directory path where all the temporary files will live + path(str): a directory path where all the temporary files will live Returns: returns the absolute pathname of the new directory. """ # Create a temporary directory in the specified directory From 2bfc07c24fd0faec4076e14336bd6c22feb605bc Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 28 Apr 2023 15:31:13 -0400 Subject: [PATCH 509/615] update comment and remove try except --- schematic/store/synapse.py | 2 +- schematic/utils/general.py | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index feb692709..f0e7900d6 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -74,7 +74,7 @@ def _download_manifest_to_folder(self) -> File: try downloading a manifest to local cache or a given folder manifest Return: - manifest_data: synapse file entity + manifest_data: A Synapse file entity of the downloaded manifest """ # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config # on AWS, to avoid overriding manifest, we download the manifest to a temporary folder diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 9ea030236..21f46156f 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -124,11 +124,8 @@ def create_temp_folder(path: str) -> str: Returns: returns the absolute pathname of the new directory. """ # Create a temporary directory in the specified directory - try: - path = tempfile.mkdtemp(dir=path) - return path - except FileNotFoundError: - raise FileNotFoundError(f'Folder path not found: {path}') + path = tempfile.mkdtemp(dir=path) + return path def profile(output_file=None, sort_by='cumulative', lines_to_print=None, strip_dirs=False): From f40d99864debca4bfb8a018943904f04b2ef9e3c Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 28 Apr 2023 15:55:01 -0400 Subject: [PATCH 510/615] add comment in TODO --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index f0e7900d6..38607bd55 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -76,7 +76,7 @@ def _download_manifest_to_folder(self) -> File: Return: manifest_data: A Synapse file entity of the downloaded manifest """ - # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config + # TO DO: potentially deprecate the if else statement because "manifest_folder" key always exist in config (See issue FDS-349 in Jira) # on AWS, to avoid overriding manifest, we download the manifest to a temporary folder if "SECRETS_MANAGER_SECRETS" in os.environ: temporary_manifest_storage = "/var/tmp/temp_manifest_download" From 4278a4a3d2ccdf12ee4213425d986d0247b1ffd6 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 1 May 2023 14:28:01 -0400 Subject: [PATCH 511/615] use tempfile to avoid clean up --- tests/test_utils.py | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/tests/test_utils.py b/tests/test_utils.py index 005457a53..3489f1657 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -1,12 +1,13 @@ import logging import json import os -import shutil import pandas as pd import numpy as np import pytest +import tempfile + from pandas.testing import assert_frame_equal from synapseclient.core.exceptions import SynapseHTTPError @@ -79,18 +80,9 @@ def test_entity_type_mapping_invalid_entity_id(self, synapse_store): entity_type_mapping(syn, "syn123456") def test_download_manifest_to_temp_folder(self): - # define temporary folder path - current_dir = os.getcwd() - temp_path = os.path.join(current_dir, 'temp_folder') - - # create a temporary folder to test out - if not os.path.exists(temp_path): - os.mkdir(temp_path) - - path_dir = general.create_temp_folder(temp_path) - assert os.path.exists(path_dir) - shutil.rmtree(path_dir) - shutil.rmtree(temp_path) + with tempfile.TemporaryDirectory() as tmpdir: + path_dir = general.create_temp_folder(tmpdir) + assert os.path.exists(path_dir) class TestCliUtils: def test_query_dict(self): From f9e5ba508e964f76ca0c1555fc5e1208f709155b Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 1 May 2023 17:22:13 -0400 Subject: [PATCH 512/615] change to if not --- schematic/store/synapse.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 38607bd55..dee1aa4f5 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -89,17 +89,18 @@ def _download_manifest_to_folder(self) -> File: else: download_location=None - - if download_location: + + if not download_location: + manifest_data = self.syn.get( + self.manifest_id, + ) + # if download_location is provided and it is not an empty string + else: manifest_data = self.syn.get( self.manifest_id, downloadLocation=download_location, ifcollision="overwrite.local", ) - else: - manifest_data = self.syn.get( - self.manifest_id, - ) return manifest_data def _entity_type_checking(self) -> str: From c6a066baad0289d6e4fb953fcba01b4c9b786356 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 2 May 2023 14:26:50 -0400 Subject: [PATCH 513/615] remove server port as configurable --- docker-compose.yml | 2 +- env.example | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index f0e7d8022..10caddc47 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: networks: - schematic ports: - - "${SERVER_PORT}:80" + - "80:80" - "443:443" networks: schematic: diff --git a/env.example b/env.example index d3f721107..e2545efcd 100644 --- a/env.example +++ b/env.example @@ -1,5 +1,4 @@ # API server SERVER_PROTOCOL=http:// SERVER_DOMAIN=localhost -SERVER_PORT=7080 SERVICE_ACCOUNT_CREDS='Provide service account creds' \ No newline at end of file From a2dd2865839567012bd31c867dee7d281fd9b656 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 2 May 2023 14:18:08 -0700 Subject: [PATCH 514/615] update comments and error message --- schematic/store/synapse.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 486e2d002..3bd7c7689 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1956,15 +1956,18 @@ def _get_schematic_db_creds(synStore): # Get access token from environment variable if available + # Primarily useful for testing environments, with other possible usefulness for containers env_access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") if env_access_token: authtoken = env_access_token # Get token from authorization header + # Primarily useful for API endpoint functionality if 'Authorization' in synStore.syn.default_headers: authtoken = synStore.syn.default_headers['Authorization'].split('Bearer ')[-1] # retrive credentials from synapse object + # Primarily useful for local users, could only be stored here when a .synapseConfig file is used, but including to be safe synapse_object_creds = synStore.syn.credentials if hasattr(synapse_object_creds, 'username'): username = synapse_object_creds.username @@ -1972,6 +1975,7 @@ def _get_schematic_db_creds(synStore): authtoken = synapse_object_creds.secret # Try getting creds from .synapseConfig file if it exists + # Primarily useful for local users. Seems to correlate with credentials stored in synaspe object when logged in if os.path.exists(CONFIG.SYNAPSE_CONFIG_PATH): config = synStore.syn.getConfigFile(CONFIG.SYNAPSE_CONFIG_PATH) @@ -1982,9 +1986,11 @@ def _get_schematic_db_creds(synStore): authtoken = config.get('authentication', 'authtoken') # raise error if required credentials are not found + # providing an authtoken without a username did not prohibit upsert functionality, + # but including username gathering for completeness for schematic_db if not username and not authtoken: raise NameError( - "Username or authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" + "Username and authtoken credentials could not be found in the environment, synapse object, or the .synapseConfig file" ) if not authtoken: raise NameError( From 1f8e05bf32921e998b65d4d11402117883e5b3b0 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 3 May 2023 08:34:20 -0700 Subject: [PATCH 515/615] added pylint --- poetry.lock | 2 +- pyproject.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/poetry.lock b/poetry.lock index 7a1615457..855509f2c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2636,7 +2636,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "2e8922a96ef8a1b786b1783705fcec76e70f6d39965388ccc6076046a022de0f" +content-hash = "9fa9c3b799a420f073b1c6f2d8f9c96d82bea9ebe2d979c4c276969e3e26e419" [metadata.files] alabaster = [ diff --git a/pyproject.toml b/pyproject.toml index a5b0a4ab4..e79cb7e5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -81,6 +81,7 @@ flake8 = "^6.0.0" python-dotenv = "^0.21.0" black = "^22.6.0" mypy = "^0.982" +pylint = "^2.16.1" [tool.black] From 4504696159ffb9dc83734a4de5834e33e366a74d Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 3 May 2023 08:34:37 -0700 Subject: [PATCH 516/615] added pylint config --- .pylintrc | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .pylintrc diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 000000000..b5a5c8eb1 --- /dev/null +++ b/.pylintrc @@ -0,0 +1,2 @@ +[MAIN] +load-plugins=pylint.extensions.docparams \ No newline at end of file From 85d3b767a54e8f52f8e63715c9322fc4dfcdb440 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 3 May 2023 08:34:50 -0700 Subject: [PATCH 517/615] linted python files --- schematic/help.py | 2 ++ schematic/loader.py | 32 +++++++++++++++----------------- schematic/version.py | 1 + 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/schematic/help.py b/schematic/help.py index a4b21c1a9..94fd06a08 100644 --- a/schematic/help.py +++ b/schematic/help.py @@ -1,3 +1,5 @@ +"""Help messages for CLI commands""" +# pylint: disable=line-too-long #!/usr/bin/env python3 # `schematic manifest` related sub-commands description diff --git a/schematic/loader.py b/schematic/loader.py index 794be4165..85aa2ff80 100644 --- a/schematic/loader.py +++ b/schematic/loader.py @@ -25,18 +25,16 @@ def __init__(self, namespace: str, requested_uri: str) -> None: self.requested_uri = requested_uri self.message = "Resource does not exist or is declared incorrectly" self.errno = ENOENT - super(InvalidResourceError, self).__init__(self.message) + super().__init__(self.message) def __str__(self) -> str: - return '{}({}), "{}" of {}'.format( - self.message, self.errno, self.requested_uri, self.namespace - ) + return f'{self.message}({self.errno}), "{self.requested_uri}" of {self.namespace}' def __repr__(self) -> str: return self.__str__() -class Loader(object): +class Loader: """ Args: namespace {String}: The namespace within the package (relative to the package root) @@ -58,12 +56,12 @@ def __init__(self, namespace: str, **opts: Any) -> None: def _resolve(self, uri: str) -> tuple[str, str]: resource_uri = "/".join([self.prefix] + uri.split(pathsep)) - ns = self.namespace + namespace = self.namespace - if not resource_exists(ns, resource_uri): - raise InvalidResourceError(ns, resource_uri) + if not resource_exists(namespace, resource_uri): + raise InvalidResourceError(namespace, resource_uri) - return ns, resource_uri + return namespace, resource_uri def read(self, uri: str) -> Any: """ @@ -72,8 +70,8 @@ def read(self, uri: str) -> Any: Args: uri {String}: URI of the resource. """ - ns, uri = self._resolve(uri) - return resource_string(ns, uri) + namespace, uri = self._resolve(uri) + return resource_string(namespace, uri) def open(self, uri: str) -> Any: """ @@ -82,8 +80,8 @@ def open(self, uri: str) -> Any: Args: uri {String}: URI of the resource. """ - ns, uri = self._resolve(uri) - return resource_stream(ns, uri) + namespace, uri = self._resolve(uri) + return resource_stream(namespace, uri) def filename(self, uri: str) -> str: """ @@ -92,8 +90,8 @@ def filename(self, uri: str) -> str: Args: uri {String}: URI of the resource. """ - ns, uri = self._resolve(uri) - return resource_filename(ns, uri) + namespace, uri = self._resolve(uri) + return resource_filename(namespace, uri) def list(self, url: str) -> Iterable[str]: """ @@ -102,8 +100,8 @@ def list(self, url: str) -> Iterable[str]: Args: url {String}: URL of the resources. """ - ns, uri = self._resolve(url) - return map(lambda x: url + "/" + x, resource_listdir(ns, uri)) + namespace, uri = self._resolve(url) + return map(lambda x: url + "/" + x, resource_listdir(namespace, uri)) # call Loader() and pass `schematic`, which is the global package namespace diff --git a/schematic/version.py b/schematic/version.py index f21a63461..a9bdb1578 100644 --- a/schematic/version.py +++ b/schematic/version.py @@ -1,3 +1,4 @@ +"""Sets the version of the package""" import importlib.metadata __version__ = importlib.metadata.version("schematic") From 5621690a8cc11ce8035e2a0d29e0631af06f788b Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 3 May 2023 08:37:03 -0700 Subject: [PATCH 518/615] added linting to testing workflow --- .github/workflows/test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 144b69685..44b2477fa 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -109,6 +109,15 @@ jobs: # add here when enforced poetry run mypy --disallow-untyped-defs --install-types --non-interactive schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py + #---------------------------------------------- + # linting + #---------------------------------------------- + - name: Lint with pylint + run: | + # ran only on certain files for now + # add here when checked + poetry run pylint schematic/exceptions.py schematic/help.py schematic/loader.py schematic/version.py + #---------------------------------------------- # run test suite #---------------------------------------------- From 357ee68c534edaa2850ca77ca8403b2afb6c2812 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Wed, 3 May 2023 08:52:39 -0700 Subject: [PATCH 519/615] ran black --- schematic/loader.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic/loader.py b/schematic/loader.py index 85aa2ff80..be9158002 100644 --- a/schematic/loader.py +++ b/schematic/loader.py @@ -28,7 +28,9 @@ def __init__(self, namespace: str, requested_uri: str) -> None: super().__init__(self.message) def __str__(self) -> str: - return f'{self.message}({self.errno}), "{self.requested_uri}" of {self.namespace}' + return ( + f'{self.message}({self.errno}), "{self.requested_uri}" of {self.namespace}' + ) def __repr__(self) -> str: return self.__str__() From 8eb8195a12c06670453a87e2582da598db01e544 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 3 May 2023 09:06:01 -0700 Subject: [PATCH 520/615] WIP: fix issue with column mismatch, minor refactor --- schematic/manifest/generator.py | 237 ++++++++++++++++++++------------ 1 file changed, 146 insertions(+), 91 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 8c2eac8aa..d43f93e4f 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1223,7 +1223,7 @@ def _gather_all_fields(self, fields, json_schema): required_metadata_fields = self._get_required_metadata_fields( json_schema, fields ) - # Add additioal dependencies + # Add additional dependencies required_metadata_fields = self._gather_dependency_requirements( json_schema, required_metadata_fields ) @@ -1241,6 +1241,8 @@ def get_empty_manifest(self, json_schema_filepath=None): json_schema_filepath (str): path to json schema file Returns: manifest_url (str): url of the google sheet manifest. + TODO: + In future """ spreadsheet_id = self._create_empty_manifest_spreadsheet(self.title) json_schema = self._get_json_schema(json_schema_filepath) @@ -1254,18 +1256,17 @@ def get_empty_manifest(self, json_schema_filepath=None): ) return manifest_url - def _get_missing_columns(self, wb_header, manifest_df): - # get headers from sheet - manifest_df_header = manifest_df.columns - - # find missing columns present in existing manifest but missing in latest schema - out_of_schema_columns = set(manifest_df_header) - set(wb_header) + def _get_mismatched_columns(self, headers_1, headers_2): + """ - return out_of_schema_columns + """ + # Compare two colunm sets and get cols that are in headers_1, but not headers_2 + mismatched_columns = set(headers_1) - set(headers_2) + return mismatched_columns def set_dataframe_by_url( - self, manifest_url: str, manifest_df: pd.DataFrame + self, manifest_url: str, manifest_df: pd.DataFrame, out_of_schema_columns=None, ) -> ps.Spreadsheet: """Update Google Sheets using given pandas DataFrame. Args: @@ -1279,61 +1280,19 @@ def set_dataframe_by_url( gc = ps.authorize(custom_credentials=self.creds) # open google sheets and extract first sheet + # This sheet already contains headers. sh = gc.open_by_url(manifest_url) wb = sh[0] - # Handle scenario when existing manifest does not match new - # manifest template due to changes in the data model: - # - # the sheet column header reflect the latest schema - # the existing manifest column-set may be outdated - # ensure that, if missing, attributes from the latest schema are added to the - # column-set of the existing manifest so that the user can modify their data if needed - # to comply with the latest schema - - # get headers from existing manifest and sheet - wb_header = wb.get_row(1) - manifest_df_header = manifest_df.columns - - # find missing columns in existing manifest - new_columns = set(wb_header) - set(manifest_df_header) - - # clean empty columns if any are present (there should be none) - # TODO: Remove this line once we start preventing empty column names - if '' in new_columns: - new_columns = new_columns.remove('') - - # find missing columns present in existing manifest but missing in latest schema - out_of_schema_columns = set(manifest_df_header) - set(wb_header) - - # update existing manifest w/ missing columns, if any - if new_columns: - manifest_df = manifest_df.assign( - **dict(zip(new_columns, len(new_columns) * [""])) - ) - - # sort columns in the updated manifest: - # match latest schema order - # move obsolete columns at the end - manifest_df = manifest_df[self.sort_manifest_fields(manifest_df.columns)] - manifest_df = manifest_df[[c for c in manifest_df if c not in out_of_schema_columns] + list(out_of_schema_columns)] - - # The following line sets `valueInputOption = "RAW"` in pygsheets - sh.default_parse = False - - # update spreadsheet with given manifest starting at top-left cell - wb.set_dataframe(manifest_df, (1, 1)) # update validation rules (i.e. no validation rules) for out of schema columns, if any # TODO: similarly clear formatting for out of schema columns, if any - num_out_of_schema_columns = len(out_of_schema_columns) - if num_out_of_schema_columns > 0: + if out_of_schema_columns: + num_out_of_schema_columns = len(out_of_schema_columns) start_col = self._column_to_letter(len(manifest_df.columns) - num_out_of_schema_columns) # find start of out of schema columns end_col = self._column_to_letter(len(manifest_df.columns) + 1) # find end of out of schema columns - wb.set_data_validation(start = start_col, end = end_col, condition_type = None) - # set permissions so that anyone with the link can edit sh.share("", role="writer", type="anyone") @@ -1415,6 +1374,8 @@ def get_manifest_with_annotations( # Generate empty manifest using `additional_metadata` manifest_url = self.get_empty_manifest() + + #TODO: MIALY Make sure this functionality is preserved, should be bc there isnt another manifest we are merging with. manifest_df = self.get_dataframe_by_url(manifest_url) # Annotations clashing with manifest attributes are skipped @@ -1463,7 +1424,7 @@ def export_sheet_to_excel(self, title: str = None, manifest_url : str = None, ou return output_excel_file_path - def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None): + def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None, out_of_schema_columns=None): """ handle the logic between sheet_url parameter and output_format parameter to determine the type of output to return Args: @@ -1477,6 +1438,8 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st ## TO DO: deprecate sheet_url parameter and simplify the logic here # check if output_format parameter gets set. If not, check the sheet_url parameter + + ''' if not output_format: # if the sheet_url parameter gets set to True, return a google sheet url if sheet_url: @@ -1487,27 +1450,41 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st else: return dataframe else: - # if the output type gets set to "dataframe", return a data frame - if output_format == "dataframe": - return dataframe - # if the output type gets set to "excel", return an excel spreadsheet - elif output_format == "excel": - # export the manifest url to excel - # note: the manifest url being used here is an empty manifest url that only contains column header + ''' + # if not saving excel delete after header is made. + + # if the output type gets set to "dataframe", return a data frame + if output_format == "dataframe": + """ + TODO: for backwards compatibility may need to return downloaded CSV only with no updates wrt to the schema. + Probably use a different function and endpoint for this bc could just wrap a synapse client funtion instead of going through all the prior steps. + """ + return dataframe + + # if the output type gets set to "excel", return an excel spreadsheet + elif output_format == "excel": + # export the manifest url to excel + # note: the manifest url being used here is an empty manifest url that only contains column header - # export manifest that only contains column headers to Excel - output_file_path = self.export_sheet_to_excel(title = self.title, manifest_url = empty_manifest_url, output_location = output_path) - if not os.path.exists(output_file_path): - logger.error(f'Export to Excel spreadsheet fail. Please make sure that file path {output_file_path} is valid') + # export manifest that only contains column headers to Excel + output_file_path = self.export_sheet_to_excel(title = self.title, manifest_url = empty_manifest_url, output_location = output_path) + if not os.path.exists(output_file_path): + logger.error(f'Export to Excel spreadsheet fail. Please make sure that file path {output_file_path} is valid') - # populate an excel spreadsheet with the existing dataframe - self.populate_existing_excel_spreadsheet(output_file_path, dataframe) + # populate an excel spreadsheet with the existing dataframe + self.populate_existing_excel_spreadsheet(output_file_path, dataframe) - return output_file_path - # for all other cases, return a google sheet url after populating the dataframe - else: - manifest_sh = self.set_dataframe_by_url(empty_manifest_url, dataframe) - return manifest_sh.url + return output_file_path + + # for all other cases, return a google sheet url after populating the dataframe + # TODO: add "google_sheet" as an output choice + elif sheet_url: + manifest_sh = self.set_dataframe_by_url(manifest_url=empty_manifest_url, manifest_df=dataframe, out_of_schema_columns=out_of_schema_columns) + return manifest_sh.url + + # new default is dataframe? + else: + return dataframe def get_manifest( self, dataset_id: str = None, sheet_url: bool = None, json_schema: str = None, output_format: str = None, output_path: str = None, input_token: str = None @@ -1560,21 +1537,32 @@ def get_manifest( # TODO: Update or remove the warning in self.__init__() if # you change the behavior here based on self.use_annotations + # Update df with existing manifest. Agnostic to output format + updated_df, out_of_schema_columns = self._update_dataframe_with_existing_df(empty_manifest_url=empty_manifest_url, existing_df=manifest_record[1]) + # determine the format of manifest - result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_record[1]) + #result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_record[1]) + result = self._handle_output_format_logic(output_format = output_format, + output_path = output_path, + sheet_url = sheet_url, + empty_manifest_url=empty_manifest_url, + dataframe = updated_df, + out_of_schema_columns=out_of_schema_columns, + ) return result # Generate empty template and optionally fill in with annotations else: # Using getDatasetAnnotations() to retrieve file names and subset # entities to files and folders (ignoring tables/views) + annotations = pd.DataFrame() if self.is_file_based: annotations = store.getDatasetAnnotations(dataset_id) # if there are no files with annotations just generate an empty manifest if annotations.empty: - manifest_url = self.get_empty_manifest() + manifest_url = self.get_empty_manifest() manifest_df = self.get_dataframe_by_url(manifest_url) else: # Subset columns if no interested in user-defined annotations and there are files present @@ -1584,45 +1572,111 @@ def get_manifest( # Update `additional_metadata` and generate manifest manifest_url, manifest_df = self.get_manifest_with_annotations(annotations) + # Update df with existing manifest. Agnostic to output format + updated_df, out_of_schema_columns = self._update_dataframe_with_existing_df(empty_manifest_url=empty_manifest_url, existing_df=manifest_df) + # determine the format of manifest that gets return - result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_df) + result = self._handle_output_format_logic(output_format = output_format, + output_path = output_path, + sheet_url = sheet_url, + empty_manifest_url=empty_manifest_url, + dataframe = manifest_df, + ) return result + def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_df: pd.DataFrame) -> pd.DataFrame: + """ + Handle scenario when existing manifest does not match new + manifest template due to changes in the data model: + + the sheet column header reflect the latest schema + the existing manifest column-set may be outdated + ensure that, if missing, attributes from the latest schema are added to the + column-set of the existing manifest so that the user can modify their data if needed + to comply with the latest schema + """ + + # Get headers for the current schema and existing manifest df. + current_schema_headers = list(self.get_dataframe_by_url(empty_manifest_url).columns) + existing_manfiest_headers = list(existing_df.columns) + + # Find columns that exist in the current schema, but are not in the manifest being downloaded. + new_columns = self._get_mismatched_columns(current_schema_headers, existing_manfiest_headers) + + # Find columns that exist in the manifest being downloaded, but not in the current schema. + out_of_schema_columns = self._get_mismatched_columns(existing_manfiest_headers, current_schema_headers) + + # clean empty columns if any are present (there should be none) + # TODO: Remove this line once we start preventing empty column names + if '' in new_columns: + new_columns = new_columns.remove('') + + # Copy the df for updating. + updated_df = existing_df.copy(deep=True) + + # update existing manifest w/ missing columns, if any + if new_columns: + updated_df = updated_df.assign( + **dict(zip(new_columns, len(new_columns) * [""])) + ) + + # sort columns in the updated manifest: + # match latest schema order + # move obsolete columns at the end + updated_df = updated_df[self.sort_manifest_fields(updated_df.columns)] + updated_df = updated_df[[c for c in updated_df if c not in out_of_schema_columns] + list(out_of_schema_columns)] + + return updated_df, out_of_schema_columns + def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, additional_df: pd.DataFrame = None): '''Populate an existing excel spreadsheet by using an additional dataframe (to avoid sending metadata directly to Google APIs) Args: existing_excel_path: path of an existing excel spreadsheet additional_df: additional dataframe Return: - added new dataframe to the existing excel path. + added new dataframe to the existing excel path. + TODO: + - The naming of existing and additional df is a bit confusing. ''' # load workbook + #TODO: UPDATE NAMING HERE existing_excel_path to excel_path + # Additional_df to updated_df workbook = load_workbook(existing_excel_path) - + ''' #get missing columns and sort manifest #get existing headers existing_df = pd.read_excel(existing_excel_path, sheet_name="Sheet1") - workbook_headers = existing_df.columns + current_schema_headers = list(existing_df.columns) + additional_df_headers = list(additional_df.columns) # get new column headers - out_of_schema_columns = self._get_missing_columns(workbook_headers, additional_df) - out_of_schema_columns_lst = list(out_of_schema_columns) - - # initalize excel writer - with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='overlay') as writer: + out_of_schema_columns = list(self._get_mismatched_columns(current_schema_headers, additional_df_headers)) + # get columns that are missing from the additional df + missing_schema_columns = list(self._get_mismatched_columns(additional_df_headers, current_schema_headers)) + breakpoint() + # Full set of columns to add + columns_to_add = out_of_schema_columns + missing_schema_columns + ''' + # initalize excel writer + with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='replace') as writer: writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.worksheets["Sheet1"] - + ''' + df_additional_headers = pd.DataFrame(columns=additional_df.columns) + df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=0, index=False, header=True) + ''' + ''' # if there are new columns, add them to the end of spreadsheet # Note: previously, we tried looping through the out of schema columns and use worksheet.cell to modify a particular cell. But that functionality is no longer working. - if out_of_schema_columns_lst: - df_additional_headers = pd.DataFrame(columns=out_of_schema_columns_lst) - start_col_index = len(workbook_headers) + if missing_schema_columns: + df_additional_headers = pd.DataFrame(columns=missing_schema_columns) + start_col_index = len(current_schema_headers) df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index=False, header=True) - - # add additional content to the existing spreadsheet - additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) + ''' + # overwrite existing df with new df + # In future dont start with a prepopulated excel. + additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. @@ -1643,6 +1697,7 @@ def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empt # export the manifest to excel output_excel_file_path = self.export_sheet_to_excel(manifest_url = manifest_url, title=title) + # populate exported sheet self.populate_existing_excel_spreadsheet(output_excel_file_path, manifest) return output_excel_file_path From a6bb21da896f9f0d6fdc68a2d0b89e18d2e11ec2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 3 May 2023 13:07:45 -0700 Subject: [PATCH 521/615] change check for finding if no datasets found --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 3bd7c7689..c9f0786e4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1725,7 +1725,7 @@ def getDatasetProject(self, datasetId: str) -> str: dataset_row = self.storageFileviewTable[dataset_index] # re-query if no datasets found - if len(dataset_row) == 0: + if dataset_row.empty: sleep(5) self._query_fileview() # Subset main file view From d3456204a98b745108800e2fa50141ec4bfa0bac Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 3 May 2023 13:56:31 -0700 Subject: [PATCH 522/615] Clean up code, get rid of commented code, update doc strings, fix populate_existing_excel_spreadsheet to look if additional_df is empty first before overwriting the df --- schematic/manifest/generator.py | 96 ++++++++++----------------------- 1 file changed, 27 insertions(+), 69 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index d43f93e4f..df152fd95 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1256,13 +1256,16 @@ def get_empty_manifest(self, json_schema_filepath=None): ) return manifest_url - def _get_mismatched_columns(self, headers_1, headers_2): - """ + def _get_mismatched_columns(self, headers_1:list , headers_2:list) -> list: + """Compare two colunm sets and get cols that are in headers_1, but not headers_2 + Args: + headers_1 (list): list of column headers + headers_2 (list): list of column headers + Returns: + list: column headers in headers_1 but not headers_2 """ - # Compare two colunm sets and get cols that are in headers_1, but not headers_2 - mismatched_columns = set(headers_1) - set(headers_2) - return mismatched_columns + return set(headers_1) - set(headers_2) def set_dataframe_by_url( @@ -1374,8 +1377,6 @@ def get_manifest_with_annotations( # Generate empty manifest using `additional_metadata` manifest_url = self.get_empty_manifest() - - #TODO: MIALY Make sure this functionality is preserved, should be bc there isnt another manifest we are merging with. manifest_df = self.get_dataframe_by_url(manifest_url) # Annotations clashing with manifest attributes are skipped @@ -1437,22 +1438,6 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st """ ## TO DO: deprecate sheet_url parameter and simplify the logic here - # check if output_format parameter gets set. If not, check the sheet_url parameter - - ''' - if not output_format: - # if the sheet_url parameter gets set to True, return a google sheet url - if sheet_url: - # populate google sheet with dataframe - manifest_sh = self.set_dataframe_by_url(empty_manifest_url, dataframe) - return manifest_sh.url - # else, return a pandas dataframe - else: - return dataframe - else: - ''' - # if not saving excel delete after header is made. - # if the output type gets set to "dataframe", return a data frame if output_format == "dataframe": """ @@ -1476,13 +1461,12 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st return output_file_path - # for all other cases, return a google sheet url after populating the dataframe - # TODO: add "google_sheet" as an output choice + # Return google sheet if sheet_url flag is raised. + # TODO: Depreciate sheet URL and add google_sheet as an output_format choice. elif sheet_url: manifest_sh = self.set_dataframe_by_url(manifest_url=empty_manifest_url, manifest_df=dataframe, out_of_schema_columns=out_of_schema_columns) return manifest_sh.url - # new default is dataframe? else: return dataframe @@ -1541,7 +1525,6 @@ def get_manifest( updated_df, out_of_schema_columns = self._update_dataframe_with_existing_df(empty_manifest_url=empty_manifest_url, existing_df=manifest_record[1]) # determine the format of manifest - #result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, empty_manifest_url=empty_manifest_url, dataframe = manifest_record[1]) result = self._handle_output_format_logic(output_format = output_format, output_path = output_path, sheet_url = sheet_url, @@ -1585,15 +1568,17 @@ def get_manifest( return result def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_df: pd.DataFrame) -> pd.DataFrame: - """ - Handle scenario when existing manifest does not match new - manifest template due to changes in the data model: - - the sheet column header reflect the latest schema - the existing manifest column-set may be outdated - ensure that, if missing, attributes from the latest schema are added to the - column-set of the existing manifest so that the user can modify their data if needed - to comply with the latest schema + """MIALY + Handle scenario when existing manifest does not match new manifest template due to changes in the data model: + the sheet column header reflect the latest schema the existing manifest column-set may be outdated + ensure that, if missing, attributes from the latest schema are added to the column-set of the existing manifest so that the user can modify their data if needed + to comply with the latest schema. + Args: + empty_manifest_url (str): + existing_df (Pd.DataFrame): + + Returns: + updated_df (Pd.DataFrame): new columns are added to existing_df """ # Get headers for the current schema and existing manifest df. @@ -1639,44 +1624,17 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a - The naming of existing and additional df is a bit confusing. ''' # load workbook - #TODO: UPDATE NAMING HERE existing_excel_path to excel_path - # Additional_df to updated_df workbook = load_workbook(existing_excel_path) - ''' - #get missing columns and sort manifest - #get existing headers - existing_df = pd.read_excel(existing_excel_path, sheet_name="Sheet1") - current_schema_headers = list(existing_df.columns) - additional_df_headers = list(additional_df.columns) - - # get new column headers - out_of_schema_columns = list(self._get_mismatched_columns(current_schema_headers, additional_df_headers)) - - # get columns that are missing from the additional df - missing_schema_columns = list(self._get_mismatched_columns(additional_df_headers, current_schema_headers)) - breakpoint() - # Full set of columns to add - columns_to_add = out_of_schema_columns + missing_schema_columns - ''' + # initalize excel writer with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='replace') as writer: writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.worksheets["Sheet1"] - ''' - df_additional_headers = pd.DataFrame(columns=additional_df.columns) - df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=0, index=False, header=True) - ''' - ''' - # if there are new columns, add them to the end of spreadsheet - # Note: previously, we tried looping through the out of schema columns and use worksheet.cell to modify a particular cell. But that functionality is no longer working. - if missing_schema_columns: - df_additional_headers = pd.DataFrame(columns=missing_schema_columns) - start_col_index = len(current_schema_headers) - df_additional_headers.to_excel(writer, "Sheet1", startrow=0, startcol=start_col_index, index=False, header=True) - ''' - # overwrite existing df with new df - # In future dont start with a prepopulated excel. - additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) + + # overwrite existing df with new df, if there is info in the new df + # In future depreciate using a prepopulated excel. + if not additional_df.empty: + additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. From 48ddcb88dc6a16164d684153d1e6a9a8cf628024 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 3 May 2023 15:26:20 -0700 Subject: [PATCH 523/615] Update tests to comport with changes in generator --- tests/test_manifest.py | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index e665e40a0..44cf05ad8 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -169,21 +169,15 @@ def test_get_manifest_excel(self, helpers, sheet_url, output_format, dataset_id) # if dataset id exists, it could return pandas dataframe, google spreadsheet, or an excel spreadsheet if dataset_id: - if output_format: - - if output_format == "dataframe": - assert isinstance(manifest, pd.DataFrame) - elif output_format == "excel": - assert os.path.exists(manifest) == True - else: - assert type(manifest) is str - assert manifest.startswith("https://docs.google.com/spreadsheets/") + if output_format == "dataframe": + assert isinstance(manifest, pd.DataFrame) + elif output_format == "excel": + assert os.path.exists(manifest) == True + elif sheet_url: + assert type(manifest) is str + assert manifest.startswith("https://docs.google.com/spreadsheets/") else: - if sheet_url: - assert type(manifest) is str - assert manifest.startswith("https://docs.google.com/spreadsheets/") - else: - assert isinstance(manifest, pd.DataFrame) + assert isinstance(manifest, pd.DataFrame) # if dataset id does not exist, it could return an empty google sheet or an empty excel spreadsheet exported from google else: @@ -282,15 +276,17 @@ def test_gather_all_fields(self, simple_manifest_generator): @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) - def test_get_missing_columns(self, simple_manifest_generator, wb_headers, manifest_columns): + def test_get_mismatched_columns(self, simple_manifest_generator, wb_headers, manifest_columns): generator = simple_manifest_generator manifest_test_df = pd.DataFrame(columns = manifest_columns) - missing_columns = generator._get_missing_columns(wb_headers, manifest_test_df) + manifest_test_df_headers = list(manifest_test_df.columns) + out_of_schema_columns = generator._get_mismatched_columns(manifest_test_df_headers, wb_headers) + if "column four" not in wb_headers: - assert "column four" in missing_columns + assert "column four" in out_of_schema_columns else: - assert "column four" not in missing_columns + assert "column four" not in out_of_schema_columns @@ -314,14 +310,15 @@ def test_populate_existing_excel_spreadsheet(self, simple_manifest_generator, si # if we are not adding any additional content if additional_test_df.empty: + # make sure that new content also gets added assert len(new_df.columns) == 6 # we should be able to see new columns get added else: # new columns get added assert not new_df[["test_one_column", "test_two_column"]].empty - assert len(new_df.test_one_column.value_counts()) > 0 - assert len(new_df.test_two_column.value_counts()) > 0 + assert len(new_df.test_one_column.value_counts()) > 0 + assert len(new_df.test_two_column.value_counts()) > 0 # remove file os.remove(dummy_output_path) From 1fc72b2210e78f05a1b3ea23f131a9357488a0b0 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 12:38:30 -0400 Subject: [PATCH 524/615] switch to use USE_LISTEN_PORT --- docker-compose.yml | 2 +- env.example | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 10caddc47..728104396 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -28,7 +28,7 @@ services: networks: - schematic ports: - - "80:80" + - "${USE_LISTEN_PORT}:80" - "443:443" networks: schematic: diff --git a/env.example b/env.example index e2545efcd..b13b90997 100644 --- a/env.example +++ b/env.example @@ -1,4 +1,6 @@ # API server SERVER_PROTOCOL=http:// SERVER_DOMAIN=localhost +# port on the host machine +USE_LISTEN_PORT=7080 SERVICE_ACCOUNT_CREDS='Provide service account creds' \ No newline at end of file From 4203abbcecf378857ea519cf818d0ab533665b81 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 12:53:44 -0400 Subject: [PATCH 525/615] update readme.md --- schematic_api/api/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 610f19a4a..0941dac50 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -11,13 +11,13 @@ If you define `APP_PORT` as `3001` in `docker-compose.yml`, you should be able t To start a docker container that runs flask application with uWSGI: 1) Comment out line 4 to line 19 in `docker-compose.yml`. -2) Create .env file based on env.example. Fill in `service_account_creds.json` +2) Create .env file based on env.example. Fill in `service_account_creds.json` and wrap around the credentials with single quotes. 3) Make sure that you have all the dependencies installed, including uWSGI and flask. 4) Build a docker image and spin up docker container `schematic-api-aws` by running: ```bash docker compose up ``` -If you define the value of SERVER_PORT as `7080` in `.env` file, you should be able to see the application running when visiting `http://localhost:7080/v1/ui/` +If you define the value of port as `7080` in `.env` file, you should be able to see the application running when visiting `http://localhost:7080/v1/ui/` By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. @@ -54,7 +54,7 @@ Make sure that the following libraries have the correct version: * markupsafe version: ^2.1.0 ## Notes for using schematic features and API endpoints utilizing Google Services (e.g. manifest generation): -Before trying out the API endpoints, please make sure that you have obtained `credentials.json`, `schematic_service_account_creds.json`, and `token.pickle`. (Instructions can be found in schematic/README.md) +Before trying out the API endpoints, please make sure that you have obtained `schematic_service_account_creds.json` (Instructions can be found in schematic/README.md) ### GET /manifest/generate From db5b37b29fe0ce702b9b94111b9937b36c7ab0ba Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 13:15:36 -0400 Subject: [PATCH 526/615] set uwsgi as optional --- poetry.lock | 60 ++++++++++++++++++------------------- pyproject.toml | 2 +- schematic_api/api/README.md | 8 ++++- 3 files changed, 38 insertions(+), 32 deletions(-) diff --git a/poetry.lock b/poetry.lock index b8ab6cfad..6c23b1908 100644 --- a/poetry.lock +++ b/poetry.lock @@ -128,12 +128,12 @@ optional = false python-versions = ">=3.6" [package.extras] -cov = ["attrs", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] -dev = ["attrs"] -docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] -tests = ["attrs", "zope-interface"] -tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] -tests_no_zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist"] +cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] +dev = ["attrs[docs,tests]"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] +tests = ["attrs[tests-no-zope]", "zope.interface"] +tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] +tests_no_zope = ["cloudpickle", "hypothesis", "mypy (>=0.971,<0.990)", "pympler", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-xdist[psutil]"] [[package]] name = "babel" @@ -414,7 +414,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest (<5)", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "pytest", "pytest-cov", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] [[package]] name = "dill" @@ -726,7 +726,7 @@ optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" [package.extras] -docs = ["docutils (<0.18)", "sphinx"] +docs = ["Sphinx", "docutils (<0.18)"] test = ["objgraph", "psutil"] [[package]] @@ -770,7 +770,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl-flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "inflection" @@ -812,7 +812,7 @@ tornado = ">=6.1" traitlets = ">=5.4.0" [package.extras] -cov = ["coverage", "curio", "matplotlib", "pytest-cov", "trio"] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] pyqt5 = ["pyqt5"] pyside6 = ["pyside6"] @@ -949,7 +949,7 @@ python-versions = ">=3.7" [package.extras] test = ["async-timeout", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] -trio = ["async-generator", "trio"] +trio = ["async_generator", "trio"] [[package]] name = "jinja2" @@ -1161,7 +1161,7 @@ six = "*" [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["backports-unittest-mock", "collective-checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] +testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", "gdata", "keyring[test] (>=10.3.1)", "pycrypto", "pytest (>=3.5)", "pytest-flake8", "pytest-sugar (>=0.9.1)", "python-keyczar"] [[package]] name = "lazy-object-proxy" @@ -1305,7 +1305,7 @@ traitlets = ">=5.3" [package.extras] dev = ["pre-commit"] -docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient", "sphinx (>=1.7)", "sphinx-book-theme"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme"] test = ["ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] @@ -1335,9 +1335,9 @@ tinycss2 = "*" traitlets = ">=5.0" [package.extras] -all = ["nbconvert"] +all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] -qtpdf = ["nbconvert"] +qtpdf = ["nbconvert[qtpng]"] qtpng = ["pyqtwebengine (>=5.15)"] serve = ["tornado (>=6.1)"] test = ["ipykernel", "ipywidgets (>=7)", "pre-commit", "pytest", "pytest-dependency"] @@ -2104,7 +2104,7 @@ python-versions = "<3.12,>=3.8" numpy = ">=1.19.5,<1.27.0" [package.extras] -dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing-extensions"] +dev = ["click", "doit (>=0.36.0)", "flake8", "mypy", "pycodestyle", "pydevtool", "rich-click", "typing_extensions"] doc = ["matplotlib (>2)", "numpydoc", "pydata-sphinx-theme (==0.9.0)", "sphinx (!=4.1.0)", "sphinx-design (>=0.2.0)"] test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeout", "pytest-xdist", "scikit-umfpack", "threadpoolctl"] @@ -2129,8 +2129,8 @@ optional = false python-versions = "*" [package.extras] -nativelib = ["pyobjc-framework-cocoa", "pywin32"] -objc = ["pyobjc-framework-cocoa"] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] win32 = ["pywin32"] [[package]] @@ -2143,8 +2143,8 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -2324,7 +2324,7 @@ postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] postgresql_psycopg2binary = ["psycopg2-binary"] postgresql_psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql", "pymysql (<1)"] -sqlcipher = ["sqlcipher3-binary"] +sqlcipher = ["sqlcipher3_binary"] [[package]] name = "sqlalchemy-utils" @@ -2346,8 +2346,8 @@ intervals = ["intervals (>=0.7.1)"] password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] -test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports-zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test_all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports-zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test_all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -2439,7 +2439,7 @@ python-versions = ">=3.7" webencodings = ">=0.4" [package.extras] -doc = ["sphinx", "sphinx-rtd-theme"] +doc = ["sphinx", "sphinx_rtd_theme"] test = ["flake8", "isort", "pytest"] [[package]] @@ -2540,7 +2540,7 @@ pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] -devenv = ["black", "pyroma", "pytest-cov", "zest-releaser"] +devenv = ["black", "pyroma", "pytest-cov", "zest.releaser"] test = ["pytest (>=4.3)", "pytest-mock (>=3.3)"] [[package]] @@ -2576,11 +2576,11 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "p socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] -name = "uwsgi" +name = "uWSGI" version = "2.0.21" description = "The uWSGI server" category = "main" -optional = false +optional = true python-versions = "*" [[package]] @@ -2657,12 +2657,12 @@ python-versions = ">=3.7" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "func-timeout", "jaraco-functools", "jaraco-itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "2e8922a96ef8a1b786b1783705fcec76e70f6d39965388ccc6076046a022de0f" +content-hash = "11ac64fffdf87867e5cd018221a2efb7c3252a2978d48e6b25a417c08d9f6861" [metadata.files] alabaster = [ @@ -4311,7 +4311,7 @@ urllib3 = [ {file = "urllib3-1.26.14-py2.py3-none-any.whl", hash = "sha256:75edcdc2f7d85b137124a6c3c9fc3933cdeaa12ecb9a6a959f22797a0feca7e1"}, {file = "urllib3-1.26.14.tar.gz", hash = "sha256:076907bf8fd355cde77728471316625a4d2f7e713c125f51953bb5b3eecf4f72"}, ] -uwsgi = [ +uWSGI = [ {file = "uwsgi-2.0.21.tar.gz", hash = "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9"}, ] wcwidth = [ diff --git a/pyproject.toml b/pyproject.toml index 4a29156dc..7e78cfacd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ dateparser = "^1.1.4" pandarallel = "^1.6.4" schematic-db = {version = "^0.0.6", extras = ["synapse"]} pyopenssl = "^23.0.0" -uWSGI = "^2.0.21" +uWSGI = {version = "^2.0.21", optional = true} [tool.poetry.dev-dependencies] diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 0941dac50..41a647658 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -1,5 +1,11 @@ +## Installation +For unix OSs users, simply run the following poetry command to install uWSGI: +```bash +poetry install -E uwsgi +``` + ## Setup -There are two ways to run schematic APIs: 1) start a flask server and run your application locally (preferred for external users); 2) build a docker image that allows you to run a container with flask application with uWSGI. +There are two ways to run schematic APIs: 1) start a flask server and run your application locally (preferred for external users); 2) build a docker image that allows you to run a container with flask application with uWSGI (only works for unix OSs users or windows user with WSL that could install uWSGI) To start a local Flask server and test your endpoints: From 148f44f65ccb84b7e1899676c3ec010332d1ce92 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 11:35:39 -0700 Subject: [PATCH 527/615] do not use auth token from synapse default headers --- schematic/models/metadata.py | 2 ++ schematic/store/synapse.py | 39 ++++++++++++++++++++++++------------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/schematic/models/metadata.py b/schematic/models/metadata.py index d10d27151..167841f68 100644 --- a/schematic/models/metadata.py +++ b/schematic/models/metadata.py @@ -343,6 +343,7 @@ def submit_metadata_manifest( useSchemaLabel = use_schema_label, hideBlanks = hide_blanks, table_manipulation=table_manipulation, + access_token = access_token, ) restrict_maniest = True @@ -355,6 +356,7 @@ def submit_metadata_manifest( hideBlanks = hide_blanks, restrict_manifest=restrict_maniest, table_manipulation=table_manipulation, + access_token = access_token, ) logger.info(f"No validation errors occured during validation.") diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c9f0786e4..a6c6c9bbe 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -781,6 +781,7 @@ def uploadDB(self, restrict: bool = False, useSchemaLabel: bool = True, table_manipulation: str = 'replace', + access_token: str = None, ): """ Method to upload a database to an asset store. In synapse, this will upload a metadata table @@ -805,7 +806,7 @@ def uploadDB(self, col_schema, table_manifest = self.formatDB(se, manifest, useSchemaLabel) - manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict, access_token) return manifest_table_id, manifest, table_manifest @@ -865,6 +866,7 @@ def buildDB(self, table_manifest: pd.DataFrame, table_manipulation: str, restrict: bool = False, + access_token: str = None, ): """ Method to construct the table appropriately: create new table, replace existing, or upsert new into existing @@ -894,7 +896,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) + manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId, access_token=access_token) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) @@ -1267,6 +1269,7 @@ def upload_manifest_as_table( useSchemaLabel, hideBlanks, table_manipulation, + access_token, ): """Upload manifest to Synapse as a table and csv. Args: @@ -1293,7 +1296,8 @@ def upload_manifest_as_table( table_name, restrict, useSchemaLabel, - table_manipulation) + table_manipulation, + access_token) manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) # Load manifest to synapse as a CSV File @@ -1312,7 +1316,9 @@ def upload_manifest_as_table( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation='update',) + table_manipulation='update', + access_token=access_token, + ) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1377,6 +1383,7 @@ def upload_manifest_combo( useSchemaLabel, hideBlanks, table_manipulation, + access_token ): """Upload manifest to Synapse as a table and CSV with entities. Args: @@ -1402,7 +1409,9 @@ def upload_manifest_combo( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation=table_manipulation,) + table_manipulation=table_manipulation, + access_token=access_token, + ) manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) @@ -1422,7 +1431,9 @@ def upload_manifest_combo( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation='update',) + table_manipulation='update', + access_token=access_token, + ) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1431,7 +1442,7 @@ def upload_manifest_combo( def associateMetadataWithFiles( self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'table_file_and_entities', - useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', access_token: str = None, ) -> str: """Associate metadata with files in a storage dataset already on Synapse. Upload metadataManifest in the storage dataset folder on Synapse as well. Return synapseId of the uploaded manifest file. @@ -1499,6 +1510,7 @@ def associateMetadataWithFiles( hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, + access_token=access_token, ) elif manifest_record_type == "file_and_entities": manifest_synapse_file_id = self.upload_manifest_as_csv( @@ -1528,6 +1540,7 @@ def associateMetadataWithFiles( hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, + access_token=access_token, ) else: raise ValueError("Please enter a valid manifest_record_type.") @@ -1950,7 +1963,7 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No return existingTableId - def _get_schematic_db_creds(synStore): + def _get_schematic_db_creds(synStore, access_token): username = None authtoken = None @@ -1961,10 +1974,10 @@ def _get_schematic_db_creds(synStore): if env_access_token: authtoken = env_access_token - # Get token from authorization header + # Get token passed in from api endpoint # Primarily useful for API endpoint functionality - if 'Authorization' in synStore.syn.default_headers: - authtoken = synStore.syn.default_headers['Authorization'].split('Bearer ')[-1] + if access_token: + authtoken = access_token # retrive credentials from synapse object # Primarily useful for local users, could only be stored here when a .synapseConfig file is used, but including to be safe @@ -1999,7 +2012,7 @@ def _get_schematic_db_creds(synStore): return username, authtoken - def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None, access_token: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse For upsert functionality to work, primary keys must follow the naming convention of _id @@ -2019,7 +2032,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non existingTableId: synID of the already existing table that had its metadata replaced """ - username, authtoken = TableOperations._get_schematic_db_creds(synStore) + username, authtoken = TableOperations._get_schematic_db_creds(synStore, access_token) synConfig = SynapseConfig(username, authtoken, synStore.getDatasetProject(datasetId)) synapseDB = SynapseDatabase(synConfig) From da2c7bd942d33ed3b1e980693786533766d167ed Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 4 May 2023 12:31:48 -0700 Subject: [PATCH 528/615] update formatting and documentation --- schematic/manifest/generator.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index df152fd95..a17688ecf 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1420,6 +1420,7 @@ def export_sheet_to_excel(self, title: str = None, manifest_url : str = None, ou # otherwise, use the default location else: output_excel_file_path = os.path.abspath(os.path.join(os.getcwd(), file_name)) + # export the manifest to excel export_manifest_drive_service(manifest_url, file_path=output_excel_file_path, mimeType = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') @@ -1427,16 +1428,18 @@ def export_sheet_to_excel(self, title: str = None, manifest_url : str = None, ou def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None, out_of_schema_columns=None): """ - handle the logic between sheet_url parameter and output_format parameter to determine the type of output to return + Handle the logic between sheet_url parameter and output_format parameter to determine the type of output to return Args: output_format: Determines if Google sheet URL, pandas dataframe, or Excel spreadsheet gets returned. sheet_url (Will be deprecated): a boolean ; determine if a pandas dataframe or a google sheet url gets return empty_manifest_url: Google sheet URL that leads to an empty manifest dataframe: the pandas dataframe that contains the metadata that needs to be populated to an empty manifest output_path: Determines the output path of the exported manifest (only relevant if returning an excel spreadsheet) - return: a pandas dataframe, file path of an excel spreadsheet, or a google sheet URL + Return: + a pandas dataframe, file path of an excel spreadsheet, or a google sheet URL + TODO: + Depreciate sheet URL and add google_sheet as an output_format choice. """ - ## TO DO: deprecate sheet_url parameter and simplify the logic here # if the output type gets set to "dataframe", return a data frame if output_format == "dataframe": @@ -1448,11 +1451,12 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st # if the output type gets set to "excel", return an excel spreadsheet elif output_format == "excel": - # export the manifest url to excel - # note: the manifest url being used here is an empty manifest url that only contains column header - - # export manifest that only contains column headers to Excel - output_file_path = self.export_sheet_to_excel(title = self.title, manifest_url = empty_manifest_url, output_location = output_path) + # export manifest url that only contains column headers to Excel + output_file_path = self.export_sheet_to_excel(title = self.title, + manifest_url = empty_manifest_url, + output_location = output_path, + ) + if not os.path.exists(output_file_path): logger.error(f'Export to Excel spreadsheet fail. Please make sure that file path {output_file_path} is valid') @@ -1462,11 +1466,11 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st return output_file_path # Return google sheet if sheet_url flag is raised. - # TODO: Depreciate sheet URL and add google_sheet as an output_format choice. elif sheet_url: manifest_sh = self.set_dataframe_by_url(manifest_url=empty_manifest_url, manifest_df=dataframe, out_of_schema_columns=out_of_schema_columns) return manifest_sh.url - + + # Default return a DataFrame else: return dataframe @@ -1568,17 +1572,17 @@ def get_manifest( return result def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_df: pd.DataFrame) -> pd.DataFrame: - """MIALY + """ Handle scenario when existing manifest does not match new manifest template due to changes in the data model: the sheet column header reflect the latest schema the existing manifest column-set may be outdated ensure that, if missing, attributes from the latest schema are added to the column-set of the existing manifest so that the user can modify their data if needed to comply with the latest schema. Args: - empty_manifest_url (str): - existing_df (Pd.DataFrame): + empty_manifest_url (str): Google Sheet URL with an empty manifest with headers. + existing_df (Pd.DataFrame): df of an existing manifest Returns: - updated_df (Pd.DataFrame): new columns are added to existing_df + updated_df (Pd.DataFrame): existing_df with new_columns added. """ # Get headers for the current schema and existing manifest df. From 25b39c3c777019d73c2d8fbb654c6ccdb182e17c Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 4 May 2023 12:45:07 -0700 Subject: [PATCH 529/615] add todo for get_empty_manifest --- schematic/manifest/generator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index a17688ecf..72a928439 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1242,7 +1242,7 @@ def get_empty_manifest(self, json_schema_filepath=None): Returns: manifest_url (str): url of the google sheet manifest. TODO: - In future + Refactor to not be dependent on GS. """ spreadsheet_id = self._create_empty_manifest_spreadsheet(self.title) json_schema = self._get_json_schema(json_schema_filepath) From 198f6adb7e8b63589d8a47c24f146f795ff874f7 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 16:24:40 -0400 Subject: [PATCH 530/615] update ocmments --- schematic/utils/general.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index ab95c3555..1dc26e4ef 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -40,14 +40,13 @@ def unlist(_list): def get_dir_size(path: str): - """calculate total size of a directory + """Recursively descend the directory tree rooted at the top and call .st_size function to calculate size of files in bytes. Args: path: path to a folder - return: total size of a directory + return: total size of all the files in a given directory in bytes. """ total = 0 - # Example usage of os.scandir could be found here: https://docs.python.org/3/library/os.html#os.scandir - # Technically, scandir.close() is called automatically. But it is still advisable to call it explicitly or use the with statement. + # Recursively scan directory to find entries with os.scandir(path) as it: for entry in it: if entry.is_file(): From 4e7dcd9801496417d7470e750c1e13f70f1f956f Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 16:26:23 -0400 Subject: [PATCH 531/615] return the calculation result --- schematic/utils/general.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/utils/general.py b/schematic/utils/general.py index 1dc26e4ef..1145d013b 100644 --- a/schematic/utils/general.py +++ b/schematic/utils/general.py @@ -80,8 +80,7 @@ def convert_gb_to_bytes(gb: int): gb: number of gb return: total number of bytes """ - bytes_to_return = gb * 1024 * 1024 * 1024 - return bytes_to_return + return gb * 1024 * 1024 * 1024 def entity_type_mapping(syn, entity_id): """ From a03273c3e4789e3b53ad8aa43bd0360374d73b76 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 16:36:05 -0400 Subject: [PATCH 532/615] update instructions in readme --- schematic_api/api/README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 41a647658..a94260f3a 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -15,11 +15,12 @@ python3 run_api.py ``` If you define `APP_PORT` as `3001` in `docker-compose.yml`, you should be able to see the application running when visiting `http://localhost:3001/v1/ui/` -To start a docker container that runs flask application with uWSGI: -1) Comment out line 4 to line 19 in `docker-compose.yml`. -2) Create .env file based on env.example. Fill in `service_account_creds.json` and wrap around the credentials with single quotes. -3) Make sure that you have all the dependencies installed, including uWSGI and flask. -4) Build a docker image and spin up docker container `schematic-api-aws` by running: +After installing uWSGI, flask and connexion, to start a docker container that runs flask application with uWSGI: +1) Comment out the first part of `docker-compose.yml` and focus only on building container `schematic-aws`. +2) Get `service_account_creds.json` by doing `schematic init --config /path/to/config.yml`. +3) Make a copy of `env.example` and rename it as `.env` and keep it in the same directory as `env.example` By default, schematic uses port 7080. If port 7080 is not available, please update `SERVER_PORT` in .env file. +4) Copy the content of `service_account_creds.json` and put it in `.env` file after key `SERVICE_ACCOUNT_CREDS`. Remember to wrap around the credentials with single quotes. +5) Build a docker image and spin up docker container `schematic-api-aws` by running: ```bash docker compose up ``` From 5c94aa0399089fedde5884801817723338bc69df Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 13:58:12 -0700 Subject: [PATCH 533/615] Revert "do not use auth token from synapse default headers" This reverts commit 148f44f65ccb84b7e1899676c3ec010332d1ce92. --- schematic/models/metadata.py | 2 -- schematic/store/synapse.py | 39 ++++++++++++------------------------ 2 files changed, 13 insertions(+), 28 deletions(-) diff --git a/schematic/models/metadata.py b/schematic/models/metadata.py index 167841f68..d10d27151 100644 --- a/schematic/models/metadata.py +++ b/schematic/models/metadata.py @@ -343,7 +343,6 @@ def submit_metadata_manifest( useSchemaLabel = use_schema_label, hideBlanks = hide_blanks, table_manipulation=table_manipulation, - access_token = access_token, ) restrict_maniest = True @@ -356,7 +355,6 @@ def submit_metadata_manifest( hideBlanks = hide_blanks, restrict_manifest=restrict_maniest, table_manipulation=table_manipulation, - access_token = access_token, ) logger.info(f"No validation errors occured during validation.") diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index a6c6c9bbe..c9f0786e4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -781,7 +781,6 @@ def uploadDB(self, restrict: bool = False, useSchemaLabel: bool = True, table_manipulation: str = 'replace', - access_token: str = None, ): """ Method to upload a database to an asset store. In synapse, this will upload a metadata table @@ -806,7 +805,7 @@ def uploadDB(self, col_schema, table_manifest = self.formatDB(se, manifest, useSchemaLabel) - manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict, access_token) + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) return manifest_table_id, manifest, table_manifest @@ -866,7 +865,6 @@ def buildDB(self, table_manifest: pd.DataFrame, table_manipulation: str, restrict: bool = False, - access_token: str = None, ): """ Method to construct the table appropriately: create new table, replace existing, or upsert new into existing @@ -896,7 +894,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId, access_token=access_token) + manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) @@ -1269,7 +1267,6 @@ def upload_manifest_as_table( useSchemaLabel, hideBlanks, table_manipulation, - access_token, ): """Upload manifest to Synapse as a table and csv. Args: @@ -1296,8 +1293,7 @@ def upload_manifest_as_table( table_name, restrict, useSchemaLabel, - table_manipulation, - access_token) + table_manipulation) manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) # Load manifest to synapse as a CSV File @@ -1316,9 +1312,7 @@ def upload_manifest_as_table( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation='update', - access_token=access_token, - ) + table_manipulation='update',) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1383,7 +1377,6 @@ def upload_manifest_combo( useSchemaLabel, hideBlanks, table_manipulation, - access_token ): """Upload manifest to Synapse as a table and CSV with entities. Args: @@ -1409,9 +1402,7 @@ def upload_manifest_combo( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation=table_manipulation, - access_token=access_token, - ) + table_manipulation=table_manipulation,) manifest = self.add_entities(se, schemaGenerator, manifest, manifest_record_type, datasetId, useSchemaLabel, hideBlanks, manifest_synapse_table_id) @@ -1431,9 +1422,7 @@ def upload_manifest_combo( table_name, restrict, useSchemaLabel=useSchemaLabel, - table_manipulation='update', - access_token=access_token, - ) + table_manipulation='update',) # Set annotations for the table manifest manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) @@ -1442,7 +1431,7 @@ def upload_manifest_combo( def associateMetadataWithFiles( self, schemaGenerator: SchemaGenerator, metadataManifestPath: str, datasetId: str, manifest_record_type: str = 'table_file_and_entities', - useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', access_token: str = None, + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False, table_manipulation: str = 'replace', ) -> str: """Associate metadata with files in a storage dataset already on Synapse. Upload metadataManifest in the storage dataset folder on Synapse as well. Return synapseId of the uploaded manifest file. @@ -1510,7 +1499,6 @@ def associateMetadataWithFiles( hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, - access_token=access_token, ) elif manifest_record_type == "file_and_entities": manifest_synapse_file_id = self.upload_manifest_as_csv( @@ -1540,7 +1528,6 @@ def associateMetadataWithFiles( hideBlanks=hideBlanks, manifest_record_type=manifest_record_type, table_manipulation=table_manipulation, - access_token=access_token, ) else: raise ValueError("Please enter a valid manifest_record_type.") @@ -1963,7 +1950,7 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No return existingTableId - def _get_schematic_db_creds(synStore, access_token): + def _get_schematic_db_creds(synStore): username = None authtoken = None @@ -1974,10 +1961,10 @@ def _get_schematic_db_creds(synStore, access_token): if env_access_token: authtoken = env_access_token - # Get token passed in from api endpoint + # Get token from authorization header # Primarily useful for API endpoint functionality - if access_token: - authtoken = access_token + if 'Authorization' in synStore.syn.default_headers: + authtoken = synStore.syn.default_headers['Authorization'].split('Bearer ')[-1] # retrive credentials from synapse object # Primarily useful for local users, could only be stored here when a .synapseConfig file is used, but including to be safe @@ -2012,7 +1999,7 @@ def _get_schematic_db_creds(synStore, access_token): return username, authtoken - def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None, access_token: str = None): + def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse For upsert functionality to work, primary keys must follow the naming convention of _id @@ -2032,7 +2019,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non existingTableId: synID of the already existing table that had its metadata replaced """ - username, authtoken = TableOperations._get_schematic_db_creds(synStore, access_token) + username, authtoken = TableOperations._get_schematic_db_creds(synStore) synConfig = SynapseConfig(username, authtoken, synStore.getDatasetProject(datasetId)) synapseDB = SynapseDatabase(synConfig) From ac6e7577839a0f8fed6405cb929200ddfdbbac51 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 14:05:15 -0700 Subject: [PATCH 534/615] Do not check for local creds if found from env or api --- schematic/store/synapse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c9f0786e4..826d52f20 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1960,11 +1960,13 @@ def _get_schematic_db_creds(synStore): env_access_token = os.getenv("SYNAPSE_ACCESS_TOKEN") if env_access_token: authtoken = env_access_token + return username, authtoken # Get token from authorization header # Primarily useful for API endpoint functionality if 'Authorization' in synStore.syn.default_headers: authtoken = synStore.syn.default_headers['Authorization'].split('Bearer ')[-1] + return username, authtoken # retrive credentials from synapse object # Primarily useful for local users, could only be stored here when a .synapseConfig file is used, but including to be safe From 1c46a1414d3102a19b8a9299d1c2cbb207d6b9cf Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 14:36:00 -0700 Subject: [PATCH 535/615] update comments --- schematic/utils/df_utils.py | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 940efee84..6f58add8c 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -15,6 +15,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): """ Universal function to load CSVs and return DataFrames Parses string entries to convert as appropriate to type int, float, and pandas timestamp + Pandarallel is used for type inference for large manfiests to improve performance Args: file_path: path of csv to open preserve_raw_input: Bool. If false, convert cell datatypes to an inferred type @@ -22,44 +23,56 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): load_args: dict of key value pairs to be passed to the pd.read_csv function **kwargs: keyword arguments for pd.read_csv() - Returns: a processed dataframe for manifests or unprocessed df for data models + Returns: a processed dataframe for manifests or unprocessed df for data models and where indicated """ - #Read CSV to df as type specified in kwargs + # start performance timer t_load_df = perf_counter() + + #Read CSV to df as type specified in kwargs org_df = pd.read_csv(file_path, keep_default_na = True, encoding='utf8', **load_args) + # If type inference not allowed: trim and return if preserve_raw_input: #only trim if not data model csv if not data_model: org_df=trim_commas_df(org_df) + # log manifest load and processing time logger.debug(f"Load Elapsed time {perf_counter()-t_load_df}") return org_df + # If type inferences is allowed: infer types, trim, and return else: + # create a separate copy of the manifest + # before beginning conversions to store float values float_df=deepcopy(org_df) - #Find integers stored as strings - #Cast the columns in dataframe to string while preserving NaN + + # Cast the columns in the dataframe to string and + # replace Null values with empty strings null_cells = org_df.isnull() org_df = org_df.astype(str).mask(null_cells, '') - if org_df.size < 1000: + # Find integers stored as strings and replace with entries of type np.int64 + if org_df.size < 1000: # If small manifest, iterate as normal for improved performance ints = org_df.applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) - else: + + else: # parallelize iterations for large manfiests pandarallel.initialize(verbose = 1) ints = org_df.parallel_applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) - #convert strings to numerical dtype (float) if possible, preserve non-numerical strings + # convert strings to numerical dtype (float) if possible, preserve non-numerical strings for col in org_df.columns: float_df[col]=pd.to_numeric(float_df[col], errors='coerce') + # replace values that couldn't be converted to float with the original str values float_df[col].fillna(org_df[col][float_df[col].isna()],inplace=True) - #Trim nans and empty rows and columns + # Trim nans and empty rows and columns processed_df = trim_commas_df(float_df) - #Store values that were entered as ints and dates + # Store values that were converted to type int in the final dataframe processed_df=processed_df.mask(ints != False, other = ints) + # log manifest load and processing time logger.debug(f"Load Elapsed time {perf_counter()-t_load_df}") return processed_df From 6c5961a6c086400a5471a4f8df5b964ca7cb9b33 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 17:45:30 -0400 Subject: [PATCH 536/615] update docker file and add uwsgi as optional dependencies --- pyproject.toml | 4 ++-- schematic_api/Dockerfile | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 7e78cfacd..b51fa51ca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,8 +72,6 @@ dateparser = "^1.1.4" pandarallel = "^1.6.4" schematic-db = {version = "^0.0.6", extras = ["synapse"]} pyopenssl = "^23.0.0" -uWSGI = {version = "^2.0.21", optional = true} - [tool.poetry.dev-dependencies] pytest = "^7.0.0" @@ -84,6 +82,8 @@ python-dotenv = "^0.21.0" black = "^22.6.0" mypy = "^0.982" +[tool.poetry.group.aws.dependencies] +uWSGI = "^2.0.21" [tool.black] line-length = 88 diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index cc2d30b59..bc2400da1 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -14,6 +14,7 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ POETRY_VERSION=1.2.0 \ + POETRY_VIRTUALENVS_IN_PROJECT=true \ APP_PORT=80 \ APP_DIR=/opt/app \ SERVER_PROTOCOL=http:// \ @@ -47,7 +48,7 @@ RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" # copy relevant files and run poetry install COPY ./pyproject.toml ./poetry.lock ./uwsgi.ini ./config.yml ./run_api.py ./ RUN poetry config virtualenvs.create false -RUN poetry install --no-interaction --no-ansi --no-root +RUN poetry install --no-interaction --no-ansi --no-root --with aws # copy schematic_api folder COPY schematic_api ./schematic_api From c23272cd272fc855b9a143bfffcfd71efe0c32c6 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 17:47:40 -0400 Subject: [PATCH 537/615] change lock --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index 6c23b1908..cb859e7ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2579,8 +2579,8 @@ socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] name = "uWSGI" version = "2.0.21" description = "The uWSGI server" -category = "main" -optional = true +category = "dev" +optional = false python-versions = "*" [[package]] @@ -2662,7 +2662,7 @@ testing = ["flake8 (<5)", "func-timeout", "jaraco.functools", "jaraco.itertools" [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "11ac64fffdf87867e5cd018221a2efb7c3252a2978d48e6b25a417c08d9f6861" +content-hash = "ad3655e527484a7fffc4bf90b43527da8d6143e0dc8e5a8dfa406d56d9038001" [metadata.files] alabaster = [ From 3e3f2463e4329d083c4a8437a304fc0e8350d12f Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 4 May 2023 17:48:44 -0400 Subject: [PATCH 538/615] reoganize import and delete unused import --- schematic/store/synapse.py | 3 +-- schematic_api/api/__main__.py | 3 --- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 31750b66e..5d8340251 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -18,7 +18,6 @@ import re import synapseclient from time import sleep -from schematic.utils.general import get_dir_size, convert_size, convert_gb_to_bytes from synapseclient import ( Synapse, File, @@ -46,13 +45,13 @@ from schematic.utils.df_utils import update_df, load_df from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list +from schematic.utils.general import entity_type_mapping, get_dir_size, convert_size, convert_gb_to_bytes from schematic.schemas.explorer import SchemaExplorer from schematic.schemas.generator import SchemaGenerator from schematic.store.base import BaseStorage from schematic.exceptions import MissingConfigValueError, AccessCredentialsError from schematic import CONFIG -from schematic.utils.general import entity_type_mapping logger = logging.getLogger("Synapse storage") diff --git a/schematic_api/api/__main__.py b/schematic_api/api/__main__.py index 1aba56e45..923cebaf5 100644 --- a/schematic_api/api/__main__.py +++ b/schematic_api/api/__main__.py @@ -1,7 +1,4 @@ import os -import connexion -from schematic import CONFIG -from flask_cors import CORS from schematic_api.api import app From 9f40274e2ba2be20b281da4993846b5a9798eb70 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 15:32:03 -0700 Subject: [PATCH 539/615] Update example.single_rule.model.jsonld --- tests/data/example.single_rule.model.jsonld | 22 ++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/tests/data/example.single_rule.model.jsonld b/tests/data/example.single_rule.model.jsonld index 484ef2317..738bba05e 100644 --- a/tests/data/example.single_rule.model.jsonld +++ b/tests/data/example.single_rule.model.jsonld @@ -2920,7 +2920,7 @@ "sms:required": "sms:false", "sms:validationRules": [ "int error", - "IsNA" + "IsNA warning" ] }, { @@ -2944,6 +2944,9 @@ }, { "@id": "bts:MockRDBId" + }, + { + "@id": "bts:SourceManifest" } ], "sms:validationRules": [] @@ -2967,6 +2970,23 @@ "int" ] }, + { + "@id": "bts:SourceManifest", + "@type": "rdfs:Class", + "rdfs:comment": "TBD", + "rdfs:label": "SourceManifest", + "rdfs:subClassOf": [ + { + "@id": "bts:DataProperty" + } + ], + "schema:isPartOf": { + "@id": "http://schema.biothings.io" + }, + "sms:displayName": "SourceManifest", + "sms:required": "sms:true", + "sms:validationRules": [] + }, { "@id": "bts:Component", "@type": "rdfs:Class", From 468df56e0b3407bb84b183f7d89064f6327bcb7c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 4 May 2023 15:34:30 -0700 Subject: [PATCH 540/615] change cutoff size to a variable --- schematic/utils/df_utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 6f58add8c..e47c8723d 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -25,6 +25,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): Returns: a processed dataframe for manifests or unprocessed df for data models and where indicated """ + large_manifest_cutoff_size = 1000 # start performance timer t_load_df = perf_counter() @@ -53,7 +54,7 @@ def load_df(file_path, preserve_raw_input=True, data_model=False, **load_args): org_df = org_df.astype(str).mask(null_cells, '') # Find integers stored as strings and replace with entries of type np.int64 - if org_df.size < 1000: # If small manifest, iterate as normal for improved performance + if org_df.size < large_manifest_cutoff_size: # If small manifest, iterate as normal for improved performance ints = org_df.applymap(lambda x: np.int64(x) if str.isdigit(x) else False, na_action='ignore').fillna(False) else: # parallelize iterations for large manfiests From 5bfbd913034c2590d1e8b11b20932441d1fe3d8f Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 4 May 2023 21:54:04 -0700 Subject: [PATCH 541/615] added unit test for test_update_dataframe_with_existing_df --- tests/test_manifest.py | 60 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 57 insertions(+), 3 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 44cf05ad8..78c338886 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -276,19 +276,73 @@ def test_gather_all_fields(self, simple_manifest_generator): @pytest.mark.parametrize("wb_headers", [["column one", "column two", "column three"], ["column four", "column two"]]) @pytest.mark.parametrize("manifest_columns", [["column four"]]) - def test_get_mismatched_columns(self, simple_manifest_generator, wb_headers, manifest_columns): + def test_get_missing_columns(self, simple_manifest_generator, wb_headers, manifest_columns): generator = simple_manifest_generator manifest_test_df = pd.DataFrame(columns = manifest_columns) manifest_test_df_headers = list(manifest_test_df.columns) - out_of_schema_columns = generator._get_mismatched_columns(manifest_test_df_headers, wb_headers) + out_of_schema_columns = generator._get_missing_columns(manifest_test_df_headers, wb_headers) if "column four" not in wb_headers: assert "column four" in out_of_schema_columns else: assert "column four" not in out_of_schema_columns - + # Need to actually put in different dfs + @pytest.mark.parametrize("existing_manifest", [{"Patient ID": ["1738"], "Sex": ["Male"], "Year of Birth": ["1999"], "Diagnosis": [""], 'Component': [""], 'Cancer Type': [""], 'Family History': [""]}, + {"Patient ID": ["1738"], "Sex": ["Male"], "Year of Birth": ["1999"], "Diagnosis": [""], 'Component': [""], 'Cancer Type': [""], 'Family History': [""], 'Non Schema Column': [""]}, + {"Patient ID": ["1738"], "Sex": ["Male"]}, + None]) + @pytest.mark.google_credentials_needed + def test_update_dataframe_with_existing_df(self, helpers, existing_manifest): + ''' + Tests the following discrepancies with an existing schema: + - schema has matching columns to existing_df + - existing_df has columns the schema does not + - schema has columns the existing_df does not. + - No existing manifest + ''' + data_type = "Patient" + sheet_url = True + + # Instantiate the Manifest Generator. + generator = ManifestGenerator(path_to_json_ld=helpers.get_data_path("example.model.jsonld"), + root=data_type, + use_annotations=False, + ) + + # Generate a google sheet url for a blank manifest. + empty_manifest_url= generator.get_manifest(sheet_url = sheet_url) + + # Loading existing manifest + existing_manifest_df = pd.DataFrame(existing_manifest) + + # Update the empty manifest with the existing manifest + updated_df = generator._update_dataframe_with_existing_df(empty_manifest_url=empty_manifest_url, + existing_df = existing_manifest_df, + )[0] + + # Check that update happened as intended. + # If the existing manifest is emtpy, the columns will not change, no data will be added + if existing_manifest_df.empty: + assert updated_df.empty == True + assert list(updated_df.columns) == ['Patient ID', 'Sex', 'Year of Birth', 'Diagnosis', 'Component', + 'Cancer Type', 'Family History'] + # If the existing manifest has only 2 of the schema columns, the columns should match the schema, data is added. + elif len(existing_manifest_df.columns) == 2: + assert updated_df['Patient ID'][0] == '1738' + assert list(updated_df.columns) == ['Patient ID', 'Sex', 'Year of Birth', 'Diagnosis', 'Component', + 'Cancer Type', 'Family History'] + # If the existing manifest has matching columns to the schema, the columns should remain the same, data is added. + elif len(existing_manifest_df.columns) == 7: + assert updated_df['Patient ID'][0] == '1738' + assert list(updated_df.columns) == ['Patient ID', 'Sex', 'Year of Birth', 'Diagnosis', 'Component', + 'Cancer Type', 'Family History'] + # If the existing manifest has an extra column that is not in the schema, the new column should be added, data is added. + elif len(existing_manifest_df.columns) == 8: + assert updated_df['Patient ID'][0] == '1738' + assert list(updated_df.columns) == ['Patient ID', 'Sex', 'Year of Birth', 'Diagnosis', 'Component', + 'Cancer Type', 'Family History','Non Schema Column'] @pytest.mark.parametrize("additional_df_dict", [{"Filename": ['a', 'b'], "Sample ID": ['a', 'b'], "File Format": ['a', 'b'], "Component": ['a', 'b'], "Genome Build": ['a', 'b'], "Genome FASTA": ['a', 'b'], "test_one_column": ['a', 'b'], "test_two_column": ['c', 'd']}, None]) def test_populate_existing_excel_spreadsheet(self, simple_manifest_generator, simple_test_manifest_excel, additional_df_dict): From 3c3f0a8c561d4d6ab40a3545ff0e78f2869077bb Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Thu, 4 May 2023 21:55:53 -0700 Subject: [PATCH 542/615] revert function name to _get_missing_columns --- schematic/manifest/generator.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 72a928439..2a27eaebc 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1256,7 +1256,7 @@ def get_empty_manifest(self, json_schema_filepath=None): ) return manifest_url - def _get_mismatched_columns(self, headers_1:list , headers_2:list) -> list: + def _get_missing_columns(self, headers_1:list , headers_2:list) -> list: """Compare two colunm sets and get cols that are in headers_1, but not headers_2 Args: headers_1 (list): list of column headers @@ -1267,7 +1267,6 @@ def _get_mismatched_columns(self, headers_1:list , headers_2:list) -> list: """ return set(headers_1) - set(headers_2) - def set_dataframe_by_url( self, manifest_url: str, manifest_df: pd.DataFrame, out_of_schema_columns=None, ) -> ps.Spreadsheet: @@ -1590,10 +1589,10 @@ def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_d existing_manfiest_headers = list(existing_df.columns) # Find columns that exist in the current schema, but are not in the manifest being downloaded. - new_columns = self._get_mismatched_columns(current_schema_headers, existing_manfiest_headers) + new_columns = self._get_missing_columns(current_schema_headers, existing_manfiest_headers) # Find columns that exist in the manifest being downloaded, but not in the current schema. - out_of_schema_columns = self._get_mismatched_columns(existing_manfiest_headers, current_schema_headers) + out_of_schema_columns = self._get_missing_columns(existing_manfiest_headers, current_schema_headers) # clean empty columns if any are present (there should be none) # TODO: Remove this line once we start preventing empty column names From 48eda46909e7de08b8628aa5d89e050ddbf733f5 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 10:43:21 -0400 Subject: [PATCH 543/615] update instructions --- schematic_api/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index a94260f3a..5374680b8 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -1,7 +1,7 @@ ## Installation For unix OSs users, simply run the following poetry command to install uWSGI: ```bash -poetry install -E uwsgi +poetry install --with aws ``` ## Setup From 1782eb9b11d5f8e7b8f0d713d1b80a7d5419e4d2 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 10:48:43 -0400 Subject: [PATCH 544/615] set maximum cache allowed as an optional argument --- schematic/store/synapse.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 5d8340251..d709ec35f 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -193,22 +193,21 @@ def __init__( self._query_fileview() - def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/"): + def _purge_synapse_cache(self, root_dir: str = "/var/www/.synapseCache/", maximum_storage_allowed_cache_gb=7): """ Purge synapse cache if it exceeds 7GB Args: root_dir: directory of the .synapseCache function + maximum_storage_allowed_cache_gb: the maximum storage allowed before purging cache. Default is 7 GB. + Returns: - if size of cache reaches 7GB, return the number of files that get deleted + if size of cache reaches a certain threshold (default is 7GB), return the number of files that get deleted otherwise, return the total remaining space (assuming total ephemeral storage is 20GB on AWS ) """ # try clearing the cache # scan a directory and check size of files cache = self.syn.cache if os.path.exists(root_dir): - # set maximum synapse cache allowed - # set maximum ephemeral stroage allowed on AWS - maximum_storage_allowed_cache_gb = 7 maximum_storage_allowed_cache_bytes = convert_gb_to_bytes(maximum_storage_allowed_cache_gb) total_ephemeral_storag_gb = 20 total_ephemeral_storage_bytes = convert_gb_to_bytes(total_ephemeral_storag_gb) From bac8e253ea0301f014d422b1a20abbc91a029f4a Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 11:17:05 -0400 Subject: [PATCH 545/615] remove try and except block --- schematic_api/api/routes.py | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/schematic_api/api/routes.py b/schematic_api/api/routes.py index 51b3f36bd..320ac6d7f 100644 --- a/schematic_api/api/routes.py +++ b/schematic_api/api/routes.py @@ -171,15 +171,8 @@ def parse_bool(str_bool): def return_as_json(manifest_local_file_path): manifest_csv = pd.read_csv(manifest_local_file_path) - try: - manifest_json = manifest_csv.to_dict(orient="records") - return manifest_json - except JSONDecodeError as e: - logger.error("Json data is not formatted correctly", e) - raise(e) - except ValueError as e: - logger.error('Failed to return the downloaded manifest as a json', e) - raise(e) + manifest_json = manifest_csv.to_dict(orient="records") + return manifest_json def save_file(file_key="csv_file"): ''' @@ -579,14 +572,7 @@ def download_manifest(input_token, manifest_id, new_manifest_name='', as_json=Tr # use Synapse Storage store = SynapseStorage(input_token=input_token) # try logging in to asset store - try: - syn = store.login(input_token=input_token) - except SynapseAuthenticationError as e: - raise e - except SynapseTimeoutError as e: - raise e - except SynapseHTTPError as e: - raise e + syn = store.login(input_token=input_token) try: md = ManifestDownload(syn, manifest_id) manifest_data = ManifestDownload.download_manifest(md, new_manifest_name) From 75b77db019247def28989554a3ba4a6b549e7c36 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 14:44:38 -0400 Subject: [PATCH 546/615] raise permission error and chain exception --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index d709ec35f..90073bc3f 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -126,7 +126,7 @@ def download_manifest(self, newManifestName: str="", manifest_df: pd.DataFrame=p try: manifest_data = self._download_manifest_to_folder() except (SynapseUnmetAccessRestrictions, SynapseAuthenticationError) as e: - raise e + raise PermissionError("You don't have access to censored and uncensored manifests in this dataset.") from e else: logger.error(f"You don't have access to the requested resource: {self.manifest_id}") @@ -530,7 +530,7 @@ def getDatasetManifest( manifest_data = ManifestDownload.download_manifest(md, newManifestName=newManifestName, manifest_df=manifest) ## TO DO: revisit how downstream code handle manifest_data. If the downstream code would break when manifest_data is an empty string, ## then we should catch the error here without returning an empty string. - if manifest_data == "": + if not manifest_data: logger.debug(f"No manifest data returned. Please check if you have successfully downloaded manifest: {manifest_syn_id}") return manifest_data return manifest_syn_id From e514ac7a25e7eb5b96b1492e663dd26238028198 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 15:18:14 -0400 Subject: [PATCH 547/615] update docs to refer access_token; --- schematic_api/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 5374680b8..abadfb6c3 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -88,7 +88,7 @@ Note: if the dataset_id you provided is invalid, it will generate an empty manif ### POST /model/submit -* For the input_token parameter, please use the value of `auth token` in your `.synapseConfig` +* For the access_token parameter, please use the value of `auth token` in your `.synapseConfig` * For the dataset_id parameter, please create a test folder on synapse and use its synapse ID From 37d23342f15f3b8c3f3932da173ee5b8e34408fc Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 5 May 2023 15:49:50 -0400 Subject: [PATCH 548/615] remove unused import; set debug back to False --- run_api.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/run_api.py b/run_api.py index 633592b4e..4b86ad2a9 100755 --- a/run_api.py +++ b/run_api.py @@ -3,7 +3,6 @@ # import our application # Run our application from schematic_api.api import create_app -from flask_cors import CORS import os if __name__ == "__main__": @@ -15,4 +14,4 @@ # Launch app app = create_app() #TO DO: add a flag --debug to control debug parameter - app.run(host=host, port=port, debug=True) \ No newline at end of file + app.run(host=host, port=port, debug=False) \ No newline at end of file From bcc3f76d7cde063dc99c971f97e7c0758674285a Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Mon, 8 May 2023 08:21:36 -0700 Subject: [PATCH 549/615] updated lock file --- poetry.lock | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index b0db62f53..31609f6db 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2653,11 +2653,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -<<<<<<< HEAD -content-hash = "9fa9c3b799a420f073b1c6f2d8f9c96d82bea9ebe2d979c4c276969e3e26e419" -======= -content-hash = "3788ace046f8b51b9e0e14bf53dd8968d8f1f19910b9ff009252f6de9fc465ff" ->>>>>>> develop +content-hash = "91a724d31593bf5196b4f095ebbaa3a18cf84e474f7aeca6bf1d5d03d43cb6ba" [metadata.files] alabaster = [ @@ -3994,6 +3990,7 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, + {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, From 8aee22dc7c98cbf068333098538c6868baecad1d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 13:49:32 -0700 Subject: [PATCH 550/615] change capitalization of Id col --- schematic/store/synapse.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 2501601a9..c4168aaad 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -849,9 +849,9 @@ def formatDB(self, se, manifest, useSchemaLabel): # Get the column schema col_schema = as_table_columns(table_manifest) - # Set id column length to 64 (for some reason not being auto set.) + # Set Id column length to 64 (for some reason not being auto set.) for i, col in enumerate(col_schema): - if col['name'] == 'id': + if col['name'] == 'Id': col_schema[i]['maximumSize'] = 64 return col_schema, table_manifest @@ -1057,15 +1057,15 @@ def _add_id_columns_to_manifest(self, manifest): Returns (pd.DataFrame): Manifest df with new id and EntityId columns (and UUID values) if they were not already present. """ - # Add id for table updates and fill. - if not "id" in manifest.columns: - manifest["id"] = '' + # Add Id for table updates and fill. + if not "Id" in manifest.columns: + manifest["Id"] = '' for idx,row in manifest.iterrows(): - if not row["id"]: + if not row["Id"]: gen_uuid = str(uuid.uuid4()) - row["id"] = gen_uuid - manifest.loc[idx, 'id'] = gen_uuid + row["Id"] = gen_uuid + manifest.loc[idx, 'Id'] = gen_uuid # add entityId as a column if not already there or # fill any blanks with an empty string. @@ -1951,7 +1951,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'id', restrict: bool = False): + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Id', restrict: bool = False): """ Method to update an existing table with a new column From f23c8dbd8eff224c68612397354453a7b32344a0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 13:50:29 -0700 Subject: [PATCH 551/615] Revert "remove dupe import and commented out code" This reverts commit 0b1c89a4b60afbd1bcaf841909f9de348aa27fb2. --- schematic/store/synapse.py | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 2501601a9..941733ab1 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -36,6 +36,8 @@ from synapseutils import walk from synapseutils.copy_functions import changeFileMetaData +import uuid + from schematic_db.synapse.synapse import SynapseConfig from schematic_db.rdb.synapse_database import SynapseDatabase from schematic_db.schema.schema import get_key_attribute @@ -1028,6 +1030,82 @@ def format_manifest_annotations(self, manifest, manifest_synapse_id): annos[annos_k] = annos_v return annos + ''' + def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPath, + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False): + """ + Purpose: + Works very similarly to associateMetadataWithFiles except takes in the manifest + rather than the manifest path + + """ + + # Add uuid for table updates and fill. + if not "Uuid" in manifest.columns: + manifest["Uuid"] = '' + + for idx,row in manifest.iterrows(): + if not row["Uuid"]: + gen_uuid = uuid.uuid4() + row["Uuid"] = gen_uuid + manifest.loc[idx, 'Uuid'] = gen_uuid + + # add entityId as a column if not already there or + # fill any blanks with an empty string. + if not "entityId" in manifest.columns: + manifest["entityId"] = "" + else: + manifest["entityId"].fillna("", inplace=True) + + # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations + se = SchemaExplorer() + + # Create table name here. + if 'Component' in manifest.columns: + table_name = manifest['Component'][0].lower() + '_synapse_storage_manifest_table' + else: + table_name = 'synapse_storage_manifest_table' + + # Upload manifest as a table and get the SynID and manifest + manifest_synapse_table_id, manifest, table_manifest = self.upload_format_manifest_table( + se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,) + + # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed + # also set metadata for each synapse entity as Synapse annotations + for idx, row in manifest.iterrows(): + if not row["entityId"]: + # If not using entityIds, fill with manifest_table_id so + row["entityId"] = manifest_synapse_table_id + entityId = '' + else: + # get the entity id corresponding to this row + entityId = row["entityId"] + + # Load manifest to synapse as a CSV File + manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest) + + # Get annotations for the file manifest. + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) + + self.syn.set_annotations(manifest_annotations) + + logger.info("Associated manifest file with dataset on Synapse.") + + # Update manifest Synapse table with new entity id column. + self.make_synapse_table( + table_to_load = table_manifest, + dataset_id = datasetId, + existingTableId = manifest_synapse_table_id, + table_name = table_name, + update_col = 'Uuid', + specify_schema = False, + ) + + # Get annotations for the table manifest + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) + self.syn.set_annotations(manifest_annotations) + return manifest_synapse_table_id + ''' def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: """Helper function to read in provided manifest as a pandas DataFrame for subsequent downstream processing. From 6bd6e9946d790555748dac00b05dfb5e144b22fa Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 13:58:37 -0700 Subject: [PATCH 552/615] update docstring --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c4168aaad..59ef9b38b 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1055,7 +1055,7 @@ def _add_id_columns_to_manifest(self, manifest): Args: Manifest loaded as a pd.Dataframe Returns (pd.DataFrame): - Manifest df with new id and EntityId columns (and UUID values) if they were not already present. + Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ # Add Id for table updates and fill. if not "Id" in manifest.columns: From 72e78c6b4fac4a12a3488072fd7d27045d54c9e1 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 13:49:32 -0700 Subject: [PATCH 553/615] change capitalization of Id col --- schematic/store/synapse.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 941733ab1..52d69bf09 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -851,9 +851,9 @@ def formatDB(self, se, manifest, useSchemaLabel): # Get the column schema col_schema = as_table_columns(table_manifest) - # Set id column length to 64 (for some reason not being auto set.) + # Set Id column length to 64 (for some reason not being auto set.) for i, col in enumerate(col_schema): - if col['name'] == 'id': + if col['name'] == 'Id': col_schema[i]['maximumSize'] = 64 return col_schema, table_manifest @@ -1135,15 +1135,15 @@ def _add_id_columns_to_manifest(self, manifest): Returns (pd.DataFrame): Manifest df with new id and EntityId columns (and UUID values) if they were not already present. """ - # Add id for table updates and fill. - if not "id" in manifest.columns: - manifest["id"] = '' + # Add Id for table updates and fill. + if not "Id" in manifest.columns: + manifest["Id"] = '' for idx,row in manifest.iterrows(): - if not row["id"]: + if not row["Id"]: gen_uuid = str(uuid.uuid4()) - row["id"] = gen_uuid - manifest.loc[idx, 'id'] = gen_uuid + row["Id"] = gen_uuid + manifest.loc[idx, 'Id'] = gen_uuid # add entityId as a column if not already there or # fill any blanks with an empty string. @@ -2029,7 +2029,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'id', restrict: bool = False): + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Id', restrict: bool = False): """ Method to update an existing table with a new column From 3d6da09c8c6b035d5f33c7ac2f159180f0991a09 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 13:58:37 -0700 Subject: [PATCH 554/615] update docstring --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 52d69bf09..3ef0b0eed 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1133,7 +1133,7 @@ def _add_id_columns_to_manifest(self, manifest): Args: Manifest loaded as a pd.Dataframe Returns (pd.DataFrame): - Manifest df with new id and EntityId columns (and UUID values) if they were not already present. + Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ # Add Id for table updates and fill. if not "Id" in manifest.columns: From b7efeff22f9bb3cc1e53477823fdeae285e88b8b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 8 May 2023 14:07:50 -0700 Subject: [PATCH 555/615] rename `Uuid` col if present --- schematic/store/synapse.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 59ef9b38b..931484229 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1059,7 +1059,10 @@ def _add_id_columns_to_manifest(self, manifest): """ # Add Id for table updates and fill. if not "Id" in manifest.columns: - manifest["Id"] = '' + if 'Uuid' in manifest.columns: + manifest.rename(columns={'Uuid': 'Id'}, inplace=True) + else: + manifest["Id"] = '' for idx,row in manifest.iterrows(): if not row["Id"]: From be523bd3f84fc2c4087bd94e70ef063cd3d7cf8b Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Tue, 9 May 2023 10:05:35 -0700 Subject: [PATCH 556/615] Revert "remove dupe import and commented out code" This reverts commit 0b1c89a4b60afbd1bcaf841909f9de348aa27fb2. --- schematic/store/synapse.py | 78 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 931484229..fd6123294 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -36,6 +36,8 @@ from synapseutils import walk from synapseutils.copy_functions import changeFileMetaData +import uuid + from schematic_db.synapse.synapse import SynapseConfig from schematic_db.rdb.synapse_database import SynapseDatabase from schematic_db.schema.schema import get_key_attribute @@ -1028,6 +1030,82 @@ def format_manifest_annotations(self, manifest, manifest_synapse_id): annos[annos_k] = annos_v return annos + ''' + def annotate_upload_manifest_table(self, manifest, datasetId, metadataManifestPath, + useSchemaLabel: bool = True, hideBlanks: bool = False, restrict_manifest = False): + """ + Purpose: + Works very similarly to associateMetadataWithFiles except takes in the manifest + rather than the manifest path + + """ + + # Add uuid for table updates and fill. + if not "Uuid" in manifest.columns: + manifest["Uuid"] = '' + + for idx,row in manifest.iterrows(): + if not row["Uuid"]: + gen_uuid = uuid.uuid4() + row["Uuid"] = gen_uuid + manifest.loc[idx, 'Uuid'] = gen_uuid + + # add entityId as a column if not already there or + # fill any blanks with an empty string. + if not "entityId" in manifest.columns: + manifest["entityId"] = "" + else: + manifest["entityId"].fillna("", inplace=True) + + # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations + se = SchemaExplorer() + + # Create table name here. + if 'Component' in manifest.columns: + table_name = manifest['Component'][0].lower() + '_synapse_storage_manifest_table' + else: + table_name = 'synapse_storage_manifest_table' + + # Upload manifest as a table and get the SynID and manifest + manifest_synapse_table_id, manifest, table_manifest = self.upload_format_manifest_table( + se, manifest, datasetId, table_name, restrict = restrict_manifest, useSchemaLabel=useSchemaLabel,) + + # Iterate over manifest rows, create Synapse entities and store corresponding entity IDs in manifest if needed + # also set metadata for each synapse entity as Synapse annotations + for idx, row in manifest.iterrows(): + if not row["entityId"]: + # If not using entityIds, fill with manifest_table_id so + row["entityId"] = manifest_synapse_table_id + entityId = '' + else: + # get the entity id corresponding to this row + entityId = row["entityId"] + + # Load manifest to synapse as a CSV File + manifest_synapse_file_id = self.upload_manifest_file(manifest, metadataManifestPath, datasetId, restrict_manifest) + + # Get annotations for the file manifest. + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_file_id) + + self.syn.set_annotations(manifest_annotations) + + logger.info("Associated manifest file with dataset on Synapse.") + + # Update manifest Synapse table with new entity id column. + self.make_synapse_table( + table_to_load = table_manifest, + dataset_id = datasetId, + existingTableId = manifest_synapse_table_id, + table_name = table_name, + update_col = 'Uuid', + specify_schema = False, + ) + + # Get annotations for the table manifest + manifest_annotations = self.format_manifest_annotations(manifest, manifest_synapse_table_id) + self.syn.set_annotations(manifest_annotations) + return manifest_synapse_table_id + ''' def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: """Helper function to read in provided manifest as a pandas DataFrame for subsequent downstream processing. From 8162a5aba0a37229b670c4fb72de612a13cf225e Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 10 May 2023 13:13:38 -0700 Subject: [PATCH 557/615] minor formatting and doc updates --- schematic/manifest/generator.py | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 2a27eaebc..8917e943b 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1268,12 +1268,13 @@ def _get_missing_columns(self, headers_1:list , headers_2:list) -> list: return set(headers_1) - set(headers_2) def set_dataframe_by_url( - self, manifest_url: str, manifest_df: pd.DataFrame, out_of_schema_columns=None, + self, manifest_url: str, manifest_df: pd.DataFrame, out_of_schema_columns: set =None, ) -> ps.Spreadsheet: """Update Google Sheets using given pandas DataFrame. Args: manifest_url (str): Google Sheets URL. manifest_df (pd.DataFrame): Data frame to "upload". + out_of_schema_columns (set): Columns that are in downloaded manifest, but not in current schema. Returns: ps.Spreadsheet: A Google Sheet object. """ @@ -1425,7 +1426,7 @@ def export_sheet_to_excel(self, title: str = None, manifest_url : str = None, ou return output_excel_file_path - def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None, out_of_schema_columns=None): + def _handle_output_format_logic(self, output_format: str = None, output_path: str = None, sheet_url: bool = None, empty_manifest_url: str = None, dataframe: pd.DataFrame = None, out_of_schema_columns: set =None): """ Handle the logic between sheet_url parameter and output_format parameter to determine the type of output to return Args: @@ -1434,6 +1435,7 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st empty_manifest_url: Google sheet URL that leads to an empty manifest dataframe: the pandas dataframe that contains the metadata that needs to be populated to an empty manifest output_path: Determines the output path of the exported manifest (only relevant if returning an excel spreadsheet) + out_of_schema_columns (set): Columns that are in downloaded manifest, but not in current schema. Return: a pandas dataframe, file path of an excel spreadsheet, or a google sheet URL TODO: @@ -1442,10 +1444,6 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st # if the output type gets set to "dataframe", return a data frame if output_format == "dataframe": - """ - TODO: for backwards compatibility may need to return downloaded CSV only with no updates wrt to the schema. - Probably use a different function and endpoint for this bc could just wrap a synapse client funtion instead of going through all the prior steps. - """ return dataframe # if the output type gets set to "excel", return an excel spreadsheet @@ -1582,6 +1580,7 @@ def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_d Returns: updated_df (Pd.DataFrame): existing_df with new_columns added. + out_of_schema_columns (set): Columns that are in downloaded manifest, but not in current schema. """ # Get headers for the current schema and existing manifest df. From 0969c095beb031426cc699073f90dc994e6717f2 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 10 May 2023 15:10:02 -0700 Subject: [PATCH 558/615] fix typo --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index fd6123294..4ac9b4bcc 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -874,7 +874,7 @@ def buildDB(self, datasetId: synID of the dataset for the manifest table_name: name of the table to be uploaded col_schema: schema for table columns: type, size, etc from `formatDB` - table_manifest: formatted manifest taht can be uploaded as a table + table_manifest: formatted manifest that can be uploaded as a table table_manipulation: str, 'replace' or 'upsert', in the case where a manifest already exists, should the new metadata replace the existing (replace) or be added to it (upsert) restrict: bool, whether or not the manifest contains sensitive data that will need additional access restrictions From e54eaa7e757318618bffb0db74c75b947f39b758 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 10 May 2023 15:10:32 -0700 Subject: [PATCH 559/615] handle mismatched headers in table/manifest --- schematic/store/synapse.py | 54 +++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 4ac9b4bcc..8f912aad5 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -29,8 +29,7 @@ as_table_columns, ) -from synapseclient.table import CsvFileTable -from synapseclient.table import build_table +from synapseclient.table import CsvFileTable, build_table, Schema from synapseclient.annotations import from_synapse_annotations from synapseclient.core.exceptions import SynapseHTTPError, SynapseAuthenticationError, SynapseUnmetAccessRestrictions from synapseutils import walk @@ -2028,10 +2027,59 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non synConfig = SynapseConfig(username, authtoken, synStore.getDatasetProject(datasetId)) synapseDB = SynapseDatabase(synConfig) - synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) + + try: + synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) + except(SynapseHTTPError) as ex: + if 'header' in str(ex): + TableOperations._update_table_uuid_column(synStore, existingTableId) + else: + raise ex return existingTableId + def _update_table_uuid_column(synStore, table_id: str) -> None: + """Removes the `Uuid` column when present, and relpaces with an `Id` column + Used to enable backwards compatability for manifests using the old `Uuid` convention + + Args: + table_id (str): The Synapse id of the table to be upserted into, that needs columns updated + + Returns: + None + """ + schema = synStore.syn.get(table_id) + cols = synStore.syn.getTableColumns(schema) + for col in cols: + if col.name == 'Uuid': + new_col = deepcopy(col) + new_col['name'] = 'Id' + schema.addColumn(new_col) + schema = synStore.syn.store(schema) + TableOperations._populate_new_id_column(synStore, table_id, schema) + schema = synStore.syn.get(table_id) + schema.removeColumn(col) + schema = synStore.syn.store(schema) + break + + return + + def _populate_new_id_column(synStore, table_id: str, schema: Schema) -> None: + """Copies the uuid values that were present in the column named `Uuid` to the new column named `Id` + + Args: + table_id (str): The Synapse id of the table to be upserted into, that needs columns updated + schema (synapseclient.table.Schema): Schema of the table columns + + Returns: + None + """ + results = synStore.syn.tableQuery(f"select Uuid,Id from {table_id}") + results_df = results.asDataFrame() + results_df['Id']=results_df['Uuid'] + table = synStore.syn.store(Table(schema, results_df, etag=results.etag)) + return + def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Id', restrict: bool = False): """ Method to update an existing table with a new column From b02012200ecdccc20d8b6a2211d074a6d36f903c Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 10 May 2023 15:42:00 -0700 Subject: [PATCH 560/615] add path errors and raise them instead of logging --- schematic/manifest/commands.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index 975e8ddae..1ccc0f1ce 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -142,16 +142,26 @@ def create_single_manifest(data_type, output_csv=None, output_xlsx=None): # if output_xlsx gets specified, output_format = "excel" if output_xlsx: output_format = "excel" - # if file name is in the path, and that file does not exist if not os.path.exists(output_xlsx): + breakpoint() if ".xlsx" or ".xls" in output_xlsx: path = Path(output_xlsx) output_path = path.parent.absolute() - else: - logger.error(f"{output_xlsx} does not exists. Please try a valid file path") - - else: + if not os.path.exists(output_path): + raise ValueError( + f"{output_path} does not exists. Please try a valid file path" + ) + else: + raise ValueError( + f"{output_xlsx} does not exists. Please try a valid file path" + ) + else: + # Check if base path itself exists. + if not os.path.exists(os.path.dirname(output_xlsx)): + raise ValueError( + f"{output_xlsx} does not exists. Please try a valid file path" + ) output_path = output_xlsx else: output_format = None From b2924dc7b85cca325c60d5fedc73c0a0422b50ca Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 10 May 2023 15:42:34 -0700 Subject: [PATCH 561/615] remove path check, now in CLI --- schematic/manifest/generator.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 8917e943b..91c49b96d 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1454,9 +1454,6 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st output_location = output_path, ) - if not os.path.exists(output_file_path): - logger.error(f'Export to Excel spreadsheet fail. Please make sure that file path {output_file_path} is valid') - # populate an excel spreadsheet with the existing dataframe self.populate_existing_excel_spreadsheet(output_file_path, dataframe) From 7ceca6f2c791ffbc40b5673041ffee2e01e2f747 Mon Sep 17 00:00:00 2001 From: andrewelamb Date: Thu, 11 May 2023 07:21:55 -0700 Subject: [PATCH 562/615] update lock file --- poetry.lock | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/poetry.lock b/poetry.lock index 7bca15145..0382be33e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -584,7 +584,7 @@ six = ">=1.9.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] -enterprise_cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] +enterprise-cert = ["cryptography (==36.0.2)", "pyopenssl (==22.0.0)"] pyopenssl = ["cryptography (>=38.0.3)", "pyopenssl (>=20.0.0)"] reauth = ["pyu2f (>=0.1.5)"] requests = ["requests (>=2.20.0,<3.0.0dev)"] @@ -692,9 +692,9 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] arrow = ["feather-format (>=0.4.1)", "pyarrow"] athena = ["pyathena (>=1.11)", "sqlalchemy (>=1.3.18,<2.0.0)"] -aws_secrets = ["boto3 (==1.17.106)"] +aws-secrets = ["boto3 (==1.17.106)"] azure = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] -azure_secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] +azure-secrets = ["azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)"] bigquery = ["gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)"] dev = ["PyHive (>=0.6.5)", "PyMySQL (>=0.9.3,<0.10)", "azure-identity (>=1.10.0)", "azure-keyvault-secrets (>=4.0.0)", "azure-storage-blob (>=12.5.0)", "black[jupyter] (==22.3.0)", "boto3 (==1.17.106)", "docstring-parser (==0.15)", "feather-format (>=0.4.1)", "flask (>=1.0.0)", "freezegun (>=0.3.15)", "gcsfs (>=0.5.1)", "google-cloud-bigquery (>=3.3.6)", "google-cloud-secret-manager (>=1.0.0)", "google-cloud-storage (>=1.28.0)", "invoke (>=2.0.0)", "ipykernel (<=6.17.1)", "mock-alchemy (>=0.2.5)", "moto (>=2.0.0,<3.0.0)", "mypy (==1.0.0)", "nbconvert (>=5)", "openpyxl (>=3.0.7)", "pre-commit (>=2.21.0)", "psycopg2-binary (>=2.7.6)", "pyarrow", "pyathena (>=1.11)", "pyfakefs (>=4.5.1)", "pyodbc (>=4.0.30)", "pypd (==1.1.0)", "pyspark (>=2.3.2)", "pytest (>=6.2.0)", "pytest-benchmark (>=3.4.1)", "pytest-cov (>=2.8.1)", "pytest-icdiff (>=0.6)", "pytest-mock (>=3.8.2)", "pytest-order (>=0.9.5)", "pytest-random-order (>=1.0.4)", "pytest-timeout (>=2.1.0)", "requirements-parser (>=0.2.0)", "ruff (==0.0.246)", "s3fs (>=0.5.1)", "snapshottest (==0.6.0)", "snowflake-connector-python (>=2.5.0)", "snowflake-sqlalchemy (>=1.2.3)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-bigquery (>=1.3.0)", "sqlalchemy-dremio (==1.2.1)", "sqlalchemy-redshift (>=0.8.8)", "sqlalchemy-vertica-python (>=0.5.10)", "teradatasqlalchemy (==17.0.0.1)", "thrift (>=0.16.0)", "thrift-sasl (>=0.4.3)", "trino (>=0.310.0,!=0.316.0)", "xlrd (>=1.1.0,<2.0.0)"] dremio = ["pyarrow", "pyodbc (>=4.0.30)", "sqlalchemy (>=1.3.18,<2.0.0)", "sqlalchemy-dremio (==1.2.1)"] @@ -850,7 +850,7 @@ notebook = ["ipywidgets", "notebook"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] -test_extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] [[package]] name = "ipython-genutils" @@ -1989,7 +1989,7 @@ urllib3 = ">=1.21.1,<1.27" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] [[package]] name = "requests-oauthlib" @@ -2305,19 +2305,19 @@ aiomysql = ["aiomysql", "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)", "greenlet (!=0.4.17)"] -mariadb_connector = ["mariadb (>=1.0.1,!=1.1.2)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] mssql = ["pyodbc"] -mssql_pymssql = ["pymssql"] -mssql_pyodbc = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] -mysql_connector = ["mysql-connector-python"] +mysql-connector = ["mysql-connector-python"] oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] postgresql = ["psycopg2 (>=2.7)"] -postgresql_asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql_pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] -postgresql_psycopg2binary = ["psycopg2-binary"] -postgresql_psycopg2cffi = ["psycopg2cffi"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] pymysql = ["pymysql", "pymysql (<1)"] sqlcipher = ["sqlcipher3_binary"] @@ -2342,7 +2342,7 @@ password = ["passlib (>=1.6,<2.0)"] pendulum = ["pendulum (>=2.0.5)"] phone = ["phonenumbers (>=5.9.2)"] test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] -test_all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (>=2.7.1)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] @@ -2661,7 +2661,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "91a724d31593bf5196b4f095ebbaa3a18cf84e474f7aeca6bf1d5d03d43cb6ba" +content-hash = "93b3630734394087f4d3ddcefb848a937b7752a9660bdb35b6766fc699773050" [metadata.files] alabaster = [ From 95aa6a3fcf884746d03b9b3ea04dad2677d48036 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 11 May 2023 10:07:18 -0700 Subject: [PATCH 563/615] update error catching --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 8f912aad5..b6352366e 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -2031,7 +2031,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non try: synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) except(SynapseHTTPError) as ex: - if 'header' in str(ex): + if 'Id is not a valid column name or id' in str(ex): TableOperations._update_table_uuid_column(synStore, existingTableId) else: raise ex From 0bc08e3d78b5bb4d26c395d57320754ade4cb833 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 11 May 2023 10:18:27 -0700 Subject: [PATCH 564/615] add comments --- schematic/store/synapse.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index b6352366e..78a932fcd 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -2029,10 +2029,13 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non synapseDB = SynapseDatabase(synConfig) try: + # Try performing upsert synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) except(SynapseHTTPError) as ex: + # If error is raised because Table has old `Uuid` column and not new `Id` column, then handle if 'Id is not a valid column name or id' in str(ex): TableOperations._update_table_uuid_column(synStore, existingTableId) + # Raise if other error else: raise ex @@ -2048,18 +2051,28 @@ def _update_table_uuid_column(synStore, table_id: str) -> None: Returns: None """ + # Get the columns of the schema schema = synStore.syn.get(table_id) cols = synStore.syn.getTableColumns(schema) + + # Iterate through columns until `Uuid` column is found for col in cols: if col.name == 'Uuid': + # Create a new `Id` column based off of the old `Uuid` column, and store (column is empty) new_col = deepcopy(col) new_col['name'] = 'Id' schema.addColumn(new_col) schema = synStore.syn.store(schema) + + # Recently stored column is empty, so populated with uuid values TableOperations._populate_new_id_column(synStore, table_id, schema) + + # get the up-to-date table, remove old `Uuid` column, and store schema = synStore.syn.get(table_id) schema.removeColumn(col) schema = synStore.syn.store(schema) + + # Exit iteration; only concerned with `Uuid` column break return @@ -2074,8 +2087,11 @@ def _populate_new_id_column(synStore, table_id: str, schema: Schema) -> None: Returns: None """ + # Query the table for the old `Uuid` column and new `Id` column results = synStore.syn.tableQuery(f"select Uuid,Id from {table_id}") results_df = results.asDataFrame() + + # Copy uuid values to new column, and store in table results_df['Id']=results_df['Uuid'] table = synStore.syn.store(Table(schema, results_df, etag=results.etag)) return From 009f2a31ca585d75344156ce0e9d896a3e24239c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 11 May 2023 13:26:26 -0700 Subject: [PATCH 565/615] wait before getting updated schema --- schematic/store/synapse.py | 1 + 1 file changed, 1 insertion(+) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 78a932fcd..c1d6718c6 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -2068,6 +2068,7 @@ def _update_table_uuid_column(synStore, table_id: str) -> None: TableOperations._populate_new_id_column(synStore, table_id, schema) # get the up-to-date table, remove old `Uuid` column, and store + sleep(1) schema = synStore.syn.get(table_id) schema.removeColumn(col) schema = synStore.syn.store(schema) From c15a35c91102feb0af1e867852b3480796b45384 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 11 May 2023 13:58:07 -0700 Subject: [PATCH 566/615] retry upsert after updating table schema --- schematic/store/synapse.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index c1d6718c6..cee501921 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -2032,9 +2032,10 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non # Try performing upsert synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) except(SynapseHTTPError) as ex: - # If error is raised because Table has old `Uuid` column and not new `Id` column, then handle + # If error is raised because Table has old `Uuid` column and not new `Id` column, then handle and re-attempt upload if 'Id is not a valid column name or id' in str(ex): TableOperations._update_table_uuid_column(synStore, existingTableId) + synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) # Raise if other error else: raise ex From b77e35dcc891105b65790f78359cff96c77b9178 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 11 May 2023 14:30:54 -0700 Subject: [PATCH 567/615] update type hinting --- schematic/store/synapse.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index cee501921..5bb9cbdc7 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1812,7 +1812,7 @@ class TableOperations: """ - def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, datasetId: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): + def createTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tableName: str = None, datasetId: str = None, columnTypeDict: dict = None, specifySchema: bool = True, restrict: bool = False): """ Method to create a table from a metadata manifest and upload it to synapse @@ -1868,7 +1868,7 @@ def createTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non table = synStore.syn.store(table, isRestricted = restrict) return table.schema.id - def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, specifySchema: bool = True, datasetId: str = None, columnTypeDict: dict = None, restrict: bool = False): + def replaceTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, specifySchema: bool = True, datasetId: str = None, columnTypeDict: dict = None, restrict: bool = False): """ Method to replace an existing table on synapse with metadata from a new manifest @@ -1952,7 +1952,7 @@ def replaceTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = No return existingTableId - def _get_schematic_db_creds(synStore): + def _get_schematic_db_creds(synStore: SynapseStorage): username = None authtoken = None @@ -2003,7 +2003,7 @@ def _get_schematic_db_creds(synStore): return username, authtoken - def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + def upsertTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse For upsert functionality to work, primary keys must follow the naming convention of _id @@ -2042,7 +2042,7 @@ def upsertTable(synStore, tableToLoad: pd.DataFrame = None, tableName: str = Non return existingTableId - def _update_table_uuid_column(synStore, table_id: str) -> None: + def _update_table_uuid_column(synStore: SynapseStorage, table_id: str) -> None: """Removes the `Uuid` column when present, and relpaces with an `Id` column Used to enable backwards compatability for manifests using the old `Uuid` convention @@ -2079,7 +2079,7 @@ def _update_table_uuid_column(synStore, table_id: str) -> None: return - def _populate_new_id_column(synStore, table_id: str, schema: Schema) -> None: + def _populate_new_id_column(synStore: SynapseStorage, table_id: str, schema: Schema) -> None: """Copies the uuid values that were present in the column named `Uuid` to the new column named `Id` Args: @@ -2098,7 +2098,7 @@ def _populate_new_id_column(synStore, table_id: str, schema: Schema) -> None: table = synStore.syn.store(Table(schema, results_df, etag=results.etag)) return - def updateTable(synStore, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Id', restrict: bool = False): + def updateTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, existingTableId: str = None, update_col: str = 'Id', restrict: bool = False): """ Method to update an existing table with a new column From 6825497223ae9f92b2548d5bb76174e0af950e3e Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 15 May 2023 18:19:00 -0400 Subject: [PATCH 568/615] install poetry 1.2.0 --- .github/workflows/test.yml | 2 +- Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 44b2477fa..af83b5ee0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -27,7 +27,7 @@ jobs: test: runs-on: ubuntu-latest env: - POETRY_VERSION: 1.2.0rc1 + POETRY_VERSION: 1.2.0 strategy: fail-fast: false matrix: diff --git a/Dockerfile b/Dockerfile index f41ca51b7..3117c63c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV PYTHONFAULTHANDLER=1 \ PIP_NO_CACHE_DIR=off \ PIP_DISABLE_PIP_VERSION_CHECK=on \ PIP_DEFAULT_TIMEOUT=200 \ - POETRY_VERSION=1.2.0rc1 + POETRY_VERSION=1.2.0 WORKDIR /usr/src/app From 0daba512cd0890ebb168409403798397f2541daa Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 15 May 2023 22:09:20 -0400 Subject: [PATCH 569/615] update poetry version --- .github/workflows/api_test.yml | 2 +- .readthedocs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index a20c642d8..851873f5d 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -15,7 +15,7 @@ jobs: test: runs-on: ubuntu-latest env: - POETRY_VERSION: 1.2.0rc1 + POETRY_VERSION: 1.2.0 strategy: fail-fast: false matrix: diff --git a/.readthedocs.yml b/.readthedocs.yml index 7d17414e6..6599ad15f 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -12,7 +12,7 @@ build: python: "3.9" jobs: post_install: - - pip install poetry==1.2.0b1 + - pip install poetry==1.2.0 - poetry config virtualenvs.create false - poetry install --with doc #Poetry will install my dependencies into the virtualenv created by readthedocs if I set virtualenvs.create=false From 7ac68d5b2ff69ff6bf4544c18ef2d703cec1b570 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 17 May 2023 10:35:06 -0700 Subject: [PATCH 570/615] remove breakpoint from command --- schematic/manifest/commands.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/manifest/commands.py b/schematic/manifest/commands.py index d908a329d..03edf648e 100644 --- a/schematic/manifest/commands.py +++ b/schematic/manifest/commands.py @@ -144,7 +144,6 @@ def create_single_manifest(data_type, output_csv=None, output_xlsx=None): output_format = "excel" # if file name is in the path, and that file does not exist if not os.path.exists(output_xlsx): - breakpoint() if ".xlsx" or ".xls" in output_xlsx: path = Path(output_xlsx) output_path = path.parent.absolute() @@ -277,4 +276,4 @@ def migrate_manifests( logging.info("Migrating entitites") synStore.move_entities_to_new_project(project, archive_project, return_entities, dry_run) - return \ No newline at end of file + return From c5cfe1a5f03d10996b0ac3ab8dae3ad7575e49c5 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 18 May 2023 14:09:46 -0400 Subject: [PATCH 571/615] break down test and fix test --- tests/test_api.py | 146 ++++++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 70 deletions(-) diff --git a/tests/test_api.py b/tests/test_api.py index fa8dc83f0..2ba1bf5d4 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -1,15 +1,20 @@ -import pytest -from schematic_api.api import create_app import configparser import json +import logging import os import re +import time from math import ceil -import logging from time import perf_counter -import pandas as pd # third party library import -from schematic.schemas.generator import SchemaGenerator #Local application/library specific imports. + +import numpy as np +import pandas as pd # third party library import +import pytest + +from schematic.schemas.generator import \ + SchemaGenerator # Local application/library specific imports. +from schematic_api.api import create_app logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) @@ -39,7 +44,7 @@ def test_invalid_manifest(helpers): @pytest.fixture(scope="class") def test_upsert_manifest_csv(helpers): - test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest.csv") + test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest_upsert.csv") yield test_upsert_manifest_path @pytest.fixture(scope="class") @@ -656,7 +661,10 @@ def test_dataset_manifest_download(self, client, as_json, syn_token, new_manifes if as_json: response_json = json.loads(response_dt) - assert response_json == [{'Component': 'BulkRNA-seqAssay', 'File Format': 'CSV/TSV', 'Filename': 'Sample_A', 'Genome Build': 'GRCm38', 'Genome FASTA': None, 'Sample ID': 2022, 'entityId': 'syn28278954'}] + assert response_json[0]["Component"] == "BulkRNA-seqAssay" + assert response_json[0]["File Format"] == "CSV/TSV" + assert response_json[0]["Sample ID"] == 2022 + assert response_json[0]["entityId"] == "syn28278954" else: # return a file path response_path = response_dt.decode('utf-8') @@ -664,96 +672,94 @@ def test_dataset_manifest_download(self, client, as_json, syn_token, new_manifes assert isinstance(response_path, str) assert response_path.endswith(".csv") - @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) - @pytest.mark.parametrize("use_schema_label", ['true','false']) - @pytest.mark.parametrize("manifest_record_type", ['table_and_file', 'file_only']) - def test_submit_manifest(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, use_schema_label, manifest_record_type): + def test_submit_manifest_table_and_file_replace(self, client, syn_token, data_model_jsonld, test_manifest_csv): + """Testing submit manifest in a csv format as a table and a file. Only replace the table + """ params = { "access_token": syn_token, "schema_url": data_model_jsonld, - "data_type": "Patient", + "data_type": "MockComponent", "restrict_rules": False, - "manifest_record_type": manifest_record_type, - "asset_view": "syn44259375", - "dataset_id": "syn44259313", + "manifest_record_type": "table_and_file", + "asset_view": "syn51514344", + "dataset_id": "syn51514345", "table_manipulation": 'replace', - "use_schema_label": use_schema_label + "use_schema_label": True } - if json_str: - params["json_str"] = json_str - response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) - assert response.status_code == 200 - else: - headers = { - 'Content-Type': "multipart/form-data", - 'Accept': "application/json" - } - params["data_type"] = "MockComponent" + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + assert response_csv.status_code == 200 - # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) - assert response_csv.status_code == 200 - - @pytest.mark.parametrize("json_str", [None, '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]']) - @pytest.mark.parametrize("manifest_record_type", ['file_and_entities', 'table_file_and_entities']) - def test_submit_manifest_w_entities(self, client, syn_token, data_model_jsonld, json_str, test_manifest_csv, manifest_record_type): + def test_submit_manifest_file_only_replace(self, client, syn_token, data_model_jsonld, test_manifest_csv): + """Testing submit manifest in a csv format as a file + """ + params = { + "access_token": syn_token, + "schema_url": data_model_jsonld, + "data_type": "MockComponent", + "restrict_rules": False, + "manifest_record_type": "file_only", + "asset_view": "syn51514344", + "dataset_id": "syn51514345", + "table_manipulation": 'replace', + "use_schema_label": True + } + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + assert response_csv.status_code == 200 + + def test_submit_manifest_json_str_replace(self, client, syn_token, data_model_jsonld): + """Submit json str as a file + """ + json_str = '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]' params = { "access_token": syn_token, "schema_url": data_model_jsonld, "data_type": "Patient", + "json_str": json_str, "restrict_rules": False, - "manifest_record_type": manifest_record_type, - "asset_view": "syn44259375", - "dataset_id": "syn44259313", + "manifest_record_type": "file_only", + "asset_view": "syn51514344", + "dataset_id": "syn51514345", "table_manipulation": 'replace', "use_schema_label": True } + params["json_str"] = json_str + response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) + assert response.status_code == 200 - if json_str: - params["json_str"] = json_str - response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) - assert response.status_code == 200 - else: - headers = { - 'Content-Type': "multipart/form-data", - 'Accept': "application/json" - } - params["data_type"] = "MockComponent" + def test_submit_manifest_w_file_and_entities(self, client, syn_token, data_model_jsonld, test_manifest_csv): + params = { + "access_token": syn_token, + "schema_url": data_model_jsonld, + "data_type": "MockComponent", + "restrict_rules": False, + "manifest_record_type": "file_and_entities", + "asset_view": "syn51514501", + "dataset_id": "syn51514523", + "table_manipulation": 'replace', + "use_schema_label": True + } - # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}, headers=headers) - assert response_csv.status_code == 200 + # test uploading a csv file + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + assert response_csv.status_code == 200 - - @pytest.mark.parametrize("json_str", [None, '[{ "Component": "MockRDB", "MockRDB_id": 5 }]']) - def test_submit_manifest_upsert(self, client, syn_token, data_model_jsonld, json_str, test_upsert_manifest_csv, ): + def test_submit_manifest_table_and_file_upsert(self, client, syn_token, data_model_jsonld, test_upsert_manifest_csv, ): params = { "access_token": syn_token, "schema_url": data_model_jsonld, "data_type": "MockRDB", "restrict_rules": False, - "manifest_record_type": "table", - "asset_view": "syn44259375", - "dataset_id": "syn44259313", + "manifest_record_type": "table_and_file", + "asset_view": "syn51514557", + "dataset_id": "syn51514551", "table_manipulation": 'upsert', - "use_schema_label": False + "use_schema_label": False # have to set use_schema_label to false to ensure upsert feature works } - if json_str: - params["json_str"] = json_str - response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) - assert response.status_code == 200 - else: - headers = { - 'Content-Type': "multipart/form-data", - 'Accept': "application/json" - } - params["data_type"] = "MockRDB" - - # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_upsert_manifest_csv, 'rb'), "test.csv")}, headers=headers) - assert response_csv.status_code == 200 + # test uploading a csv file + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_upsert_manifest_csv, 'rb'), "test.csv")},) + assert response_csv.status_code == 200 @pytest.mark.schematic_api class TestSchemaVisualization: From e2973cb9f11316c8d59ebb701dee1251df5e9618 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 18 May 2023 14:10:10 -0400 Subject: [PATCH 572/615] run api test when push to develop or main --- .github/workflows/api_test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 851873f5d..14361c07c 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -4,11 +4,14 @@ name: Test schematic API on: + push: + branches: ['main', 'develop'] workflow_dispatch: inputs: perform_benchmarking: required: true type: boolean + default: False description: perform benchmarking test (True) or skip (False) jobs: @@ -82,7 +85,7 @@ jobs: env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} SERVICE_ACCOUNT_CREDS: ${{ secrets.SERVICE_ACCOUNT_CREDS }} - if: ${{ false == inputs.perform_benchmarking }} + if: ${{ false == inputs.perform_benchmarking }} || ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' }} run: > source .venv/bin/activate; pytest -m "schematic_api and not rule_benchmark" From 2169286e923a61a8bd75eb52fd7dfc7cea7206b3 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 19 May 2023 10:01:14 -0700 Subject: [PATCH 573/615] make manifest column checks case agnostic --- schematic/store/synapse.py | 12 ++++++------ schematic/utils/df_utils.py | 13 +++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 5bb9cbdc7..841706bdd 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -41,7 +41,7 @@ from schematic_db.rdb.synapse_database import SynapseDatabase from schematic_db.schema.schema import get_key_attribute -from schematic.utils.df_utils import update_df, load_df +from schematic.utils.df_utils import update_df, load_df, col_in_dataframe from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list from schematic.schemas.explorer import SchemaExplorer from schematic.schemas.generator import SchemaGenerator @@ -852,7 +852,7 @@ def formatDB(self, se, manifest, useSchemaLabel): # Set Id column length to 64 (for some reason not being auto set.) for i, col in enumerate(col_schema): - if col['name'] == 'Id': + if col['name'].lower() == 'id': col_schema[i]['maximumSize'] = 64 return col_schema, table_manifest @@ -1135,8 +1135,8 @@ def _add_id_columns_to_manifest(self, manifest): Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ # Add Id for table updates and fill. - if not "Id" in manifest.columns: - if 'Uuid' in manifest.columns: + if col_in_dataframe("Id", manifest): + if col_in_dataframe("Uuid", manifest): manifest.rename(columns={'Uuid': 'Id'}, inplace=True) else: manifest["Id"] = '' @@ -1149,7 +1149,7 @@ def _add_id_columns_to_manifest(self, manifest): # add entityId as a column if not already there or # fill any blanks with an empty string. - if not "entityId" in manifest.columns: + if not col_in_dataframe("entityId", manifest): manifest["entityId"] = "" else: manifest["entityId"].fillna("", inplace=True) @@ -2058,7 +2058,7 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str) -> None: # Iterate through columns until `Uuid` column is found for col in cols: - if col.name == 'Uuid': + if col.name.lower() == 'uuid': # Create a new `Id` column based off of the old `Uuid` column, and store (column is empty) new_col = deepcopy(col) new_col['name'] = 'Id' diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index e47c8723d..6c85a33ff 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -183,3 +183,16 @@ def trim_commas_df(df: pd.DataFrame): #Fill in nan cells with empty strings df.fillna("", inplace=True) return df + + +def col_in_dataframe(col: str, df: pd.DataFrame) -> bool: + """Check if a column is in a dataframe, without worring about case + + Args: + col: name of column whose presence in the dataframe is being checked + df: pandas dataframe with data from manifest file. + + Returns: + bool: whether or not the column name is a column in the dataframe, case agnostic + """ + return col.lower() in [manifest_col.lower() for manifest_col in df.columns.to_list()] \ No newline at end of file From 2054bc209fafee178277485e43c92bbe4642e6f0 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 19 May 2023 10:13:50 -0700 Subject: [PATCH 574/615] correct logic --- schematic/store/synapse.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index fa5d60f16..771fc31ca 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1244,7 +1244,7 @@ def _add_id_columns_to_manifest(self, manifest): Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ # Add Id for table updates and fill. - if col_in_dataframe("Id", manifest): + if not col_in_dataframe("Id", manifest): if col_in_dataframe("Uuid", manifest): manifest.rename(columns={'Uuid': 'Id'}, inplace=True) else: From 70501e74d0d46fdb32d37566585e6fc5e292b9c9 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Fri, 19 May 2023 11:23:09 -0700 Subject: [PATCH 575/615] Do not delete `Uuid` columns when specified --- schematic/store/synapse.py | 83 ++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 25 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 771fc31ca..6b15169f4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -913,7 +913,7 @@ def uploadDB(self, col_schema, table_manifest = self.formatDB(se, manifest, useSchemaLabel) - manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, restrict) + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, se, restrict,) return manifest_table_id, manifest, table_manifest @@ -972,7 +972,9 @@ def buildDB(self, col_schema: List, table_manifest: pd.DataFrame, table_manipulation: str, - restrict: bool = False, + se: SchemaExplorer, + restrict: bool = False, + ): """ Method to construct the table appropriately: create new table, replace existing, or upsert new into existing @@ -1002,7 +1004,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) + manifest_table_id = TableOperations.upsertTable(self, se=se, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) @@ -1236,17 +1238,29 @@ def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: ) from err return manifest - def _add_id_columns_to_manifest(self, manifest): + def _add_id_columns_to_manifest(self, manifest: pd.DataFrame, se: SchemaExplorer): """Helper function to add id and entityId columns to the manifest if they do not already exist, Fill id values per row. Args: Manifest loaded as a pd.Dataframe Returns (pd.DataFrame): Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ + # load the specific schema being used + temp_schema_explorer = deepcopy(se) + temp_schema_explorer.load_schema(CONFIG["model"]["input"]["location"]) + # Add Id for table updates and fill. if not col_in_dataframe("Id", manifest): - if col_in_dataframe("Uuid", manifest): + # See if schema has `Uuid` column specified + try: + uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') + except (KeyError): + uuid_col_in_schema = False + + # Rename `Uuid` column if it wasn't specified in the schema + if col_in_dataframe("Uuid", manifest) and not uuid_col_in_schema: manifest.rename(columns={'Uuid': 'Id'}, inplace=True) + # If no `Uuid` column exists or it is specified in the schema, create a new `Id` column else: manifest["Id"] = '' @@ -1570,14 +1584,14 @@ def associateMetadataWithFiles( Returns: manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. """ - - # Read new manifest CSV: - manifest = self._read_manifest(metadataManifestPath) - manifest = self._add_id_columns_to_manifest(manifest) # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations se = SchemaExplorer() + # Read new manifest CSV: + manifest = self._read_manifest(metadataManifestPath) + manifest = self._add_id_columns_to_manifest(manifest, se) + table_name, component_name = self._generate_table_name(manifest) # Upload manifest to synapse based on user input (manifest_record_type) @@ -2112,7 +2126,7 @@ def _get_schematic_db_creds(synStore: SynapseStorage): return username, authtoken - def upsertTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + def upsertTable(synStore: SynapseStorage, se: SchemaExplorer, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse For upsert functionality to work, primary keys must follow the naming convention of _id @@ -2143,7 +2157,7 @@ def upsertTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tabl except(SynapseHTTPError) as ex: # If error is raised because Table has old `Uuid` column and not new `Id` column, then handle and re-attempt upload if 'Id is not a valid column name or id' in str(ex): - TableOperations._update_table_uuid_column(synStore, existingTableId) + TableOperations._update_table_uuid_column(synStore, existingTableId, se) synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) # Raise if other error else: @@ -2151,7 +2165,7 @@ def upsertTable(synStore: SynapseStorage, tableToLoad: pd.DataFrame = None, tabl return existingTableId - def _update_table_uuid_column(synStore: SynapseStorage, table_id: str) -> None: + def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, se: SchemaExplorer,) -> None: """Removes the `Uuid` column when present, and relpaces with an `Id` column Used to enable backwards compatability for manifests using the old `Uuid` convention @@ -2161,6 +2175,11 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str) -> None: Returns: None """ + + # load the specific schema being used + temp_schema_explorer = deepcopy(se) + temp_schema_explorer.load_schema(CONFIG["model"]["input"]["location"]) + # Get the columns of the schema schema = synStore.syn.get(table_id) cols = synStore.syn.getTableColumns(schema) @@ -2168,22 +2187,36 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str) -> None: # Iterate through columns until `Uuid` column is found for col in cols: if col.name.lower() == 'uuid': - # Create a new `Id` column based off of the old `Uuid` column, and store (column is empty) - new_col = deepcopy(col) - new_col['name'] = 'Id' - schema.addColumn(new_col) - schema = synStore.syn.store(schema) + # See if schema has `Uuid` column specified + try: + uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') + except (KeyError): + uuid_col_in_schema = False + + # If there is, then create a new `Id` column from scratch + if uuid_col_in_schema: + new_col = Column(columnType = "STRING", maximumSize = 64, name = "Id") + schema.addColumn(new_col) + schema = synStore.syn.store(schema) + # If there is not, then use the old `Uuid` column as a basis for the new `Id` column + else: + # Create a new `Id` column based off of the old `Uuid` column, and store (column is empty) + new_col = deepcopy(col) + new_col['name'] = 'Id' + schema.addColumn(new_col) + schema = synStore.syn.store(schema) + - # Recently stored column is empty, so populated with uuid values - TableOperations._populate_new_id_column(synStore, table_id, schema) + # Recently stored column is empty, so populated with uuid values + TableOperations._populate_new_id_column(synStore, table_id, schema) - # get the up-to-date table, remove old `Uuid` column, and store - sleep(1) - schema = synStore.syn.get(table_id) - schema.removeColumn(col) - schema = synStore.syn.store(schema) + # get the up-to-date table, remove old `Uuid` column, and store + sleep(1) + schema = synStore.syn.get(table_id) + schema.removeColumn(col) + schema = synStore.syn.store(schema) - # Exit iteration; only concerned with `Uuid` column + # Exit iteration; only concerned with `Uuid` column break return From b37d65995dfa7c2e06812c9018e3a5e43e498c34 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 19 May 2023 17:47:14 -0400 Subject: [PATCH 576/615] add example biospecimen test --- .../example_biospecimen_test.csv | 2 ++ tests/test_api.py | 27 +++++++++++-------- 2 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 tests/data/mock_manifests/example_biospecimen_test.csv diff --git a/tests/data/mock_manifests/example_biospecimen_test.csv b/tests/data/mock_manifests/example_biospecimen_test.csv new file mode 100644 index 000000000..b8197a6ce --- /dev/null +++ b/tests/data/mock_manifests/example_biospecimen_test.csv @@ -0,0 +1,2 @@ +Sample ID,Patient ID,Tissue Status,Component +123,1,Healthy,Biospecimen \ No newline at end of file diff --git a/tests/test_api.py b/tests/test_api.py index 2ba1bf5d4..f9f52d453 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -37,6 +37,11 @@ def test_manifest_csv(helpers): test_manifest_path = helpers.get_data_path("mock_manifests/Valid_Test_Manifest.csv") yield test_manifest_path +@pytest.fixture(scope="class") +def test_manifest_submit(helpers): + test_manifest_path = helpers.get_data_path("mock_manifests/example_biospecimen_test.csv") + yield test_manifest_path + @pytest.fixture(scope="class") def test_invalid_manifest(helpers): test_invalid_manifest = helpers.get_data_frame("mock_manifests/Invalid_Test_Manifest.csv", preserve_raw_input=False) @@ -672,13 +677,13 @@ def test_dataset_manifest_download(self, client, as_json, syn_token, new_manifes assert isinstance(response_path, str) assert response_path.endswith(".csv") - def test_submit_manifest_table_and_file_replace(self, client, syn_token, data_model_jsonld, test_manifest_csv): + def test_submit_manifest_table_and_file_replace(self, client, syn_token, data_model_jsonld, test_manifest_submit): """Testing submit manifest in a csv format as a table and a file. Only replace the table """ params = { "access_token": syn_token, "schema_url": data_model_jsonld, - "data_type": "MockComponent", + "data_type": "Biospecimen", "restrict_rules": False, "manifest_record_type": "table_and_file", "asset_view": "syn51514344", @@ -687,16 +692,16 @@ def test_submit_manifest_table_and_file_replace(self, client, syn_token, data_mo "use_schema_label": True } - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_submit, 'rb'), "test.csv")}) assert response_csv.status_code == 200 - def test_submit_manifest_file_only_replace(self, client, syn_token, data_model_jsonld, test_manifest_csv): + def test_submit_manifest_file_only_replace(self, client, syn_token, data_model_jsonld, test_manifest_submit): """Testing submit manifest in a csv format as a file """ params = { "access_token": syn_token, "schema_url": data_model_jsonld, - "data_type": "MockComponent", + "data_type": "Biospecimen", "restrict_rules": False, "manifest_record_type": "file_only", "asset_view": "syn51514344", @@ -704,17 +709,17 @@ def test_submit_manifest_file_only_replace(self, client, syn_token, data_model_j "table_manipulation": 'replace', "use_schema_label": True } - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_submit, 'rb'), "test.csv")}) assert response_csv.status_code == 200 def test_submit_manifest_json_str_replace(self, client, syn_token, data_model_jsonld): """Submit json str as a file """ - json_str = '[{ "Patient ID": 123, "Sex": "Female", "Year of Birth": "", "Diagnosis": "Healthy", "Component": "Patient", "Cancer Type": "Breast", "Family History": "Breast, Lung", }]' + json_str = '[{"Sample ID": 123, "Patient ID": 1,"Tissue Status": "Healthy","Component": "Biospecimen"}]' params = { "access_token": syn_token, "schema_url": data_model_jsonld, - "data_type": "Patient", + "data_type": "Biospecimen", "json_str": json_str, "restrict_rules": False, "manifest_record_type": "file_only", @@ -727,11 +732,11 @@ def test_submit_manifest_json_str_replace(self, client, syn_token, data_model_js response = client.post('http://localhost:3001/v1/model/submit', query_string = params, data={"file_name":''}) assert response.status_code == 200 - def test_submit_manifest_w_file_and_entities(self, client, syn_token, data_model_jsonld, test_manifest_csv): + def test_submit_manifest_w_file_and_entities(self, client, syn_token, data_model_jsonld, test_manifest_submit): params = { "access_token": syn_token, "schema_url": data_model_jsonld, - "data_type": "MockComponent", + "data_type": "Biospecimen", "restrict_rules": False, "manifest_record_type": "file_and_entities", "asset_view": "syn51514501", @@ -741,7 +746,7 @@ def test_submit_manifest_w_file_and_entities(self, client, syn_token, data_model } # test uploading a csv file - response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_csv, 'rb'), "test.csv")}) + response_csv = client.post('http://localhost:3001/v1/model/submit', query_string=params, data={"file_name": (open(test_manifest_submit, 'rb'), "test.csv")}) assert response_csv.status_code == 200 def test_submit_manifest_table_and_file_upsert(self, client, syn_token, data_model_jsonld, test_upsert_manifest_csv, ): From e0a5d8b80b38863018ce41cd58c1804bf356f43a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 22 May 2023 13:33:45 -0700 Subject: [PATCH 577/615] update schema checks to work for properties --- schematic/store/synapse.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 6b15169f4..b55cc9123 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -1253,7 +1253,7 @@ def _add_id_columns_to_manifest(self, manifest: pd.DataFrame, se: SchemaExplorer if not col_in_dataframe("Id", manifest): # See if schema has `Uuid` column specified try: - uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') + uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') or temp_schema_explorer.is_class_in_schema('uuid') except (KeyError): uuid_col_in_schema = False @@ -2189,7 +2189,7 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, se: Schem if col.name.lower() == 'uuid': # See if schema has `Uuid` column specified try: - uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') + uuid_col_in_schema = temp_schema_explorer.is_class_in_schema(col.name) except (KeyError): uuid_col_in_schema = False From 2f75ca7eb142b675d79cdbac2c954dd91d251932 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 22 May 2023 14:17:56 -0700 Subject: [PATCH 578/615] add new helper function and test --- schematic/store/synapse.py | 4 ++-- schematic/utils/df_utils.py | 16 +++++++++++++++- tests/test_utils.py | 11 +++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index b55cc9123..9ee2b26c4 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -45,7 +45,7 @@ from schematic_db.schema.schema import get_key_attribute -from schematic.utils.df_utils import update_df, load_df, col_in_dataframe +from schematic.utils.df_utils import update_df, load_df, col_in_dataframe, populate_df_col_with_another_col from schematic.utils.validate_utils import comma_separated_list_regex, rule_in_rule_list from schematic.utils.general import entity_type_mapping, get_dir_size, convert_size, convert_gb_to_bytes, create_temp_folder from schematic.schemas.explorer import SchemaExplorer @@ -2236,7 +2236,7 @@ def _populate_new_id_column(synStore: SynapseStorage, table_id: str, schema: Sch results_df = results.asDataFrame() # Copy uuid values to new column, and store in table - results_df['Id']=results_df['Uuid'] + results_df = populate_df_col_with_another_col(results_df, 'Uuid', 'Id') table = synStore.syn.store(Table(schema, results_df, etag=results.etag)) return diff --git a/schematic/utils/df_utils.py b/schematic/utils/df_utils.py index 1682e5fac..93325ced9 100644 --- a/schematic/utils/df_utils.py +++ b/schematic/utils/df_utils.py @@ -194,4 +194,18 @@ def col_in_dataframe(col: str, df: pd.DataFrame) -> bool: Returns: bool: whether or not the column name is a column in the dataframe, case agnostic """ - return col.lower() in [manifest_col.lower() for manifest_col in df.columns.to_list()] \ No newline at end of file + return col.lower() in [manifest_col.lower() for manifest_col in df.columns.to_list()] + +def populate_df_col_with_another_col(df: pd.DataFrame, source_col: str, target_col: str) -> pd.DataFrame: + """Copy the values from one column in a dataframe to another column in the same dataframe + Args: + df: pandas dataframe with data from manifest file. + source_col: column whose contents to copy over + target_col: column to be updated with other contents + + Returns: + dataframe with contents updated + """ + # Copy the contents over + df[target_col]=df[source_col] + return df \ No newline at end of file diff --git a/tests/test_utils.py b/tests/test_utils.py index 3489f1657..bc21cdbd2 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -286,6 +286,17 @@ def test_update_dataframe(self): actual_df = df_utils.update_df(input_df, updates_df, "entityId") pd.testing.assert_frame_equal(expected_df, actual_df) + def test_populate_column(self): + input_df = pd.DataFrame( + { + "column1": ["col1Val","col1Val"], + "column2": [None, None] + } + ) + + output_df = df_utils.populate_df_col_with_another_col(input_df,'column1','column2') + assert (output_df["column2"].values == ["col1Val","col1Val"]).all() + class TestValidateUtils: def test_validate_schema(self, helpers): From 2414317adad81a7614cc3b28e9d30c15030dc7a7 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Mon, 22 May 2023 16:00:56 -0700 Subject: [PATCH 579/615] pass along schemaGenerator object instead of schemaExplorer --- schematic/store/synapse.py | 46 ++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index 9ee2b26c4..e7e9a07c9 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -882,7 +882,7 @@ def get_table_info(self, datasetId: str = None, projectId: str = None) -> List[s @missing_entity_handler def uploadDB(self, - se: SchemaExplorer, + sg: SchemaGenerator, manifest: pd.DataFrame, datasetId: str, table_name: str, @@ -911,13 +911,13 @@ def uploadDB(self, """ - col_schema, table_manifest = self.formatDB(se, manifest, useSchemaLabel) + col_schema, table_manifest = self.formatDB(sg, manifest, useSchemaLabel) - manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, se, restrict,) + manifest_table_id = self.buildDB(datasetId, table_name, col_schema, table_manifest, table_manipulation, sg, restrict,) return manifest_table_id, manifest, table_manifest - def formatDB(self, se, manifest, useSchemaLabel): + def formatDB(self, sg, manifest, useSchemaLabel): """ Method to format a manifest appropriatly for upload as table @@ -940,7 +940,7 @@ def formatDB(self, se, manifest, useSchemaLabel): if useSchemaLabel: cols = [ - se.get_class_label_from_display_name( + sg.se.get_class_label_from_display_name( str(col) ).translate({ord(x): '' for x in blacklist_chars}) for col in manifest_columns @@ -972,7 +972,7 @@ def buildDB(self, col_schema: List, table_manifest: pd.DataFrame, table_manipulation: str, - se: SchemaExplorer, + sg: SchemaGenerator, restrict: bool = False, ): @@ -1004,7 +1004,7 @@ def buildDB(self, if table_manipulation.lower() == 'replace': manifest_table_id = TableOperations.replaceTable(self, tableToLoad=table_manifest, tableName=table_name, existingTableId=table_info[table_name], specifySchema = True, datasetId = datasetId, columnTypeDict=col_schema, restrict=restrict) elif table_manipulation.lower() == 'upsert': - manifest_table_id = TableOperations.upsertTable(self, se=se, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) + manifest_table_id = TableOperations.upsertTable(self, sg=sg, tableToLoad = table_manifest, tableName=table_name, existingTableId=table_info[table_name], datasetId=datasetId) elif table_manipulation.lower() == 'update': manifest_table_id = TableOperations.updateTable(self, tableToLoad=table_manifest, existingTableId=table_info[table_name], restrict=restrict) @@ -1238,22 +1238,19 @@ def _read_manifest(self, metadataManifestPath:str) -> pd.DataFrame: ) from err return manifest - def _add_id_columns_to_manifest(self, manifest: pd.DataFrame, se: SchemaExplorer): + def _add_id_columns_to_manifest(self, manifest: pd.DataFrame, sg: SchemaGenerator): """Helper function to add id and entityId columns to the manifest if they do not already exist, Fill id values per row. Args: Manifest loaded as a pd.Dataframe Returns (pd.DataFrame): Manifest df with new Id and EntityId columns (and UUID values) if they were not already present. """ - # load the specific schema being used - temp_schema_explorer = deepcopy(se) - temp_schema_explorer.load_schema(CONFIG["model"]["input"]["location"]) # Add Id for table updates and fill. if not col_in_dataframe("Id", manifest): # See if schema has `Uuid` column specified try: - uuid_col_in_schema = temp_schema_explorer.is_class_in_schema('Uuid') or temp_schema_explorer.is_class_in_schema('uuid') + uuid_col_in_schema = sg.se.is_class_in_schema('Uuid') or sg.se.is_class_in_schema('uuid') except (KeyError): uuid_col_in_schema = False @@ -1412,7 +1409,7 @@ def upload_manifest_as_table( """ # Upload manifest as a table, get the ID and updated manifest. manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( - se, + schemaGenerator, manifest, datasetId, table_name, @@ -1431,7 +1428,7 @@ def upload_manifest_as_table( # Update manifest Synapse table with new entity id column. manifest_synapse_table_id, manifest, table_manifest = self.uploadDB( - se, + schemaGenerator, manifest, datasetId, table_name, @@ -1584,13 +1581,12 @@ def associateMetadataWithFiles( Returns: manifest_synapse_file_id: SynID of manifest csv uploaded to synapse. """ - - # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations - se = SchemaExplorer() - # Read new manifest CSV: manifest = self._read_manifest(metadataManifestPath) - manifest = self._add_id_columns_to_manifest(manifest, se) + manifest = self._add_id_columns_to_manifest(manifest, schemaGenerator) + + # get a schema explorer object to ensure schema attribute names used in manifest are translated to schema labels for synapse annotations + se = SchemaExplorer() table_name, component_name = self._generate_table_name(manifest) @@ -2126,7 +2122,7 @@ def _get_schematic_db_creds(synStore: SynapseStorage): return username, authtoken - def upsertTable(synStore: SynapseStorage, se: SchemaExplorer, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): + def upsertTable(synStore: SynapseStorage, sg: SchemaGenerator, tableToLoad: pd.DataFrame = None, tableName: str = None, existingTableId: str = None, datasetId: str = None): """ Method to upsert rows from a new manifest into an existing table on synapse For upsert functionality to work, primary keys must follow the naming convention of _id @@ -2157,7 +2153,7 @@ def upsertTable(synStore: SynapseStorage, se: SchemaExplorer, tableToLoad: pd.Da except(SynapseHTTPError) as ex: # If error is raised because Table has old `Uuid` column and not new `Id` column, then handle and re-attempt upload if 'Id is not a valid column name or id' in str(ex): - TableOperations._update_table_uuid_column(synStore, existingTableId, se) + TableOperations._update_table_uuid_column(synStore, existingTableId, sg) synapseDB.upsert_table_rows(table_name=tableName, data=tableToLoad) # Raise if other error else: @@ -2165,7 +2161,7 @@ def upsertTable(synStore: SynapseStorage, se: SchemaExplorer, tableToLoad: pd.Da return existingTableId - def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, se: SchemaExplorer,) -> None: + def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, sg: SchemaGenerator,) -> None: """Removes the `Uuid` column when present, and relpaces with an `Id` column Used to enable backwards compatability for manifests using the old `Uuid` convention @@ -2176,10 +2172,6 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, se: Schem None """ - # load the specific schema being used - temp_schema_explorer = deepcopy(se) - temp_schema_explorer.load_schema(CONFIG["model"]["input"]["location"]) - # Get the columns of the schema schema = synStore.syn.get(table_id) cols = synStore.syn.getTableColumns(schema) @@ -2189,7 +2181,7 @@ def _update_table_uuid_column(synStore: SynapseStorage, table_id: str, se: Schem if col.name.lower() == 'uuid': # See if schema has `Uuid` column specified try: - uuid_col_in_schema = temp_schema_explorer.is_class_in_schema(col.name) + uuid_col_in_schema = sg.se.is_class_in_schema(col.name) except (KeyError): uuid_col_in_schema = False From 54f8847ff2d482fc26f3e19d713fc937685d7f29 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 23 May 2023 11:53:38 -0400 Subject: [PATCH 580/615] add some comments --- schematic_api/Dockerfile | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/schematic_api/Dockerfile b/schematic_api/Dockerfile index 5fdf43bae..101bc545e 100644 --- a/schematic_api/Dockerfile +++ b/schematic_api/Dockerfile @@ -1,6 +1,5 @@ FROM tiangolo/uwsgi-nginx-flask:python3.10 -# set default APP_PORT to 80 # the environment variables defined here are the default # and can be overwritten by docker run -e VARIABLE = XX # or can be overwritten by .env when using docker compose @@ -21,7 +20,10 @@ ENV PYTHONFAULTHANDLER=1 \ # Note: # The starting number of uWSGI processes is controlled by the variable UWSGI_CHEAPER, by default set to 2. # The maximum number of uWSGI processes is controlled by the variable UWSGI_PROCESSES, by default set to 16 +# By default, the image starts with 2 uWSGI processes running. When the server is experiencing a high load, it creates up to 16 uWSGI processes to handle it on demand. # NGINX_MAX_UPLOAD is set to 0 by default that allows unlimited upload file sizes +# NGINX_WORKER_CONNECTIONS is set to 1024 by default that allows a maximum limit of 1024 connections per worker. +# NGINX_WORKER_OPEN_FILES is set to 2048 by default that allows 2048 open files # run open ssl and generate certificate RUN apt update && \ @@ -58,11 +60,11 @@ RUN pip install --no-cache-dir "poetry==$POETRY_VERSION" WORKDIR ${APP_PARENT_DIR} RUN chown www-data:www-data ${APP_PARENT_DIR} -# remove the old uwsgi.ini and main.py +# remove the old uwsgi.ini and main.py from the original image RUN rm -rf ${APP_PARENT_DIR}/main.py RUN rm -rf ${APP_PARENT_DIR}/uwsgi.ini -# copy relevant files and run poetry install +# copy to use custom uwsgi.ini COPY ./uwsgi.ini ./ # create a separate folder called app From b99d544209cdd238bdaa78f096099c1844316853 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 23 May 2023 15:30:26 -0400 Subject: [PATCH 581/615] update comment; instructions in readme --- docker-compose.yml | 4 ++-- schematic_api/api/README.md | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 333df4f84..862f41247 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,6 @@ version: "3.9" services: - #run schematic APIs in a docker container without uWSGI + # run schematic APIs in a docker container without uWSGI schematic: build: dockerfile: Dockerfile @@ -17,7 +17,7 @@ services: SCHEMATIC_CONFIG: /schematic/config.yml SCHEMATIC_CONFIG_CONTENT: "${SCHEMATIC_CONFIG_CONTENT}" GE_HOME: /usr/src/app/great_expectations/ - #run schematic APIs in a docker container with uWSGI + # run schematic APIs in a docker container with uWSGI and nginx schematic-aws: build: context: ../schematic diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index abadfb6c3..545c6c71b 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -18,13 +18,15 @@ If you define `APP_PORT` as `3001` in `docker-compose.yml`, you should be able t After installing uWSGI, flask and connexion, to start a docker container that runs flask application with uWSGI: 1) Comment out the first part of `docker-compose.yml` and focus only on building container `schematic-aws`. 2) Get `service_account_creds.json` by doing `schematic init --config /path/to/config.yml`. -3) Make a copy of `env.example` and rename it as `.env` and keep it in the same directory as `env.example` By default, schematic uses port 7080. If port 7080 is not available, please update `SERVER_PORT` in .env file. +3) Make a copy of `env.example` and rename it as `.env` and keep it in the same directory as `env.example` By default, schematic uses port 80. If port 80 is not available, please update `USE_LISTEN_PORT` in .env file. 4) Copy the content of `service_account_creds.json` and put it in `.env` file after key `SERVICE_ACCOUNT_CREDS`. Remember to wrap around the credentials with single quotes. 5) Build a docker image and spin up docker container `schematic-api-aws` by running: ```bash docker compose up ``` -If you define the value of port as `7080` in `.env` file, you should be able to see the application running when visiting `http://localhost:7080/v1/ui/` +You should be able to view your application when visit: `https://127.0.0.1/v1/ui/`. You might receive an notification like this in your browser: +Screen Shot 2023-05-06 at 10 06 44 AM +But please click on "show details" and "visit this website" to proceed. Note that the instructions might be slightly different for different browsers. By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. From 66d3efbacd66ed3e6964d5353b00d6fa1c17ba70 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 23 May 2023 15:32:52 -0400 Subject: [PATCH 582/615] change image --- schematic_api/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 545c6c71b..796c59049 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -25,7 +25,7 @@ After installing uWSGI, flask and connexion, to start a docker container that ru docker compose up ``` You should be able to view your application when visit: `https://127.0.0.1/v1/ui/`. You might receive an notification like this in your browser: -Screen Shot 2023-05-06 at 10 06 44 AM +Screen Shot 2023-05-23 at 3 31 46 PM But please click on "show details" and "visit this website" to proceed. Note that the instructions might be slightly different for different browsers. By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. From 7eab9f34b52dc708eb9e7afbfc73118c169d3a88 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 23 May 2023 15:34:29 -0400 Subject: [PATCH 583/615] edit instructions --- schematic_api/api/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 796c59049..6a98810c4 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -26,7 +26,9 @@ docker compose up ``` You should be able to view your application when visit: `https://127.0.0.1/v1/ui/`. You might receive an notification like this in your browser: Screen Shot 2023-05-23 at 3 31 46 PM -But please click on "show details" and "visit this website" to proceed. Note that the instructions might be slightly different for different browsers. + + +Please click on "show details" and "visit this website" to proceed. Note that the instructions might be slightly different for different browsers. By default, this command builds up two containers (`schematic` and `schematic-aws`). You could spin up two containers if you want. But only `schematic-aws` runs flask with uWSGI. From 8b4fa21424c82c46afee417ade46958ac42d79f8 Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 23 May 2023 15:36:37 -0400 Subject: [PATCH 584/615] add space --- schematic_api/api/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 6a98810c4..8d351e438 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -25,8 +25,8 @@ After installing uWSGI, flask and connexion, to start a docker container that ru docker compose up ``` You should be able to view your application when visit: `https://127.0.0.1/v1/ui/`. You might receive an notification like this in your browser: -Screen Shot 2023-05-23 at 3 31 46 PM +Screen Shot 2023-05-23 at 3 31 46 PM Please click on "show details" and "visit this website" to proceed. Note that the instructions might be slightly different for different browsers. From 492629f39b3a44c3a627b06aab35c72a243088ee Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 24 May 2023 09:39:35 -0700 Subject: [PATCH 585/615] make aws group optional --- poetry.lock | 618 +++++++++++++++++++++++++------------------------ pyproject.toml | 3 + 2 files changed, 318 insertions(+), 303 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0382be33e..4e6936cc3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -94,7 +94,7 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.15.4" +version = "2.15.5" description = "An abstract syntax tree for Python with inference support." category = "main" optional = false @@ -212,7 +212,7 @@ python-versions = "~=3.7" [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -324,7 +324,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14 [[package]] name = "coverage" -version = "7.2.3" +version = "7.2.6" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -427,7 +427,7 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "docutils" -version = "0.19" +version = "0.20.1" description = "Docutils -- Python Documentation Utilities" category = "main" optional = false @@ -473,7 +473,7 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.16.3" +version = "2.17.1" description = "Fastest Python implementation of JSON schema" category = "main" optional = false @@ -570,7 +570,7 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.17.3" +version = "2.18.1" description = "Google Authentication Library" category = "main" optional = false @@ -581,6 +581,7 @@ cachetools = ">=2.0.0,<6.0" pyasn1-modules = ">=0.2.1" rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} six = ">=1.9.0" +urllib3 = "<2.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] @@ -788,7 +789,7 @@ python-versions = ">=3.7" [[package]] name = "ipykernel" -version = "6.22.0" +version = "6.23.1" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -818,11 +819,11 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.12.0" +version = "8.13.2" description = "IPython: Productive Interactive Computing" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -1258,7 +1259,7 @@ python-versions = ">=3.5" [[package]] name = "nbclassic" -version = "0.5.6" +version = "1.0.0" description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false @@ -1290,26 +1291,26 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p [[package]] name = "nbclient" -version = "0.7.4" +version = "0.8.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "main" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" [package.dependencies] jupyter-client = ">=6.1.12" jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" nbformat = ">=5.1" -traitlets = ">=5.3" +traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.3.1" +version = "7.4.0" description = "Converting Jupyter Notebooks" category = "main" optional = false @@ -1485,11 +1486,11 @@ python-versions = ">=3.7" [[package]] name = "pandarallel" -version = "1.6.4" +version = "1.6.5" description = "An easy to use library to speed up computation (by parallelizing on multi CPUs) with pandas." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] dill = ">=0.3.1" @@ -1584,14 +1585,14 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "3.4.0" +version = "3.5.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] @@ -1630,7 +1631,7 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.22.3" +version = "4.23.1" description = "" category = "main" optional = false @@ -1703,7 +1704,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.10.7" +version = "1.10.8" description = "Data validation and settings management using python type hints" category = "main" optional = false @@ -1752,7 +1753,7 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.17.3" +version = "2.17.4" description = "python code static checker" category = "main" optional = false @@ -1893,17 +1894,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "pytz-deprecation-shim" -version = "0.1.0.post0" -description = "Shims to make deprecation of pytz easier" -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" - -[package.dependencies] -tzdata = {version = "*", markers = "python_version >= \"3.6\""} - [[package]] name = "pywin32" version = "306" @@ -1967,15 +1957,15 @@ networkx = ["networkx (>=2.0.0,<3.0.0)"] [[package]] name = "regex" -version = "2023.3.23" +version = "2023.5.5" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" [[package]] name = "requests" -version = "2.29.0" +version = "2.31.0" description = "Python HTTP for Humans." category = "main" optional = false @@ -1985,7 +1975,7 @@ python-versions = ">=3.7" certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -2175,7 +2165,7 @@ python-versions = ">=3.7" [[package]] name = "sphinx" -version = "6.2.1" +version = "7.0.1" description = "Python documentation generator" category = "main" optional = false @@ -2185,7 +2175,7 @@ python-versions = ">=3.8" alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.20" +docutils = ">=0.18.1,<0.21" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" @@ -2291,7 +2281,7 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.47" +version = "1.4.48" description = "Database Abstraction Library" category = "main" optional = false @@ -2472,7 +2462,7 @@ python-versions = ">=3.5" [[package]] name = "tornado" -version = "6.3.1" +version = "6.3.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "main" optional = false @@ -2509,7 +2499,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.6.1" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -2525,14 +2515,13 @@ python-versions = ">=2" [[package]] name = "tzlocal" -version = "4.3" +version = "5.0.1" description = "tzinfo object for the local timezone" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] @@ -2559,7 +2548,7 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.15" +version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -2571,7 +2560,7 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "p socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] -name = "uWSGI" +name = "uwsgi" version = "2.0.21" description = "The uWSGI server" category = "dev" @@ -2608,7 +2597,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.5.1" +version = "1.5.2" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2661,7 +2650,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "93b3630734394087f4d3ddcefb848a937b7752a9660bdb35b6766fc699773050" +content-hash = "4851b89cfd9ec278b4b65e633ca5adac284934f06c45e1adacdfd91620328e7a" [metadata.files] alabaster = [ @@ -2712,8 +2701,8 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, + {file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"}, + {file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, @@ -2758,8 +2747,8 @@ cachetools = [ {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, ] certifi = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] cffi = [ {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, @@ -2929,57 +2918,57 @@ connexion = [ {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"}, - {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"}, - {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"}, - {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"}, - {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"}, - {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"}, - {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"}, - {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"}, - {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"}, - {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"}, - {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"}, - {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"}, - {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"}, - {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"}, - {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"}, + {file = "coverage-7.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec"}, + {file = "coverage-7.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80"}, + {file = "coverage-7.2.6-cp310-cp310-win32.whl", hash = "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec"}, + {file = "coverage-7.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"}, + {file = "coverage-7.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044"}, + {file = "coverage-7.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995"}, + {file = "coverage-7.2.6-cp311-cp311-win32.whl", hash = "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b"}, + {file = "coverage-7.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1"}, + {file = "coverage-7.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb"}, + {file = "coverage-7.2.6-cp37-cp37m-win32.whl", hash = "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473"}, + {file = "coverage-7.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110"}, + {file = "coverage-7.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1"}, + {file = "coverage-7.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8"}, + {file = "coverage-7.2.6-cp38-cp38-win32.whl", hash = "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5"}, + {file = "coverage-7.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd"}, + {file = "coverage-7.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478"}, + {file = "coverage-7.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6"}, + {file = "coverage-7.2.6-cp39-cp39-win32.whl", hash = "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb"}, + {file = "coverage-7.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783"}, + {file = "coverage-7.2.6-pp37.pp38.pp39-none-any.whl", hash = "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d"}, + {file = "coverage-7.2.6.tar.gz", hash = "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d"}, ] cryptography = [ {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, @@ -3043,8 +3032,8 @@ dill = [ {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, ] docutils = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] entrypoints = [ {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, @@ -3063,8 +3052,8 @@ executing = [ {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, ] fastjsonschema = [ - {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, - {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, + {file = "fastjsonschema-2.17.1-py3-none-any.whl", hash = "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0"}, + {file = "fastjsonschema-2.17.1.tar.gz", hash = "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3"}, ] flake8 = [ {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, @@ -3091,8 +3080,8 @@ google-api-python-client = [ {file = "google_api_python_client-2.86.0-py2.py3-none-any.whl", hash = "sha256:0f320190ab9d5bd2fdb0cb894e8e53bb5e17d4888ee8dc4d26ba65ce378409e2"}, ] google-auth = [ - {file = "google-auth-2.17.3.tar.gz", hash = "sha256:ce311e2bc58b130fddf316df57c9b3943c2a7b4f6ec31de9663a9333e4064efc"}, - {file = "google_auth-2.17.3-py2.py3-none-any.whl", hash = "sha256:f586b274d3eb7bd932ea424b1c702a30e0393a2e2bc4ca3eae8263ffd8be229f"}, + {file = "google-auth-2.18.1.tar.gz", hash = "sha256:d7a3249027e7f464fbbfd7ee8319a08ad09d2eea51578575c4bd360ffa049ccb"}, + {file = "google_auth-2.18.1-py2.py3-none-any.whl", hash = "sha256:55a395cdfd3f3dd3f649131d41f97c17b4ed8a2aac1be3502090c716314e8a37"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -3201,12 +3190,12 @@ iniconfig = [ {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] ipykernel = [ - {file = "ipykernel-6.22.0-py3-none-any.whl", hash = "sha256:1ae6047c1277508933078163721bbb479c3e7292778a04b4bacf0874550977d6"}, - {file = "ipykernel-6.22.0.tar.gz", hash = "sha256:302558b81f1bc22dc259fb2a0c5c7cf2f4c0bdb21b50484348f7bafe7fb71421"}, + {file = "ipykernel-6.23.1-py3-none-any.whl", hash = "sha256:77aeffab056c21d16f1edccdc9e5ccbf7d96eb401bd6703610a21be8b068aadc"}, + {file = "ipykernel-6.23.1.tar.gz", hash = "sha256:1aba0ae8453e15e9bc6b24e497ef6840114afcdb832ae597f32137fa19d42a6f"}, ] ipython = [ - {file = "ipython-8.12.0-py3-none-any.whl", hash = "sha256:1c183bf61b148b00bcebfa5d9b39312733ae97f6dad90d7e9b4d86c8647f498c"}, - {file = "ipython-8.12.0.tar.gz", hash = "sha256:a950236df04ad75b5bc7f816f9af3d74dc118fd42f2ff7e80e8e60ca1f182e2d"}, + {file = "ipython-8.13.2-py3-none-any.whl", hash = "sha256:ffca270240fbd21b06b2974e14a86494d6d29290184e788275f55e0b55914926"}, + {file = "ipython-8.13.2.tar.gz", hash = "sha256:7dff3fad32b97f6488e02f87b970f309d082f758d7b7fc252e3b19ee0e432dbb"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -3423,16 +3412,16 @@ mypy-extensions = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] nbclassic = [ - {file = "nbclassic-0.5.6-py3-none-any.whl", hash = "sha256:e3c8b7de80046c4a36a74662a5e325386d345289906c618366d8154e03dc2322"}, - {file = "nbclassic-0.5.6.tar.gz", hash = "sha256:aab53fa1bea084fb6ade5c538b011a4f070c69f88d72878a8e8fb356f152509f"}, + {file = "nbclassic-1.0.0-py3-none-any.whl", hash = "sha256:f99e4769b4750076cd4235c044b61232110733322384a94a63791d2e7beacc66"}, + {file = "nbclassic-1.0.0.tar.gz", hash = "sha256:0ae11eb2319455d805596bf320336cda9554b41d99ab9a3c31bf8180bffa30e3"}, ] nbclient = [ - {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, - {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, + {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, + {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, ] nbconvert = [ - {file = "nbconvert-7.3.1-py3-none-any.whl", hash = "sha256:d2e95904666f1ff77d36105b9de4e0801726f93b862d5b28f69e93d99ad3b19c"}, - {file = "nbconvert-7.3.1.tar.gz", hash = "sha256:78685362b11d2e8058e70196fe83b09abed8df22d3e599cf271f4d39fdc48b9e"}, + {file = "nbconvert-7.4.0-py3-none-any.whl", hash = "sha256:af5064a9db524f9f12f4e8be7f0799524bd5b14c1adea37e34e83c95127cc818"}, + {file = "nbconvert-7.4.0.tar.gz", hash = "sha256:51b6c77b507b177b73f6729dba15676e42c4e92bcb00edc8cc982ee72e7d89d7"}, ] nbformat = [ {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, @@ -3501,7 +3490,7 @@ packaging = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] pandarallel = [ - {file = "pandarallel-1.6.4.tar.gz", hash = "sha256:70091652485050241ffac37c3e94d21732697c63ee4613ae7bf85da076be41f2"}, + {file = "pandarallel-1.6.5.tar.gz", hash = "sha256:1c2df98ff6441e8ae13ff428ceebaa7ec42d731f7f972c41ce4fdef1d3adf640"}, ] pandas = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, @@ -3557,8 +3546,8 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-3.4.0-py3-none-any.whl", hash = "sha256:01437886022decaf285d8972f9526397bfae2ac55480ed372ed6d9eca048870a"}, - {file = "platformdirs-3.4.0.tar.gz", hash = "sha256:a5e1536e5ea4b1c238a1364da17ff2993d5bd28e15600c2c8224008aff6bbcad"}, + {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -3573,19 +3562,19 @@ prompt-toolkit = [ {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, ] protobuf = [ - {file = "protobuf-4.22.3-cp310-abi3-win32.whl", hash = "sha256:8b54f56d13ae4a3ec140076c9d937221f887c8f64954673d46f63751209e839a"}, - {file = "protobuf-4.22.3-cp310-abi3-win_amd64.whl", hash = "sha256:7760730063329d42a9d4c4573b804289b738d4931e363ffbe684716b796bde51"}, - {file = "protobuf-4.22.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:d14fc1a41d1a1909998e8aff7e80d2a7ae14772c4a70e4bf7db8a36690b54425"}, - {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:70659847ee57a5262a65954538088a1d72dfc3e9882695cab9f0c54ffe71663b"}, - {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:13233ee2b9d3bd9a5f216c1fa2c321cd564b93d8f2e4f521a85b585447747997"}, - {file = "protobuf-4.22.3-cp37-cp37m-win32.whl", hash = "sha256:ecae944c6c2ce50dda6bf76ef5496196aeb1b85acb95df5843cd812615ec4b61"}, - {file = "protobuf-4.22.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d4b66266965598ff4c291416be429cef7989d8fae88b55b62095a2331511b3fa"}, - {file = "protobuf-4.22.3-cp38-cp38-win32.whl", hash = "sha256:f08aa300b67f1c012100d8eb62d47129e53d1150f4469fd78a29fa3cb68c66f2"}, - {file = "protobuf-4.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:f2f4710543abec186aee332d6852ef5ae7ce2e9e807a3da570f36de5a732d88e"}, - {file = "protobuf-4.22.3-cp39-cp39-win32.whl", hash = "sha256:7cf56e31907c532e460bb62010a513408e6cdf5b03fb2611e4b67ed398ad046d"}, - {file = "protobuf-4.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:e0e630d8e6a79f48c557cd1835865b593d0547dce221c66ed1b827de59c66c97"}, - {file = "protobuf-4.22.3-py3-none-any.whl", hash = "sha256:52f0a78141078077cfe15fe333ac3e3a077420b9a3f5d1bf9b5fe9d286b4d881"}, - {file = "protobuf-4.22.3.tar.gz", hash = "sha256:23452f2fdea754a8251d0fc88c0317735ae47217e0d27bf330a30eec2848811a"}, + {file = "protobuf-4.23.1-cp310-abi3-win32.whl", hash = "sha256:410bcc0a5b279f634d3e16082ce221dfef7c3392fac723500e2e64d1806dd2be"}, + {file = "protobuf-4.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:32e78beda26d7a101fecf15d7a4a792278a0d26a31bc327ff05564a9d68ab8ee"}, + {file = "protobuf-4.23.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9510cac91e764e86acd74e2b7f7bc5e6127a7f3fb646d7c8033cfb84fd1176a"}, + {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:346990f634272caac1f09efbcfbbacb23098b1f606d172534c6fa2d9758bb436"}, + {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3ce113b3f3362493bddc9069c2163a38f240a9ed685ff83e7bcb756b05e1deb0"}, + {file = "protobuf-4.23.1-cp37-cp37m-win32.whl", hash = "sha256:2036a3a1e7fc27f973fa0a7888dce712393af644f4695385f117886abc792e39"}, + {file = "protobuf-4.23.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3b8905eafe4439076e1f58e9d1fa327025fd2777cf90f14083092ae47f77b0aa"}, + {file = "protobuf-4.23.1-cp38-cp38-win32.whl", hash = "sha256:5b9cd6097e6acae48a68cb29b56bc79339be84eca65b486910bb1e7a30e2b7c1"}, + {file = "protobuf-4.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:decf119d54e820f298ee6d89c72d6b289ea240c32c521f00433f9dc420595f38"}, + {file = "protobuf-4.23.1-cp39-cp39-win32.whl", hash = "sha256:91fac0753c3c4951fbb98a93271c43cc7cf3b93cf67747b3e600bb1e5cc14d61"}, + {file = "protobuf-4.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac50be82491369a9ec3710565777e4da87c6d2e20404e0abb1f3a8f10ffd20f0"}, + {file = "protobuf-4.23.1-py3-none-any.whl", hash = "sha256:65f0ac96ef67d7dd09b19a46aad81a851b6f85f89725577f16de38f2d68ad477"}, + {file = "protobuf-4.23.1.tar.gz", hash = "sha256:95789b569418a3e32a53f43d7763be3d490a831e9c08042539462b6d972c2d7e"}, ] psutil = [ {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, @@ -3628,42 +3617,42 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, - {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, - {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, - {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, - {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, - {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, - {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, - {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, - {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, - {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab"}, + {file = "pydantic-1.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4"}, + {file = "pydantic-1.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd"}, + {file = "pydantic-1.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea"}, + {file = "pydantic-1.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108"}, + {file = "pydantic-1.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01"}, + {file = "pydantic-1.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a"}, + {file = "pydantic-1.10.8-py3-none-any.whl", hash = "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2"}, + {file = "pydantic-1.10.8.tar.gz", hash = "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca"}, ] pyflakes = [ {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, @@ -3678,8 +3667,8 @@ pygsheets = [ {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.17.3-py3-none-any.whl", hash = "sha256:a6cbb4c6e96eab4a3c7de7c6383c512478f58f88d95764507d84c899d656a89a"}, - {file = "pylint-2.17.3.tar.gz", hash = "sha256:761907349e699f8afdcd56c4fe02f3021ab5b3a0fc26d19a9bfdc66c7d0d5cd5"}, + {file = "pylint-2.17.4-py3-none-any.whl", hash = "sha256:7a1145fb08c251bdb5cca11739722ce64a63db479283d10ce718b2460e54123c"}, + {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, ] pyopenssl = [ {file = "pyOpenSSL-23.1.1-py3-none-any.whl", hash = "sha256:9e0c526404a210df9d2b18cd33364beadb0dc858a739b885677bc65e105d4a4c"}, @@ -3746,10 +3735,6 @@ pytz = [ {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] -pytz-deprecation-shim = [ - {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, - {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, -] pywin32 = [ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, @@ -3904,70 +3889,98 @@ rdflib = [ {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, ] regex = [ - {file = "regex-2023.3.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:845a5e2d84389c4ddada1a9b95c055320070f18bb76512608374aca00d22eca8"}, - {file = "regex-2023.3.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87d9951f5a538dd1d016bdc0dcae59241d15fa94860964833a54d18197fcd134"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae17d3be44c0b3f782c28ae9edd8b47c1f1776d4cabe87edc0b98e1f12b021"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b8eb1e3bca6b48dc721818a60ae83b8264d4089a4a41d62be6d05316ec38e15"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df45fac182ebc3c494460c644e853515cc24f5ad9da05f8ffb91da891bfee879"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7006105b10b59971d3b248ad75acc3651c7e4cf54d81694df5a5130a3c3f7ea"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93f3f1aa608380fe294aa4cb82e2afda07a7598e828d0341e124b8fd9327c715"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787954f541ab95d8195d97b0b8cf1dc304424adb1e07365967e656b92b38a699"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20abe0bdf03630fe92ccafc45a599bca8b3501f48d1de4f7d121153350a2f77d"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11d00c31aeab9a6e0503bc77e73ed9f4527b3984279d997eb145d7c7be6268fd"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d5bbe0e1511b844794a3be43d6c145001626ba9a6c1db8f84bdc724e91131d9d"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ea3c0cb56eadbf4ab2277e7a095676370b3e46dbfc74d5c383bd87b0d6317910"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d895b4c863059a4934d3e874b90998df774644a41b349ebb330f85f11b4ef2c0"}, - {file = "regex-2023.3.23-cp310-cp310-win32.whl", hash = "sha256:9d764514d19b4edcc75fd8cb1423448ef393e8b6cbd94f38cab983ab1b75855d"}, - {file = "regex-2023.3.23-cp310-cp310-win_amd64.whl", hash = "sha256:11d1f2b7a0696dc0310de0efb51b1f4d813ad4401fe368e83c0c62f344429f98"}, - {file = "regex-2023.3.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8a9c63cde0eaa345795c0fdeb19dc62d22e378c50b0bc67bf4667cd5b482d98b"}, - {file = "regex-2023.3.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dd7200b4c27b68cf9c9646da01647141c6db09f48cc5b51bc588deaf8e98a797"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22720024b90a6ba673a725dcc62e10fb1111b889305d7c6b887ac7466b74bedb"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b190a339090e6af25f4a5fd9e77591f6d911cc7b96ecbb2114890b061be0ac1"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e76b6fc0d8e9efa39100369a9b3379ce35e20f6c75365653cf58d282ad290f6f"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7868b8f218bf69a2a15402fde08b08712213a1f4b85a156d90473a6fb6b12b09"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2472428efc4127374f494e570e36b30bb5e6b37d9a754f7667f7073e43b0abdd"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c37df2a060cb476d94c047b18572ee2b37c31f831df126c0da3cd9227b39253d"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4479f9e2abc03362df4045b1332d4a2b7885b245a30d4f4b051c4083b97d95d8"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2396e0678167f2d0c197da942b0b3fb48fee2f0b5915a0feb84d11b6686afe6"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75f288c60232a5339e0ff2fa05779a5e9c74e9fc085c81e931d4a264501e745b"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c869260aa62cee21c5eb171a466c0572b5e809213612ef8d495268cd2e34f20d"}, - {file = "regex-2023.3.23-cp311-cp311-win32.whl", hash = "sha256:25f0532fd0c53e96bad84664171969de9673b4131f2297f1db850d3918d58858"}, - {file = "regex-2023.3.23-cp311-cp311-win_amd64.whl", hash = "sha256:5ccfafd98473e007cebf7da10c1411035b7844f0f204015efd050601906dbb53"}, - {file = "regex-2023.3.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6572ff287176c0fb96568adb292674b421fa762153ed074d94b1d939ed92c253"}, - {file = "regex-2023.3.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a610e0adfcb0fc84ea25f6ea685e39e74cbcd9245a72a9a7aab85ff755a5ed27"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086afe222d58b88b62847bdbd92079b4699350b4acab892f88a935db5707c790"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79e29fd62fa2f597a6754b247356bda14b866131a22444d67f907d6d341e10f3"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c07ce8e9eee878a48ebeb32ee661b49504b85e164b05bebf25420705709fdd31"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b036f401895e854de9fefe061518e78d506d8a919cc250dc3416bca03f6f9a"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78ac8dd8e18800bb1f97aad0d73f68916592dddf233b99d2b5cabc562088503a"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:539dd010dc35af935b32f248099e38447bbffc10b59c2b542bceead2bed5c325"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9bf4a5626f2a0ea006bf81e8963f498a57a47d58907eaa58f4b3e13be68759d8"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf86b4328c204c3f315074a61bc1c06f8a75a8e102359f18ce99fbcbbf1951f0"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2848bf76673c83314068241c8d5b7fa9ad9bed866c979875a0e84039349e8fa7"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c125a02d22c555e68f7433bac8449992fa1cead525399f14e47c2d98f2f0e467"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cd1671e9d5ac05ce6aa86874dd8dfa048824d1dbe73060851b310c6c1a201a96"}, - {file = "regex-2023.3.23-cp38-cp38-win32.whl", hash = "sha256:fffe57312a358be6ec6baeb43d253c36e5790e436b7bf5b7a38df360363e88e9"}, - {file = "regex-2023.3.23-cp38-cp38-win_amd64.whl", hash = "sha256:dbb3f87e15d3dd76996d604af8678316ad2d7d20faa394e92d9394dfd621fd0c"}, - {file = "regex-2023.3.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c88e8c226473b5549fe9616980ea7ca09289246cfbdf469241edf4741a620004"}, - {file = "regex-2023.3.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6560776ec19c83f3645bbc5db64a7a5816c9d8fb7ed7201c5bcd269323d88072"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b1fc2632c01f42e06173d8dd9bb2e74ab9b0afa1d698058c867288d2c7a31f3"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdf7ad455f1916b8ea5cdbc482d379f6daf93f3867b4232d14699867a5a13af7"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5fc33b27b1d800fc5b78d7f7d0f287e35079ecabe68e83d46930cf45690e1c8c"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c49552dc938e3588f63f8a78c86f3c9c75301e813bca0bef13bdb4b87ccf364"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e152461e9a0aedec7d37fc66ec0fa635eca984777d3d3c3e36f53bf3d3ceb16e"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:db034255e72d2995cf581b14bb3fc9c00bdbe6822b49fcd4eef79e1d5f232618"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:55ae114da21b7a790b90255ea52d2aa3a0d121a646deb2d3c6a3194e722fc762"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ef3f528fe1cc3d139508fe1b22523745aa77b9d6cb5b0bf277f48788ee0b993f"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:a81c9ec59ca2303acd1ccd7b9ac409f1e478e40e96f8f79b943be476c5fdb8bb"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cde09c4fdd070772aa2596d97e942eb775a478b32459e042e1be71b739d08b77"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3cd9f5dd7b821f141d3a6ca0d5d9359b9221e4f051ca3139320adea9f1679691"}, - {file = "regex-2023.3.23-cp39-cp39-win32.whl", hash = "sha256:7304863f3a652dab5e68e6fb1725d05ebab36ec0390676d1736e0571ebb713ef"}, - {file = "regex-2023.3.23-cp39-cp39-win_amd64.whl", hash = "sha256:54c3fa855a3f7438149de3211738dd9b5f0c733f48b54ae05aa7fce83d48d858"}, - {file = "regex-2023.3.23.tar.gz", hash = "sha256:dc80df325b43ffea5cdea2e3eaa97a44f3dd298262b1c7fe9dbb2a9522b956a7"}, + {file = "regex-2023.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:48c9ec56579d4ba1c88f42302194b8ae2350265cb60c64b7b9a88dcb7fbde309"}, + {file = "regex-2023.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f4541550459c08fdd6f97aa4e24c6f1932eec780d58a2faa2068253df7d6ff"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e22e4460f0245b468ee645156a4f84d0fc35a12d9ba79bd7d79bdcd2f9629d"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b870b6f632fc74941cadc2a0f3064ed8409e6f8ee226cdfd2a85ae50473aa94"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:171c52e320fe29260da550d81c6b99f6f8402450dc7777ef5ced2e848f3b6f8f"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad5524c2aedaf9aa14ef1bc9327f8abd915699dea457d339bebbe2f0d218f86"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a0f874ee8c0bc820e649c900243c6d1e6dc435b81da1492046716f14f1a2a96"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e645c757183ee0e13f0bbe56508598e2d9cd42b8abc6c0599d53b0d0b8dd1479"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a4c5da39bca4f7979eefcbb36efea04471cd68db2d38fcbb4ee2c6d440699833"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5e3f4468b8c6fd2fd33c218bbd0a1559e6a6fcf185af8bb0cc43f3b5bfb7d636"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:59e4b729eae1a0919f9e4c0fc635fbcc9db59c74ad98d684f4877be3d2607dd6"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ba73a14e9c8f9ac409863543cde3290dba39098fc261f717dc337ea72d3ebad2"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bbd5dcb19603ab8d2781fac60114fb89aee8494f4505ae7ad141a3314abb1f9"}, + {file = "regex-2023.5.5-cp310-cp310-win32.whl", hash = "sha256:40005cbd383438aecf715a7b47fe1e3dcbc889a36461ed416bdec07e0ef1db66"}, + {file = "regex-2023.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:59597cd6315d3439ed4b074febe84a439c33928dd34396941b4d377692eca810"}, + {file = "regex-2023.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f08276466fedb9e36e5193a96cb944928301152879ec20c2d723d1031cd4ddd"}, + {file = "regex-2023.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cd46f30e758629c3ee91713529cfbe107ac50d27110fdcc326a42ce2acf4dafc"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2910502f718828cecc8beff004917dcf577fc5f8f5dd40ffb1ea7612124547b"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:445d6f4fc3bd9fc2bf0416164454f90acab8858cd5a041403d7a11e3356980e8"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18196c16a584619c7c1d843497c069955d7629ad4a3fdee240eb347f4a2c9dbe"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33d430a23b661629661f1fe8395be2004006bc792bb9fc7c53911d661b69dd7e"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72a28979cc667e5f82ef433db009184e7ac277844eea0f7f4d254b789517941d"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f764e4dfafa288e2eba21231f455d209f4709436baeebb05bdecfb5d8ddc3d35"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23d86ad2121b3c4fc78c58f95e19173790e22ac05996df69b84e12da5816cb17"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:690a17db524ee6ac4a27efc5406530dd90e7a7a69d8360235323d0e5dafb8f5b"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1ecf3dcff71f0c0fe3e555201cbe749fa66aae8d18f80d2cc4de8e66df37390a"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:811040d7f3dd9c55eb0d8b00b5dcb7fd9ae1761c454f444fd9f37fe5ec57143a"}, + {file = "regex-2023.5.5-cp311-cp311-win32.whl", hash = "sha256:c8c143a65ce3ca42e54d8e6fcaf465b6b672ed1c6c90022794a802fb93105d22"}, + {file = "regex-2023.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:586a011f77f8a2da4b888774174cd266e69e917a67ba072c7fc0e91878178a80"}, + {file = "regex-2023.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b6365703e8cf1644b82104cdd05270d1a9f043119a168d66c55684b1b557d008"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a56c18f21ac98209da9c54ae3ebb3b6f6e772038681d6cb43b8d53da3b09ee81"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b942d8b3ce765dbc3b1dad0a944712a89b5de290ce8f72681e22b3c55f3cc8"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:844671c9c1150fcdac46d43198364034b961bd520f2c4fdaabfc7c7d7138a2dd"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2ce65bdeaf0a386bb3b533a28de3994e8e13b464ac15e1e67e4603dd88787fa"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fee0016cc35a8a91e8cc9312ab26a6fe638d484131a7afa79e1ce6165328a135"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18f05d14f14a812fe9723f13afafefe6b74ca042d99f8884e62dbd34dcccf3e2"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:941b3f1b2392f0bcd6abf1bc7a322787d6db4e7457be6d1ffd3a693426a755f2"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:921473a93bcea4d00295799ab929522fc650e85c6b9f27ae1e6bb32a790ea7d3"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:e2205a81f815b5bb17e46e74cc946c575b484e5f0acfcb805fb252d67e22938d"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:385992d5ecf1a93cb85adff2f73e0402dd9ac29b71b7006d342cc920816e6f32"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:890a09cb0a62198bff92eda98b2b507305dd3abf974778bae3287f98b48907d3"}, + {file = "regex-2023.5.5-cp36-cp36m-win32.whl", hash = "sha256:821a88b878b6589c5068f4cc2cfeb2c64e343a196bc9d7ac68ea8c2a776acd46"}, + {file = "regex-2023.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:7918a1b83dd70dc04ab5ed24c78ae833ae8ea228cef84e08597c408286edc926"}, + {file = "regex-2023.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:338994d3d4ca4cf12f09822e025731a5bdd3a37aaa571fa52659e85ca793fb67"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a69cf0c00c4d4a929c6c7717fd918414cab0d6132a49a6d8fc3ded1988ed2ea"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f5e06df94fff8c4c85f98c6487f6636848e1dc85ce17ab7d1931df4a081f657"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8906669b03c63266b6a7693d1f487b02647beb12adea20f8840c1a087e2dfb5"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fda3e50abad8d0f48df621cf75adc73c63f7243cbe0e3b2171392b445401550"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ac2b7d341dc1bd102be849d6dd33b09701223a851105b2754339e390be0627a"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2b495dd94b02de8215625948132cc2ea360ae84fe6634cd19b6567709c8ae2"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aa7d032c1d84726aa9edeb6accf079b4caa87151ca9fabacef31fa028186c66d"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d45864693351c15531f7e76f545ec35000d50848daa833cead96edae1665559"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21e90a288e6ba4bf44c25c6a946cb9b0f00b73044d74308b5e0afd190338297c"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:10250a093741ec7bf74bcd2039e697f519b028518f605ff2aa7ac1e9c9f97423"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6b8d0c153f07a953636b9cdb3011b733cadd4178123ef728ccc4d5969e67f3c2"}, + {file = "regex-2023.5.5-cp37-cp37m-win32.whl", hash = "sha256:10374c84ee58c44575b667310d5bbfa89fb2e64e52349720a0182c0017512f6c"}, + {file = "regex-2023.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9b320677521aabf666cdd6e99baee4fb5ac3996349c3b7f8e7c4eee1c00dfe3a"}, + {file = "regex-2023.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:afb1c70ec1e594a547f38ad6bf5e3d60304ce7539e677c1429eebab115bce56e"}, + {file = "regex-2023.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf123225945aa58b3057d0fba67e8061c62d14cc8a4202630f8057df70189051"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99757ad7fe5c8a2bb44829fc57ced11253e10f462233c1255fe03888e06bc19"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a623564d810e7a953ff1357f7799c14bc9beeab699aacc8b7ab7822da1e952b8"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ced02e3bd55e16e89c08bbc8128cff0884d96e7f7a5633d3dc366b6d95fcd1d6"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cbe6b5be3b9b698d8cc4ee4dee7e017ad655e83361cd0ea8e653d65e469468"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a6e4b0e0531223f53bad07ddf733af490ba2b8367f62342b92b39b29f72735a"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e9c4f778514a560a9c9aa8e5538bee759b55f6c1dcd35613ad72523fd9175b8"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:256f7f4c6ba145f62f7a441a003c94b8b1af78cee2cccacfc1e835f93bc09426"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd7b68fd2e79d59d86dcbc1ccd6e2ca09c505343445daaa4e07f43c8a9cc34da"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4a5059bd585e9e9504ef9c07e4bc15b0a621ba20504388875d66b8b30a5c4d18"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6893544e06bae009916a5658ce7207e26ed17385149f35a3125f5259951f1bbe"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c64d5abe91a3dfe5ff250c6bb267ef00dbc01501518225b45a5f9def458f31fb"}, + {file = "regex-2023.5.5-cp38-cp38-win32.whl", hash = "sha256:7923470d6056a9590247ff729c05e8e0f06bbd4efa6569c916943cb2d9b68b91"}, + {file = "regex-2023.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:4035d6945cb961c90c3e1c1ca2feb526175bcfed44dfb1cc77db4fdced060d3e"}, + {file = "regex-2023.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50fd2d9b36938d4dcecbd684777dd12a407add4f9f934f235c66372e630772b0"}, + {file = "regex-2023.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d19e57f888b00cd04fc38f5e18d0efbd91ccba2d45039453ab2236e6eec48d4d"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd966475e963122ee0a7118ec9024388c602d12ac72860f6eea119a3928be053"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db09e6c18977a33fea26fe67b7a842f706c67cf8bda1450974d0ae0dd63570df"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6164d4e2a82f9ebd7752a06bd6c504791bedc6418c0196cd0a23afb7f3e12b2d"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84397d3f750d153ebd7f958efaa92b45fea170200e2df5e0e1fd4d85b7e3f58a"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c3efee9bb53cbe7b285760c81f28ac80dc15fa48b5fe7e58b52752e642553f1"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:144b5b017646b5a9392a5554a1e5db0000ae637be4971c9747566775fc96e1b2"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1189fbbb21e2c117fda5303653b61905aeeeea23de4a94d400b0487eb16d2d60"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f83fe9e10f9d0b6cf580564d4d23845b9d692e4c91bd8be57733958e4c602956"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:72aa4746993a28c841e05889f3f1b1e5d14df8d3daa157d6001a34c98102b393"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:de2f780c3242ea114dd01f84848655356af4dd561501896c751d7b885ea6d3a1"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:290fd35219486dfbc00b0de72f455ecdd63e59b528991a6aec9fdfc0ce85672e"}, + {file = "regex-2023.5.5-cp39-cp39-win32.whl", hash = "sha256:732176f5427e72fa2325b05c58ad0b45af341c459910d766f814b0584ac1f9ac"}, + {file = "regex-2023.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:1307aa4daa1cbb23823d8238e1f61292fd07e4e5d8d38a6efff00b67a7cdb764"}, + {file = "regex-2023.5.5.tar.gz", hash = "sha256:7d76a8a1fc9da08296462a18f16620ba73bcbf5909e42383b253ef34d9d5141e"}, ] requests = [ - {file = "requests-2.29.0-py3-none-any.whl", hash = "sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b"}, - {file = "requests-2.29.0.tar.gz", hash = "sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, @@ -3998,7 +4011,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, @@ -4081,8 +4093,8 @@ soupsieve = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] sphinx = [ - {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, - {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, + {file = "Sphinx-7.0.1.tar.gz", hash = "sha256:61e025f788c5977d9412587e733733a289e2b9fdc2fef8868ddfbfc4ccfe881d"}, + {file = "sphinx-7.0.1-py3-none-any.whl", hash = "sha256:60c5e04756c1709a98845ed27a2eed7a556af3993afb66e77fec48189f742616"}, ] sphinx-click = [ {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, @@ -4113,47 +4125,47 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.47-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:dcfb480bfc9e1fab726003ae00a6bfc67a29bad275b63a4e36d17fe7f13a624e"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28fda5a69d6182589892422c5a9b02a8fd1125787aab1d83f1392aa955bf8d0a"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-win32.whl", hash = "sha256:45e799c1a41822eba6bee4e59b0e38764e1a1ee69873ab2889079865e9ea0e23"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-win_amd64.whl", hash = "sha256:10edbb92a9ef611f01b086e271a9f6c1c3e5157c3b0c5ff62310fb2187acbd4a"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7a4df53472c9030a8ddb1cce517757ba38a7a25699bbcabd57dcc8a5d53f324e"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:511d4abc823152dec49461209607bbfb2df60033c8c88a3f7c93293b8ecbb13d"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbe57f39f531c5d68d5594ea4613daa60aba33bb51a8cc42f96f17bbd6305e8d"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca8ab6748e3ec66afccd8b23ec2f92787a58d5353ce9624dccd770427ee67c82"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299b5c5c060b9fbe51808d0d40d8475f7b3873317640b9b7617c7f988cf59fda"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-win32.whl", hash = "sha256:684e5c773222781775c7f77231f412633d8af22493bf35b7fa1029fdf8066d10"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-win_amd64.whl", hash = "sha256:2bba39b12b879c7b35cde18b6e14119c5f1a16bd064a48dd2ac62d21366a5e17"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:795b5b9db573d3ed61fae74285d57d396829e3157642794d3a8f72ec2a5c719b"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:989c62b96596b7938cbc032e39431e6c2d81b635034571d6a43a13920852fb65"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b67bda733da1dcdccaf354e71ef01b46db483a4f6236450d3f9a61efdba35a"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-win32.whl", hash = "sha256:9a198f690ac12a3a807e03a5a45df6a30cd215935f237a46f4248faed62e69c8"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-win_amd64.whl", hash = "sha256:03be6f3cb66e69fb3a09b5ea89d77e4bc942f3bf84b207dba84666a26799c166"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:16ee6fea316790980779268da47a9260d5dd665c96f225d28e7750b0bb2e2a04"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557675e0befafa08d36d7a9284e8761c97490a248474d778373fb96b0d7fd8de"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb2797fee8a7914fb2c3dc7de404d3f96eb77f20fc60e9ee38dc6b0ca720f2c2"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28297aa29e035f29cba6b16aacd3680fbc6a9db682258d5f2e7b49ec215dbe40"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-win32.whl", hash = "sha256:998e782c8d9fd57fa8704d149ccd52acf03db30d7dd76f467fd21c1c21b414fa"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-win_amd64.whl", hash = "sha256:dde4d02213f1deb49eaaf8be8a6425948963a7af84983b3f22772c63826944de"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e98ef1babe34f37f443b7211cd3ee004d9577a19766e2dbacf62fce73c76245a"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14a3879853208a242b5913f3a17c6ac0eae9dc210ff99c8f10b19d4a1ed8ed9b"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7120a2f72599d4fed7c001fa1cbbc5b4d14929436135768050e284f53e9fbe5e"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:048509d7f3ac27b83ad82fd96a1ab90a34c8e906e4e09c8d677fc531d12c23c5"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-win32.whl", hash = "sha256:6572d7c96c2e3e126d0bb27bfb1d7e2a195b68d951fcc64c146b94f088e5421a"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-win_amd64.whl", hash = "sha256:a6c3929df5eeaf3867724003d5c19fed3f0c290f3edc7911616616684f200ecf"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71d4bf7768169c4502f6c2b0709a02a33703544f611810fb0c75406a9c576ee1"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd45c60cc4f6d68c30d5179e2c2c8098f7112983532897566bb69c47d87127d3"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fdbb8e9d4e9003f332a93d6a37bca48ba8095086c97a89826a136d8eddfc455"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f216a51451a0a0466e082e163591f6dcb2f9ec182adb3f1f4b1fd3688c7582c"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-win32.whl", hash = "sha256:bd988b3362d7e586ef581eb14771bbb48793a4edb6fcf62da75d3f0f3447060b"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-win_amd64.whl", hash = "sha256:32ab09f2863e3de51529aa84ff0e4fe89a2cb1bfbc11e225b6dbc60814e44c94"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:07764b240645627bc3e82596435bd1a1884646bfc0721642d24c26b12f1df194"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e2a42017984099ef6f56438a6b898ce0538f6fadddaa902870c5aa3e1d82583"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b6d807c76c20b4bc143a49ad47782228a2ac98bdcdcb069da54280e138847fc"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a94632ba26a666e7be0a7d7cc3f7acab622a04259a3aa0ee50ff6d44ba9df0d"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-win32.whl", hash = "sha256:f80915681ea9001f19b65aee715115f2ad310730c8043127cf3e19b3009892dd"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-win_amd64.whl", hash = "sha256:fc700b862e0a859a37faf85367e205e7acaecae5a098794aff52fdd8aea77b12"}, - {file = "SQLAlchemy-1.4.47.tar.gz", hash = "sha256:95fc02f7fc1f3199aaa47a8a757437134cf618e9d994c84effd53f530c38586f"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4bac3aa3c3d8bc7408097e6fe8bf983caa6e9491c5d2e2488cfcfd8106f13b6a"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:dbcae0e528d755f4522cad5842f0942e54b578d79f21a692c44d91352ea6d64e"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-win32.whl", hash = "sha256:cbbe8b8bffb199b225d2fe3804421b7b43a0d49983f81dc654d0431d2f855543"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-win_amd64.whl", hash = "sha256:627e04a5d54bd50628fc8734d5fc6df2a1aa5962f219c44aad50b00a6cdcf965"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9af1db7a287ef86e0f5cd990b38da6bd9328de739d17e8864f1817710da2d217"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ce7915eecc9c14a93b73f4e1c9d779ca43e955b43ddf1e21df154184f39748e5"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5381ddd09a99638f429f4cbe1b71b025bed318f6a7b23e11d65f3eed5e181c33"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:87609f6d4e81a941a17e61a4c19fee57f795e96f834c4f0a30cee725fc3f81d9"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb0808ad34167f394fea21bd4587fc62f3bd81bba232a1e7fbdfa17e6cfa7cd7"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-win32.whl", hash = "sha256:d53cd8bc582da5c1c8c86b6acc4ef42e20985c57d0ebc906445989df566c5603"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-win_amd64.whl", hash = "sha256:4355e5915844afdc5cf22ec29fba1010166e35dd94a21305f49020022167556b"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:066c2b0413e8cb980e6d46bf9d35ca83be81c20af688fedaef01450b06e4aa5e"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99bf13e07140601d111a7c6f1fc1519914dd4e5228315bbda255e08412f61a4"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee26276f12614d47cc07bc85490a70f559cba965fb178b1c45d46ffa8d73fda"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-win32.whl", hash = "sha256:49c312bcff4728bffc6fb5e5318b8020ed5c8b958a06800f91859fe9633ca20e"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-win_amd64.whl", hash = "sha256:cef2e2abc06eab187a533ec3e1067a71d7bbec69e582401afdf6d8cad4ba3515"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:3509159e050bd6d24189ec7af373359f07aed690db91909c131e5068176c5a5d"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc2ab4d9f6d9218a5caa4121bdcf1125303482a1cdcfcdbd8567be8518969c0"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1ddbbcef9bcedaa370c03771ebec7e39e3944782bef49e69430383c376a250b"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f82d8efea1ca92b24f51d3aea1a82897ed2409868a0af04247c8c1e4fef5890"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-win32.whl", hash = "sha256:e3e98d4907805b07743b583a99ecc58bf8807ecb6985576d82d5e8ae103b5272"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-win_amd64.whl", hash = "sha256:25887b4f716e085a1c5162f130b852f84e18d2633942c8ca40dfb8519367c14f"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:0817c181271b0ce5df1aa20949f0a9e2426830fed5ecdcc8db449618f12c2730"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe1dd2562313dd9fe1778ed56739ad5d9aae10f9f43d9f4cf81d65b0c85168bb"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:68413aead943883b341b2b77acd7a7fe2377c34d82e64d1840860247cec7ff7c"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbde5642104ac6e95f96e8ad6d18d9382aa20672008cf26068fe36f3004491df"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-win32.whl", hash = "sha256:11c6b1de720f816c22d6ad3bbfa2f026f89c7b78a5c4ffafb220e0183956a92a"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-win_amd64.whl", hash = "sha256:eb5464ee8d4bb6549d368b578e9529d3c43265007193597ddca71c1bae6174e6"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:92e6133cf337c42bfee03ca08c62ba0f2d9695618c8abc14a564f47503157be9"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d29a3fc6d9c45962476b470a81983dd8add6ad26fdbfae6d463b509d5adcda"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:005e942b451cad5285015481ae4e557ff4154dde327840ba91b9ac379be3b6ce"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c8cfe951ed074ba5e708ed29c45397a95c4143255b0d022c7c8331a75ae61f3"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-win32.whl", hash = "sha256:2b9af65cc58726129d8414fc1a1a650dcdd594ba12e9c97909f1f57d48e393d3"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-win_amd64.whl", hash = "sha256:2b562e9d1e59be7833edf28b0968f156683d57cabd2137d8121806f38a9d58f4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a1fc046756cf2a37d7277c93278566ddf8be135c6a58397b4c940abf837011f4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d9b55252d2ca42a09bcd10a697fa041e696def9dfab0b78c0aaea1485551a08"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6dab89874e72a9ab5462997846d4c760cdb957958be27b03b49cf0de5e5c327c"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd8b5ee5a3acc4371f820934b36f8109ce604ee73cc668c724abb054cebcb6e"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-win32.whl", hash = "sha256:eee09350fd538e29cfe3a496ec6f148504d2da40dbf52adefb0d2f8e4d38ccc4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-win_amd64.whl", hash = "sha256:7ad2b0f6520ed5038e795cc2852eb5c1f20fa6831d73301ced4aafbe3a10e1f6"}, + {file = "SQLAlchemy-1.4.48.tar.gz", hash = "sha256:b47bc287096d989a0838ce96f7d8e966914a24da877ed41a7531d44b55cdb8df"}, ] sqlalchemy-utils = [ {file = "SQLAlchemy-Utils-0.38.3.tar.gz", hash = "sha256:9f9afba607a40455cf703adfa9846584bf26168a0c5a60a70063b70d65051f4d"}, @@ -4200,17 +4212,17 @@ toolz = [ {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, ] tornado = [ - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:db181eb3df8738613ff0a26f49e1b394aade05034b01200a63e9662f347d4415"}, - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b4e7b956f9b5e6f9feb643ea04f07e7c6b49301e03e0023eedb01fa8cf52f579"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661aa8bc0e9d83d757cd95b6f6d1ece8ca9fd1ccdd34db2de381e25bf818233"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81c17e0cc396908a5e25dc8e9c5e4936e6dfd544c9290be48bd054c79bcad51e"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27a1cfa9997923f80bdd962b3aab048ac486ad8cfb2f237964f8ab7f7eb824b"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d7117f3c7ba5d05813b17a1f04efc8e108a1b811ccfddd9134cc68553c414864"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:ffdce65a281fd708da5a9def3bfb8f364766847fa7ed806821a69094c9629e8a"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:90f569a35a8ec19bde53aa596952071f445da678ec8596af763b9b9ce07605e6"}, - {file = "tornado-6.3.1-cp38-abi3-win32.whl", hash = "sha256:3455133b9ff262fd0a75630af0a8ee13564f25fb4fd3d9ce239b8a7d3d027bf8"}, - {file = "tornado-6.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:1285f0691143f7ab97150831455d4db17a267b59649f7bd9700282cba3d5e771"}, - {file = "tornado-6.3.1.tar.gz", hash = "sha256:5e2f49ad371595957c50e42dd7e5c14d64a6843a3cf27352b69c706d1b5918af"}, + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, + {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, + {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, + {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, ] tqdm = [ {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, @@ -4221,16 +4233,16 @@ traitlets = [ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.6.1-py3-none-any.whl", hash = "sha256:6bac751f4789b135c43228e72de18637e9a6c29d12777023a703fd1a6858469f"}, + {file = "typing_extensions-4.6.1.tar.gz", hash = "sha256:558bc0c4145f01e6405f4a5fdbd82050bd221b119f4bf72a961a1cfd471349d6"}, ] tzdata = [ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] tzlocal = [ - {file = "tzlocal-4.3-py3-none-any.whl", hash = "sha256:b44c4388f3d34f25862cfbb387578a4d70fec417649da694a132f628a23367e2"}, - {file = "tzlocal-4.3.tar.gz", hash = "sha256:3f21d09e1b2aa9f2dacca12da240ca37de3ba5237a93addfd6d593afe9073355"}, + {file = "tzlocal-5.0.1-py3-none-any.whl", hash = "sha256:f3596e180296aaf2dbd97d124fe76ae3a0e3d32b258447de7b939b3fd4be992f"}, + {file = "tzlocal-5.0.1.tar.gz", hash = "sha256:46eb99ad4bdb71f3f72b7d24f4267753e240944ecfc16f25d2719ba89827a803"}, ] uri-template = [ {file = "uri_template-1.2.0-py3-none-any.whl", hash = "sha256:f1699c77b73b925cf4937eae31ab282a86dc885c333f2e942513f08f691fc7db"}, @@ -4241,10 +4253,10 @@ uritemplate = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] urllib3 = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, ] -uWSGI = [ +uwsgi = [ {file = "uwsgi-2.0.21.tar.gz", hash = "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9"}, ] wcwidth = [ @@ -4260,8 +4272,8 @@ webencodings = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.5.1.tar.gz", hash = "sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40"}, - {file = "websocket_client-1.5.1-py3-none-any.whl", hash = "sha256:cdf5877568b7e83aa7cf2244ab56a3213de587bbe0ce9d8b9600fc77b455d89e"}, + {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, + {file = "websocket_client-1.5.2-py3-none-any.whl", hash = "sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1"}, ] werkzeug = [ {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, diff --git a/pyproject.toml b/pyproject.toml index e053f9899..97f173092 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,9 @@ black = "^22.6.0" mypy = "^0.982" pylint = "^2.16.1" +[tool.poetry.group.aws] +optional = true + [tool.poetry.group.aws.dependencies] uWSGI = "^2.0.21" From 26b96c7cf1bbf13133fb3c55e8eb0b46981a3e4d Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 24 May 2023 09:46:54 -0700 Subject: [PATCH 586/615] update `schematic_db` version --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e053f9899..40452dcd1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -70,7 +70,7 @@ Flask-Cors = "^3.0.10" pdoc = "^12.2.0" dateparser = "^1.1.4" pandarallel = "^1.6.4" -schematic-db = {version = "^0.0.6", extras = ["synapse"]} +schematic-db = {version = "^0.0.20", extras = ["synapse"]} pyopenssl = "^23.0.0" [tool.poetry.dev-dependencies] From bc28c532eb50e57fa8fef56181256faa5e72450e Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 24 May 2023 09:47:05 -0700 Subject: [PATCH 587/615] make aws group optional --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 40452dcd1..ecedc8dde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -83,6 +83,9 @@ black = "^22.6.0" mypy = "^0.982" pylint = "^2.16.1" +[tool.poetry.group.aws] +optional = true + [tool.poetry.group.aws.dependencies] uWSGI = "^2.0.21" From 37b66d84a5e5be8448f388844a04080368ffbc65 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 24 May 2023 09:47:08 -0700 Subject: [PATCH 588/615] Update poetry.lock --- poetry.lock | 740 +++++++++++++++++++++++++++++----------------------- 1 file changed, 410 insertions(+), 330 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0382be33e..c1f9bfeb9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -94,9 +94,9 @@ python-dateutil = ">=2.7.0" [[package]] name = "astroid" -version = "2.15.4" +version = "2.15.5" description = "An abstract syntax tree for Python with inference support." -category = "main" +category = "dev" optional = false python-versions = ">=3.7.2" @@ -169,7 +169,7 @@ lxml = ["lxml"] name = "black" version = "22.12.0" description = "The uncompromising code formatter." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -212,7 +212,7 @@ python-versions = "~=3.7" [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." category = "main" optional = false @@ -324,7 +324,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14 [[package]] name = "coverage" -version = "7.2.3" +version = "7.2.6" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -427,7 +427,7 @@ graph = ["objgraph (>=1.7.2)"] [[package]] name = "docutils" -version = "0.19" +version = "0.20.1" description = "Docutils -- Python Documentation Utilities" category = "main" optional = false @@ -453,7 +453,7 @@ python-versions = ">=3.6" name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -473,7 +473,7 @@ tests = ["asttokens", "littleutils", "pytest", "rich"] [[package]] name = "fastjsonschema" -version = "2.16.3" +version = "2.17.1" description = "Fastest Python implementation of JSON schema" category = "main" optional = false @@ -570,7 +570,7 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.17.3" +version = "2.18.1" description = "Google Authentication Library" category = "main" optional = false @@ -581,6 +581,7 @@ cachetools = ">=2.0.0,<6.0" pyasn1-modules = ">=0.2.1" rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} six = ">=1.9.0" +urllib3 = "<2.0" [package.extras] aiohttp = ["aiohttp (>=3.6.2,<4.0.0dev)", "requests (>=2.20.0,<3.0.0dev)"] @@ -782,13 +783,35 @@ python-versions = ">=3.5" name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" +[[package]] +name = "interrogate" +version = "1.5.0" +description = "Interrogate a codebase for docstring coverage." +category = "main" +optional = false +python-versions = ">=3.6" + +[package.dependencies] +attrs = "*" +click = ">=7.1" +colorama = "*" +py = "*" +tabulate = "*" +toml = "*" + +[package.extras] +dev = ["cairosvg", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "sphinx", "sphinx-autobuild", "wheel"] +docs = ["sphinx", "sphinx-autobuild"] +png = ["cairosvg"] +tests = ["pytest", "pytest-cov", "pytest-mock"] + [[package]] name = "ipykernel" -version = "6.22.0" +version = "6.23.1" description = "IPython Kernel for Jupyter" category = "main" optional = false @@ -818,11 +841,11 @@ test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio" [[package]] name = "ipython" -version = "8.12.0" +version = "8.13.2" description = "IPython: Productive Interactive Computing" category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} @@ -904,7 +927,7 @@ arrow = ">=0.15.0" name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." -category = "main" +category = "dev" optional = false python-versions = ">=3.8.0" @@ -1166,7 +1189,7 @@ testing = ["backports.unittest-mock", "collective.checkdocs", "fs (>=0.5,<2)", " name = "lazy-object-proxy" version = "1.9.0" description = "A fast and thorough lazy object proxy." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -1218,7 +1241,7 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "main" +category = "dev" optional = false python-versions = ">=3.6" @@ -1234,7 +1257,7 @@ python-versions = "*" name = "mypy" version = "0.982" description = "Optional static typing for Python" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -1252,13 +1275,13 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" +category = "dev" optional = false python-versions = ">=3.5" [[package]] name = "nbclassic" -version = "0.5.6" +version = "1.0.0" description = "Jupyter Notebook as a Jupyter Server extension." category = "main" optional = false @@ -1290,26 +1313,26 @@ test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-p [[package]] name = "nbclient" -version = "0.7.4" +version = "0.8.0" description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." category = "main" optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" [package.dependencies] jupyter-client = ">=6.1.12" jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" nbformat = ">=5.1" -traitlets = ">=5.3" +traitlets = ">=5.4" [package.extras] dev = ["pre-commit"] docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] -test = ["flaky", "ipykernel", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] [[package]] name = "nbconvert" -version = "7.3.1" +version = "7.4.0" description = "Converting Jupyter Notebooks" category = "main" optional = false @@ -1485,11 +1508,11 @@ python-versions = ">=3.7" [[package]] name = "pandarallel" -version = "1.6.4" +version = "1.6.5" description = "An easy to use library to speed up computation (by parallelizing on multi CPUs) with pandas." category = "main" optional = false -python-versions = "*" +python-versions = ">=3.7" [package.dependencies] dill = ">=0.3.1" @@ -1543,7 +1566,7 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.11.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -1584,21 +1607,21 @@ python-versions = "*" [[package]] name = "platformdirs" -version = "3.4.0" +version = "3.5.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = ">=3.7" [package.extras] -docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] +docs = ["furo (>=2023.3.27)", "proselint (>=0.13)", "sphinx (>=6.2.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.3.1)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] [[package]] name = "pluggy" version = "1.0.0" description = "plugin and hook calling mechanisms for python" -category = "main" +category = "dev" optional = false python-versions = ">=3.6" @@ -1630,7 +1653,7 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.22.3" +version = "4.23.1" description = "" category = "main" optional = false @@ -1666,6 +1689,14 @@ python-versions = "*" [package.extras] tests = ["pytest"] +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +category = "main" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" + [[package]] name = "pyasn1" version = "0.5.0" @@ -1703,7 +1734,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pydantic" -version = "1.10.7" +version = "1.10.8" description = "Data validation and settings management using python type hints" category = "main" optional = false @@ -1752,9 +1783,9 @@ pandas = ["pandas (>=0.14.0)"] [[package]] name = "pylint" -version = "2.17.3" +version = "2.17.4" description = "python code static checker" -category = "main" +category = "dev" optional = false python-versions = ">=3.7.2" @@ -1811,7 +1842,7 @@ python-versions = ">=3.7" name = "pytest" version = "7.3.1" description = "pytest: simple powerful testing with Python" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -1845,7 +1876,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "pytest-mock" version = "3.10.0" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -1893,17 +1924,6 @@ category = "main" optional = false python-versions = "*" -[[package]] -name = "pytz-deprecation-shim" -version = "0.1.0.post0" -description = "Shims to make deprecation of pytz easier" -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" - -[package.dependencies] -tzdata = {version = "*", markers = "python_version >= \"3.6\""} - [[package]] name = "pywin32" version = "306" @@ -1967,15 +1987,15 @@ networkx = ["networkx (>=2.0.0,<3.0.0)"] [[package]] name = "regex" -version = "2023.3.23" +version = "2023.5.5" description = "Alternative regular expression module, to replace re." category = "main" optional = false -python-versions = ">=3.8" +python-versions = ">=3.6" [[package]] name = "requests" -version = "2.29.0" +version = "2.31.0" description = "Python HTTP for Humans." category = "main" optional = false @@ -1985,7 +2005,7 @@ python-versions = ">=3.7" certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] @@ -2061,31 +2081,29 @@ python-versions = ">=3.5" [[package]] name = "schematic-db" -version = "0.0.6" +version = "0.0.20" description = "" category = "main" optional = false python-versions = ">=3.9,<4.0" [package.dependencies] -black = ">=22.6.0,<23.0.0" -mypy = ">=0.982,<0.983" +interrogate = ">=1.5.0,<2.0.0" networkx = ">=2.8.6,<3.0.0" pandas = ">=1.4.3,<2.0.0" -pdoc = ">=12.1.0,<13.0.0" -pylint = ">=2.15.4,<3.0.0" -pytest-mock = ">=3.10.0,<4.0.0" +pydantic = ">=1.10.7,<2.0.0" PyYAML = ">=6.0,<7.0" requests = ">=2.28.1,<3.0.0" SQLAlchemy = ">=1.4.39,<2.0.0" SQLAlchemy-Utils = ">=0.38.3,<0.39.0" -synapseclient = {version = ">=2.6.0,<3.0.0", optional = true, markers = "extra == \"synapse\""} +synapseclient = {version = ">=2.7.0,<3.0.0", optional = true, markers = "extra == \"synapse\""} tenacity = ">=8.1.0,<9.0.0" +validators = ">=0.20.0,<0.21.0" [package.extras] mysql = ["mysqlclient (>=2.1.1,<3.0.0)"] -postgres = ["psycopg2 (>=2.9.5,<3.0.0)"] -synapse = ["synapseclient (>=2.6.0,<3.0.0)"] +postgres = ["psycopg2-binary (>=2.9.5,<3.0.0)"] +synapse = ["synapseclient (>=2.7.0,<3.0.0)"] [[package]] name = "scipy" @@ -2175,7 +2193,7 @@ python-versions = ">=3.7" [[package]] name = "sphinx" -version = "6.2.1" +version = "7.0.1" description = "Python documentation generator" category = "main" optional = false @@ -2185,7 +2203,7 @@ python-versions = ">=3.8" alabaster = ">=0.7,<0.8" babel = ">=2.9" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.18.1,<0.20" +docutils = ">=0.18.1,<0.21" imagesize = ">=1.3" importlib-metadata = {version = ">=4.8", markers = "python_version < \"3.10\""} Jinja2 = ">=3.0" @@ -2291,7 +2309,7 @@ test = ["pytest"] [[package]] name = "sqlalchemy" -version = "1.4.47" +version = "1.4.48" description = "Database Abstraction Library" category = "main" optional = false @@ -2395,6 +2413,17 @@ pandas = ["pandas (>=0.25.0,<1.5)"] pysftp = ["pysftp (>=0.2.8,<0.3)"] tests = ["flake8 (>=3.7.0,<4.0)", "pytest (>=5.0.0,<7.0)", "pytest-mock (>=3.0,<4.0)", "pytest-xdist[psutil] (>=2.2,<3.0.0)"] +[[package]] +name = "tabulate" +version = "0.9.0" +description = "Pretty-print tabular data" +category = "main" +optional = false +python-versions = ">=3.7" + +[package.extras] +widechars = ["wcwidth"] + [[package]] name = "tenacity" version = "8.2.2" @@ -2450,7 +2479,7 @@ python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -2458,7 +2487,7 @@ python-versions = ">=3.7" name = "tomlkit" version = "0.11.8" description = "Style preserving TOML library" -category = "main" +category = "dev" optional = false python-versions = ">=3.7" @@ -2472,7 +2501,7 @@ python-versions = ">=3.5" [[package]] name = "tornado" -version = "6.3.1" +version = "6.3.2" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." category = "main" optional = false @@ -2509,7 +2538,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.5.0" +version = "4.6.1" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -2525,14 +2554,13 @@ python-versions = ">=2" [[package]] name = "tzlocal" -version = "4.3" +version = "5.0.1" description = "tzinfo object for the local timezone" category = "main" optional = false python-versions = ">=3.7" [package.dependencies] -pytz-deprecation-shim = "*" tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] @@ -2559,7 +2587,7 @@ python-versions = ">=3.6" [[package]] name = "urllib3" -version = "1.26.15" +version = "1.26.16" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "main" optional = false @@ -2571,13 +2599,27 @@ secure = ["certifi", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "ipaddress", "p socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] [[package]] -name = "uWSGI" +name = "uwsgi" version = "2.0.21" description = "The uWSGI server" category = "dev" optional = false python-versions = "*" +[[package]] +name = "validators" +version = "0.20.0" +description = "Python Data Validation for Humans™." +category = "main" +optional = false +python-versions = ">=3.4" + +[package.dependencies] +decorator = ">=3.4.0" + +[package.extras] +test = ["flake8 (>=2.4.0)", "isort (>=4.2.2)", "pytest (>=2.2.3)"] + [[package]] name = "wcwidth" version = "0.2.6" @@ -2608,7 +2650,7 @@ python-versions = "*" [[package]] name = "websocket-client" -version = "1.5.1" +version = "1.5.2" description = "WebSocket client for Python with low level API options" category = "main" optional = false @@ -2661,7 +2703,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "93b3630734394087f4d3ddcefb848a937b7752a9660bdb35b6766fc699773050" +content-hash = "f1c0bda7dea6b5a2f118f98866b3502f8877ce1ed57c66797b2137a48278dc58" [metadata.files] alabaster = [ @@ -2712,8 +2754,8 @@ arrow = [ {file = "arrow-1.2.3.tar.gz", hash = "sha256:3934b30ca1b9f292376d9db15b19446088d12ec58629bc3f0da28fd55fb633a1"}, ] astroid = [ - {file = "astroid-2.15.4-py3-none-any.whl", hash = "sha256:a1b8543ef9d36ea777194bc9b17f5f8678d2c56ee6a45b2c2f17eec96f242347"}, - {file = "astroid-2.15.4.tar.gz", hash = "sha256:c81e1c7fbac615037744d067a9bb5f9aeb655edf59b63ee8b59585475d6f80d8"}, + {file = "astroid-2.15.5-py3-none-any.whl", hash = "sha256:078e5212f9885fa85fbb0cf0101978a336190aadea6e13305409d099f71b2324"}, + {file = "astroid-2.15.5.tar.gz", hash = "sha256:1039262575027b441137ab4a62a793a9b43defb42c32d5670f38686207cd780f"}, ] asttokens = [ {file = "asttokens-2.2.1-py2.py3-none-any.whl", hash = "sha256:6b0ac9e93fb0335014d382b8fa9b3afa7df546984258005da0b9e7095b3deb1c"}, @@ -2758,8 +2800,8 @@ cachetools = [ {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, ] certifi = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] cffi = [ {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, @@ -2929,57 +2971,57 @@ connexion = [ {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.2.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e58c0d41d336569d63d1b113bd573db8363bc4146f39444125b7f8060e4e04f5"}, - {file = "coverage-7.2.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:344e714bd0fe921fc72d97404ebbdbf9127bac0ca1ff66d7b79efc143cf7c0c4"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:974bc90d6f6c1e59ceb1516ab00cf1cdfbb2e555795d49fa9571d611f449bcb2"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0743b0035d4b0e32bc1df5de70fba3059662ace5b9a2a86a9f894cfe66569013"}, - {file = "coverage-7.2.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d0391fb4cfc171ce40437f67eb050a340fdbd0f9f49d6353a387f1b7f9dd4fa"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4a42e1eff0ca9a7cb7dc9ecda41dfc7cbc17cb1d02117214be0561bd1134772b"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:be19931a8dcbe6ab464f3339966856996b12a00f9fe53f346ab3be872d03e257"}, - {file = "coverage-7.2.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:72fcae5bcac3333a4cf3b8f34eec99cea1187acd55af723bcbd559adfdcb5535"}, - {file = "coverage-7.2.3-cp310-cp310-win32.whl", hash = "sha256:aeae2aa38395b18106e552833f2a50c27ea0000122bde421c31d11ed7e6f9c91"}, - {file = "coverage-7.2.3-cp310-cp310-win_amd64.whl", hash = "sha256:83957d349838a636e768251c7e9979e899a569794b44c3728eaebd11d848e58e"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfd393094cd82ceb9b40df4c77976015a314b267d498268a076e940fe7be6b79"}, - {file = "coverage-7.2.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:182eb9ac3f2b4874a1f41b78b87db20b66da6b9cdc32737fbbf4fea0c35b23fc"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bb1e77a9a311346294621be905ea8a2c30d3ad371fc15bb72e98bfcfae532df"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca0f34363e2634deffd390a0fef1aa99168ae9ed2af01af4a1f5865e362f8623"}, - {file = "coverage-7.2.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55416d7385774285b6e2a5feca0af9652f7f444a4fa3d29d8ab052fafef9d00d"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:06ddd9c0249a0546997fdda5a30fbcb40f23926df0a874a60a8a185bc3a87d93"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:fff5aaa6becf2c6a1699ae6a39e2e6fb0672c2d42eca8eb0cafa91cf2e9bd312"}, - {file = "coverage-7.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea53151d87c52e98133eb8ac78f1206498c015849662ca8dc246255265d9c3c4"}, - {file = "coverage-7.2.3-cp311-cp311-win32.whl", hash = "sha256:8f6c930fd70d91ddee53194e93029e3ef2aabe26725aa3c2753df057e296b925"}, - {file = "coverage-7.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:fa546d66639d69aa967bf08156eb8c9d0cd6f6de84be9e8c9819f52ad499c910"}, - {file = "coverage-7.2.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b2317d5ed777bf5a033e83d4f1389fd4ef045763141d8f10eb09a7035cee774c"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be9824c1c874b73b96288c6d3de793bf7f3a597770205068c6163ea1f326e8b9"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2c3b2803e730dc2797a017335827e9da6da0e84c745ce0f552e66400abdfb9a1"}, - {file = "coverage-7.2.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f69770f5ca1994cb32c38965e95f57504d3aea96b6c024624fdd5bb1aa494a1"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1127b16220f7bfb3f1049ed4a62d26d81970a723544e8252db0efde853268e21"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa784405f0c640940595fa0f14064d8e84aff0b0f762fa18393e2760a2cf5841"}, - {file = "coverage-7.2.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3146b8e16fa60427e03884301bf8209221f5761ac754ee6b267642a2fd354c48"}, - {file = "coverage-7.2.3-cp37-cp37m-win32.whl", hash = "sha256:1fd78b911aea9cec3b7e1e2622c8018d51c0d2bbcf8faaf53c2497eb114911c1"}, - {file = "coverage-7.2.3-cp37-cp37m-win_amd64.whl", hash = "sha256:0f3736a5d34e091b0a611964c6262fd68ca4363df56185902528f0b75dbb9c1f"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:981b4df72c93e3bc04478153df516d385317628bd9c10be699c93c26ddcca8ab"}, - {file = "coverage-7.2.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0045f8f23a5fb30b2eb3b8a83664d8dc4fb58faddf8155d7109166adb9f2040"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f760073fcf8f3d6933178d67754f4f2d4e924e321f4bb0dcef0424ca0215eba1"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c86bd45d1659b1ae3d0ba1909326b03598affbc9ed71520e0ff8c31a993ad911"}, - {file = "coverage-7.2.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172db976ae6327ed4728e2507daf8a4de73c7cc89796483e0a9198fd2e47b462"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:d2a3a6146fe9319926e1d477842ca2a63fe99af5ae690b1f5c11e6af074a6b5c"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f649dd53833b495c3ebd04d6eec58479454a1784987af8afb77540d6c1767abd"}, - {file = "coverage-7.2.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:7c4ed4e9f3b123aa403ab424430b426a1992e6f4c8fd3cb56ea520446e04d152"}, - {file = "coverage-7.2.3-cp38-cp38-win32.whl", hash = "sha256:eb0edc3ce9760d2f21637766c3aa04822030e7451981ce569a1b3456b7053f22"}, - {file = "coverage-7.2.3-cp38-cp38-win_amd64.whl", hash = "sha256:63cdeaac4ae85a179a8d6bc09b77b564c096250d759eed343a89d91bce8b6367"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:20d1a2a76bb4eb00e4d36b9699f9b7aba93271c9c29220ad4c6a9581a0320235"}, - {file = "coverage-7.2.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ea748802cc0de4de92ef8244dd84ffd793bd2e7be784cd8394d557a3c751e21"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21b154aba06df42e4b96fc915512ab39595105f6c483991287021ed95776d934"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd214917cabdd6f673a29d708574e9fbdb892cb77eb426d0eae3490d95ca7859"}, - {file = "coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c2e58e45fe53fab81f85474e5d4d226eeab0f27b45aa062856c89389da2f0d9"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:87ecc7c9a1a9f912e306997ffee020297ccb5ea388421fe62a2a02747e4d5539"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:387065e420aed3c71b61af7e82c7b6bc1c592f7e3c7a66e9f78dd178699da4fe"}, - {file = "coverage-7.2.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ea3f5bc91d7d457da7d48c7a732beaf79d0c8131df3ab278e6bba6297e23c6c4"}, - {file = "coverage-7.2.3-cp39-cp39-win32.whl", hash = "sha256:ae7863a1d8db6a014b6f2ff9c1582ab1aad55a6d25bac19710a8df68921b6e30"}, - {file = "coverage-7.2.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f04becd4fcda03c0160d0da9c8f0c246bc78f2f7af0feea1ec0930e7c93fa4a"}, - {file = "coverage-7.2.3-pp37.pp38.pp39-none-any.whl", hash = "sha256:965ee3e782c7892befc25575fa171b521d33798132692df428a09efacaffe8d0"}, - {file = "coverage-7.2.3.tar.gz", hash = "sha256:d298c2815fa4891edd9abe5ad6e6cb4207104c7dd9fd13aea3fdebf6f9b91259"}, + {file = "coverage-7.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec"}, + {file = "coverage-7.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd"}, + {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087"}, + {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80"}, + {file = "coverage-7.2.6-cp310-cp310-win32.whl", hash = "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec"}, + {file = "coverage-7.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"}, + {file = "coverage-7.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044"}, + {file = "coverage-7.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9"}, + {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636"}, + {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995"}, + {file = "coverage-7.2.6-cp311-cp311-win32.whl", hash = "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b"}, + {file = "coverage-7.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1"}, + {file = "coverage-7.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba"}, + {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8"}, + {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb"}, + {file = "coverage-7.2.6-cp37-cp37m-win32.whl", hash = "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473"}, + {file = "coverage-7.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110"}, + {file = "coverage-7.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1"}, + {file = "coverage-7.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0"}, + {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70"}, + {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8"}, + {file = "coverage-7.2.6-cp38-cp38-win32.whl", hash = "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5"}, + {file = "coverage-7.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd"}, + {file = "coverage-7.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478"}, + {file = "coverage-7.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9"}, + {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb"}, + {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6"}, + {file = "coverage-7.2.6-cp39-cp39-win32.whl", hash = "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb"}, + {file = "coverage-7.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783"}, + {file = "coverage-7.2.6-pp37.pp38.pp39-none-any.whl", hash = "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d"}, + {file = "coverage-7.2.6.tar.gz", hash = "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d"}, ] cryptography = [ {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, @@ -3043,8 +3085,8 @@ dill = [ {file = "dill-0.3.6.tar.gz", hash = "sha256:e5db55f3687856d8fbdab002ed78544e1c4559a130302693d839dfe8f93f2373"}, ] docutils = [ - {file = "docutils-0.19-py3-none-any.whl", hash = "sha256:5e1de4d849fee02c63b040a4a3fd567f4ab104defd8a5511fbbc24a8a017efbc"}, - {file = "docutils-0.19.tar.gz", hash = "sha256:33995a6753c30b7f577febfc2c50411fec6aac7f7ffeb7c4cfe5991072dcf9e6"}, + {file = "docutils-0.20.1-py3-none-any.whl", hash = "sha256:96f387a2c5562db4476f09f13bbab2192e764cac08ebbf3a34a95d9b1e4a59d6"}, + {file = "docutils-0.20.1.tar.gz", hash = "sha256:f08a4e276c3a1583a86dce3e34aba3fe04d02bba2dd51ed16106244e8a923e3b"}, ] entrypoints = [ {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, @@ -3063,8 +3105,8 @@ executing = [ {file = "executing-1.2.0.tar.gz", hash = "sha256:19da64c18d2d851112f09c287f8d3dbbdf725ab0e569077efb6cdcbd3497c107"}, ] fastjsonschema = [ - {file = "fastjsonschema-2.16.3-py3-none-any.whl", hash = "sha256:04fbecc94300436f628517b05741b7ea009506ce8f946d40996567c669318490"}, - {file = "fastjsonschema-2.16.3.tar.gz", hash = "sha256:4a30d6315a68c253cfa8f963b9697246315aa3db89f98b97235e345dedfb0b8e"}, + {file = "fastjsonschema-2.17.1-py3-none-any.whl", hash = "sha256:4b90b252628ca695280924d863fe37234eebadc29c5360d322571233dc9746e0"}, + {file = "fastjsonschema-2.17.1.tar.gz", hash = "sha256:f4eeb8a77cef54861dbf7424ac8ce71306f12cbb086c45131bcba2c6a4f726e3"}, ] flake8 = [ {file = "flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, @@ -3091,8 +3133,8 @@ google-api-python-client = [ {file = "google_api_python_client-2.86.0-py2.py3-none-any.whl", hash = "sha256:0f320190ab9d5bd2fdb0cb894e8e53bb5e17d4888ee8dc4d26ba65ce378409e2"}, ] google-auth = [ - {file = "google-auth-2.17.3.tar.gz", hash = "sha256:ce311e2bc58b130fddf316df57c9b3943c2a7b4f6ec31de9663a9333e4064efc"}, - {file = "google_auth-2.17.3-py2.py3-none-any.whl", hash = "sha256:f586b274d3eb7bd932ea424b1c702a30e0393a2e2bc4ca3eae8263ffd8be229f"}, + {file = "google-auth-2.18.1.tar.gz", hash = "sha256:d7a3249027e7f464fbbfd7ee8319a08ad09d2eea51578575c4bd360ffa049ccb"}, + {file = "google_auth-2.18.1-py2.py3-none-any.whl", hash = "sha256:55a395cdfd3f3dd3f649131d41f97c17b4ed8a2aac1be3502090c716314e8a37"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -3200,13 +3242,17 @@ iniconfig = [ {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, ] +interrogate = [ + {file = "interrogate-1.5.0-py3-none-any.whl", hash = "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a"}, + {file = "interrogate-1.5.0.tar.gz", hash = "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c"}, +] ipykernel = [ - {file = "ipykernel-6.22.0-py3-none-any.whl", hash = "sha256:1ae6047c1277508933078163721bbb479c3e7292778a04b4bacf0874550977d6"}, - {file = "ipykernel-6.22.0.tar.gz", hash = "sha256:302558b81f1bc22dc259fb2a0c5c7cf2f4c0bdb21b50484348f7bafe7fb71421"}, + {file = "ipykernel-6.23.1-py3-none-any.whl", hash = "sha256:77aeffab056c21d16f1edccdc9e5ccbf7d96eb401bd6703610a21be8b068aadc"}, + {file = "ipykernel-6.23.1.tar.gz", hash = "sha256:1aba0ae8453e15e9bc6b24e497ef6840114afcdb832ae597f32137fa19d42a6f"}, ] ipython = [ - {file = "ipython-8.12.0-py3-none-any.whl", hash = "sha256:1c183bf61b148b00bcebfa5d9b39312733ae97f6dad90d7e9b4d86c8647f498c"}, - {file = "ipython-8.12.0.tar.gz", hash = "sha256:a950236df04ad75b5bc7f816f9af3d74dc118fd42f2ff7e80e8e60ca1f182e2d"}, + {file = "ipython-8.13.2-py3-none-any.whl", hash = "sha256:ffca270240fbd21b06b2974e14a86494d6d29290184e788275f55e0b55914926"}, + {file = "ipython-8.13.2.tar.gz", hash = "sha256:7dff3fad32b97f6488e02f87b970f309d082f758d7b7fc252e3b19ee0e432dbb"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, @@ -3423,16 +3469,16 @@ mypy-extensions = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] nbclassic = [ - {file = "nbclassic-0.5.6-py3-none-any.whl", hash = "sha256:e3c8b7de80046c4a36a74662a5e325386d345289906c618366d8154e03dc2322"}, - {file = "nbclassic-0.5.6.tar.gz", hash = "sha256:aab53fa1bea084fb6ade5c538b011a4f070c69f88d72878a8e8fb356f152509f"}, + {file = "nbclassic-1.0.0-py3-none-any.whl", hash = "sha256:f99e4769b4750076cd4235c044b61232110733322384a94a63791d2e7beacc66"}, + {file = "nbclassic-1.0.0.tar.gz", hash = "sha256:0ae11eb2319455d805596bf320336cda9554b41d99ab9a3c31bf8180bffa30e3"}, ] nbclient = [ - {file = "nbclient-0.7.4-py3-none-any.whl", hash = "sha256:c817c0768c5ff0d60e468e017613e6eae27b6fa31e43f905addd2d24df60c125"}, - {file = "nbclient-0.7.4.tar.gz", hash = "sha256:d447f0e5a4cfe79d462459aec1b3dc5c2e9152597262be8ee27f7d4c02566a0d"}, + {file = "nbclient-0.8.0-py3-none-any.whl", hash = "sha256:25e861299e5303a0477568557c4045eccc7a34c17fc08e7959558707b9ebe548"}, + {file = "nbclient-0.8.0.tar.gz", hash = "sha256:f9b179cd4b2d7bca965f900a2ebf0db4a12ebff2f36a711cb66861e4ae158e55"}, ] nbconvert = [ - {file = "nbconvert-7.3.1-py3-none-any.whl", hash = "sha256:d2e95904666f1ff77d36105b9de4e0801726f93b862d5b28f69e93d99ad3b19c"}, - {file = "nbconvert-7.3.1.tar.gz", hash = "sha256:78685362b11d2e8058e70196fe83b09abed8df22d3e599cf271f4d39fdc48b9e"}, + {file = "nbconvert-7.4.0-py3-none-any.whl", hash = "sha256:af5064a9db524f9f12f4e8be7f0799524bd5b14c1adea37e34e83c95127cc818"}, + {file = "nbconvert-7.4.0.tar.gz", hash = "sha256:51b6c77b507b177b73f6729dba15676e42c4e92bcb00edc8cc982ee72e7d89d7"}, ] nbformat = [ {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, @@ -3501,7 +3547,7 @@ packaging = [ {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, ] pandarallel = [ - {file = "pandarallel-1.6.4.tar.gz", hash = "sha256:70091652485050241ffac37c3e94d21732697c63ee4613ae7bf85da076be41f2"}, + {file = "pandarallel-1.6.5.tar.gz", hash = "sha256:1c2df98ff6441e8ae13ff428ceebaa7ec42d731f7f972c41ce4fdef1d3adf640"}, ] pandas = [ {file = "pandas-1.5.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3749077d86e3a2f0ed51367f30bf5b82e131cc0f14260c4d3e499186fccc4406"}, @@ -3557,8 +3603,8 @@ pickleshare = [ {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] platformdirs = [ - {file = "platformdirs-3.4.0-py3-none-any.whl", hash = "sha256:01437886022decaf285d8972f9526397bfae2ac55480ed372ed6d9eca048870a"}, - {file = "platformdirs-3.4.0.tar.gz", hash = "sha256:a5e1536e5ea4b1c238a1364da17ff2993d5bd28e15600c2c8224008aff6bbcad"}, + {file = "platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {file = "platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] pluggy = [ {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, @@ -3573,19 +3619,19 @@ prompt-toolkit = [ {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, ] protobuf = [ - {file = "protobuf-4.22.3-cp310-abi3-win32.whl", hash = "sha256:8b54f56d13ae4a3ec140076c9d937221f887c8f64954673d46f63751209e839a"}, - {file = "protobuf-4.22.3-cp310-abi3-win_amd64.whl", hash = "sha256:7760730063329d42a9d4c4573b804289b738d4931e363ffbe684716b796bde51"}, - {file = "protobuf-4.22.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:d14fc1a41d1a1909998e8aff7e80d2a7ae14772c4a70e4bf7db8a36690b54425"}, - {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:70659847ee57a5262a65954538088a1d72dfc3e9882695cab9f0c54ffe71663b"}, - {file = "protobuf-4.22.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:13233ee2b9d3bd9a5f216c1fa2c321cd564b93d8f2e4f521a85b585447747997"}, - {file = "protobuf-4.22.3-cp37-cp37m-win32.whl", hash = "sha256:ecae944c6c2ce50dda6bf76ef5496196aeb1b85acb95df5843cd812615ec4b61"}, - {file = "protobuf-4.22.3-cp37-cp37m-win_amd64.whl", hash = "sha256:d4b66266965598ff4c291416be429cef7989d8fae88b55b62095a2331511b3fa"}, - {file = "protobuf-4.22.3-cp38-cp38-win32.whl", hash = "sha256:f08aa300b67f1c012100d8eb62d47129e53d1150f4469fd78a29fa3cb68c66f2"}, - {file = "protobuf-4.22.3-cp38-cp38-win_amd64.whl", hash = "sha256:f2f4710543abec186aee332d6852ef5ae7ce2e9e807a3da570f36de5a732d88e"}, - {file = "protobuf-4.22.3-cp39-cp39-win32.whl", hash = "sha256:7cf56e31907c532e460bb62010a513408e6cdf5b03fb2611e4b67ed398ad046d"}, - {file = "protobuf-4.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:e0e630d8e6a79f48c557cd1835865b593d0547dce221c66ed1b827de59c66c97"}, - {file = "protobuf-4.22.3-py3-none-any.whl", hash = "sha256:52f0a78141078077cfe15fe333ac3e3a077420b9a3f5d1bf9b5fe9d286b4d881"}, - {file = "protobuf-4.22.3.tar.gz", hash = "sha256:23452f2fdea754a8251d0fc88c0317735ae47217e0d27bf330a30eec2848811a"}, + {file = "protobuf-4.23.1-cp310-abi3-win32.whl", hash = "sha256:410bcc0a5b279f634d3e16082ce221dfef7c3392fac723500e2e64d1806dd2be"}, + {file = "protobuf-4.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:32e78beda26d7a101fecf15d7a4a792278a0d26a31bc327ff05564a9d68ab8ee"}, + {file = "protobuf-4.23.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9510cac91e764e86acd74e2b7f7bc5e6127a7f3fb646d7c8033cfb84fd1176a"}, + {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:346990f634272caac1f09efbcfbbacb23098b1f606d172534c6fa2d9758bb436"}, + {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3ce113b3f3362493bddc9069c2163a38f240a9ed685ff83e7bcb756b05e1deb0"}, + {file = "protobuf-4.23.1-cp37-cp37m-win32.whl", hash = "sha256:2036a3a1e7fc27f973fa0a7888dce712393af644f4695385f117886abc792e39"}, + {file = "protobuf-4.23.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3b8905eafe4439076e1f58e9d1fa327025fd2777cf90f14083092ae47f77b0aa"}, + {file = "protobuf-4.23.1-cp38-cp38-win32.whl", hash = "sha256:5b9cd6097e6acae48a68cb29b56bc79339be84eca65b486910bb1e7a30e2b7c1"}, + {file = "protobuf-4.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:decf119d54e820f298ee6d89c72d6b289ea240c32c521f00433f9dc420595f38"}, + {file = "protobuf-4.23.1-cp39-cp39-win32.whl", hash = "sha256:91fac0753c3c4951fbb98a93271c43cc7cf3b93cf67747b3e600bb1e5cc14d61"}, + {file = "protobuf-4.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac50be82491369a9ec3710565777e4da87c6d2e20404e0abb1f3a8f10ffd20f0"}, + {file = "protobuf-4.23.1-py3-none-any.whl", hash = "sha256:65f0ac96ef67d7dd09b19a46aad81a851b6f85f89725577f16de38f2d68ad477"}, + {file = "protobuf-4.23.1.tar.gz", hash = "sha256:95789b569418a3e32a53f43d7763be3d490a831e9c08042539462b6d972c2d7e"}, ] psutil = [ {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, @@ -3611,6 +3657,10 @@ pure-eval = [ {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, ] +py = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] pyasn1 = [ {file = "pyasn1-0.5.0-py2.py3-none-any.whl", hash = "sha256:87a2121042a1ac9358cabcaf1d07680ff97ee6404333bacca15f76aa8ad01a57"}, {file = "pyasn1-0.5.0.tar.gz", hash = "sha256:97b7290ca68e62a832558ec3976f15cbf911bf5d7c7039d8b861c2a0ece69fde"}, @@ -3628,42 +3678,42 @@ pycparser = [ {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, ] pydantic = [ - {file = "pydantic-1.10.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e79e999e539872e903767c417c897e729e015872040e56b96e67968c3b918b2d"}, - {file = "pydantic-1.10.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:01aea3a42c13f2602b7ecbbea484a98169fb568ebd9e247593ea05f01b884b2e"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:516f1ed9bc2406a0467dd777afc636c7091d71f214d5e413d64fef45174cfc7a"}, - {file = "pydantic-1.10.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae150a63564929c675d7f2303008d88426a0add46efd76c3fc797cd71cb1b46f"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ecbbc51391248116c0a055899e6c3e7ffbb11fb5e2a4cd6f2d0b93272118a209"}, - {file = "pydantic-1.10.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f4a2b50e2b03d5776e7f21af73e2070e1b5c0d0df255a827e7c632962f8315af"}, - {file = "pydantic-1.10.7-cp310-cp310-win_amd64.whl", hash = "sha256:a7cd2251439988b413cb0a985c4ed82b6c6aac382dbaff53ae03c4b23a70e80a"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:68792151e174a4aa9e9fc1b4e653e65a354a2fa0fed169f7b3d09902ad2cb6f1"}, - {file = "pydantic-1.10.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dfe2507b8ef209da71b6fb5f4e597b50c5a34b78d7e857c4f8f3115effaef5fe"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10a86d8c8db68086f1e30a530f7d5f83eb0685e632e411dbbcf2d5c0150e8dcd"}, - {file = "pydantic-1.10.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d75ae19d2a3dbb146b6f324031c24f8a3f52ff5d6a9f22f0683694b3afcb16fb"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:464855a7ff7f2cc2cf537ecc421291b9132aa9c79aef44e917ad711b4a93163b"}, - {file = "pydantic-1.10.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:193924c563fae6ddcb71d3f06fa153866423ac1b793a47936656e806b64e24ca"}, - {file = "pydantic-1.10.7-cp311-cp311-win_amd64.whl", hash = "sha256:b4a849d10f211389502059c33332e91327bc154acc1845f375a99eca3afa802d"}, - {file = "pydantic-1.10.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cc1dde4e50a5fc1336ee0581c1612215bc64ed6d28d2c7c6f25d2fe3e7c3e918"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0cfe895a504c060e5d36b287ee696e2fdad02d89e0d895f83037245218a87fe"}, - {file = "pydantic-1.10.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:670bb4683ad1e48b0ecb06f0cfe2178dcf74ff27921cdf1606e527d2617a81ee"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:950ce33857841f9a337ce07ddf46bc84e1c4946d2a3bba18f8280297157a3fd1"}, - {file = "pydantic-1.10.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c15582f9055fbc1bfe50266a19771bbbef33dd28c45e78afbe1996fd70966c2a"}, - {file = "pydantic-1.10.7-cp37-cp37m-win_amd64.whl", hash = "sha256:82dffb306dd20bd5268fd6379bc4bfe75242a9c2b79fec58e1041fbbdb1f7914"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8c7f51861d73e8b9ddcb9916ae7ac39fb52761d9ea0df41128e81e2ba42886cd"}, - {file = "pydantic-1.10.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6434b49c0b03a51021ade5c4daa7d70c98f7a79e95b551201fff682fc1661245"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64d34ab766fa056df49013bb6e79921a0265204c071984e75a09cbceacbbdd5d"}, - {file = "pydantic-1.10.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:701daea9ffe9d26f97b52f1d157e0d4121644f0fcf80b443248434958fd03dc3"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf135c46099ff3f919d2150a948ce94b9ce545598ef2c6c7bf55dca98a304b52"}, - {file = "pydantic-1.10.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0f85904f73161817b80781cc150f8b906d521fa11e3cdabae19a581c3606209"}, - {file = "pydantic-1.10.7-cp38-cp38-win_amd64.whl", hash = "sha256:9f6f0fd68d73257ad6685419478c5aece46432f4bdd8d32c7345f1986496171e"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c230c0d8a322276d6e7b88c3f7ce885f9ed16e0910354510e0bae84d54991143"}, - {file = "pydantic-1.10.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:976cae77ba6a49d80f461fd8bba183ff7ba79f44aa5cfa82f1346b5626542f8e"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d45fc99d64af9aaf7e308054a0067fdcd87ffe974f2442312372dfa66e1001d"}, - {file = "pydantic-1.10.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d2a5ebb48958754d386195fe9e9c5106f11275867051bf017a8059410e9abf1f"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:abfb7d4a7cd5cc4e1d1887c43503a7c5dd608eadf8bc615413fc498d3e4645cd"}, - {file = "pydantic-1.10.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:80b1fab4deb08a8292d15e43a6edccdffa5377a36a4597bb545b93e79c5ff0a5"}, - {file = "pydantic-1.10.7-cp39-cp39-win_amd64.whl", hash = "sha256:d71e69699498b020ea198468e2480a2f1e7433e32a3a99760058c6520e2bea7e"}, - {file = "pydantic-1.10.7-py3-none-any.whl", hash = "sha256:0cd181f1d0b1d00e2b705f1bf1ac7799a2d938cce3376b8007df62b29be3c2c6"}, - {file = "pydantic-1.10.7.tar.gz", hash = "sha256:cfc83c0678b6ba51b0532bea66860617c4cd4251ecf76e9846fa5a9f3454e97e"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1243d28e9b05003a89d72e7915fdb26ffd1d39bdd39b00b7dbe4afae4b557f9d"}, + {file = "pydantic-1.10.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c0ab53b609c11dfc0c060d94335993cc2b95b2150e25583bec37a49b2d6c6c3f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9613fadad06b4f3bc5db2653ce2f22e0de84a7c6c293909b48f6ed37b83c61f"}, + {file = "pydantic-1.10.8-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df7800cb1984d8f6e249351139667a8c50a379009271ee6236138a22a0c0f319"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0c6fafa0965b539d7aab0a673a046466d23b86e4b0e8019d25fd53f4df62c277"}, + {file = "pydantic-1.10.8-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e82d4566fcd527eae8b244fa952d99f2ca3172b7e97add0b43e2d97ee77f81ab"}, + {file = "pydantic-1.10.8-cp310-cp310-win_amd64.whl", hash = "sha256:ab523c31e22943713d80d8d342d23b6f6ac4b792a1e54064a8d0cf78fd64e800"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:666bdf6066bf6dbc107b30d034615d2627e2121506c555f73f90b54a463d1f33"}, + {file = "pydantic-1.10.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:35db5301b82e8661fa9c505c800d0990bc14e9f36f98932bb1d248c0ac5cada5"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f90c1e29f447557e9e26afb1c4dbf8768a10cc676e3781b6a577841ade126b85"}, + {file = "pydantic-1.10.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93e766b4a8226e0708ef243e843105bf124e21331694367f95f4e3b4a92bbb3f"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:88f195f582851e8db960b4a94c3e3ad25692c1c1539e2552f3df7a9e972ef60e"}, + {file = "pydantic-1.10.8-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:34d327c81e68a1ecb52fe9c8d50c8a9b3e90d3c8ad991bfc8f953fb477d42fb4"}, + {file = "pydantic-1.10.8-cp311-cp311-win_amd64.whl", hash = "sha256:d532bf00f381bd6bc62cabc7d1372096b75a33bc197a312b03f5838b4fb84edd"}, + {file = "pydantic-1.10.8-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7d5b8641c24886d764a74ec541d2fc2c7fb19f6da2a4001e6d580ba4a38f7878"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b1f6cb446470b7ddf86c2e57cd119a24959af2b01e552f60705910663af09a4"}, + {file = "pydantic-1.10.8-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33b60054b2136aef8cf190cd4c52a3daa20b2263917c49adad20eaf381e823b"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1952526ba40b220b912cdc43c1c32bcf4a58e3f192fa313ee665916b26befb68"}, + {file = "pydantic-1.10.8-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bb14388ec45a7a0dc429e87def6396f9e73c8c77818c927b6a60706603d5f2ea"}, + {file = "pydantic-1.10.8-cp37-cp37m-win_amd64.whl", hash = "sha256:16f8c3e33af1e9bb16c7a91fc7d5fa9fe27298e9f299cff6cb744d89d573d62c"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1ced8375969673929809d7f36ad322934c35de4af3b5e5b09ec967c21f9f7887"}, + {file = "pydantic-1.10.8-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93e6bcfccbd831894a6a434b0aeb1947f9e70b7468f274154d03d71fabb1d7c6"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:191ba419b605f897ede9892f6c56fb182f40a15d309ef0142212200a10af4c18"}, + {file = "pydantic-1.10.8-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:052d8654cb65174d6f9490cc9b9a200083a82cf5c3c5d3985db765757eb3b375"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ceb6a23bf1ba4b837d0cfe378329ad3f351b5897c8d4914ce95b85fba96da5a1"}, + {file = "pydantic-1.10.8-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f2e754d5566f050954727c77f094e01793bcb5725b663bf628fa6743a5a9108"}, + {file = "pydantic-1.10.8-cp38-cp38-win_amd64.whl", hash = "sha256:6a82d6cda82258efca32b40040228ecf43a548671cb174a1e81477195ed3ed56"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e59417ba8a17265e632af99cc5f35ec309de5980c440c255ab1ca3ae96a3e0e"}, + {file = "pydantic-1.10.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:84d80219c3f8d4cad44575e18404099c76851bc924ce5ab1c4c8bb5e2a2227d0"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e4148e635994d57d834be1182a44bdb07dd867fa3c2d1b37002000646cc5459"}, + {file = "pydantic-1.10.8-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:12f7b0bf8553e310e530e9f3a2f5734c68699f42218bf3568ef49cd9b0e44df4"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:42aa0c4b5c3025483240a25b09f3c09a189481ddda2ea3a831a9d25f444e03c1"}, + {file = "pydantic-1.10.8-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:17aef11cc1b997f9d574b91909fed40761e13fac438d72b81f902226a69dac01"}, + {file = "pydantic-1.10.8-cp39-cp39-win_amd64.whl", hash = "sha256:66a703d1983c675a6e0fed8953b0971c44dba48a929a2000a493c3772eb61a5a"}, + {file = "pydantic-1.10.8-py3-none-any.whl", hash = "sha256:7456eb22ed9aaa24ff3e7b4757da20d9e5ce2a81018c1b3ebd81a0b88a18f3b2"}, + {file = "pydantic-1.10.8.tar.gz", hash = "sha256:1410275520dfa70effadf4c21811d755e7ef9bb1f1d077a21958153a92c8d9ca"}, ] pyflakes = [ {file = "pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, @@ -3678,8 +3728,8 @@ pygsheets = [ {file = "pygsheets-2.0.6.tar.gz", hash = "sha256:bff46c812e99f9b8b81a09b456581365281c797620ec08530b0d0e48fa9299e2"}, ] pylint = [ - {file = "pylint-2.17.3-py3-none-any.whl", hash = "sha256:a6cbb4c6e96eab4a3c7de7c6383c512478f58f88d95764507d84c899d656a89a"}, - {file = "pylint-2.17.3.tar.gz", hash = "sha256:761907349e699f8afdcd56c4fe02f3021ab5b3a0fc26d19a9bfdc66c7d0d5cd5"}, + {file = "pylint-2.17.4-py3-none-any.whl", hash = "sha256:7a1145fb08c251bdb5cca11739722ce64a63db479283d10ce718b2460e54123c"}, + {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, ] pyopenssl = [ {file = "pyOpenSSL-23.1.1-py3-none-any.whl", hash = "sha256:9e0c526404a210df9d2b18cd33364beadb0dc858a739b885677bc65e105d4a4c"}, @@ -3746,10 +3796,6 @@ pytz = [ {file = "pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, {file = "pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, ] -pytz-deprecation-shim = [ - {file = "pytz_deprecation_shim-0.1.0.post0-py2.py3-none-any.whl", hash = "sha256:8314c9692a636c8eb3bda879b9f119e350e93223ae83e70e80c31675a0fdc1a6"}, - {file = "pytz_deprecation_shim-0.1.0.post0.tar.gz", hash = "sha256:af097bae1b616dde5c5744441e2ddc69e74dfdcb0c263129610d85b87445a59d"}, -] pywin32 = [ {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, @@ -3904,70 +3950,98 @@ rdflib = [ {file = "rdflib-6.3.2.tar.gz", hash = "sha256:72af591ff704f4caacea7ecc0c5a9056b8553e0489dd4f35a9bc52dbd41522e0"}, ] regex = [ - {file = "regex-2023.3.23-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:845a5e2d84389c4ddada1a9b95c055320070f18bb76512608374aca00d22eca8"}, - {file = "regex-2023.3.23-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:87d9951f5a538dd1d016bdc0dcae59241d15fa94860964833a54d18197fcd134"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37ae17d3be44c0b3f782c28ae9edd8b47c1f1776d4cabe87edc0b98e1f12b021"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0b8eb1e3bca6b48dc721818a60ae83b8264d4089a4a41d62be6d05316ec38e15"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df45fac182ebc3c494460c644e853515cc24f5ad9da05f8ffb91da891bfee879"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7006105b10b59971d3b248ad75acc3651c7e4cf54d81694df5a5130a3c3f7ea"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93f3f1aa608380fe294aa4cb82e2afda07a7598e828d0341e124b8fd9327c715"}, - {file = "regex-2023.3.23-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:787954f541ab95d8195d97b0b8cf1dc304424adb1e07365967e656b92b38a699"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:20abe0bdf03630fe92ccafc45a599bca8b3501f48d1de4f7d121153350a2f77d"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:11d00c31aeab9a6e0503bc77e73ed9f4527b3984279d997eb145d7c7be6268fd"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:d5bbe0e1511b844794a3be43d6c145001626ba9a6c1db8f84bdc724e91131d9d"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ea3c0cb56eadbf4ab2277e7a095676370b3e46dbfc74d5c383bd87b0d6317910"}, - {file = "regex-2023.3.23-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d895b4c863059a4934d3e874b90998df774644a41b349ebb330f85f11b4ef2c0"}, - {file = "regex-2023.3.23-cp310-cp310-win32.whl", hash = "sha256:9d764514d19b4edcc75fd8cb1423448ef393e8b6cbd94f38cab983ab1b75855d"}, - {file = "regex-2023.3.23-cp310-cp310-win_amd64.whl", hash = "sha256:11d1f2b7a0696dc0310de0efb51b1f4d813ad4401fe368e83c0c62f344429f98"}, - {file = "regex-2023.3.23-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8a9c63cde0eaa345795c0fdeb19dc62d22e378c50b0bc67bf4667cd5b482d98b"}, - {file = "regex-2023.3.23-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dd7200b4c27b68cf9c9646da01647141c6db09f48cc5b51bc588deaf8e98a797"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22720024b90a6ba673a725dcc62e10fb1111b889305d7c6b887ac7466b74bedb"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b190a339090e6af25f4a5fd9e77591f6d911cc7b96ecbb2114890b061be0ac1"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e76b6fc0d8e9efa39100369a9b3379ce35e20f6c75365653cf58d282ad290f6f"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7868b8f218bf69a2a15402fde08b08712213a1f4b85a156d90473a6fb6b12b09"}, - {file = "regex-2023.3.23-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2472428efc4127374f494e570e36b30bb5e6b37d9a754f7667f7073e43b0abdd"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c37df2a060cb476d94c047b18572ee2b37c31f831df126c0da3cd9227b39253d"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4479f9e2abc03362df4045b1332d4a2b7885b245a30d4f4b051c4083b97d95d8"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e2396e0678167f2d0c197da942b0b3fb48fee2f0b5915a0feb84d11b6686afe6"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:75f288c60232a5339e0ff2fa05779a5e9c74e9fc085c81e931d4a264501e745b"}, - {file = "regex-2023.3.23-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c869260aa62cee21c5eb171a466c0572b5e809213612ef8d495268cd2e34f20d"}, - {file = "regex-2023.3.23-cp311-cp311-win32.whl", hash = "sha256:25f0532fd0c53e96bad84664171969de9673b4131f2297f1db850d3918d58858"}, - {file = "regex-2023.3.23-cp311-cp311-win_amd64.whl", hash = "sha256:5ccfafd98473e007cebf7da10c1411035b7844f0f204015efd050601906dbb53"}, - {file = "regex-2023.3.23-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6572ff287176c0fb96568adb292674b421fa762153ed074d94b1d939ed92c253"}, - {file = "regex-2023.3.23-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a610e0adfcb0fc84ea25f6ea685e39e74cbcd9245a72a9a7aab85ff755a5ed27"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086afe222d58b88b62847bdbd92079b4699350b4acab892f88a935db5707c790"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79e29fd62fa2f597a6754b247356bda14b866131a22444d67f907d6d341e10f3"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c07ce8e9eee878a48ebeb32ee661b49504b85e164b05bebf25420705709fdd31"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86b036f401895e854de9fefe061518e78d506d8a919cc250dc3416bca03f6f9a"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78ac8dd8e18800bb1f97aad0d73f68916592dddf233b99d2b5cabc562088503a"}, - {file = "regex-2023.3.23-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:539dd010dc35af935b32f248099e38447bbffc10b59c2b542bceead2bed5c325"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9bf4a5626f2a0ea006bf81e8963f498a57a47d58907eaa58f4b3e13be68759d8"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf86b4328c204c3f315074a61bc1c06f8a75a8e102359f18ce99fbcbbf1951f0"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:2848bf76673c83314068241c8d5b7fa9ad9bed866c979875a0e84039349e8fa7"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:c125a02d22c555e68f7433bac8449992fa1cead525399f14e47c2d98f2f0e467"}, - {file = "regex-2023.3.23-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cd1671e9d5ac05ce6aa86874dd8dfa048824d1dbe73060851b310c6c1a201a96"}, - {file = "regex-2023.3.23-cp38-cp38-win32.whl", hash = "sha256:fffe57312a358be6ec6baeb43d253c36e5790e436b7bf5b7a38df360363e88e9"}, - {file = "regex-2023.3.23-cp38-cp38-win_amd64.whl", hash = "sha256:dbb3f87e15d3dd76996d604af8678316ad2d7d20faa394e92d9394dfd621fd0c"}, - {file = "regex-2023.3.23-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c88e8c226473b5549fe9616980ea7ca09289246cfbdf469241edf4741a620004"}, - {file = "regex-2023.3.23-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6560776ec19c83f3645bbc5db64a7a5816c9d8fb7ed7201c5bcd269323d88072"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b1fc2632c01f42e06173d8dd9bb2e74ab9b0afa1d698058c867288d2c7a31f3"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fdf7ad455f1916b8ea5cdbc482d379f6daf93f3867b4232d14699867a5a13af7"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5fc33b27b1d800fc5b78d7f7d0f287e35079ecabe68e83d46930cf45690e1c8c"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c49552dc938e3588f63f8a78c86f3c9c75301e813bca0bef13bdb4b87ccf364"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e152461e9a0aedec7d37fc66ec0fa635eca984777d3d3c3e36f53bf3d3ceb16e"}, - {file = "regex-2023.3.23-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:db034255e72d2995cf581b14bb3fc9c00bdbe6822b49fcd4eef79e1d5f232618"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:55ae114da21b7a790b90255ea52d2aa3a0d121a646deb2d3c6a3194e722fc762"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ef3f528fe1cc3d139508fe1b22523745aa77b9d6cb5b0bf277f48788ee0b993f"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:a81c9ec59ca2303acd1ccd7b9ac409f1e478e40e96f8f79b943be476c5fdb8bb"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:cde09c4fdd070772aa2596d97e942eb775a478b32459e042e1be71b739d08b77"}, - {file = "regex-2023.3.23-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3cd9f5dd7b821f141d3a6ca0d5d9359b9221e4f051ca3139320adea9f1679691"}, - {file = "regex-2023.3.23-cp39-cp39-win32.whl", hash = "sha256:7304863f3a652dab5e68e6fb1725d05ebab36ec0390676d1736e0571ebb713ef"}, - {file = "regex-2023.3.23-cp39-cp39-win_amd64.whl", hash = "sha256:54c3fa855a3f7438149de3211738dd9b5f0c733f48b54ae05aa7fce83d48d858"}, - {file = "regex-2023.3.23.tar.gz", hash = "sha256:dc80df325b43ffea5cdea2e3eaa97a44f3dd298262b1c7fe9dbb2a9522b956a7"}, + {file = "regex-2023.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:48c9ec56579d4ba1c88f42302194b8ae2350265cb60c64b7b9a88dcb7fbde309"}, + {file = "regex-2023.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02f4541550459c08fdd6f97aa4e24c6f1932eec780d58a2faa2068253df7d6ff"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53e22e4460f0245b468ee645156a4f84d0fc35a12d9ba79bd7d79bdcd2f9629d"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4b870b6f632fc74941cadc2a0f3064ed8409e6f8ee226cdfd2a85ae50473aa94"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:171c52e320fe29260da550d81c6b99f6f8402450dc7777ef5ced2e848f3b6f8f"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad5524c2aedaf9aa14ef1bc9327f8abd915699dea457d339bebbe2f0d218f86"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a0f874ee8c0bc820e649c900243c6d1e6dc435b81da1492046716f14f1a2a96"}, + {file = "regex-2023.5.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e645c757183ee0e13f0bbe56508598e2d9cd42b8abc6c0599d53b0d0b8dd1479"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a4c5da39bca4f7979eefcbb36efea04471cd68db2d38fcbb4ee2c6d440699833"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5e3f4468b8c6fd2fd33c218bbd0a1559e6a6fcf185af8bb0cc43f3b5bfb7d636"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:59e4b729eae1a0919f9e4c0fc635fbcc9db59c74ad98d684f4877be3d2607dd6"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:ba73a14e9c8f9ac409863543cde3290dba39098fc261f717dc337ea72d3ebad2"}, + {file = "regex-2023.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0bbd5dcb19603ab8d2781fac60114fb89aee8494f4505ae7ad141a3314abb1f9"}, + {file = "regex-2023.5.5-cp310-cp310-win32.whl", hash = "sha256:40005cbd383438aecf715a7b47fe1e3dcbc889a36461ed416bdec07e0ef1db66"}, + {file = "regex-2023.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:59597cd6315d3439ed4b074febe84a439c33928dd34396941b4d377692eca810"}, + {file = "regex-2023.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8f08276466fedb9e36e5193a96cb944928301152879ec20c2d723d1031cd4ddd"}, + {file = "regex-2023.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cd46f30e758629c3ee91713529cfbe107ac50d27110fdcc326a42ce2acf4dafc"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f2910502f718828cecc8beff004917dcf577fc5f8f5dd40ffb1ea7612124547b"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:445d6f4fc3bd9fc2bf0416164454f90acab8858cd5a041403d7a11e3356980e8"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18196c16a584619c7c1d843497c069955d7629ad4a3fdee240eb347f4a2c9dbe"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:33d430a23b661629661f1fe8395be2004006bc792bb9fc7c53911d661b69dd7e"}, + {file = "regex-2023.5.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:72a28979cc667e5f82ef433db009184e7ac277844eea0f7f4d254b789517941d"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:f764e4dfafa288e2eba21231f455d209f4709436baeebb05bdecfb5d8ddc3d35"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:23d86ad2121b3c4fc78c58f95e19173790e22ac05996df69b84e12da5816cb17"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:690a17db524ee6ac4a27efc5406530dd90e7a7a69d8360235323d0e5dafb8f5b"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:1ecf3dcff71f0c0fe3e555201cbe749fa66aae8d18f80d2cc4de8e66df37390a"}, + {file = "regex-2023.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:811040d7f3dd9c55eb0d8b00b5dcb7fd9ae1761c454f444fd9f37fe5ec57143a"}, + {file = "regex-2023.5.5-cp311-cp311-win32.whl", hash = "sha256:c8c143a65ce3ca42e54d8e6fcaf465b6b672ed1c6c90022794a802fb93105d22"}, + {file = "regex-2023.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:586a011f77f8a2da4b888774174cd266e69e917a67ba072c7fc0e91878178a80"}, + {file = "regex-2023.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b6365703e8cf1644b82104cdd05270d1a9f043119a168d66c55684b1b557d008"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a56c18f21ac98209da9c54ae3ebb3b6f6e772038681d6cb43b8d53da3b09ee81"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8b942d8b3ce765dbc3b1dad0a944712a89b5de290ce8f72681e22b3c55f3cc8"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:844671c9c1150fcdac46d43198364034b961bd520f2c4fdaabfc7c7d7138a2dd"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c2ce65bdeaf0a386bb3b533a28de3994e8e13b464ac15e1e67e4603dd88787fa"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fee0016cc35a8a91e8cc9312ab26a6fe638d484131a7afa79e1ce6165328a135"}, + {file = "regex-2023.5.5-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18f05d14f14a812fe9723f13afafefe6b74ca042d99f8884e62dbd34dcccf3e2"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:941b3f1b2392f0bcd6abf1bc7a322787d6db4e7457be6d1ffd3a693426a755f2"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:921473a93bcea4d00295799ab929522fc650e85c6b9f27ae1e6bb32a790ea7d3"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:e2205a81f815b5bb17e46e74cc946c575b484e5f0acfcb805fb252d67e22938d"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:385992d5ecf1a93cb85adff2f73e0402dd9ac29b71b7006d342cc920816e6f32"}, + {file = "regex-2023.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:890a09cb0a62198bff92eda98b2b507305dd3abf974778bae3287f98b48907d3"}, + {file = "regex-2023.5.5-cp36-cp36m-win32.whl", hash = "sha256:821a88b878b6589c5068f4cc2cfeb2c64e343a196bc9d7ac68ea8c2a776acd46"}, + {file = "regex-2023.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:7918a1b83dd70dc04ab5ed24c78ae833ae8ea228cef84e08597c408286edc926"}, + {file = "regex-2023.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:338994d3d4ca4cf12f09822e025731a5bdd3a37aaa571fa52659e85ca793fb67"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a69cf0c00c4d4a929c6c7717fd918414cab0d6132a49a6d8fc3ded1988ed2ea"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f5e06df94fff8c4c85f98c6487f6636848e1dc85ce17ab7d1931df4a081f657"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8906669b03c63266b6a7693d1f487b02647beb12adea20f8840c1a087e2dfb5"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fda3e50abad8d0f48df621cf75adc73c63f7243cbe0e3b2171392b445401550"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ac2b7d341dc1bd102be849d6dd33b09701223a851105b2754339e390be0627a"}, + {file = "regex-2023.5.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fb2b495dd94b02de8215625948132cc2ea360ae84fe6634cd19b6567709c8ae2"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:aa7d032c1d84726aa9edeb6accf079b4caa87151ca9fabacef31fa028186c66d"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d45864693351c15531f7e76f545ec35000d50848daa833cead96edae1665559"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:21e90a288e6ba4bf44c25c6a946cb9b0f00b73044d74308b5e0afd190338297c"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:10250a093741ec7bf74bcd2039e697f519b028518f605ff2aa7ac1e9c9f97423"}, + {file = "regex-2023.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6b8d0c153f07a953636b9cdb3011b733cadd4178123ef728ccc4d5969e67f3c2"}, + {file = "regex-2023.5.5-cp37-cp37m-win32.whl", hash = "sha256:10374c84ee58c44575b667310d5bbfa89fb2e64e52349720a0182c0017512f6c"}, + {file = "regex-2023.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9b320677521aabf666cdd6e99baee4fb5ac3996349c3b7f8e7c4eee1c00dfe3a"}, + {file = "regex-2023.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:afb1c70ec1e594a547f38ad6bf5e3d60304ce7539e677c1429eebab115bce56e"}, + {file = "regex-2023.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf123225945aa58b3057d0fba67e8061c62d14cc8a4202630f8057df70189051"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a99757ad7fe5c8a2bb44829fc57ced11253e10f462233c1255fe03888e06bc19"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a623564d810e7a953ff1357f7799c14bc9beeab699aacc8b7ab7822da1e952b8"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ced02e3bd55e16e89c08bbc8128cff0884d96e7f7a5633d3dc366b6d95fcd1d6"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d1cbe6b5be3b9b698d8cc4ee4dee7e017ad655e83361cd0ea8e653d65e469468"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a6e4b0e0531223f53bad07ddf733af490ba2b8367f62342b92b39b29f72735a"}, + {file = "regex-2023.5.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2e9c4f778514a560a9c9aa8e5538bee759b55f6c1dcd35613ad72523fd9175b8"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:256f7f4c6ba145f62f7a441a003c94b8b1af78cee2cccacfc1e835f93bc09426"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:bd7b68fd2e79d59d86dcbc1ccd6e2ca09c505343445daaa4e07f43c8a9cc34da"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4a5059bd585e9e9504ef9c07e4bc15b0a621ba20504388875d66b8b30a5c4d18"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6893544e06bae009916a5658ce7207e26ed17385149f35a3125f5259951f1bbe"}, + {file = "regex-2023.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c64d5abe91a3dfe5ff250c6bb267ef00dbc01501518225b45a5f9def458f31fb"}, + {file = "regex-2023.5.5-cp38-cp38-win32.whl", hash = "sha256:7923470d6056a9590247ff729c05e8e0f06bbd4efa6569c916943cb2d9b68b91"}, + {file = "regex-2023.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:4035d6945cb961c90c3e1c1ca2feb526175bcfed44dfb1cc77db4fdced060d3e"}, + {file = "regex-2023.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:50fd2d9b36938d4dcecbd684777dd12a407add4f9f934f235c66372e630772b0"}, + {file = "regex-2023.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d19e57f888b00cd04fc38f5e18d0efbd91ccba2d45039453ab2236e6eec48d4d"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd966475e963122ee0a7118ec9024388c602d12ac72860f6eea119a3928be053"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:db09e6c18977a33fea26fe67b7a842f706c67cf8bda1450974d0ae0dd63570df"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6164d4e2a82f9ebd7752a06bd6c504791bedc6418c0196cd0a23afb7f3e12b2d"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84397d3f750d153ebd7f958efaa92b45fea170200e2df5e0e1fd4d85b7e3f58a"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9c3efee9bb53cbe7b285760c81f28ac80dc15fa48b5fe7e58b52752e642553f1"}, + {file = "regex-2023.5.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:144b5b017646b5a9392a5554a1e5db0000ae637be4971c9747566775fc96e1b2"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1189fbbb21e2c117fda5303653b61905aeeeea23de4a94d400b0487eb16d2d60"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f83fe9e10f9d0b6cf580564d4d23845b9d692e4c91bd8be57733958e4c602956"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:72aa4746993a28c841e05889f3f1b1e5d14df8d3daa157d6001a34c98102b393"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:de2f780c3242ea114dd01f84848655356af4dd561501896c751d7b885ea6d3a1"}, + {file = "regex-2023.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:290fd35219486dfbc00b0de72f455ecdd63e59b528991a6aec9fdfc0ce85672e"}, + {file = "regex-2023.5.5-cp39-cp39-win32.whl", hash = "sha256:732176f5427e72fa2325b05c58ad0b45af341c459910d766f814b0584ac1f9ac"}, + {file = "regex-2023.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:1307aa4daa1cbb23823d8238e1f61292fd07e4e5d8d38a6efff00b67a7cdb764"}, + {file = "regex-2023.5.5.tar.gz", hash = "sha256:7d76a8a1fc9da08296462a18f16620ba73bcbf5909e42383b253ef34d9d5141e"}, ] requests = [ - {file = "requests-2.29.0-py3-none-any.whl", hash = "sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b"}, - {file = "requests-2.29.0.tar.gz", hash = "sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"}, + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, ] requests-oauthlib = [ {file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"}, @@ -3998,7 +4072,6 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:d000f258cf42fec2b1bbf2863c61d7b8918d31ffee905da62dede869254d3b8a"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:045e0626baf1c52e5527bd5db361bc83180faaba2ff586e763d3d5982a876a9e"}, {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-macosx_12_6_arm64.whl", hash = "sha256:721bc4ba4525f53f6a611ec0967bdcee61b31df5a56801281027a3a6d1c2daf5"}, - {file = "ruamel.yaml.clib-0.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:41d0f1fa4c6830176eef5b276af04c89320ea616655d01327d5ce65e50575c94"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4b3a93bb9bc662fc1f99c5c3ea8e623d8b23ad22f861eb6fce9377ac07ad6072"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-macosx_12_0_arm64.whl", hash = "sha256:a234a20ae07e8469da311e182e70ef6b199d0fbeb6c6cc2901204dd87fb867e8"}, {file = "ruamel.yaml.clib-0.2.7-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:15910ef4f3e537eea7fe45f8a5d19997479940d9196f357152a09031c5be59f3"}, @@ -4026,8 +4099,8 @@ ruamel-yaml-clib = [ {file = "ruamel.yaml.clib-0.2.7.tar.gz", hash = "sha256:1f08fd5a2bea9c4180db71678e850b995d2a5f4537be0e94557668cf0f5f9497"}, ] schematic-db = [ - {file = "schematic_db-0.0.6-py3-none-any.whl", hash = "sha256:4bcf7ca487e88af52c2e77f31f7c0cb5f967617d68d2efe8433f57abb1c40ac8"}, - {file = "schematic_db-0.0.6.tar.gz", hash = "sha256:d3505850fb7c23d5c2dd1ad2147cfb29ab86eaf72bf71b390f7707545576bb88"}, + {file = "schematic_db-0.0.20-py3-none-any.whl", hash = "sha256:e1c5a3774156fe510c703df74fee5e7b5f38b721d870c9161dcc657b6fe18723"}, + {file = "schematic_db-0.0.20.tar.gz", hash = "sha256:577cdb32004b6ab5d383a3411e7c812410ae56d46d5a7065af57b488ffe5fe0a"}, ] scipy = [ {file = "scipy-1.10.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e7354fd7527a4b0377ce55f286805b34e8c54b91be865bac273f527e1b839019"}, @@ -4081,8 +4154,8 @@ soupsieve = [ {file = "soupsieve-2.4.1.tar.gz", hash = "sha256:89d12b2d5dfcd2c9e8c22326da9d9aa9cb3dfab0a83a024f05704076ee8d35ea"}, ] sphinx = [ - {file = "Sphinx-6.2.1.tar.gz", hash = "sha256:6d56a34697bb749ffa0152feafc4b19836c755d90a7c59b72bc7dfd371b9cc6b"}, - {file = "sphinx-6.2.1-py3-none-any.whl", hash = "sha256:97787ff1fa3256a3eef9eda523a63dbf299f7b47e053cfcf684a1c2a8380c912"}, + {file = "Sphinx-7.0.1.tar.gz", hash = "sha256:61e025f788c5977d9412587e733733a289e2b9fdc2fef8868ddfbfc4ccfe881d"}, + {file = "sphinx-7.0.1-py3-none-any.whl", hash = "sha256:60c5e04756c1709a98845ed27a2eed7a556af3993afb66e77fec48189f742616"}, ] sphinx-click = [ {file = "sphinx-click-4.4.0.tar.gz", hash = "sha256:cc67692bd28f482c7f01531c61b64e9d2f069bfcf3d24cbbb51d4a84a749fa48"}, @@ -4113,47 +4186,47 @@ sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, ] sqlalchemy = [ - {file = "SQLAlchemy-1.4.47-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:dcfb480bfc9e1fab726003ae00a6bfc67a29bad275b63a4e36d17fe7f13a624e"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:28fda5a69d6182589892422c5a9b02a8fd1125787aab1d83f1392aa955bf8d0a"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-win32.whl", hash = "sha256:45e799c1a41822eba6bee4e59b0e38764e1a1ee69873ab2889079865e9ea0e23"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27m-win_amd64.whl", hash = "sha256:10edbb92a9ef611f01b086e271a9f6c1c3e5157c3b0c5ff62310fb2187acbd4a"}, - {file = "SQLAlchemy-1.4.47-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:7a4df53472c9030a8ddb1cce517757ba38a7a25699bbcabd57dcc8a5d53f324e"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:511d4abc823152dec49461209607bbfb2df60033c8c88a3f7c93293b8ecbb13d"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbe57f39f531c5d68d5594ea4613daa60aba33bb51a8cc42f96f17bbd6305e8d"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ca8ab6748e3ec66afccd8b23ec2f92787a58d5353ce9624dccd770427ee67c82"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:299b5c5c060b9fbe51808d0d40d8475f7b3873317640b9b7617c7f988cf59fda"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-win32.whl", hash = "sha256:684e5c773222781775c7f77231f412633d8af22493bf35b7fa1029fdf8066d10"}, - {file = "SQLAlchemy-1.4.47-cp310-cp310-win_amd64.whl", hash = "sha256:2bba39b12b879c7b35cde18b6e14119c5f1a16bd064a48dd2ac62d21366a5e17"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:795b5b9db573d3ed61fae74285d57d396829e3157642794d3a8f72ec2a5c719b"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:989c62b96596b7938cbc032e39431e6c2d81b635034571d6a43a13920852fb65"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3b67bda733da1dcdccaf354e71ef01b46db483a4f6236450d3f9a61efdba35a"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-win32.whl", hash = "sha256:9a198f690ac12a3a807e03a5a45df6a30cd215935f237a46f4248faed62e69c8"}, - {file = "SQLAlchemy-1.4.47-cp311-cp311-win_amd64.whl", hash = "sha256:03be6f3cb66e69fb3a09b5ea89d77e4bc942f3bf84b207dba84666a26799c166"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:16ee6fea316790980779268da47a9260d5dd665c96f225d28e7750b0bb2e2a04"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:557675e0befafa08d36d7a9284e8761c97490a248474d778373fb96b0d7fd8de"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bb2797fee8a7914fb2c3dc7de404d3f96eb77f20fc60e9ee38dc6b0ca720f2c2"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28297aa29e035f29cba6b16aacd3680fbc6a9db682258d5f2e7b49ec215dbe40"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-win32.whl", hash = "sha256:998e782c8d9fd57fa8704d149ccd52acf03db30d7dd76f467fd21c1c21b414fa"}, - {file = "SQLAlchemy-1.4.47-cp36-cp36m-win_amd64.whl", hash = "sha256:dde4d02213f1deb49eaaf8be8a6425948963a7af84983b3f22772c63826944de"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e98ef1babe34f37f443b7211cd3ee004d9577a19766e2dbacf62fce73c76245a"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14a3879853208a242b5913f3a17c6ac0eae9dc210ff99c8f10b19d4a1ed8ed9b"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7120a2f72599d4fed7c001fa1cbbc5b4d14929436135768050e284f53e9fbe5e"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:048509d7f3ac27b83ad82fd96a1ab90a34c8e906e4e09c8d677fc531d12c23c5"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-win32.whl", hash = "sha256:6572d7c96c2e3e126d0bb27bfb1d7e2a195b68d951fcc64c146b94f088e5421a"}, - {file = "SQLAlchemy-1.4.47-cp37-cp37m-win_amd64.whl", hash = "sha256:a6c3929df5eeaf3867724003d5c19fed3f0c290f3edc7911616616684f200ecf"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:71d4bf7768169c4502f6c2b0709a02a33703544f611810fb0c75406a9c576ee1"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dd45c60cc4f6d68c30d5179e2c2c8098f7112983532897566bb69c47d87127d3"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0fdbb8e9d4e9003f332a93d6a37bca48ba8095086c97a89826a136d8eddfc455"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f216a51451a0a0466e082e163591f6dcb2f9ec182adb3f1f4b1fd3688c7582c"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-win32.whl", hash = "sha256:bd988b3362d7e586ef581eb14771bbb48793a4edb6fcf62da75d3f0f3447060b"}, - {file = "SQLAlchemy-1.4.47-cp38-cp38-win_amd64.whl", hash = "sha256:32ab09f2863e3de51529aa84ff0e4fe89a2cb1bfbc11e225b6dbc60814e44c94"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:07764b240645627bc3e82596435bd1a1884646bfc0721642d24c26b12f1df194"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e2a42017984099ef6f56438a6b898ce0538f6fadddaa902870c5aa3e1d82583"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6b6d807c76c20b4bc143a49ad47782228a2ac98bdcdcb069da54280e138847fc"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a94632ba26a666e7be0a7d7cc3f7acab622a04259a3aa0ee50ff6d44ba9df0d"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-win32.whl", hash = "sha256:f80915681ea9001f19b65aee715115f2ad310730c8043127cf3e19b3009892dd"}, - {file = "SQLAlchemy-1.4.47-cp39-cp39-win_amd64.whl", hash = "sha256:fc700b862e0a859a37faf85367e205e7acaecae5a098794aff52fdd8aea77b12"}, - {file = "SQLAlchemy-1.4.47.tar.gz", hash = "sha256:95fc02f7fc1f3199aaa47a8a757437134cf618e9d994c84effd53f530c38586f"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:4bac3aa3c3d8bc7408097e6fe8bf983caa6e9491c5d2e2488cfcfd8106f13b6a"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:dbcae0e528d755f4522cad5842f0942e54b578d79f21a692c44d91352ea6d64e"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-win32.whl", hash = "sha256:cbbe8b8bffb199b225d2fe3804421b7b43a0d49983f81dc654d0431d2f855543"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27m-win_amd64.whl", hash = "sha256:627e04a5d54bd50628fc8734d5fc6df2a1aa5962f219c44aad50b00a6cdcf965"}, + {file = "SQLAlchemy-1.4.48-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9af1db7a287ef86e0f5cd990b38da6bd9328de739d17e8864f1817710da2d217"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:ce7915eecc9c14a93b73f4e1c9d779ca43e955b43ddf1e21df154184f39748e5"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5381ddd09a99638f429f4cbe1b71b025bed318f6a7b23e11d65f3eed5e181c33"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:87609f6d4e81a941a17e61a4c19fee57f795e96f834c4f0a30cee725fc3f81d9"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb0808ad34167f394fea21bd4587fc62f3bd81bba232a1e7fbdfa17e6cfa7cd7"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-win32.whl", hash = "sha256:d53cd8bc582da5c1c8c86b6acc4ef42e20985c57d0ebc906445989df566c5603"}, + {file = "SQLAlchemy-1.4.48-cp310-cp310-win_amd64.whl", hash = "sha256:4355e5915844afdc5cf22ec29fba1010166e35dd94a21305f49020022167556b"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:066c2b0413e8cb980e6d46bf9d35ca83be81c20af688fedaef01450b06e4aa5e"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c99bf13e07140601d111a7c6f1fc1519914dd4e5228315bbda255e08412f61a4"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee26276f12614d47cc07bc85490a70f559cba965fb178b1c45d46ffa8d73fda"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-win32.whl", hash = "sha256:49c312bcff4728bffc6fb5e5318b8020ed5c8b958a06800f91859fe9633ca20e"}, + {file = "SQLAlchemy-1.4.48-cp311-cp311-win_amd64.whl", hash = "sha256:cef2e2abc06eab187a533ec3e1067a71d7bbec69e582401afdf6d8cad4ba3515"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:3509159e050bd6d24189ec7af373359f07aed690db91909c131e5068176c5a5d"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2fc2ab4d9f6d9218a5caa4121bdcf1125303482a1cdcfcdbd8567be8518969c0"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1ddbbcef9bcedaa370c03771ebec7e39e3944782bef49e69430383c376a250b"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f82d8efea1ca92b24f51d3aea1a82897ed2409868a0af04247c8c1e4fef5890"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-win32.whl", hash = "sha256:e3e98d4907805b07743b583a99ecc58bf8807ecb6985576d82d5e8ae103b5272"}, + {file = "SQLAlchemy-1.4.48-cp36-cp36m-win_amd64.whl", hash = "sha256:25887b4f716e085a1c5162f130b852f84e18d2633942c8ca40dfb8519367c14f"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:0817c181271b0ce5df1aa20949f0a9e2426830fed5ecdcc8db449618f12c2730"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe1dd2562313dd9fe1778ed56739ad5d9aae10f9f43d9f4cf81d65b0c85168bb"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:68413aead943883b341b2b77acd7a7fe2377c34d82e64d1840860247cec7ff7c"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbde5642104ac6e95f96e8ad6d18d9382aa20672008cf26068fe36f3004491df"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-win32.whl", hash = "sha256:11c6b1de720f816c22d6ad3bbfa2f026f89c7b78a5c4ffafb220e0183956a92a"}, + {file = "SQLAlchemy-1.4.48-cp37-cp37m-win_amd64.whl", hash = "sha256:eb5464ee8d4bb6549d368b578e9529d3c43265007193597ddca71c1bae6174e6"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:92e6133cf337c42bfee03ca08c62ba0f2d9695618c8abc14a564f47503157be9"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d29a3fc6d9c45962476b470a81983dd8add6ad26fdbfae6d463b509d5adcda"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:005e942b451cad5285015481ae4e557ff4154dde327840ba91b9ac379be3b6ce"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c8cfe951ed074ba5e708ed29c45397a95c4143255b0d022c7c8331a75ae61f3"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-win32.whl", hash = "sha256:2b9af65cc58726129d8414fc1a1a650dcdd594ba12e9c97909f1f57d48e393d3"}, + {file = "SQLAlchemy-1.4.48-cp38-cp38-win_amd64.whl", hash = "sha256:2b562e9d1e59be7833edf28b0968f156683d57cabd2137d8121806f38a9d58f4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a1fc046756cf2a37d7277c93278566ddf8be135c6a58397b4c940abf837011f4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d9b55252d2ca42a09bcd10a697fa041e696def9dfab0b78c0aaea1485551a08"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6dab89874e72a9ab5462997846d4c760cdb957958be27b03b49cf0de5e5c327c"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fd8b5ee5a3acc4371f820934b36f8109ce604ee73cc668c724abb054cebcb6e"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-win32.whl", hash = "sha256:eee09350fd538e29cfe3a496ec6f148504d2da40dbf52adefb0d2f8e4d38ccc4"}, + {file = "SQLAlchemy-1.4.48-cp39-cp39-win_amd64.whl", hash = "sha256:7ad2b0f6520ed5038e795cc2852eb5c1f20fa6831d73301ced4aafbe3a10e1f6"}, + {file = "SQLAlchemy-1.4.48.tar.gz", hash = "sha256:b47bc287096d989a0838ce96f7d8e966914a24da877ed41a7531d44b55cdb8df"}, ] sqlalchemy-utils = [ {file = "SQLAlchemy-Utils-0.38.3.tar.gz", hash = "sha256:9f9afba607a40455cf703adfa9846584bf26168a0c5a60a70063b70d65051f4d"}, @@ -4171,6 +4244,10 @@ synapseclient = [ {file = "synapseclient-2.7.1-py3-none-any.whl", hash = "sha256:c15efaec148dda18faa5a1736846f427713ceaa656178d5e7044fcd87fa8aa05"}, {file = "synapseclient-2.7.1.tar.gz", hash = "sha256:c6a7d5ff834c825390a0514f3f0020876ea4fb8c863889894b9a636458278d69"}, ] +tabulate = [ + {file = "tabulate-0.9.0-py3-none-any.whl", hash = "sha256:024ca478df22e9340661486f85298cff5f6dcdba14f3813e8830015b9ed1948f"}, + {file = "tabulate-0.9.0.tar.gz", hash = "sha256:0095b12bf5966de529c0feb1fa08671671b3368eec77d7ef7ab114be2c068b3c"}, +] tenacity = [ {file = "tenacity-8.2.2-py3-none-any.whl", hash = "sha256:2f277afb21b851637e8f52e6a613ff08734c347dc19ade928e519d7d2d8569b0"}, {file = "tenacity-8.2.2.tar.gz", hash = "sha256:43af037822bd0029025877f3b2d97cc4d7bb0c2991000a3d59d71517c5c969e0"}, @@ -4200,17 +4277,17 @@ toolz = [ {file = "toolz-0.12.0.tar.gz", hash = "sha256:88c570861c440ee3f2f6037c4654613228ff40c93a6c25e0eba70d17282c6194"}, ] tornado = [ - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:db181eb3df8738613ff0a26f49e1b394aade05034b01200a63e9662f347d4415"}, - {file = "tornado-6.3.1-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b4e7b956f9b5e6f9feb643ea04f07e7c6b49301e03e0023eedb01fa8cf52f579"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661aa8bc0e9d83d757cd95b6f6d1ece8ca9fd1ccdd34db2de381e25bf818233"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:81c17e0cc396908a5e25dc8e9c5e4936e6dfd544c9290be48bd054c79bcad51e"}, - {file = "tornado-6.3.1-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a27a1cfa9997923f80bdd962b3aab048ac486ad8cfb2f237964f8ab7f7eb824b"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d7117f3c7ba5d05813b17a1f04efc8e108a1b811ccfddd9134cc68553c414864"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:ffdce65a281fd708da5a9def3bfb8f364766847fa7ed806821a69094c9629e8a"}, - {file = "tornado-6.3.1-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:90f569a35a8ec19bde53aa596952071f445da678ec8596af763b9b9ce07605e6"}, - {file = "tornado-6.3.1-cp38-abi3-win32.whl", hash = "sha256:3455133b9ff262fd0a75630af0a8ee13564f25fb4fd3d9ce239b8a7d3d027bf8"}, - {file = "tornado-6.3.1-cp38-abi3-win_amd64.whl", hash = "sha256:1285f0691143f7ab97150831455d4db17a267b59649f7bd9700282cba3d5e771"}, - {file = "tornado-6.3.1.tar.gz", hash = "sha256:5e2f49ad371595957c50e42dd7e5c14d64a6843a3cf27352b69c706d1b5918af"}, + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:c367ab6c0393d71171123ca5515c61ff62fe09024fa6bf299cd1339dc9456829"}, + {file = "tornado-6.3.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:b46a6ab20f5c7c1cb949c72c1994a4585d2eaa0be4853f50a03b5031e964fc7c"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2de14066c4a38b4ecbbcd55c5cc4b5340eb04f1c5e81da7451ef555859c833f"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:05615096845cf50a895026f749195bf0b10b8909f9be672f50b0fe69cba368e4"}, + {file = "tornado-6.3.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b17b1cf5f8354efa3d37c6e28fdfd9c1c1e5122f2cb56dac121ac61baa47cbe"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:29e71c847a35f6e10ca3b5c2990a52ce38b233019d8e858b755ea6ce4dcdd19d"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:834ae7540ad3a83199a8da8f9f2d383e3c3d5130a328889e4cc991acc81e87a0"}, + {file = "tornado-6.3.2-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6a0848f1aea0d196a7c4f6772197cbe2abc4266f836b0aac76947872cd29b411"}, + {file = "tornado-6.3.2-cp38-abi3-win32.whl", hash = "sha256:7efcbcc30b7c654eb6a8c9c9da787a851c18f8ccd4a5a3a95b05c7accfa068d2"}, + {file = "tornado-6.3.2-cp38-abi3-win_amd64.whl", hash = "sha256:0c325e66c8123c606eea33084976c832aa4e766b7dff8aedd7587ea44a604cdf"}, + {file = "tornado-6.3.2.tar.gz", hash = "sha256:4b927c4f19b71e627b13f3db2324e4ae660527143f9e1f2e2fb404f3a187e2ba"}, ] tqdm = [ {file = "tqdm-4.65.0-py3-none-any.whl", hash = "sha256:c4f53a17fe37e132815abceec022631be8ffe1b9381c2e6e30aa70edc99e9671"}, @@ -4221,16 +4298,16 @@ traitlets = [ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ - {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, - {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, + {file = "typing_extensions-4.6.1-py3-none-any.whl", hash = "sha256:6bac751f4789b135c43228e72de18637e9a6c29d12777023a703fd1a6858469f"}, + {file = "typing_extensions-4.6.1.tar.gz", hash = "sha256:558bc0c4145f01e6405f4a5fdbd82050bd221b119f4bf72a961a1cfd471349d6"}, ] tzdata = [ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, {file = "tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, ] tzlocal = [ - {file = "tzlocal-4.3-py3-none-any.whl", hash = "sha256:b44c4388f3d34f25862cfbb387578a4d70fec417649da694a132f628a23367e2"}, - {file = "tzlocal-4.3.tar.gz", hash = "sha256:3f21d09e1b2aa9f2dacca12da240ca37de3ba5237a93addfd6d593afe9073355"}, + {file = "tzlocal-5.0.1-py3-none-any.whl", hash = "sha256:f3596e180296aaf2dbd97d124fe76ae3a0e3d32b258447de7b939b3fd4be992f"}, + {file = "tzlocal-5.0.1.tar.gz", hash = "sha256:46eb99ad4bdb71f3f72b7d24f4267753e240944ecfc16f25d2719ba89827a803"}, ] uri-template = [ {file = "uri_template-1.2.0-py3-none-any.whl", hash = "sha256:f1699c77b73b925cf4937eae31ab282a86dc885c333f2e942513f08f691fc7db"}, @@ -4241,12 +4318,15 @@ uritemplate = [ {file = "uritemplate-4.1.1.tar.gz", hash = "sha256:4346edfc5c3b79f694bccd6d6099a322bbeb628dbf2cd86eea55a456ce5124f0"}, ] urllib3 = [ - {file = "urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, - {file = "urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {file = "urllib3-1.26.16-py2.py3-none-any.whl", hash = "sha256:8d36afa7616d8ab714608411b4a3b13e58f463aee519024578e062e141dce20f"}, + {file = "urllib3-1.26.16.tar.gz", hash = "sha256:8f135f6502756bde6b2a9b28989df5fbe87c9970cecaa69041edcce7f0589b14"}, ] -uWSGI = [ +uwsgi = [ {file = "uwsgi-2.0.21.tar.gz", hash = "sha256:35a30d83791329429bc04fe44183ce4ab512fcf6968070a7bfba42fc5a0552a9"}, ] +validators = [ + {file = "validators-0.20.0.tar.gz", hash = "sha256:24148ce4e64100a2d5e267233e23e7afeb55316b47d30faae7eb6e7292bc226a"}, +] wcwidth = [ {file = "wcwidth-0.2.6-py2.py3-none-any.whl", hash = "sha256:795b138f6875577cd91bba52baf9e445cd5118fd32723b460e30a0af30ea230e"}, {file = "wcwidth-0.2.6.tar.gz", hash = "sha256:a5220780a404dbe3353789870978e472cfe477761f06ee55077256e509b156d0"}, @@ -4260,8 +4340,8 @@ webencodings = [ {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, ] websocket-client = [ - {file = "websocket-client-1.5.1.tar.gz", hash = "sha256:3f09e6d8230892547132177f575a4e3e73cfdf06526e20cc02aa1c3b47184d40"}, - {file = "websocket_client-1.5.1-py3-none-any.whl", hash = "sha256:cdf5877568b7e83aa7cf2244ab56a3213de587bbe0ce9d8b9600fc77b455d89e"}, + {file = "websocket-client-1.5.2.tar.gz", hash = "sha256:c7d67c13b928645f259d9b847ab5b57fd2d127213ca41ebd880de1f553b7c23b"}, + {file = "websocket_client-1.5.2-py3-none-any.whl", hash = "sha256:f8c64e28cd700e7ba1f04350d66422b6833b82a796b525a51e740b8cc8dab4b1"}, ] werkzeug = [ {file = "Werkzeug-2.1.2-py3-none-any.whl", hash = "sha256:72a4b735692dd3135217911cbeaa1be5fa3f62bffb8745c5215420a03dc55255"}, From 3dd111a2e38884158161b06f284aa294934bb66c Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 24 May 2023 09:48:53 -0700 Subject: [PATCH 589/615] remove depreciated function use --- schematic/store/synapse.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/schematic/store/synapse.py b/schematic/store/synapse.py index e7e9a07c9..1f77715b0 100644 --- a/schematic/store/synapse.py +++ b/schematic/store/synapse.py @@ -42,7 +42,6 @@ from schematic_db.synapse.synapse import SynapseConfig from schematic_db.rdb.synapse_database import SynapseDatabase -from schematic_db.schema.schema import get_key_attribute from schematic.utils.df_utils import update_df, load_df, col_in_dataframe, populate_df_col_with_another_col @@ -1014,7 +1013,7 @@ def buildDB(self, existing_tables=self.get_table_info(datasetId=datasetId) tableId=existing_tables[table_name] annos = self.syn.get_annotations(tableId) - annos['primary_key'] = get_key_attribute(table_manifest['Component'][0]) + annos['primary_key'] = table_manifest['Component'][0] + "_id" annos = self.syn.set_annotations(annos) return manifest_table_id From c3814e713a244025245945565fcd03e1f5128c14 Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Thu, 25 May 2023 15:19:32 -0700 Subject: [PATCH 590/615] restrict `typing-extensions` to versions before `4.6.0` --- poetry.lock | 51 +++++++++++++++++++++++++++++++------------------- pyproject.toml | 1 + 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4e6936cc3..669437674 100644 --- a/poetry.lock +++ b/poetry.lock @@ -555,7 +555,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.86.0" +version = "2.87.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -1068,7 +1068,7 @@ test = ["click", "coverage", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>= [[package]] name = "jupyter-server" -version = "2.5.0" +version = "2.6.0" description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." category = "main" optional = false @@ -1080,10 +1080,11 @@ argon2-cffi = "*" jinja2 = "*" jupyter-client = ">=7.4.4" jupyter-core = ">=4.12,<5.0.0 || >=5.1.0" -jupyter-events = ">=0.4.0" +jupyter-events = ">=0.6.0" jupyter-server-terminals = "*" nbconvert = ">=6.4.4" nbformat = ">=5.3.0" +overrides = "*" packaging = "*" prometheus-client = "*" pywinpty = {version = "*", markers = "os_name == \"nt\""} @@ -1095,7 +1096,7 @@ traitlets = ">=5.6.0" websocket-client = "*" [package.extras] -docs = ["docutils (<0.20)", "ipykernel", "jinja2", "jupyter-client", "jupyter-server", "mistune (<1.0.0)", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] test = ["ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] [[package]] @@ -1476,6 +1477,14 @@ python-versions = ">=3.6" [package.dependencies] et-xmlfile = "*" +[[package]] +name = "overrides" +version = "7.3.1" +description = "A decorator to automatically detect mismatch when overriding a method." +category = "main" +optional = false +python-versions = ">=3.6" + [[package]] name = "packaging" version = "23.1" @@ -1609,7 +1618,7 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prometheus-client" -version = "0.16.0" +version = "0.17.0" description = "Python client for the Prometheus monitoring system." category = "main" optional = false @@ -1829,11 +1838,11 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no [[package]] name = "pytest-cov" -version = "4.0.0" +version = "4.1.0" description = "Pytest plugin for measuring coverage." category = "dev" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] coverage = {version = ">=5.2.1", extras = ["toml"]} @@ -2499,7 +2508,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.6.1" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -2650,7 +2659,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "4851b89cfd9ec278b4b65e633ca5adac284934f06c45e1adacdfd91620328e7a" +content-hash = "d78723d551cd222138d608505f89d9c0b38d400be2fda19dfa9a9773fb0e3a33" [metadata.files] alabaster = [ @@ -3076,8 +3085,8 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.86.0.tar.gz", hash = "sha256:3ca4e93821f4e9ac29b91ab0d9df168b42c8ad0fb8bff65b8c2ccb2d462b0464"}, - {file = "google_api_python_client-2.86.0-py2.py3-none-any.whl", hash = "sha256:0f320190ab9d5bd2fdb0cb894e8e53bb5e17d4888ee8dc4d26ba65ce378409e2"}, + {file = "google-api-python-client-2.87.0.tar.gz", hash = "sha256:bbea5869877c822d12d318943833d988497b3a18b9ca2386967118074db676f3"}, + {file = "google_api_python_client-2.87.0-py2.py3-none-any.whl", hash = "sha256:29b52232b159be72a79890b6d9f703cf6d8ebbec0ef6371c5670c1abeca5a9f9"}, ] google-auth = [ {file = "google-auth-2.18.1.tar.gz", hash = "sha256:d7a3249027e7f464fbbfd7ee8319a08ad09d2eea51578575c4bd360ffa049ccb"}, @@ -3258,8 +3267,8 @@ jupyter-events = [ {file = "jupyter_events-0.6.3.tar.gz", hash = "sha256:9a6e9995f75d1b7146b436ea24d696ce3a35bfa8bfe45e0c33c334c79464d0b3"}, ] jupyter-server = [ - {file = "jupyter_server-2.5.0-py3-none-any.whl", hash = "sha256:e6bc1e9e96d7c55b9ce9699ff6cb9a910581fe7349e27c40389acb67632e24c0"}, - {file = "jupyter_server-2.5.0.tar.gz", hash = "sha256:9fde612791f716fd34d610cd939704a9639643744751ba66e7ee8fdc9cead07e"}, + {file = "jupyter_server-2.6.0-py3-none-any.whl", hash = "sha256:19525a1515b5999618a91b3e99ec9f6869aa8c5ba73e0b6279fcda918b54ba36"}, + {file = "jupyter_server-2.6.0.tar.gz", hash = "sha256:ae4af349f030ed08dd78cb7ac1a03a92d886000380c9ea6283f3c542a81f4b06"}, ] jupyter-server-terminals = [ {file = "jupyter_server_terminals-0.4.4-py3-none-any.whl", hash = "sha256:75779164661cec02a8758a5311e18bb8eb70c4e86c6b699403100f1585a12a36"}, @@ -3485,6 +3494,10 @@ openpyxl = [ {file = "openpyxl-3.1.2-py2.py3-none-any.whl", hash = "sha256:f91456ead12ab3c6c2e9491cf33ba6d08357d802192379bb482f1033ade496f5"}, {file = "openpyxl-3.1.2.tar.gz", hash = "sha256:a6f5977418eff3b2d5500d54d9db50c8277a368436f4e4f8ddb1be3422870184"}, ] +overrides = [ + {file = "overrides-7.3.1-py3-none-any.whl", hash = "sha256:6187d8710a935d09b0bcef8238301d6ee2569d2ac1ae0ec39a8c7924e27f58ca"}, + {file = "overrides-7.3.1.tar.gz", hash = "sha256:8b97c6c1e1681b78cbc9424b138d880f0803c2254c5ebaabdde57bb6c62093f2"}, +] packaging = [ {file = "packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, {file = "packaging-23.1.tar.gz", hash = "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f"}, @@ -3554,8 +3567,8 @@ pluggy = [ {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, ] prometheus-client = [ - {file = "prometheus_client-0.16.0-py3-none-any.whl", hash = "sha256:0836af6eb2c8f4fed712b2f279f6c0a8bbab29f9f4aa15276b91c7cb0d1616ab"}, - {file = "prometheus_client-0.16.0.tar.gz", hash = "sha256:a03e35b359f14dd1630898543e2120addfdeacd1a6069c1367ae90fd93ad3f48"}, + {file = "prometheus_client-0.17.0-py3-none-any.whl", hash = "sha256:a77b708cf083f4d1a3fb3ce5c95b4afa32b9c521ae363354a4a910204ea095ce"}, + {file = "prometheus_client-0.17.0.tar.gz", hash = "sha256:9c3b26f1535945e85b8934fb374678d263137b78ef85f305b1156c7c881cd11b"}, ] prompt-toolkit = [ {file = "prompt_toolkit-3.0.38-py3-none-any.whl", hash = "sha256:45ea77a2f7c60418850331366c81cf6b5b9cf4c7fd34616f733c5427e6abbb1f"}, @@ -3712,8 +3725,8 @@ pytest = [ {file = "pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, ] pytest-cov = [ - {file = "pytest-cov-4.0.0.tar.gz", hash = "sha256:996b79efde6433cdbd0088872dbc5fb3ed7fe1578b68cdbba634f14bb8dd0470"}, - {file = "pytest_cov-4.0.0-py3-none-any.whl", hash = "sha256:2feb1b751d66a8bd934e5edfa2e961d11309dc37b73b0eabe73b5945fee20f6b"}, + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, ] pytest-mock = [ {file = "pytest-mock-3.10.0.tar.gz", hash = "sha256:fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"}, @@ -4233,8 +4246,8 @@ traitlets = [ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ - {file = "typing_extensions-4.6.1-py3-none-any.whl", hash = "sha256:6bac751f4789b135c43228e72de18637e9a6c29d12777023a703fd1a6858469f"}, - {file = "typing_extensions-4.6.1.tar.gz", hash = "sha256:558bc0c4145f01e6405f4a5fdbd82050bd221b119f4bf72a961a1cfd471349d6"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] tzdata = [ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, diff --git a/pyproject.toml b/pyproject.toml index 97f173092..a6c858bde 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,6 +72,7 @@ dateparser = "^1.1.4" pandarallel = "^1.6.4" schematic-db = {version = "^0.0.6", extras = ["synapse"]} pyopenssl = "^23.0.0" +typing-extensions = "<4.6.0" [tool.poetry.dev-dependencies] pytest = "^7.0.0" From c0057809b540c1df315b1aa115a5266fe443c3e1 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 29 May 2023 09:42:34 -0400 Subject: [PATCH 591/615] add a line to install dependencies --- Dockerfile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 3117c63c4..b7488c21e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,4 +27,6 @@ RUN poetry config virtualenvs.create false RUN poetry install --no-interaction --no-ansi --no-root -COPY . ./ \ No newline at end of file +COPY . ./ + +RUN poetry install --only-root \ No newline at end of file From 1a173394a9c3da152215a5359d8eaee631c2f46f Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 29 May 2023 14:49:44 -0400 Subject: [PATCH 592/615] prevent minor releases from publishing --- .github/workflows/docker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index 6b9f5a3df..58f903f76 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -5,7 +5,7 @@ name: Build and publish container to Docker Hub on: push: - tags: ['v[0-9]*', '[0-9]+.[0-9]+*'] # Match tags that resemble a version + tags: ['^v\d+\.\d+\.\d+$'] # Match tags that resemble a version, but exclude minior releases. For example, v0.1.1-beta would not get included workflow_dispatch: jobs: From 50a4776923249daffdb160852ddfdd8e3c9e2b3a Mon Sep 17 00:00:00 2001 From: Gianna Jordan <61707471+GiaJordan@users.noreply.github.com> Date: Wed, 31 May 2023 11:07:32 -0700 Subject: [PATCH 593/615] regen .lock file --- poetry.lock | 420 +++++++++++++++++++++++++++------------------------- 1 file changed, 215 insertions(+), 205 deletions(-) diff --git a/poetry.lock b/poetry.lock index b8b18c8c3..b52c2d473 100644 --- a/poetry.lock +++ b/poetry.lock @@ -27,20 +27,21 @@ dev = ["black", "docutils", "flake8", "ipython", "m2r", "mistune (<2.0.0)", "pyt [[package]] name = "anyio" -version = "3.6.2" +version = "3.7.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" category = "main" optional = false -python-versions = ">=3.6.2" +python-versions = ">=3.7" [package.dependencies] +exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" [package.extras] -doc = ["packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["contextlib2", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (<0.15)", "uvloop (>=0.15)"] -trio = ["trio (>=0.16,<0.22)"] +doc = ["Sphinx (>=6.1.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme", "sphinxcontrib-jquery"] +test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (<0.22)"] [[package]] name = "appnope" @@ -204,11 +205,11 @@ css = ["tinycss2 (>=1.1.0,<1.2)"] [[package]] name = "cachetools" -version = "5.3.0" +version = "5.3.1" description = "Extensible memoizing collections and decorators" category = "main" optional = false -python-versions = "~=3.7" +python-versions = ">=3.7" [[package]] name = "certifi" @@ -324,7 +325,7 @@ tests = ["MarkupSafe (>=0.23)", "aiohttp (>=2.3.10,<4)", "aiohttp-jinja2 (>=0.14 [[package]] name = "coverage" -version = "7.2.6" +version = "7.2.7" description = "Code coverage measurement for Python" category = "dev" optional = false @@ -338,11 +339,11 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "40.0.2" +version = "41.0.0" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" [package.dependencies] cffi = ">=1.12" @@ -350,12 +351,12 @@ cffi = ">=1.12" [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] -pep8test = ["black", "check-manifest", "mypy", "ruff"] -sdist = ["setuptools-rust (>=0.11.4)"] +nox = ["nox"] +pep8test = ["black", "check-sdist", "mypy", "ruff"] +sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] -tox = ["tox"] [[package]] name = "dateparser" @@ -402,7 +403,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "deprecated" -version = "1.2.13" +version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." category = "main" optional = false @@ -412,7 +413,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" wrapt = ">=1.10,<2" [package.extras] -dev = ["PyTest", "PyTest (<5)", "PyTest-Cov", "PyTest-Cov (<2.6)", "bump2version (<1)", "configparser (<5)", "importlib-metadata (<3)", "importlib-resources (<4)", "sphinx (<2)", "sphinxcontrib-websupport (<2)", "tox", "zipp (<2)"] +dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] [[package]] name = "dill" @@ -453,7 +454,7 @@ python-versions = ">=3.6" name = "exceptiongroup" version = "1.1.1" description = "Backport of PEP 654 (exception groups)" -category = "dev" +category = "main" optional = false python-versions = ">=3.7" @@ -555,7 +556,7 @@ grpcio-gcp = ["grpcio-gcp (>=0.2.2,<1.0dev)"] [[package]] name = "google-api-python-client" -version = "2.87.0" +version = "2.88.0" description = "Google API Client Library for Python" category = "main" optional = false @@ -570,16 +571,16 @@ uritemplate = ">=3.0.1,<5" [[package]] name = "google-auth" -version = "2.18.1" +version = "2.19.0" description = "Google Authentication Library" category = "main" optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*" +python-versions = ">=3.6" [package.dependencies] cachetools = ">=2.0.0,<6.0" pyasn1-modules = ">=0.2.1" -rsa = {version = ">=3.1.4,<5", markers = "python_version >= \"3.6\""} +rsa = ">=3.1.4,<5" six = ">=1.9.0" urllib3 = "<2.0" @@ -1368,11 +1369,11 @@ webpdf = ["pyppeteer (>=1,<1.1)"] [[package]] name = "nbformat" -version = "5.8.0" +version = "5.9.0" description = "The Jupyter Notebook format" category = "main" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" [package.dependencies] fastjsonschema = "*" @@ -1662,7 +1663,7 @@ wcwidth = "*" [[package]] name = "protobuf" -version = "4.23.1" +version = "4.23.2" description = "" category = "main" optional = false @@ -1815,14 +1816,14 @@ testutils = ["gitpython (>3)"] [[package]] name = "pyopenssl" -version = "23.1.1" +version = "23.2.0" description = "Python wrapper module around the OpenSSL library" category = "main" optional = false python-versions = ">=3.6" [package.dependencies] -cryptography = ">=38.0.0,<41" +cryptography = ">=38.0.0,<40.0.0 || >40.0.0,<40.0.1 || >40.0.1,<42" [package.extras] docs = ["sphinx (!=5.2.0,!=5.2.0.post0)", "sphinx-rtd-theme"] @@ -1967,7 +1968,7 @@ python-versions = ">=3.6" [[package]] name = "pyzmq" -version = "25.0.2" +version = "25.1.0" description = "Python bindings for 0MQ" category = "main" optional = false @@ -2547,7 +2548,7 @@ test = ["argcomplete (>=2.0)", "pre-commit", "pytest", "pytest-mock"] [[package]] name = "typing-extensions" -version = "4.6.1" +version = "4.5.0" description = "Backported and Experimental Type Hints for Python 3.7+" category = "main" optional = false @@ -2712,7 +2713,7 @@ testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more [metadata] lock-version = "1.1" python-versions = ">=3.9.0,<3.11" -content-hash = "d78723d551cd222138d608505f89d9c0b38d400be2fda19dfa9a9773fb0e3a33" +content-hash = "b20d2b7dcf507cfe6397de135cbf25eca23c9c6241a5900199e59ae88dfc00d4" [metadata.files] alabaster = [ @@ -2724,8 +2725,8 @@ altair = [ {file = "altair-4.2.0.tar.gz", hash = "sha256:d87d9372e63b48cd96b2a6415f0cf9457f50162ab79dc7a31cd7e024dd840026"}, ] anyio = [ - {file = "anyio-3.6.2-py3-none-any.whl", hash = "sha256:fbbe32bd270d2a2ef3ed1c5d45041250284e31fc0a4df4a5a6071842051a51e3"}, - {file = "anyio-3.6.2.tar.gz", hash = "sha256:25ea0d673ae30af41a0c442f81cf3b38c7e79fdc7b60335a4c14e05eb0947421"}, + {file = "anyio-3.7.0-py3-none-any.whl", hash = "sha256:eddca883c4175f14df8aedce21054bfca3adb70ffe76a9f607aef9d7fa2ea7f0"}, + {file = "anyio-3.7.0.tar.gz", hash = "sha256:275d9973793619a5374e1c89a4f4ad3f4b0a5510a2b5b939444bee8f4c4d37ce"}, ] appnope = [ {file = "appnope-0.1.3-py2.py3-none-any.whl", hash = "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e"}, @@ -2805,8 +2806,8 @@ bleach = [ {file = "bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, ] cachetools = [ - {file = "cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"}, - {file = "cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, + {file = "cachetools-5.3.1-py3-none-any.whl", hash = "sha256:95ef631eeaea14ba2e36f06437f36463aac3a096799e876ee55e5cdccb102590"}, + {file = "cachetools-5.3.1.tar.gz", hash = "sha256:dce83f2d9b4e1f732a8cd44af8e8fab2dbe46201467fc98b3ef8f269092bf62b"}, ] certifi = [ {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, @@ -2980,78 +2981,87 @@ connexion = [ {file = "connexion-2.14.2.tar.gz", hash = "sha256:dbc06f52ebeebcf045c9904d570f24377e8bbd5a6521caef15a06f634cf85646"}, ] coverage = [ - {file = "coverage-7.2.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:496b86f1fc9c81a1cd53d8842ef712e950a4611bba0c42d33366a7b91ba969ec"}, - {file = "coverage-7.2.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fbe6e8c0a9a7193ba10ee52977d4d5e7652957c1f56ccefed0701db8801a2a3b"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d06b721c2550c01a60e5d3093f417168658fb454e5dfd9a23570e9bffe39a1"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:77a04b84d01f0e12c66f16e69e92616442dc675bbe51b90bfb074b1e5d1c7fbd"}, - {file = "coverage-7.2.6-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35db06450272473eab4449e9c2ad9bc6a0a68dab8e81a0eae6b50d9c2838767e"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6727a0d929ff0028b1ed8b3e7f8701670b1d7032f219110b55476bb60c390bfb"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aac1d5fdc5378f6bac2c0c7ebe7635a6809f5b4376f6cf5d43243c1917a67087"}, - {file = "coverage-7.2.6-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1c9e4a5eb1bbc3675ee57bc31f8eea4cd7fb0cbcbe4912cf1cb2bf3b754f4a80"}, - {file = "coverage-7.2.6-cp310-cp310-win32.whl", hash = "sha256:71f739f97f5f80627f1fee2331e63261355fd1e9a9cce0016394b6707ac3f4ec"}, - {file = "coverage-7.2.6-cp310-cp310-win_amd64.whl", hash = "sha256:fde5c7a9d9864d3e07992f66767a9817f24324f354caa3d8129735a3dc74f126"}, - {file = "coverage-7.2.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bc7b667f8654376e9353dd93e55e12ce2a59fb6d8e29fce40de682273425e044"}, - {file = "coverage-7.2.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:697f4742aa3f26c107ddcb2b1784a74fe40180014edbd9adaa574eac0529914c"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:541280dde49ce74a4262c5e395b48ea1207e78454788887118c421cb4ffbfcac"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e7f1a8328eeec34c54f1d5968a708b50fc38d31e62ca8b0560e84a968fbf9a9"}, - {file = "coverage-7.2.6-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bbd58eb5a2371bf160590f4262109f66b6043b0b991930693134cb617bc0169"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ae82c5f168d2a39a5d69a12a69d4dc23837a43cf2ca99be60dfe59996ea6b113"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:f5440cdaf3099e7ab17a5a7065aed59aff8c8b079597b61c1f8be6f32fe60636"}, - {file = "coverage-7.2.6-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a6f03f87fea579d55e0b690d28f5042ec1368650466520fbc400e7aeaf09e995"}, - {file = "coverage-7.2.6-cp311-cp311-win32.whl", hash = "sha256:dc4d5187ef4d53e0d4c8eaf530233685667844c5fb0b855fea71ae659017854b"}, - {file = "coverage-7.2.6-cp311-cp311-win_amd64.whl", hash = "sha256:c93d52c3dc7b9c65e39473704988602300e3cc1bad08b5ab5b03ca98bbbc68c1"}, - {file = "coverage-7.2.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:42c692b55a647a832025a4c048007034fe77b162b566ad537ce65ad824b12a84"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7786b2fa7809bf835f830779ad285215a04da76293164bb6745796873f0942d"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25bad4196104761bc26b1dae9b57383826542ec689ff0042f7f4f4dd7a815cba"}, - {file = "coverage-7.2.6-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2692306d3d4cb32d2cceed1e47cebd6b1d2565c993d6d2eda8e6e6adf53301e6"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:392154d09bd4473b9d11351ab5d63391f3d5d24d752f27b3be7498b0ee2b5226"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fa079995432037b5e2ef5ddbb270bcd2ded9f52b8e191a5de11fe59a00ea30d8"}, - {file = "coverage-7.2.6-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d712cefff15c712329113b01088ba71bbcef0f7ea58478ca0bbec63a824844cb"}, - {file = "coverage-7.2.6-cp37-cp37m-win32.whl", hash = "sha256:004948e296149644d208964300cb3d98affc5211e9e490e9979af4030b0d6473"}, - {file = "coverage-7.2.6-cp37-cp37m-win_amd64.whl", hash = "sha256:c1d7a31603c3483ac49c1726723b0934f88f2c011c660e6471e7bd735c2fa110"}, - {file = "coverage-7.2.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3436927d1794fa6763b89b60c896f9e3bd53212001026ebc9080d23f0c2733c1"}, - {file = "coverage-7.2.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44c9b9f1a245f3d0d202b1a8fa666a80b5ecbe4ad5d0859c0fb16a52d9763224"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e3783a286d5a93a2921396d50ce45a909aa8f13eee964465012f110f0cbb611"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cff6980fe7100242170092bb40d2b1cdad79502cd532fd26b12a2b8a5f9aee0"}, - {file = "coverage-7.2.6-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c534431153caffc7c495c3eddf7e6a6033e7f81d78385b4e41611b51e8870446"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3062fd5c62df988cea9f2972c593f77fed1182bfddc5a3b12b1e606cb7aba99e"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6284a2005e4f8061c58c814b1600ad0074ccb0289fe61ea709655c5969877b70"}, - {file = "coverage-7.2.6-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:97729e6828643f168a2a3f07848e1b1b94a366b13a9f5aba5484c2215724edc8"}, - {file = "coverage-7.2.6-cp38-cp38-win32.whl", hash = "sha256:dc11b42fa61ff1e788dd095726a0aed6aad9c03d5c5984b54cb9e1e67b276aa5"}, - {file = "coverage-7.2.6-cp38-cp38-win_amd64.whl", hash = "sha256:cbcc874f454ee51f158afd604a315f30c0e31dff1d5d5bf499fc529229d964dd"}, - {file = "coverage-7.2.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3cacc6a665221108ecdf90517a8028d07a2783df3417d12dcfef1c517e67478"}, - {file = "coverage-7.2.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:272ab31228a9df857ab5df5d67936d8861464dc89c5d3fab35132626e9369379"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9a8723ccec4e564d4b9a79923246f7b9a8de4ec55fa03ec4ec804459dade3c4f"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5906f6a84b47f995cd1bf0aca1c72d591c55ee955f98074e93660d64dfc66eb9"}, - {file = "coverage-7.2.6-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52c139b7ab3f0b15f9aad0a3fedef5a1f8c0b2bdc291d88639ca2c97d3682416"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:a5ffd45c6b93c23a8507e2f436983015c6457aa832496b6a095505ca2f63e8f1"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:4f3c7c19581d471af0e9cb49d928172cd8492cd78a2b7a4e82345d33662929bb"}, - {file = "coverage-7.2.6-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:2e8c0e79820cdd67978e1120983786422d279e07a381dbf89d03bbb23ec670a6"}, - {file = "coverage-7.2.6-cp39-cp39-win32.whl", hash = "sha256:13cde6bb0e58fb67d09e2f373de3899d1d1e866c5a9ff05d93615f2f54fbd2bb"}, - {file = "coverage-7.2.6-cp39-cp39-win_amd64.whl", hash = "sha256:6b9f64526286255735847aed0221b189486e0b9ed943446936e41b7e44b08783"}, - {file = "coverage-7.2.6-pp37.pp38.pp39-none-any.whl", hash = "sha256:6babcbf1e66e46052442f10833cfc4a0d3554d8276aa37af8531a83ed3c1a01d"}, - {file = "coverage-7.2.6.tar.gz", hash = "sha256:2025f913f2edb0272ef15d00b1f335ff8908c921c8eb2013536fcaf61f5a683d"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, + {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, + {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, + {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, + {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, + {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, + {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, + {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, + {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, + {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, + {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, + {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, + {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, + {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, + {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, + {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, + {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, + {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, + {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, + {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, + {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, + {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, + {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, + {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, + {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, + {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, + {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, + {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, + {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, + {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, + {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, + {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, + {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, ] cryptography = [ - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, - {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, - {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, - {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, - {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, - {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, - {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, - {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, - {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, + {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c5ef25d060c80d6d9f7f9892e1d41bb1c79b78ce74805b8cb4aa373cb7d5ec8"}, + {file = "cryptography-41.0.0-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:8362565b3835ceacf4dc8f3b56471a2289cf51ac80946f9087e66dc283a810e0"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3680248309d340fda9611498a5319b0193a8dbdb73586a1acf8109d06f25b92d"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a165379cb9d411d58ed739e4af3396e544eac190805a54ba2e0322feb55c46"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4ab14d567f7bbe7f1cdff1c53d5324ed4d3fc8bd17c481b395db224fb405c237"}, + {file = "cryptography-41.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:9f65e842cb02550fac96536edb1d17f24c0a338fd84eaf582be25926e993dde4"}, + {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:b7f2f5c525a642cecad24ee8670443ba27ac1fab81bba4cc24c7b6b41f2d0c75"}, + {file = "cryptography-41.0.0-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:7d92f0248d38faa411d17f4107fc0bce0c42cae0b0ba5415505df72d751bf62d"}, + {file = "cryptography-41.0.0-cp37-abi3-win32.whl", hash = "sha256:34d405ea69a8b34566ba3dfb0521379b210ea5d560fafedf9f800a9a94a41928"}, + {file = "cryptography-41.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:344c6de9f8bda3c425b3a41b319522ba3208551b70c2ae00099c205f0d9fd3be"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:88ff107f211ea696455ea8d911389f6d2b276aabf3231bf72c8853d22db755c5"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b846d59a8d5a9ba87e2c3d757ca019fa576793e8758174d3868aecb88d6fc8eb"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5d0bf9b252f30a31664b6f64432b4730bb7038339bd18b1fafe129cfc2be9be"}, + {file = "cryptography-41.0.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5c1f7293c31ebc72163a9a0df246f890d65f66b4a40d9ec80081969ba8c78cc9"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf8fc66012ca857d62f6a347007e166ed59c0bc150cefa49f28376ebe7d992a2"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a4fc68d1c5b951cfb72dfd54702afdbbf0fb7acdc9b7dc4301bbf2225a27714d"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:14754bcdae909d66ff24b7b5f166d69340ccc6cb15731670435efd5719294895"}, + {file = "cryptography-41.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0ddaee209d1cf1f180f1efa338a68c4621154de0afaef92b89486f5f96047c55"}, + {file = "cryptography-41.0.0.tar.gz", hash = "sha256:6b71f64beeea341c9b4f963b48ee3b62d62d57ba93eb120e1196b31dc1025e78"}, ] dateparser = [ {file = "dateparser-1.1.8-py2.py3-none-any.whl", hash = "sha256:070b29b5bbf4b1ec2cd51c96ea040dc68a614de703910a91ad1abba18f9f379f"}, @@ -3086,8 +3096,8 @@ defusedxml = [ {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, ] deprecated = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, + {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, + {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, ] dill = [ {file = "dill-0.3.6-py3-none-any.whl", hash = "sha256:a07ffd2351b8c678dfc4a856a3005f8067aea51d6ba6c700796a4d9e280f39f0"}, @@ -3138,12 +3148,12 @@ google-api-core = [ {file = "google_api_core-2.11.0-py3-none-any.whl", hash = "sha256:ce222e27b0de0d7bc63eb043b956996d6dccab14cc3b690aaea91c9cc99dc16e"}, ] google-api-python-client = [ - {file = "google-api-python-client-2.87.0.tar.gz", hash = "sha256:bbea5869877c822d12d318943833d988497b3a18b9ca2386967118074db676f3"}, - {file = "google_api_python_client-2.87.0-py2.py3-none-any.whl", hash = "sha256:29b52232b159be72a79890b6d9f703cf6d8ebbec0ef6371c5670c1abeca5a9f9"}, + {file = "google-api-python-client-2.88.0.tar.gz", hash = "sha256:37068453f79ea28e5394a8fe20a4ba620594e7f8541068bea2e844dacdcc9d33"}, + {file = "google_api_python_client-2.88.0-py2.py3-none-any.whl", hash = "sha256:d003008400a779524ea21b5a3ddc6fc59327d401fb8c37c466d413694c279cae"}, ] google-auth = [ - {file = "google-auth-2.18.1.tar.gz", hash = "sha256:d7a3249027e7f464fbbfd7ee8319a08ad09d2eea51578575c4bd360ffa049ccb"}, - {file = "google_auth-2.18.1-py2.py3-none-any.whl", hash = "sha256:55a395cdfd3f3dd3f649131d41f97c17b4ed8a2aac1be3502090c716314e8a37"}, + {file = "google-auth-2.19.0.tar.gz", hash = "sha256:f39d528077ac540793dd3c22a8706178f157642a67d874db25c640b7fead277e"}, + {file = "google_auth-2.19.0-py2.py3-none-any.whl", hash = "sha256:be617bfaf77774008e9d177573f782e109188c8a64ae6e744285df5cea3e7df6"}, ] google-auth-httplib2 = [ {file = "google-auth-httplib2-0.1.0.tar.gz", hash = "sha256:a07c39fd632becacd3f07718dfd6021bf396978f03ad3ce4321d060015cc30ac"}, @@ -3490,8 +3500,8 @@ nbconvert = [ {file = "nbconvert-7.4.0.tar.gz", hash = "sha256:51b6c77b507b177b73f6729dba15676e42c4e92bcb00edc8cc982ee72e7d89d7"}, ] nbformat = [ - {file = "nbformat-5.8.0-py3-none-any.whl", hash = "sha256:d910082bd3e0bffcf07eabf3683ed7dda0727a326c446eeb2922abe102e65162"}, - {file = "nbformat-5.8.0.tar.gz", hash = "sha256:46dac64c781f1c34dfd8acba16547024110348f9fc7eab0f31981c2a3dc48d1f"}, + {file = "nbformat-5.9.0-py3-none-any.whl", hash = "sha256:8c8fa16d6d05062c26177754bfbfac22de644888e2ef69d27ad2a334cf2576e5"}, + {file = "nbformat-5.9.0.tar.gz", hash = "sha256:e98ebb6120c3efbafdee2a40af2a140cadee90bb06dd69a2a63d9551fcc7f976"}, ] nest-asyncio = [ {file = "nest_asyncio-1.5.6-py3-none-any.whl", hash = "sha256:b9a953fb40dceaa587d109609098db21900182b16440652454a146cffb06e8b8"}, @@ -3632,19 +3642,19 @@ prompt-toolkit = [ {file = "prompt_toolkit-3.0.38.tar.gz", hash = "sha256:23ac5d50538a9a38c8bde05fecb47d0b403ecd0662857a86f886f798563d5b9b"}, ] protobuf = [ - {file = "protobuf-4.23.1-cp310-abi3-win32.whl", hash = "sha256:410bcc0a5b279f634d3e16082ce221dfef7c3392fac723500e2e64d1806dd2be"}, - {file = "protobuf-4.23.1-cp310-abi3-win_amd64.whl", hash = "sha256:32e78beda26d7a101fecf15d7a4a792278a0d26a31bc327ff05564a9d68ab8ee"}, - {file = "protobuf-4.23.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f9510cac91e764e86acd74e2b7f7bc5e6127a7f3fb646d7c8033cfb84fd1176a"}, - {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:346990f634272caac1f09efbcfbbacb23098b1f606d172534c6fa2d9758bb436"}, - {file = "protobuf-4.23.1-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:3ce113b3f3362493bddc9069c2163a38f240a9ed685ff83e7bcb756b05e1deb0"}, - {file = "protobuf-4.23.1-cp37-cp37m-win32.whl", hash = "sha256:2036a3a1e7fc27f973fa0a7888dce712393af644f4695385f117886abc792e39"}, - {file = "protobuf-4.23.1-cp37-cp37m-win_amd64.whl", hash = "sha256:3b8905eafe4439076e1f58e9d1fa327025fd2777cf90f14083092ae47f77b0aa"}, - {file = "protobuf-4.23.1-cp38-cp38-win32.whl", hash = "sha256:5b9cd6097e6acae48a68cb29b56bc79339be84eca65b486910bb1e7a30e2b7c1"}, - {file = "protobuf-4.23.1-cp38-cp38-win_amd64.whl", hash = "sha256:decf119d54e820f298ee6d89c72d6b289ea240c32c521f00433f9dc420595f38"}, - {file = "protobuf-4.23.1-cp39-cp39-win32.whl", hash = "sha256:91fac0753c3c4951fbb98a93271c43cc7cf3b93cf67747b3e600bb1e5cc14d61"}, - {file = "protobuf-4.23.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac50be82491369a9ec3710565777e4da87c6d2e20404e0abb1f3a8f10ffd20f0"}, - {file = "protobuf-4.23.1-py3-none-any.whl", hash = "sha256:65f0ac96ef67d7dd09b19a46aad81a851b6f85f89725577f16de38f2d68ad477"}, - {file = "protobuf-4.23.1.tar.gz", hash = "sha256:95789b569418a3e32a53f43d7763be3d490a831e9c08042539462b6d972c2d7e"}, + {file = "protobuf-4.23.2-cp310-abi3-win32.whl", hash = "sha256:384dd44cb4c43f2ccddd3645389a23ae61aeb8cfa15ca3a0f60e7c3ea09b28b3"}, + {file = "protobuf-4.23.2-cp310-abi3-win_amd64.whl", hash = "sha256:09310bce43353b46d73ba7e3bca78273b9bc50349509b9698e64d288c6372c2a"}, + {file = "protobuf-4.23.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:b2cfab63a230b39ae603834718db74ac11e52bccaaf19bf20f5cce1a84cf76df"}, + {file = "protobuf-4.23.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:c52cfcbfba8eb791255edd675c1fe6056f723bf832fa67f0442218f8817c076e"}, + {file = "protobuf-4.23.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:86df87016d290143c7ce3be3ad52d055714ebaebb57cc659c387e76cfacd81aa"}, + {file = "protobuf-4.23.2-cp37-cp37m-win32.whl", hash = "sha256:281342ea5eb631c86697e1e048cb7e73b8a4e85f3299a128c116f05f5c668f8f"}, + {file = "protobuf-4.23.2-cp37-cp37m-win_amd64.whl", hash = "sha256:ce744938406de1e64b91410f473736e815f28c3b71201302612a68bf01517fea"}, + {file = "protobuf-4.23.2-cp38-cp38-win32.whl", hash = "sha256:6c081863c379bb1741be8f8193e893511312b1d7329b4a75445d1ea9955be69e"}, + {file = "protobuf-4.23.2-cp38-cp38-win_amd64.whl", hash = "sha256:25e3370eda26469b58b602e29dff069cfaae8eaa0ef4550039cc5ef8dc004511"}, + {file = "protobuf-4.23.2-cp39-cp39-win32.whl", hash = "sha256:efabbbbac1ab519a514579ba9ec52f006c28ae19d97915951f69fa70da2c9e91"}, + {file = "protobuf-4.23.2-cp39-cp39-win_amd64.whl", hash = "sha256:54a533b971288af3b9926e53850c7eb186886c0c84e61daa8444385a4720297f"}, + {file = "protobuf-4.23.2-py3-none-any.whl", hash = "sha256:8da6070310d634c99c0db7df48f10da495cc283fd9e9234877f0cd182d43ab7f"}, + {file = "protobuf-4.23.2.tar.gz", hash = "sha256:20874e7ca4436f683b64ebdbee2129a5a2c301579a67d1a7dda2cdf62fb7f5f7"}, ] psutil = [ {file = "psutil-5.9.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:be8929ce4313f9f8146caad4272f6abb8bf99fc6cf59344a3167ecd74f4f203f"}, @@ -3745,8 +3755,8 @@ pylint = [ {file = "pylint-2.17.4.tar.gz", hash = "sha256:5dcf1d9e19f41f38e4e85d10f511e5b9c35e1aa74251bf95cdd8cb23584e2db1"}, ] pyopenssl = [ - {file = "pyOpenSSL-23.1.1-py3-none-any.whl", hash = "sha256:9e0c526404a210df9d2b18cd33364beadb0dc858a739b885677bc65e105d4a4c"}, - {file = "pyOpenSSL-23.1.1.tar.gz", hash = "sha256:841498b9bec61623b1b6c47ebbc02367c07d60e0e195f19790817f10cc8db0b7"}, + {file = "pyOpenSSL-23.2.0-py3-none-any.whl", hash = "sha256:24f0dc5227396b3e831f4c7f602b950a5e9833d292c8e4a2e06b709292806ae2"}, + {file = "pyOpenSSL-23.2.0.tar.gz", hash = "sha256:276f931f55a452e7dea69c7173e984eb2a4407ce413c918aa34b55f82f9b8bac"}, ] pyparsing = [ {file = "pyparsing-3.0.9-py3-none-any.whl", hash = "sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc"}, @@ -3880,83 +3890,83 @@ pyyaml = [ {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, ] pyzmq = [ - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ac178e666c097c8d3deb5097b58cd1316092fc43e8ef5b5fdb259b51da7e7315"}, - {file = "pyzmq-25.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:659e62e1cbb063151c52f5b01a38e1df6b54feccfa3e2509d44c35ca6d7962ee"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8280ada89010735a12b968ec3ea9a468ac2e04fddcc1cede59cb7f5178783b9c"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b5eeb5278a8a636bb0abdd9ff5076bcbb836cd2302565df53ff1fa7d106d54"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a2e5fe42dfe6b73ca120b97ac9f34bfa8414feb15e00e37415dbd51cf227ef6"}, - {file = "pyzmq-25.0.2-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:827bf60e749e78acb408a6c5af6688efbc9993e44ecc792b036ec2f4b4acf485"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7b504ae43d37e282301da586529e2ded8b36d4ee2cd5e6db4386724ddeaa6bbc"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb1f69a0a2a2b1aae8412979dd6293cc6bcddd4439bf07e4758d864ddb112354"}, - {file = "pyzmq-25.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2b9c9cc965cdf28381e36da525dcb89fc1571d9c54800fdcd73e3f73a2fc29bd"}, - {file = "pyzmq-25.0.2-cp310-cp310-win32.whl", hash = "sha256:24abbfdbb75ac5039205e72d6c75f10fc39d925f2df8ff21ebc74179488ebfca"}, - {file = "pyzmq-25.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6a821a506822fac55d2df2085a52530f68ab15ceed12d63539adc32bd4410f6e"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:9af0bb0277e92f41af35e991c242c9c71920169d6aa53ade7e444f338f4c8128"}, - {file = "pyzmq-25.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:54a96cf77684a3a537b76acfa7237b1e79a8f8d14e7f00e0171a94b346c5293e"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88649b19ede1cab03b96b66c364cbbf17c953615cdbc844f7f6e5f14c5e5261c"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:715cff7644a80a7795953c11b067a75f16eb9fc695a5a53316891ebee7f3c9d5"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:312b3f0f066b4f1d17383aae509bacf833ccaf591184a1f3c7a1661c085063ae"}, - {file = "pyzmq-25.0.2-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d488c5c8630f7e782e800869f82744c3aca4aca62c63232e5d8c490d3d66956a"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:38d9f78d69bcdeec0c11e0feb3bc70f36f9b8c44fc06e5d06d91dc0a21b453c7"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:3059a6a534c910e1d5d068df42f60d434f79e6cc6285aa469b384fa921f78cf8"}, - {file = "pyzmq-25.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6526d097b75192f228c09d48420854d53dfbc7abbb41b0e26f363ccb26fbc177"}, - {file = "pyzmq-25.0.2-cp311-cp311-win32.whl", hash = "sha256:5c5fbb229e40a89a2fe73d0c1181916f31e30f253cb2d6d91bea7927c2e18413"}, - {file = "pyzmq-25.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:ed15e3a2c3c2398e6ae5ce86d6a31b452dfd6ad4cd5d312596b30929c4b6e182"}, - {file = "pyzmq-25.0.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:032f5c8483c85bf9c9ca0593a11c7c749d734ce68d435e38c3f72e759b98b3c9"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:374b55516393bfd4d7a7daa6c3b36d6dd6a31ff9d2adad0838cd6a203125e714"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:08bfcc21b5997a9be4fefa405341320d8e7f19b4d684fb9c0580255c5bd6d695"}, - {file = "pyzmq-25.0.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1a843d26a8da1b752c74bc019c7b20e6791ee813cd6877449e6a1415589d22ff"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b48616a09d7df9dbae2f45a0256eee7b794b903ddc6d8657a9948669b345f220"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:d4427b4a136e3b7f85516c76dd2e0756c22eec4026afb76ca1397152b0ca8145"}, - {file = "pyzmq-25.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:26b0358e8933990502f4513c991c9935b6c06af01787a36d133b7c39b1df37fa"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win32.whl", hash = "sha256:c8fedc3ccd62c6b77dfe6f43802057a803a411ee96f14e946f4a76ec4ed0e117"}, - {file = "pyzmq-25.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:2da6813b7995b6b1d1307329c73d3e3be2fd2d78e19acfc4eff2e27262732388"}, - {file = "pyzmq-25.0.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a35960c8b2f63e4ef67fd6731851030df68e4b617a6715dd11b4b10312d19fef"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eef2a0b880ab40aca5a878933376cb6c1ec483fba72f7f34e015c0f675c90b20"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:85762712b74c7bd18e340c3639d1bf2f23735a998d63f46bb6584d904b5e401d"}, - {file = "pyzmq-25.0.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:64812f29d6eee565e129ca14b0c785744bfff679a4727137484101b34602d1a7"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:510d8e55b3a7cd13f8d3e9121edf0a8730b87d925d25298bace29a7e7bc82810"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b164cc3c8acb3d102e311f2eb6f3c305865ecb377e56adc015cb51f721f1dda6"}, - {file = "pyzmq-25.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:28fdb9224a258134784a9cf009b59265a9dde79582fb750d4e88a6bcbc6fa3dc"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win32.whl", hash = "sha256:dd771a440effa1c36d3523bc6ba4e54ff5d2e54b4adcc1e060d8f3ca3721d228"}, - {file = "pyzmq-25.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:9bdc40efb679b9dcc39c06d25629e55581e4c4f7870a5e88db4f1c51ce25e20d"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:1f82906a2d8e4ee310f30487b165e7cc8ed09c009e4502da67178b03083c4ce0"}, - {file = "pyzmq-25.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:21ec0bf4831988af43c8d66ba3ccd81af2c5e793e1bf6790eb2d50e27b3c570a"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abbce982a17c88d2312ec2cf7673985d444f1beaac6e8189424e0a0e0448dbb3"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9e1d2f2d86fc75ed7f8845a992c5f6f1ab5db99747fb0d78b5e4046d041164d2"}, - {file = "pyzmq-25.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2e92ff20ad5d13266bc999a29ed29a3b5b101c21fdf4b2cf420c09db9fb690e"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edbbf06cc2719889470a8d2bf5072bb00f423e12de0eb9ffec946c2c9748e149"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:77942243ff4d14d90c11b2afd8ee6c039b45a0be4e53fb6fa7f5e4fd0b59da39"}, - {file = "pyzmq-25.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ab046e9cb902d1f62c9cc0eca055b1d11108bdc271caf7c2171487298f229b56"}, - {file = "pyzmq-25.0.2-cp38-cp38-win32.whl", hash = "sha256:ad761cfbe477236802a7ab2c080d268c95e784fe30cafa7e055aacd1ca877eb0"}, - {file = "pyzmq-25.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:8560756318ec7c4c49d2c341012167e704b5a46d9034905853c3d1ade4f55bee"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:ab2c056ac503f25a63f6c8c6771373e2a711b98b304614151dfb552d3d6c81f6"}, - {file = "pyzmq-25.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:cca8524b61c0eaaa3505382dc9b9a3bc8165f1d6c010fdd1452c224225a26689"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:cfb9f7eae02d3ac42fbedad30006b7407c984a0eb4189a1322241a20944d61e5"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5eaeae038c68748082137d6896d5c4db7927e9349237ded08ee1bbd94f7361c9"}, - {file = "pyzmq-25.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a31992a8f8d51663ebf79df0df6a04ffb905063083d682d4380ab8d2c67257c"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6a979e59d2184a0c8f2ede4b0810cbdd86b64d99d9cc8a023929e40dce7c86cc"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:1f124cb73f1aa6654d31b183810febc8505fd0c597afa127c4f40076be4574e0"}, - {file = "pyzmq-25.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:65c19a63b4a83ae45d62178b70223adeee5f12f3032726b897431b6553aa25af"}, - {file = "pyzmq-25.0.2-cp39-cp39-win32.whl", hash = "sha256:83d822e8687621bed87404afc1c03d83fa2ce39733d54c2fd52d8829edb8a7ff"}, - {file = "pyzmq-25.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:24683285cc6b7bf18ad37d75b9db0e0fefe58404e7001f1d82bf9e721806daa7"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a4b4261eb8f9ed71f63b9eb0198dd7c934aa3b3972dac586d0ef502ba9ab08b"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:62ec8d979f56c0053a92b2b6a10ff54b9ec8a4f187db2b6ec31ee3dd6d3ca6e2"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:affec1470351178e892121b3414c8ef7803269f207bf9bef85f9a6dd11cde264"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffc71111433bd6ec8607a37b9211f4ef42e3d3b271c6d76c813669834764b248"}, - {file = "pyzmq-25.0.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6fadc60970714d86eff27821f8fb01f8328dd36bebd496b0564a500fe4a9e354"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:269968f2a76c0513490aeb3ba0dc3c77b7c7a11daa894f9d1da88d4a0db09835"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f7c8b8368e84381ae7c57f1f5283b029c888504aaf4949c32e6e6fb256ec9bf0"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25e6873a70ad5aa31e4a7c41e5e8c709296edef4a92313e1cd5fc87bbd1874e2"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b733076ff46e7db5504c5e7284f04a9852c63214c74688bdb6135808531755a3"}, - {file = "pyzmq-25.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a6f6ae12478fdc26a6d5fdb21f806b08fa5403cd02fd312e4cb5f72df078f96f"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:67da1c213fbd208906ab3470cfff1ee0048838365135a9bddc7b40b11e6d6c89"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:531e36d9fcd66f18de27434a25b51d137eb546931033f392e85674c7a7cea853"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:34a6fddd159ff38aa9497b2e342a559f142ab365576284bc8f77cb3ead1f79c5"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b491998ef886662c1f3d49ea2198055a9a536ddf7430b051b21054f2a5831800"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:5d496815074e3e3d183fe2c7fcea2109ad67b74084c254481f87b64e04e9a471"}, - {file = "pyzmq-25.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:56a94ab1d12af982b55ca96c6853db6ac85505e820d9458ac76364c1998972f4"}, - {file = "pyzmq-25.0.2.tar.gz", hash = "sha256:6b8c1bbb70e868dc88801aa532cae6bd4e3b5233784692b786f17ad2962e5149"}, + {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:1a6169e69034eaa06823da6a93a7739ff38716142b3596c180363dee729d713d"}, + {file = "pyzmq-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:19d0383b1f18411d137d891cab567de9afa609b214de68b86e20173dc624c101"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1e931d9a92f628858a50f5bdffdfcf839aebe388b82f9d2ccd5d22a38a789dc"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:97d984b1b2f574bc1bb58296d3c0b64b10e95e7026f8716ed6c0b86d4679843f"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:154bddda2a351161474b36dba03bf1463377ec226a13458725183e508840df89"}, + {file = "pyzmq-25.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:cb6d161ae94fb35bb518b74bb06b7293299c15ba3bc099dccd6a5b7ae589aee3"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:90146ab578931e0e2826ee39d0c948d0ea72734378f1898939d18bc9c823fcf9"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:831ba20b660b39e39e5ac8603e8193f8fce1ee03a42c84ade89c36a251449d80"}, + {file = "pyzmq-25.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3a522510e3434e12aff80187144c6df556bb06fe6b9d01b2ecfbd2b5bfa5c60c"}, + {file = "pyzmq-25.1.0-cp310-cp310-win32.whl", hash = "sha256:be24a5867b8e3b9dd5c241de359a9a5217698ff616ac2daa47713ba2ebe30ad1"}, + {file = "pyzmq-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:5693dcc4f163481cf79e98cf2d7995c60e43809e325b77a7748d8024b1b7bcba"}, + {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:13bbe36da3f8aaf2b7ec12696253c0bf6ffe05f4507985a8844a1081db6ec22d"}, + {file = "pyzmq-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:69511d604368f3dc58d4be1b0bad99b61ee92b44afe1cd9b7bd8c5e34ea8248a"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4a983c8694667fd76d793ada77fd36c8317e76aa66eec75be2653cef2ea72883"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:332616f95eb400492103ab9d542b69d5f0ff628b23129a4bc0a2fd48da6e4e0b"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58416db767787aedbfd57116714aad6c9ce57215ffa1c3758a52403f7c68cff5"}, + {file = "pyzmq-25.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:cad9545f5801a125f162d09ec9b724b7ad9b6440151b89645241d0120e119dcc"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d6128d431b8dfa888bf51c22a04d48bcb3d64431caf02b3cb943269f17fd2994"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:2b15247c49d8cbea695b321ae5478d47cffd496a2ec5ef47131a9e79ddd7e46c"}, + {file = "pyzmq-25.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:442d3efc77ca4d35bee3547a8e08e8d4bb88dadb54a8377014938ba98d2e074a"}, + {file = "pyzmq-25.1.0-cp311-cp311-win32.whl", hash = "sha256:65346f507a815a731092421d0d7d60ed551a80d9b75e8b684307d435a5597425"}, + {file = "pyzmq-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:8b45d722046fea5a5694cba5d86f21f78f0052b40a4bbbbf60128ac55bfcc7b6"}, + {file = "pyzmq-25.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f45808eda8b1d71308c5416ef3abe958f033fdbb356984fabbfc7887bed76b3f"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b697774ea8273e3c0460cf0bba16cd85ca6c46dfe8b303211816d68c492e132"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b324fa769577fc2c8f5efcd429cef5acbc17d63fe15ed16d6dcbac2c5eb00849"}, + {file = "pyzmq-25.1.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:5873d6a60b778848ce23b6c0ac26c39e48969823882f607516b91fb323ce80e5"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:f0d9e7ba6a815a12c8575ba7887da4b72483e4cfc57179af10c9b937f3f9308f"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:414b8beec76521358b49170db7b9967d6974bdfc3297f47f7d23edec37329b00"}, + {file = "pyzmq-25.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:01f06f33e12497dca86353c354461f75275a5ad9eaea181ac0dc1662da8074fa"}, + {file = "pyzmq-25.1.0-cp36-cp36m-win32.whl", hash = "sha256:b5a07c4f29bf7cb0164664ef87e4aa25435dcc1f818d29842118b0ac1eb8e2b5"}, + {file = "pyzmq-25.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:968b0c737797c1809ec602e082cb63e9824ff2329275336bb88bd71591e94a90"}, + {file = "pyzmq-25.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:47b915ba666c51391836d7ed9a745926b22c434efa76c119f77bcffa64d2c50c"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5af31493663cf76dd36b00dafbc839e83bbca8a0662931e11816d75f36155897"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5489738a692bc7ee9a0a7765979c8a572520d616d12d949eaffc6e061b82b4d1"}, + {file = "pyzmq-25.1.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1fc56a0221bdf67cfa94ef2d6ce5513a3d209c3dfd21fed4d4e87eca1822e3a3"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:75217e83faea9edbc29516fc90c817bc40c6b21a5771ecb53e868e45594826b0"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3830be8826639d801de9053cf86350ed6742c4321ba4236e4b5568528d7bfed7"}, + {file = "pyzmq-25.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3575699d7fd7c9b2108bc1c6128641a9a825a58577775ada26c02eb29e09c517"}, + {file = "pyzmq-25.1.0-cp37-cp37m-win32.whl", hash = "sha256:95bd3a998d8c68b76679f6b18f520904af5204f089beebb7b0301d97704634dd"}, + {file = "pyzmq-25.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:dbc466744a2db4b7ca05589f21ae1a35066afada2f803f92369f5877c100ef62"}, + {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:3bed53f7218490c68f0e82a29c92335daa9606216e51c64f37b48eb78f1281f4"}, + {file = "pyzmq-25.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eb52e826d16c09ef87132c6e360e1879c984f19a4f62d8a935345deac43f3c12"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ddbef8b53cd16467fdbfa92a712eae46dd066aa19780681a2ce266e88fbc7165"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:9301cf1d7fc1ddf668d0abbe3e227fc9ab15bc036a31c247276012abb921b5ff"}, + {file = "pyzmq-25.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7e23a8c3b6c06de40bdb9e06288180d630b562db8ac199e8cc535af81f90e64b"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4a82faae00d1eed4809c2f18b37f15ce39a10a1c58fe48b60ad02875d6e13d80"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c8398a1b1951aaa330269c35335ae69744be166e67e0ebd9869bdc09426f3871"}, + {file = "pyzmq-25.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d40682ac60b2a613d36d8d3a0cd14fbdf8e7e0618fbb40aa9fa7b796c9081584"}, + {file = "pyzmq-25.1.0-cp38-cp38-win32.whl", hash = "sha256:33d5c8391a34d56224bccf74f458d82fc6e24b3213fc68165c98b708c7a69325"}, + {file = "pyzmq-25.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:c66b7ff2527e18554030319b1376d81560ca0742c6e0b17ff1ee96624a5f1afd"}, + {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:af56229ea6527a849ac9fb154a059d7e32e77a8cba27e3e62a1e38d8808cb1a5"}, + {file = "pyzmq-25.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:bdca18b94c404af6ae5533cd1bc310c4931f7ac97c148bbfd2cd4bdd62b96253"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0b6b42f7055bbc562f63f3df3b63e3dd1ebe9727ff0f124c3aa7bcea7b3a00f9"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4c2fc7aad520a97d64ffc98190fce6b64152bde57a10c704b337082679e74f67"}, + {file = "pyzmq-25.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be86a26415a8b6af02cd8d782e3a9ae3872140a057f1cadf0133de685185c02b"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:851fb2fe14036cfc1960d806628b80276af5424db09fe5c91c726890c8e6d943"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:2a21fec5c3cea45421a19ccbe6250c82f97af4175bc09de4d6dd78fb0cb4c200"}, + {file = "pyzmq-25.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bad172aba822444b32eae54c2d5ab18cd7dee9814fd5c7ed026603b8cae2d05f"}, + {file = "pyzmq-25.1.0-cp39-cp39-win32.whl", hash = "sha256:4d67609b37204acad3d566bb7391e0ecc25ef8bae22ff72ebe2ad7ffb7847158"}, + {file = "pyzmq-25.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:71c7b5896e40720d30cd77a81e62b433b981005bbff0cb2f739e0f8d059b5d99"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4cb27ef9d3bdc0c195b2dc54fcb8720e18b741624686a81942e14c8b67cc61a6"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0c4fc2741e0513b5d5a12fe200d6785bbcc621f6f2278893a9ca7bed7f2efb7d"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fc34fdd458ff77a2a00e3c86f899911f6f269d393ca5675842a6e92eea565bae"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8751f9c1442624da391bbd92bd4b072def6d7702a9390e4479f45c182392ff78"}, + {file = "pyzmq-25.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6581e886aec3135964a302a0f5eb68f964869b9efd1dbafdebceaaf2934f8a68"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5482f08d2c3c42b920e8771ae8932fbaa0a67dff925fc476996ddd8155a170f3"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5e7fbcafa3ea16d1de1f213c226005fea21ee16ed56134b75b2dede5a2129e62"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:adecf6d02b1beab8d7c04bc36f22bb0e4c65a35eb0b4750b91693631d4081c70"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6d39e42a0aa888122d1beb8ec0d4ddfb6c6b45aecb5ba4013c27e2f28657765"}, + {file = "pyzmq-25.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:7018289b402ebf2b2c06992813523de61d4ce17bd514c4339d8f27a6f6809492"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9e68ae9864d260b18f311b68d29134d8776d82e7f5d75ce898b40a88df9db30f"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e21cc00e4debe8f54c3ed7b9fcca540f46eee12762a9fa56feb8512fd9057161"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f666ae327a6899ff560d741681fdcdf4506f990595201ed39b44278c471ad98"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f5efcc29056dfe95e9c9db0dfbb12b62db9c4ad302f812931b6d21dd04a9119"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:48e5e59e77c1a83162ab3c163fc01cd2eebc5b34560341a67421b09be0891287"}, + {file = "pyzmq-25.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:108c96ebbd573d929740d66e4c3d1bdf31d5cde003b8dc7811a3c8c5b0fc173b"}, + {file = "pyzmq-25.1.0.tar.gz", hash = "sha256:80c41023465d36280e801564a69cbfce8ae85ff79b080e1913f6e90481fb8957"}, ] rdflib = [ {file = "rdflib-6.3.2-py3-none-any.whl", hash = "sha256:36b4e74a32aa1e4fa7b8719876fb192f19ecd45ff932ea5ebbd2e417a0247e63"}, @@ -4311,8 +4321,8 @@ traitlets = [ {file = "traitlets-5.9.0.tar.gz", hash = "sha256:f6cde21a9c68cf756af02035f72d5a723bf607e862e7be33ece505abf4a3bad9"}, ] typing-extensions = [ - {file = "typing_extensions-4.6.1-py3-none-any.whl", hash = "sha256:6bac751f4789b135c43228e72de18637e9a6c29d12777023a703fd1a6858469f"}, - {file = "typing_extensions-4.6.1.tar.gz", hash = "sha256:558bc0c4145f01e6405f4a5fdbd82050bd221b119f4bf72a961a1cfd471349d6"}, + {file = "typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, + {file = "typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] tzdata = [ {file = "tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, From 12046f88cc86bf31c0ebcd4c61c69442f378fa94 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 2 Jun 2023 11:14:24 -0400 Subject: [PATCH 594/615] trigger workflow when review gets requested --- .github/workflows/api_test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 14361c07c..4ada13916 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -4,8 +4,8 @@ name: Test schematic API on: - push: - branches: ['main', 'develop'] + pull_request_review: + types: [submitted] workflow_dispatch: inputs: perform_benchmarking: @@ -85,7 +85,7 @@ jobs: env: SYNAPSE_ACCESS_TOKEN: ${{ secrets.SYNAPSE_ACCESS_TOKEN }} SERVICE_ACCOUNT_CREDS: ${{ secrets.SERVICE_ACCOUNT_CREDS }} - if: ${{ false == inputs.perform_benchmarking }} || ${{ github.ref == 'refs/heads/main' || github.ref == 'refs/heads/develop' }} + if: ${{ false == inputs.perform_benchmarking }} run: > source .venv/bin/activate; pytest -m "schematic_api and not rule_benchmark" From 8bd0a46528d6f298b7839508c38cf02f4ddc36c8 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 2 Jun 2023 11:23:54 -0400 Subject: [PATCH 595/615] update test --- tests/test_api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_api.py b/tests/test_api.py index f9f52d453..d21f84987 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -49,7 +49,7 @@ def test_invalid_manifest(helpers): @pytest.fixture(scope="class") def test_upsert_manifest_csv(helpers): - test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest_upsert.csv") + test_upsert_manifest_path = helpers.get_data_path("mock_manifests/rdb_table_manifest.csv") yield test_upsert_manifest_path @pytest.fixture(scope="class") From 437449e502c22f02d85c002cd236bd88f8918f35 Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 2 Jun 2023 12:18:01 -0400 Subject: [PATCH 596/615] cancel in progress --- .github/workflows/api_test.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index 4ada13916..c8a17f76c 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -14,6 +14,19 @@ on: default: False description: perform benchmarking test (True) or skip (False) +concurrency: + # cancel the current running workflow from the same branch, PR when a new workflow is triggered + # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group + # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows + # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag + # {{ github.event.pull_request.number}}: get PR number + # {{ github.sha }}: full commit sha + # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml + group: >- + ${{ github.workflow }}-${{ github.ref_type }}- + ${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + jobs: test: runs-on: ubuntu-latest @@ -88,5 +101,4 @@ jobs: if: ${{ false == inputs.perform_benchmarking }} run: > source .venv/bin/activate; - pytest -m "schematic_api and not rule_benchmark" - \ No newline at end of file + pytest -m "schematic_api and not rule_benchmark" \ No newline at end of file From 240c6b9dba665369aa2e9482af40c0379b10bc2d Mon Sep 17 00:00:00 2001 From: linglp Date: Fri, 2 Jun 2023 13:52:30 -0400 Subject: [PATCH 597/615] mock triggering workflow? --- .github/workflows/api_test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index c8a17f76c..cea98039c 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -49,7 +49,6 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - #---------------------------------------------- # install & configure poetry #---------------------------------------------- From 17e8644eb288e3727e4b7270b36e5debcde27423 Mon Sep 17 00:00:00 2001 From: linglp Date: Mon, 5 Jun 2023 16:08:35 -0400 Subject: [PATCH 598/615] change to use port 81 and update instructions --- env.example | 2 +- schematic_api/api/README.md | 46 +++++++++++++++++++++++++------------ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/env.example b/env.example index b13b90997..afeeda77b 100644 --- a/env.example +++ b/env.example @@ -2,5 +2,5 @@ SERVER_PROTOCOL=http:// SERVER_DOMAIN=localhost # port on the host machine -USE_LISTEN_PORT=7080 +USE_LISTEN_PORT=81 SERVICE_ACCOUNT_CREDS='Provide service account creds' \ No newline at end of file diff --git a/schematic_api/api/README.md b/schematic_api/api/README.md index 8d351e438..8e8f27fa5 100644 --- a/schematic_api/api/README.md +++ b/schematic_api/api/README.md @@ -1,28 +1,44 @@ -## Installation -For unix OSs users, simply run the following poetry command to install uWSGI: -```bash -poetry install --with aws +# Directions to run APIs locally +## Run Schematic without uWSGI (preferred approach for external users) +### Run Schematic APIs locally +1) To run Schematic API locally, simply install dependencies by doing: ``` +poetry install +``` +2) Get `service_account_creds.json` by doing `schematic init --config /path/to/config.yml`. +3) Run the APIs by doing: +``` +poetry run python3 run_api.py +``` +You should be able to see swagger UI interface when visiting `localhost:3001/v1/ui` -## Setup -There are two ways to run schematic APIs: 1) start a flask server and run your application locally (preferred for external users); 2) build a docker image that allows you to run a container with flask application with uWSGI (only works for unix OSs users or windows user with WSL that could install uWSGI) - -To start a local Flask server and test your endpoints: +### Run Schematic APIs in a docker container +To run Schematic in a docker container, check out `docker-compose.yml` file in this repository. Please comment out the second part related to building `schematic-aws` container. You could start Schematic docker container by running: +``` +docker compose up --build --remove-orphans +``` -```bash -source .venv/bin/activate -python3 run_api.py +## Run Schematic APIs with uWSGI and nginx in a docker container (preferred approach for developers) +### install uWSGI +Install uWSGI by doing: +``` +poetry install --with aws ``` -If you define `APP_PORT` as `3001` in `docker-compose.yml`, you should be able to see the application running when visiting `http://localhost:3001/v1/ui/` +Note: this approach only works for unix OSs users or windows user with WSL -After installing uWSGI, flask and connexion, to start a docker container that runs flask application with uWSGI: +### Run Schematic APIs with uWSGI and nginx in a docker container +See steps below: 1) Comment out the first part of `docker-compose.yml` and focus only on building container `schematic-aws`. + 2) Get `service_account_creds.json` by doing `schematic init --config /path/to/config.yml`. -3) Make a copy of `env.example` and rename it as `.env` and keep it in the same directory as `env.example` By default, schematic uses port 80. If port 80 is not available, please update `USE_LISTEN_PORT` in .env file. + +3) Make a copy of `env.example` and rename it as `.env` and keep it in the same directory as `env.example`. By default, schematic uses port 81. If port 81 is not available, please update `USE_LISTEN_PORT` in `.env` file. + 4) Copy the content of `service_account_creds.json` and put it in `.env` file after key `SERVICE_ACCOUNT_CREDS`. Remember to wrap around the credentials with single quotes. + 5) Build a docker image and spin up docker container `schematic-api-aws` by running: ```bash -docker compose up +docker compose up --build --remove-orphans ``` You should be able to view your application when visit: `https://127.0.0.1/v1/ui/`. You might receive an notification like this in your browser: From 0d3b07acb2f0192e11f4f08d745d3df1a31281ec Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Tue, 6 Jun 2023 10:08:34 -0700 Subject: [PATCH 599/615] add openpyxl import, organize imports in manifest generator --- schematic/manifest/generator.py | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index 0d2d354d6..f12635221 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1,12 +1,14 @@ -import os -import logging -from typing import Dict, List, Tuple, Union from collections import OrderedDict -from tempfile import NamedTemporaryFile - +import json +import logging +from openpyxl import load_workbook +from openpyxl.utils.dataframe import dataframe_to_rows +import os import pandas as pd +from pathlib import Path import pygsheets as ps -import json +from tempfile import NamedTemporaryFile +from typing import Dict, List, Tuple, Union from schematic.schemas.generator import SchemaGenerator from schematic.utils.google_api_utils import ( @@ -22,8 +24,7 @@ from schematic import CONFIG from schematic.utils.google_api_utils import export_manifest_drive_service -from openpyxl import load_workbook -from pathlib import Path + logger = logging.getLogger(__name__) @@ -1453,7 +1454,7 @@ def _handle_output_format_logic(self, output_format: str = None, output_path: st manifest_url = empty_manifest_url, output_location = output_path, ) - + # populate an excel spreadsheet with the existing dataframe self.populate_existing_excel_spreadsheet(output_file_path, dataframe) @@ -1629,11 +1630,12 @@ def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, a with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='replace') as writer: writer.worksheets = {ws.title: ws for ws in workbook.worksheets} worksheet = writer.worksheets["Sheet1"] - + breakpoint() # overwrite existing df with new df, if there is info in the new df # In future depreciate using a prepopulated excel. if not additional_df.empty: - additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) + #additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) + additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. From ceef2c4b00e7df439f4b8018526466c774eb77ca Mon Sep 17 00:00:00 2001 From: linglp Date: Tue, 6 Jun 2023 16:32:22 -0400 Subject: [PATCH 600/615] fix test --- tests/test_manifest.py | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/tests/test_manifest.py b/tests/test_manifest.py index 78c338886..d2fb7eda8 100644 --- a/tests/test_manifest.py +++ b/tests/test_manifest.py @@ -193,8 +193,8 @@ def test_get_manifest_excel(self, helpers, sheet_url, output_format, dataset_id) os.remove(manifest) # test all the functions used under get_manifest - @pytest.mark.parametrize("template_id", [["provided", "not provided"]]) - def test_create_empty_manifest_spreadsheet(self, config, simple_manifest_generator, template_id): + @pytest.mark.parametrize("master_template_id", [None, "mock_master_template_id"]) + def test_create_empty_manifest_spreadsheet(self, config, simple_manifest_generator, master_template_id): ''' Create an empty manifest spreadsheet regardless if master_template_id is provided Note: _create_empty_manifest_spreadsheet calls _gdrive_copy_file. If there's no template id provided in config, this function will create a new manifest @@ -205,17 +205,15 @@ def test_create_empty_manifest_spreadsheet(self, config, simple_manifest_generat title="Example" - if template_id == "provided": + if master_template_id: # mock _gdrive_copy_file function - with patch('schematic.manifest.generator.ManifestGenerator._gdrive_copy_file') as MockClass: - instance = MockClass.return_value - instance.method.return_value = 'mock google sheet id' + config["style"]["google_manifest"]["master_template_id"] = master_template_id + with patch('schematic.manifest.generator.ManifestGenerator._gdrive_copy_file', return_value="mock google sheet id") as MockClass: spreadsheet_id = generator._create_empty_manifest_spreadsheet(title=title) assert spreadsheet_id == "mock google sheet id" else: - # overwrite test config so that we could test the case when manifest_template_id is not provided config["style"]["google_manifest"]["master_template_id"] = "" mock_spreadsheet = Mock() From 3df4a52ab0a1d47ef0a43b24c62de17824f7fca8 Mon Sep 17 00:00:00 2001 From: Mialy DeFelice Date: Wed, 7 Jun 2023 13:09:05 -0700 Subject: [PATCH 601/615] Fix issue with formatting not transfering for excel when pullling form Synapse --- schematic/manifest/generator.py | 60 ++++++++++++++++++++++++++------- 1 file changed, 47 insertions(+), 13 deletions(-) diff --git a/schematic/manifest/generator.py b/schematic/manifest/generator.py index f12635221..a244bcd1e 100644 --- a/schematic/manifest/generator.py +++ b/schematic/manifest/generator.py @@ -1,6 +1,7 @@ from collections import OrderedDict import json import logging +from openpyxl.styles import Font, Alignment, PatternFill from openpyxl import load_workbook from openpyxl.utils.dataframe import dataframe_to_rows import os @@ -1613,29 +1614,62 @@ def _update_dataframe_with_existing_df(self, empty_manifest_url: str, existing_d return updated_df, out_of_schema_columns + def _format_new_excel_column(self, worksheet, new_column_index: int, col: str): + """Add new column to an openpyxl worksheet and format header. + Args: + worksheet: openpyxl worksheet + new_column_index, int: index to add new column + Return: + modified worksheet + """ + # Add column header + worksheet.cell(row=1, column=new_column_index+1).value = col + # Format new column header + worksheet.cell(row=1, column=new_column_index+1).font = Font(size=8, bold=True, color="FF000000") + worksheet.cell(row=1, column=new_column_index+1).alignment = Alignment(horizontal="center", vertical="bottom") + worksheet.cell(row=1, column=new_column_index+1).fill = PatternFill(start_color='FFE0E0E0', end_color='FFE0E0E0', fill_type='solid') + return worksheet + def populate_existing_excel_spreadsheet(self, existing_excel_path: str = None, additional_df: pd.DataFrame = None): '''Populate an existing excel spreadsheet by using an additional dataframe (to avoid sending metadata directly to Google APIs) + New columns will be placed at the end of the spreadsheet. Args: existing_excel_path: path of an existing excel spreadsheet additional_df: additional dataframe Return: added new dataframe to the existing excel path. - TODO: - - The naming of existing and additional df is a bit confusing. + Note: + - Done by rows and column as a way to preserve formatting. + Doing a complete replacement will remove all conditional formatting and dropdowns. ''' # load workbook workbook = load_workbook(existing_excel_path) - - # initalize excel writer - with pd.ExcelWriter(existing_excel_path, mode='a', engine='openpyxl', if_sheet_exists='replace') as writer: - writer.worksheets = {ws.title: ws for ws in workbook.worksheets} - worksheet = writer.worksheets["Sheet1"] - breakpoint() - # overwrite existing df with new df, if there is info in the new df - # In future depreciate using a prepopulated excel. - if not additional_df.empty: - #additional_df.to_excel(writer, "Sheet1", startrow=0, index = False, header=True) - additional_df.to_excel(writer, "Sheet1", startrow=1, index = False, header=False) + worksheet = workbook.active + + # Add new data to existing excel + if not additional_df.empty: + existing_excel_headers = [cell.value for cell in worksheet[1] if cell.value != None] + + new_column_index = len(existing_excel_headers) + df_columns = additional_df.columns + + # Iteratively fill workbook with contents of additional_df + for row_num, row_contents in enumerate(dataframe_to_rows(additional_df, index=False, header=False), 2): + for index, col in enumerate(df_columns): + if col in existing_excel_headers: + # Get index of column header in existing excel to ensure no values are placed in incorrect spot. + existing_column_index = existing_excel_headers.index(col) + worksheet.cell(row=row_num, column=existing_column_index+1).value = row_contents[index] + else: + # Add new col to excel worksheet and format. + worksheet = self._format_new_excel_column(worksheet=worksheet, new_column_index=new_column_index, col=col) + # Add data to column + worksheet.cell(row=row_num, column=new_column_index+1).value = row_contents[index] + # Add new column to headers so it can be accounted for. + existing_excel_headers.append(col) + # Update index for adding new columns. + new_column_index+=1 + workbook.save(existing_excel_path) def populate_manifest_spreadsheet(self, existing_manifest_path: str = None, empty_manifest_url: str = None, return_excel: bool = False, title: str = None): """Creates a google sheet manifest based on existing manifest. From cdbf079d4ba229d481a3aea7c7b402c4d6f232ae Mon Sep 17 00:00:00 2001 From: linglp Date: Wed, 7 Jun 2023 17:32:28 -0400 Subject: [PATCH 602/615] revert changes of workflow --- .github/workflows/api_test.yml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/.github/workflows/api_test.yml b/.github/workflows/api_test.yml index cea98039c..5ad38267e 100644 --- a/.github/workflows/api_test.yml +++ b/.github/workflows/api_test.yml @@ -4,29 +4,13 @@ name: Test schematic API on: - pull_request_review: - types: [submitted] workflow_dispatch: inputs: perform_benchmarking: required: true type: boolean - default: False description: perform benchmarking test (True) or skip (False) -concurrency: - # cancel the current running workflow from the same branch, PR when a new workflow is triggered - # when the trigger is not a PR but a push, it will use the commit sha to generate the concurrency group - # {{ github.workflow }}: the workflow name is used to generate the concurrency group. This allows you to have more than one workflows - # {{ github.ref_type }}: the type of Git ref object created in the repository. Can be either branch or tag - # {{ github.event.pull_request.number}}: get PR number - # {{ github.sha }}: full commit sha - # credit: https://github.com/Sage-Bionetworks-Workflows/sagetasks/blob/main/.github/workflows/ci.yml - group: >- - ${{ github.workflow }}-${{ github.ref_type }}- - ${{ github.event.pull_request.number || github.sha }} - cancel-in-progress: true - jobs: test: runs-on: ubuntu-latest @@ -49,6 +33,7 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + #---------------------------------------------- # install & configure poetry #---------------------------------------------- From 7233f38b62311681d2f153db047cd0688df65c6c Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 14:30:34 -0400 Subject: [PATCH 603/615] add manifest --- .../test_bulkRNAseq_manifest.xlsx | Bin 4979 -> 4941 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx b/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx index 73a603bb46974e99e8cd766ff0cb777f65f56179..ffb88e7d3764f2f7d19a8d0e7f023068edfe9385 100644 GIT binary patch literal 4941 zcmaJ_2Q*x3*T#r8dT$94B_bHTM@u9+qZ7UN9-`L}(Pnf;L=PfrkRW>RqDL9MlL#4v z_-AtO`uTj{z5A?b>zw_*^X~HOXKyt{046ya4h{~Qb;6J~+7$sJzZ<(*I=FLlq25cO zLka*M;)s3!sCZwm8j6P&RgICu8BhF!Qu}|K3Z;Q)JpFw`arBGwvE$?eehdi7rq7XD z9Yw(&N69%C>vKfMo>BYeW)UK`=^E{I2JQ@MD=-t8_ZE+}I~+1XozN@kKvPfETXl^@ zmrU~MKSo&0S@?!I8X5yGEH-{d7X6&Jng11|9f1f-DKFZVi||@8!jKagS<=ag=S19< z%>6vP6O+z=eji z=lb(7`^}pzy4hO&t)|W5Y9G16W;%Ahnv16L3^D24NYR(>=Q5cd*qS@Y8+h==XMe=k z(p>wtAaJ4f`3-?u*}0&cCq>Ew5T&Xgj^;sBH5kqMr|QH?=jp%>(Xj9n27JS0rihq9 zB7wU*Qut3|+vl}&DjYuC4-YGRe>+ZSz}kpxH>?kKQlc|s9Fy|hFVF_u8>`oof5WbN zw2*t+s~aM^1m-P+<1C6(BiI9_Z1R-u$qr6@XNFq@b{TxRJ#Tx*s9J`r_Tvb+6MtY) zKPED#`+{P+Ce&voZ8vk>IvdYFil%hqU@gFH(puf*5fBz@wLI^IZKh+|Z?!0HcI#j# z`=(|;E4lSyzBU;?$QPt4vx9-G?HTVeh*lMA(=mM%4prt= z4TQd<-wFwkf4q>B?Yx5CyBn_UyT@GfEYYub>-SB*CY|;zDpbt8^5)w`prfHV0sbv! z2>yy0caP@|mhPyC+0`|4&H$17FO-#^eU=&JcVv?p_w21sDbm*{8m-2r!q+{*uFMoX zoZP1c1Q*QZd5n^>tNxUjb@!|Lj3et&K}s(Hc1(rxiHqX#uw};B5IM$JUY1Ew zvYlXI-k}YM3o)+YC+3jTV=!M?JV}f9YKtr9=1YU&w#@9wP!7E129928U&dGkGtO~0 zLUg;eSH)qy3R8C68tdmQVv~8aF{(acK0%)QNh;YNPQPy5PUMAh$R9h3w9zcSSRy>l zd2IpgBq>b0VLEWo8l#;QOje0CPmEW?H9`@XdK9 z!fGoiJt&c-Y_0dDZet$7w~s0`QYo-i@G#ZONqxQasZ*YkMPVjKrhAE2LyWtEAm^DG ziKJu}!UM!BNIu6eS-mB#<}V4Xs~FAiBb5q{T3rUn(|aPq)2sG)6N`2n7~ey&(`#6P z$rv9}Xx>#)CE-na(mEOxcCPoy94!Xq&j?O2@GXa?3H3XiJKXH2|NC+P?tWI&b*xph*|5K!If2+!x_DiAUQe(PT6{wp@bdvj zy%lWfR@5x^DSn_=;63j$7ldLbXTk$KL0laLoYA#76|AsjA>0k?AtBLFB@uPHsA6{{DIza0n()+3prBFKNdp8F_uu9YYY{RRsL2MnIJ9+d%j)_RlHg5FPT^=F!59(b8q-$LO8vOT+Dg(1{Nh0bFzj zc$PcE3B!{=K0i6y;*Z&iY?sByD$czf7YCcqtVy9MDJ0mqraIk8(ZDl_W?TNel1lC z*g0eVaZsD~sI+W;&JP1+8P#tmKBLHUv;1pSpuVgM?lzW|9`4+KK6p^c-l(nY{8gB^ zalee%W5d?|oFp+EuhLr5vTC+MeCu0g%b>?=Ktj(P#t{W9HGL3U(pJtn z6)jrdP_xDNV}|^1nwVzpl8j@j;R?|=)2y=LLh&;%MxjS|!pxL5h(=3O5tT}x-btts zCOH`Fvds+l08f7By!Se+b-D)vz9-ayFYMKaAKGr(#CUO{M=h?HRz})7k|*7?K(lZ< zNt8P{NO!;tbXH9A%rNC#%>|0gf98N1hga#4)VkiIFqHy*3I`7qR_)dK34kR1r9qQp zeI#C4+oSi-s6zAK!=$JJKz4j%0vj=pms^hggq{3ai~X?HMG7J$W~YX9V?@Cx+={u* zCP4b{MruMY_!75Y{lwJtS!;*dzFXyL))y`Wnp+x$q_fYQ@X4`9va0786R(V$90{v; z`ZF9o&Z^sdY8mqw-iMX@)mAdL<}H5_@df=ItY49OFR49<+x*+lQq8O5>K@3!cJEMj zMY@JY4mWnTE;7`(cr)*uHMb^2PRqBSF)y7mn|&uW8)_Xv-tl1GS-N&7ry8{7V3(g( zuDD9)7{AyPJ5aHUnNb6zmn)|mUw2~_@J((debBZ?@X2$?Q2M@NESdWB=x5SKQ(+!N zW6naow-?WQ+9zV|cP5NYJKJ8Z5pCBeQvy!|)B1(pCNn0DKI>Hfq5=#rtixzD8-mAS zf7zt|JTTGaB;YVO4RRq@++ELhW4pymtoW2OKqGz8?0npk^j=XZEB>#x^n{h~3d0OE zRm$sx-*QGbp}5aprS;FkzYaS?x@!Z|4>7G=3-4q_&VR~Fn?%v^&QWriZU~}iC zCjMD)q*0<1XTxK3OWP<<(up6nyxZTPquY-4B?T3E)eS^S3-M3=Q%@FzB!RY);&A15 z%v$fhx)c$Tz=bxfGMZ0HKC>np7ls|`ip$iBJWX92;<#r&G7C%VmfqH@&533RFG|qpZ^abUBzs zo*nyN;gkgVgoU%YnwztWJGZ&Bn2&ZAy7&;OXj&@N?lp$neaSu+9W~R*thU$wx5_H&B2lS@b!rzXPIR*81fI z<7znoVg6DlJg2+PoDDM*K}V!d$wR7hXA^Cf8?&j!KBIR$C8ZaQ+@83%2B;Pgj1H`# zbxAHDd)Lg@BHre2;?VifBZ}NFn&03nK6;3`ja2YY!h|rmaT#{W>^LCwpsOfPlDf`L z;#IEi{))}cC$7zd7TP`4Z@`ow z_=`;+x}O@su{y6>c){mubZckg4I}y?-r`}=9J97$nwfQXqov{iS^2eRo6kjLwUVu# z!&J=NYME>K>kFALHZqK`@H07gEH1R}@$%m^4YaR4Kf~CIyA#7WW^{@bd-(AT;a|*v za>(p2GgUB>!AAY7Lx`_B#MH$F<&R8Ak5em%_yw{j?A}Te#x;V@B2TbutJKCRR9ocwSZBQDL6|_-SOI0TCZ~5`y(^%t{BMbuM^Uekl|LuAVS? zq_WWyB3UssFS-*dm-R5@JH>Pad@a#u%AC!QwvSaiaaWAQY-<0lmIC0j{_*B8roP2= z*b>hh$X)C`EM}dhGveRCB+9`bC!YRpkS@KLO#4StgBx?Dj>L|oVk^&;7BGG;JuQ(A z^CtQIKI2vj6|Sgqge`<}hyf$nIAgZ}=D?P_l5I}sbu5SD!LRWsK}aD6PYo^R{&@BM z>_pIg#t2hEx;SeBtLO)Incq zX-xxJXD1I!Cl6!I=Ps7+hJT2HW}iwMh`0g4!DOtylMIl#YfB^^tM<}Oj&+{7;Ja*% z!Az5Nri@k+KLyj0#dJMi6<>1ZfMBuw1iXP?l#NW36?dZ*r>F$haR1h*J#R*AWyeH_ zYPrrY*x2nUx=ug!(52V3Kw6G`*C_1SPf>bC_n+U`aTEV+7CwUR@kDlo@yiaO!e=`f zx2BfmOs-aWxBBf@V3EZM!AdxK-+gU8wn6D--ynO=*aF2S*4#)3Uq8;$CgD;OPfun> zEf30}dXjz0Pq!V>c~q%u6EL76UW*V82a~c9++4t~P4Eo=PFvk-29M$lgKtDSyP{qY zs6*j)n9p_)&=`O@KKv{{O3`0#A;J+5U~`mw7=6ICCVO!~{amcbdY6}G>iqS^(?bC- z#@C^32#I3?dN;&C@bO2!iRB?U93kts&M;E+h{;9zr}4QFNzug)?UDf%V}M;8??gc2 z7u7$3j`@K{AL$mI8z|SHW00d=PCl--{;0{vf6A3P$aTf5{U2&Fa49s%t**@pt}9<9 z-KZAvQk0SP1F3x3FkV-^%1TkJ{8A{e{;2)~N58(#)nbL>u$RJ({r~^}zZmWHRjz_M zs<2&(3DTOVgIq6j*H^fTLMZURlmPtyQ3|fBUrjp{R9y-Y;T842f$O^V?3KtsrRJp= bB7OQl5>-v{2GYuCXt>Br5{a9~fA;)8aN=Ft literal 4979 zcmZ`-1ymGm+g?gqSVE9Sx?8%XTPazjmyncB374*2Qb}o)Sdb3sM!G>l8UdwT0f}$b z^MAhbzu(N6XU?26*FE=h&E48+Xy_yW000Z%QQ@wyXw;4uf_$n(UWCZY%Gpxe)!D_3 z$K1t*+uPAWBTfUigO~8Zwd&5IlimRxAKhf$O2417@O`M2yl3cz|D*Q!1&Jlzm`2h8 z!!8Cdp|Gx^=fHj?KrOCfr~Jg5yGl$Hc7`-E!#>f(b2eR!6_mYbW~Ax@!|4~)do^NP zRLw%GY&#`&p)WJsQ=js&o~GI#$A!)`)7CnlnPapjo?~eLr7va@W721&o`Wa=0Pvss zS~|Oee=1x6)6nYV#S6P0Nb=hil%>ioPtC~;gLE+x*0CPeMs3PR>NEvvfogA~3&$P) zIIS$3WM(HOk}4qN(~0&Gsvouiucl>23r5 zW~nb(TN}~SHsecl_D}7TREpX1ts7ah!pp;)yU+Q5lmvMSX==O2)mzW3D>%_0K+{;< zR_$Q=w~}O0Y91`h%ro&<>7y76H1mPv@Q}hV)9Yz})W3;&Wt_o4cnbi?U;zM#k;HgA z@VMK89l^g>zMs_W8-d*BMM$21g^zmMARKXf?g!Ua6T8`YE>ypQ>}%470u5swe5_!Q zz*eREgo7#g`w1G2=@RIiJ3odMl(x1-e2%|xTWp6#BprF1&G9TuH`Vbhtr+k#0%dvc z7QqkNa0=8-YK-gvogxAK#6+DRL!zm)f=<|r=)|rvEV!uVgp&`hKTB;Gl%Yr`6Vgv$c`8_f3OoTr6FD5uyfJ6 zrcuNv-Hxudr#901_Pt}{%0VIh0ZAB*Du}!ZQY?Oaaj{IpVNZWV*M4@)z`VPlBgM+v zp|?ow;CQqP75a)!Q&vaji9>6?EOvFC-Kfv?eUh~JiR6|mfRPtrPw?drV)85H# zhh-TO)Wk$XNw~LU!%`WUiQb4l*H9+D;wYHE%9xNjNaA5USB1sfRWTH~GY@SGP_!$; zDLuk%$0dBPFwQcBaHwFE)TlO;Rf_ZwyQTvgIAdH|SqG3qPRio$eG1o_JHfTj-ayQZ zh1u^r|9%H|U=s(SV8!jkSOv8_Zao9j3wc+cH zBb?IHtX&@BhjKkOFWgab8qy{j$Q>|J@U`JYGH1L_m?6NXeIgpPr04|d`ccj|KO@M^ zYH8p))Yq#EPh^`F&2HPfw3W&_+&`aVguv4tb1~e3ss&fcGS**24;-*}VQ*W3n6L+R zC&0o{L|Jl_PCJjjsV2{Cz#CZWB|z&t@Emt3&XF?-)2-?uTmktySGCWzNi8+ZBC02q zA6ztP2JysgBoe4=y-nZC41?$H(`adaqU zFboq#d5u1 zGAUV2CaHLw_iBZvD%>sIx4uK6^xANm=8S(?)MY_z3C(1am{UIgd3!)qR1mPlqNNe8 zb;gt-UhQ`nOqYH!y^xPsT*337EHNsu;s8pkVfxc1+_H=Tod}x7lUS4$R+jb5^Wpgf z86M;1Sc@!&E2L2fOhuQ9#^N~3PRVRYFHGXwBJc&NU>GKRuWIk-t!v^)e7yRKU(wMO z_h~=673J>)Qpt6+mV(Txuh0Mh^4|%>%h}c5%@z!HcjNhW`;|pv6CIrw=m>jTaaJ!? zDeQK2=Tb7POnzACC6_MP6J=YHtQd>T?AFmj!>toi5u{$2t=E!(xge)45WpfZrdDc; zOUH`?vRrMJ-`a88Vb*T+u1dQH=#x0+J5A`Ah1e^9pd$NVG-o%>6PUS{(PMA-58r!~ zzl)*8$`8ZO_$qW4QXa~XJZ7n@K=u8MN@)CS{7o{-E~(Mx>wX`f0FVYTO!ML)@2Nm~ zxAk;H)Aq+1(d@1?na;3W2;Ly>2ie_X5_TV{h@-lEm_%Ltk=|$Nq`DNE&Emk4wE2v{ zjnXhhL|Tf-$M&3}5oacD#{PS5BD`ejT<c5Wrn#EIqbyn_nz~G3@>X9AROb`q6ZJCG{W!fk)QALpHp*Em{pnV_(IC19vEzV zwmIYB>KN5Z%%)*!eR-v1JH5MjlykBEso}(=B`z|uiX&DF5$+BGOHPcU5A{!J)O*(j zqWOhas1?9rSQ`8b2Oe$RXy&c5`H95KD?7q>0&o1w?}&KpB2)mt5f=c!|NSrB+R_Mg4`ibY8+s(k{#-4Q-ubx%~U%s>$uK;O~ZL3foJ*_1g%uvQgZBd%~^pZm3bn_aWEB>!A1QhwHEU*%$fQo^o_p7eXX% zU5?v(DpI72M1&dabd-dpR+s}*$)8piK<-c5SFJGn&%j(FPkRC4kffQzV2i3RuiQR< z_A^9Jm}%+By>Q>7Z+Q>y?LM;fZ9gDzc|^J3;d>>mkkNd;$IDAmNODYF3e$J%KvSJ#91%91OAQO4TjYGuJ0mSEU*U zGI~1%62(XN#(YV}v8fF*Z7Ir4>i~P=`kh+s$!N1v2Pv`Rl9}!7nd@JhfqCpBO*9pE zp3N`@cIp_DOxWGBkrTdXOLsJ$57_TUM|Yuw^Y#gkzHh~fu)=@_5i$nA%%P=i3;~z% zK4sg@sLG1DeXqJAuah1(yEb04KQ^DJGk+1|6DT@)SOWH@MPdbU{m!sU8sDe zvla3Yxb=}+d9S))mR%=^*x5EZTcFx?Ru&hWK=8FEmD@srLl1A4@tnR;8Q`5gn_1Sg zTtjvtH5slPLFnkWSwhauW2Qc?PN(TQb+-$Z6CBuXqgyrD3y0(z%4vCL8iT65(cH5j z0k!L)k0UsfX_@fSy^A8DgTfET-{_#ZN(wHVC$N0=XwM|LRMuik{&9h&MYZ?x_Vw{- zF^S|^YbI|&Rt}WfeCBX>Vl&|FO z`yfE2wanvKO)j#$Dudyp!8r7{r;l{=-YJNjEr-rpE1lHKzc_mQ_T>I+{^;9WSvlN# zIsD7xJ23K*^#|!1-B#*vm^;mIISnsi!eg6FOK15JOYgfs6r_=&%+mR(P)5RE^fN#< za&|+%jA0$9;!5y-qizi7fRLXl#JNXRT5Ez>^>UdBa>{qx+nP7!8!iftjEyA1Jwme@V-7hU2nm-@m{%u79yK9YQNK$_w38wf> z?r%f-C&j;vss<)``vosvD4b{mKwdnVgIdU4N=gPOhi{-7@*f&7y#vKlb`|U;vtk441UE}k2n)yM4L_nTf zcJWm^iGjWa(&0}&?i(}+jVRTZ(XX8BuHM*WdYBx961l+{WFr6B34-LEo!r4r?xwmv zE?~DOKdq=Napb2J^_UiX_IN5F;v%!l9mBELh70L>lDC;{;q2}lzwl1=btQhXT3!$0 zyW0g*Nu4G72QeE-eII!e+EAIPphUwktSkl(Wlf^%!pw+=HLjSe&l~&+*}YM`zwmy1m28;e}FJ#MT6Y>KV9}F_@ Date: Thu, 15 Jun 2023 16:40:26 -0400 Subject: [PATCH 604/615] try using python version3.10 and remove 3.9 --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index 654b6cb5c..ba1e44809 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -30,7 +30,7 @@ jobs: POETRY_VERSION: 1.2.0 strategy: matrix: - python-version: ["3.9", "3.10"] + python-version: ["3.10"] steps: #---------------------------------------------- From dbebb3df00d6210acdd675c0c1e5e5633eaaa38f Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 16:47:41 -0400 Subject: [PATCH 605/615] try reproducing --- .github/workflows/pdoc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index ba1e44809..63499290f 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -5,6 +5,7 @@ on: push: branches: - develop + - fix-pdoc-workflow workflow_dispatch: # Allow manually triggering the workflow # security: restrict permissions for CI jobs. From 25e67dfadddf3d470a8b342b12a5ba1a8d357c4d Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 16:49:49 -0400 Subject: [PATCH 606/615] use poetry 1.2.2 --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index 63499290f..f0d44bf2c 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -28,7 +28,7 @@ jobs: build: runs-on: ubuntu-latest env: - POETRY_VERSION: 1.2.0 + POETRY_VERSION: 1.2.2 strategy: matrix: python-version: ["3.10"] From 46d9452bc5ab6c18a608bb6d06a3e2f3f880d8e7 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:00:38 -0400 Subject: [PATCH 607/615] try running pdoc help --- .github/workflows/pdoc.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index f0d44bf2c..1e56180b9 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -74,6 +74,7 @@ jobs: # create documentation - run: poetry show pdoc + - run: pdoc --help - run: poetry run pdoc --docformat google -o docs/schematic schematic/manifest schematic/models schematic/schemas schematic/store schematic/utils schematic/visualization - uses: actions/upload-pages-artifact@v1 From 0313bcc6aa1887950c5775d317a874c4057c28cf Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:03:04 -0400 Subject: [PATCH 608/615] run poetry shell --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index 1e56180b9..a4e90c83e 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -74,7 +74,7 @@ jobs: # create documentation - run: poetry show pdoc - - run: pdoc --help + - run: poetry shell - run: poetry run pdoc --docformat google -o docs/schematic schematic/manifest schematic/models schematic/schemas schematic/store schematic/utils schematic/visualization - uses: actions/upload-pages-artifact@v1 From 8b366c48a7103a9966cb95e943ccd3d118a16106 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:05:12 -0400 Subject: [PATCH 609/615] try poetry pdoc --help --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index a4e90c83e..fd3c688f6 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -74,7 +74,7 @@ jobs: # create documentation - run: poetry show pdoc - - run: poetry shell + - run: poetry run pdoc --help - run: poetry run pdoc --docformat google -o docs/schematic schematic/manifest schematic/models schematic/schemas schematic/store schematic/utils schematic/visualization - uses: actions/upload-pages-artifact@v1 From e99838ac18cddf863751feb3877433db68f2afcb Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:07:11 -0400 Subject: [PATCH 610/615] upgrade poetry version --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index fd3c688f6..f0d00e001 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -28,7 +28,7 @@ jobs: build: runs-on: ubuntu-latest env: - POETRY_VERSION: 1.2.2 + POETRY_VERSION: 1.3.0 strategy: matrix: python-version: ["3.10"] From f328944e2f4ec226bc6a01751499d2f73511105d Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:20:16 -0400 Subject: [PATCH 611/615] try deleting xlsx and see if that make pdoc work --- .../mock_manifests/test_bulkRNAseq_manifest.xlsx | Bin 4941 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx diff --git a/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx b/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx deleted file mode 100644 index ffb88e7d3764f2f7d19a8d0e7f023068edfe9385..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4941 zcmaJ_2Q*x3*T#r8dT$94B_bHTM@u9+qZ7UN9-`L}(Pnf;L=PfrkRW>RqDL9MlL#4v z_-AtO`uTj{z5A?b>zw_*^X~HOXKyt{046ya4h{~Qb;6J~+7$sJzZ<(*I=FLlq25cO zLka*M;)s3!sCZwm8j6P&RgICu8BhF!Qu}|K3Z;Q)JpFw`arBGwvE$?eehdi7rq7XD z9Yw(&N69%C>vKfMo>BYeW)UK`=^E{I2JQ@MD=-t8_ZE+}I~+1XozN@kKvPfETXl^@ zmrU~MKSo&0S@?!I8X5yGEH-{d7X6&Jng11|9f1f-DKFZVi||@8!jKagS<=ag=S19< z%>6vP6O+z=eji z=lb(7`^}pzy4hO&t)|W5Y9G16W;%Ahnv16L3^D24NYR(>=Q5cd*qS@Y8+h==XMe=k z(p>wtAaJ4f`3-?u*}0&cCq>Ew5T&Xgj^;sBH5kqMr|QH?=jp%>(Xj9n27JS0rihq9 zB7wU*Qut3|+vl}&DjYuC4-YGRe>+ZSz}kpxH>?kKQlc|s9Fy|hFVF_u8>`oof5WbN zw2*t+s~aM^1m-P+<1C6(BiI9_Z1R-u$qr6@XNFq@b{TxRJ#Tx*s9J`r_Tvb+6MtY) zKPED#`+{P+Ce&voZ8vk>IvdYFil%hqU@gFH(puf*5fBz@wLI^IZKh+|Z?!0HcI#j# z`=(|;E4lSyzBU;?$QPt4vx9-G?HTVeh*lMA(=mM%4prt= z4TQd<-wFwkf4q>B?Yx5CyBn_UyT@GfEYYub>-SB*CY|;zDpbt8^5)w`prfHV0sbv! z2>yy0caP@|mhPyC+0`|4&H$17FO-#^eU=&JcVv?p_w21sDbm*{8m-2r!q+{*uFMoX zoZP1c1Q*QZd5n^>tNxUjb@!|Lj3et&K}s(Hc1(rxiHqX#uw};B5IM$JUY1Ew zvYlXI-k}YM3o)+YC+3jTV=!M?JV}f9YKtr9=1YU&w#@9wP!7E129928U&dGkGtO~0 zLUg;eSH)qy3R8C68tdmQVv~8aF{(acK0%)QNh;YNPQPy5PUMAh$R9h3w9zcSSRy>l zd2IpgBq>b0VLEWo8l#;QOje0CPmEW?H9`@XdK9 z!fGoiJt&c-Y_0dDZet$7w~s0`QYo-i@G#ZONqxQasZ*YkMPVjKrhAE2LyWtEAm^DG ziKJu}!UM!BNIu6eS-mB#<}V4Xs~FAiBb5q{T3rUn(|aPq)2sG)6N`2n7~ey&(`#6P z$rv9}Xx>#)CE-na(mEOxcCPoy94!Xq&j?O2@GXa?3H3XiJKXH2|NC+P?tWI&b*xph*|5K!If2+!x_DiAUQe(PT6{wp@bdvj zy%lWfR@5x^DSn_=;63j$7ldLbXTk$KL0laLoYA#76|AsjA>0k?AtBLFB@uPHsA6{{DIza0n()+3prBFKNdp8F_uu9YYY{RRsL2MnIJ9+d%j)_RlHg5FPT^=F!59(b8q-$LO8vOT+Dg(1{Nh0bFzj zc$PcE3B!{=K0i6y;*Z&iY?sByD$czf7YCcqtVy9MDJ0mqraIk8(ZDl_W?TNel1lC z*g0eVaZsD~sI+W;&JP1+8P#tmKBLHUv;1pSpuVgM?lzW|9`4+KK6p^c-l(nY{8gB^ zalee%W5d?|oFp+EuhLr5vTC+MeCu0g%b>?=Ktj(P#t{W9HGL3U(pJtn z6)jrdP_xDNV}|^1nwVzpl8j@j;R?|=)2y=LLh&;%MxjS|!pxL5h(=3O5tT}x-btts zCOH`Fvds+l08f7By!Se+b-D)vz9-ayFYMKaAKGr(#CUO{M=h?HRz})7k|*7?K(lZ< zNt8P{NO!;tbXH9A%rNC#%>|0gf98N1hga#4)VkiIFqHy*3I`7qR_)dK34kR1r9qQp zeI#C4+oSi-s6zAK!=$JJKz4j%0vj=pms^hggq{3ai~X?HMG7J$W~YX9V?@Cx+={u* zCP4b{MruMY_!75Y{lwJtS!;*dzFXyL))y`Wnp+x$q_fYQ@X4`9va0786R(V$90{v; z`ZF9o&Z^sdY8mqw-iMX@)mAdL<}H5_@df=ItY49OFR49<+x*+lQq8O5>K@3!cJEMj zMY@JY4mWnTE;7`(cr)*uHMb^2PRqBSF)y7mn|&uW8)_Xv-tl1GS-N&7ry8{7V3(g( zuDD9)7{AyPJ5aHUnNb6zmn)|mUw2~_@J((debBZ?@X2$?Q2M@NESdWB=x5SKQ(+!N zW6naow-?WQ+9zV|cP5NYJKJ8Z5pCBeQvy!|)B1(pCNn0DKI>Hfq5=#rtixzD8-mAS zf7zt|JTTGaB;YVO4RRq@++ELhW4pymtoW2OKqGz8?0npk^j=XZEB>#x^n{h~3d0OE zRm$sx-*QGbp}5aprS;FkzYaS?x@!Z|4>7G=3-4q_&VR~Fn?%v^&QWriZU~}iC zCjMD)q*0<1XTxK3OWP<<(up6nyxZTPquY-4B?T3E)eS^S3-M3=Q%@FzB!RY);&A15 z%v$fhx)c$Tz=bxfGMZ0HKC>np7ls|`ip$iBJWX92;<#r&G7C%VmfqH@&533RFG|qpZ^abUBzs zo*nyN;gkgVgoU%YnwztWJGZ&Bn2&ZAy7&;OXj&@N?lp$neaSu+9W~R*thU$wx5_H&B2lS@b!rzXPIR*81fI z<7znoVg6DlJg2+PoDDM*K}V!d$wR7hXA^Cf8?&j!KBIR$C8ZaQ+@83%2B;Pgj1H`# zbxAHDd)Lg@BHre2;?VifBZ}NFn&03nK6;3`ja2YY!h|rmaT#{W>^LCwpsOfPlDf`L z;#IEi{))}cC$7zd7TP`4Z@`ow z_=`;+x}O@su{y6>c){mubZckg4I}y?-r`}=9J97$nwfQXqov{iS^2eRo6kjLwUVu# z!&J=NYME>K>kFALHZqK`@H07gEH1R}@$%m^4YaR4Kf~CIyA#7WW^{@bd-(AT;a|*v za>(p2GgUB>!AAY7Lx`_B#MH$F<&R8Ak5em%_yw{j?A}Te#x;V@B2TbutJKCRR9ocwSZBQDL6|_-SOI0TCZ~5`y(^%t{BMbuM^Uekl|LuAVS? zq_WWyB3UssFS-*dm-R5@JH>Pad@a#u%AC!QwvSaiaaWAQY-<0lmIC0j{_*B8roP2= z*b>hh$X)C`EM}dhGveRCB+9`bC!YRpkS@KLO#4StgBx?Dj>L|oVk^&;7BGG;JuQ(A z^CtQIKI2vj6|Sgqge`<}hyf$nIAgZ}=D?P_l5I}sbu5SD!LRWsK}aD6PYo^R{&@BM z>_pIg#t2hEx;SeBtLO)Incq zX-xxJXD1I!Cl6!I=Ps7+hJT2HW}iwMh`0g4!DOtylMIl#YfB^^tM<}Oj&+{7;Ja*% z!Az5Nri@k+KLyj0#dJMi6<>1ZfMBuw1iXP?l#NW36?dZ*r>F$haR1h*J#R*AWyeH_ zYPrrY*x2nUx=ug!(52V3Kw6G`*C_1SPf>bC_n+U`aTEV+7CwUR@kDlo@yiaO!e=`f zx2BfmOs-aWxBBf@V3EZM!AdxK-+gU8wn6D--ynO=*aF2S*4#)3Uq8;$CgD;OPfun> zEf30}dXjz0Pq!V>c~q%u6EL76UW*V82a~c9++4t~P4Eo=PFvk-29M$lgKtDSyP{qY zs6*j)n9p_)&=`O@KKv{{O3`0#A;J+5U~`mw7=6ICCVO!~{amcbdY6}G>iqS^(?bC- z#@C^32#I3?dN;&C@bO2!iRB?U93kts&M;E+h{;9zr}4QFNzug)?UDf%V}M;8??gc2 z7u7$3j`@K{AL$mI8z|SHW00d=PCl--{;0{vf6A3P$aTf5{U2&Fa49s%t**@pt}9<9 z-KZAvQk0SP1F3x3FkV-^%1TkJ{8A{e{;2)~N58(#)nbL>u$RJ({r~^}zZmWHRjz_M zs<2&(3DTOVgIq6j*H^fTLMZURlmPtyQ3|fBUrjp{R9y-Y;T842f$O^V?3KtsrRJp= bB7OQl5>-v{2GYuCXt>Br5{a9~fA;)8aN=Ft From 2b18a130de2e848470b17d9ee3ff4a7b4d3b4a72 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:23:05 -0400 Subject: [PATCH 612/615] update pdoc in workflow --- .github/workflows/pdoc.yml | 2 +- .../mock_manifests/test_bulkRNAseq_manifest.xlsx | Bin 0 -> 4941 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index f0d00e001..5a8b07e5a 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -73,8 +73,8 @@ jobs: run: poetry install --no-interaction --no-root # create documentation + - run: poetry add pdoc@13.0.0 - run: poetry show pdoc - - run: poetry run pdoc --help - run: poetry run pdoc --docformat google -o docs/schematic schematic/manifest schematic/models schematic/schemas schematic/store schematic/utils schematic/visualization - uses: actions/upload-pages-artifact@v1 diff --git a/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx b/tests/data/mock_manifests/test_bulkRNAseq_manifest.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..ffb88e7d3764f2f7d19a8d0e7f023068edfe9385 GIT binary patch literal 4941 zcmaJ_2Q*x3*T#r8dT$94B_bHTM@u9+qZ7UN9-`L}(Pnf;L=PfrkRW>RqDL9MlL#4v z_-AtO`uTj{z5A?b>zw_*^X~HOXKyt{046ya4h{~Qb;6J~+7$sJzZ<(*I=FLlq25cO zLka*M;)s3!sCZwm8j6P&RgICu8BhF!Qu}|K3Z;Q)JpFw`arBGwvE$?eehdi7rq7XD z9Yw(&N69%C>vKfMo>BYeW)UK`=^E{I2JQ@MD=-t8_ZE+}I~+1XozN@kKvPfETXl^@ zmrU~MKSo&0S@?!I8X5yGEH-{d7X6&Jng11|9f1f-DKFZVi||@8!jKagS<=ag=S19< z%>6vP6O+z=eji z=lb(7`^}pzy4hO&t)|W5Y9G16W;%Ahnv16L3^D24NYR(>=Q5cd*qS@Y8+h==XMe=k z(p>wtAaJ4f`3-?u*}0&cCq>Ew5T&Xgj^;sBH5kqMr|QH?=jp%>(Xj9n27JS0rihq9 zB7wU*Qut3|+vl}&DjYuC4-YGRe>+ZSz}kpxH>?kKQlc|s9Fy|hFVF_u8>`oof5WbN zw2*t+s~aM^1m-P+<1C6(BiI9_Z1R-u$qr6@XNFq@b{TxRJ#Tx*s9J`r_Tvb+6MtY) zKPED#`+{P+Ce&voZ8vk>IvdYFil%hqU@gFH(puf*5fBz@wLI^IZKh+|Z?!0HcI#j# z`=(|;E4lSyzBU;?$QPt4vx9-G?HTVeh*lMA(=mM%4prt= z4TQd<-wFwkf4q>B?Yx5CyBn_UyT@GfEYYub>-SB*CY|;zDpbt8^5)w`prfHV0sbv! z2>yy0caP@|mhPyC+0`|4&H$17FO-#^eU=&JcVv?p_w21sDbm*{8m-2r!q+{*uFMoX zoZP1c1Q*QZd5n^>tNxUjb@!|Lj3et&K}s(Hc1(rxiHqX#uw};B5IM$JUY1Ew zvYlXI-k}YM3o)+YC+3jTV=!M?JV}f9YKtr9=1YU&w#@9wP!7E129928U&dGkGtO~0 zLUg;eSH)qy3R8C68tdmQVv~8aF{(acK0%)QNh;YNPQPy5PUMAh$R9h3w9zcSSRy>l zd2IpgBq>b0VLEWo8l#;QOje0CPmEW?H9`@XdK9 z!fGoiJt&c-Y_0dDZet$7w~s0`QYo-i@G#ZONqxQasZ*YkMPVjKrhAE2LyWtEAm^DG ziKJu}!UM!BNIu6eS-mB#<}V4Xs~FAiBb5q{T3rUn(|aPq)2sG)6N`2n7~ey&(`#6P z$rv9}Xx>#)CE-na(mEOxcCPoy94!Xq&j?O2@GXa?3H3XiJKXH2|NC+P?tWI&b*xph*|5K!If2+!x_DiAUQe(PT6{wp@bdvj zy%lWfR@5x^DSn_=;63j$7ldLbXTk$KL0laLoYA#76|AsjA>0k?AtBLFB@uPHsA6{{DIza0n()+3prBFKNdp8F_uu9YYY{RRsL2MnIJ9+d%j)_RlHg5FPT^=F!59(b8q-$LO8vOT+Dg(1{Nh0bFzj zc$PcE3B!{=K0i6y;*Z&iY?sByD$czf7YCcqtVy9MDJ0mqraIk8(ZDl_W?TNel1lC z*g0eVaZsD~sI+W;&JP1+8P#tmKBLHUv;1pSpuVgM?lzW|9`4+KK6p^c-l(nY{8gB^ zalee%W5d?|oFp+EuhLr5vTC+MeCu0g%b>?=Ktj(P#t{W9HGL3U(pJtn z6)jrdP_xDNV}|^1nwVzpl8j@j;R?|=)2y=LLh&;%MxjS|!pxL5h(=3O5tT}x-btts zCOH`Fvds+l08f7By!Se+b-D)vz9-ayFYMKaAKGr(#CUO{M=h?HRz})7k|*7?K(lZ< zNt8P{NO!;tbXH9A%rNC#%>|0gf98N1hga#4)VkiIFqHy*3I`7qR_)dK34kR1r9qQp zeI#C4+oSi-s6zAK!=$JJKz4j%0vj=pms^hggq{3ai~X?HMG7J$W~YX9V?@Cx+={u* zCP4b{MruMY_!75Y{lwJtS!;*dzFXyL))y`Wnp+x$q_fYQ@X4`9va0786R(V$90{v; z`ZF9o&Z^sdY8mqw-iMX@)mAdL<}H5_@df=ItY49OFR49<+x*+lQq8O5>K@3!cJEMj zMY@JY4mWnTE;7`(cr)*uHMb^2PRqBSF)y7mn|&uW8)_Xv-tl1GS-N&7ry8{7V3(g( zuDD9)7{AyPJ5aHUnNb6zmn)|mUw2~_@J((debBZ?@X2$?Q2M@NESdWB=x5SKQ(+!N zW6naow-?WQ+9zV|cP5NYJKJ8Z5pCBeQvy!|)B1(pCNn0DKI>Hfq5=#rtixzD8-mAS zf7zt|JTTGaB;YVO4RRq@++ELhW4pymtoW2OKqGz8?0npk^j=XZEB>#x^n{h~3d0OE zRm$sx-*QGbp}5aprS;FkzYaS?x@!Z|4>7G=3-4q_&VR~Fn?%v^&QWriZU~}iC zCjMD)q*0<1XTxK3OWP<<(up6nyxZTPquY-4B?T3E)eS^S3-M3=Q%@FzB!RY);&A15 z%v$fhx)c$Tz=bxfGMZ0HKC>np7ls|`ip$iBJWX92;<#r&G7C%VmfqH@&533RFG|qpZ^abUBzs zo*nyN;gkgVgoU%YnwztWJGZ&Bn2&ZAy7&;OXj&@N?lp$neaSu+9W~R*thU$wx5_H&B2lS@b!rzXPIR*81fI z<7znoVg6DlJg2+PoDDM*K}V!d$wR7hXA^Cf8?&j!KBIR$C8ZaQ+@83%2B;Pgj1H`# zbxAHDd)Lg@BHre2;?VifBZ}NFn&03nK6;3`ja2YY!h|rmaT#{W>^LCwpsOfPlDf`L z;#IEi{))}cC$7zd7TP`4Z@`ow z_=`;+x}O@su{y6>c){mubZckg4I}y?-r`}=9J97$nwfQXqov{iS^2eRo6kjLwUVu# z!&J=NYME>K>kFALHZqK`@H07gEH1R}@$%m^4YaR4Kf~CIyA#7WW^{@bd-(AT;a|*v za>(p2GgUB>!AAY7Lx`_B#MH$F<&R8Ak5em%_yw{j?A}Te#x;V@B2TbutJKCRR9ocwSZBQDL6|_-SOI0TCZ~5`y(^%t{BMbuM^Uekl|LuAVS? zq_WWyB3UssFS-*dm-R5@JH>Pad@a#u%AC!QwvSaiaaWAQY-<0lmIC0j{_*B8roP2= z*b>hh$X)C`EM}dhGveRCB+9`bC!YRpkS@KLO#4StgBx?Dj>L|oVk^&;7BGG;JuQ(A z^CtQIKI2vj6|Sgqge`<}hyf$nIAgZ}=D?P_l5I}sbu5SD!LRWsK}aD6PYo^R{&@BM z>_pIg#t2hEx;SeBtLO)Incq zX-xxJXD1I!Cl6!I=Ps7+hJT2HW}iwMh`0g4!DOtylMIl#YfB^^tM<}Oj&+{7;Ja*% z!Az5Nri@k+KLyj0#dJMi6<>1ZfMBuw1iXP?l#NW36?dZ*r>F$haR1h*J#R*AWyeH_ zYPrrY*x2nUx=ug!(52V3Kw6G`*C_1SPf>bC_n+U`aTEV+7CwUR@kDlo@yiaO!e=`f zx2BfmOs-aWxBBf@V3EZM!AdxK-+gU8wn6D--ynO=*aF2S*4#)3Uq8;$CgD;OPfun> zEf30}dXjz0Pq!V>c~q%u6EL76UW*V82a~c9++4t~P4Eo=PFvk-29M$lgKtDSyP{qY zs6*j)n9p_)&=`O@KKv{{O3`0#A;J+5U~`mw7=6ICCVO!~{amcbdY6}G>iqS^(?bC- z#@C^32#I3?dN;&C@bO2!iRB?U93kts&M;E+h{;9zr}4QFNzug)?UDf%V}M;8??gc2 z7u7$3j`@K{AL$mI8z|SHW00d=PCl--{;0{vf6A3P$aTf5{U2&Fa49s%t**@pt}9<9 z-KZAvQk0SP1F3x3FkV-^%1TkJ{8A{e{;2)~N58(#)nbL>u$RJ({r~^}zZmWHRjz_M zs<2&(3DTOVgIq6j*H^fTLMZURlmPtyQ3|fBUrjp{R9y-Y;T842f$O^V?3KtsrRJp= bB7OQl5>-v{2GYuCXt>Br5{a9~fA;)8aN=Ft literal 0 HcmV?d00001 From 8646b4f512541df465d2a5f905a9102f2f447698 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:29:26 -0400 Subject: [PATCH 613/615] add pdoc in a step --- .github/workflows/pdoc.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index 5a8b07e5a..fec187f31 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -5,7 +5,6 @@ on: push: branches: - develop - - fix-pdoc-workflow workflow_dispatch: # Allow manually triggering the workflow # security: restrict permissions for CI jobs. From e9a8af9386509dbde24df86eaed1224f672cf133 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:32:22 -0400 Subject: [PATCH 614/615] revert poetry version back --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index fec187f31..f99bb1317 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -27,7 +27,7 @@ jobs: build: runs-on: ubuntu-latest env: - POETRY_VERSION: 1.3.0 + POETRY_VERSION: 1.2.0 strategy: matrix: python-version: ["3.10"] From 1f298d924df26f3ef70d42a3a56b99bcea877e23 Mon Sep 17 00:00:00 2001 From: linglp Date: Thu, 15 Jun 2023 17:39:51 -0400 Subject: [PATCH 615/615] added back python version --- .github/workflows/pdoc.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pdoc.yml b/.github/workflows/pdoc.yml index f99bb1317..8823d0c02 100644 --- a/.github/workflows/pdoc.yml +++ b/.github/workflows/pdoc.yml @@ -30,7 +30,7 @@ jobs: POETRY_VERSION: 1.2.0 strategy: matrix: - python-version: ["3.10"] + python-version: ["3.9", "3.10"] steps: #----------------------------------------------