From 80ebde9539a5fbd257335334a087dd632f43857d Mon Sep 17 00:00:00 2001 From: "Thomas J. Zajac" Date: Mon, 15 Jan 2024 08:52:39 +0000 Subject: [PATCH] Template update --- .coveragerc | 5 - .devcontainer/dev_install | 2 +- .github/workflows/check_config_docs.yaml | 2 +- .github/workflows/check_openapi_spec.yaml | 19 ++ .github/workflows/check_pyproject.yaml | 16 ++ .github/workflows/check_readme.yaml | 2 +- .github/workflows/static_code_analysis.yaml | 2 +- .github/workflows/tests.yaml | 2 +- .mypy.ini | 12 - .pyproject_generation/README.md | 29 +++ .pyproject_generation/pyproject_custom.toml | 17 ++ .../pyproject_template.toml | 61 ++++- .../README.md | 22 +- .../description.md | 8 +- .design.md => .readme_generation/design.md | 4 - .../readme_template.md | 5 +- .template/README.md | 47 ++++ .../deprecated_files.txt | 19 ++ .template/deprecated_files_ignore.txt | 2 + .../mandatory_files.txt | 14 +- .../mandatory_files_ignore.txt | 2 - .static_files => .template/static_files.txt | 21 +- .../static_files_ignore.txt | 4 - README.md | 21 +- lock/README.md | 56 ++++ .../requirements-dev-template.in | 0 lock/requirements-dev.in | 7 + .../requirements-dev.txt | 240 ++++++++++-------- requirements.txt => lock/requirements.txt | 199 ++++++--------- pyproject.toml | 124 ++++++++- pytest.ini | 5 - requirements-dev.in | 7 - scripts/license_checker.py | 12 +- scripts/list_outdated_dependencies.py | 7 +- scripts/script_utils/fastapi_app_location.py | 23 ++ scripts/update_all.py | 40 ++- scripts/update_hook_revs.py | 2 +- scripts/update_lock.py | 7 +- scripts/update_openapi_docs.py | 103 ++++++++ scripts/update_pyproject.py | 117 +++++++++ scripts/update_readme.py | 29 ++- scripts/update_template_files.py | 32 ++- 42 files changed, 982 insertions(+), 366 deletions(-) delete mode 100644 .coveragerc create mode 100644 .github/workflows/check_openapi_spec.yaml create mode 100644 .github/workflows/check_pyproject.yaml delete mode 100644 .mypy.ini create mode 100644 .pyproject_generation/README.md create mode 100644 .pyproject_generation/pyproject_custom.toml rename .ruff.toml => .pyproject_generation/pyproject_template.toml (55%) rename readme_generation.md => .readme_generation/README.md (66%) rename .description.md => .readme_generation/description.md (65%) rename .design.md => .readme_generation/design.md (75%) rename .readme_template.md => .readme_generation/readme_template.md (92%) create mode 100644 .template/README.md rename .deprecated_files => .template/deprecated_files.txt (63%) create mode 100644 .template/deprecated_files_ignore.txt rename .mandatory_files => .template/mandatory_files.txt (74%) rename .mandatory_files_ignore => .template/mandatory_files_ignore.txt (73%) rename .static_files => .template/static_files.txt (81%) rename .static_files_ignore => .template/static_files_ignore.txt (57%) create mode 100644 lock/README.md rename requirements-dev-common.in => lock/requirements-dev-template.in (100%) create mode 100644 lock/requirements-dev.in rename requirements-dev.txt => lock/requirements-dev.txt (88%) rename requirements.txt => lock/requirements.txt (85%) delete mode 100644 pytest.ini delete mode 100644 requirements-dev.in create mode 100644 scripts/script_utils/fastapi_app_location.py create mode 100755 scripts/update_openapi_docs.py create mode 100755 scripts/update_pyproject.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index b172375f..00000000 --- a/.coveragerc +++ /dev/null @@ -1,5 +0,0 @@ -[paths] -source = - src - /workspace/src - **/lib/python*/site-packages diff --git a/.devcontainer/dev_install b/.devcontainer/dev_install index b5ee1890..6a433892 100755 --- a/.devcontainer/dev_install +++ b/.devcontainer/dev_install @@ -7,7 +7,7 @@ cd /workspace python -m pip install --upgrade pip # install or upgrade dependencies for development and testing -pip install --no-deps -r requirements-dev.txt +pip install --no-deps -r ./lock/requirements-dev.txt # install the package itself in edit mode: pip install --no-deps -e . diff --git a/.github/workflows/check_config_docs.yaml b/.github/workflows/check_config_docs.yaml index f863f80b..bb88b574 100644 --- a/.github/workflows/check_config_docs.yaml +++ b/.github/workflows/check_config_docs.yaml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v3 + uses: ghga-de/gh-action-common@v4 - name: Check config docs run: | diff --git a/.github/workflows/check_openapi_spec.yaml b/.github/workflows/check_openapi_spec.yaml new file mode 100644 index 00000000..f5db7665 --- /dev/null +++ b/.github/workflows/check_openapi_spec.yaml @@ -0,0 +1,19 @@ +# This file is only needed, if your repository uses FastAPI +name: Check if openapi.yaml is up to date + +on: push + +jobs: + static-code-analysis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - id: common + uses: ghga-de/gh-action-common@v4 + + - name: Check if openapi.yaml is up to date + run: | + export ${{ steps.common.outputs.CONFIG_YAML_ENV_VAR_NAME }}="${{ steps.common.outputs.CONFIG_YAML }}" + + ./scripts/update_openapi_docs.py --check diff --git a/.github/workflows/check_pyproject.yaml b/.github/workflows/check_pyproject.yaml new file mode 100644 index 00000000..d929c799 --- /dev/null +++ b/.github/workflows/check_pyproject.yaml @@ -0,0 +1,16 @@ +name: Check if the config schema and the example are up to date. + +on: push + +jobs: + static-code-analysis: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - id: common + uses: ghga-de/gh-action-common@v4 + + - name: Check pyproject.toml + run: | + ./scripts/update_pyproject.py --check diff --git a/.github/workflows/check_readme.yaml b/.github/workflows/check_readme.yaml index 9f400d23..7414554d 100644 --- a/.github/workflows/check_readme.yaml +++ b/.github/workflows/check_readme.yaml @@ -9,7 +9,7 @@ jobs: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v3 + uses: ghga-de/gh-action-common@v4 - name: Check readme run: | diff --git a/.github/workflows/static_code_analysis.yaml b/.github/workflows/static_code_analysis.yaml index 39b9bad4..86a014df 100644 --- a/.github/workflows/static_code_analysis.yaml +++ b/.github/workflows/static_code_analysis.yaml @@ -10,7 +10,7 @@ jobs: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v3 + uses: ghga-de/gh-action-common@v4 - uses: pre-commit/action@v3.0.0 env: diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 05f474ca..dacc9f50 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -11,7 +11,7 @@ jobs: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v3 + uses: ghga-de/gh-action-common@v4 - id: pytest run: | diff --git a/.mypy.ini b/.mypy.ini deleted file mode 100644 index 10e9574c..00000000 --- a/.mypy.ini +++ /dev/null @@ -1,12 +0,0 @@ -# Global options: - -[mypy] -disable_error_code = import -show_error_codes = True -exclude = (?x)( - build/lib/ - ) -warn_redundant_casts = True -warn_unused_ignores = True -check_untyped_defs = True -no_site_packages = False diff --git a/.pyproject_generation/README.md b/.pyproject_generation/README.md new file mode 100644 index 00000000..93b988fe --- /dev/null +++ b/.pyproject_generation/README.md @@ -0,0 +1,29 @@ + + +# Generating the pyproject.toml + +The pyproject.toml of the service is generated by combining static configuration +captured in [`./pyproject_template.toml`](./pyproject_template.toml) and custom +package metadata specified in [`./pyproject_custom.toml`](./pyproject_custom.toml). + +The `./pyproject_template.toml` is managed by the template, please do not edit manually. + +You may specify properties in the `./pyproject_custom.toml` which are already specified +in the `./pyproject_template.toml`. In that case, the `./pyproject_custom.toml` takes +priority. diff --git a/.pyproject_generation/pyproject_custom.toml b/.pyproject_generation/pyproject_custom.toml new file mode 100644 index 00000000..08a8d06e --- /dev/null +++ b/.pyproject_generation/pyproject_custom.toml @@ -0,0 +1,17 @@ +[project] +name = "ghga_connector" +version = "1.2.0" +description = "GHGA Connector - A CLI client application for interacting with the GHGA system." +dependencies = [ + "typer~=0.9.0", + "crypt4gh>=1.6, <2", + "ghga-service-commons[api, crypt]~=2.0.0", + "hexkit[s3]~=2.0.0", +] + + +[project.urls] +Repository = "https://github.com/ghga-de/ghga-connector" + +[project.scripts] +ghga-connector = "ghga_connector.__main__:run" diff --git a/.ruff.toml b/.pyproject_generation/pyproject_template.toml similarity index 55% rename from .ruff.toml rename to .pyproject_generation/pyproject_template.toml index 75a9dbe4..c6bb5fc0 100644 --- a/.ruff.toml +++ b/.pyproject_generation/pyproject_template.toml @@ -1,3 +1,30 @@ +[build-system] +requires = ["setuptools>=67.7.2"] +build-backend = "setuptools.build_meta" + +[project] +readme = "README.md" +authors = [ + { name = "German Human Genome Phenome Archive (GHGA)", email = "contact@ghga.de" }, +] +requires-python = ">=3.9" +license = { text = "Apache 2.0" } +classifiers = [ + "Development Status :: 1 - Planning", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "License :: OSI Approved :: Apache Software License", + "Topic :: Internet :: WWW/HTTP :: HTTP Servers", + "Topic :: Software Development :: Libraries", + "Intended Audience :: Developers", +] + +[tool.setuptools.packages.find] +where = ["src"] + +[tool.ruff] exclude = [ ".git", ".devcontainer", @@ -5,7 +32,6 @@ exclude = [ "build", "dist", ] - ignore = [ "E", # pycodestyle errors "W", # pycodestyle warnings - pycodestyle covered by black @@ -23,9 +49,7 @@ ignore = [ "D206", # indent-with-spaces (ignored for formatter) "D300", # triple-single-quotes (ignored for formatter) ] - line-length = 88 - select = [ "C90", # McCabe Complexity "F", # pyflakes codes @@ -39,26 +63,45 @@ select = [ "SIM", # flake8-simplify "D", # pydocstyle ] - fixable = [ "UP", # e.g. List -> list "I", # sort imports "D", # pydocstyle ] - src = ["src", "tests", "examples", "scripts"] - target-version = "py39" -[mccabe] +[tool.ruff.mccabe] max-complexity = 10 -[per-file-ignores] +[tool.ruff.per-file-ignores] "scripts/*" = ["PL", "S", "SIM", "D"] "tests/*" = ["S", "SIM", "PLR", "B011"] ".devcontainer/*" = ["S", "SIM", "D"] "examples/*" = ["S", "D"] "__init__.py" = ["D"] -[pydocstyle] +[tool.ruff.pydocstyle] convention = "pep257" + +[tool.mypy] +disable_error_code = "import" +show_error_codes = true +exclude = [ + 'build/lib/', +] +warn_redundant_casts = true +warn_unused_ignores = true +check_untyped_defs = true +no_site_packages = false + +[tool.pytest.ini_options] +minversion = "7.1" +asyncio_mode = "strict" + +[tool.coverage.paths] +source = [ + "src", + "/workspace/src", + "**/lib/python*/site-packages", +] diff --git a/readme_generation.md b/.readme_generation/README.md similarity index 66% rename from readme_generation.md rename to .readme_generation/README.md index 84cd618b..ed2a2a79 100644 --- a/readme_generation.md +++ b/.readme_generation/README.md @@ -18,30 +18,30 @@ # Readme Generation -The README file is generated by collecting information from different sources as +The Repository README is generated by collecting information from different sources as outlined in the following. - name: The full name of the package is derived from the remote origin Git repository. - title: A title case representation of the name. - shortname: An abbreviation of the full name. This is derived from the name mentioned - in the [`./pyproject.toml`](./pyproject.toml). + in the [`../pyproject.toml`](../pyproject.toml). - summary: A short 1-2 sentence summary derived from the description in the - [`./pyproject.toml`](./pyproject.toml). + [`../pyproject.toml`](../pyproject.toml). - version: The package version derived from the version specified in the - [`./pyproject.toml`](./pyproject.toml). + [`../pyproject.toml`](../pyproject.toml). - description: A markdown-formatted description of the features and use cases of this - service or package. Obtained from the [`./.description.md`](./.description.md). + service or package. Obtained from the [`./description.md`](./description.md). - design_description: A markdown-formatted description of the overall architecture and - design of the package. Obtained from the [`./.design.md`](./.design.md). + design of the package. Obtained from the [`./design.md`](./design.md). - config_description: A markdown-formatted description of all config parameters. - This is autogenerated from the [`./config_schema.json`](./config_schema.json). + This is autogenerated from the [`../config_schema.json`](../config_schema.json). - openapi_doc: A markdown-formatted description of the HTTP API. This is autogenerated - and links to the [`./openapi.yaml`](./openapi.yaml). If the openapi.yaml is not + and links to the [`../openapi.yaml`](../openapi.yaml). If the openapi.yaml is not this documentation is empty. -The [`./.readme_template.md`](./.readme_template.md) serves as a template where the +The [`./readme_template.md`](./readme_template.md) serves as a template where the above variable can be filled in using Pythons `string.Template` utility from the standard library. -The [`./scripts/update_readme.py`] script can be used to collect all information and -fill it into the template to generate the README file. +The [`../scripts/update_readme.py`](../scripts/update_readme.py) script can be used to +collect all information and fill it into the template to generate the README file. diff --git a/.description.md b/.readme_generation/description.md similarity index 65% rename from .description.md rename to .readme_generation/description.md index 092aef6a..ba7daf69 100644 --- a/.description.md +++ b/.readme_generation/description.md @@ -1,9 +1,9 @@ - - The GHGA Connector is a command line client facilitating interaction with the file storage infrastructure of GHGA. -To this end, it provides commands for the up- and download of files that interact with the RESTful APIs exposed by the Upload Controller Service (https://github.com/ghga-de/upload-controller-service) and Download Controller Service (https://github.com/ghga-de/download-controller-service), respectively. +To this end, it provides commands for the up- and download of files that interact with the RESTful APIs exposed +by the Upload Controller Service (https://github.com/ghga-de/upload-controller-service) and Download Controller Service (https://github.com/ghga-de/download-controller-service), respectively. -When uploading, the Connector expects an unencrypted file that is subsequently encrypted according to the Crypt4GH standard (https://www.ga4gh.org/news_item/crypt4gh-a-secure-method-for-sharing-human-genetic-data/) and only afterwards uploaded to the GHGA storage infrastructure. +When uploading, the Connector expects an unencrypted file that is subsequently encrypted according to the Crypt4 +GH standard (https://www.ga4gh.org/news_item/crypt4gh-a-secure-method-for-sharing-human-genetic-data/) and only afterwards uploaded to the GHGA storage infrastructure. When downloading, the resulting file is still encrypted in this manner and can be decrypted using the Connector's decrypt command. As the user is expected to download multiple files, this command takes a directory location as input and an optional output directory location can be provided, creating the directory if it does not yet exist (defaulting to the current working directory, if none is provided). diff --git a/.design.md b/.readme_generation/design.md similarity index 75% rename from .design.md rename to .readme_generation/design.md index c9b3420c..531626a5 100644 --- a/.design.md +++ b/.readme_generation/design.md @@ -1,7 +1,3 @@ - - This is a Python-based client enabling interaction with GHGA's file services. Contrary to the design of the actual services, the client does not follow the triple-hexagonal architecture. The client is roughly structured into three parts: diff --git a/.readme_template.md b/.readme_generation/readme_template.md similarity index 92% rename from .readme_template.md rename to .readme_generation/readme_template.md index 10e3e612..98a00c09 100644 --- a/.readme_template.md +++ b/.readme_generation/readme_template.md @@ -1,6 +1,5 @@ - -[![tests](https://github.com/ghga-de/$name/actions/workflows/tests.yaml/badge.svg)](https://github.com/ghga-de/$name/actions/workflows/tests.yaml) -[![Coverage Status](https://coveralls.io/repos/github/ghga-de/$name/badge.svg?branch=main)](https://coveralls.io/github/ghga-de/$name?branch=main) +[![tests](https://github.com/ghga-de/$repo_name/actions/workflows/tests.yaml/badge.svg)](https://github.com/ghga-de/$repo_name/actions/workflows/tests.yaml) +[![Coverage Status](https://coveralls.io/repos/github/ghga-de/$repo_name/badge.svg?branch=main)](https://coveralls.io/github/ghga-de/$repo_name?branch=main) # $title diff --git a/.template/README.md b/.template/README.md new file mode 100644 index 00000000..8a5e7cd6 --- /dev/null +++ b/.template/README.md @@ -0,0 +1,47 @@ + + +# Template File Lists + +This directory contains multiple text files that are listing paths to other files +of this repository. The listed files are affected in different ways by template updates +as explained in the following. + +## `static_files.txt` +The files listed here are synced with their counterparts in the template. They should +never be modified manually. + +## `static_files_ignore.txt` +To opt out of template updates just for individual files declared as static +(e.g. because you would like manually modify them), you may add them to this list. + +## `mandatory_files.txt` +The contents of the files listed here are not synced with the template, however, upon +every template update it is checked that the files exist. You should modify them +manually to the needs of your repository. + +## `mandatory_files_ignore.txt` +To opt out of existence checks for individual files declared as mandatory, you may add +them to this list. + +## `deprecated_files.txt` +Files listed here must not exist in your repository and are automatically deleted upon +a template update. + +## `deprecated_files_ignore.txt` +If you would like to keep files declared as deprecated, you may add them to this list. diff --git a/.deprecated_files b/.template/deprecated_files.txt similarity index 63% rename from .deprecated_files rename to .template/deprecated_files.txt index 1fc91256..df962efe 100644 --- a/.deprecated_files +++ b/.template/deprecated_files.txt @@ -19,7 +19,26 @@ docs setup.py setup.cfg +requirements-dev-common.in +requirements-dev.in +requirements-dev.txt +requirements.txt +pytest.ini +readme_generation.md .pylintrc .flake8 +.mypy.ini +.ruff.toml +.coveragerc .editorconfig +.deprecated_files +.deprecated_files_ignore +.mandatory_files +.mandatory_files_ignore +.static_files +.static_files_ignore +.description.md +.design.md +.readme_template.md +.readme_generation.md diff --git a/.template/deprecated_files_ignore.txt b/.template/deprecated_files_ignore.txt new file mode 100644 index 00000000..b589813a --- /dev/null +++ b/.template/deprecated_files_ignore.txt @@ -0,0 +1,2 @@ +# Optional list of files which are actually deprecated in the template +# but are still allowed to be used in the current repository diff --git a/.mandatory_files b/.template/mandatory_files.txt similarity index 74% rename from .mandatory_files rename to .template/mandatory_files.txt index ba9f6c31..660a15ed 100644 --- a/.mandatory_files +++ b/.template/mandatory_files.txt @@ -13,16 +13,20 @@ tests/fixtures/__init__.py scripts/script_utils/fastapi_app_location.py +.readme_generation/description.md +.readme_generation/design.md + +.pyproject_generation/pyproject_custom.toml + +lock/requirements-dev.in +lock/requirements-dev.txt +lock/requirements.txt + Dockerfile config_schema.json example_config.yaml LICENSE pyproject.toml README.md -requirements-dev.in -requirements-dev.txt -requirements.txt -.description.md -.design.md .pre-commit-config.yaml diff --git a/.mandatory_files_ignore b/.template/mandatory_files_ignore.txt similarity index 73% rename from .mandatory_files_ignore rename to .template/mandatory_files_ignore.txt index e58701d7..b8a7ee6e 100644 --- a/.mandatory_files_ignore +++ b/.template/mandatory_files_ignore.txt @@ -1,4 +1,2 @@ # Optional list of files which are actually mandatory in the template # but are allowed to be removed in the current repository - -scripts/script_utils/fastapi_app_location.py diff --git a/.static_files b/.template/static_files.txt similarity index 81% rename from .static_files rename to .template/static_files.txt index 1f129ea4..46e46bf6 100644 --- a/.static_files +++ b/.template/static_files.txt @@ -26,12 +26,14 @@ scripts/update_openapi_docs.py scripts/update_readme.py scripts/update_lock.py scripts/update_hook_revs.py +scripts/update_pyproject.py scripts/list_outdated_dependencies.py scripts/README.md .github/workflows/check_config_docs.yaml .github/workflows/check_openapi_spec.yaml .github/workflows/check_readme.yaml +.github/workflows/check_pyproject.yaml .github/workflows/check_template_files.yaml .github/workflows/ci_release.yaml .github/workflows/ci_workflow_dispatch.yaml @@ -40,15 +42,18 @@ scripts/README.md example_data/README.md -.coveragerc +.template/README.md + +.readme_generation/readme_template.md +.readme_generation/README.md + +.pyproject_generation/pyproject_template.toml +.pyproject_generation/README.md + +lock/requirements-dev-template.in +lock/README.md + .gitattributes .gitignore -.mypy.ini -.ruff.toml -pytest.ini LICENSE -requirements-dev-common.in - -.readme_template.md -readme_generation.md diff --git a/.static_files_ignore b/.template/static_files_ignore.txt similarity index 57% rename from .static_files_ignore rename to .template/static_files_ignore.txt index 0023eaee..8f374ce0 100644 --- a/.static_files_ignore +++ b/.template/static_files_ignore.txt @@ -1,6 +1,2 @@ # Optional list of files which are actually static in the template # but are allowed to have different content in the current repository -./devcontainer/Dockerfile - -scripts/update_openapi_docs.py -.github/workflows/check_openapi_spec.yaml diff --git a/README.md b/README.md index 65b749be..b6f01480 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - [![tests](https://github.com/ghga-de/ghga-connector/actions/workflows/tests.yaml/badge.svg)](https://github.com/ghga-de/ghga-connector/actions/workflows/tests.yaml) [![Coverage Status](https://coveralls.io/repos/github/ghga-de/ghga-connector/badge.svg?branch=main)](https://coveralls.io/github/ghga-de/ghga-connector?branch=main) @@ -8,12 +7,12 @@ GHGA Connector - A CLI client application for interacting with the GHGA system. ## Description - - The GHGA Connector is a command line client facilitating interaction with the file storage infrastructure of GHGA. -To this end, it provides commands for the up- and download of files that interact with the RESTful APIs exposed by the Upload Controller Service (https://github.com/ghga-de/upload-controller-service) and Download Controller Service (https://github.com/ghga-de/download-controller-service), respectively. +To this end, it provides commands for the up- and download of files that interact with the RESTful APIs exposed +by the Upload Controller Service (https://github.com/ghga-de/upload-controller-service) and Download Controller Service (https://github.com/ghga-de/download-controller-service), respectively. -When uploading, the Connector expects an unencrypted file that is subsequently encrypted according to the Crypt4GH standard (https://www.ga4gh.org/news_item/crypt4gh-a-secure-method-for-sharing-human-genetic-data/) and only afterwards uploaded to the GHGA storage infrastructure. +When uploading, the Connector expects an unencrypted file that is subsequently encrypted according to the Crypt4 +GH standard (https://www.ga4gh.org/news_item/crypt4gh-a-secure-method-for-sharing-human-genetic-data/) and only afterwards uploaded to the GHGA storage infrastructure. When downloading, the resulting file is still encrypted in this manner and can be decrypted using the Connector's decrypt command. As the user is expected to download multiple files, this command takes a directory location as input and an optional output directory location can be provided, creating the directory if it does not yet exist (defaulting to the current working directory, if none is provided). @@ -22,20 +21,19 @@ Most of the commands need the submitter's private key that matches the public ke The private key is used for file encryption in the upload path and decryption of the work package access and work order tokens during download. Additionally, the decrypt command needs the private key to decrypt the downloaded file. - ## Installation We recommend using the provided Docker container. A pre-build version is available at [docker hub](https://hub.docker.com/repository/docker/ghga/ghga-connector): ```bash -docker pull ghga/ghga-connector:1.1.2 +docker pull ghga/ghga-connector:1.2.0 ``` Or you can build the container yourself from the [`./Dockerfile`](./Dockerfile): ```bash # Execute in the repo's root dir: -docker build -t ghga/ghga-connector:1.1.2 . +docker build -t ghga/ghga-connector:1.2.0 . ``` For production-ready deployment, we recommend using Kubernetes, however, @@ -43,7 +41,7 @@ for simple use cases, you could execute the service using docker on a single server: ```bash # The entrypoint is preconfigured: -docker run -p 8080:8080 ghga/ghga-connector:1.1.2 --help +docker run -p 8080:8080 ghga/ghga-connector:1.2.0 --help ``` If you prefer not to use containers, you may install the service from source: @@ -96,10 +94,6 @@ of the pydantic documentation. ## Architecture and Design: - - This is a Python-based client enabling interaction with GHGA's file services. Contrary to the design of the actual services, the client does not follow the triple-hexagonal architecture. The client is roughly structured into three parts: @@ -108,7 +102,6 @@ The client is roughly structured into three parts: 2. Functionality dealing with intermediate transformations, delegating work and handling state is provided within the core module. 3. core.api_calls provides abstractions over S3 and work package service interactions. - ## Development For setting up the development environment, we rely on the diff --git a/lock/README.md b/lock/README.md new file mode 100644 index 00000000..fc255b55 --- /dev/null +++ b/lock/README.md @@ -0,0 +1,56 @@ + + +# Lock Files + +This directory contains two lock files locking the dependencies of this microservice: + +The [`./requirements.txt`](./requirements.txt) contains production dependencies. + +The [`./requirements-dev.txt`](./requirements-dev.txt) additionally contains development +dependencies. + +## Sources + +For generating the production lock file, only the dependencies specified in the +[`../pyproject.toml`](../pyproject.toml) are considered as input. + +For generating the development lock file, additionally, the +[`./requirements-dev-template.in`](./requirements-dev-template.in) as well as +the [`./requirements-dev.in`](./requirements-dev.in) are considered. + +The `./requirements-dev-template.in` is automatically updated from the template +repository and should not be manually modified. + +If you require additional dev dependencies not part of the +`./requirements-dev-template.in`, you can add them to the +`./requirements-dev.in`. + +## Update and Upgrade + +The lock files can be updated running the +[`../scripts/update_lock.py`](../scripts/update_lock.py) script. This will keep the +dependency versions in the lockfile unchanged unless they are in conflict with the +the input sources. In that case, the affected dependencies are updated to the latest +versions compatible with the input. + +If you would like to upgrade all dependencies in the lock file to the latest versions +compatible with the input, you can run `../scripts/update_lock.py --upgrade`. + +If you just want to check if the script would do update, you can run +`../scripts/update_lock.py --check`. diff --git a/requirements-dev-common.in b/lock/requirements-dev-template.in similarity index 100% rename from requirements-dev-common.in rename to lock/requirements-dev-template.in diff --git a/lock/requirements-dev.in b/lock/requirements-dev.in new file mode 100644 index 00000000..4d48a8fd --- /dev/null +++ b/lock/requirements-dev.in @@ -0,0 +1,7 @@ +# requirements for development and testing this service + +# template requirements for development and testing +-r requirements-dev-template.in + +# additional requirements can be listed here +testcontainers[kafka,mongo]>=3.4.1 diff --git a/requirements-dev.txt b/lock/requirements-dev.txt similarity index 88% rename from requirements-dev.txt rename to lock/requirements-dev.txt index e421b2bc..337d1cfc 100644 --- a/requirements-dev.txt +++ b/lock/requirements-dev.txt @@ -2,7 +2,7 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --generate-hashes --output-file=/workspace/requirements-dev.txt /tmp/tmphk1abqaq/pyproject.toml /workspace/requirements-dev.in +# pip-compile --generate-hashes --output-file=/workspace/lock/requirements-dev.txt /tmp/tmpmn8w1gjh/pyproject.toml /workspace/lock/requirements-dev.in # annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ @@ -45,13 +45,13 @@ bcrypt==4.1.2 \ --hash=sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7 \ --hash=sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369 # via crypt4gh -boto3==1.34.17 \ - --hash=sha256:1efc02be786884034d503d59c018cf7650d0cff9fcb37cd2eb49b802a6fe6111 \ - --hash=sha256:8ca248cc84e7e859e4e276eb9c4309fa01a3e58473bf48d6c33448be870c2bb8 +boto3==1.34.19 \ + --hash=sha256:4c76ef92af7dbdcea21b196a2699671e82e8814d4cfe570c48eda477dd1aeb19 \ + --hash=sha256:95d2c2bde86a0934d4c461020c50fc1344b444f167654e215f1de549bc77fc0f # via hexkit -botocore==1.34.17 \ - --hash=sha256:7272c39032c6f1d62781e4c8445d9a1d9140c2bf52ba7ee66bf6db559c4b2427 \ - --hash=sha256:e48a662f3a6919219276b55085e8f73c3347966675f55e9d448be30cf79678ee +botocore==1.34.19 \ + --hash=sha256:64352b2f05de5c6ab025c1d5232880c22775356dcc5a53d798a6f65db847e826 \ + --hash=sha256:a4a39c7092960f5da2439efc5f6220730dab634aaff4c1444bbd1dfa43bc28cc # via # boto3 # hexkit @@ -223,7 +223,7 @@ click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # pip-tools # typer # uvicorn @@ -312,78 +312,6 @@ cryptography==41.0.7 \ --hash=sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7 \ --hash=sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d # via crypt4gh -dependency-injector==4.41.0 \ - --hash=sha256:02620454ee8101f77a317f3229935ce687480883d72a40858ff4b0c87c935cce \ - --hash=sha256:059fbb48333148143e8667a5323d162628dfe27c386bd0ed3deeecfc390338bf \ - --hash=sha256:05e15ea0f2b14c1127e8b0d1597fef13f98845679f63bf670ba12dbfc12a16ef \ - --hash=sha256:12e91ac0333e7e589421943ff6c6bf9cf0d9ac9703301cec37ccff3723406332 \ - --hash=sha256:1662e2ef60ac6e681b9e11b5d8b7c17a0f733688916cf695f9540f8f50a61b1e \ - --hash=sha256:168334cba3f1cbf55299ef38f0f2e31879115cc767b780c859f7814a52d80abb \ - --hash=sha256:16de2797dcfcc2263b8672bf0751166f7c7b369ca2ff9246ceb67b65f8e1d802 \ - --hash=sha256:1baee908f21190bdc46a65ce4c417a5175e9397ca62354928694fce218f84487 \ - --hash=sha256:22b11dbf696e184f0b3d5ac4e5418aeac3c379ba4ea758c04a83869b7e5d1cbf \ - --hash=sha256:300838e9d4f3fbf539892a5a4072851728e23b37a1f467afcf393edd994d88f0 \ - --hash=sha256:3055b3fc47a0d6e5f27defb4166c0d37543a4967c279549b154afaf506ce6efc \ - --hash=sha256:33a724e0a737baadb4378f5dc1b079867cc3a88552fcca719b3dba84716828b2 \ - --hash=sha256:3535d06416251715b45f8412482b58ec1c6196a4a3baa207f947f0b03a7c4b44 \ - --hash=sha256:3588bd887b051d16b8bcabaae1127eb14059a0719a8fe34c8a75ba59321b352c \ - --hash=sha256:3744c327d18408e74781bd6d8b7738745ee80ef89f2c8daecf9ebd098cb84972 \ - --hash=sha256:37d5954026e3831663518d78bdf4be9c2dbfea691edcb73c813aa3093aa4363a \ - --hash=sha256:40936d9384363331910abd59dd244158ec3572abf9d37322f15095315ac99893 \ - --hash=sha256:409441122f40e1b4b8582845fdd76deb9dc5c9d6eb74a057b85736ef9e9c671f \ - --hash=sha256:48b6886a87b4ceb9b9f78550f77b2a5c7d2ce33bc83efd886556ad468cc9c85a \ - --hash=sha256:4a31d9d60be4b585585081109480cfb2ef564d3b851cb32a139bf8408411a93a \ - --hash=sha256:4a44ca3ce5867513a70b31855b218be3d251f5068ce1c480cc3a4ad24ffd3280 \ - --hash=sha256:51217cb384b468d7cc355544cec20774859f00812f9a1a71ed7fa701c957b2a7 \ - --hash=sha256:5168dc59808317dc4cdd235aa5d7d556d33e5600156acaf224cead236b48a3e8 \ - --hash=sha256:54032d62610cf2f4421c9d92cef52957215aaa0bca403cda580c58eb3f726eda \ - --hash=sha256:56d37b9d2f50a18f059d9abdbea7669a7518bd42b81603c21a27910a2b3f1657 \ - --hash=sha256:586a0821720b15932addbefb00f7370fbcd5831d6ebbd6494d774b44ff96d23a \ - --hash=sha256:5fa3ed8f0700e47a0e7363f949b4525ffa8277aa1c5b10ca5b41fce4dea61bb9 \ - --hash=sha256:63bfba21f8bff654a80e9b9d06dd6c43a442990b73bf89cd471314c11c541ec2 \ - --hash=sha256:67b369592c57549ccdcad0d5fef1ddb9d39af7fed8083d76e789ab0111fc6389 \ - --hash=sha256:6b29abac56ce347d2eb58a560723e1663ee2125cf5cc38866ed92b84319927ec \ - --hash=sha256:6b98945edae88e777091bf0848f869fb94bd76dfa4066d7c870a5caa933391d0 \ - --hash=sha256:6ee9810841c6e0599356cb884d16453bfca6ab739d0e4f0248724ed8f9ee0d79 \ - --hash=sha256:740a8e8106a04d3f44b52b25b80570fdac96a8a3934423de7c9202c5623e7936 \ - --hash=sha256:75280dfa23f7c88e1bf56c3920d58a43516816de6f6ab2a6650bb8a0f27d5c2c \ - --hash=sha256:75e7a733b372db3144a34020c4233f6b94db2c6342d6d16bc5245b1b941ee2bd \ - --hash=sha256:76b94c8310929e54136f3cb3de3adc86d1a657b3984299f40bf1cd2ba0bae548 \ - --hash=sha256:786f7aac592e191c9caafc47732161d807bad65c62f260cd84cd73c7e2d67d6d \ - --hash=sha256:7a92680bea1c260e5c0d2d6cd60b0c913cba76a456a147db5ac047ecfcfcc758 \ - --hash=sha256:7dcba8665cafec825b7095d5dd80afb5cf14404450eca3fe8b66e1edbf4dbc10 \ - --hash=sha256:7fa4970f12a3fc95d8796938b11c41276ad1ff4c447b0e589212eab3fc527a90 \ - --hash=sha256:87be84084a1b922c4ba15e2e5aa900ee24b78a5467997cb7aec0a1d6cdb4a00b \ - --hash=sha256:89c67edffe7007cf33cee79ecbca38f48efcc2add5c280717af434db6c789377 \ - --hash=sha256:8b51efeaebacaf79ef68edfc65e9687699ccffb3538c4a3ab30d0d77e2db7189 \ - --hash=sha256:8b8cf1c6c56f5c18bdbd9f5e93b52ca29cb4d99606d4056e91f0c761eef496dc \ - --hash=sha256:8d670a844268dcd758195e58e9a5b39fc74bb8648aba99a13135a4a10ec9cfac \ - --hash=sha256:8f0090ff14038f17a026ca408a3a0b0e7affb6aa7498b2b59d670f40ac970fbe \ - --hash=sha256:939dfc657104bc3e66b67afd3fb2ebb0850c9a1e73d0d26066f2bbdd8735ff9c \ - --hash=sha256:953bfac819d32dc72b963767589e0ed372e5e9e78b03fb6b89419d0500d34bbe \ - --hash=sha256:99ed73b1521bf249e2823a08a730c9f9413a58f4b4290da022e0ad4fb333ba3d \ - --hash=sha256:9e3b9d41e0eff4c8e16fea1e33de66ff0030fe51137ca530f3c52ce110447914 \ - --hash=sha256:a2381a251b04244125148298212550750e6e1403e9b2850cc62e0e829d050ad3 \ - --hash=sha256:a2dee5d4abdd21f1a30a51d46645c095be9dcc404c7c6e9f81d0a01415a49e64 \ - --hash=sha256:a4f113e5d4c3070973ad76e5bda7317e500abae6083d78689f0b6e37cf403abf \ - --hash=sha256:a8686fa330c83251c75c8238697686f7a0e0f6d40658538089165dc72df9bcff \ - --hash=sha256:ac79f3c05747f9724bd56c06985e78331fc6c85eb50f3e3f1a35e0c60f9977e9 \ - --hash=sha256:b0c9c966ff66c77364a2d43d08de9968aff7e3903938fe912ba49796b2133344 \ - --hash=sha256:b2440b32474d4e747209528ca3ae48f42563b2fbe3d74dbfe949c11dfbfef7c4 \ - --hash=sha256:b365a8548e9a49049fa6acb24d3cd939f619eeb8e300ca3e156e44402dcc07ec \ - --hash=sha256:b37f36ecb0c1227f697e1d4a029644e3eda8dd0f0716aa63ad04d96dbb15bbbb \ - --hash=sha256:b3890a12423ae3a9eade035093beba487f8d092ee6c6cb8706f4e7080a56e819 \ - --hash=sha256:b8b61a15bc46a3aa7b29bd8a7384b650aa3a7ef943491e93c49a0540a0b3dda4 \ - --hash=sha256:bc852da612c7e347f2fcf921df2eca2718697a49f648a28a63db3ab504fd9510 \ - --hash=sha256:c71d30b6708438050675f338edb9a25bea6c258478dbe5ec8405286756a2d347 \ - --hash=sha256:d03f5fa0fa98a18bd0dfce846db80e2798607f0b861f1f99c97f441f7669d7a2 \ - --hash=sha256:d09c08c944a25dabfb454238c1a889acd85102b93ae497de523bf9ab7947b28a \ - --hash=sha256:d283aee588a72072439e6721cb64aa6cba5bc18c576ef0ab28285a6ec7a9d655 \ - --hash=sha256:d557e40673de984f78dab13ebd68d27fbb2f16d7c4e3b663ea2fa2f9fae6765b \ - --hash=sha256:e3229d83e99e255451605d5276604386e06ad948e3d60f31ddd796781c77f76f \ - --hash=sha256:f2842e15bae664a9f69932e922b02afa055c91efec959cb1896f6c499bf68180 \ - --hash=sha256:f89a507e389b7e4d4892dd9a6f5f4da25849e24f73275478634ac594d621ab3f - # via hexkit deprecation==2.1.0 \ --hash=sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff \ --hash=sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a @@ -392,6 +320,10 @@ distlib==0.3.8 \ --hash=sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784 \ --hash=sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64 # via virtualenv +dnspython==2.4.2 \ + --hash=sha256:57c6fbaaeaaf39c891292012060beb141791735dbb4004798328fc2c467402d8 \ + --hash=sha256:8dcfae8c7460a2f84b4072e26f1c9f4101ca20c071649cb7c34e8b6a93d58984 + # via pymongo docker==7.0.0 \ --hash=sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b \ --hash=sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3 @@ -413,9 +345,9 @@ filelock==3.13.1 \ --hash=sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e \ --hash=sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c # via virtualenv -ghga-service-commons[api,crypt]==1.1.1 \ - --hash=sha256:265a48fced8c2a77f48c8c1306f3b93522b943574524e72fdafe268116bf924f \ - --hash=sha256:3be28881ca52fb6b50f3ca78bf32f55405cc0c1d072c7eb1c2e7c1f9db88936a +ghga-service-commons[api,crypt,objectstorage]==2.0.0 \ + --hash=sha256:56b91fdff152715cbb4649e9deb683a03fcac3cbca1021374a3e2877da944b69 \ + --hash=sha256:c552c884cb3fc6d810b81bd900bd9f43f096a6c3f7bdd9ecdda6e94a7e92aa01 # via # ghga-service-commons # ghga_connector (pyproject.toml) @@ -429,12 +361,13 @@ h11==0.14.0 \ # via # httpcore # uvicorn -hexkit[s3]==1.0.0 \ - --hash=sha256:767e9cda5433f8e0c74e8f0b0376dccbfee8db1efecd2dc75e3f2b841dc99c60 \ - --hash=sha256:a88afb9d8ff9c1672fe81a233501b2ae369e155b72aae46ff5ae83f7bb252b6b +hexkit[s3]==2.0.0 \ + --hash=sha256:baaaa7af9634e2438591e6fe78b0192f850659045797235a9faab8f6b63b583a \ + --hash=sha256:cae4b5b58edfd5f79576ac6385c377cc95bf07621a3486b29b360358e045f9cc # via - # -r /workspace/requirements-dev.in + # ghga-service-commons # ghga_connector (pyproject.toml) + # hexkit httpcore==1.0.2 \ --hash=sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7 \ --hash=sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535 @@ -481,7 +414,7 @@ httpx==0.25.2 \ --hash=sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8 \ --hash=sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118 # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # ghga-service-commons # pytest-httpx identify==2.5.33 \ @@ -512,7 +445,11 @@ jmespath==1.0.1 \ jsonschema2md==1.1.0 \ --hash=sha256:2386fc4d119330686db3989ea497ab96a4defb6388386fc0ceff756b5c1a66a7 \ --hash=sha256:e89edf2de1bc7fc3e842915c7c29b7b70888555a87002eccc06350c0412a1458 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in +kafka-python==2.0.2 \ + --hash=sha256:04dfe7fea2b63726cd6f3e79a2d86e709d608d74406638c5da33a01d45a9d7e3 \ + --hash=sha256:2d92418c7cb1c298fa6c7f0fb3519b520d0d7526ac6cb7ae2a4fc65a51a94b6e + # via testcontainers mypy==1.8.0 \ --hash=sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6 \ --hash=sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d \ @@ -541,12 +478,12 @@ mypy==1.8.0 \ --hash=sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4 \ --hash=sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410 \ --hash=sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in mypy-extensions==1.0.0 \ --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # mypy nodeenv==1.8.0 \ --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ @@ -563,7 +500,7 @@ packaging==23.2 \ pip-tools==7.3.0 \ --hash=sha256:8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e \ --hash=sha256:8e9c99127fe024c025b46a0b2d15c7bd47f18f33226cf7330d35493663fc1d1d - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in platformdirs==4.1.0 \ --hash=sha256:11c8f37bcca40db96d8144522d925583bdb7a31f7b0e37e3ed4318400a8e2380 \ --hash=sha256:906d548203468492d432bcb294d4bc2fff751bf84971fbb2c10918cc206ee420 @@ -575,7 +512,7 @@ pluggy==1.3.0 \ pre-commit==3.6.0 \ --hash=sha256:c255039ef399049a5544b6ce13d135caba8f2c28c3b4033277a788f434308376 \ --hash=sha256:d30bad9abf165f7785c15a21a1f46da7d0677cb00ee7ff4c579fd38922efe15d - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 @@ -699,6 +636,90 @@ pydantic-settings==2.1.0 \ --hash=sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c \ --hash=sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a # via hexkit +pymongo==4.6.1 \ + --hash=sha256:00c199e1c593e2c8b033136d7a08f0c376452bac8a896c923fcd6f419e07bdd2 \ + --hash=sha256:010bc9aa90fd06e5cc52c8fac2c2fd4ef1b5f990d9638548dde178005770a5e8 \ + --hash=sha256:026a24a36394dc8930cbcb1d19d5eb35205ef3c838a7e619e04bd170713972e7 \ + --hash=sha256:061598cbc6abe2f382ab64c9caa83faa2f4c51256f732cdd890bcc6e63bfb67e \ + --hash=sha256:13552ca505366df74e3e2f0a4f27c363928f3dff0eef9f281eb81af7f29bc3c5 \ + --hash=sha256:13d613c866f9f07d51180f9a7da54ef491d130f169e999c27e7633abe8619ec9 \ + --hash=sha256:144a31391a39a390efce0c5ebcaf4bf112114af4384c90163f402cec5ede476b \ + --hash=sha256:1461199b07903fc1424709efafe379205bf5f738144b1a50a08b0396357b5abf \ + --hash=sha256:154b361dcb358ad377d5d40df41ee35f1cc14c8691b50511547c12404f89b5cb \ + --hash=sha256:1c5654bb8bb2bdb10e7a0bc3c193dd8b49a960b9eebc4381ff5a2043f4c3c441 \ + --hash=sha256:1de3c6faf948f3edd4e738abdb4b76572b4f4fdfc1fed4dad02427e70c5a6219 \ + --hash=sha256:1ed23b0e2dac6f84f44c8494fbceefe6eb5c35db5c1099f56ab78fc0d94ab3af \ + --hash=sha256:1f2b856518bfcfa316c8dae3d7b412aecacf2e8ba30b149f5eb3b63128d703b9 \ + --hash=sha256:2346450a075625c4d6166b40a013b605a38b6b6168ce2232b192a37fb200d588 \ + --hash=sha256:262356ea5fcb13d35fb2ab6009d3927bafb9504ef02339338634fffd8a9f1ae4 \ + --hash=sha256:27b81ecf18031998ad7db53b960d1347f8f29e8b7cb5ea7b4394726468e4295e \ + --hash=sha256:2940aa20e9cc328e8ddeacea8b9a6f5ddafe0b087fedad928912e787c65b4909 \ + --hash=sha256:2d4ccac3053b84a09251da8f5350bb684cbbf8c8c01eda6b5418417d0a8ab198 \ + --hash=sha256:2dd2f6960ee3c9360bed7fb3c678be0ca2d00f877068556785ec2eb6b73d2414 \ + --hash=sha256:3071ec998cc3d7b4944377e5f1217c2c44b811fae16f9a495c7a1ce9b42fb038 \ + --hash=sha256:3094c7d2f820eecabadae76bfec02669567bbdd1730eabce10a5764778564f7b \ + --hash=sha256:30b2c9caf3e55c2e323565d1f3b7e7881ab87db16997dc0cbca7c52885ed2347 \ + --hash=sha256:3177f783ae7e08aaf7b2802e0df4e4b13903520e8380915e6337cdc7a6ff01d8 \ + --hash=sha256:31dab1f3e1d0cdd57e8df01b645f52d43cc1b653ed3afd535d2891f4fc4f9712 \ + --hash=sha256:33bb16a07d3cc4e0aea37b242097cd5f7a156312012455c2fa8ca396953b11c4 \ + --hash=sha256:349093675a2d3759e4fb42b596afffa2b2518c890492563d7905fac503b20daa \ + --hash=sha256:39d77d8bbb392fa443831e6d4ae534237b1f4eee6aa186f0cdb4e334ba89536e \ + --hash=sha256:3a7f02a58a0c2912734105e05dedbee4f7507e6f1bd132ebad520be0b11d46fd \ + --hash=sha256:3b287e814a01deddb59b88549c1e0c87cefacd798d4afc0c8bd6042d1c3d48aa \ + --hash=sha256:3c74f4725485f0a7a3862cfd374cc1b740cebe4c133e0c1425984bcdcce0f4bb \ + --hash=sha256:3cadf7f4c8e94d8a77874b54a63c80af01f4d48c4b669c8b6867f86a07ba994f \ + --hash=sha256:3d18a9b9b858ee140c15c5bfcb3e66e47e2a70a03272c2e72adda2482f76a6ad \ + --hash=sha256:3f0e6a6c807fa887a0c51cc24fe7ea51bb9e496fe88f00d7930063372c3664c3 \ + --hash=sha256:4344c30025210b9fa80ec257b0e0aab5aa1d5cca91daa70d82ab97b482cc038e \ + --hash=sha256:4497d49d785482cc1a44a0ddf8830b036a468c088e72a05217f5b60a9e025012 \ + --hash=sha256:547dc5d7f834b1deefda51aedb11a7af9c51c45e689e44e14aa85d44147c7657 \ + --hash=sha256:5556e306713e2522e460287615d26c0af0fe5ed9d4f431dad35c6624c5d277e9 \ + --hash=sha256:55dac73316e7e8c2616ba2e6f62b750918e9e0ae0b2053699d66ca27a7790105 \ + --hash=sha256:56816e43c92c2fa8c11dc2a686f0ca248bea7902f4a067fa6cbc77853b0f041e \ + --hash=sha256:5bd94c503271e79917b27c6e77f7c5474da6930b3fb9e70a12e68c2dff386b9a \ + --hash=sha256:5ec31adc2e988fd7db3ab509954791bbc5a452a03c85e45b804b4bfc31fa221d \ + --hash=sha256:69247f7a2835fc0984bbf0892e6022e9a36aec70e187fcfe6cae6a373eb8c4de \ + --hash=sha256:6a0ae7a48a6ef82ceb98a366948874834b86c84e288dbd55600c1abfc3ac1d88 \ + --hash=sha256:6a1810c2cbde714decf40f811d1edc0dae45506eb37298fd9d4247b8801509fe \ + --hash=sha256:6dcc95f4bb9ed793714b43f4f23a7b0c57e4ef47414162297d6f650213512c19 \ + --hash=sha256:76013fef1c9cd1cd00d55efde516c154aa169f2bf059b197c263a255ba8a9ddf \ + --hash=sha256:77e0df59b1a4994ad30c6d746992ae887f9756a43fc25dec2db515d94cf0222d \ + --hash=sha256:7bb0e9049e81def6829d09558ad12d16d0454c26cabe6efc3658e544460688d9 \ + --hash=sha256:88beb444fb438385e53dc9110852910ec2a22f0eab7dd489e827038fdc19ed8d \ + --hash=sha256:8b47ebd89e69fbf33d1c2df79759d7162fc80c7652dacfec136dae1c9b3afac7 \ + --hash=sha256:8d219b4508f71d762368caec1fc180960569766049bbc4d38174f05e8ef2fe5b \ + --hash=sha256:8ec75f35f62571a43e31e7bd11749d974c1b5cd5ea4a8388725d579263c0fdf6 \ + --hash=sha256:9167e735379ec43d8eafa3fd675bfbb12e2c0464f98960586e9447d2cf2c7a83 \ + --hash=sha256:9a710c184ba845afb05a6f876edac8f27783ba70e52d5eaf939f121fc13b2f59 \ + --hash=sha256:9aafd036f6f2e5ad109aec92f8dbfcbe76cff16bad683eb6dd18013739c0b3ae \ + --hash=sha256:9c79d597fb3a7c93d7c26924db7497eba06d58f88f58e586aa69b2ad89fee0f8 \ + --hash=sha256:a2831e05ce0a4df10c4ac5399ef50b9a621f90894c2a4d2945dc5658765514ed \ + --hash=sha256:a5e641f931c5cd95b376fd3c59db52770e17bec2bf86ef16cc83b3906c054845 \ + --hash=sha256:b10d8cda9fc2fcdcfa4a000aa10413a2bf8b575852cd07cb8a595ed09689ca98 \ + --hash=sha256:b435b13bb8e36be11b75f7384a34eefe487fe87a6267172964628e2b14ecf0a7 \ + --hash=sha256:b7b1a83ce514700276a46af3d9e481ec381f05b64939effc9065afe18456a6b9 \ + --hash=sha256:b8729dbf25eb32ad0dc0b9bd5e6a0d0b7e5c2dc8ec06ad171088e1896b522a74 \ + --hash=sha256:bbed8cccebe1169d45cedf00461b2842652d476d2897fd1c42cf41b635d88746 \ + --hash=sha256:c258dbacfff1224f13576147df16ce3c02024a0d792fd0323ac01bed5d3c545d \ + --hash=sha256:c30a9e06041fbd7a7590693ec5e407aa8737ad91912a1e70176aff92e5c99d20 \ + --hash=sha256:c91ea3915425bd4111cb1b74511cdc56d1d16a683a48bf2a5a96b6a6c0f297f7 \ + --hash=sha256:d0355cff58a4ed6d5e5f6b9c3693f52de0784aa0c17119394e2a8e376ce489d4 \ + --hash=sha256:d483793a384c550c2d12cb794ede294d303b42beff75f3b3081f57196660edaf \ + --hash=sha256:d4c2be9760b112b1caf649b4977b81b69893d75aa86caf4f0f398447be871f3c \ + --hash=sha256:d8e62d06e90f60ea2a3d463ae51401475568b995bafaffd81767d208d84d7bb1 \ + --hash=sha256:da08ea09eefa6b960c2dd9a68ec47949235485c623621eb1d6c02b46765322ac \ + --hash=sha256:dd1fa413f8b9ba30140de198e4f408ffbba6396864c7554e0867aa7363eb58b2 \ + --hash=sha256:e2aced6fb2f5261b47d267cb40060b73b6527e64afe54f6497844c9affed5fd0 \ + --hash=sha256:e438417ce1dc5b758742e12661d800482200b042d03512a8f31f6aaa9137ad40 \ + --hash=sha256:e470fa4bace5f50076c32f4b3cc182b31303b4fefb9b87f990144515d572820b \ + --hash=sha256:eaf2f65190c506def2581219572b9c70b8250615dc918b3b7c218361a51ec42e \ + --hash=sha256:ef102a67ede70e1721fe27f75073b5314911dbb9bc27cde0a1c402a11531e7bd \ + --hash=sha256:ef801027629c5b511cf2ba13b9be29bfee36ae834b2d95d9877818479cdc99ea \ + --hash=sha256:f7acc03a4f1154ba2643edeb13658d08598fe6e490c3dd96a241b94f09801626 \ + --hash=sha256:f9756f1d25454ba6a3c2f1ef8b7ddec23e5cdeae3dc3c3377243ae37a383db00 \ + --hash=sha256:ff62ba8ff70f01ab4fe0ae36b2cb0b5d1f42e73dfc81ddf0758cd9f77331ad25 \ + --hash=sha256:ff925f1cca42e933376d09ddc254598f8c5fcd36efc5cac0118bb36c36217c41 + # via testcontainers pynacl==1.5.0 \ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ --hash=sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d \ @@ -721,7 +742,7 @@ pytest==7.4.4 \ --hash=sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280 \ --hash=sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8 # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # pytest-asyncio # pytest-cov # pytest-httpx @@ -729,19 +750,19 @@ pytest==7.4.4 \ pytest-asyncio==0.23.3 \ --hash=sha256:37a9d912e8338ee7b4a3e917381d1c95bfc8682048cb0fbc35baba316ec1faba \ --hash=sha256:af313ce900a62fbe2b1aed18e37ad757f1ef9940c6b6a88e2954de38d6b1fb9f - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in pytest-cov==4.1.0 \ --hash=sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6 \ --hash=sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in pytest-httpx==0.27.0 \ --hash=sha256:24f6f53d507ab483bea8f89b975a1a111fb613ccab4d86e570be8991776e8bcc \ --hash=sha256:a33c4e8df415cc1232b3664869b6a8b8061c4c223335aca0b237cefbc01ba0eb - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in pytest-profiling==1.7.0 \ --hash=sha256:93938f147662225d2b8bd5af89587b979652426a8a6ffd7e73ec4a23e24b7f29 \ --hash=sha256:999cc9ac94f2e528e3f5d43465da277429984a1c237ae9818f8cfd0b06acb019 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in python-dateutil==2.8.2 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 @@ -813,7 +834,7 @@ requests==2.31.0 \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # docker ruff==0.1.13 \ --hash=sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6 \ @@ -833,7 +854,7 @@ ruff==0.1.13 \ --hash=sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7 \ --hash=sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e \ --hash=sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in s3transfer==0.10.0 \ --hash=sha256:3cdb40f5cfa6966e812209d0994f2a4709b561c88e90cf00c2696d2df4e56b2e \ --hash=sha256:d0c8bbf672d5eebbe4e57945e23b972d963f07d82f661cabf678a5c88831595b @@ -842,13 +863,12 @@ six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 # via - # dependency-injector # pytest-profiling # python-dateutil snakeviz==2.2.0 \ --hash=sha256:569e2d71c47f80a886aa6e70d6405cb6d30aa3520969ad956b06f824c5f02b8e \ --hash=sha256:7bfd00be7ae147eb4a170a471578e1cd3f41f803238958b6b8efcf2c698a6aa9 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 @@ -861,15 +881,17 @@ starlette==0.27.0 \ # via fastapi stringcase==1.2.0 \ --hash=sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008 - # via -r /workspace/requirements-dev-common.in -testcontainers==3.7.1 \ + # via -r /workspace/lock/requirements-dev-template.in +testcontainers[kafka,mongo]==3.7.1 \ --hash=sha256:7f48cef4bf0ccd78f1a4534d4b701a003a3bace851f24eae58a32f9e3f0aeba0 - # via -r /workspace/requirements-dev.in + # via + # -r /workspace/lock/requirements-dev.in + # testcontainers tomli==2.0.1 \ --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # build # coverage # mypy @@ -879,7 +901,7 @@ tomli==2.0.1 \ tomli-w==1.0.0 \ --hash=sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463 \ --hash=sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9 - # via -r /workspace/requirements-dev-common.in + # via -r /workspace/lock/requirements-dev-template.in tornado==6.4 \ --hash=sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0 \ --hash=sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63 \ @@ -897,7 +919,7 @@ typer==0.9.0 \ --hash=sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2 \ --hash=sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # ghga_connector (pyproject.toml) typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ @@ -914,7 +936,7 @@ urllib3==1.26.18 \ --hash=sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07 \ --hash=sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0 # via - # -r /workspace/requirements-dev-common.in + # -r /workspace/lock/requirements-dev-template.in # botocore # docker # requests diff --git a/requirements.txt b/lock/requirements.txt similarity index 85% rename from requirements.txt rename to lock/requirements.txt index 68333bb1..57594710 100644 --- a/requirements.txt +++ b/lock/requirements.txt @@ -2,19 +2,19 @@ # This file is autogenerated by pip-compile with Python 3.9 # by the following command: # -# pip-compile --constraint=/workspace/requirements-dev.txt --generate-hashes --output-file=/workspace/requirements.txt /tmp/tmphk1abqaq/pyproject.toml +# pip-compile --constraint=/workspace/lock/requirements-dev.txt --generate-hashes --output-file=/workspace/lock/requirements.txt /tmp/tmpmn8w1gjh/pyproject.toml # annotated-types==0.6.0 \ --hash=sha256:0641064de18ba7a25dee8f96403ebc39113d0cb953a01429249d5c7564666a43 \ --hash=sha256:563339e807e53ffd9c267e99fc6d9ea23eb8443c08f112651963e24e22f84a5d # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # pydantic anyio==3.7.1 \ --hash=sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780 \ --hash=sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # fastapi # httpx # starlette @@ -48,13 +48,27 @@ bcrypt==4.1.2 \ --hash=sha256:f70d9c61f9c4ca7d57f3bfe88a5ccf62546ffbadf3681bb1e268d9d2e41c91a7 \ --hash=sha256:fbe188b878313d01b7718390f31528be4010fed1faa798c5a1d0469c9c48c369 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # crypt4gh +boto3==1.34.19 \ + --hash=sha256:4c76ef92af7dbdcea21b196a2699671e82e8814d4cfe570c48eda477dd1aeb19 \ + --hash=sha256:95d2c2bde86a0934d4c461020c50fc1344b444f167654e215f1de549bc77fc0f + # via + # -c /workspace/lock/requirements-dev.txt + # hexkit +botocore==1.34.19 \ + --hash=sha256:64352b2f05de5c6ab025c1d5232880c22775356dcc5a53d798a6f65db847e826 \ + --hash=sha256:a4a39c7092960f5da2439efc5f6220730dab634aaff4c1444bbd1dfa43bc28cc + # via + # -c /workspace/lock/requirements-dev.txt + # boto3 + # hexkit + # s3transfer certifi==2023.11.17 \ --hash=sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1 \ --hash=sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # httpcore # httpx cffi==1.16.0 \ @@ -111,21 +125,21 @@ cffi==1.16.0 \ --hash=sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956 \ --hash=sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # cryptography # pynacl click==8.1.7 \ --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # typer # uvicorn crypt4gh==1.6 \ --hash=sha256:134015d4d1ea469389f6ee2c7036dec58caf91b3fb87cc6e131876080942306a \ --hash=sha256:c44d999e5da84ca0bff00d0381eacfa27855ccbbd2eb0c95ec7b80f31e82860d # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga_connector (pyproject.toml) cryptography==41.0.7 \ --hash=sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960 \ @@ -152,124 +166,52 @@ cryptography==41.0.7 \ --hash=sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7 \ --hash=sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # crypt4gh -dependency-injector==4.41.0 \ - --hash=sha256:02620454ee8101f77a317f3229935ce687480883d72a40858ff4b0c87c935cce \ - --hash=sha256:059fbb48333148143e8667a5323d162628dfe27c386bd0ed3deeecfc390338bf \ - --hash=sha256:05e15ea0f2b14c1127e8b0d1597fef13f98845679f63bf670ba12dbfc12a16ef \ - --hash=sha256:12e91ac0333e7e589421943ff6c6bf9cf0d9ac9703301cec37ccff3723406332 \ - --hash=sha256:1662e2ef60ac6e681b9e11b5d8b7c17a0f733688916cf695f9540f8f50a61b1e \ - --hash=sha256:168334cba3f1cbf55299ef38f0f2e31879115cc767b780c859f7814a52d80abb \ - --hash=sha256:16de2797dcfcc2263b8672bf0751166f7c7b369ca2ff9246ceb67b65f8e1d802 \ - --hash=sha256:1baee908f21190bdc46a65ce4c417a5175e9397ca62354928694fce218f84487 \ - --hash=sha256:22b11dbf696e184f0b3d5ac4e5418aeac3c379ba4ea758c04a83869b7e5d1cbf \ - --hash=sha256:300838e9d4f3fbf539892a5a4072851728e23b37a1f467afcf393edd994d88f0 \ - --hash=sha256:3055b3fc47a0d6e5f27defb4166c0d37543a4967c279549b154afaf506ce6efc \ - --hash=sha256:33a724e0a737baadb4378f5dc1b079867cc3a88552fcca719b3dba84716828b2 \ - --hash=sha256:3535d06416251715b45f8412482b58ec1c6196a4a3baa207f947f0b03a7c4b44 \ - --hash=sha256:3588bd887b051d16b8bcabaae1127eb14059a0719a8fe34c8a75ba59321b352c \ - --hash=sha256:3744c327d18408e74781bd6d8b7738745ee80ef89f2c8daecf9ebd098cb84972 \ - --hash=sha256:37d5954026e3831663518d78bdf4be9c2dbfea691edcb73c813aa3093aa4363a \ - --hash=sha256:40936d9384363331910abd59dd244158ec3572abf9d37322f15095315ac99893 \ - --hash=sha256:409441122f40e1b4b8582845fdd76deb9dc5c9d6eb74a057b85736ef9e9c671f \ - --hash=sha256:48b6886a87b4ceb9b9f78550f77b2a5c7d2ce33bc83efd886556ad468cc9c85a \ - --hash=sha256:4a31d9d60be4b585585081109480cfb2ef564d3b851cb32a139bf8408411a93a \ - --hash=sha256:4a44ca3ce5867513a70b31855b218be3d251f5068ce1c480cc3a4ad24ffd3280 \ - --hash=sha256:51217cb384b468d7cc355544cec20774859f00812f9a1a71ed7fa701c957b2a7 \ - --hash=sha256:5168dc59808317dc4cdd235aa5d7d556d33e5600156acaf224cead236b48a3e8 \ - --hash=sha256:54032d62610cf2f4421c9d92cef52957215aaa0bca403cda580c58eb3f726eda \ - --hash=sha256:56d37b9d2f50a18f059d9abdbea7669a7518bd42b81603c21a27910a2b3f1657 \ - --hash=sha256:586a0821720b15932addbefb00f7370fbcd5831d6ebbd6494d774b44ff96d23a \ - --hash=sha256:5fa3ed8f0700e47a0e7363f949b4525ffa8277aa1c5b10ca5b41fce4dea61bb9 \ - --hash=sha256:63bfba21f8bff654a80e9b9d06dd6c43a442990b73bf89cd471314c11c541ec2 \ - --hash=sha256:67b369592c57549ccdcad0d5fef1ddb9d39af7fed8083d76e789ab0111fc6389 \ - --hash=sha256:6b29abac56ce347d2eb58a560723e1663ee2125cf5cc38866ed92b84319927ec \ - --hash=sha256:6b98945edae88e777091bf0848f869fb94bd76dfa4066d7c870a5caa933391d0 \ - --hash=sha256:6ee9810841c6e0599356cb884d16453bfca6ab739d0e4f0248724ed8f9ee0d79 \ - --hash=sha256:740a8e8106a04d3f44b52b25b80570fdac96a8a3934423de7c9202c5623e7936 \ - --hash=sha256:75280dfa23f7c88e1bf56c3920d58a43516816de6f6ab2a6650bb8a0f27d5c2c \ - --hash=sha256:75e7a733b372db3144a34020c4233f6b94db2c6342d6d16bc5245b1b941ee2bd \ - --hash=sha256:76b94c8310929e54136f3cb3de3adc86d1a657b3984299f40bf1cd2ba0bae548 \ - --hash=sha256:786f7aac592e191c9caafc47732161d807bad65c62f260cd84cd73c7e2d67d6d \ - --hash=sha256:7a92680bea1c260e5c0d2d6cd60b0c913cba76a456a147db5ac047ecfcfcc758 \ - --hash=sha256:7dcba8665cafec825b7095d5dd80afb5cf14404450eca3fe8b66e1edbf4dbc10 \ - --hash=sha256:7fa4970f12a3fc95d8796938b11c41276ad1ff4c447b0e589212eab3fc527a90 \ - --hash=sha256:87be84084a1b922c4ba15e2e5aa900ee24b78a5467997cb7aec0a1d6cdb4a00b \ - --hash=sha256:89c67edffe7007cf33cee79ecbca38f48efcc2add5c280717af434db6c789377 \ - --hash=sha256:8b51efeaebacaf79ef68edfc65e9687699ccffb3538c4a3ab30d0d77e2db7189 \ - --hash=sha256:8b8cf1c6c56f5c18bdbd9f5e93b52ca29cb4d99606d4056e91f0c761eef496dc \ - --hash=sha256:8d670a844268dcd758195e58e9a5b39fc74bb8648aba99a13135a4a10ec9cfac \ - --hash=sha256:8f0090ff14038f17a026ca408a3a0b0e7affb6aa7498b2b59d670f40ac970fbe \ - --hash=sha256:939dfc657104bc3e66b67afd3fb2ebb0850c9a1e73d0d26066f2bbdd8735ff9c \ - --hash=sha256:953bfac819d32dc72b963767589e0ed372e5e9e78b03fb6b89419d0500d34bbe \ - --hash=sha256:99ed73b1521bf249e2823a08a730c9f9413a58f4b4290da022e0ad4fb333ba3d \ - --hash=sha256:9e3b9d41e0eff4c8e16fea1e33de66ff0030fe51137ca530f3c52ce110447914 \ - --hash=sha256:a2381a251b04244125148298212550750e6e1403e9b2850cc62e0e829d050ad3 \ - --hash=sha256:a2dee5d4abdd21f1a30a51d46645c095be9dcc404c7c6e9f81d0a01415a49e64 \ - --hash=sha256:a4f113e5d4c3070973ad76e5bda7317e500abae6083d78689f0b6e37cf403abf \ - --hash=sha256:a8686fa330c83251c75c8238697686f7a0e0f6d40658538089165dc72df9bcff \ - --hash=sha256:ac79f3c05747f9724bd56c06985e78331fc6c85eb50f3e3f1a35e0c60f9977e9 \ - --hash=sha256:b0c9c966ff66c77364a2d43d08de9968aff7e3903938fe912ba49796b2133344 \ - --hash=sha256:b2440b32474d4e747209528ca3ae48f42563b2fbe3d74dbfe949c11dfbfef7c4 \ - --hash=sha256:b365a8548e9a49049fa6acb24d3cd939f619eeb8e300ca3e156e44402dcc07ec \ - --hash=sha256:b37f36ecb0c1227f697e1d4a029644e3eda8dd0f0716aa63ad04d96dbb15bbbb \ - --hash=sha256:b3890a12423ae3a9eade035093beba487f8d092ee6c6cb8706f4e7080a56e819 \ - --hash=sha256:b8b61a15bc46a3aa7b29bd8a7384b650aa3a7ef943491e93c49a0540a0b3dda4 \ - --hash=sha256:bc852da612c7e347f2fcf921df2eca2718697a49f648a28a63db3ab504fd9510 \ - --hash=sha256:c71d30b6708438050675f338edb9a25bea6c258478dbe5ec8405286756a2d347 \ - --hash=sha256:d03f5fa0fa98a18bd0dfce846db80e2798607f0b861f1f99c97f441f7669d7a2 \ - --hash=sha256:d09c08c944a25dabfb454238c1a889acd85102b93ae497de523bf9ab7947b28a \ - --hash=sha256:d283aee588a72072439e6721cb64aa6cba5bc18c576ef0ab28285a6ec7a9d655 \ - --hash=sha256:d557e40673de984f78dab13ebd68d27fbb2f16d7c4e3b663ea2fa2f9fae6765b \ - --hash=sha256:e3229d83e99e255451605d5276604386e06ad948e3d60f31ddd796781c77f76f \ - --hash=sha256:f2842e15bae664a9f69932e922b02afa055c91efec959cb1896f6c499bf68180 \ - --hash=sha256:f89a507e389b7e4d4892dd9a6f5f4da25849e24f73275478634ac594d621ab3f - # via - # -c /workspace/requirements-dev.txt - # hexkit docopt==0.6.2 \ --hash=sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # crypt4gh exceptiongroup==1.2.0 \ --hash=sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14 \ --hash=sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # anyio fastapi==0.104.1 \ --hash=sha256:752dc31160cdbd0436bb93bad51560b57e525cbb1d4bbf6f4904ceee75548241 \ --hash=sha256:e5e4540a7c5e1dcfbbcf5b903c234feddcdcd881f191977a1c5dfd917487e7ae # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga-service-commons -ghga-service-commons[api,crypt]==1.1.1 \ - --hash=sha256:265a48fced8c2a77f48c8c1306f3b93522b943574524e72fdafe268116bf924f \ - --hash=sha256:3be28881ca52fb6b50f3ca78bf32f55405cc0c1d072c7eb1c2e7c1f9db88936a +ghga-service-commons[api,crypt,objectstorage]==2.0.0 \ + --hash=sha256:56b91fdff152715cbb4649e9deb683a03fcac3cbca1021374a3e2877da944b69 \ + --hash=sha256:c552c884cb3fc6d810b81bd900bd9f43f096a6c3f7bdd9ecdda6e94a7e92aa01 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga-service-commons # ghga_connector (pyproject.toml) h11==0.14.0 \ --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # httpcore # uvicorn -hexkit==1.0.0 \ - --hash=sha256:767e9cda5433f8e0c74e8f0b0376dccbfee8db1efecd2dc75e3f2b841dc99c60 \ - --hash=sha256:a88afb9d8ff9c1672fe81a233501b2ae369e155b72aae46ff5ae83f7bb252b6b +hexkit[s3]==2.0.0 \ + --hash=sha256:baaaa7af9634e2438591e6fe78b0192f850659045797235a9faab8f6b63b583a \ + --hash=sha256:cae4b5b58edfd5f79576ac6385c377cc95bf07621a3486b29b360358e045f9cc # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt + # ghga-service-commons # ghga_connector (pyproject.toml) + # hexkit httpcore==1.0.2 \ --hash=sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7 \ --hash=sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # httpx httptools==0.6.1 \ --hash=sha256:00d5d4b68a717765b1fabfd9ca755bd12bf44105eeb806c03d1962acd9b8e563 \ @@ -309,32 +251,39 @@ httptools==0.6.1 \ --hash=sha256:e57997ac7fb7ee43140cc03664de5f268813a481dff6245e0075925adc6aa185 \ --hash=sha256:fe467eb086d80217b7584e61313ebadc8d187a4d95bb62031b7bab4b205c3ba3 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # uvicorn httpx==0.25.2 \ --hash=sha256:8b8fcaa0c8ea7b05edd69a094e63a2094c4efcb48129fb757361bc423c0ad9e8 \ --hash=sha256:a05d3d052d9b2dfce0e3896636467f8a5342fb2b902c819428e1ac65413ca118 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga-service-commons idna==3.6 \ --hash=sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca \ --hash=sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # anyio # httpx +jmespath==1.0.1 \ + --hash=sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980 \ + --hash=sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe + # via + # -c /workspace/lock/requirements-dev.txt + # boto3 + # botocore pycparser==2.21 \ --hash=sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9 \ --hash=sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # cffi pydantic==2.5.3 \ --hash=sha256:b3ef57c62535b0941697cce638c08900d87fcb67e29cfa99e8a68f747f393f7a \ --hash=sha256:d0caf5954bee831b6bfe7e338c32b9e30c85dfe080c843680783ac2b631673b4 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # fastapi # ghga-service-commons # hexkit @@ -446,13 +395,13 @@ pydantic-core==2.14.6 \ --hash=sha256:fd9e98b408384989ea4ab60206b8e100d8687da18b5c813c11e92fd8212a98e0 \ --hash=sha256:ffff855100bc066ff2cd3aa4a60bc9534661816b110f0243e59503ec2df38421 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # pydantic pydantic-settings==2.1.0 \ --hash=sha256:26b1492e0a24755626ac5e6d715e9077ab7ad4fb5f19a8b7ed7011d52f36141c \ --hash=sha256:7621c0cb5d90d1140d2f0ef557bdf03573aac7035948109adf2574770b77605a # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # hexkit pynacl==1.5.0 \ --hash=sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858 \ @@ -466,14 +415,20 @@ pynacl==1.5.0 \ --hash=sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b \ --hash=sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # crypt4gh # ghga-service-commons +python-dateutil==2.8.2 \ + --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ + --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 + # via + # -c /workspace/lock/requirements-dev.txt + # botocore python-dotenv==1.0.0 \ --hash=sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba \ --hash=sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # pydantic-settings # uvicorn pyyaml==6.0.1 \ @@ -528,51 +483,63 @@ pyyaml==6.0.1 \ --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # crypt4gh # hexkit # uvicorn +s3transfer==0.10.0 \ + --hash=sha256:3cdb40f5cfa6966e812209d0994f2a4709b561c88e90cf00c2696d2df4e56b2e \ + --hash=sha256:d0c8bbf672d5eebbe4e57945e23b972d963f07d82f661cabf678a5c88831595b + # via + # -c /workspace/lock/requirements-dev.txt + # boto3 six==1.16.0 \ --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 # via - # -c /workspace/requirements-dev.txt - # dependency-injector + # -c /workspace/lock/requirements-dev.txt + # python-dateutil sniffio==1.3.0 \ --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # anyio # httpx starlette==0.27.0 \ --hash=sha256:6a6b0d042acb8d469a01eba54e9cda6cbd24ac602c4cd016723117d6a7e73b75 \ --hash=sha256:918416370e846586541235ccd38a474c08b80443ed31c578a418e2209b3eef91 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # fastapi typer==0.9.0 \ --hash=sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2 \ --hash=sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga_connector (pyproject.toml) typing-extensions==4.9.0 \ --hash=sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783 \ --hash=sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # fastapi # pydantic # pydantic-core # starlette # typer # uvicorn +urllib3==1.26.18 \ + --hash=sha256:34b97092d7e0a3a8cf7cd10e386f401b3737364026c45e622aa02903dffe0f07 \ + --hash=sha256:f8ecc1bba5667413457c529ab955bf8c67b45db799d159066261719e328580a0 + # via + # -c /workspace/lock/requirements-dev.txt + # botocore uvicorn[standard]==0.23.2 \ --hash=sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53 \ --hash=sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # ghga-service-commons # uvicorn uvloop==0.19.0 \ @@ -608,7 +575,7 @@ uvloop==0.19.0 \ --hash=sha256:e27f100e1ff17f6feeb1f33968bc185bf8ce41ca557deee9d9bbbffeb72030b7 \ --hash=sha256:f467a5fd23b4fc43ed86342641f3936a68ded707f4627622fa3f82a120e18256 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # uvicorn watchfiles==0.21.0 \ --hash=sha256:02b73130687bc3f6bb79d8a170959042eb56eb3a42df3671c79b428cd73f17cc \ @@ -687,7 +654,7 @@ watchfiles==0.21.0 \ --hash=sha256:f564bf68404144ea6b87a78a3f910cc8de216c6b12a4cf0b27718bf4ec38d303 \ --hash=sha256:fd7ac678b92b29ba630d8c842d8ad6c555abda1b9ef044d6cc092dacbfc9719d # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # uvicorn websockets==12.0 \ --hash=sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b \ @@ -763,5 +730,5 @@ websockets==12.0 \ --hash=sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8 \ --hash=sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7 # via - # -c /workspace/requirements-dev.txt + # -c /workspace/lock/requirements-dev.txt # uvicorn diff --git a/pyproject.toml b/pyproject.toml index 55d400b5..d821f93d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,11 +1,10 @@ [build-system] -requires = ["setuptools>=67.7.2"] +requires = [ + "setuptools>=67.7.2", +] build-backend = "setuptools.build_meta" [project] -name = "ghga_connector" -version = "1.1.2" -description = "GHGA Connector - A CLI client application for interacting with the GHGA system." readme = "README.md" authors = [ { name = "German Human Genome Phenome Archive (GHGA)", email = "contact@ghga.de" }, @@ -22,11 +21,14 @@ classifiers = [ "Topic :: Software Development :: Libraries", "Intended Audience :: Developers", ] +name = "ghga_connector" +version = "1.2.0" +description = "GHGA Connector - A CLI client application for interacting with the GHGA system." dependencies = [ "typer~=0.9.0", "crypt4gh>=1.6, <2", - "ghga-service-commons[api, crypt]~=1.1.0", - "hexkit~=1.0.0", + "ghga-service-commons[api, crypt]~=2.0.0", + "hexkit[s3]~=2.0.0", ] [project.license] @@ -39,4 +41,112 @@ Repository = "https://github.com/ghga-de/ghga-connector" ghga-connector = "ghga_connector.__main__:run" [tool.setuptools.packages.find] -where = ["src"] +where = [ + "src", +] + +[tool.ruff] +exclude = [ + ".git", + ".devcontainer", + "__pycache__", + "build", + "dist", +] +ignore = [ + "E", + "W", + "PLW", + "RUF001", + "RUF010", + "RUF012", + "N818", + "B008", + "PLR2004", + "D205", + "D400", + "D401", + "D107", + "D206", + "D300", +] +line-length = 88 +select = [ + "C90", + "F", + "I", + "S", + "B", + "N", + "UP", + "PL", + "RUF", + "SIM", + "D", +] +fixable = [ + "UP", + "I", + "D", +] +src = [ + "src", + "tests", + "examples", + "scripts", +] +target-version = "py39" + +[tool.ruff.mccabe] +max-complexity = 10 + +[tool.ruff.per-file-ignores] +"scripts/*" = [ + "PL", + "S", + "SIM", + "D", +] +"tests/*" = [ + "S", + "SIM", + "PLR", + "B011", +] +".devcontainer/*" = [ + "S", + "SIM", + "D", +] +"examples/*" = [ + "S", + "D", +] +"__init__.py" = [ + "D", +] + +[tool.ruff.pydocstyle] +convention = "pep257" + +[tool.mypy] +disable_error_code = "import" +show_error_codes = true +exclude = [ + "build/lib/", +] +warn_redundant_casts = true +warn_unused_ignores = true +check_untyped_defs = true +no_site_packages = false + +[tool.pytest.ini_options] +minversion = "7.1" +asyncio_mode = "strict" + +[tool.coverage.paths] +source = [ + "src", + "/workspace/src", + "**/lib/python*/site-packages", +] diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index ed67994e..00000000 --- a/pytest.ini +++ /dev/null @@ -1,5 +0,0 @@ -# pytest.ini - -[pytest] -minversion = 7.1 -asyncio_mode = strict diff --git a/requirements-dev.in b/requirements-dev.in deleted file mode 100644 index 3927463c..00000000 --- a/requirements-dev.in +++ /dev/null @@ -1,7 +0,0 @@ -# requirements for development and testing this service - --r requirements-dev-common.in - -# additional requirements can be listed here -testcontainers>=3.4.1 -hexkit[s3]>=0.11.1 diff --git a/scripts/license_checker.py b/scripts/license_checker.py index 5d8be069..b6a718df 100755 --- a/scripts/license_checker.py +++ b/scripts/license_checker.py @@ -64,12 +64,12 @@ ".mypy.ini", ".pytest_cache", ".editorconfig", - ".static_files", - ".static_files_ignore", - ".mandatory_files", - ".mandatory_files_ignore", - ".deprecated_files", - ".deprecated_files_ignore", + ".template/.static_files.txt", + ".template/.static_files_ignore.txt", + ".template/.mandatory_files.txt", + ".template/.mandatory_files_ignore.txt", + ".template/.deprecated_files.txt", + ".template/.deprecated_files_ignore.txt", ] # exclude file by file ending from license header check: diff --git a/scripts/list_outdated_dependencies.py b/scripts/list_outdated_dependencies.py index db91fe05..84e950b3 100755 --- a/scripts/list_outdated_dependencies.py +++ b/scripts/list_outdated_dependencies.py @@ -28,8 +28,9 @@ REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() PYPROJECT_TOML_PATH = REPO_ROOT_DIR / "pyproject.toml" -DEV_DEPS_PATH = REPO_ROOT_DIR / "requirements-dev.in" -LOCK_FILE_PATH = REPO_ROOT_DIR / "requirements-dev.txt" +LOCK_DIR = REPO_ROOT_DIR / "lock" +DEV_DEPS_PATH = LOCK_DIR / "requirements-dev.in" +LOCK_FILE_PATH = LOCK_DIR / "requirements-dev.txt" class OutdatedDep(NamedTuple): @@ -78,7 +79,7 @@ def get_deps_dev() -> list[Requirement]: for line in (line.strip() for line in dev_deps) if line # skip empty lines and not line.startswith("#") # skip comments - and "requirements-dev-common.in" not in line # skip inclusion line + and "requirements-dev-template.in" not in line # skip inclusion line ] return [Requirement(dependency) for dependency in dependencies] diff --git a/scripts/script_utils/fastapi_app_location.py b/scripts/script_utils/fastapi_app_location.py new file mode 100644 index 00000000..b2ddb1d9 --- /dev/null +++ b/scripts/script_utils/fastapi_app_location.py @@ -0,0 +1,23 @@ +# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""Used to define the location of the main FastAPI app object.""" + +# flake8: noqa +# pylint: skip-file + +# Please adapt to package structure: +from my_microservice.api.main import app diff --git a/scripts/update_all.py b/scripts/update_all.py index 78854dfe..f319faef 100755 --- a/scripts/update_all.py +++ b/scripts/update_all.py @@ -19,33 +19,57 @@ """Run all update scripts that are present in the repository in the correct order""" try: - from scripts.update_template_files import main as update_template + from update_template_files import main as update_template except ImportError: - pass + print("update_template_files script not found") else: print("Pulling in updates from template repository") update_template() try: - from scripts.update_config_docs import main as update_config + from update_pyproject import main as update_pyproject except ImportError: - pass + print("update_pyproject script not found") +else: + print("Updating pyproject.toml file") + update_pyproject() + +try: + from update_lock import main as update_lock +except ImportError: + print("update_lock script not found") +else: + print("Upgrading the lock file") + update_lock(upgrade=True) + +try: + from update_hook_revs import main as update_hook_revs +except ImportError: + print("update_hook_revs script not found") +else: + print("Updating config docs") + update_hook_revs() + +try: + from update_config_docs import main as update_config +except ImportError: + print("update_config_docs script not found") else: print("Updating config docs") update_config() try: - from scripts.update_openapi_docs import main as update_openapi + from update_openapi_docs import main as update_openapi except ImportError: - pass + print("update_openapi_docs script not found") else: print("Updating OpenAPI docs") update_openapi() try: - from scripts.update_readme import main as update_readme + from update_readme import main as update_readme except ImportError: - pass + print("update_readme script not found") else: print("Updating README") update_readme() diff --git a/scripts/update_hook_revs.py b/scripts/update_hook_revs.py index 3d653f85..6522cbe6 100755 --- a/scripts/update_hook_revs.py +++ b/scripts/update_hook_revs.py @@ -27,7 +27,7 @@ REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() PRE_COMMIT_CFG_PATH = REPO_ROOT_DIR / ".pre-commit-config.yaml" -LOCK_FILE_PATH = REPO_ROOT_DIR / "requirements-dev.txt" +LOCK_FILE_PATH = REPO_ROOT_DIR / "lock" / "requirements-dev.txt" def make_dependency_dict(requirements: list[Requirement]) -> dict[str, str]: diff --git a/scripts/update_lock.py b/scripts/update_lock.py index 825aade0..98516b88 100755 --- a/scripts/update_lock.py +++ b/scripts/update_lock.py @@ -31,11 +31,12 @@ from script_utils import cli, deps REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() +LOCK_DIR = REPO_ROOT_DIR / "lock" PYPROJECT_TOML_PATH = REPO_ROOT_DIR / "pyproject.toml" -DEV_DEPS_PATH = REPO_ROOT_DIR / "requirements-dev.in" -OUTPUT_LOCK_PATH = REPO_ROOT_DIR / "requirements.txt" -OUTPUT_DEV_LOCK_PATH = REPO_ROOT_DIR / "requirements-dev.txt" +DEV_DEPS_PATH = LOCK_DIR / "requirements-dev.in" +OUTPUT_LOCK_PATH = LOCK_DIR / "requirements.txt" +OUTPUT_DEV_LOCK_PATH = LOCK_DIR / "requirements-dev.txt" def fix_temp_dir_comments(file_path: Path): diff --git a/scripts/update_openapi_docs.py b/scripts/update_openapi_docs.py new file mode 100755 index 00000000..c7c049c4 --- /dev/null +++ b/scripts/update_openapi_docs.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python3 + +# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Updates OpenAPI-based documentation""" + +import sys +from difflib import unified_diff +from pathlib import Path + +import yaml + +from script_utils.cli import echo_failure, echo_success, run +from script_utils.fastapi_app_location import app + +HERE = Path(__file__).parent.resolve() +REPO_ROOT_DIR = HERE.parent +OPENAPI_YAML = REPO_ROOT_DIR / "openapi.yaml" + + +class ValidationError(RuntimeError): + """Raised when validation of OpenAPI documentation fails.""" + + +def get_openapi_spec() -> str: + """Get an OpenAPI spec in YAML format from the main FastAPI app as defined in the + fastapi_app_location.py file. + """ + + openapi_spec = app.openapi() + return yaml.safe_dump(openapi_spec) + + +def update_docs(): + """Update the OpenAPI YAML file located in the repository's root dir.""" + + openapi_spec = get_openapi_spec() + with open(OPENAPI_YAML, "w", encoding="utf-8") as openapi_file: + openapi_file.write(openapi_spec) + + +def print_diff(expected: str, observed: str): + """Print differences between expected and observed files.""" + echo_failure("Differences in OpenAPI YAML:") + for line in unified_diff( + expected.splitlines(keepends=True), + observed.splitlines(keepends=True), + fromfile="expected", + tofile="observed", + ): + print(" ", line.rstrip()) + + +def check_docs(): + """Checks whether the OpenAPI YAML file located in the repository's root dir is up + to date. + + Raises: + ValidationError: if not up to date. + """ + + openapi_expected = get_openapi_spec() + with open(OPENAPI_YAML, encoding="utf-8") as openapi_file: + openapi_observed = openapi_file.read() + + if openapi_expected != openapi_observed: + print_diff(openapi_expected, openapi_observed) + raise ValidationError( + f"The OpenAPI YAML at '{OPENAPI_YAML}' is not up to date." + ) + + +def main(check: bool = False): + """Update or check the OpenAPI documentation.""" + + if check: + try: + check_docs() + except ValidationError as error: + echo_failure(f"Validation failed: {error}") + sys.exit(1) + echo_success("OpenAPI docs are up to date.") + return + + update_docs() + echo_success("Successfully updated the OpenAPI docs.") + + +if __name__ == "__main__": + run(main) diff --git a/scripts/update_pyproject.py b/scripts/update_pyproject.py new file mode 100755 index 00000000..b68d43da --- /dev/null +++ b/scripts/update_pyproject.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 + +# Copyright 2021 - 2023 Universität Tübingen, DKFZ, EMBL, and Universität zu Köln +# for the German Human Genome-Phenome Archive (GHGA) +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +"""A script to update the pyproject.toml.""" + +import sys +from pathlib import Path + +import tomli +import tomli_w + +from script_utils import cli + +REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() +PYPROJECT_GENERATION_DIR = REPO_ROOT_DIR / ".pyproject_generation" + +PYPROJECT_TEMPLATE_PATH = PYPROJECT_GENERATION_DIR / "pyproject_template.toml" +PYPROJECT_CUSTOM_PATH = PYPROJECT_GENERATION_DIR / "pyproject_custom.toml" +PYPROJECT_TOML = REPO_ROOT_DIR / "pyproject.toml" + + +def read_template_pyproject() -> dict[str, object]: + """Read the pyproject_template.toml.""" + with open(PYPROJECT_TEMPLATE_PATH, "rb") as file: + return tomli.load(file) + + +def read_custom_pyproject() -> dict[str, object]: + """Read the pyproject_custom.toml.""" + with open(PYPROJECT_CUSTOM_PATH, "rb") as file: + return tomli.load(file) + + +def read_current_pyproject() -> dict[str, object]: + """Read the current pyproject.toml.""" + with open(PYPROJECT_TOML, "rb") as file: + return tomli.load(file) + + +def write_pyproject(pyproject: dict[str, object]) -> None: + """Write the given pyproject dict into the pyproject.toml.""" + with open(PYPROJECT_TOML, "wb") as file: + tomli_w.dump(pyproject, file) + + +def merge_fields(*, source: dict[str, object], dest: dict[str, object]): + """Merge fields existing in both custom and template pyproject definitions. + + If a given field is a dictionary, merge or assign depending on if it's found in dest. + If the field is anything else either assign the value or exit with a message if a + conflict exists. + """ + for field, value in source.items(): + if isinstance(value, dict): + if field in dest: + merge_fields(source=source[field], dest=dest[field]) # type: ignore + else: + dest[field] = value + else: + if field in dest and value != dest[field]: + cli.echo_failure(f"Conflicting values for '{field}'") + exit(1) + elif field not in dest: + dest[field] = value + + +def merge_pyprojects(inputs: list[dict[str, object]]) -> dict[str, object]: + """Compile a pyproject dict from the provided input dicts.""" + pyproject = inputs[0] + + for input in inputs[1:]: + for field, value in input.items(): + if field not in pyproject: + pyproject[field] = value + else: + merge_fields(source=value, dest=pyproject[field]) # type: ignore + + return pyproject + + +def main(*, check: bool = False): + """Update the pyproject.toml or checks for updates if the check flag is specified.""" + template_pyproject = read_template_pyproject() + custom_pyproject = read_custom_pyproject() + merged_pyproject = merge_pyprojects([template_pyproject, custom_pyproject]) + + if check: + current_pyproject = read_current_pyproject() + + if current_pyproject != merged_pyproject: + cli.echo_failure("The pyproject.toml is not up to date.") + sys.exit(1) + + cli.echo_success("The pyproject.toml is up to date.") + return + + write_pyproject(merged_pyproject) + cli.echo_success("Successfully updated the pyproject.toml.") + + +if __name__ == "__main__": + cli.run(main) diff --git a/scripts/update_readme.py b/scripts/update_readme.py index 244d0ba3..b8273b02 100755 --- a/scripts/update_readme.py +++ b/scripts/update_readme.py @@ -32,9 +32,11 @@ ROOT_DIR = Path(__file__).parent.parent.resolve() PYPROJECT_TOML_PATH = ROOT_DIR / "pyproject.toml" -DESCRIPTION_PATH = ROOT_DIR / ".description.md" -DESIGN_PATH = ROOT_DIR / ".design.md" -README_TEMPLATE_PATH = ROOT_DIR / ".readme_template.md" +README_GENERATION_DIR = ROOT_DIR / ".readme_generation" +TEMPLATE_OVERVIEW_PATH = README_GENERATION_DIR / "template_overview.md" +DESCRIPTION_PATH = README_GENERATION_DIR / "description.md" +DESIGN_PATH = README_GENERATION_DIR / "design.md" +README_TEMPLATE_PATH = README_GENERATION_DIR / "readme_template.md" CONFIG_SCHEMA_PATH = ROOT_DIR / "config_schema.json" OPENAPI_YAML_REL_PATH = "./openapi.yaml" README_PATH = ROOT_DIR / "README.md" @@ -58,6 +60,7 @@ class PackageHeader(BaseModel): class PackageName(BaseModel): """The name of a package and it's different representations.""" + repo_name: str = Field(..., description="The name of the repo") name: str = Field(..., description="The full name of the package in spinal case.") title: str = Field(..., description="The name of the package formatted as title.") @@ -118,9 +121,21 @@ def read_package_name() -> PackageName: raise RuntimeError("The name of the git origin could not be resolved.") git_origin_name = stdout.decode("utf-8").strip() - return PackageName( - name=spinalcase(git_origin_name), title=titlecase(git_origin_name) + repo_name = spinalcase(git_origin_name) + name = ( + "my-microservice" + if repo_name == "microservice-repository-template" + else repo_name ) + title = titlecase(name) + + return PackageName(repo_name=repo_name, name=name, title=title) + + +def read_template_overview() -> str: + """Read the template_overview.""" + + return TEMPLATE_OVERVIEW_PATH.read_text() def read_package_description() -> str: @@ -204,6 +219,10 @@ def main(check: bool = False) -> None: details = get_package_details() readme_content = generate_single_readme(details=details) + if details.repo_name == "microservice-repository-template": + template_overview = read_template_overview() + readme_content = template_overview + readme_content + if check: if README_PATH.read_text() != readme_content: echo_failure("README.md is not up to date.") diff --git a/scripts/update_template_files.py b/scripts/update_template_files.py index d3313fd5..fe29d575 100755 --- a/scripts/update_template_files.py +++ b/scripts/update_template_files.py @@ -40,12 +40,20 @@ def run(main_fn): main_fn(check="--check" in sys.argv[1:]) -REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() +REPO_ROOT_DIR = Path(__file__).parent.parent.absolute() + +FILE_LIST_DIR_NAME = ".template" +DEPRECATED_FILES = "deprecated_files" +MANDATORY_FILES = "mandatory_files" +STATIC_FILES = "static_files" -DEPRECATED_FILES = ".deprecated_files" -MANDATORY_FILES = ".mandatory_files" -STATIC_FILES = ".static_files" IGNORE_SUFFIX = "_ignore" + +TEMPLATE_LIST_REL_PATHS = [ + f"{FILE_LIST_DIR_NAME}/{list_name}.txt" + for list_name in [STATIC_FILES, MANDATORY_FILES, DEPRECATED_FILES] +] + RAW_TEMPLATE_URL = ( "https://raw.githubusercontent.com/ghga-de/microservice-repository-template/main/" ) @@ -55,9 +63,14 @@ class ValidationError(RuntimeError): """Raised when files need to be updated.""" +def get_file_list_path(list_name: str, relative: bool = False) -> Path: + """Get the path to the file list of the given name.""" + return Path(REPO_ROOT_DIR / FILE_LIST_DIR_NAME / f"{list_name}.txt") + + def get_file_list(list_name: str) -> list[str]: """Return a list of all file names specified in a given list file.""" - list_path = REPO_ROOT_DIR / list_name + list_path = get_file_list_path(list_name) with open(list_path, encoding="utf8") as list_file: file_list = [ clean_line @@ -212,14 +225,13 @@ def remove_files(files: list[str], check: bool = False) -> bool: def main(check: bool = False): """Update the static files in the service template.""" updated = False - if not check: - update_files([STATIC_FILES], diff=True, check=False) + + print("Template lists...") + if update_files(TEMPLATE_LIST_REL_PATHS, diff=True, check=False): + updated = True print("Static files...") files_to_update = get_file_list(STATIC_FILES) - if check: - files_to_update.append(STATIC_FILES) - files_to_update.extend((MANDATORY_FILES, DEPRECATED_FILES)) if update_files(files_to_update, diff=True, check=check): updated = True