diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..8b05a9a --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @Sage-Bionetworks-Workflows/dpe diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e5cc84..977a0e3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,20 +2,20 @@ # MODIFY IT ACCORDING TO YOUR NEEDS! # Reference: https://docs.github.com/en/actions -name: tests +name: test on: push: # Avoid using all the resources/limits available by checking only # relevant branches and tags. Other branches can be checked via PRs. branches: [main] - tags: ['v[0-9]*', '[0-9]+.[0-9]+*'] # Match tags that resemble a version - pull_request: # Run in every PR - workflow_dispatch: # Allow manually triggering the workflow + tags: ["v[0-9]*", "[0-9]+.[0-9]+*"] # Match tags that resemble a version + pull_request: # Run in every PR + workflow_dispatch: # Allow manually triggering the workflow schedule: # Run roughly every 15 days at 00:00 UTC # (useful to check if updates on dependencies break the package) - - cron: '0 0 1,16 * *' + - cron: "0 0 1,16 * *" concurrency: group: >- @@ -31,9 +31,9 @@ jobs: tarball-path: ${{ steps.distribution-paths.outputs.tarball }} steps: - uses: actions/checkout@v3 - with: {fetch-depth: 0} # deep clone for setuptools-scm + with: { fetch-depth: 0 } # deep clone for setuptools-scm - uses: actions/setup-python@v4 - with: {python-version: "3.11"} + with: { python-version: "3.11" } - name: Run static analysis and format checkers run: pipx run pre-commit run --all-files --show-diff-on-failure - name: Install tox-gh plugin @@ -54,17 +54,21 @@ jobs: name: python-distribution-files path: dist/ retention-days: 1 + - name: Keepalive Workflow + uses: gautamkrishnar/keepalive-workflow@1.1.0 + with: + time_elapsed: 44 test: needs: prepare strategy: matrix: python: - - "3.9" # oldest Python that is supported - - "3.11" # newest Python that is stable + - "3.9" # oldest Python that is supported + - "3.11" # newest Python that is stable platform: - - ubuntu-latest - - macos-latest + - ubuntu-latest + - macos-latest # TODO: Debug the Windows issues # - windows-latest env: @@ -77,7 +81,7 @@ jobs: with: python-version: ${{ matrix.python }} - uses: actions/download-artifact@v3 - with: {name: python-distribution-files, path: dist/} + with: { name: python-distribution-files, path: dist/ } - name: Install tox-gh plugin run: python -m pip install tox-gh>=1.2 - name: Setup test suite @@ -106,9 +110,9 @@ jobs: steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 - with: {python-version: "3.11"} + with: { python-version: "3.11" } - uses: actions/download-artifact@v3 - with: {name: python-distribution-files, path: dist/} + with: { name: python-distribution-files, path: dist/ } - name: Publish Python Package to PyPI env: TWINE_REPOSITORY: pypi @@ -123,7 +127,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: actions/download-artifact@v3 - with: {name: python-distribution-files, path: dist/} + with: { name: python-distribution-files, path: dist/ } - uses: docker/setup-qemu-action@v2 - uses: docker/setup-buildx-action@v2 - uses: docker/login-action@v2 diff --git a/.gitignore b/.gitignore index 45af9c3..c95cde1 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,5 @@ MANIFEST .venv*/ .conda*/ .python-version + +debugging/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3c3bbd1..04555af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -43,18 +43,18 @@ that any documentation update is done in the same way was a code contribution. The documentation is written using [CommonMark] with [MyST] extensions. :::{tip} - Please notice that the [GitHub web interface] provides a quick way of - propose changes in `dcqc`'s files. While this mechanism can - be tricky for normal code contributions, it works perfectly fine for - contributing to the docs, and can be quite handy. - - If you are interested in trying this method out, please navigate to - the `docs` folder in the source [repository], find which file you - would like to propose changes and click in the little pencil icon at the - top, to open [GitHub's code editor]. Once you finish editing the file, - please write a message in the form at the bottom of the page describing - which changes have you made and what are the motivations behind them and - submit your proposal. +Please notice that the [GitHub web interface] provides a quick way of +propose changes in `dcqc`'s files. While this mechanism can +be tricky for normal code contributions, it works perfectly fine for +contributing to the docs, and can be quite handy. + +If you are interested in trying this method out, please navigate to +the `docs` folder in the source [repository], find which file you +would like to propose changes and click in the little pencil icon at the +top, to open [GitHub's code editor]. Once you finish editing the file, +please write a message in the form at the bottom of the page describing +which changes have you made and what are the motivations behind them and +submit your proposal. ::: When working on documentation changes in your local machine, you can @@ -91,7 +91,7 @@ This often provides additional considerations and avoids unnecessary work. 1. Create an user account on GitHub if you do not already have one. -2. Fork the project [repository]: click on the *Fork* button near the top of the +2. Fork the project [repository]: click on the _Fork_ button near the top of the page. This creates a copy of the code under your account on GitHub. 3. Clone this copy to your local disk: @@ -108,7 +108,7 @@ This often provides additional considerations and avoids unnecessary work. ``` to create an isolated virtual environment containing package dependencies, - including those needed for development (*e.g.* testing, documentation). + including those needed for development (_e.g._ testing, documentation). 5. Install [pre-commit] hooks: @@ -186,34 +186,79 @@ This often provides additional considerations and avoids unnecessary work. the PR as a draft first and mark it as ready for review after the feedbacks from the continuous integration (CI) system or any required fixes. -### Special Considerations for Contributing External Tests +### Contributing Internal Tests + +In `py-dcqc`, any test where the primary business logic is executed within the package itself is considered internal. One example is the `Md5ChecksumTest`. + +When contributing an internal test be sure to do the following: + +1. Follow the steps above to set up `py-dcqc` and create your contribution. + +1. Include a class docstring that describes the purpose of the test. + +1. Include the following class attributes: + + - `tier`: A `TestTier` enum describing the complexity of the test contributed. Valid `tier` values include: + - `FILE_INTEGRITY` + - `INTERNAL_CONFORMANCE` + - `EXTERNAL_CONFORMANCE` + - `SUBJECTIVE_CONFORMANCE` + - `target`: The target class that the test will be applied to. This value will be `SingleTarget` for individual files and `PairedTarget` for paired files. + +1. Implement the major logic of the test in the `compute_status` method. This should include a condition for returning a `status` of `TestStatus.PASS` when the test conditions are met and `TestStatus.FAIL` when they are not. + - For failing cases be sure to include a line setting the class' `status_reason` to a helpful string that will tell users why the test failed before returning the `status`. + +### Contributing External Tests In `py-dcqc`, any test where the primary business logic is executed outside of this package itself is considered to be external. One example is the `LibTiffInfoTest`. For these tests, `py-dcqc` is responsible for packaging up a Nextflow process which is then executed in an [nf-dcqc](https://github.com/Sage-Bionetworks-Workflows/nf-dcqc) workflow run. Such tests are not possible to run in `py-dcqc` alone at this time. This makes contributing, testing, debugging, and using external tests a little more complicated that internal tests such as the `Md5ChecksumTest` which has all of its logic built into this package. -When contributing an external test, following these steps may be helpful: +When contributing an internal test be sure to do the following: 1. Follow the steps above to set up `py-dcqc` and create your contribution. -2. Follow the instructions in the [README.md](https://github.com/Sage-Bionetworks-Workflows/nf-dcqc/blob/dev/README.md) +1. Include a class docstring that describes the purpose of the test. + +1. Include the following class attributes: + + - `tier`: A `TestTier` enum describing the complexity of the test contributed. Valid `tier` values include: + - `FILE_INTEGRITY` + - `INTERNAL_CONFORMANCE` + - `EXTERNAL_CONFORMANCE` + - `SUBJECTIVE_CONFORMANCE` + - `pass_code`: The exit code that will be returned by the command indicating a passed test. + - `fail_code`: The exit code that will be returned by the command indicating a failed test. + - `failure_reason_location`: The file (either `"std_out"` or `"std_err"`) that will contain the reason for a failed test. + - `target`: The target class that the test will be applied to. This value will be `SingleTarget` for individual files and `PairedTarget` for paired files. + +1. If possible, contribute an external test that returns different codes when it fails and when it errors out. Currently, a limitation of DCQC is that several external tests return the same `exit_code` when they fail and encounter an error. This will be addressed in future work that will add finer grained result interpretation. + +### Testing Your Changes + +1. Follow the instructions in the [README.md](https://github.com/Sage-Bionetworks-Workflows/nf-dcqc/blob/dev/README.md) file in the `nf-dcqc` respository to set up the workflow on your local machine. + - Run `git checkout dev` to switch to the developer branch -3. Build your local version of `py-dcqc` with your new changes with: +1. Build your local version of `py-dcqc` with your new changes with: + ```console src/docker/build.sh ``` + NOTE: This step assumes that you have docker installed and that it is running, and that you have `pipx` installed. -4. Follow `nf-dcqc` instructions to create a `nextflow run` command that tests your contribution. +1. Follow `nf-dcqc` instructions to create a `nextflow run` command that tests your contribution. + - You should include at least two files in your `nf-dcqc` input file ([example](https://github.com/Sage-Bionetworks-Workflows/nf-dcqc/blob/dev/testdata/input_full.csv)), one that you expect to pass your contributed test, and one that you expect to fail. - Include the `local` profile so that the workflow leverages your locally built `py-orca` container Example command (executed from within your local `nf-dcqc` repo clone): + ``` nextflow run main.nf -profile local,docker --input path/to/your/input.csv -- outdir output --required_tests ``` -5. Examine the final `suites.json` that is exported by the Nextflow workflow, if your contributed test bahaved as +1. Examine the final `output.csv` and `suites.json` files exported by the Nextflow workflow, if your contributed test bahaved as expected, you're done! If not, debug and make changes to your contribution and re-run the workflow. ### Troubleshooting @@ -291,7 +336,8 @@ on [PyPI], the following steps can be used to release a new version for 6. Run `tox -e publish -- --repository pypi` and check that everything was uploaded to [PyPI] correctly. -[^contrib1]: Even though, these resources focus on open source projects and +[^contrib1]: + Even though, these resources focus on open source projects and communities, the general ideas behind collaborating with other developers to collectively create software are general and can be applied to all sorts of environments, including private companies and proprietary code bases. diff --git a/Pipfile.lock b/Pipfile.lock index c9ad561..4691db5 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -23,13 +23,21 @@ ], "version": "==1.4.4" }, + "backoff": { + "hashes": [ + "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", + "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8" + ], + "markers": "python_version >= '3.7'", + "version": "==2.2.1" + }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "charset-normalizer": { "hashes": [ @@ -159,27 +167,35 @@ }, "fs-synapse": { "hashes": [ - "sha256:1c8fb5b1da3220d21d13a6e48642d8b75a913a9b4779b99d6de9fc6074167898", - "sha256:8d95badbd14a052eac06875bcefec4570d336bbe318f0aa7878c469a70dfd35f" + "sha256:3fe1397564b0a84e4f6ae9e07bf3a0d002623d486e591a965a89be4b3e392bf4", + "sha256:c4ec5c3d04d7fcc3a4115cdf496e1055a680893a2dfb1c649271fc240964efe9" ], - "markers": "python_version >= '3.8'", - "version": "==1.0.0" + "markers": "python_version < '3.12' and python_version >= '3.9'", + "version": "==2.0.1" + }, + "googleapis-common-protos": { + "hashes": [ + "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e", + "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632" + ], + "markers": "python_version >= '3.7'", + "version": "==1.63.0" }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "importlib-metadata": { "hashes": [ - "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116", - "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d" + "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443", + "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b" ], - "markers": "python_version >= '3.7'", - "version": "==4.13.0" + "markers": "python_version >= '3.8'", + "version": "==6.11.0" }, "isodate": { "hashes": [ @@ -188,21 +204,86 @@ ], "version": "==0.6.1" }, - "keyring": { + "nest-asyncio": { "hashes": [ - "sha256:17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca", - "sha256:89cbd74d4683ed164c8082fb38619341097741323b3786905c6dac04d6915a55" + "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", + "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c" ], - "markers": "python_version >= '3.6'", - "version": "==23.4.1" + "markers": "python_version >= '3.5'", + "version": "==1.6.0" + }, + "opentelemetry-api": { + "hashes": [ + "sha256:4bb86b28627b7e41098f0e93280fe4892a1abed1b79a19aec6f928f39b17dffb", + "sha256:d6185fd5043e000075d921822fd2d26b953eba8ca21b1e2fa360dd46a7686316" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-common": { + "hashes": [ + "sha256:61db274d8a68d636fb2ec2a0f281922949361cdd8236e25ff5539edf942b3226", + "sha256:97b1022b38270ec65d11fbfa348e0cd49d12006485c2321ea3b1b7037d42b6ec" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-http": { + "hashes": [ + "sha256:19d60afa4ae8597f7ef61ad75c8b6c6b7ef8cb73a33fb4aed4dbc86d5c8d3301", + "sha256:56837773de6fb2714c01fc4895caebe876f6397bbc4d16afddf89e1299a55ee2" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-proto": { + "hashes": [ + "sha256:32fc4248e83eebd80994e13963e683f25f3b443226336bb12b5b6d53638f50ba", + "sha256:7d5172c29ed1b525b5ecf4ebe758c7138a9224441b3cfe683d0a237c33b1941f" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-sdk": { + "hashes": [ + "sha256:3ec8cd3020328d6bc5c9991ccaf9ae820ccb6395a5648d9a95d3ec88275b8879", + "sha256:9fe633243a8c655fedace3a0b89ccdfc654c0290ea2d8e839bd5db3131186f73" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-semantic-conventions": { + "hashes": [ + "sha256:44ae67a0a3252a05072877857e5cc1242c98d4cf12870159f1a94bec800d38ec", + "sha256:5cd719cbfec448af658860796c5d0fcea2fdf0945a2bed2363f42cb1ee39f526" + ], + "markers": "python_version >= '3.7'", + "version": "==0.42b0" + }, + "protobuf": { + "hashes": [ + "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4", + "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8", + "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c", + "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d", + "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4", + "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa", + "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c", + "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019", + "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", + "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c", + "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2" + ], + "markers": "python_version >= '3.8'", + "version": "==4.25.3" }, "pyparsing": { "hashes": [ - "sha256:32c7c0b711493c72ff18a981d24f28aaf9c1fb7ed5e9667c9e84e3db623bdbfb", - "sha256:ede28a1a32462f5a9705e07aea48001a08f7cf81a021585011deba701581a0db" + "sha256:a1bac0ce561155ecc3ed78ca94d3c9378656ad4c94c1270de543f621420f94ad", + "sha256:f9db75911801ed778fe61bb643079ff86601aca99fcae6345aa67292038fb742" ], "markers": "python_full_version >= '3.6.8'", - "version": "==3.1.1" + "version": "==3.1.2" }, "rdflib": { "hashes": [ @@ -221,11 +302,11 @@ }, "setuptools": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987", + "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" + "version": "==69.5.1" }, "six": { "hashes": [ @@ -237,11 +318,11 @@ }, "synapseclient": { "hashes": [ - "sha256:dc5a61f9f495109a0c89aa7d42b641b6ff278280d7961fb450dd5015704fe15b", - "sha256:dd8b1a1b4667d08311bb651469431f43fe2eeab83c0ef1fe5a03c2929aeb26cd" + "sha256:5261a2751ea5757750e0cb2e481ecb2761954e2c0969e7cc5dd1dfff43c3ddcc", + "sha256:c5e0ac45faed1aa618cd66a0f50bf1a8149a2902a71d07487a0e470250955083" ], - "markers": "python_version >= '3.7'", - "version": "==2.7.2" + "markers": "python_version >= '3.8'", + "version": "==4.1.1" }, "typer": { "hashes": [ @@ -251,6 +332,14 @@ "markers": "python_version >= '3.6'", "version": "==0.7.0" }, + "typing-extensions": { + "hashes": [ + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" + ], + "markers": "python_version >= '3.8'", + "version": "==4.11.0" + }, "urllib3": { "hashes": [ "sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07", @@ -337,21 +426,21 @@ }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b", + "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715" ], "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.18.1" } }, "develop": { "alabaster": { "hashes": [ - "sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3", - "sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2" + "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", + "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92" ], - "markers": "python_version >= '3.6'", - "version": "==0.7.13" + "markers": "python_version >= '3.9'", + "version": "==0.7.16" }, "appdirs": { "hashes": [ @@ -362,11 +451,11 @@ }, "appnope": { "hashes": [ - "sha256:02bd91c4de869fbb1e1c50aafc4098827a7a54ab2f39d9dcba6c9547ed920e24", - "sha256:265a455292d0bd8a72453494fa24df5a11eb18373a60c7c0430889f22548605e" + "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", + "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c" ], "markers": "platform_system == 'Darwin'", - "version": "==0.1.3" + "version": "==0.1.4" }, "asttokens": { "hashes": [ @@ -377,19 +466,27 @@ }, "attrs": { "hashes": [ - "sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04", - "sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015" + "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30", + "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1" ], "markers": "python_version >= '3.7'", - "version": "==23.1.0" + "version": "==23.2.0" }, "babel": { "hashes": [ - "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363", - "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287" + "sha256:08706bdad8d0a3413266ab61bd6c34d0c28d6e1e7badf40a2cebe67644e2e1fb", + "sha256:8daf0e265d05768bc6c7a314cf1321e9a123afc328cc635c18622a2f30a04413" + ], + "markers": "python_version >= '3.8'", + "version": "==2.15.0" + }, + "backoff": { + "hashes": [ + "sha256:03f829f5bb1923180821643f8753b0502c3b682293992485b0eef2807afa5cba", + "sha256:63579f9a0628e06278f7e47b7d7d5b6ce20dc65c5e96a6f3ca99a6adca0396e8" ], "markers": "python_version >= '3.7'", - "version": "==2.14.0" + "version": "==2.2.1" }, "black": { "hashes": [ @@ -410,11 +507,11 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "cfgv": { "hashes": [ @@ -538,72 +635,72 @@ }, "comm": { "hashes": [ - "sha256:2da8d9ebb8dd7bfc247adaff99f24dce705638a8042b85cb995066793e391001", - "sha256:a517ea2ca28931c7007a7a99c562a0fa5883cfb48963140cf642c41c948498be" + "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", + "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3" ], "markers": "python_version >= '3.8'", - "version": "==0.2.0" + "version": "==0.2.2" }, "coverage": { "extras": [ "toml" ], "hashes": [ - "sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1", - "sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63", - "sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9", - "sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312", - "sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3", - "sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb", - "sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25", - "sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92", - "sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda", - "sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148", - "sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6", - "sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216", - "sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a", - "sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640", - "sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836", - "sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c", - "sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f", - "sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2", - "sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901", - "sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed", - "sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a", - "sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074", - "sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc", - "sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84", - "sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083", - "sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f", - "sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c", - "sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c", - "sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637", - "sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2", - "sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82", - "sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f", - "sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce", - "sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef", - "sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f", - "sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611", - "sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c", - "sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76", - "sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9", - "sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce", - "sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9", - "sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf", - "sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf", - "sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9", - "sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6", - "sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2", - "sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a", - "sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a", - "sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf", - "sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738", - "sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a", - "sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4" + "sha256:0646599e9b139988b63704d704af8e8df7fa4cbc4a1f33df69d97f36cb0a38de", + "sha256:0cdcbc320b14c3e5877ee79e649677cb7d89ef588852e9583e6b24c2e5072661", + "sha256:0d0a0f5e06881ecedfe6f3dd2f56dcb057b6dbeb3327fd32d4b12854df36bf26", + "sha256:1434e088b41594baa71188a17533083eabf5609e8e72f16ce8c186001e6b8c41", + "sha256:16db7f26000a07efcf6aea00316f6ac57e7d9a96501e990a36f40c965ec7a95d", + "sha256:1cc0fe9b0b3a8364093c53b0b4c0c2dd4bb23acbec4c9240b5f284095ccf7981", + "sha256:1fc81d5878cd6274ce971e0a3a18a8803c3fe25457165314271cf78e3aae3aa2", + "sha256:2ec92012fefebee89a6b9c79bc39051a6cb3891d562b9270ab10ecfdadbc0c34", + "sha256:39afcd3d4339329c5f58de48a52f6e4e50f6578dd6099961cf22228feb25f38f", + "sha256:4a7b0ceee8147444347da6a66be737c9d78f3353b0681715b668b72e79203e4a", + "sha256:4a9ca3f2fae0088c3c71d743d85404cec8df9be818a005ea065495bedc33da35", + "sha256:4bf0655ab60d754491004a5efd7f9cccefcc1081a74c9ef2da4735d6ee4a6223", + "sha256:4cc37def103a2725bc672f84bd939a6fe4522310503207aae4d56351644682f1", + "sha256:4fc84a37bfd98db31beae3c2748811a3fa72bf2007ff7902f68746d9757f3746", + "sha256:5037f8fcc2a95b1f0e80585bd9d1ec31068a9bcb157d9750a172836e98bc7a90", + "sha256:54de9ef3a9da981f7af93eafde4ede199e0846cd819eb27c88e2b712aae9708c", + "sha256:556cf1a7cbc8028cb60e1ff0be806be2eded2daf8129b8811c63e2b9a6c43bca", + "sha256:57e0204b5b745594e5bc14b9b50006da722827f0b8c776949f1135677e88d0b8", + "sha256:5a5740d1fb60ddf268a3811bcd353de34eb56dc24e8f52a7f05ee513b2d4f596", + "sha256:5c3721c2c9e4c4953a41a26c14f4cef64330392a6d2d675c8b1db3b645e31f0e", + "sha256:5fa567e99765fe98f4e7d7394ce623e794d7cabb170f2ca2ac5a4174437e90dd", + "sha256:5fd215c0c7d7aab005221608a3c2b46f58c0285a819565887ee0b718c052aa4e", + "sha256:6175d1a0559986c6ee3f7fccfc4a90ecd12ba0a383dcc2da30c2b9918d67d8a3", + "sha256:61c4bf1ba021817de12b813338c9be9f0ad5b1e781b9b340a6d29fc13e7c1b5e", + "sha256:6537e7c10cc47c595828b8a8be04c72144725c383c4702703ff4e42e44577312", + "sha256:68f962d9b72ce69ea8621f57551b2fa9c70509af757ee3b8105d4f51b92b41a7", + "sha256:7352b9161b33fd0b643ccd1f21f3a3908daaddf414f1c6cb9d3a2fd618bf2572", + "sha256:796a79f63eca8814ca3317a1ea443645c9ff0d18b188de470ed7ccd45ae79428", + "sha256:79afb6197e2f7f60c4824dd4b2d4c2ec5801ceb6ba9ce5d2c3080e5660d51a4f", + "sha256:7a588d39e0925f6a2bff87154752481273cdb1736270642aeb3635cb9b4cad07", + "sha256:8748731ad392d736cc9ccac03c9845b13bb07d020a33423fa5b3a36521ac6e4e", + "sha256:8fe7502616b67b234482c3ce276ff26f39ffe88adca2acf0261df4b8454668b4", + "sha256:9314d5678dcc665330df5b69c1e726a0e49b27df0461c08ca12674bcc19ef136", + "sha256:9735317685ba6ec7e3754798c8871c2f49aa5e687cc794a0b1d284b2389d1bd5", + "sha256:9981706d300c18d8b220995ad22627647be11a4276721c10911e0e9fa44c83e8", + "sha256:9e78295f4144f9dacfed4f92935fbe1780021247c2fabf73a819b17f0ccfff8d", + "sha256:b016ea6b959d3b9556cb401c55a37547135a587db0115635a443b2ce8f1c7228", + "sha256:b6cf3764c030e5338e7f61f95bd21147963cf6aa16e09d2f74f1fa52013c1206", + "sha256:beccf7b8a10b09c4ae543582c1319c6df47d78fd732f854ac68d518ee1fb97fa", + "sha256:c0884920835a033b78d1c73b6d3bbcda8161a900f38a488829a83982925f6c2e", + "sha256:c3e757949f268364b96ca894b4c342b41dc6f8f8b66c37878aacef5930db61be", + "sha256:ca498687ca46a62ae590253fba634a1fe9836bc56f626852fb2720f334c9e4e5", + "sha256:d1d0d98d95dd18fe29dc66808e1accf59f037d5716f86a501fc0256455219668", + "sha256:d21918e9ef11edf36764b93101e2ae8cc82aa5efdc7c5a4e9c6c35a48496d601", + "sha256:d7fed867ee50edf1a0b4a11e8e5d0895150e572af1cd6d315d557758bfa9c057", + "sha256:db66fc317a046556a96b453a58eced5024af4582a8dbdc0c23ca4dbc0d5b3146", + "sha256:dde0070c40ea8bb3641e811c1cfbf18e265d024deff6de52c5950677a8fb1e0f", + "sha256:df4e745a81c110e7446b1cc8131bf986157770fa405fe90e15e850aaf7619bc8", + "sha256:e2213def81a50519d7cc56ed643c9e93e0247f5bbe0d1247d15fa520814a7cd7", + "sha256:ef48e2707fb320c8f139424a596f5b69955a85b178f15af261bab871873bb987", + "sha256:f152cbf5b88aaeb836127d920dd0f5e7edff5a66f10c079157306c4343d86c19", + "sha256:fc0b4d8bfeabd25ea75e94632f5b6e047eef8adaed0c2161ada1e922e7f7cece" ], "markers": "python_version >= '3.8'", - "version": "==7.3.2" + "version": "==7.5.1" }, "dcqc": { "editable": true, @@ -614,27 +711,31 @@ }, "debugpy": { "hashes": [ - "sha256:125b9a637e013f9faac0a3d6a82bd17c8b5d2c875fb6b7e2772c5aba6d082332", - "sha256:12af2c55b419521e33d5fb21bd022df0b5eb267c3e178f1d374a63a2a6bdccd0", - "sha256:3c6fb41c98ec51dd010d7ed650accfd07a87fe5e93eca9d5f584d0578f28f35f", - "sha256:46ab6780159eeabb43c1495d9c84cf85d62975e48b6ec21ee10c95767c0590aa", - "sha256:57161629133113c97b387382045649a2b985a348f0c9366e22217c87b68b73c6", - "sha256:5d9de202f5d42e62f932507ee8b21e30d49aae7e46d5b1dd5c908db1d7068637", - "sha256:60009b132c91951354f54363f8ebdf7457aeb150e84abba5ae251b8e9f29a8a6", - "sha256:61eab4a4c8b6125d41a34bad4e5fe3d2cc145caecd63c3fe953be4cc53e65bf8", - "sha256:7fb95ca78f7ac43393cd0e0f2b6deda438ec7c5e47fa5d38553340897d2fbdfb", - "sha256:8cd0197141eb9e8a4566794550cfdcdb8b3db0818bdf8c49a8e8f8053e56e38b", - "sha256:9c9b0ac1ce2a42888199df1a1906e45e6f3c9555497643a85e0bf2406e3ffbc4", - "sha256:a64093656c4c64dc6a438e11d59369875d200bd5abb8f9b26c1f5f723622e153", - "sha256:a8b7a2fd27cd9f3553ac112f356ad4ca93338feadd8910277aff71ab24d8775f", - "sha256:b05a6b503ed520ad58c8dc682749113d2fd9f41ffd45daec16e558ca884008cd", - "sha256:bdc5ef99d14b9c0fcb35351b4fbfc06ac0ee576aeab6b2511702e5a648a2e595", - "sha256:e3412f9faa9ade82aa64a50b602544efcba848c91384e9f93497a458767e6926", - "sha256:ef54404365fae8d45cf450d0544ee40cefbcb9cb85ea7afe89a963c27028261e", - "sha256:ef9ab7df0b9a42ed9c878afd3eaaff471fce3fa73df96022e1f5c9f8f8c87ada" + "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb", + "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146", + "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8", + "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242", + "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0", + "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741", + "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539", + "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23", + "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3", + "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39", + "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd", + "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9", + "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace", + "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42", + "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0", + "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7", + "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e", + "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234", + "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98", + "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703", + "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42", + "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099" ], "markers": "python_version >= '3.8'", - "version": "==1.8.0" + "version": "==1.8.1" }, "decorator": { "hashes": [ @@ -676,11 +777,11 @@ }, "execnet": { "hashes": [ - "sha256:88256416ae766bc9e8895c76a87928c0012183da3cc4fc18016e6f050e025f41", - "sha256:cc59bc4423742fd71ad227122eb0dd44db51efb3dc4095b45ac9a08c770096af" + "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", + "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3" ], - "markers": "python_version >= '3.7'", - "version": "==2.0.2" + "markers": "python_version >= '3.8'", + "version": "==2.1.1" }, "executing": { "hashes": [ @@ -692,18 +793,18 @@ }, "fastjsonschema": { "hashes": [ - "sha256:b9fd1a2dd6971dbc7fee280a95bd199ae0dd9ce22beb91cc75e9c1c528a5170e", - "sha256:e25df6647e1bc4a26070b700897b07b542ec898dd4f1f6ea013e7f6a88417225" + "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0", + "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d" ], - "version": "==2.19.0" + "version": "==2.19.1" }, "filelock": { "hashes": [ - "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e", - "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c" + "sha256:43339835842f110ca7ae60f1e1c160714c5a6afd15a2873419ab185334975c0f", + "sha256:6ea72da3be9b8c82afd3edcf99f2fffbb5076335a5ae4d03248bb5b6c3eae78a" ], "markers": "python_version >= '3.8'", - "version": "==3.13.1" + "version": "==3.14.0" }, "flake8": { "hashes": [ @@ -727,11 +828,19 @@ }, "fs-synapse": { "hashes": [ - "sha256:1c8fb5b1da3220d21d13a6e48642d8b75a913a9b4779b99d6de9fc6074167898", - "sha256:8d95badbd14a052eac06875bcefec4570d336bbe318f0aa7878c469a70dfd35f" + "sha256:3fe1397564b0a84e4f6ae9e07bf3a0d002623d486e591a965a89be4b3e392bf4", + "sha256:c4ec5c3d04d7fcc3a4115cdf496e1055a680893a2dfb1c649271fc240964efe9" ], - "markers": "python_version >= '3.8'", - "version": "==1.0.0" + "markers": "python_version < '3.12' and python_version >= '3.9'", + "version": "==2.0.1" + }, + "googleapis-common-protos": { + "hashes": [ + "sha256:17ad01b11d5f1d0171c06d3ba5c04c54474e883b66b949722b4938ee2694ef4e", + "sha256:ae45f75702f7c08b541f750854a678bd8f534a1a6bace6afe975f1d0a82d6632" + ], + "markers": "python_version >= '3.7'", + "version": "==1.63.0" }, "hypothesis": { "hashes": [ @@ -742,19 +851,19 @@ }, "identify": { "hashes": [ - "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d", - "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34" + "sha256:37d93f380f4de590500d9dba7db359d0d3da95ffe7f9de1753faa159e71e7dfa", + "sha256:e5e00f54165f9047fbebeb4a560f9acfb8af4c88232be60a488e9b68d122745d" ], "markers": "python_version >= '3.8'", - "version": "==2.5.33" + "version": "==2.5.36" }, "idna": { "hashes": [ - "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca", - "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f" + "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc", + "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0" ], "markers": "python_version >= '3.5'", - "version": "==3.6" + "version": "==3.7" }, "imagesize": { "hashes": [ @@ -766,11 +875,11 @@ }, "importlib-metadata": { "hashes": [ - "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116", - "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d" + "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443", + "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b" ], - "markers": "python_version >= '3.7'", - "version": "==4.13.0" + "markers": "python_version >= '3.8'", + "version": "==6.11.0" }, "iniconfig": { "hashes": [ @@ -782,33 +891,33 @@ }, "interrogate": { "hashes": [ - "sha256:a4ccc5cbd727c74acc98dee6f5e79ef264c0bcfa66b68d4e123069b2af89091a", - "sha256:b6f325f0aa84ac3ac6779d8708264d366102226c5af7d69058cecffcff7a6d6c" + "sha256:a320d6ec644dfd887cc58247a345054fc4d9f981100c45184470068f4b3719b0", + "sha256:b13ff4dd8403369670e2efe684066de9fcb868ad9d7f2b4095d8112142dc9d12" ], - "version": "==1.5.0" + "version": "==1.7.0" }, "ipykernel": { "hashes": [ - "sha256:7d5d594b6690654b4d299edba5e872dc17bb7396a8d0609c97cb7b8a1c605de6", - "sha256:dab88b47f112f9f7df62236511023c9bdeef67abc73af7c652e4ce4441601686" + "sha256:1181e653d95c6808039c509ef8e67c4126b3b3af7781496c7cbfb5ed938a27da", + "sha256:3d44070060f9475ac2092b760123fadf105d2e2493c24848b6691a7c4f42af5c" ], "markers": "python_version >= '3.8'", - "version": "==6.27.1" + "version": "==6.29.4" }, "ipython": { "hashes": [ - "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", - "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397" + "sha256:010db3f8a728a578bb641fdd06c063b9fb8e96a9464c63aec6310fbcb5e80501", + "sha256:d7bf2f6c4314984e3e02393213bab8703cf163ede39672ce5918c51fe253a2a3" ], - "markers": "python_version >= '3.9'", - "version": "==8.18.1" + "markers": "python_version >= '3.10'", + "version": "==8.24.0" }, "isort": { "hashes": [ - "sha256:56a51732c25f94ca96f6721be206dd96a95f42950502eb26c1015d333bc6edb7", - "sha256:aaed790b463e8703fb1eddb831dfa8e8616bacde2c083bd557ef73c8189b7263" + "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", + "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6" ], - "version": "==5.13.1" + "version": "==5.13.2" }, "jedi": { "hashes": [ @@ -820,125 +929,117 @@ }, "jinja2": { "hashes": [ - "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852", - "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61" + "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", + "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" ], "markers": "python_version >= '3.7'", - "version": "==3.1.2" + "version": "==3.1.4" }, "jsonschema": { "hashes": [ - "sha256:4f614fd46d8d61258610998997743ec5492a648b33cf478c1ddc23ed4598a5fa", - "sha256:ed6231f0429ecf966f5bc8dfef245998220549cbbcf140f913b7464c52c3b6b3" + "sha256:5b22d434a45935119af990552c862e5d6d564e8f6601206b305a61fdf661a2b7", + "sha256:ff4cfd6b1367a40e7bc6411caec72effadd3db0bbe5017de188f2d6108335802" ], "markers": "python_version >= '3.8'", - "version": "==4.20.0" + "version": "==4.22.0" }, "jsonschema-specifications": { "hashes": [ - "sha256:9472fc4fea474cd74bea4a2b190daeccb5a9e4db2ea80efcf7a1b582fc9a81b8", - "sha256:e74ba7c0a65e8cb49dc26837d6cfe576557084a8b423ed16a420984228104f93" + "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc", + "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c" ], "markers": "python_version >= '3.8'", - "version": "==2023.11.2" + "version": "==2023.12.1" }, "jupyter-client": { "hashes": [ - "sha256:0642244bb83b4764ae60d07e010e15f0e2d275ec4e918a8f7b80fbbef3ca60c7", - "sha256:909c474dbe62582ae62b758bca86d6518c85234bdee2d908c778db6d72f39d99" + "sha256:3b7bd22f058434e3b9a7ea4b1500ed47de2713872288c0d511d19926f99b459f", + "sha256:e842515e2bab8e19186d89fdfea7abd15e39dd581f94e399f00e2af5a1652d3f" ], "markers": "python_version >= '3.8'", - "version": "==8.6.0" + "version": "==8.6.1" }, "jupyter-core": { "hashes": [ - "sha256:880b86053bf298a8724994f95e99b99130659022a4f7f45f563084b6223861d3", - "sha256:e11e02cd8ae0a9de5c6c44abf5727df9f2581055afe00b22183f621ba3585805" + "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", + "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9" ], "markers": "python_version >= '3.8'", - "version": "==5.5.0" - }, - "keyring": { - "hashes": [ - "sha256:17e49fb0d6883c2b4445359434dba95aad84aabb29bbff044ad0ed7100232eca", - "sha256:89cbd74d4683ed164c8082fb38619341097741323b3786905c6dac04d6915a55" - ], - "markers": "python_version >= '3.6'", - "version": "==23.4.1" + "version": "==5.7.2" }, "markupsafe": { "hashes": [ - "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", - "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", - "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", - "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", - "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c", - "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", - "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", - "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb", - "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939", - "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", - "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", - "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", - "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", - "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", - "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", - "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", - "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd", - "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", - "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", - "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", - "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", - "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", - "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", - "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", - "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", - "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007", - "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", - "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", - "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", - "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", - "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", - "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", - "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", - "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1", - "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", - "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", - "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c", - "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", - "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823", - "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", - "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", - "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", - "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", - "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", - "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", - "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", - "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", - "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", - "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", - "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", - "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", - "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", - "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", - "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", - "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", - "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", - "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2", - "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11" + "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", + "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", + "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", + "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", + "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532", + "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", + "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", + "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df", + "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4", + "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", + "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", + "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", + "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", + "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371", + "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2", + "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", + "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52", + "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", + "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", + "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", + "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", + "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0", + "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029", + "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", + "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a", + "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", + "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", + "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", + "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", + "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9", + "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", + "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", + "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3", + "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", + "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46", + "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", + "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a", + "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", + "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", + "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", + "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", + "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", + "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", + "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", + "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", + "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f", + "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50", + "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", + "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", + "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", + "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff", + "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", + "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", + "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", + "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf", + "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", + "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", + "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab", + "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", + "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68" ], "markers": "python_version >= '3.7'", - "version": "==2.1.3" + "version": "==2.1.5" }, "matplotlib-inline": { "hashes": [ - "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311", - "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304" + "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", + "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca" ], - "markers": "python_version >= '3.5'", - "version": "==0.1.6" + "markers": "python_version >= '3.8'", + "version": "==0.1.7" }, "mccabe": { "hashes": [ @@ -1001,26 +1102,26 @@ }, "nbformat": { "hashes": [ - "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9", - "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192" + "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", + "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b" ], "markers": "python_version >= '3.8'", - "version": "==5.9.2" + "version": "==5.10.4" }, "nbmake": { "hashes": [ - "sha256:233603c9186c659cb42524de36b556197c352ede1f9daeaa1b1141dfad226218", - "sha256:874c5b9d99922f88bf0c92a3b869e75bff154edba2538efef0a1d7ad2263f5fb" + "sha256:0b76b829e8b128eb1895539bacf515a1ee85e5b7b492cdfe76e3a12f804e069e", + "sha256:6cfa2b926d335e9c6dce7e8543d01b2398b0a56c03131c5c0bce2b1722116212" ], - "version": "==1.4.6" + "version": "==1.5.3" }, "nest-asyncio": { "hashes": [ - "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb", - "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d" + "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", + "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c" ], "markers": "python_version >= '3.5'", - "version": "==1.5.8" + "version": "==1.6.0" }, "nodeenv": { "hashes": [ @@ -1030,21 +1131,69 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4, 3.5, 3.6'", "version": "==1.8.0" }, + "opentelemetry-api": { + "hashes": [ + "sha256:4bb86b28627b7e41098f0e93280fe4892a1abed1b79a19aec6f928f39b17dffb", + "sha256:d6185fd5043e000075d921822fd2d26b953eba8ca21b1e2fa360dd46a7686316" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-common": { + "hashes": [ + "sha256:61db274d8a68d636fb2ec2a0f281922949361cdd8236e25ff5539edf942b3226", + "sha256:97b1022b38270ec65d11fbfa348e0cd49d12006485c2321ea3b1b7037d42b6ec" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-exporter-otlp-proto-http": { + "hashes": [ + "sha256:19d60afa4ae8597f7ef61ad75c8b6c6b7ef8cb73a33fb4aed4dbc86d5c8d3301", + "sha256:56837773de6fb2714c01fc4895caebe876f6397bbc4d16afddf89e1299a55ee2" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-proto": { + "hashes": [ + "sha256:32fc4248e83eebd80994e13963e683f25f3b443226336bb12b5b6d53638f50ba", + "sha256:7d5172c29ed1b525b5ecf4ebe758c7138a9224441b3cfe683d0a237c33b1941f" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-sdk": { + "hashes": [ + "sha256:3ec8cd3020328d6bc5c9991ccaf9ae820ccb6395a5648d9a95d3ec88275b8879", + "sha256:9fe633243a8c655fedace3a0b89ccdfc654c0290ea2d8e839bd5db3131186f73" + ], + "markers": "python_version >= '3.7'", + "version": "==1.21.0" + }, + "opentelemetry-semantic-conventions": { + "hashes": [ + "sha256:44ae67a0a3252a05072877857e5cc1242c98d4cf12870159f1a94bec800d38ec", + "sha256:5cd719cbfec448af658860796c5d0fcea2fdf0945a2bed2363f42cb1ee39f526" + ], + "markers": "python_version >= '3.7'", + "version": "==0.42b0" + }, "packaging": { "hashes": [ - "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5", - "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7" + "sha256:2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5", + "sha256:eb82c5e3e56209074766e6885bb04b8c38a0c015d0a30036ebe7ece34c9989e9" ], "markers": "python_version >= '3.7'", - "version": "==23.2" + "version": "==24.0" }, "parso": { "hashes": [ - "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0", - "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75" + "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", + "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d" ], "markers": "python_version >= '3.6'", - "version": "==0.8.3" + "version": "==0.8.4" }, "pathspec": { "hashes": [ @@ -1059,24 +1208,24 @@ "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f" ], - "markers": "sys_platform != 'win32'", + "markers": "sys_platform != 'win32' and sys_platform != 'emscripten'", "version": "==4.9.0" }, "platformdirs": { "hashes": [ - "sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380", - "sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420" + "sha256:031cd18d4ec63ec53e82dceaac0417d218a6863f7745dfcc9efe7793b7039bdf", + "sha256:17d5a1161b3fd67b390023cb2d3b026bbd40abde6fdb052dfbd3a29c3ba22ee1" ], "markers": "python_version >= '3.8'", - "version": "==4.1.0" + "version": "==4.2.1" }, "pluggy": { "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" + "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", + "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669" ], "markers": "python_version >= '3.8'", - "version": "==1.3.0" + "version": "==1.5.0" }, "pre-commit": { "hashes": [ @@ -1093,26 +1242,43 @@ "markers": "python_full_version >= '3.7.0'", "version": "==3.0.43" }, + "protobuf": { + "hashes": [ + "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4", + "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8", + "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c", + "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d", + "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4", + "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa", + "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c", + "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019", + "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", + "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c", + "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2" + ], + "markers": "python_version >= '3.8'", + "version": "==4.25.3" + }, "psutil": { "hashes": [ - "sha256:10e8c17b4f898d64b121149afb136c53ea8b68c7531155147867b7b1ac9e7e28", - "sha256:18cd22c5db486f33998f37e2bb054cc62fd06646995285e02a51b1e08da97017", - "sha256:3ebf2158c16cc69db777e3c7decb3c0f43a7af94a60d72e87b2823aebac3d602", - "sha256:51dc3d54607c73148f63732c727856f5febec1c7c336f8f41fcbd6315cce76ac", - "sha256:6e5fb8dc711a514da83098bc5234264e551ad980cec5f85dabf4d38ed6f15e9a", - "sha256:70cb3beb98bc3fd5ac9ac617a327af7e7f826373ee64c80efd4eb2856e5051e9", - "sha256:748c9dd2583ed86347ed65d0035f45fa8c851e8d90354c122ab72319b5f366f4", - "sha256:91ecd2d9c00db9817a4b4192107cf6954addb5d9d67a969a4f436dbc9200f88c", - "sha256:92e0cc43c524834af53e9d3369245e6cc3b130e78e26100d1f63cdb0abeb3d3c", - "sha256:a6f01f03bf1843280f4ad16f4bde26b817847b4c1a0db59bf6419807bc5ce05c", - "sha256:c69596f9fc2f8acd574a12d5f8b7b1ba3765a641ea5d60fb4736bf3c08a8214a", - "sha256:ca2780f5e038379e520281e4c032dddd086906ddff9ef0d1b9dcf00710e5071c", - "sha256:daecbcbd29b289aac14ece28eca6a3e60aa361754cf6da3dfb20d4d32b6c7f57", - "sha256:e4b92ddcd7dd4cdd3f900180ea1e104932c7bce234fb88976e2a3b296441225a", - "sha256:fb8a697f11b0f5994550555fcfe3e69799e5b060c8ecf9e2f75c69302cc35c0d", - "sha256:ff18b8d1a784b810df0b0fff3bcb50ab941c3b8e2c8de5726f9c71c601c611aa" - ], - "version": "==5.9.6" + "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d", + "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73", + "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8", + "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2", + "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e", + "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36", + "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7", + "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c", + "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee", + "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421", + "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf", + "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81", + "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0", + "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631", + "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4", + "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8" + ], + "version": "==5.9.8" }, "ptyprocess": { "hashes": [ @@ -1154,18 +1320,18 @@ }, "pygments": { "hashes": [ - "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c", - "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367" + "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", + "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" ], - "markers": "python_version >= '3.7'", - "version": "==2.17.2" + "markers": "python_version >= '3.8'", + "version": "==2.18.0" }, "pytest": { "hashes": [ - "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac", - "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5" + "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", + "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8" ], - "version": "==7.4.3" + "version": "==7.4.4" }, "pytest-cov": { "hashes": [ @@ -1176,28 +1342,28 @@ }, "pytest-mock": { "hashes": [ - "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f", - "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9" + "sha256:0b72c38033392a5f4621342fe11e9219ac11ec9d375f8e2a0c164539e0d70f6f", + "sha256:2719255a1efeceadbc056d6bf3df3d1c5015530fb40cf347c0f9afac88410bd0" ], - "version": "==3.12.0" + "version": "==3.14.0" }, "pytest-xdist": { "extras": [ "psutil" ], "hashes": [ - "sha256:cbb36f3d67e0c478baa57fa4edc8843887e0f6cfc42d677530a36d7472b32d8a", - "sha256:d075629c7e00b611df89f490a5063944bee7a4362a5ff11c7cc7824a03dfce24" + "sha256:9ed4adfb68a016610848639bb7e02c9352d5d9f03d04809919e2dafc3be4cca7", + "sha256:ead156a4db231eec769737f57668ef58a2084a34b2e55c4a8fa20d861107300d" ], - "version": "==3.5.0" + "version": "==3.6.1" }, "python-dateutil": { "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" + "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", + "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427" ], "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2'", - "version": "==2.8.2" + "version": "==2.9.0.post0" }, "pyyaml": { "hashes": [ @@ -1230,6 +1396,7 @@ "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4", "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba", "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8", + "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef", "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5", "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd", "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3", @@ -1257,110 +1424,105 @@ }, "pyzmq": { "hashes": [ - "sha256:004ff469d21e86f0ef0369717351073e0e577428e514c47c8480770d5e24a565", - "sha256:00a06faa7165634f0cac1abb27e54d7a0b3b44eb9994530b8ec73cf52e15353b", - "sha256:00c48ae2fd81e2a50c3485de1b9d5c7c57cd85dc8ec55683eac16846e57ac979", - "sha256:01171fc48542348cd1a360a4b6c3e7d8f46cdcf53a8d40f84db6707a6768acc1", - "sha256:019744b99da30330798bb37df33549d59d380c78e516e3bab9c9b84f87a9592f", - "sha256:02bbc1a87b76e04fd780b45e7f695471ae6de747769e540da909173d50ff8e2d", - "sha256:02c9087b109070c5ab0b383079fa1b5f797f8d43e9a66c07a4b8b8bdecfd88ee", - "sha256:07cd61a20a535524906595e09344505a9bd46f1da7a07e504b315d41cd42eb07", - "sha256:0806175f2ae5ad4b835ecd87f5f85583316b69f17e97786f7443baaf54b9bb98", - "sha256:09dfe949e83087da88c4a76767df04b22304a682d6154de2c572625c62ad6886", - "sha256:0dabfb10ef897f3b7e101cacba1437bd3a5032ee667b7ead32bbcdd1a8422fe7", - "sha256:0ddd6d71d4ef17ba5a87becf7ddf01b371eaba553c603477679ae817a8d84d75", - "sha256:0f513130c4c361201da9bc69df25a086487250e16b5571ead521b31ff6b02220", - "sha256:0f97bc2f1f13cb16905a5f3e1fbdf100e712d841482b2237484360f8bc4cb3d7", - "sha256:11e70516688190e9c2db14fcf93c04192b02d457b582a1f6190b154691b4c93a", - "sha256:146b9b1f29ead41255387fb07be56dc29639262c0f7344f570eecdcd8d683314", - "sha256:16b726c1f6c2e7625706549f9dbe9b06004dfbec30dbed4bf50cbdfc73e5b32a", - "sha256:1b3cbba2f47062b85fe0ef9de5b987612140a9ba3a9c6d2543c6dec9f7c2ab27", - "sha256:1b9b1f2ad6498445a941d9a4fee096d387fee436e45cc660e72e768d3d8ee611", - "sha256:1ec23bd7b3a893ae676d0e54ad47d18064e6c5ae1fadc2f195143fb27373f7f6", - "sha256:246747b88917e4867e2367b005fc8eefbb4a54b7db363d6c92f89d69abfff4b6", - "sha256:25c2dbb97d38b5ac9fd15586e048ec5eb1e38f3d47fe7d92167b0c77bb3584e9", - "sha256:2c6441e0398c2baacfe5ba30c937d274cfc2dc5b55e82e3749e333aabffde561", - "sha256:2c9a79f1d2495b167119d02be7448bfba57fad2a4207c4f68abc0bab4b92925b", - "sha256:2e2713ef44be5d52dd8b8e2023d706bf66cb22072e97fc71b168e01d25192755", - "sha256:313c3794d650d1fccaaab2df942af9f2c01d6217c846177cfcbc693c7410839e", - "sha256:3516e0b6224cf6e43e341d56da15fd33bdc37fa0c06af4f029f7d7dfceceabbc", - "sha256:359f7f74b5d3c65dae137f33eb2bcfa7ad9ebefd1cab85c935f063f1dbb245cc", - "sha256:39b1067f13aba39d794a24761e385e2eddc26295826530a8c7b6c6c341584289", - "sha256:3c00c9b7d1ca8165c610437ca0c92e7b5607b2f9076f4eb4b095c85d6e680a1d", - "sha256:3c53687dde4d9d473c587ae80cc328e5b102b517447456184b485587ebd18b62", - "sha256:3e124e6b1dd3dfbeb695435dff0e383256655bb18082e094a8dd1f6293114642", - "sha256:4345c9a27f4310afbb9c01750e9461ff33d6fb74cd2456b107525bbeebcb5be3", - "sha256:45999e7f7ed5c390f2e87ece7f6c56bf979fb213550229e711e45ecc7d42ccb8", - "sha256:49151b0efece79f6a79d41a461d78535356136ee70084a1c22532fc6383f4ad0", - "sha256:4cb8fc1f8d69b411b8ec0b5f1ffbcaf14c1db95b6bccea21d83610987435f1a4", - "sha256:4e5837af3e5aaa99a091302df5ee001149baff06ad22b722d34e30df5f0d9097", - "sha256:4e6f689880d5ad87918430957297c975203a082d9a036cc426648fcbedae769b", - "sha256:5074adeacede5f810b7ef39607ee59d94e948b4fd954495bdb072f8c54558181", - "sha256:518efd91c3d8ac9f9b4f7dd0e2b7b8bf1a4fe82a308009016b07eaa48681af82", - "sha256:55875492f820d0eb3417b51d96fea549cde77893ae3790fd25491c5754ea2f68", - "sha256:5a68d491fc20762b630e5db2191dd07ff89834086740f70e978bb2ef2668be08", - "sha256:5dde6751e857910c1339890f3524de74007958557593b9e7e8c5f01cd919f8a7", - "sha256:5e319ed7d6b8f5fad9b76daa0a68497bc6f129858ad956331a5835785761e003", - "sha256:5edac3f57c7ddaacdb4d40f6ef2f9e299471fc38d112f4bc6d60ab9365445fb0", - "sha256:6cc0020b74b2e410287e5942e1e10886ff81ac77789eb20bec13f7ae681f0fdd", - "sha256:6dd0d50bbf9dca1d0bdea219ae6b40f713a3fb477c06ca3714f208fd69e16fd8", - "sha256:7598d2ba821caa37a0f9d54c25164a4fa351ce019d64d0b44b45540950458840", - "sha256:759cfd391a0996345ba94b6a5110fca9c557ad4166d86a6e81ea526c376a01e8", - "sha256:7ae8f354b895cbd85212da245f1a5ad8159e7840e37d78b476bb4f4c3f32a9fe", - "sha256:7b6d09a8962a91151f0976008eb7b29b433a560fde056ec7a3db9ec8f1075438", - "sha256:7c61e346ac34b74028ede1c6b4bcecf649d69b707b3ff9dc0fab453821b04d1e", - "sha256:7f51a7b4ead28d3fca8dda53216314a553b0f7a91ee8fc46a72b402a78c3e43d", - "sha256:82544e0e2d0c1811482d37eef297020a040c32e0687c1f6fc23a75b75db8062c", - "sha256:8807c87fa893527ae8a524c15fc505d9950d5e856f03dae5921b5e9aa3b8783b", - "sha256:889370d5174a741a62566c003ee8ddba4b04c3f09a97b8000092b7ca83ec9c49", - "sha256:8b14c75979ce932c53b79976a395cb2a8cd3aaf14aef75e8c2cb55a330b9b49d", - "sha256:8c5f80e578427d4695adac6fdf4370c14a2feafdc8cb35549c219b90652536ae", - "sha256:8e9f3fabc445d0ce320ea2c59a75fe3ea591fdbdeebec5db6de530dd4b09412e", - "sha256:93f1aa311e8bb912e34f004cf186407a4e90eec4f0ecc0efd26056bf7eda0226", - "sha256:94504ff66f278ab4b7e03e4cba7e7e400cb73bfa9d3d71f58d8972a8dc67e7a6", - "sha256:967668420f36878a3c9ecb5ab33c9d0ff8d054f9c0233d995a6d25b0e95e1b6b", - "sha256:9880078f683466b7f567b8624bfc16cad65077be046b6e8abb53bed4eeb82dd3", - "sha256:99a6b36f95c98839ad98f8c553d8507644c880cf1e0a57fe5e3a3f3969040882", - "sha256:9a18fff090441a40ffda8a7f4f18f03dc56ae73f148f1832e109f9bffa85df15", - "sha256:9add2e5b33d2cd765ad96d5eb734a5e795a0755f7fc49aa04f76d7ddda73fd70", - "sha256:a793ac733e3d895d96f865f1806f160696422554e46d30105807fdc9841b9f7d", - "sha256:a86c2dd76ef71a773e70551a07318b8e52379f58dafa7ae1e0a4be78efd1ff16", - "sha256:a8c1d566344aee826b74e472e16edae0a02e2a044f14f7c24e123002dcff1c05", - "sha256:ac170e9e048b40c605358667aca3d94e98f604a18c44bdb4c102e67070f3ac9b", - "sha256:b264bf2cc96b5bc43ce0e852be995e400376bd87ceb363822e2cb1964fcdc737", - "sha256:b8c8a419dfb02e91b453615c69568442e897aaf77561ee0064d789705ff37a92", - "sha256:bc69c96735ab501419c432110016329bf0dea8898ce16fab97c6d9106dc0b348", - "sha256:bef02cfcbded83473bdd86dd8d3729cd82b2e569b75844fb4ea08fee3c26ae41", - "sha256:c0b5ca88a8928147b7b1e2dfa09f3b6c256bc1135a1338536cbc9ea13d3b7add", - "sha256:cc69949484171cc961e6ecd4a8911b9ce7a0d1f738fcae717177c231bf77437b", - "sha256:ced111c2e81506abd1dc142e6cd7b68dd53747b3b7ae5edbea4578c5eeff96b7", - "sha256:d1299d7e964c13607efd148ca1f07dcbf27c3ab9e125d1d0ae1d580a1682399d", - "sha256:d1b604734bec94f05f81b360a272fc824334267426ae9905ff32dc2be433ab96", - "sha256:d9a5f194cf730f2b24d6af1f833c14c10f41023da46a7f736f48b6d35061e76e", - "sha256:db36c27baed588a5a8346b971477b718fdc66cf5b80cbfbd914b4d6d355e44e2", - "sha256:df0c7a16ebb94452d2909b9a7b3337940e9a87a824c4fc1c7c36bb4404cb0cde", - "sha256:e10a4b5a4b1192d74853cc71a5e9fd022594573926c2a3a4802020360aa719d8", - "sha256:e624c789359f1a16f83f35e2c705d07663ff2b4d4479bad35621178d8f0f6ea4", - "sha256:e690145a8c0c273c28d3b89d6fb32c45e0d9605b2293c10e650265bf5c11cfec", - "sha256:ea1608dd169da230a0ad602d5b1ebd39807ac96cae1845c3ceed39af08a5c6df", - "sha256:ea253b368eb41116011add00f8d5726762320b1bda892f744c91997b65754d73", - "sha256:eb7e49a17fb8c77d3119d41a4523e432eb0c6932187c37deb6fbb00cc3028088", - "sha256:ef12e259e7bc317c7597d4f6ef59b97b913e162d83b421dd0db3d6410f17a244", - "sha256:f8429b17cbb746c3e043cb986328da023657e79d5ed258b711c06a70c2ea7537", - "sha256:fa99973d2ed20417744fca0073390ad65ce225b546febb0580358e36aa90dba6", - "sha256:faf79a302f834d9e8304fafdc11d0d042266667ac45209afa57e5efc998e3872", - "sha256:fc31baa0c32a2ca660784d5af3b9487e13b61b3032cb01a115fce6588e1bed30" + "sha256:01fbfbeb8249a68d257f601deb50c70c929dc2dfe683b754659569e502fbd3aa", + "sha256:0270b49b6847f0d106d64b5086e9ad5dc8a902413b5dbbb15d12b60f9c1747a4", + "sha256:03c0ae165e700364b266876d712acb1ac02693acd920afa67da2ebb91a0b3c09", + "sha256:068ca17214038ae986d68f4a7021f97e187ed278ab6dccb79f837d765a54d753", + "sha256:082a2988364b60bb5de809373098361cf1dbb239623e39e46cb18bc035ed9c0c", + "sha256:0aaf982e68a7ac284377d051c742610220fd06d330dcd4c4dbb4cdd77c22a537", + "sha256:0c0991f5a96a8e620f7691e61178cd8f457b49e17b7d9cfa2067e2a0a89fc1d5", + "sha256:115f8359402fa527cf47708d6f8a0f8234f0e9ca0cab7c18c9c189c194dbf620", + "sha256:15c59e780be8f30a60816a9adab900c12a58d79c1ac742b4a8df044ab2a6d920", + "sha256:1b7d0e124948daa4d9686d421ef5087c0516bc6179fdcf8828b8444f8e461a77", + "sha256:1c8eb19abe87029c18f226d42b8a2c9efdd139d08f8bf6e085dd9075446db450", + "sha256:204e0f176fd1d067671157d049466869b3ae1fc51e354708b0dc41cf94e23a3a", + "sha256:2136f64fbb86451dbbf70223635a468272dd20075f988a102bf8a3f194a411dc", + "sha256:2b291d1230845871c00c8462c50565a9cd6026fe1228e77ca934470bb7d70ea0", + "sha256:2c18645ef6294d99b256806e34653e86236eb266278c8ec8112622b61db255de", + "sha256:2cc4e280098c1b192c42a849de8de2c8e0f3a84086a76ec5b07bfee29bda7d18", + "sha256:2ed8357f4c6e0daa4f3baf31832df8a33334e0fe5b020a61bc8b345a3db7a606", + "sha256:3191d312c73e3cfd0f0afdf51df8405aafeb0bad71e7ed8f68b24b63c4f36500", + "sha256:3401613148d93ef0fd9aabdbddb212de3db7a4475367f49f590c837355343972", + "sha256:34106f68e20e6ff253c9f596ea50397dbd8699828d55e8fa18bd4323d8d966e6", + "sha256:3516119f4f9b8671083a70b6afaa0a070f5683e431ab3dc26e9215620d7ca1ad", + "sha256:38ece17ec5f20d7d9b442e5174ae9f020365d01ba7c112205a4d59cf19dc38ee", + "sha256:3b4032a96410bdc760061b14ed6a33613ffb7f702181ba999df5d16fb96ba16a", + "sha256:3bf8b000a4e2967e6dfdd8656cd0757d18c7e5ce3d16339e550bd462f4857e59", + "sha256:3e3070e680f79887d60feeda051a58d0ac36622e1759f305a41059eff62c6da7", + "sha256:4496b1282c70c442809fc1b151977c3d967bfb33e4e17cedbf226d97de18f709", + "sha256:44dd6fc3034f1eaa72ece33588867df9e006a7303725a12d64c3dff92330f625", + "sha256:4adfbb5451196842a88fda3612e2c0414134874bffb1c2ce83ab4242ec9e027d", + "sha256:4b7c0c0b3244bb2275abe255d4a30c050d541c6cb18b870975553f1fb6f37527", + "sha256:4c82a6d952a1d555bf4be42b6532927d2a5686dd3c3e280e5f63225ab47ac1f5", + "sha256:5344b896e79800af86ad643408ca9aa303a017f6ebff8cee5a3163c1e9aec987", + "sha256:5bde86a2ed3ce587fa2b207424ce15b9a83a9fa14422dcc1c5356a13aed3df9d", + "sha256:5bf6c237f8c681dfb91b17f8435b2735951f0d1fad10cc5dfd96db110243370b", + "sha256:5dbb9c997932473a27afa93954bb77a9f9b786b4ccf718d903f35da3232317de", + "sha256:69ea9d6d9baa25a4dc9cef5e2b77b8537827b122214f210dd925132e34ae9b12", + "sha256:6b3146f9ae6af82c47a5282ac8803523d381b3b21caeae0327ed2f7ecb718798", + "sha256:6bcb34f869d431799c3ee7d516554797f7760cb2198ecaa89c3f176f72d062be", + "sha256:6ca08b840fe95d1c2bd9ab92dac5685f949fc6f9ae820ec16193e5ddf603c3b2", + "sha256:6ca7a9a06b52d0e38ccf6bca1aeff7be178917893f3883f37b75589d42c4ac20", + "sha256:703c60b9910488d3d0954ca585c34f541e506a091a41930e663a098d3b794c67", + "sha256:715bdf952b9533ba13dfcf1f431a8f49e63cecc31d91d007bc1deb914f47d0e4", + "sha256:72b67f966b57dbd18dcc7efbc1c7fc9f5f983e572db1877081f075004614fcdd", + "sha256:74423631b6be371edfbf7eabb02ab995c2563fee60a80a30829176842e71722a", + "sha256:77a85dca4c2430ac04dc2a2185c2deb3858a34fe7f403d0a946fa56970cf60a1", + "sha256:7821d44fe07335bea256b9f1f41474a642ca55fa671dfd9f00af8d68a920c2d4", + "sha256:788f15721c64109cf720791714dc14afd0f449d63f3a5487724f024345067381", + "sha256:7ca684ee649b55fd8f378127ac8462fb6c85f251c2fb027eb3c887e8ee347bcd", + "sha256:7daa3e1369355766dea11f1d8ef829905c3b9da886ea3152788dc25ee6079e02", + "sha256:7e6bc96ebe49604df3ec2c6389cc3876cabe475e6bfc84ced1bf4e630662cb35", + "sha256:80b12f25d805a919d53efc0a5ad7c0c0326f13b4eae981a5d7b7cc343318ebb7", + "sha256:871587bdadd1075b112e697173e946a07d722459d20716ceb3d1bd6c64bd08ce", + "sha256:88b88282e55fa39dd556d7fc04160bcf39dea015f78e0cecec8ff4f06c1fc2b5", + "sha256:8d7a498671ca87e32b54cb47c82a92b40130a26c5197d392720a1bce1b3c77cf", + "sha256:926838a535c2c1ea21c903f909a9a54e675c2126728c21381a94ddf37c3cbddf", + "sha256:971e8990c5cc4ddcff26e149398fc7b0f6a042306e82500f5e8db3b10ce69f84", + "sha256:9b273ecfbc590a1b98f014ae41e5cf723932f3b53ba9367cfb676f838038b32c", + "sha256:a42db008d58530efa3b881eeee4991146de0b790e095f7ae43ba5cc612decbc5", + "sha256:a72a84570f84c374b4c287183debc776dc319d3e8ce6b6a0041ce2e400de3f32", + "sha256:ac97a21de3712afe6a6c071abfad40a6224fd14fa6ff0ff8d0c6e6cd4e2f807a", + "sha256:acb704195a71ac5ea5ecf2811c9ee19ecdc62b91878528302dd0be1b9451cc90", + "sha256:b32bff85fb02a75ea0b68f21e2412255b5731f3f389ed9aecc13a6752f58ac97", + "sha256:b3cd31f859b662ac5d7f4226ec7d8bd60384fa037fc02aee6ff0b53ba29a3ba8", + "sha256:b63731993cdddcc8e087c64e9cf003f909262b359110070183d7f3025d1c56b5", + "sha256:b6907da3017ef55139cf0e417c5123a84c7332520e73a6902ff1f79046cd3b94", + "sha256:ba6e5e6588e49139a0979d03a7deb9c734bde647b9a8808f26acf9c547cab1bf", + "sha256:c1c8f2a2ca45292084c75bb6d3a25545cff0ed931ed228d3a1810ae3758f975f", + "sha256:ce828058d482ef860746bf532822842e0ff484e27f540ef5c813d516dd8896d2", + "sha256:d0a2d1bd63a4ad79483049b26514e70fa618ce6115220da9efdff63688808b17", + "sha256:d0cdde3c78d8ab5b46595054e5def32a755fc028685add5ddc7403e9f6de9879", + "sha256:d57dfbf9737763b3a60d26e6800e02e04284926329aee8fb01049635e957fe81", + "sha256:d8416c23161abd94cc7da80c734ad7c9f5dbebdadfdaa77dad78244457448223", + "sha256:dba7d9f2e047dfa2bca3b01f4f84aa5246725203d6284e3790f2ca15fba6b40a", + "sha256:dbf012d8fcb9f2cf0643b65df3b355fdd74fc0035d70bb5c845e9e30a3a4654b", + "sha256:e1258c639e00bf5e8a522fec6c3eaa3e30cf1c23a2f21a586be7e04d50c9acab", + "sha256:e222562dc0f38571c8b1ffdae9d7adb866363134299264a1958d077800b193b7", + "sha256:e4946d6bdb7ba972dfda282f9127e5756d4f299028b1566d1245fa0d438847e6", + "sha256:e746524418b70f38550f2190eeee834db8850088c834d4c8406fbb9bc1ae10b2", + "sha256:e76654e9dbfb835b3518f9938e565c7806976c07b37c33526b574cc1a1050480", + "sha256:e8918973fbd34e7814f59143c5f600ecd38b8038161239fd1a3d33d5817a38b8", + "sha256:e891ce81edd463b3b4c3b885c5603c00141151dd9c6936d98a680c8c72fe5c67", + "sha256:ebbbd0e728af5db9b04e56389e2299a57ea8b9dd15c9759153ee2455b32be6ad", + "sha256:eeb438a26d87c123bb318e5f2b3d86a36060b01f22fbdffd8cf247d52f7c9a2b", + "sha256:eed56b6a39216d31ff8cd2f1d048b5bf1700e4b32a01b14379c3b6dde9ce3aa3", + "sha256:f17cde1db0754c35a91ac00b22b25c11da6eec5746431d6e5092f0cd31a3fea9", + "sha256:f1a9b7d00fdf60b4039f4455afd031fe85ee8305b019334b72dcf73c567edc47", + "sha256:f4b6cecbbf3b7380f3b61de3a7b93cb721125dc125c854c14ddc91225ba52f83", + "sha256:f6b1d1c631e5940cac5a0b22c5379c86e8df6a4ec277c7a856b714021ab6cfad", + "sha256:f6c21c00478a7bea93caaaef9e7629145d4153b15a8653e8bb4609d4bc70dbfc" ], - "markers": "python_version >= '3.6'", - "version": "==25.1.2" + "markers": "python_version >= '3.7'", + "version": "==26.0.3" }, "referencing": { "hashes": [ - "sha256:689e64fe121843dcfd57b71933318ef1f91188ffb45367332700a86ac8fd6161", - "sha256:bdcd3efb936f82ff86f993093f6da7435c7de69a3b3a5a06678a6050184bee99" + "sha256:25b42124a6c8b632a425174f24087783efb348a6f1e0008e63cd4466fedf703c", + "sha256:eda6d3234d62814d1c64e305c1331c9a3a6132da475ab6382eaa997b21ee75de" ], "markers": "python_version >= '3.8'", - "version": "==0.32.0" + "version": "==0.35.1" }, "requests": { "hashes": [ @@ -1372,116 +1534,116 @@ }, "rpds-py": { "hashes": [ - "sha256:06d218e4464d31301e943b65b2c6919318ea6f69703a351961e1baaf60347276", - "sha256:12ecf89bd54734c3c2c79898ae2021dca42750c7bcfb67f8fb3315453738ac8f", - "sha256:15253fff410873ebf3cfba1cc686a37711efcd9b8cb30ea21bb14a973e393f60", - "sha256:188435794405c7f0573311747c85a96b63c954a5f2111b1df8018979eca0f2f0", - "sha256:1ceebd0ae4f3e9b2b6b553b51971921853ae4eebf3f54086be0565d59291e53d", - "sha256:244e173bb6d8f3b2f0c4d7370a1aa341f35da3e57ffd1798e5b2917b91731fd3", - "sha256:25b28b3d33ec0a78e944aaaed7e5e2a94ac811bcd68b557ca48a0c30f87497d2", - "sha256:25ea41635d22b2eb6326f58e608550e55d01df51b8a580ea7e75396bafbb28e9", - "sha256:29d311e44dd16d2434d5506d57ef4d7036544fc3c25c14b6992ef41f541b10fb", - "sha256:2a1472956c5bcc49fb0252b965239bffe801acc9394f8b7c1014ae9258e4572b", - "sha256:2a7bef6977043673750a88da064fd513f89505111014b4e00fbdd13329cd4e9a", - "sha256:2ac26f50736324beb0282c819668328d53fc38543fa61eeea2c32ea8ea6eab8d", - "sha256:2e72f750048b32d39e87fc85c225c50b2a6715034848dbb196bf3348aa761fa1", - "sha256:31e220a040b89a01505128c2f8a59ee74732f666439a03e65ccbf3824cdddae7", - "sha256:35f53c76a712e323c779ca39b9a81b13f219a8e3bc15f106ed1e1462d56fcfe9", - "sha256:38d4f822ee2f338febcc85aaa2547eb5ba31ba6ff68d10b8ec988929d23bb6b4", - "sha256:38f9bf2ad754b4a45b8210a6c732fe876b8a14e14d5992a8c4b7c1ef78740f53", - "sha256:3a44c8440183b43167fd1a0819e8356692bf5db1ad14ce140dbd40a1485f2dea", - "sha256:3ab96754d23372009638a402a1ed12a27711598dd49d8316a22597141962fe66", - "sha256:3c55d7f2d817183d43220738270efd3ce4e7a7b7cbdaefa6d551ed3d6ed89190", - "sha256:46e1ed994a0920f350a4547a38471217eb86f57377e9314fbaaa329b71b7dfe3", - "sha256:4a5375c5fff13f209527cd886dc75394f040c7d1ecad0a2cb0627f13ebe78a12", - "sha256:4c2d26aa03d877c9730bf005621c92da263523a1e99247590abbbe252ccb7824", - "sha256:4c4e314d36d4f31236a545696a480aa04ea170a0b021e9a59ab1ed94d4c3ef27", - "sha256:4d0c10d803549427f427085ed7aebc39832f6e818a011dcd8785e9c6a1ba9b3e", - "sha256:4dcc5ee1d0275cb78d443fdebd0241e58772a354a6d518b1d7af1580bbd2c4e8", - "sha256:51967a67ea0d7b9b5cd86036878e2d82c0b6183616961c26d825b8c994d4f2c8", - "sha256:530190eb0cd778363bbb7596612ded0bb9fef662daa98e9d92a0419ab27ae914", - "sha256:5379e49d7e80dca9811b36894493d1c1ecb4c57de05c36f5d0dd09982af20211", - "sha256:5493569f861fb7b05af6d048d00d773c6162415ae521b7010197c98810a14cab", - "sha256:5a4c1058cdae6237d97af272b326e5f78ee7ee3bbffa6b24b09db4d828810468", - "sha256:5d75d6d220d55cdced2f32cc22f599475dbe881229aeddba6c79c2e9df35a2b3", - "sha256:5d97e9ae94fb96df1ee3cb09ca376c34e8a122f36927230f4c8a97f469994bff", - "sha256:5feae2f9aa7270e2c071f488fab256d768e88e01b958f123a690f1cc3061a09c", - "sha256:603d5868f7419081d616dab7ac3cfa285296735e7350f7b1e4f548f6f953ee7d", - "sha256:61d42d2b08430854485135504f672c14d4fc644dd243a9c17e7c4e0faf5ed07e", - "sha256:61dbc1e01dc0c5875da2f7ae36d6e918dc1b8d2ce04e871793976594aad8a57a", - "sha256:65cfed9c807c27dee76407e8bb29e6f4e391e436774bcc769a037ff25ad8646e", - "sha256:67a429520e97621a763cf9b3ba27574779c4e96e49a27ff8a1aa99ee70beb28a", - "sha256:6aadae3042f8e6db3376d9e91f194c606c9a45273c170621d46128f35aef7cd0", - "sha256:6ba8858933f0c1a979781272a5f65646fca8c18c93c99c6ddb5513ad96fa54b1", - "sha256:6bc568b05e02cd612be53900c88aaa55012e744930ba2eeb56279db4c6676eb3", - "sha256:729408136ef8d45a28ee9a7411917c9e3459cf266c7e23c2f7d4bb8ef9e0da42", - "sha256:751758d9dd04d548ec679224cc00e3591f5ebf1ff159ed0d4aba6a0746352452", - "sha256:76d59d4d451ba77f08cb4cd9268dec07be5bc65f73666302dbb5061989b17198", - "sha256:79bf58c08f0756adba691d480b5a20e4ad23f33e1ae121584cf3a21717c36dfa", - "sha256:7de12b69d95072394998c622cfd7e8cea8f560db5fca6a62a148f902a1029f8b", - "sha256:7f55cd9cf1564b7b03f238e4c017ca4794c05b01a783e9291065cb2858d86ce4", - "sha256:80e5acb81cb49fd9f2d5c08f8b74ffff14ee73b10ca88297ab4619e946bcb1e1", - "sha256:87a90f5545fd61f6964e65eebde4dc3fa8660bb7d87adb01d4cf17e0a2b484ad", - "sha256:881df98f0a8404d32b6de0fd33e91c1b90ed1516a80d4d6dc69d414b8850474c", - "sha256:8a776a29b77fe0cc28fedfd87277b0d0f7aa930174b7e504d764e0b43a05f381", - "sha256:8c2a61c0e4811012b0ba9f6cdcb4437865df5d29eab5d6018ba13cee1c3064a0", - "sha256:8fa6bd071ec6d90f6e7baa66ae25820d57a8ab1b0a3c6d3edf1834d4b26fafa2", - "sha256:96f2975fb14f39c5fe75203f33dd3010fe37d1c4e33177feef1107b5ced750e3", - "sha256:96fb0899bb2ab353f42e5374c8f0789f54e0a94ef2f02b9ac7149c56622eaf31", - "sha256:97163a1ab265a1073a6372eca9f4eeb9f8c6327457a0b22ddfc4a17dcd613e74", - "sha256:9c95a1a290f9acf7a8f2ebbdd183e99215d491beea52d61aa2a7a7d2c618ddc6", - "sha256:9d94d78418203904730585efa71002286ac4c8ac0689d0eb61e3c465f9e608ff", - "sha256:a6ba2cb7d676e9415b9e9ac7e2aae401dc1b1e666943d1f7bc66223d3d73467b", - "sha256:aa0379c1935c44053c98826bc99ac95f3a5355675a297ac9ce0dfad0ce2d50ca", - "sha256:ac96d67b37f28e4b6ecf507c3405f52a40658c0a806dffde624a8fcb0314d5fd", - "sha256:ade2ccb937060c299ab0dfb2dea3d2ddf7e098ed63ee3d651ebfc2c8d1e8632a", - "sha256:aefbdc934115d2f9278f153952003ac52cd2650e7313750390b334518c589568", - "sha256:b07501b720cf060c5856f7b5626e75b8e353b5f98b9b354a21eb4bfa47e421b1", - "sha256:b5267feb19070bef34b8dea27e2b504ebd9d31748e3ecacb3a4101da6fcb255c", - "sha256:b5f6328e8e2ae8238fc767703ab7b95785521c42bb2b8790984e3477d7fa71ad", - "sha256:b8996ffb60c69f677245f5abdbcc623e9442bcc91ed81b6cd6187129ad1fa3e7", - "sha256:b981a370f8f41c4024c170b42fbe9e691ae2dbc19d1d99151a69e2c84a0d194d", - "sha256:b9d121be0217787a7d59a5c6195b0842d3f701007333426e5154bf72346aa658", - "sha256:bcef4f2d3dc603150421de85c916da19471f24d838c3c62a4f04c1eb511642c1", - "sha256:bed0252c85e21cf73d2d033643c945b460d6a02fc4a7d644e3b2d6f5f2956c64", - "sha256:bfdfbe6a36bc3059fff845d64c42f2644cf875c65f5005db54f90cdfdf1df815", - "sha256:c0095b8aa3e432e32d372e9a7737e65b58d5ed23b9620fea7cb81f17672f1fa1", - "sha256:c1f41d32a2ddc5a94df4b829b395916a4b7f103350fa76ba6de625fcb9e773ac", - "sha256:c45008ca79bad237cbc03c72bc5205e8c6f66403773929b1b50f7d84ef9e4d07", - "sha256:c82bbf7e03748417c3a88c1b0b291288ce3e4887a795a3addaa7a1cfd9e7153e", - "sha256:c918621ee0a3d1fe61c313f2489464f2ae3d13633e60f520a8002a5e910982ee", - "sha256:d204957169f0b3511fb95395a9da7d4490fb361763a9f8b32b345a7fe119cb45", - "sha256:d329896c40d9e1e5c7715c98529e4a188a1f2df51212fd65102b32465612b5dc", - "sha256:d3a61e928feddc458a55110f42f626a2a20bea942ccedb6fb4cee70b4830ed41", - "sha256:d48db29bd47814671afdd76c7652aefacc25cf96aad6daefa82d738ee87461e2", - "sha256:d5593855b5b2b73dd8413c3fdfa5d95b99d657658f947ba2c4318591e745d083", - "sha256:d79c159adea0f1f4617f54aa156568ac69968f9ef4d1e5fefffc0a180830308e", - "sha256:db09b98c7540df69d4b47218da3fbd7cb466db0fb932e971c321f1c76f155266", - "sha256:ddf23960cb42b69bce13045d5bc66f18c7d53774c66c13f24cf1b9c144ba3141", - "sha256:e06cfea0ece444571d24c18ed465bc93afb8c8d8d74422eb7026662f3d3f779b", - "sha256:e7c564c58cf8f248fe859a4f0fe501b050663f3d7fbc342172f259124fb59933", - "sha256:e86593bf8637659e6a6ed58854b6c87ec4e9e45ee8a4adfd936831cef55c2d21", - "sha256:eaffbd8814bb1b5dc3ea156a4c5928081ba50419f9175f4fc95269e040eff8f0", - "sha256:ee353bb51f648924926ed05e0122b6a0b1ae709396a80eb583449d5d477fcdf7", - "sha256:ee6faebb265e28920a6f23a7d4c362414b3f4bb30607141d718b991669e49ddc", - "sha256:efe093acc43e869348f6f2224df7f452eab63a2c60a6c6cd6b50fd35c4e075ba", - "sha256:f03a1b3a4c03e3e0161642ac5367f08479ab29972ea0ffcd4fa18f729cd2be0a", - "sha256:f0d320e70b6b2300ff6029e234e79fe44e9dbbfc7b98597ba28e054bd6606a57", - "sha256:f252dfb4852a527987a9156cbcae3022a30f86c9d26f4f17b8c967d7580d65d2", - "sha256:f5f4424cb87a20b016bfdc157ff48757b89d2cc426256961643d443c6c277007", - "sha256:f8eae66a1304de7368932b42d801c67969fd090ddb1a7a24f27b435ed4bed68f", - "sha256:fdb82eb60d31b0c033a8e8ee9f3fc7dfbaa042211131c29da29aea8531b4f18f" + "sha256:05f3d615099bd9b13ecf2fc9cf2d839ad3f20239c678f461c753e93755d629ee", + "sha256:06d218939e1bf2ca50e6b0ec700ffe755e5216a8230ab3e87c059ebb4ea06afc", + "sha256:07f2139741e5deb2c5154a7b9629bc5aa48c766b643c1a6750d16f865a82c5fc", + "sha256:08d74b184f9ab6289b87b19fe6a6d1a97fbfea84b8a3e745e87a5de3029bf944", + "sha256:0abeee75434e2ee2d142d650d1e54ac1f8b01e6e6abdde8ffd6eeac6e9c38e20", + "sha256:154bf5c93d79558b44e5b50cc354aa0459e518e83677791e6adb0b039b7aa6a7", + "sha256:17c6d2155e2423f7e79e3bb18151c686d40db42d8645e7977442170c360194d4", + "sha256:1805d5901779662d599d0e2e4159d8a82c0b05faa86ef9222bf974572286b2b6", + "sha256:19ba472b9606c36716062c023afa2484d1e4220548751bda14f725a7de17b4f6", + "sha256:19e515b78c3fc1039dd7da0a33c28c3154458f947f4dc198d3c72db2b6b5dc93", + "sha256:1d54f74f40b1f7aaa595a02ff42ef38ca654b1469bef7d52867da474243cc633", + "sha256:207c82978115baa1fd8d706d720b4a4d2b0913df1c78c85ba73fe6c5804505f0", + "sha256:2625f03b105328729f9450c8badda34d5243231eef6535f80064d57035738360", + "sha256:27bba383e8c5231cd559affe169ca0b96ec78d39909ffd817f28b166d7ddd4d8", + "sha256:2c3caec4ec5cd1d18e5dd6ae5194d24ed12785212a90b37f5f7f06b8bedd7139", + "sha256:2cc7c1a47f3a63282ab0f422d90ddac4aa3034e39fc66a559ab93041e6505da7", + "sha256:2fc24a329a717f9e2448f8cd1f960f9dac4e45b6224d60734edeb67499bab03a", + "sha256:312fe69b4fe1ffbe76520a7676b1e5ac06ddf7826d764cc10265c3b53f96dbe9", + "sha256:32b7daaa3e9389db3695964ce8e566e3413b0c43e3394c05e4b243a4cd7bef26", + "sha256:338dee44b0cef8b70fd2ef54b4e09bb1b97fc6c3a58fea5db6cc083fd9fc2724", + "sha256:352a88dc7892f1da66b6027af06a2e7e5d53fe05924cc2cfc56495b586a10b72", + "sha256:35b2b771b13eee8729a5049c976197ff58a27a3829c018a04341bcf1ae409b2b", + "sha256:38e14fb4e370885c4ecd734f093a2225ee52dc384b86fa55fe3f74638b2cfb09", + "sha256:3c20f05e8e3d4fc76875fc9cb8cf24b90a63f5a1b4c5b9273f0e8225e169b100", + "sha256:3dd3cd86e1db5aadd334e011eba4e29d37a104b403e8ca24dcd6703c68ca55b3", + "sha256:489bdfe1abd0406eba6b3bb4fdc87c7fa40f1031de073d0cfb744634cc8fa261", + "sha256:48c2faaa8adfacefcbfdb5f2e2e7bdad081e5ace8d182e5f4ade971f128e6bb3", + "sha256:4a98a1f0552b5f227a3d6422dbd61bc6f30db170939bd87ed14f3c339aa6c7c9", + "sha256:4adec039b8e2928983f885c53b7cc4cda8965b62b6596501a0308d2703f8af1b", + "sha256:4e0ee01ad8260184db21468a6e1c37afa0529acc12c3a697ee498d3c2c4dcaf3", + "sha256:51584acc5916212e1bf45edd17f3a6b05fe0cbb40482d25e619f824dccb679de", + "sha256:531796fb842b53f2695e94dc338929e9f9dbf473b64710c28af5a160b2a8927d", + "sha256:5463c47c08630007dc0fe99fb480ea4f34a89712410592380425a9b4e1611d8e", + "sha256:5c45a639e93a0c5d4b788b2613bd637468edd62f8f95ebc6fcc303d58ab3f0a8", + "sha256:6031b25fb1b06327b43d841f33842b383beba399884f8228a6bb3df3088485ff", + "sha256:607345bd5912aacc0c5a63d45a1f73fef29e697884f7e861094e443187c02be5", + "sha256:618916f5535784960f3ecf8111581f4ad31d347c3de66d02e728de460a46303c", + "sha256:636a15acc588f70fda1661234761f9ed9ad79ebed3f2125d44be0862708b666e", + "sha256:673fdbbf668dd958eff750e500495ef3f611e2ecc209464f661bc82e9838991e", + "sha256:6afd80f6c79893cfc0574956f78a0add8c76e3696f2d6a15bca2c66c415cf2d4", + "sha256:6b5ff7e1d63a8281654b5e2896d7f08799378e594f09cf3674e832ecaf396ce8", + "sha256:6c4c4c3f878df21faf5fac86eda32671c27889e13570645a9eea0a1abdd50922", + "sha256:6cd8098517c64a85e790657e7b1e509b9fe07487fd358e19431cb120f7d96338", + "sha256:6d1e42d2735d437e7e80bab4d78eb2e459af48c0a46e686ea35f690b93db792d", + "sha256:6e30ac5e329098903262dc5bdd7e2086e0256aa762cc8b744f9e7bf2a427d3f8", + "sha256:70a838f7754483bcdc830444952fd89645569e7452e3226de4a613a4c1793fb2", + "sha256:720edcb916df872d80f80a1cc5ea9058300b97721efda8651efcd938a9c70a72", + "sha256:732672fbc449bab754e0b15356c077cc31566df874964d4801ab14f71951ea80", + "sha256:740884bc62a5e2bbb31e584f5d23b32320fd75d79f916f15a788d527a5e83644", + "sha256:7700936ef9d006b7ef605dc53aa364da2de5a3aa65516a1f3ce73bf82ecfc7ae", + "sha256:7732770412bab81c5a9f6d20aeb60ae943a9b36dcd990d876a773526468e7163", + "sha256:7750569d9526199c5b97e5a9f8d96a13300950d910cf04a861d96f4273d5b104", + "sha256:7f1944ce16401aad1e3f7d312247b3d5de7981f634dc9dfe90da72b87d37887d", + "sha256:81c5196a790032e0fc2464c0b4ab95f8610f96f1f2fa3d4deacce6a79852da60", + "sha256:8352f48d511de5f973e4f2f9412736d7dea76c69faa6d36bcf885b50c758ab9a", + "sha256:8927638a4d4137a289e41d0fd631551e89fa346d6dbcfc31ad627557d03ceb6d", + "sha256:8c7672e9fba7425f79019db9945b16e308ed8bc89348c23d955c8c0540da0a07", + "sha256:8d2e182c9ee01135e11e9676e9a62dfad791a7a467738f06726872374a83db49", + "sha256:910e71711d1055b2768181efa0a17537b2622afeb0424116619817007f8a2b10", + "sha256:942695a206a58d2575033ff1e42b12b2aece98d6003c6bc739fbf33d1773b12f", + "sha256:9437ca26784120a279f3137ee080b0e717012c42921eb07861b412340f85bae2", + "sha256:967342e045564cef76dfcf1edb700b1e20838d83b1aa02ab313e6a497cf923b8", + "sha256:998125738de0158f088aef3cb264a34251908dd2e5d9966774fdab7402edfab7", + "sha256:9e6934d70dc50f9f8ea47081ceafdec09245fd9f6032669c3b45705dea096b88", + "sha256:a3d456ff2a6a4d2adcdf3c1c960a36f4fd2fec6e3b4902a42a384d17cf4e7a65", + "sha256:a7b28c5b066bca9a4eb4e2f2663012debe680f097979d880657f00e1c30875a0", + "sha256:a888e8bdb45916234b99da2d859566f1e8a1d2275a801bb8e4a9644e3c7e7909", + "sha256:aa3679e751408d75a0b4d8d26d6647b6d9326f5e35c00a7ccd82b78ef64f65f8", + "sha256:aaa71ee43a703c321906813bb252f69524f02aa05bf4eec85f0c41d5d62d0f4c", + "sha256:b646bf655b135ccf4522ed43d6902af37d3f5dbcf0da66c769a2b3938b9d8184", + "sha256:b906b5f58892813e5ba5c6056d6a5ad08f358ba49f046d910ad992196ea61397", + "sha256:b9bb1f182a97880f6078283b3505a707057c42bf55d8fca604f70dedfdc0772a", + "sha256:bd1105b50ede37461c1d51b9698c4f4be6e13e69a908ab7751e3807985fc0346", + "sha256:bf18932d0003c8c4d51a39f244231986ab23ee057d235a12b2684ea26a353590", + "sha256:c273e795e7a0f1fddd46e1e3cb8be15634c29ae8ff31c196debb620e1edb9333", + "sha256:c69882964516dc143083d3795cb508e806b09fc3800fd0d4cddc1df6c36e76bb", + "sha256:c827576e2fa017a081346dce87d532a5310241648eb3700af9a571a6e9fc7e74", + "sha256:cbfbea39ba64f5e53ae2915de36f130588bba71245b418060ec3330ebf85678e", + "sha256:ce0bb20e3a11bd04461324a6a798af34d503f8d6f1aa3d2aa8901ceaf039176d", + "sha256:d0cee71bc618cd93716f3c1bf56653740d2d13ddbd47673efa8bf41435a60daa", + "sha256:d21be4770ff4e08698e1e8e0bce06edb6ea0626e7c8f560bc08222880aca6a6f", + "sha256:d31dea506d718693b6b2cffc0648a8929bdc51c70a311b2770f09611caa10d53", + "sha256:d44607f98caa2961bab4fa3c4309724b185b464cdc3ba6f3d7340bac3ec97cc1", + "sha256:d58ad6317d188c43750cb76e9deacf6051d0f884d87dc6518e0280438648a9ac", + "sha256:d70129cef4a8d979caa37e7fe957202e7eee8ea02c5e16455bc9808a59c6b2f0", + "sha256:d85164315bd68c0806768dc6bb0429c6f95c354f87485ee3593c4f6b14def2bd", + "sha256:d960de62227635d2e61068f42a6cb6aae91a7fe00fca0e3aeed17667c8a34611", + "sha256:dc48b479d540770c811fbd1eb9ba2bb66951863e448efec2e2c102625328e92f", + "sha256:e1735502458621921cee039c47318cb90b51d532c2766593be6207eec53e5c4c", + "sha256:e2be6e9dd4111d5b31ba3b74d17da54a8319d8168890fbaea4b9e5c3de630ae5", + "sha256:e4c39ad2f512b4041343ea3c7894339e4ca7839ac38ca83d68a832fc8b3748ab", + "sha256:ed402d6153c5d519a0faf1bb69898e97fb31613b49da27a84a13935ea9164dfc", + "sha256:ee17cd26b97d537af8f33635ef38be873073d516fd425e80559f4585a7b90c43", + "sha256:f3027be483868c99b4985fda802a57a67fdf30c5d9a50338d9db646d590198da", + "sha256:f5bab211605d91db0e2995a17b5c6ee5edec1270e46223e513eaa20da20076ac", + "sha256:f6f8e3fecca256fefc91bb6765a693d96692459d7d4c644660a9fff32e517843", + "sha256:f7afbfee1157e0f9376c00bb232e80a60e59ed716e3211a80cb8506550671e6e", + "sha256:fa242ac1ff583e4ec7771141606aafc92b361cd90a05c30d93e343a0c2d82a89", + "sha256:fab6ce90574645a0d6c58890e9bcaac8d94dff54fb51c69e5522a7358b80ab64" ], "markers": "python_version >= '3.8'", - "version": "==0.13.2" + "version": "==0.18.1" }, "setuptools": { "hashes": [ - "sha256:1e8fdff6797d3865f37397be788a4e3cba233608e9b509382a2777d25ebde7f2", - "sha256:735896e78a4742605974de002ac60562d286fa8051a7e2299445e8e8fbb01aa6" + "sha256:6c1fccdac05a97e598fb0ae3bbed5904ccb317337a51139dcd51453611bbb987", + "sha256:c636ac361bc47580504644275c9ad802c50415c7522212252c033bd15f301f32" ], "markers": "python_version >= '3.8'", - "version": "==69.0.2" + "version": "==69.5.1" }, "six": { "hashes": [ @@ -1507,18 +1669,18 @@ }, "sphinx": { "hashes": [ - "sha256:1e09160a40b956dc623c910118fa636da93bd3ca0b9876a7b3df90f07d691560", - "sha256:9a5160e1ea90688d5963ba09a2dcd8bdd526620edbb65c328728f1b2228d5ab5" + "sha256:413f75440be4cacf328f580b4274ada4565fb2187d696a84970c23f77b64d8c3", + "sha256:a4a7db75ed37531c05002d56ed6948d4c42f473a36f46e1382b0bd76ca9627bc" ], "markers": "python_version >= '3.9'", - "version": "==7.2.6" + "version": "==7.3.7" }, "sphinx-autodoc-typehints": { "hashes": [ - "sha256:3cabc2537e17989b2f92e64a399425c4c8bf561ed73f087bc7414a5003616a50", - "sha256:5ed05017d23ad4b937eab3bee9fae9ab0dd63f0b42aa360031f1fad47e47f673" + "sha256:70db10b391acf4e772019765991d2de0ff30ec0899b9ba137706dc0b3c4835e0", + "sha256:d3da7fa9a9761eff6ff09f8b1956ae3090a2d4f4ad54aebcade8e458d6340835" ], - "version": "==1.25.2" + "version": "==1.25.3" }, "sphinx-rtd-theme": { "hashes": [ @@ -1529,27 +1691,27 @@ }, "sphinxcontrib-applehelp": { "hashes": [ - "sha256:094c4d56209d1734e7d252f6e0b3ccc090bd52ee56807a5d9315b19c122ab15d", - "sha256:39fdc8d762d33b01a7d8f026a3b7d71563ea3b72787d5f00ad8465bd9d6dfbfa" + "sha256:c40a4f96f3776c4393d933412053962fac2b84f4c99a7982ba42e09576a70619", + "sha256:cb61eb0ec1b61f349e5cc36b2028e9e7ca765be05e49641c97241274753067b4" ], "markers": "python_version >= '3.9'", - "version": "==1.0.7" + "version": "==1.0.8" }, "sphinxcontrib-devhelp": { "hashes": [ - "sha256:63b41e0d38207ca40ebbeabcf4d8e51f76c03e78cd61abe118cf4435c73d4212", - "sha256:fe8009aed765188f08fcaadbb3ea0d90ce8ae2d76710b7e29ea7d047177dae2f" + "sha256:6485d09629944511c893fa11355bda18b742b83a2b181f9a009f7e500595c90f", + "sha256:9893fd3f90506bc4b97bdb977ceb8fbd823989f4316b28c3841ec128544372d3" ], "markers": "python_version >= '3.9'", - "version": "==1.0.5" + "version": "==1.0.6" }, "sphinxcontrib-htmlhelp": { "hashes": [ - "sha256:6c26a118a05b76000738429b724a0568dbde5b72391a688577da08f11891092a", - "sha256:8001661c077a73c29beaf4a79968d0726103c5605e27db92b9ebed8bab1359e9" + "sha256:0dc87637d5de53dd5eec3a6a01753b1ccf99494bd756aafecd74b4fa9e729015", + "sha256:393f04f112b4d2f53d93448d4bce35842f62b307ccdc549ec1585e950bc35e04" ], "markers": "python_version >= '3.9'", - "version": "==2.0.4" + "version": "==2.0.5" }, "sphinxcontrib-jquery": { "hashes": [ @@ -1569,19 +1731,19 @@ }, "sphinxcontrib-qthelp": { "hashes": [ - "sha256:62b9d1a186ab7f5ee3356d906f648cacb7a6bdb94d201ee7adf26db55092982d", - "sha256:bf76886ee7470b934e363da7a954ea2825650013d367728588732c7350f49ea4" + "sha256:053dedc38823a80a7209a80860b16b722e9e0209e32fea98c90e4e6624588ed6", + "sha256:e2ae3b5c492d58fcbd73281fbd27e34b8393ec34a073c792642cd8e529288182" ], "markers": "python_version >= '3.9'", - "version": "==1.0.6" + "version": "==1.0.7" }, "sphinxcontrib-serializinghtml": { "hashes": [ - "sha256:0c64ff898339e1fac29abd2bf5f11078f3ec413cfe9c046d3120d7ca65530b54", - "sha256:9b36e503703ff04f20e9675771df105e58aa029cfcbc23b8ed716019b7416ae1" + "sha256:326369b8df80a7d2d8d7f99aa5ac577f51ea51556ed974e7716cfd4fca3f6cb7", + "sha256:93f3f5dc458b91b192fe10c397e324f262cf163d79f3282c158e8436a2c4511f" ], "markers": "python_version >= '3.9'", - "version": "==1.1.9" + "version": "==1.1.10" }, "stack-data": { "hashes": [ @@ -1592,11 +1754,11 @@ }, "synapseclient": { "hashes": [ - "sha256:dc5a61f9f495109a0c89aa7d42b641b6ff278280d7961fb450dd5015704fe15b", - "sha256:dd8b1a1b4667d08311bb651469431f43fe2eeab83c0ef1fe5a03c2929aeb26cd" + "sha256:5261a2751ea5757750e0cb2e481ecb2761954e2c0969e7cc5dd1dfff43c3ddcc", + "sha256:c5e0ac45faed1aa618cd66a0f50bf1a8149a2902a71d07487a0e470250955083" ], - "markers": "python_version >= '3.7'", - "version": "==2.7.2" + "markers": "python_version >= '3.8'", + "version": "==4.1.1" }, "tabulate": { "hashes": [ @@ -1606,14 +1768,6 @@ "markers": "python_version >= '3.7'", "version": "==0.9.0" }, - "toml": { - "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2'", - "version": "==0.10.2" - }, "tornado": { "hashes": [ "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0", @@ -1633,11 +1787,11 @@ }, "traitlets": { "hashes": [ - "sha256:f14949d23829023013c47df20b4a76ccd1a85effb786dc060f34de7948361b33", - "sha256:fcdaa8ac49c04dfa0ed3ee3384ef6dfdb5d6f3741502be247279407679296772" + "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", + "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f" ], "markers": "python_version >= '3.8'", - "version": "==5.14.0" + "version": "==5.14.3" }, "typer": { "hashes": [ @@ -1649,11 +1803,11 @@ }, "typing-extensions": { "hashes": [ - "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783", - "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd" + "sha256:83f085bd5ca59c80295fc2a82ab5dac679cbe02b9f33f7d83af68e241bea51b0", + "sha256:c1f94d72897edaf4ce775bb7558d5b79d8126906a14ea5ed1635921406c0387a" ], "markers": "python_version >= '3.8'", - "version": "==4.9.0" + "version": "==4.11.0" }, "urllib3": { "hashes": [ @@ -1665,26 +1819,26 @@ }, "virtualenv": { "hashes": [ - "sha256:4238949c5ffe6876362d9c0180fc6c3a824a7b12b80604eeb8085f2ed7460de3", - "sha256:bf51c0d9c7dd63ea8e44086fa1e4fb1093a31e963b86959257378aef020e1f1b" + "sha256:604bfdceaeece392802e6ae48e69cec49168b9c5f4a44e483963f9242eb0e78b", + "sha256:7aa9982a728ae5892558bff6a2839c00b9ed145523ece2274fad6f414690ae75" ], "markers": "python_version >= '3.7'", - "version": "==20.25.0" + "version": "==20.26.1" }, "wcwidth": { "hashes": [ - "sha256:f01c104efdf57971bcb756f054dd58ddec5204dd15fa31d6503ea57947d97c02", - "sha256:f26ec43d96c8cbfed76a5075dac87680124fa84e0855195a6184da9c187f133c" + "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", + "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5" ], - "version": "==0.2.12" + "version": "==0.2.13" }, "websocket-client": { "hashes": [ - "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6", - "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588" + "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", + "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da" ], "markers": "python_version >= '3.8'", - "version": "==1.7.0" + "version": "==1.8.0" }, "wrapt": { "hashes": [ @@ -1764,11 +1918,11 @@ }, "zipp": { "hashes": [ - "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31", - "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0" + "sha256:206f5a15f2af3dbaee80769fb7dc6f249695e940acca08dfb2a4769fe61e538b", + "sha256:2884ed22e7d8961de1c9a05142eb69a247f120291bc0206a00a7642f09b5b715" ], "markers": "python_version >= '3.8'", - "version": "==3.17.0" + "version": "==3.18.1" } } } diff --git a/setup.cfg b/setup.cfg index 1218dfa..73d9001 100644 --- a/setup.cfg +++ b/setup.cfg @@ -51,7 +51,7 @@ python_requires = >=3.9, <3.12 # Updates here should be reflected in `docs/requirements.txt` install_requires = fs~=2.4 - fs-synapse~=1.0 + fs-synapse~=2.0 typer~=0.7.0 [options.packages.find] diff --git a/src/dcqc/main.py b/src/dcqc/main.py index 72583a8..0065825 100644 --- a/src/dcqc/main.py +++ b/src/dcqc/main.py @@ -166,7 +166,7 @@ def list_tests(): "file_type": file_type_name, "edam_iri": file_type.edam_iri, "test_name": test_cls.__name__, - "test_tier": test_cls.tier, + "test_tier": test_cls.tier.value, "test_type": "external" if test_cls.is_external_test else "internal", } rows.append(test_dict) diff --git a/src/dcqc/suites/suite_abc.py b/src/dcqc/suites/suite_abc.py index 36a715d..0954237 100644 --- a/src/dcqc/suites/suite_abc.py +++ b/src/dcqc/suites/suite_abc.py @@ -15,11 +15,13 @@ class SuiteStatus(Enum): + """Status of a suite.""" + NONE = "NONE" # status not yet evaluated GREEN = "GREEN" # all tests passed RED = "RED" # one or more required tests failed AMBER = "AMBER" # all required tests passed, but one or more optional tests failed - # TODO GREY = "GREY" # error occurred + GREY = "GREY" # error occurred # TODO: Consider the Composite design pattern once @@ -172,7 +174,7 @@ def list_test_classes_by_file_type(cls) -> dict[str, list[Type[BaseTest]]]: @classmethod def _default_required_tests(cls) -> list[str]: test_classes = cls.list_test_classes() - required_tests = filter(lambda test: test.tier <= 2, test_classes) + required_tests = filter(lambda test: test.tier.value <= 2, test_classes) required_test_names = [test.__name__ for test in required_tests] return required_test_names @@ -207,7 +209,7 @@ def get_subclass_by_file_type( return registry[name] @property - def tests_by_name(self): + def tests_by_name(self) -> dict[str, BaseTest]: return {test.type: test for test in self.tests} def compute_tests(self) -> None: @@ -225,13 +227,16 @@ def compute_status(self) -> SuiteStatus: for test in self.tests: test_name = test.type test_status = test.get_status() - if test_name in self.required_tests: - if test_status == TestStatus.FAIL: - self._status = SuiteStatus.RED - return self._status - else: - if test_status == TestStatus.FAIL: - self._status = SuiteStatus.AMBER + # if test errors, always return grey immediately + if test_status == TestStatus.ERROR: + self._status = SuiteStatus.GREY + return self._status + # if required test failed, red takes precedence over amber + if test_status == TestStatus.FAIL and test_name in self.required_tests: + self._status = SuiteStatus.RED + # if test failed not required test, amber + if test_status == TestStatus.FAIL and self._status != SuiteStatus.RED: + self._status = SuiteStatus.AMBER return self._status def to_dict(self) -> SerializedObject: diff --git a/src/dcqc/suites/suites.py b/src/dcqc/suites/suites.py index 485e607..0339fbe 100644 --- a/src/dcqc/suites/suites.py +++ b/src/dcqc/suites/suites.py @@ -3,24 +3,30 @@ from dcqc.suites.suite_abc import SuiteABC -# TODO: Consider moving the filetype-test association logic -# to the file types class FileSuite(SuiteABC): + """Base class for all file-based test suites.""" + file_type = FileType.get_file_type("*") add_tests = (tests.FileExtensionTest, tests.Md5ChecksumTest) class JsonSuite(FileSuite): + """Suite class for JSON files.""" + file_type = FileType.get_file_type("JSON") add_tests = (tests.JsonLoadTest,) class JsonLdSuite(JsonSuite): + """Suite class for JSON-LD files.""" + file_type = FileType.get_file_type("JSON-LD") add_tests = (tests.JsonLdLoadTest,) class TiffSuite(FileSuite): + """Suite class for TIFF files.""" + file_type = FileType.get_file_type("TIFF") add_tests = ( tests.LibTiffInfoTest, @@ -30,30 +36,44 @@ class TiffSuite(FileSuite): class OmeTiffSuite(TiffSuite): + """Suite class for OME-TIFF files.""" + file_type = FileType.get_file_type("OME-TIFF") add_tests = (tests.OmeXmlSchemaTest, tests.BioFormatsInfoTest) class TSVSuite(FileSuite): + """Suite class for TSV files.""" + file_type = FileType.get_file_type("TSV") class BAMSuite(FileSuite): + """Suite class for BAM files.""" + file_type = FileType.get_file_type("BAM") class FastqSuite(FileSuite): + """Suite class for FASTQ files.""" + file_type = FileType.get_file_type("FASTQ") add_tests = (tests.PairedFastqParityTest,) class TXTSuite(FileSuite): + """Suite class for TXT files.""" + file_type = FileType.get_file_type("TXT") class CSVSuite(FileSuite): + """Suite class for CSV files.""" + file_type = FileType.get_file_type("CSV") class HDF5Suite(FileSuite): + """Suite class for HDF5 files.""" + file_type = FileType.get_file_type("HDF5") diff --git a/src/dcqc/tests/__init__.py b/src/dcqc/tests/__init__.py index cc37ba0..f775fd2 100644 --- a/src/dcqc/tests/__init__.py +++ b/src/dcqc/tests/__init__.py @@ -1,4 +1,10 @@ -from dcqc.tests.base_test import BaseTest, ExternalTestMixin, Process, TestStatus +from dcqc.tests.base_test import ( + BaseTest, + ExternalTestMixin, + Process, + TestStatus, + TestTier, +) from dcqc.tests.bioformats_info_test import BioFormatsInfoTest from dcqc.tests.file_extension_test import FileExtensionTest from dcqc.tests.grep_date_test import GrepDateTest diff --git a/src/dcqc/tests/base_test.py b/src/dcqc/tests/base_test.py index fd1c610..5e789e8 100644 --- a/src/dcqc/tests/base_test.py +++ b/src/dcqc/tests/base_test.py @@ -18,10 +18,22 @@ class TestStatus(Enum): + """Enum for test statuses.""" + NONE = "pending" FAIL = "failed" PASS = "passed" SKIP = "skipped" + ERROR = "error" + + +class TestTier(Enum): + """Enum for test tiers.""" + + FILE_INTEGRITY = 1 + INTERNAL_CONFORMANCE = 2 + EXTERNAL_CONFORMANCE = 3 + SUBJECTIVE_CONFORMANCE = 4 # TODO: Look into the @typing.final decorator @@ -40,20 +52,20 @@ class BaseTest(SerializableMixin, SubclassRegistryMixin, ABC, Generic[Target]): """ # Class attributes - tier: ClassVar[int] - is_external_test: ClassVar[bool] - is_external_test = False + tier: TestTier + is_external_test: bool = False # Instance attributes type: str target: Target + status_reason: str = "" def __init__(self, target: Target, skip: bool = False): self.type = self.__class__.__name__ self.target = target self._status = TestStatus.SKIP if skip else TestStatus.NONE - def skip(self): + def skip(self) -> None: """Force the test to be skipped.""" self._status = TestStatus.SKIP @@ -70,9 +82,10 @@ def compute_status(self) -> TestStatus: def to_dict(self) -> SerializedObject: test_dict = { "type": self.type, - "tier": self.tier, + "tier": self.tier.value, "is_external_test": self.is_external_test, "status": self._status.value, + "status_reason": self.status_reason, "target": self.target.to_dict(), } return test_dict @@ -97,6 +110,7 @@ def from_dict(cls, dictionary: SerializedObject) -> BaseTest: status = TestStatus(dictionary["status"]) test._status = status + test.status_reason = dictionary["status_reason"] return test @@ -119,6 +133,8 @@ def get_base_class(cls): @dataclass class Process(SerializableMixin): + """Class for composing external processes""" + container: str command_args: InitVar[Sequence[str]] cpus: int = 1 @@ -153,10 +169,16 @@ def from_dict(cls, dictionary: SerializedObject) -> Process: class ExternalTestMixin(BaseTest): - pass_code: ClassVar[str] + """Class Mixin for external tests.""" + # Class attributes is_external_test = True + # Instance attributes + pass_code: int + fail_code: int + failure_reason_location: str + # Class constants STDOUT_PATH: ClassVar[Path] STDOUT_PATH = Path("std_out.txt") @@ -190,16 +212,21 @@ def _find_process_outputs( if not path.exists(): message = f"Expected process output ({path}) does not exist." raise FileNotFoundError(message) + return outputs def _interpret_process_outputs(self, outputs: dict[str, Path]) -> TestStatus: """Interpret the process output files to yield a test status.""" - exit_code = outputs["exit_code"].read_text() - exit_code = exit_code.strip() + exit_code = int(outputs["exit_code"].read_text().strip()) + if exit_code == self.pass_code: status = TestStatus.PASS - else: + elif exit_code == self.fail_code: status = TestStatus.FAIL + self.status_reason = outputs[self.failure_reason_location].read_text() + else: + status = TestStatus.ERROR + self.status_reason = outputs["std_err"].read_text() return status # TODO: Include process in serialized test dictionary diff --git a/src/dcqc/tests/bioformats_info_test.py b/src/dcqc/tests/bioformats_info_test.py index 40144f7..0b6aa1d 100644 --- a/src/dcqc/tests/bioformats_info_test.py +++ b/src/dcqc/tests/bioformats_info_test.py @@ -1,10 +1,14 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class BioFormatsInfoTest(ExternalBaseTest): - tier = 2 - pass_code = "0" + """Tests if a file is valid OME-TIFF.""" + + tier = TestTier.INTERNAL_CONFORMANCE + pass_code = 0 + fail_code = 1 + failure_reason_location = "std_err" target: SingleTarget def generate_process(self) -> Process: diff --git a/src/dcqc/tests/file_extension_test.py b/src/dcqc/tests/file_extension_test.py index b6206c8..115521e 100644 --- a/src/dcqc/tests/file_extension_test.py +++ b/src/dcqc/tests/file_extension_test.py @@ -1,9 +1,11 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import InternalBaseTest, TestStatus +from dcqc.tests.base_test import InternalBaseTest, TestStatus, TestTier class FileExtensionTest(InternalBaseTest): - tier = 1 + """Tests if a file has a valid extension for its file type.""" + + tier = TestTier.FILE_INTEGRITY target: SingleTarget def compute_status(self) -> TestStatus: @@ -13,5 +15,8 @@ def compute_status(self) -> TestStatus: file_extensions = file_type.file_extensions if not file.name.endswith(file_extensions): status = TestStatus.FAIL + self.status_reason = ( + f"File extension does not match one of: {file_extensions}" + ) break return status diff --git a/src/dcqc/tests/grep_date_test.py b/src/dcqc/tests/grep_date_test.py index 668b94a..1f54692 100644 --- a/src/dcqc/tests/grep_date_test.py +++ b/src/dcqc/tests/grep_date_test.py @@ -1,10 +1,16 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class GrepDateTest(ExternalBaseTest): - tier = 4 - pass_code = "1" + """Tests if a file has the word "date" or "time" in it. + Used for dtecting potential PHI in files. + """ + + tier = TestTier.SUBJECTIVE_CONFORMANCE + pass_code = 1 + fail_code = 0 + failure_reason_location = "std_out" target: SingleTarget def generate_process(self) -> Process: @@ -15,7 +21,6 @@ def generate_process(self) -> Process: "-E", # extended regular expression "-i", # case insensitive "-a", # treat input as text - "-q", # suppress output "'date|time'", # match date or time f"'{path.name}'", ] diff --git a/src/dcqc/tests/json_load_test.py b/src/dcqc/tests/json_load_test.py index b31ee5b..edcdcc5 100644 --- a/src/dcqc/tests/json_load_test.py +++ b/src/dcqc/tests/json_load_test.py @@ -2,11 +2,13 @@ from pathlib import Path from dcqc.target import SingleTarget -from dcqc.tests.base_test import InternalBaseTest, TestStatus +from dcqc.tests.base_test import InternalBaseTest, TestStatus, TestTier class JsonLoadTest(InternalBaseTest): - tier = 2 + """Tests if a file can be loaded as JSON.""" + + tier = TestTier.INTERNAL_CONFORMANCE target: SingleTarget def compute_status(self) -> TestStatus: @@ -15,6 +17,7 @@ def compute_status(self) -> TestStatus: status = TestStatus.PASS else: status = TestStatus.FAIL + self.status_reason = "File content is unable to be loaded as JSON" return status def _can_be_loaded(self, path: Path) -> bool: diff --git a/src/dcqc/tests/jsonld_load_test.py b/src/dcqc/tests/jsonld_load_test.py index ad9e959..08b1b3c 100644 --- a/src/dcqc/tests/jsonld_load_test.py +++ b/src/dcqc/tests/jsonld_load_test.py @@ -1,11 +1,13 @@ from pathlib import Path from dcqc.target import SingleTarget -from dcqc.tests.base_test import InternalBaseTest, TestStatus +from dcqc.tests.base_test import InternalBaseTest, TestStatus, TestTier class JsonLdLoadTest(InternalBaseTest): - tier = 2 + """Tests if a file can be loaded as JSON-LD.""" + + tier = TestTier.INTERNAL_CONFORMANCE target: SingleTarget def compute_status(self) -> TestStatus: @@ -14,6 +16,7 @@ def compute_status(self) -> TestStatus: status = TestStatus.PASS else: status = TestStatus.FAIL + self.status_reason = "File content is unable to be loaded as JSON-LD" return status def _can_be_loaded(self, path: Path) -> bool: diff --git a/src/dcqc/tests/libtiff_info_test.py b/src/dcqc/tests/libtiff_info_test.py index c7d146d..356231b 100644 --- a/src/dcqc/tests/libtiff_info_test.py +++ b/src/dcqc/tests/libtiff_info_test.py @@ -1,10 +1,14 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class LibTiffInfoTest(ExternalBaseTest): - tier = 2 - pass_code = "0" + """Tests if a file is valid TIFF.""" + + tier = TestTier.INTERNAL_CONFORMANCE + pass_code = 0 + fail_code = 1 + failure_reason_location = "std_err" target: SingleTarget def generate_process(self) -> Process: diff --git a/src/dcqc/tests/md5_checksum_test.py b/src/dcqc/tests/md5_checksum_test.py index 3a76f16..e0e9661 100644 --- a/src/dcqc/tests/md5_checksum_test.py +++ b/src/dcqc/tests/md5_checksum_test.py @@ -2,11 +2,13 @@ from pathlib import Path from dcqc.target import SingleTarget -from dcqc.tests.base_test import InternalBaseTest, TestStatus +from dcqc.tests.base_test import InternalBaseTest, TestStatus, TestTier class Md5ChecksumTest(InternalBaseTest): - tier = 1 + """Tests if a file has the expected MD5 checksum.""" + + tier = TestTier.FILE_INTEGRITY target: SingleTarget def compute_status(self) -> TestStatus: @@ -17,6 +19,7 @@ def compute_status(self) -> TestStatus: status = TestStatus.PASS else: status = TestStatus.FAIL + self.status_reason = "Computed MD5 checksum does not match provided value" return status def _compute_md5_checksum(self, path: Path) -> str: diff --git a/src/dcqc/tests/ome_xml_schema_test.py b/src/dcqc/tests/ome_xml_schema_test.py index f8e246a..a5de40f 100644 --- a/src/dcqc/tests/ome_xml_schema_test.py +++ b/src/dcqc/tests/ome_xml_schema_test.py @@ -1,10 +1,14 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class OmeXmlSchemaTest(ExternalBaseTest): - tier = 2 - pass_code = "0" + """Tests if OME-TIFF file has valid XML metadata.""" + + tier = TestTier.INTERNAL_CONFORMANCE + pass_code = 0 + fail_code = 1 + failure_reason_location = "std_out" target: SingleTarget def generate_process(self) -> Process: diff --git a/src/dcqc/tests/paired_fastq_parity_test.py b/src/dcqc/tests/paired_fastq_parity_test.py index 3e9f85e..1451951 100644 --- a/src/dcqc/tests/paired_fastq_parity_test.py +++ b/src/dcqc/tests/paired_fastq_parity_test.py @@ -3,11 +3,13 @@ from typing import TextIO from dcqc.target import PairedTarget -from dcqc.tests.base_test import InternalBaseTest, TestStatus +from dcqc.tests.base_test import InternalBaseTest, TestStatus, TestTier class PairedFastqParityTest(InternalBaseTest): - tier = 2 + """Test that paired FASTQ files have the same number of lines.""" + + tier = TestTier.INTERNAL_CONFORMANCE target: PairedTarget def compute_status(self) -> TestStatus: @@ -18,6 +20,7 @@ def compute_status(self) -> TestStatus: try: count = self._count_fastq_lines(path) except Exception: + self.status_reason = "Unable to count FASTQ lines" return TestStatus.FAIL counts.append(count) @@ -26,6 +29,7 @@ def compute_status(self) -> TestStatus: status = TestStatus.PASS else: status = TestStatus.FAIL + self.status_reason = "FASTQ files do not have the same number of lines" return status def _count_fastq_lines(self, path: Path) -> int: diff --git a/src/dcqc/tests/tiff_date_time_test.py b/src/dcqc/tests/tiff_date_time_test.py index dfeecd9..7ec71a8 100644 --- a/src/dcqc/tests/tiff_date_time_test.py +++ b/src/dcqc/tests/tiff_date_time_test.py @@ -1,10 +1,16 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class TiffDateTimeTest(ExternalBaseTest): - tier = 4 - pass_code = "1" + """Tests if a TIFF file has the word "date" or "time" in its metadata. + Used for detecting potential PHI in files. + """ + + tier = TestTier.SUBJECTIVE_CONFORMANCE + pass_code = 1 + fail_code = 0 + failure_reason_location = "std_out" target: SingleTarget def generate_process(self) -> Process: diff --git a/src/dcqc/tests/tiff_tag_306_date_time_test.py b/src/dcqc/tests/tiff_tag_306_date_time_test.py index 5ec5d67..f0c49fc 100644 --- a/src/dcqc/tests/tiff_tag_306_date_time_test.py +++ b/src/dcqc/tests/tiff_tag_306_date_time_test.py @@ -1,10 +1,16 @@ from dcqc.target import SingleTarget -from dcqc.tests.base_test import ExternalBaseTest, Process +from dcqc.tests.base_test import ExternalBaseTest, Process, TestTier class TiffTag306DateTimeTest(ExternalBaseTest): - tier = 4 - pass_code = "1" + """Tests if a tiff file has the `306` date/time tag in its metadata. + Used for detecting potential PHI in files. + """ + + tier = TestTier.SUBJECTIVE_CONFORMANCE + pass_code = 1 + fail_code = 0 + failure_reason_location = "std_out" target: SingleTarget def generate_process(self) -> Process: diff --git a/src/dcqc/updaters.py b/src/dcqc/updaters.py index 6002643..9c3926d 100644 --- a/src/dcqc/updaters.py +++ b/src/dcqc/updaters.py @@ -1,15 +1,17 @@ -from collections import defaultdict from csv import DictWriter from dataclasses import dataclass from pathlib import Path -from typing import List +from typing import Any, List from dcqc.parsers import CsvParser from dcqc.suites.suite_abc import SuiteABC +from dcqc.tests.base_test import TestStatus @dataclass class CsvUpdater: + """Updates the CSV manifest file with DCQC results.""" + input_path: Path output_path: Path parser: CsvParser @@ -18,30 +20,41 @@ def __init__(self, input_path: Path, output_path: Path): self.output_path = output_path self.input_path = input_path - def update(self, suites: List[SuiteABC]): - suite_dict = defaultdict(list) - # {url: [list_of_statuses]} data structure to allow for multi-file targets + def update(self, suites: List[SuiteABC]) -> None: + suite_dict: dict[str, dict[str, Any]] = {} # TODO add support for suites with multiple files in them (multi) for suite in suites: url = suite.target.files[0].url - status = suite.get_status() - suite_dict[url].append(status.value) - # Evaluate dcqc_status for each url - collapsed_dict = {} - for url, statuses in suite_dict.items(): - if "RED" in statuses: - collapsed_dict[url] = "RED" - elif "AMBER" in statuses: - collapsed_dict[url] = "AMBER" - elif "GREEN" in statuses: - collapsed_dict[url] = "GREEN" - else: - collapsed_dict[url] = "NONE" + suite_dict[url] = { + "status": suite.get_status().value, + "required_tests": suite.required_tests, + "skipped_tests": suite.skipped_tests, + "failed_tests": [], + "errored_tests": [], + } + for test in suite.tests: + if test._status == TestStatus.FAIL: + suite_dict[url]["failed_tests"].append(test.type) + if test._status == TestStatus.ERROR: + suite_dict[url]["errored_tests"].append(test.type) + # Create CSV data structure row_list = [] parser = CsvParser(self.input_path) for _, csv_data in parser.list_rows(): - csv_data["dcqc_status"] = collapsed_dict[csv_data["url"]] + csv_data["dcqc_status"] = suite_dict[csv_data["url"]]["status"] + csv_data["dcqc_required_tests"] = ",".join( + suite_dict[csv_data["url"]]["required_tests"] + ) + csv_data["dcqc_skipped_tests"] = ",".join( + suite_dict[csv_data["url"]]["skipped_tests"] + ) + csv_data["dcqc_failed_tests"] = ",".join( + suite_dict[csv_data["url"]]["failed_tests"] + ) + csv_data["dcqc_errored_tests"] = ",".join( + suite_dict[csv_data["url"]]["errored_tests"] + ) row_list.append(csv_data) if row_list: diff --git a/src/docker/build.sh b/src/docker/build.sh index 8f77a3a..a35946c 100644 --- a/src/docker/build.sh +++ b/src/docker/build.sh @@ -10,5 +10,6 @@ export TARBALL_PATH docker build \ -t dcqc \ -f "${SCRIPT_DIR}/Dockerfile" \ + --platform linux/amd64 \ --build-arg TARBALL_PATH \ "${SCRIPT_DIR}/../.." diff --git a/tests/data/suite.json b/tests/data/suite.json index 3f6236d..437134c 100644 --- a/tests/data/suite.json +++ b/tests/data/suite.json @@ -29,13 +29,15 @@ "type": "Md5ChecksumTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "LibTiffInfoTest", "tier": 2, "is_external_test": true, - "status": "skipped" + "status": "skipped", + "status_reason": "" } ] } diff --git a/tests/data/suites.json b/tests/data/suites.json index aaf72e4..c922343 100644 --- a/tests/data/suites.json +++ b/tests/data/suites.json @@ -30,31 +30,36 @@ "type": "FileExtensionTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "GrepDateTest", "tier": 4, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "LibTiffInfoTest", "tier": 2, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "Md5ChecksumTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "TiffTag306DateTimeTest", "tier": 4, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" } ] }, @@ -89,31 +94,36 @@ "type": "FileExtensionTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "GrepDateTest", "tier": 4, "is_external_test": true, - "status": "failed" + "status": "failed", + "status_reason": "test failed" }, { "type": "LibTiffInfoTest", "tier": 2, "is_external_test": true, - "status": "failed" + "status": "failed", + "status_reason": "test failed" }, { "type": "Md5ChecksumTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "TiffTag306DateTimeTest", "tier": 4, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" } ] }, @@ -148,31 +158,36 @@ "type": "FileExtensionTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "GrepDateTest", "tier": 4, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "LibTiffInfoTest", "tier": 2, "is_external_test": true, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "Md5ChecksumTest", "tier": 1, "is_external_test": false, - "status": "passed" + "status": "passed", + "status_reason": "" }, { "type": "TiffTag306DateTimeTest", "tier": 4, "is_external_test": true, - "status": "failed" + "status": "failed", + "status_reason": "test failed" } ] } diff --git a/tests/data/test.computed.json b/tests/data/test.computed.json index b1b936a..c86f044 100644 --- a/tests/data/test.computed.json +++ b/tests/data/test.computed.json @@ -3,6 +3,7 @@ "tier": 1, "is_external_test": false, "status": "passed", + "status_reason": "", "target": { "id": "001", "files": [ diff --git a/tests/data/test.external.json b/tests/data/test.external.json index c127947..f4cd893 100644 --- a/tests/data/test.external.json +++ b/tests/data/test.external.json @@ -3,6 +3,7 @@ "tier": 2, "is_external_test": true, "status": "pending", + "status_reason": "", "target": { "id": "001", "files": [ diff --git a/tests/data/test.internal.json b/tests/data/test.internal.json index 55d91be..0c47c29 100644 --- a/tests/data/test.internal.json +++ b/tests/data/test.internal.json @@ -3,6 +3,7 @@ "tier": 1, "is_external_test": false, "status": "pending", + "status_reason": "", "target": { "id": "001", "files": [ diff --git a/tests/data/test_output.csv b/tests/data/test_output.csv index e37ee65..b27ae39 100644 --- a/tests/data/test_output.csv +++ b/tests/data/test_output.csv @@ -1,5 +1,5 @@ -url,file_type,md5_checksum,dcqc_status -syn://syn51585496,TXT,38b86a456d1f441008986c6f798d5ef9,GREEN -syn://syn51585494,TXT,a542e9b744bedcfd874129ab0f98c4ff,RED -syn://syn51585495,TIFF,38b86a456d1f441008986c6f798d5ef9,AMBER -syn://syn51585493,TIFF,38b86a456d1f441008986c6f798d5ef9,NONE +url,file_type,md5_checksum,dcqc_status,dcqc_required_tests,dcqc_skipped_tests,dcqc_failed_tests,dcqc_errored_tests +syn://syn51585496,TXT,38b86a456d1f441008986c6f798d5ef9,GREEN,,,, +syn://syn51585494,TXT,a542e9b744bedcfd874129ab0f98c4ff,RED,,,, +syn://syn51585495,TIFF,38b86a456d1f441008986c6f798d5ef9,AMBER,,,, +syn://syn51585493,TIFF,38b86a456d1f441008986c6f798d5ef9,NONE,,,, diff --git a/tests/data/tests.json b/tests/data/tests.json index 21d89de..be36038 100644 --- a/tests/data/tests.json +++ b/tests/data/tests.json @@ -4,6 +4,7 @@ "tier": 1, "is_external_test": false, "status": "pending", + "status_reason": "", "target": { "id": "001", "files": [ @@ -25,6 +26,7 @@ "tier": 2, "is_external_test": true, "status": "pending", + "status_reason": "", "target": { "id": "001", "files": [ @@ -46,6 +48,7 @@ "tier": 1, "is_external_test": false, "status": "passed", + "status_reason": "", "target": { "id": "001", "files": [ diff --git a/tests/test_internal_tests.py b/tests/test_internal_tests.py index 9fc5603..7318d7a 100644 --- a/tests/test_internal_tests.py +++ b/tests/test_internal_tests.py @@ -52,6 +52,10 @@ def test_that_a_tiff_file_with_good_extensions_is_passed(self): def test_that_the_file_extension_test_works_on_incorrect_files(self): assert self.bad_txt_test.get_status() == TestStatus.FAIL + assert self.bad_txt_test.status_reason == ( + "File extension does not match one of: " + f"{self.bad_txt_target.get_file_type().file_extensions}" + ) class Md5ChecksumTest: @@ -67,6 +71,10 @@ def test_that_the_md5_checksum_test_works_on_a_correct_file(self): def test_that_the_md5_checksum_test_works_on_incorrect_files(self): assert self.bad_txt_test.get_status() == TestStatus.FAIL + assert ( + self.bad_txt_test.status_reason + == "Computed MD5 checksum does not match provided value" + ) class TestJsonLoadTest: @@ -82,6 +90,10 @@ def test_that_the_json_load_test_works_on_a_correct_file(self): def test_that_the_json_load_test_works_on_incorrect_files(self): assert self.good_txt_test.get_status() == TestStatus.FAIL + assert ( + self.good_txt_test.status_reason + == "File content is unable to be loaded as JSON" + ) class TestJsonLdLoadTest: @@ -97,6 +109,10 @@ def test_that_the_jsonld_load_test_works_on_a_correct_file(self): def test_that_the_jsonld_load_test_works_on_incorrect_files(self): assert self.good_txt_test.get_status() == TestStatus.FAIL + assert ( + self.good_txt_test.status_reason + == "File content is unable to be loaded as JSON-LD" + ) class TestPairedFastqParityTest: @@ -104,6 +120,7 @@ class TestPairedFastqParityTest: def setup_method(self, test_files): self.fastq1_file = test_files["good_fastq"] self.fastq2_file = test_files["good_compressed_fastq"] + self.good_txt_file = test_files["good_txt"] self.good_paired_target = PairedTarget([self.fastq1_file, self.fastq1_file]) self.good_paired_test = tests.PairedFastqParityTest(self.good_paired_target) self.bad_paired_target = PairedTarget([self.fastq1_file, self.fastq2_file]) @@ -114,18 +131,24 @@ def setup_method(self, test_files): self.good_compressed_paired_test = tests.PairedFastqParityTest( self.good_compressed_paired_target ) + self.good_txt_target = PairedTarget([self.good_txt_file, self.good_txt_file]) + self.good_txt_test = tests.PairedFastqParityTest(self.good_txt_target) def test_that_paired_fastq_parity_test_correctly_passes_identical_fastq_files( self, ): assert self.good_paired_test.get_status() == TestStatus.PASS - def test_that_paired_fastq_parity_test_correctly_fails_different_fastq_files( + def test_that_paired_fastq_parity_test_correctly_handles_compressed_fastq_files( self, ): - assert self.bad_paired_test.get_status() == TestStatus.FAIL + assert self.good_compressed_paired_test.get_status() == TestStatus.PASS - def test_that_paired_fastq_parity_test_correctly_handles_compressed_fastq_files( + def test_that_paired_fastq_parity_test_correctly_fails_different_fastq_files( self, ): - assert self.good_compressed_paired_test.get_status() == TestStatus.PASS + assert self.bad_paired_test.get_status() == TestStatus.FAIL + assert ( + self.bad_paired_test.status_reason + == "FASTQ files do not have the same number of lines" + ) diff --git a/tests/test_suites.py b/tests/test_suites.py index 2cf0348..ef6d5a0 100644 --- a/tests/test_suites.py +++ b/tests/test_suites.py @@ -79,7 +79,7 @@ def test_that_the_generic_file_suite_is_retrieved_for_an_unpaired_file_type(): def test_that_the_default_required_tests_are_only_tiers_1_and_2(test_suites): suite = test_suites["good_jsonld"] - assert all(test.tier <= 2 for test in suite.tests) + assert all(test.tier.value <= 2 for test in suite.tests) def test_that_skipped_tests_are_skipped_when_building_suite_from_tests(test_suites):