From 49a84ccb568b9b852f99670420091b28a197e974 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 9 Oct 2023 15:43:23 +0000 Subject: [PATCH 1/3] Update template files Make minor changes according to pre-commit results --- .coveragerc | 5 + .deprecated_files | 7 + .devcontainer/dev_install | 8 +- .flake8 | 21 - .github/workflows/cd.yaml | 5 +- .github/workflows/check_config_docs.yaml | 2 +- .github/workflows/check_readme.yaml | 2 +- .github/workflows/static_code_analysis.yaml | 16 +- .../{unit_and_int_tests.yaml => tests.yaml} | 16 +- .gitignore | 1 + .mandatory_files | 6 +- .pre-commit-config.yaml | 44 +- .pylintrc | 546 ----------- .readme_template.md | 2 +- .ruff.toml | 62 ++ .static_files | 14 +- pyproject.toml | 41 + readme_generation.md | 6 +- requirements-dev-common.in | 34 + requirements-dev-common.txt | 36 - requirements-dev.in | 7 + requirements-dev.txt | 922 +++++++++++++++++- requirements.txt | 409 +++++++- scripts/get_package_name.py | 10 +- scripts/license_checker.py | 59 +- scripts/list_outdated_dependencies.py | 210 ++++ scripts/script_utils/deps.py | 74 ++ scripts/script_utils/lock_deps.py | 46 + scripts/update_config_docs.py | 9 +- scripts/update_hook_revs.py | 132 +++ scripts/update_lock.py | 210 ++++ scripts/update_readme.py | 32 +- scripts/update_template_files.py | 6 +- setup.cfg | 52 - setup.py | 23 - {ns => src/ns}/__init__.py | 4 +- {ns => src/ns}/__main__.py | 0 {ns => src/ns}/adapters/__init__.py | 0 {ns => src/ns}/adapters/inbound/__init__.py | 0 {ns => src/ns}/adapters/inbound/akafka.py | 0 {ns => src/ns}/adapters/outbound/__init__.py | 0 .../ns}/adapters/outbound/smtp_client.py | 7 +- {ns => src/ns}/config.py | 0 {ns => src/ns}/container.py | 0 {ns => src/ns}/core/__init__.py | 0 {ns => src/ns}/core/notifier.py | 0 {ns => src/ns}/main.py | 1 - {ns => src/ns}/ports/__init__.py | 0 {ns => src/ns}/ports/inbound/__init__.py | 0 {ns => src/ns}/ports/inbound/notifier.py | 0 {ns => src/ns}/ports/outbound/__init__.py | 0 {ns => src/ns}/ports/outbound/smtp_client.py | 0 tests/fixtures/config.py | 9 +- tests/fixtures/joint.py | 5 +- tests/fixtures/server.py | 10 +- 55 files changed, 2291 insertions(+), 820 deletions(-) create mode 100644 .coveragerc delete mode 100644 .flake8 rename .github/workflows/{unit_and_int_tests.yaml => tests.yaml} (65%) delete mode 100644 .pylintrc create mode 100644 .ruff.toml create mode 100644 pyproject.toml create mode 100644 requirements-dev-common.in delete mode 100644 requirements-dev-common.txt create mode 100644 requirements-dev.in create mode 100755 scripts/list_outdated_dependencies.py create mode 100644 scripts/script_utils/deps.py create mode 100644 scripts/script_utils/lock_deps.py create mode 100755 scripts/update_hook_revs.py create mode 100755 scripts/update_lock.py delete mode 100644 setup.cfg delete mode 100755 setup.py rename {ns => src/ns}/__init__.py (91%) rename {ns => src/ns}/__main__.py (100%) rename {ns => src/ns}/adapters/__init__.py (100%) rename {ns => src/ns}/adapters/inbound/__init__.py (100%) rename {ns => src/ns}/adapters/inbound/akafka.py (100%) rename {ns => src/ns}/adapters/outbound/__init__.py (100%) rename {ns => src/ns}/adapters/outbound/smtp_client.py (92%) rename {ns => src/ns}/config.py (100%) rename {ns => src/ns}/container.py (100%) rename {ns => src/ns}/core/__init__.py (100%) rename {ns => src/ns}/core/notifier.py (100%) rename {ns => src/ns}/main.py (99%) rename {ns => src/ns}/ports/__init__.py (100%) rename {ns => src/ns}/ports/inbound/__init__.py (100%) rename {ns => src/ns}/ports/inbound/notifier.py (100%) rename {ns => src/ns}/ports/outbound/__init__.py (100%) rename {ns => src/ns}/ports/outbound/smtp_client.py (100%) diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..b172375 --- /dev/null +++ b/.coveragerc @@ -0,0 +1,5 @@ +[paths] +source = + src + /workspace/src + **/lib/python*/site-packages diff --git a/.deprecated_files b/.deprecated_files index 888a8e8..ca3684e 100644 --- a/.deprecated_files +++ b/.deprecated_files @@ -9,8 +9,15 @@ .github/workflows/check_mandatory_and_static_files.yaml .github/workflows/dev_cd.yaml +.github/workflows/unit_and_int_tests.yaml scripts/check_mandatory_and_static_files.py scripts/update_static_files.py docs + +setup.py +setup.cfg + +.pylintrc +.flake8 diff --git a/.devcontainer/dev_install b/.devcontainer/dev_install index 31cb590..b5ee189 100755 --- a/.devcontainer/dev_install +++ b/.devcontainer/dev_install @@ -6,11 +6,11 @@ cd /workspace # upgrade pip python -m pip install --upgrade pip -# install with all extras in editable mode -pip install -e .[all] - # install or upgrade dependencies for development and testing -pip install -r requirements-dev.txt +pip install --no-deps -r requirements-dev.txt + +# install the package itself in edit mode: +pip install --no-deps -e . # install pre-commit hooks to git pre-commit install diff --git a/.flake8 b/.flake8 deleted file mode 100644 index bfd9ba4..0000000 --- a/.flake8 +++ /dev/null @@ -1,21 +0,0 @@ -; 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. - -[flake8] -ignore = E, W - # ignore all style checks from pycodestyle - # as they are already checked by black -exclude = .git,__pycache__,build,dist -max-complexity = 10 diff --git a/.github/workflows/cd.yaml b/.github/workflows/cd.yaml index 786220f..bdcd34b 100644 --- a/.github/workflows/cd.yaml +++ b/.github/workflows/cd.yaml @@ -2,7 +2,8 @@ name: CD on: release: - types: [published] + types: + [published] # trigger only on new release jobs: @@ -44,7 +45,7 @@ jobs: name: Verify package version vs tag version # package version must be same with tag version run: | - PKG_VER="$(python setup.py --version)" + PKG_VER="$(grep -oP 'version = "\K[^"]+' pyproject.toml)" echo "Package version is $PKG_VER" >&2 echo "Tag version is ${{ steps.get_version_tag.outputs.version }}" >&2 if [ "$PKG_VER" != "${{ steps.get_version_tag.outputs.version }}" ]; then diff --git a/.github/workflows/check_config_docs.yaml b/.github/workflows/check_config_docs.yaml index c44b4b7..f863f80 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@v2 + uses: ghga-de/gh-action-common@v3 - name: Check config docs run: | diff --git a/.github/workflows/check_readme.yaml b/.github/workflows/check_readme.yaml index a052d1e..9f400d2 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@v2 + uses: ghga-de/gh-action-common@v3 - name: Check readme run: | diff --git a/.github/workflows/static_code_analysis.yaml b/.github/workflows/static_code_analysis.yaml index 31feccf..401f428 100644 --- a/.github/workflows/static_code_analysis.yaml +++ b/.github/workflows/static_code_analysis.yaml @@ -10,29 +10,19 @@ jobs: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v2 + uses: ghga-de/gh-action-common@v3 - uses: pre-commit/action@v3.0.0 env: SKIP: no-commit-to-branch + - name: ruff + uses: chartboost/ruff-action@v1 - name: black run: | black --check . - - name: isort - run: | - isort --check --profile black . - name: mypy run: | mypy . - - name: pylint - run: | - pylint "${{ steps.common.outputs.MAIN_SRC_DIR }}" - - name: flake8 - run: | - flake8 --config .flake8 - - name: bandit - run: | - bandit -r "${{ steps.common.outputs.MAIN_SRC_DIR }}" - name: Check license header and file run: | ./scripts/license_checker.py diff --git a/.github/workflows/unit_and_int_tests.yaml b/.github/workflows/tests.yaml similarity index 65% rename from .github/workflows/unit_and_int_tests.yaml rename to .github/workflows/tests.yaml index d6e5ed3..05f474c 100644 --- a/.github/workflows/unit_and_int_tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,24 +1,26 @@ -name: Unit and Integration Tests +name: Tests on: push jobs: - unit_and_int_tests: + tests: runs-on: ubuntu-latest - name: Unit and Integration Tests + name: Tests steps: - uses: actions/checkout@v3 - id: common - uses: ghga-de/gh-action-common@v2 + uses: ghga-de/gh-action-common@v3 - - name: Run pytest + - id: pytest run: | export ${{ steps.common.outputs.CONFIG_YAML_ENV_VAR_NAME }}="${{ steps.common.outputs.CONFIG_YAML }}" + pytest \ - --cov="${{ steps.common.outputs.MAIN_SRC_DIR }}" \ - --cov-report=xml + --cov="${{ steps.common.outputs.PACKAGE_NAME }}" \ + --cov-report=xml \ + tests - id: coveralls name: Upload coverage to coveralls diff --git a/.gitignore b/.gitignore index 28b8a9d..a71cfd2 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +.ruff_cache/ prof/ # Translations diff --git a/.mandatory_files b/.mandatory_files index d7cf949..c0b51fb 100644 --- a/.mandatory_files +++ b/.mandatory_files @@ -19,10 +19,12 @@ Dockerfile config_schema.json example_config.yaml LICENSE +pyproject.toml README.md -setup.py -setup.cfg +requirements-dev.in requirements-dev.txt +requirements.txt .description.md .design.md +.pre-commit-config.yaml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 31f8a5b..594a10d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,6 +7,20 @@ default_language_version: minimum_pre_commit_version: 3.0.0 repos: + - repo: local + hooks: + - id: update-hook-revs + name: "ensure hooks are up to date" + language: python + additional_dependencies: + - "packaging" + - "typer" + fail_fast: true + always_run: true + entry: ./scripts/update_hook_revs.py + files: '\.pre-commit-config.yaml' + args: [--check] + pass_filenames: false - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.4.0 hooks: @@ -36,33 +50,17 @@ repos: - id: debug-statements - id: debug-statements - id: debug-statements + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.0.292 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 23.9.1 hooks: - id: black - - repo: https://github.com/pycqa/isort - rev: 5.12.0 - hooks: - - id: isort - args: [--profile, black] - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.0.0 + rev: v1.5.1 hooks: - id: mypy args: [--no-warn-unused-ignores] - - repo: https://github.com/PyCQA/pylint - rev: v2.16.4 - hooks: - - id: pylint - args: [--disable=E0401] - exclude: tests|.devcontainer - - repo: https://github.com/PyCQA/flake8 - rev: 6.0.0 - hooks: - - id: flake8 - args: [--config, .flake8] - - repo: https://github.com/PyCQA/bandit - rev: 1.7.4 - hooks: - - id: bandit - exclude: tests|.devcontainer|scripts diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index cfb50db..0000000 --- a/.pylintrc +++ /dev/null @@ -1,546 +0,0 @@ -[MASTER] - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. -extension-pkg-allow-list= - -# A comma-separated list of package or module names from where C extensions may -# be loaded. Extensions are loading into the active Python interpreter and may -# run arbitrary code. (This is an alternative name to extension-pkg-allow-list -# for backward compatibility.) -extension-pkg-whitelist=pydantic - -# Specify a score threshold to be exceeded before program exits with error. -fail-under=10.0 - -# Files or directories to be skipped. They should be base names, not paths. -ignore=CVS - - -# Files or directories matching the regex patterns are skipped. The regex -# matches against base names, not paths. -ignore-patterns= - -# Python code to execute, usually for sys.path manipulation such as -# pygtk.require(). -#init-hook= - -# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the -# number of processors available to use. -jobs=1 - -# Control the amount of potential inferred values when inferring a single -# object. This can help the performance when dealing with large functions or -# complex, nested conditions. -limit-inference-results=100 - -# List of plugins (as comma separated values of python module names) to load, -# usually to register additional checkers. -load-plugins= - -# Pickle collected data for later comparisons. -persistent=yes - -# When enabled, pylint would attempt to guess common misconfiguration and emit -# user-friendly hints instead of false-positive error messages. -suggestion-mode=yes - -# Allow loading of arbitrary C extensions. Extensions are imported into the -# active Python interpreter and may run arbitrary code. -unsafe-load-any-extension=no - - -[MESSAGES CONTROL] - -# Only show warnings with the listed confidence levels. Leave empty to show -# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED. -confidence= - -# Disable the message, report, category or checker with the given id(s). You -# can either give multiple identifiers separated by comma (,) or put this -# option multiple times (only on the command line, not in the configuration -# file where it should appear only once). You can also use "--disable=all" to -# disable everything first and then reenable specific checks. For example, if -# you want to run only the similarities checker, you can use "--disable=all -# --enable=similarities". If you want to run only the classes checker, but have -# no Warning level messages displayed, use "--disable=all --enable=classes -# --disable=W". -disable= - duplicate-code, # is behaving strangely sometimes and cannot - # be disabled on an individual basis: - # https://github.com/PyCQA/pylint/issues/214 - - too-few-public-methods, # says that classes should always have methods - # but that is not true anymore (e.g. dataclasses) - - unnecessary-ellipsis, # often used for interfaces/protocols - -# Enable the message, report, category or checker with the given id(s). You can -# either give multiple identifier separated by comma (,) or put this option -# multiple time (only on the command line, not in the configuration file where -# it should appear only once). See also the "--disable" option for examples. -enable=c-extension-no-member - - -[REPORTS] - -# Python expression which should return a score less than or equal to 10. You -# have access to the variables 'error', 'warning', 'refactor', and 'convention' -# which contain the number of messages in each category, as well as 'statement' -# which is the total number of statements analyzed. This score is used by the -# global evaluation report (RP0004). -evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10) - -# Template used to display messages. This is a python new-style format string -# used to format the message information. See doc for all details. -#msg-template= - -# Set the output format. Available formats are text, parseable, colorized, json -# and msvs (visual studio). You can also give a reporter class, e.g. -# mypackage.mymodule.MyReporterClass. -output-format=text - -# Tells whether to display a full report or only the messages. -reports=no - -# Activate the evaluation score. -score=yes - - -[REFACTORING] - -# Maximum number of nested blocks for function / method body -max-nested-blocks=5 - -# Complete name of functions that never returns. When checking for -# inconsistent-return-statements if a never returning function is called then -# it will be considered as an explicit return statement and no message will be -# printed. -never-returning-functions=sys.exit,argparse.parse_error - - -[STRING] - -# This flag controls whether inconsistent-quotes generates a warning when the -# character used as a quote delimiter is used inconsistently within a module. -check-quote-consistency=no - -# This flag controls whether the implicit-str-concat should generate a warning -# on implicit string concatenation in sequences defined over several lines. -check-str-concat-over-line-jumps=no - - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes=FIXME, - XXX, - TODO - -# Regular expression of note tags to take in consideration. -#notes-rgx= - - -[SPELLING] - -# Limits count of emitted suggestions for spelling mistakes. -max-spelling-suggestions=4 - -# Spelling dictionary name. Available dictionaries: none. To make it work, -# install the 'python-enchant' package. -spelling-dict= - -# List of comma separated words that should be considered directives if they -# appear and the beginning of a comment and should not be checked. -spelling-ignore-comment-directives=fmt: on,fmt: off,noqa:,noqa,nosec,isort:skip,mypy: - -# List of comma separated words that should not be checked. -spelling-ignore-words= - -# A path to a file that contains the private dictionary; one word per line. -spelling-private-dict-file= - -# Tells whether to store unknown words to the private dictionary (see the -# --spelling-private-dict-file option) instead of raising a message. -spelling-store-unknown-words=no - - -[BASIC] - -# Naming style matching correct argument names. -argument-naming-style=snake_case - -# Regular expression matching correct argument names. Overrides argument- -# naming-style. -#argument-rgx= - -# Naming style matching correct attribute names. -attr-naming-style=snake_case - -# Regular expression matching correct attribute names. Overrides attr-naming- -# style. -#attr-rgx= - -# Bad variable names which should always be refused, separated by a comma. -bad-names=foo, - bar, - baz, - toto, - tutu, - tata - -# Bad variable names regexes, separated by a comma. If names match any regex, -# they will always be refused -bad-names-rgxs= - -# Naming style matching correct class attribute names. -class-attribute-naming-style=any - -# Regular expression matching correct class attribute names. Overrides class- -# attribute-naming-style. -#class-attribute-rgx= - -# Naming style matching correct class constant names. -class-const-naming-style=UPPER_CASE - -# Regular expression matching correct class constant names. Overrides class- -# const-naming-style. -#class-const-rgx= - -# Naming style matching correct class names. -class-naming-style=PascalCase - -# Regular expression matching correct class names. Overrides class-naming- -# style. -#class-rgx= - -# Naming style matching correct constant names. -const-naming-style=UPPER_CASE - -# Regular expression matching correct constant names. Overrides const-naming- -# style. -#const-rgx= - -# Minimum line length for functions/classes that require docstrings, shorter -# ones are exempt. -docstring-min-length=-1 - -# Naming style matching correct function names. -function-naming-style=snake_case - -# Regular expression matching correct function names. Overrides function- -# naming-style. -#function-rgx= - -# Good variable names which should always be accepted, separated by a comma. -good-names=i, - j, - k, - ex, - ok, - Run, - _, - __, - id, - db, - -# Good variable names regexes, separated by a comma. If names match any regex, -# they will always be accepted -good-names-rgxs= - -# Include a hint for the correct naming format with invalid-name. -include-naming-hint=no - -# Naming style matching correct inline iteration names. -inlinevar-naming-style=any - -# Regular expression matching correct inline iteration names. Overrides -# inlinevar-naming-style. -#inlinevar-rgx= - -# Naming style matching correct method names. -method-naming-style=snake_case - -# Regular expression matching correct method names. Overrides method-naming- -# style. -#method-rgx= - -# Naming style matching correct module names. -module-naming-style=snake_case - -# Regular expression matching correct module names. Overrides module-naming- -# style. -#module-rgx= - -# Colon-delimited sets of names that determine each other's naming style when -# the name regexes allow several styles. -name-group= - -# Regular expression which should only match function or class names that do -# not require a docstring. -no-docstring-rgx=^_ - -# List of decorators that produce properties, such as abc.abstractproperty. Add -# to this list to register other decorators that produce valid properties. -# These decorators are taken in consideration only for invalid-name. -property-classes=abc.abstractproperty - -# Naming style matching correct variable names. -variable-naming-style=snake_case - -# Regular expression matching correct variable names. Overrides variable- -# naming-style. -#variable-rgx= - - -[LOGGING] - -# The type of string formatting that logging methods do. `old` means using % -# formatting, `new` is for `{}` formatting. -logging-format-style=old - -# Logging modules to check that the string format arguments are in logging -# function parameter format. -logging-modules=logging - - -[VARIABLES] - -# List of additional names supposed to be defined in builtins. Remember that -# you should avoid defining new builtins when possible. -additional-builtins= - -# Tells whether unused global variables should be treated as a violation. -allow-global-unused-variables=yes - -# List of names allowed to shadow builtins -allowed-redefined-builtins= - -# List of strings which can identify a callback function by name. A callback -# name must start or end with one of those strings. -callbacks=cb_, - _cb - -# A regular expression matching the name of dummy variables (i.e. expected to -# not be used). -dummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_ - -# Argument names that match this expression will be ignored. Default to name -# with leading underscore. -ignored-argument-names=_.*|^ignored_|^unused_ - -# Tells whether we should check for unused import in __init__ files. -init-import=no - -# List of qualified module names which can have objects that can redefine -# builtins. -redefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io - - -[TYPECHECK] - -# List of decorators that produce context managers, such as -# contextlib.contextmanager. Add to this list to register other decorators that -# produce valid context managers. -contextmanager-decorators=contextlib.contextmanager - -# List of members which are set dynamically and missed by pylint inference -# system, and so shouldn't trigger E1101 when accessed. Python regular -# expressions are accepted. -generated-members= - -# Tells whether missing members accessed in mixin class should be ignored. A -# mixin class is detected if its name ends with "mixin" (case insensitive). -ignore-mixin-members=yes - -# Tells whether to warn about missing members when the owner of the attribute -# is inferred to be None. -ignore-none=yes - -# This flag controls whether pylint should warn about no-member and similar -# checks whenever an opaque object is returned when inferring. The inference -# can return multiple potential results while evaluating a Python object, but -# some branches might not be evaluated, which results in partial inference. In -# that case, it might be useful to still emit no-member and other checks for -# the rest of the inferred objects. -ignore-on-opaque-inference=yes - -# List of class names for which member attributes should not be checked (useful -# for classes with dynamically set attributes). This supports the use of -# qualified names. -ignored-classes=optparse.Values,thread._local,_thread._local - -# List of module names for which member attributes should not be checked -# (useful for modules/projects where namespaces are manipulated during runtime -# and thus existing member attributes cannot be deduced by static analysis). It -# supports qualified module names, as well as Unix pattern matching. -ignored-modules= - -# Show a hint with possible names when a member name was not found. The aspect -# of finding the hint is based on edit distance. -missing-member-hint=yes - -# The minimum edit distance a name should have in order to be considered a -# similar match for a missing member name. -missing-member-hint-distance=1 - -# The total number of similar names that should be taken in consideration when -# showing a hint for a missing member. -missing-member-max-choices=1 - -# List of decorators that change the signature of a decorated function. -signature-mutators= - - -[FORMAT] - -# Expected format of line ending, e.g. empty (any line ending), LF or CRLF. -expected-line-ending-format= - -# Regexp for a line that is allowed to be longer than the limit. -ignore-long-lines=^\s*(# )??$ - -# Number of spaces of indent required inside a hanging or continued line. -indent-after-paren=4 - -# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1 -# tab). -indent-string=' ' - -# Maximum number of characters on a single line. -max-line-length=100 - -# Maximum number of lines in a module. -max-module-lines=1000 - -# Allow the body of a class to be on the same line as the declaration if body -# contains single statement. -single-line-class-stmt=no - -# Allow the body of an if to be on the same line as the test if there is no -# else. -single-line-if-stmt=no - - -[SIMILARITIES] - -# Ignore comments when computing similarities. -ignore-comments=yes - -# Ignore docstrings when computing similarities. -ignore-docstrings=yes - -# Ignore imports when computing similarities. -ignore-imports=no - -# Minimum lines number of a similarity. -min-similarity-lines=4 - - -[DESIGN] - -# Maximum number of arguments for function / method. -max-args=5 - -# Maximum number of attributes for a class (see R0902). -max-attributes=7 - -# Maximum number of boolean expressions in an if statement (see R0916). -max-bool-expr=5 - -# Maximum number of branch for function / method body. -max-branches=12 - -# Maximum number of locals for function / method body. -max-locals=15 - -# Maximum number of parents for a class (see R0901). -max-parents=7 - -# Maximum number of public methods for a class (see R0904). -max-public-methods=20 - -# Maximum number of return / yield for function / method body. -max-returns=6 - -# Maximum number of statements in function / method body. -max-statements=50 - -# Minimum number of public methods for a class (see R0903). -min-public-methods=2 - - -[IMPORTS] - -# List of modules that can be imported at any level, not just the top level -# one. -allow-any-import-level= - -# Allow wildcard imports from modules that define __all__. -allow-wildcard-with-all=no - -# Analyse import fallback blocks. This can be used to support both Python 2 and -# 3 compatible code, which means that the block might have code that exists -# only in one or another interpreter, leading to false positives when analysed. -analyse-fallback-blocks=no - -# Deprecated modules which should not be used, separated by a comma. -deprecated-modules=optparse,tkinter.tix - -# Output a graph (.gv or any supported image format) of external dependencies -# to the given file (report RP0402 must not be disabled). -ext-import-graph= - -# Output a graph (.gv or any supported image format) of all (i.e. internal and -# external) dependencies to the given file (report RP0402 must not be -# disabled). -import-graph= - -# Output a graph (.gv or any supported image format) of internal dependencies -# to the given file (report RP0402 must not be disabled). -int-import-graph= - -# Force import order to recognize a module as part of the standard -# compatibility libraries. -known-standard-library= - -# Force import order to recognize a module as part of a third party library. -known-third-party=enchant - -# Couples of modules and preferred modules, separated by a comma. -preferred-modules= - - -[CLASSES] - -# Warn about protected attribute access inside special methods -check-protected-access-in-special-methods=no - -# List of method names used to declare (i.e. assign) instance attributes. -defining-attr-methods=__init__, - __new__, - setUp, - __post_init__ - -# List of member names, which should be excluded from the protected access -# warning. -exclude-protected=_asdict, - _fields, - _replace, - _source, - _make - -# List of valid names for the first argument in a class method. -valid-classmethod-first-arg=cls - -# List of valid names for the first argument in a metaclass class method. -valid-metaclass-classmethod-first-arg=cls - - -[EXCEPTIONS] - -# Exceptions that will emit a warning when being caught. Defaults to -# "builtins.BaseException, builtins.Exception". -overgeneral-exceptions=builtins.BaseException, - builtins.Exception diff --git a/.readme_template.md b/.readme_template.md index 878dbdc..dd8b184 100644 --- a/.readme_template.md +++ b/.readme_template.md @@ -97,7 +97,7 @@ Moreover, inside the devcontainer, a convenience commands `dev_install` is avail It installs the service with all development dependencies, installs pre-commit. The installation is performed automatically when you build the devcontainer. However, -if you update dependencies in the [`./setup.cfg`](./setup.cfg) or the +if you update dependencies in the [`./pyproject.toml`](./pyproject.toml) or the [`./requirements-dev.txt`](./requirements-dev.txt), please run it again. ## License diff --git a/.ruff.toml b/.ruff.toml new file mode 100644 index 0000000..27ee0ea --- /dev/null +++ b/.ruff.toml @@ -0,0 +1,62 @@ +exclude = [ + ".git", + ".devcontainer", + "__pycache__", + "build", + "dist", +] + +ignore = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings - pycodestyle covered by black + "PLW", # pylint warnings + "RUF001", # ambiguous unicode character strings + "RUF010", # explicit conversion to string or repr: !s or !r + "RUF012", # mutable class variables need typing.ClassVar annotation + "N818", # Errors need to have Error suffix + "B008", # function call in arg defaults, + "PLR2004", # magic numbers should be constants + "D205", # blank-line-after-summary + "D400", # first doc line ends in period + "D401", # non-imperative-mood + "D107", # missing docstring in __init__ +] + +line-length = 88 + +select = [ + "C90", # McCabe Complexity + "F", # pyflakes codes + "I", # isort + "S", # flake8-bandit + "B", # flake8-bugbear + "N", # pep8-naming + "UP", # pyupgrade + "PL", # pylint + "RUF", # ruff + "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] +max-complexity = 10 + +[per-file-ignores] +"scripts/*" = ["PL", "S", "SIM", "D"] +"tests/*" = ["S", "SIM", "PLR", "B011"] +".devcontainer/*" = ["S", "SIM", "D"] +"examples/*" = ["S", "D"] +"__init__.py" = ["D"] + +[pydocstyle] +convention = "pep257" diff --git a/.static_files b/.static_files index 3ebfa18..e3c8f76 100644 --- a/.static_files +++ b/.static_files @@ -23,31 +23,31 @@ scripts/update_config_docs.py scripts/update_template_files.py scripts/update_openapi_docs.py scripts/update_readme.py +scripts/update_lock.py +scripts/update_hook_revs.py +scripts/list_outdated_dependencies.py scripts/README.md .github/workflows/check_config_docs.yaml .github/workflows/check_template_files.yaml .github/workflows/static_code_analysis.yaml -.github/workflows/unit_and_int_tests.yaml +.github/workflows/tests.yaml .github/workflows/check_openapi_spec.yaml .github/workflows/check_readme.yaml .github/workflows/cd.yaml example_data/README.md +.coveragerc .editorconfig -.flake8 .gitattributes .gitignore -.pre-commit-config.yaml -.pylintrc .mypy.ini +.ruff.toml pytest.ini LICENSE -requirements.txt -requirements-dev-common.txt -setup.py +requirements-dev-common.in .readme_template.md readme_generation.md diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..682e9c7 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,41 @@ +[build-system] +requires = ["setuptools>=67.7.2"] +build-backend = "setuptools.build_meta" + +[project] +name = "ns" +version = "0.1.3" +description = "The Notification Service (NS) handles notification kafka events." +readme = "README.md" +authors = [ + { name = "German Human Genome Phenome Archive (GHGA)", email = "contact@ghga.de" }, +] +requires-python = ">=3.9" +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", +] +dependencies = [ + "typer>=0.7.0", + "ghga-event-schemas==0.13.4", + "hexkit[akafka]>=0.10.0", +] + +[project.license] +text = "Apache 2.0" + +[project.urls] +Repository = "https://github.com/ghga-de/notification-service" + +[project.scripts] +ns = "ns.__main__:run" + +[tool.setuptools.packages.find] +where = ["src"] diff --git a/readme_generation.md b/readme_generation.md index 432153c..84cd618 100644 --- a/readme_generation.md +++ b/readme_generation.md @@ -24,11 +24,11 @@ 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 [`./setup.cfg`](`./setup.cfg). + in the [`./pyproject.toml`](./pyproject.toml). - summary: A short 1-2 sentence summary derived from the description in the - [`./setup.cfg`](`./setup.cfg). + [`./pyproject.toml`](./pyproject.toml). - version: The package version derived from the version specified in the - [`./setup.cfg`](`./setup.cfg). + [`./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). - design_description: A markdown-formatted description of the overall architecture and diff --git a/requirements-dev-common.in b/requirements-dev-common.in new file mode 100644 index 0000000..1c677cd --- /dev/null +++ b/requirements-dev-common.in @@ -0,0 +1,34 @@ +# common requirements for development and testing of services + +pytest>=7.2.0 +pytest-asyncio>=0.20.3 +pytest-cov>=4.0.0 +pytest-profiling>=1.7.0 +snakeviz>=2.2.0 + +pre-commit>=3.1.1 + +mypy>=1.0.0 +mypy-extensions>=1.0.0 + +ruff>=0.0.290 + +black>=23.1.0 + +click>=8.1.0 +typer>=0.7.0 + +httpx>=0.23.3 +pytest-httpx>=0.21.3 + +urllib3>=1.26.15 +requests>=2.28.2 + +stringcase>=1.2.0 +jsonschema2md>=1.0.0 +setuptools>=67.7.2 + +# required since switch to pyproject.toml and pip-tools +pip-tools>=7.3.0 +tomli>=2.0.1 +tomli_w>=1.0.0 diff --git a/requirements-dev-common.txt b/requirements-dev-common.txt deleted file mode 100644 index b253cb8..0000000 --- a/requirements-dev-common.txt +++ /dev/null @@ -1,36 +0,0 @@ -# common requirements for development and testing of services - -pytest==7.2.0 -pytest-asyncio==0.20.3 -pytest-cov==4.0.0 -pytest-profiling==1.7.0 -snakeviz==2.2.0 - -pre-commit==3.1.1 - -mypy==1.0.0 -mypy-extensions==1.0.0 - -pylint==2.16.4 -flake8==6.0.0 -bandit==1.7.4 - -black==23.1.0 - -isort==5.12.0 - -click==8.1.3 -typer==0.7.0 - -httpx==0.23.3 -pytest-httpx==0.21.3 - - -# work around until this issue is solved: -# https://github.com/docker/docker-py/issues/3113 -urllib3==1.26.15 -requests==2.28.2 - -stringcase==1.2.0 -jsonschema2md==0.4.0 -setuptools==67.7.2 diff --git a/requirements-dev.in b/requirements-dev.in new file mode 100644 index 0000000..973a24b --- /dev/null +++ b/requirements-dev.in @@ -0,0 +1,7 @@ +# requirements for development and testing this service + +-r requirements-dev-common.in + +# additional requirements can be listed here +testcontainers[kafka]>=3.4.1 +aiosmtpd>=1.4.4.post2 diff --git a/requirements-dev.txt b/requirements-dev.txt index cb4d2e3..6e3a29f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -1,7 +1,917 @@ -# requirements for development and testing this service +# +# 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/tmp8mqf6xoh/pyproject.toml /workspace/requirements-dev.in +# +aiokafka==0.8.0 \ + --hash=sha256:021e9f0027ca63c6c04daccfdd0e985f7a56d51bd0d43f482f674a58fada52f5 \ + --hash=sha256:0e9d61912678ecae6b3d407107c1a935f21d55af4585b70d8f5dcc39ecb949ce \ + --hash=sha256:12457b59a06cff7369cace8d4460049b2ef2ab7f7cdc9c4924d577b9d4b48bf9 \ + --hash=sha256:1c3fd832a06fdd68e82f100fe678a800dd6dbf5e8db6af9521be333f965c325b \ + --hash=sha256:23f1fbdf54790a3751216e33e62228c8e1eb7feebcb19ef532cd3e4f13ae51ce \ + --hash=sha256:2567465ee6de4d248fc416f2eef7d33bbe246a79073410ae2368b5bdaeb758c1 \ + --hash=sha256:2760f095a8ffb5b9b97ad28a43a6a93f38d67cf3bc95b42e6b27462b614c8561 \ + --hash=sha256:4439a03820dc64a8c3aa5fe17809541e6a001f6f6196aad6b6b88e7ded2b5396 \ + --hash=sha256:49b30479f68ba9a484a0e3362fb9c48797d7320066db9fcd53e755451f389acb \ + --hash=sha256:5202073bb8d2350b72805d45ff0125c800ed101506a4ba7be2f03ad1ba8ad1e6 \ + --hash=sha256:539d8584652e354e7f7bbaf8843e936d91bfc28e224a53a82e1bcb64ac7f6dda \ + --hash=sha256:57aa55b48004da9bf5a5d37d3412c2d373b0bf32118bdc5c78cc5635998674cc \ + --hash=sha256:5a8038698a47333cdb0cd198cb4b3ccd2fbbc86ba9a4b9afc3eebe6544db0c2f \ + --hash=sha256:65e1d27a1c1cd38c66e0b22928af74b192f7598da9acd5bb939c6acea5bb5036 \ + --hash=sha256:6f50a940411ae6cd0d7bcaf2d821539e3a59b6de012f77de18a573565c9f638f \ + --hash=sha256:7e292841beda7cfdcd6939aab6cc2a623acd3d655b166f7ff97c658f14ced8c5 \ + --hash=sha256:881209100355a92696c6501ba1c2b32127bb1f7f2f318b400b3973ab0b52efed \ + --hash=sha256:8857cbd76e97186e54b98ebb3ea7778fb3618826bb9e4d01375bfab0a1d93d69 \ + --hash=sha256:9364eb81340b3a70a1222a4701c73a49ea0026a79bf138b4aec342f012d6f039 \ + --hash=sha256:95682f661f295fac2f5f3f0132aea7c44a1b6c92726161daa509af67ac506885 \ + --hash=sha256:9bf6d0da5804ae8888c357034d1a6750baa610999181e930678da0e87cec610d \ + --hash=sha256:b36066df820e30f56386deb56d72efba287ba65419848888ea4b42f9e2741cff \ + --hash=sha256:b86e3c1d649824103427c021593d75f44e01db1ffbc880b154e04098b534355f \ + --hash=sha256:d459ab92a360cac240cf10b9ce88e64c1e41d942c7f63b1df6c2aafe27f946d0 \ + --hash=sha256:dea214c2588237cf0d404624ccd99f466a2e853ca22d7153bb680b2d3f25cdde \ + --hash=sha256:dfb6dfef6c18726a783d102a6c1b0dfb6d43785a46ff34e967ddfa8f774532dd \ + --hash=sha256:e005b53597fe9bc6681a2a3b50728d235cf2fb8801e52790678c691c85383565 \ + --hash=sha256:e07f07290a150552273c02bc5109d0a40bc0f32abc0ae5aeaa1e54fb86369251 \ + --hash=sha256:ec896d114be157a886e3227bbe3f00658dc4d6f17b203bc44075650817703f0b \ + --hash=sha256:f0a216a27f05b050d5a5308fb3444014fa6bca5f0cd63468eaa169c5f19ea1dd \ + --hash=sha256:f3f96301337fa7f7242f46651619b8e9e8fa8f23902dc11416fe764436d662d3 + # via hexkit +aiosmtpd==1.4.4.post2 \ + --hash=sha256:f821fe424b703b2ea391dc2df11d89d2afd728af27393e13cf1a3530f19fdc5e \ + --hash=sha256:f9243b7dfe00aaf567da8728d891752426b51392174a34d2cf5c18053b63dcbc + # via -r /workspace/requirements-dev.in +anyio==4.0.0 \ + --hash=sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f \ + --hash=sha256:f7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a + # via httpcore +async-timeout==4.0.3 \ + --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ + --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 + # via aiokafka +atpublic==4.0 \ + --hash=sha256:0f40433219e124edf115c6c363808ca6f0e1cfa7d160d86b2fb94793086d1294 \ + --hash=sha256:80057c55641253b86dcb68b524f82328172371b6547d4c7462a9127fbfbbabfc + # via aiosmtpd +attrs==23.1.0 \ + --hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \ + --hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015 + # via + # aiosmtpd + # jsonschema + # referencing +black==23.9.1 \ + --hash=sha256:031e8c69f3d3b09e1aa471a926a1eeb0b9071f80b17689a655f7885ac9325a6f \ + --hash=sha256:13a2e4a93bb8ca74a749b6974925c27219bb3df4d42fc45e948a5d9feb5122b7 \ + --hash=sha256:13ef033794029b85dfea8032c9d3b92b42b526f1ff4bf13b2182ce4e917f5100 \ + --hash=sha256:14f04c990259576acd093871e7e9b14918eb28f1866f91968ff5524293f9c573 \ + --hash=sha256:24b6b3ff5c6d9ea08a8888f6977eae858e1f340d7260cf56d70a49823236b62d \ + --hash=sha256:403397c033adbc45c2bd41747da1f7fc7eaa44efbee256b53842470d4ac5a70f \ + --hash=sha256:50254ebfa56aa46a9fdd5d651f9637485068a1adf42270148cd101cdf56e0ad9 \ + --hash=sha256:538efb451cd50f43aba394e9ec7ad55a37598faae3348d723b59ea8e91616300 \ + --hash=sha256:638619a559280de0c2aa4d76f504891c9860bb8fa214267358f0a20f27c12948 \ + --hash=sha256:6a3b50e4b93f43b34a9d3ef00d9b6728b4a722c997c99ab09102fd5efdb88325 \ + --hash=sha256:6ccd59584cc834b6d127628713e4b6b968e5f79572da66284532525a042549f9 \ + --hash=sha256:75a2dc41b183d4872d3a500d2b9c9016e67ed95738a3624f4751a0cb4818fe71 \ + --hash=sha256:7d30ec46de88091e4316b17ae58bbbfc12b2de05e069030f6b747dfc649ad186 \ + --hash=sha256:8431445bf62d2a914b541da7ab3e2b4f3bc052d2ccbf157ebad18ea126efb91f \ + --hash=sha256:8fc1ddcf83f996247505db6b715294eba56ea9372e107fd54963c7553f2b6dfe \ + --hash=sha256:a732b82747235e0542c03bf352c126052c0fbc458d8a239a94701175b17d4855 \ + --hash=sha256:adc3e4442eef57f99b5590b245a328aad19c99552e0bdc7f0b04db6656debd80 \ + --hash=sha256:c46767e8df1b7beefb0899c4a95fb43058fa8500b6db144f4ff3ca38eb2f6393 \ + --hash=sha256:c619f063c2d68f19b2d7270f4cf3192cb81c9ec5bc5ba02df91471d0b88c4c5c \ + --hash=sha256:cf3a4d00e4cdb6734b64bf23cd4341421e8953615cba6b3670453737a72ec204 \ + --hash=sha256:cf99f3de8b3273a8317681d8194ea222f10e0133a24a7548c73ce44ea1679377 \ + --hash=sha256:d6bc09188020c9ac2555a498949401ab35bb6bf76d4e0f8ee251694664df6301 + # via -r /workspace/requirements-dev-common.in +build==1.0.3 \ + --hash=sha256:538aab1b64f9828977f84bc63ae570b060a8ed1be419e7870b8b4fc5e6ea553b \ + --hash=sha256:589bf99a67df7c9cf07ec0ac0e5e2ea5d4b37ac63301c4986d1acb126aa83f8f + # via pip-tools +certifi==2023.7.22 \ + --hash=sha256:539cc1d13202e33ca466e88b2807e29f4c13049d6d87031a3c110744495cb082 \ + --hash=sha256:92d6037539857d8206b8f6ae472e8b77db8058fec5937a1ef3f54304089edbb9 + # via + # httpcore + # httpx + # requests +cfgv==3.4.0 \ + --hash=sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9 \ + --hash=sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560 + # via pre-commit +charset-normalizer==3.3.0 \ + --hash=sha256:02673e456dc5ab13659f85196c534dc596d4ef260e4d86e856c3b2773ce09843 \ + --hash=sha256:02af06682e3590ab952599fbadac535ede5d60d78848e555aa58d0c0abbde786 \ + --hash=sha256:03680bb39035fbcffe828eae9c3f8afc0428c91d38e7d61aa992ef7a59fb120e \ + --hash=sha256:0570d21da019941634a531444364f2482e8db0b3425fcd5ac0c36565a64142c8 \ + --hash=sha256:09c77f964f351a7369cc343911e0df63e762e42bac24cd7d18525961c81754f4 \ + --hash=sha256:0d3d5b7db9ed8a2b11a774db2bbea7ba1884430a205dbd54a32d61d7c2a190fa \ + --hash=sha256:1063da2c85b95f2d1a430f1c33b55c9c17ffaf5e612e10aeaad641c55a9e2b9d \ + --hash=sha256:12ebea541c44fdc88ccb794a13fe861cc5e35d64ed689513a5c03d05b53b7c82 \ + --hash=sha256:153e7b6e724761741e0974fc4dcd406d35ba70b92bfe3fedcb497226c93b9da7 \ + --hash=sha256:15b26ddf78d57f1d143bdf32e820fd8935d36abe8a25eb9ec0b5a71c82eb3895 \ + --hash=sha256:1872d01ac8c618a8da634e232f24793883d6e456a66593135aeafe3784b0848d \ + --hash=sha256:187d18082694a29005ba2944c882344b6748d5be69e3a89bf3cc9d878e548d5a \ + --hash=sha256:1b2919306936ac6efb3aed1fbf81039f7087ddadb3160882a57ee2ff74fd2382 \ + --hash=sha256:232ac332403e37e4a03d209a3f92ed9071f7d3dbda70e2a5e9cff1c4ba9f0678 \ + --hash=sha256:23e8565ab7ff33218530bc817922fae827420f143479b753104ab801145b1d5b \ + --hash=sha256:24817cb02cbef7cd499f7c9a2735286b4782bd47a5b3516a0e84c50eab44b98e \ + --hash=sha256:249c6470a2b60935bafd1d1d13cd613f8cd8388d53461c67397ee6a0f5dce741 \ + --hash=sha256:24a91a981f185721542a0b7c92e9054b7ab4fea0508a795846bc5b0abf8118d4 \ + --hash=sha256:2502dd2a736c879c0f0d3e2161e74d9907231e25d35794584b1ca5284e43f596 \ + --hash=sha256:250c9eb0f4600361dd80d46112213dff2286231d92d3e52af1e5a6083d10cad9 \ + --hash=sha256:278c296c6f96fa686d74eb449ea1697f3c03dc28b75f873b65b5201806346a69 \ + --hash=sha256:2935ffc78db9645cb2086c2f8f4cfd23d9b73cc0dc80334bc30aac6f03f68f8c \ + --hash=sha256:2f4a0033ce9a76e391542c182f0d48d084855b5fcba5010f707c8e8c34663d77 \ + --hash=sha256:30a85aed0b864ac88309b7d94be09f6046c834ef60762a8833b660139cfbad13 \ + --hash=sha256:380c4bde80bce25c6e4f77b19386f5ec9db230df9f2f2ac1e5ad7af2caa70459 \ + --hash=sha256:3ae38d325b512f63f8da31f826e6cb6c367336f95e418137286ba362925c877e \ + --hash=sha256:3b447982ad46348c02cb90d230b75ac34e9886273df3a93eec0539308a6296d7 \ + --hash=sha256:3debd1150027933210c2fc321527c2299118aa929c2f5a0a80ab6953e3bd1908 \ + --hash=sha256:4162918ef3098851fcd8a628bf9b6a98d10c380725df9e04caf5ca6dd48c847a \ + --hash=sha256:468d2a840567b13a590e67dd276c570f8de00ed767ecc611994c301d0f8c014f \ + --hash=sha256:4cc152c5dd831641e995764f9f0b6589519f6f5123258ccaca8c6d34572fefa8 \ + --hash=sha256:542da1178c1c6af8873e143910e2269add130a299c9106eef2594e15dae5e482 \ + --hash=sha256:557b21a44ceac6c6b9773bc65aa1b4cc3e248a5ad2f5b914b91579a32e22204d \ + --hash=sha256:5707a746c6083a3a74b46b3a631d78d129edab06195a92a8ece755aac25a3f3d \ + --hash=sha256:588245972aca710b5b68802c8cad9edaa98589b1b42ad2b53accd6910dad3545 \ + --hash=sha256:5adf257bd58c1b8632046bbe43ee38c04e1038e9d37de9c57a94d6bd6ce5da34 \ + --hash=sha256:619d1c96099be5823db34fe89e2582b336b5b074a7f47f819d6b3a57ff7bdb86 \ + --hash=sha256:63563193aec44bce707e0c5ca64ff69fa72ed7cf34ce6e11d5127555756fd2f6 \ + --hash=sha256:67b8cc9574bb518ec76dc8e705d4c39ae78bb96237cb533edac149352c1f39fe \ + --hash=sha256:6a685067d05e46641d5d1623d7c7fdf15a357546cbb2f71b0ebde91b175ffc3e \ + --hash=sha256:70f1d09c0d7748b73290b29219e854b3207aea922f839437870d8cc2168e31cc \ + --hash=sha256:750b446b2ffce1739e8578576092179160f6d26bd5e23eb1789c4d64d5af7dc7 \ + --hash=sha256:7966951325782121e67c81299a031f4c115615e68046f79b85856b86ebffc4cd \ + --hash=sha256:7b8b8bf1189b3ba9b8de5c8db4d541b406611a71a955bbbd7385bbc45fcb786c \ + --hash=sha256:7f5d10bae5d78e4551b7be7a9b29643a95aded9d0f602aa2ba584f0388e7a557 \ + --hash=sha256:805dfea4ca10411a5296bcc75638017215a93ffb584c9e344731eef0dcfb026a \ + --hash=sha256:81bf654678e575403736b85ba3a7867e31c2c30a69bc57fe88e3ace52fb17b89 \ + --hash=sha256:82eb849f085624f6a607538ee7b83a6d8126df6d2f7d3b319cb837b289123078 \ + --hash=sha256:85a32721ddde63c9df9ebb0d2045b9691d9750cb139c161c80e500d210f5e26e \ + --hash=sha256:86d1f65ac145e2c9ed71d8ffb1905e9bba3a91ae29ba55b4c46ae6fc31d7c0d4 \ + --hash=sha256:86f63face3a527284f7bb8a9d4f78988e3c06823f7bea2bd6f0e0e9298ca0403 \ + --hash=sha256:8eaf82f0eccd1505cf39a45a6bd0a8cf1c70dcfc30dba338207a969d91b965c0 \ + --hash=sha256:93aa7eef6ee71c629b51ef873991d6911b906d7312c6e8e99790c0f33c576f89 \ + --hash=sha256:96c2b49eb6a72c0e4991d62406e365d87067ca14c1a729a870d22354e6f68115 \ + --hash=sha256:9cf3126b85822c4e53aa28c7ec9869b924d6fcfb76e77a45c44b83d91afd74f9 \ + --hash=sha256:9fe359b2e3a7729010060fbca442ca225280c16e923b37db0e955ac2a2b72a05 \ + --hash=sha256:a0ac5e7015a5920cfce654c06618ec40c33e12801711da6b4258af59a8eff00a \ + --hash=sha256:a3f93dab657839dfa61025056606600a11d0b696d79386f974e459a3fbc568ec \ + --hash=sha256:a4b71f4d1765639372a3b32d2638197f5cd5221b19531f9245fcc9ee62d38f56 \ + --hash=sha256:aae32c93e0f64469f74ccc730a7cb21c7610af3a775157e50bbd38f816536b38 \ + --hash=sha256:aaf7b34c5bc56b38c931a54f7952f1ff0ae77a2e82496583b247f7c969eb1479 \ + --hash=sha256:abecce40dfebbfa6abf8e324e1860092eeca6f7375c8c4e655a8afb61af58f2c \ + --hash=sha256:abf0d9f45ea5fb95051c8bfe43cb40cda383772f7e5023a83cc481ca2604d74e \ + --hash=sha256:ac71b2977fb90c35d41c9453116e283fac47bb9096ad917b8819ca8b943abecd \ + --hash=sha256:ada214c6fa40f8d800e575de6b91a40d0548139e5dc457d2ebb61470abf50186 \ + --hash=sha256:b09719a17a2301178fac4470d54b1680b18a5048b481cb8890e1ef820cb80455 \ + --hash=sha256:b1121de0e9d6e6ca08289583d7491e7fcb18a439305b34a30b20d8215922d43c \ + --hash=sha256:b3b2316b25644b23b54a6f6401074cebcecd1244c0b8e80111c9a3f1c8e83d65 \ + --hash=sha256:b3d9b48ee6e3967b7901c052b670c7dda6deb812c309439adaffdec55c6d7b78 \ + --hash=sha256:b5bcf60a228acae568e9911f410f9d9e0d43197d030ae5799e20dca8df588287 \ + --hash=sha256:b8f3307af845803fb0b060ab76cf6dd3a13adc15b6b451f54281d25911eb92df \ + --hash=sha256:c2af80fb58f0f24b3f3adcb9148e6203fa67dd3f61c4af146ecad033024dde43 \ + --hash=sha256:c350354efb159b8767a6244c166f66e67506e06c8924ed74669b2c70bc8735b1 \ + --hash=sha256:c5a74c359b2d47d26cdbbc7845e9662d6b08a1e915eb015d044729e92e7050b7 \ + --hash=sha256:c71f16da1ed8949774ef79f4a0260d28b83b3a50c6576f8f4f0288d109777989 \ + --hash=sha256:d47ecf253780c90ee181d4d871cd655a789da937454045b17b5798da9393901a \ + --hash=sha256:d7eff0f27edc5afa9e405f7165f85a6d782d308f3b6b9d96016c010597958e63 \ + --hash=sha256:d97d85fa63f315a8bdaba2af9a6a686e0eceab77b3089af45133252618e70884 \ + --hash=sha256:db756e48f9c5c607b5e33dd36b1d5872d0422e960145b08ab0ec7fd420e9d649 \ + --hash=sha256:dc45229747b67ffc441b3de2f3ae5e62877a282ea828a5bdb67883c4ee4a8810 \ + --hash=sha256:e0fc42822278451bc13a2e8626cf2218ba570f27856b536e00cfa53099724828 \ + --hash=sha256:e39c7eb31e3f5b1f88caff88bcff1b7f8334975b46f6ac6e9fc725d829bc35d4 \ + --hash=sha256:e46cd37076971c1040fc8c41273a8b3e2c624ce4f2be3f5dfcb7a430c1d3acc2 \ + --hash=sha256:e5c1502d4ace69a179305abb3f0bb6141cbe4714bc9b31d427329a95acfc8bdd \ + --hash=sha256:edfe077ab09442d4ef3c52cb1f9dab89bff02f4524afc0acf2d46be17dc479f5 \ + --hash=sha256:effe5406c9bd748a871dbcaf3ac69167c38d72db8c9baf3ff954c344f31c4cbe \ + --hash=sha256:f0d1e3732768fecb052d90d62b220af62ead5748ac51ef61e7b32c266cac9293 \ + --hash=sha256:f5969baeaea61c97efa706b9b107dcba02784b1601c74ac84f2a532ea079403e \ + --hash=sha256:f8888e31e3a85943743f8fc15e71536bda1c81d5aa36d014a3c0c44481d7db6e \ + --hash=sha256:fc52b79d83a3fe3a360902d3f5d79073a993597d48114c29485e9431092905d8 + # via requests +click==8.1.7 \ + --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ + --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de + # via + # -r /workspace/requirements-dev-common.in + # black + # pip-tools + # typer +coverage[toml]==7.3.2 \ + --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ + --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ + --hash=sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9 \ + --hash=sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312 \ + --hash=sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3 \ + --hash=sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb \ + --hash=sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25 \ + --hash=sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92 \ + --hash=sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda \ + --hash=sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148 \ + --hash=sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6 \ + --hash=sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216 \ + --hash=sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a \ + --hash=sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640 \ + --hash=sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836 \ + --hash=sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c \ + --hash=sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f \ + --hash=sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2 \ + --hash=sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901 \ + --hash=sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed \ + --hash=sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a \ + --hash=sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074 \ + --hash=sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc \ + --hash=sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84 \ + --hash=sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083 \ + --hash=sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f \ + --hash=sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c \ + --hash=sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c \ + --hash=sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637 \ + --hash=sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2 \ + --hash=sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82 \ + --hash=sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f \ + --hash=sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce \ + --hash=sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef \ + --hash=sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f \ + --hash=sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611 \ + --hash=sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c \ + --hash=sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76 \ + --hash=sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9 \ + --hash=sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce \ + --hash=sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9 \ + --hash=sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf \ + --hash=sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf \ + --hash=sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9 \ + --hash=sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6 \ + --hash=sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2 \ + --hash=sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a \ + --hash=sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a \ + --hash=sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf \ + --hash=sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738 \ + --hash=sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a \ + --hash=sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4 + # via pytest-cov +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 + # via testcontainers +distlib==0.3.7 \ + --hash=sha256:2e24928bc811348f0feb63014e97aaae3037f2cf48712d51ae61df7fd6075057 \ + --hash=sha256:9dafe54b34a028eafd95039d5e5d4851a13734540f1331060d31c9916e7147a8 + # via virtualenv +dnspython==2.3.0 \ + --hash=sha256:224e32b03eb46be70e12ef6d64e0be123a64e621ab4c0822ff6d450d52a540b9 \ + --hash=sha256:89141536394f909066cabd112e3e1a37e4e654db00a25308b0f130bc3152eb46 + # via + # email-validator + # ghga-event-schemas +docker==6.1.3 \ + --hash=sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20 \ + --hash=sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9 + # via testcontainers +email-validator==2.0.0.post2 \ + --hash=sha256:1ff6e86044200c56ae23595695c54e9614f4a9551e0e393614f764860b3d7900 \ + --hash=sha256:2466ba57cda361fb7309fd3d5a225723c788ca4bbad32a0ebd5373b99730285c + # via pydantic +exceptiongroup==1.1.3 \ + --hash=sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9 \ + --hash=sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3 + # via + # anyio + # pytest +filelock==3.12.4 \ + --hash=sha256:08c21d87ded6e2b9da6728c3dff51baf1dcecf973b768ef35bcbc3447edb9ad4 \ + --hash=sha256:2e6f249f1f3654291606e046b09f1fd5eac39b360664c27f5aad072012f8bcbd + # via virtualenv +ghga-event-schemas==0.13.4 \ + --hash=sha256:8bdc98ad0c7d2d7d82b1dd9490a933fcf9c25424fcd6d28d6728fc7f5979e553 \ + --hash=sha256:eee2495a8b857016c8e03faa0b739ae7e03125d5a608a5ec31987e24a3433443 + # via ns (pyproject.toml) +gprof2dot==2022.7.29 \ + --hash=sha256:45b4d298bd36608fccf9511c3fd88a773f7a1abc04d6cd39445b11ba43133ec5 \ + --hash=sha256:f165b3851d3c52ee4915eb1bd6cca571e5759823c2cd0f71a79bda93c2dc85d6 + # via pytest-profiling +h11==0.14.0 \ + --hash=sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d \ + --hash=sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 + # via httpcore +hexkit[akafka]==0.10.2 \ + --hash=sha256:1495f2bc6ae7423874bc20367dd28555cd15a74ccf5cb4997e0fb8307757987e \ + --hash=sha256:436ea50e706ab616803eb85a9a9f5e7bec727379b750b966650d6e64d4ea5ef0 + # via ns (pyproject.toml) +httpcore==0.18.0 \ + --hash=sha256:13b5e5cd1dca1a6636a6aaea212b19f4f85cd88c366a2b82304181b769aab3c9 \ + --hash=sha256:adc5398ee0a476567bf87467063ee63584a8bce86078bf748e48754f60202ced + # via httpx +httpx==0.25.0 \ + --hash=sha256:181ea7f8ba3a82578be86ef4171554dd45fec26a02556a744db029a0a27b7100 \ + --hash=sha256:47ecda285389cb32bb2691cc6e069e3ab0205956f681c5b2ad2325719751d875 + # via + # -r /workspace/requirements-dev-common.in + # pytest-httpx +identify==2.5.30 \ + --hash=sha256:afe67f26ae29bab007ec21b03d4114f41316ab9dd15aa8736a167481e108da54 \ + --hash=sha256:f302a4256a15c849b91cfcdcec052a8ce914634b2f77ae87dad29cd749f2d88d + # via pre-commit +idna==3.4 \ + --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ + --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 + # via + # anyio + # email-validator + # httpx + # requests +importlib-metadata==6.8.0 \ + --hash=sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb \ + --hash=sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743 + # via build +iniconfig==2.0.0 \ + --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \ + --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 + # via pytest +jsonschema==4.19.1 \ + --hash=sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e \ + --hash=sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf + # via + # ghga-event-schemas + # hexkit +jsonschema-specifications==2023.7.1 \ + --hash=sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1 \ + --hash=sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb + # via jsonschema +jsonschema2md==1.0.0 \ + --hash=sha256:01e18693c8dcdd643aa79ce757c5896877c590493422d23fd0bd76562fbc424b \ + --hash=sha256:1d1333cb6d55a152ce10051b05651bc71122c0ec5e572b3433046825661569d4 + # via -r /workspace/requirements-dev-common.in +kafka-python==2.0.2 \ + --hash=sha256:04dfe7fea2b63726cd6f3e79a2d86e709d608d74406638c5da33a01d45a9d7e3 \ + --hash=sha256:2d92418c7cb1c298fa6c7f0fb3519b520d0d7526ac6cb7ae2a4fc65a51a94b6e + # via + # aiokafka + # testcontainers +mypy==1.5.1 \ + --hash=sha256:159aa9acb16086b79bbb0016145034a1a05360626046a929f84579ce1666b315 \ + --hash=sha256:258b22210a4a258ccd077426c7a181d789d1121aca6db73a83f79372f5569ae0 \ + --hash=sha256:26f71b535dfc158a71264e6dc805a9f8d2e60b67215ca0bfa26e2e1aa4d4d373 \ + --hash=sha256:26fb32e4d4afa205b24bf645eddfbb36a1e17e995c5c99d6d00edb24b693406a \ + --hash=sha256:2fc3a600f749b1008cc75e02b6fb3d4db8dbcca2d733030fe7a3b3502902f161 \ + --hash=sha256:32cb59609b0534f0bd67faebb6e022fe534bdb0e2ecab4290d683d248be1b275 \ + --hash=sha256:330857f9507c24de5c5724235e66858f8364a0693894342485e543f5b07c8693 \ + --hash=sha256:361da43c4f5a96173220eb53340ace68cda81845cd88218f8862dfb0adc8cddb \ + --hash=sha256:4a465ea2ca12804d5b34bb056be3a29dc47aea5973b892d0417c6a10a40b2d65 \ + --hash=sha256:51cb1323064b1099e177098cb939eab2da42fea5d818d40113957ec954fc85f4 \ + --hash=sha256:57b10c56016adce71fba6bc6e9fd45d8083f74361f629390c556738565af8eeb \ + --hash=sha256:596fae69f2bfcb7305808c75c00f81fe2829b6236eadda536f00610ac5ec2243 \ + --hash=sha256:5d627124700b92b6bbaa99f27cbe615c8ea7b3402960f6372ea7d65faf376c14 \ + --hash=sha256:6ac9c21bfe7bc9f7f1b6fae441746e6a106e48fc9de530dea29e8cd37a2c0cc4 \ + --hash=sha256:82cb6193de9bbb3844bab4c7cf80e6227d5225cc7625b068a06d005d861ad5f1 \ + --hash=sha256:8f772942d372c8cbac575be99f9cc9d9fb3bd95c8bc2de6c01411e2c84ebca8a \ + --hash=sha256:9fece120dbb041771a63eb95e4896791386fe287fefb2837258925b8326d6160 \ + --hash=sha256:a156e6390944c265eb56afa67c74c0636f10283429171018446b732f1a05af25 \ + --hash=sha256:a9ec1f695f0c25986e6f7f8778e5ce61659063268836a38c951200c57479cc12 \ + --hash=sha256:abed92d9c8f08643c7d831300b739562b0a6c9fcb028d211134fc9ab20ccad5d \ + --hash=sha256:b031b9601f1060bf1281feab89697324726ba0c0bae9d7cd7ab4b690940f0b92 \ + --hash=sha256:c543214ffdd422623e9fedd0869166c2f16affe4ba37463975043ef7d2ea8770 \ + --hash=sha256:d28ddc3e3dfeab553e743e532fb95b4e6afad51d4706dd22f28e1e5e664828d2 \ + --hash=sha256:f33592ddf9655a4894aef22d134de7393e95fcbdc2d15c1ab65828eee5c66c70 \ + --hash=sha256:f6b0e77db9ff4fda74de7df13f30016a0a663928d669c9f2c057048ba44f09bb \ + --hash=sha256:f757063a83970d67c444f6e01d9550a7402322af3557ce7630d3c957386fa8f5 \ + --hash=sha256:ff0cedc84184115202475bbb46dd99f8dcb87fe24d5d0ddfc0fe6b8575c88d2f + # via -r /workspace/requirements-dev-common.in +mypy-extensions==1.0.0 \ + --hash=sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d \ + --hash=sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782 + # via + # -r /workspace/requirements-dev-common.in + # black + # mypy +nodeenv==1.8.0 \ + --hash=sha256:d51e0c37e64fbf47d017feac3145cdbb58836d7eee8c6f6d3b6880c5456227d2 \ + --hash=sha256:df865724bb3c3adc86b3876fa209771517b0cfe596beff01a92700e0e8be4cec + # via pre-commit +packaging==23.2 \ + --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ + --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 + # via + # aiokafka + # black + # build + # deprecation + # docker + # pytest +pathspec==0.11.2 \ + --hash=sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20 \ + --hash=sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3 + # via black +pip-tools==7.3.0 \ + --hash=sha256:8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e \ + --hash=sha256:8e9c99127fe024c025b46a0b2d15c7bd47f18f33226cf7330d35493663fc1d1d + # via -r /workspace/requirements-dev-common.in +platformdirs==3.11.0 \ + --hash=sha256:cf8ee52a3afdb965072dcc652433e0c7e3e40cf5ea1477cd4b3b1d2eb75495b3 \ + --hash=sha256:e9d171d00af68be50e9202731309c4e658fd8bc76f55c11c7dd760d023bda68e + # via + # black + # virtualenv +pluggy==1.3.0 \ + --hash=sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12 \ + --hash=sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7 + # via pytest +pre-commit==3.4.0 \ + --hash=sha256:6bbd5129a64cad4c0dfaeeb12cd8f7ea7e15b77028d985341478c8af3c759522 \ + --hash=sha256:96d529a951f8b677f730a7212442027e8ba53f9b04d217c4c67dc56c393ad945 + # via -r /workspace/requirements-dev-common.in +pydantic[email]==1.10.6 \ + --hash=sha256:012c99a9c0d18cfde7469aa1ebff922e24b0c706d03ead96940f5465f2c9cf62 \ + --hash=sha256:0abd9c60eee6201b853b6c4be104edfba4f8f6c5f3623f8e1dba90634d63eb35 \ + --hash=sha256:12e837fd320dd30bd625be1b101e3b62edc096a49835392dcf418f1a5ac2b832 \ + --hash=sha256:163e79386c3547c49366e959d01e37fc30252285a70619ffc1b10ede4758250a \ + --hash=sha256:189318051c3d57821f7233ecc94708767dd67687a614a4e8f92b4a020d4ffd06 \ + --hash=sha256:1c84583b9df62522829cbc46e2b22e0ec11445625b5acd70c5681ce09c9b11c4 \ + --hash=sha256:3091d2eaeda25391405e36c2fc2ed102b48bac4b384d42b2267310abae350ca6 \ + --hash=sha256:32937835e525d92c98a1512218db4eed9ddc8f4ee2a78382d77f54341972c0e7 \ + --hash=sha256:3a2be0a0f32c83265fd71a45027201e1278beaa82ea88ea5b345eea6afa9ac7f \ + --hash=sha256:3ac1cd4deed871dfe0c5f63721e29debf03e2deefa41b3ed5eb5f5df287c7b70 \ + --hash=sha256:3ce13a558b484c9ae48a6a7c184b1ba0e5588c5525482681db418268e5f86186 \ + --hash=sha256:415a3f719ce518e95a92effc7ee30118a25c3d032455d13e121e3840985f2efd \ + --hash=sha256:43cdeca8d30de9a897440e3fb8866f827c4c31f6c73838e3a01a14b03b067b1d \ + --hash=sha256:476f6674303ae7965730a382a8e8d7fae18b8004b7b69a56c3d8fa93968aa21c \ + --hash=sha256:4c19eb5163167489cb1e0161ae9220dadd4fc609a42649e7e84a8fa8fff7a80f \ + --hash=sha256:4ca83739c1263a044ec8b79df4eefc34bbac87191f0a513d00dd47d46e307a65 \ + --hash=sha256:528dcf7ec49fb5a84bf6fe346c1cc3c55b0e7603c2123881996ca3ad79db5bfc \ + --hash=sha256:53de12b4608290992a943801d7756f18a37b7aee284b9ffa794ee8ea8153f8e2 \ + --hash=sha256:587d92831d0115874d766b1f5fddcdde0c5b6c60f8c6111a394078ec227fca6d \ + --hash=sha256:60184e80aac3b56933c71c48d6181e630b0fbc61ae455a63322a66a23c14731a \ + --hash=sha256:6195ca908045054dd2d57eb9c39a5fe86409968b8040de8c2240186da0769da7 \ + --hash=sha256:61f1f08adfaa9cc02e0cbc94f478140385cbd52d5b3c5a657c2fceb15de8d1fb \ + --hash=sha256:72cb30894a34d3a7ab6d959b45a70abac8a2a93b6480fc5a7bfbd9c935bdc4fb \ + --hash=sha256:751f008cd2afe812a781fd6aa2fb66c620ca2e1a13b6a2152b1ad51553cb4b77 \ + --hash=sha256:89f15277d720aa57e173954d237628a8d304896364b9de745dcb722f584812c7 \ + --hash=sha256:8c32b6bba301490d9bb2bf5f631907803135e8085b6aa3e5fe5a770d46dd0160 \ + --hash=sha256:acc6783751ac9c9bc4680379edd6d286468a1dc8d7d9906cd6f1186ed682b2b0 \ + --hash=sha256:b1eb6610330a1dfba9ce142ada792f26bbef1255b75f538196a39e9e90388bf4 \ + --hash=sha256:b243b564cea2576725e77aeeda54e3e0229a168bc587d536cd69941e6797543d \ + --hash=sha256:b41822064585fea56d0116aa431fbd5137ce69dfe837b599e310034171996084 \ + --hash=sha256:bbd5c531b22928e63d0cb1868dee76123456e1de2f1cb45879e9e7a3f3f1779b \ + --hash=sha256:cf95adb0d1671fc38d8c43dd921ad5814a735e7d9b4d9e437c088002863854fd \ + --hash=sha256:e277bd18339177daa62a294256869bbe84df1fb592be2716ec62627bb8d7c81d \ + --hash=sha256:ea4e2a7cb409951988e79a469f609bba998a576e6d7b9791ae5d1e0619e1c0f2 \ + --hash=sha256:f9289065611c48147c1dd1fd344e9d57ab45f1d99b0fb26c51f1cf72cd9bcd31 \ + --hash=sha256:fd9b9e98068fa1068edfc9eabde70a7132017bdd4f362f8b4fd0abed79c33083 + # via + # ghga-event-schemas + # hexkit +pyproject-hooks==1.0.0 \ + --hash=sha256:283c11acd6b928d2f6a7c73fa0d01cb2bdc5f07c57a2eeb6e83d5e56b97976f8 \ + --hash=sha256:f271b298b97f5955d53fb12b72c1fb1948c22c1a6b70b315c54cedaca0264ef5 + # via build +pytest==7.4.2 \ + --hash=sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002 \ + --hash=sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069 + # via + # -r /workspace/requirements-dev-common.in + # pytest-asyncio + # pytest-cov + # pytest-httpx + # pytest-profiling +pytest-asyncio==0.21.1 \ + --hash=sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d \ + --hash=sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b + # via -r /workspace/requirements-dev-common.in +pytest-cov==4.1.0 \ + --hash=sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6 \ + --hash=sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a + # via -r /workspace/requirements-dev-common.in +pytest-httpx==0.26.0 \ + --hash=sha256:b489c5a7bb847551943eaee601bc35053b35dc4f5961c944305120f14a1d770a \ + --hash=sha256:ca372b94c569c0aca2f06240f6f78cc223dfbc3ab97b5700d4e14c9a73eab17a + # via -r /workspace/requirements-dev-common.in +pytest-profiling==1.7.0 \ + --hash=sha256:93938f147662225d2b8bd5af89587b979652426a8a6ffd7e73ec4a23e24b7f29 \ + --hash=sha256:999cc9ac94f2e528e3f5d43465da277429984a1c237ae9818f8cfd0b06acb019 + # via -r /workspace/requirements-dev-common.in +pyyaml==6.0 \ + --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \ + --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ + --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ + --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ + --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ + --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ + --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ + --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ + --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ + --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ + --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ + --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ + --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \ + --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ + --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ + --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ + --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ + --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ + --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \ + --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ + --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ + --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ + --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ + --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ + --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ + --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \ + --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ + --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ + --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \ + --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ + --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ + --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ + --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \ + --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ + --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ + --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ + --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ + --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \ + --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ + --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 + # via + # hexkit + # jsonschema2md + # pre-commit +referencing==0.30.2 \ + --hash=sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf \ + --hash=sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0 + # via + # jsonschema + # jsonschema-specifications +requests==2.31.0 \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 + # via + # -r /workspace/requirements-dev-common.in + # docker +rpds-py==0.10.4 \ + --hash=sha256:00a88003db3cc953f8656b59fc9af9d0637a1fb93c235814007988f8c153b2f2 \ + --hash=sha256:049098dabfe705e9638c55a3321137a821399c50940041a6fcce267a22c70db2 \ + --hash=sha256:08f07150c8ebbdbce1d2d51b8e9f4d588749a2af6a98035485ebe45c7ad9394e \ + --hash=sha256:125776d5db15162fdd9135372bef7fe4fb7c5f5810cf25898eb74a06a0816aec \ + --hash=sha256:13cbd79ccedc6b39c279af31ebfb0aec0467ad5d14641ddb15738bf6e4146157 \ + --hash=sha256:18d5ff7fbd305a1d564273e9eb22de83ae3cd9cd6329fddc8f12f6428a711a6a \ + --hash=sha256:1c27942722cd5039bbf5098c7e21935a96243fed00ea11a9589f3c6c6424bd84 \ + --hash=sha256:255a23bded80605e9f3997753e3a4b89c9aec9efb07ec036b1ca81440efcc1a9 \ + --hash=sha256:2573ec23ad3a59dd2bc622befac845695972f3f2d08dc1a4405d017d20a6c225 \ + --hash=sha256:2603e084054351cc65097da326570102c4c5bd07426ba8471ceaefdb0b642cc9 \ + --hash=sha256:28b4942ec7d9d6114c1e08cace0157db92ef674636a38093cab779ace5742d3a \ + --hash=sha256:28e29dac59df890972f73c511948072897f512974714a803fe793635b80ff8c7 \ + --hash=sha256:2a97406d5e08b7095428f01dac0d3c091dc072351151945a167e7968d2755559 \ + --hash=sha256:2a9e864ec051a58fdb6bb2e6da03942adb20273897bc70067aee283e62bbac4d \ + --hash=sha256:2e0e2e01c5f61ddf47e3ed2d1fe1c9136e780ca6222d57a2517b9b02afd4710c \ + --hash=sha256:2e79eeeff8394284b09577f36316d410525e0cf0133abb3de10660e704d3d38e \ + --hash=sha256:2f2ac8bb01f705c5caaa7fe77ffd9b03f92f1b5061b94228f6ea5eaa0fca68ad \ + --hash=sha256:32819b662e3b4c26355a4403ea2f60c0a00db45b640fe722dd12db3d2ef807fb \ + --hash=sha256:3507c459767cf24c11e9520e2a37c89674266abe8e65453e5cb66398aa47ee7b \ + --hash=sha256:362faeae52dc6ccc50c0b6a01fa2ec0830bb61c292033f3749a46040b876f4ba \ + --hash=sha256:3650eae998dc718960e90120eb45d42bd57b18b21b10cb9ee05f91bff2345d48 \ + --hash=sha256:36ff30385fb9fb3ac23a28bffdd4a230a5229ed5b15704b708b7c84bfb7fce51 \ + --hash=sha256:3bc561c183684636c0099f9c3fbab8c1671841942edbce784bb01b4707d17924 \ + --hash=sha256:3bd38b80491ef9686f719c1ad3d24d14fbd0e069988fdd4e7d1a6ffcdd7f4a13 \ + --hash=sha256:3e37f1f134037601eb4b1f46854194f0cc082435dac2ee3de11e51529f7831f2 \ + --hash=sha256:40f6e53461b19ddbb3354fe5bcf3d50d4333604ae4bf25b478333d83ca68002c \ + --hash=sha256:49db6c0a0e6626c2b97f5e7f8f7074da21cbd8ec73340c25e839a2457c007efa \ + --hash=sha256:4bcb1abecd998a72ad4e36a0fca93577fd0c059a6aacc44f16247031b98f6ff4 \ + --hash=sha256:4cb55454a20d1b935f9eaab52e6ceab624a2efd8b52927c7ae7a43e02828dbe0 \ + --hash=sha256:4f92d2372ec992c82fd7c74aa21e2a1910b3dcdc6a7e6392919a138f21d528a3 \ + --hash=sha256:576d48e1e45c211e99fc02655ade65c32a75d3e383ccfd98ce59cece133ed02c \ + --hash=sha256:58bae860d1d116e6b4e1aad0cdc48a187d5893994f56d26db0c5534df7a47afd \ + --hash=sha256:5bb3f3cb6072c73e6ec1f865d8b80419b599f1597acf33f63fbf02252aab5a03 \ + --hash=sha256:5db93f9017b384a4f194e1d89e1ce82d0a41b1fafdbbd3e0c8912baf13f2950f \ + --hash=sha256:5e41d5b334e8de4bc3f38843f31b2afa9a0c472ebf73119d3fd55cde08974bdf \ + --hash=sha256:60018626e637528a1fa64bb3a2b3e46ab7bf672052316d61c3629814d5e65052 \ + --hash=sha256:6090ba604ea06b525a231450ae5d343917a393cbf50423900dea968daf61d16f \ + --hash=sha256:628fbb8be71a103499d10b189af7764996ab2634ed7b44b423f1e19901606e0e \ + --hash=sha256:6baea8a4f6f01e69e75cfdef3edd4a4d1c4b56238febbdf123ce96d09fbff010 \ + --hash=sha256:6c5ca3eb817fb54bfd066740b64a2b31536eb8fe0b183dc35b09a7bd628ed680 \ + --hash=sha256:70563a1596d2e0660ca2cebb738443437fc0e38597e7cbb276de0a7363924a52 \ + --hash=sha256:7089d8bfa8064b28b2e39f5af7bf12d42f61caed884e35b9b4ea9e6fb1175077 \ + --hash=sha256:72e9b1e92830c876cd49565d8404e4dcc9928302d348ea2517bc3f9e3a873a2a \ + --hash=sha256:7c7ca791bedda059e5195cf7c6b77384657a51429357cdd23e64ac1d4973d6dc \ + --hash=sha256:7f050ceffd8c730c1619a16bbf0b9cd037dcdb94b54710928ba38c7bde67e4a4 \ + --hash=sha256:83da147124499fe41ed86edf34b4e81e951b3fe28edcc46288aac24e8a5c8484 \ + --hash=sha256:86e8d6ff15fa7a9590c0addaf3ce52fb58bda4299cab2c2d0afa404db6848dab \ + --hash=sha256:8709eb4ab477c533b7d0a76cd3065d7d95c9e25e6b9f6e27caeeb8c63e8799c9 \ + --hash=sha256:8e69bbe0ede8f7fe2616e779421bbdb37f025c802335a90f6416e4d98b368a37 \ + --hash=sha256:8f90fc6dd505867514c8b8ef68a712dc0be90031a773c1ae2ad469f04062daef \ + --hash=sha256:9123ba0f3f98ff79780eebca9984a2b525f88563844b740f94cffb9099701230 \ + --hash=sha256:927e3461dae0c09b1f2e0066e50c1a9204f8a64a3060f596e9a6742d3b307785 \ + --hash=sha256:94876c21512535955a960f42a155213315e6ab06a4ce8ce372341a2a1b143eeb \ + --hash=sha256:98c0aecf661c175ce9cb17347fc51a5c98c3e9189ca57e8fcd9348dae18541db \ + --hash=sha256:9c7e7bd1fa1f535af71dfcd3700fc83a6dc261a1204f8f5327d8ffe82e52905d \ + --hash=sha256:9e7b3ad9f53ea9e085b3d27286dd13f8290969c0a153f8a52c8b5c46002c374b \ + --hash=sha256:9f9184744fb800c9f28e155a5896ecb54816296ee79d5d1978be6a2ae60f53c4 \ + --hash=sha256:a3628815fd170a64624001bfb4e28946fd515bd672e68a1902d9e0290186eaf3 \ + --hash=sha256:a5c330cb125983c5d380fef4a4155248a276297c86d64625fdaf500157e1981c \ + --hash=sha256:aa45cc71bf23a3181b8aa62466b5a2b7b7fb90fdc01df67ca433cd4fce7ec94d \ + --hash=sha256:aab24b9bbaa3d49e666e9309556591aa00748bd24ea74257a405f7fed9e8b10d \ + --hash=sha256:ac83f5228459b84fa6279e4126a53abfdd73cd9cc183947ee5084153880f65d7 \ + --hash=sha256:ad21c60fc880204798f320387164dcacc25818a7b4ec2a0bf6b6c1d57b007d23 \ + --hash=sha256:ae8a32ab77a84cc870bbfb60645851ca0f7d58fd251085ad67464b1445d632ca \ + --hash=sha256:b0f1d336786cb62613c72c00578c98e5bb8cd57b49c5bae5d4ab906ca7872f98 \ + --hash=sha256:b28b9668a22ca2cfca4433441ba9acb2899624a323787a509a3dc5fbfa79c49d \ + --hash=sha256:b953d11b544ca5f2705bb77b177d8e17ab1bfd69e0fd99790a11549d2302258c \ + --hash=sha256:b9d8884d58ea8801e5906a491ab34af975091af76d1a389173db491ee7e316bb \ + --hash=sha256:ba3246c60303eab3d0e562addf25a983d60bddc36f4d1edc2510f056d19df255 \ + --hash=sha256:bd0ad98c7d72b0e4cbfe89cdfa12cd07d2fd6ed22864341cdce12b318a383442 \ + --hash=sha256:bf032367f921201deaecf221d4cc895ea84b3decf50a9c73ee106f961885a0ad \ + --hash=sha256:c31ecfc53ac03dad4928a1712f3a2893008bfba1b3cde49e1c14ff67faae2290 \ + --hash=sha256:cbec8e43cace64e63398155dc585dc479a89fef1e57ead06c22d3441e1bd09c3 \ + --hash=sha256:cc688a59c100f038fa9fec9e4ab457c2e2d1fca350fe7ea395016666f0d0a2dc \ + --hash=sha256:cd7da2adc721ccf19ac7ec86cae3a4fcaba03d9c477d5bd64ded6e9bb817bf3f \ + --hash=sha256:cd7e62e7d5bcfa38a62d8397fba6d0428b970ab7954c2197501cd1624f7f0bbb \ + --hash=sha256:d0f7f77a77c37159c9f417b8dd847f67a29e98c6acb52ee98fc6b91efbd1b2b6 \ + --hash=sha256:d230fddc60caced271cc038e43e6fb8f4dd6b2dbaa44ac9763f2d76d05b0365a \ + --hash=sha256:d37f27ad80f742ef82796af3fe091888864958ad0bc8bab03da1830fa00c6004 \ + --hash=sha256:d5ad7b1a1f6964d19b1a8acfc14bf7864f39587b3e25c16ca04f6cd1815026b3 \ + --hash=sha256:d81359911c3bb31c899c6a5c23b403bdc0279215e5b3bc0d2a692489fed38632 \ + --hash=sha256:d98802b78093c7083cc51f83da41a5be5a57d406798c9f69424bd75f8ae0812a \ + --hash=sha256:db0589e0bf41ff6ce284ab045ca89f27be1adf19e7bce26c2e7de6739a70c18b \ + --hash=sha256:ddbd113a37307638f94be5ae232a325155fd24dbfae2c56455da8724b471e7be \ + --hash=sha256:e3ece9aa6d07e18c966f14b4352a4c6f40249f6174d3d2c694c1062e19c6adbb \ + --hash=sha256:e3f9c9e5dd8eba4768e15f19044e1b5e216929a43a54b4ab329e103aed9f3eda \ + --hash=sha256:e41824343c2c129599645373992b1ce17720bb8a514f04ff9567031e1c26951e \ + --hash=sha256:e5dba1c11e089b526379e74f6c636202e4c5bad9a48c7416502b8a5b0d026c91 \ + --hash=sha256:e791e3d13b14d0a7921804d0efe4d7bd15508bbcf8cb7a0c1ee1a27319a5f033 \ + --hash=sha256:ec001689402b9104700b50a005c2d3d0218eae90eaa8bdbbd776fe78fe8a74b7 \ + --hash=sha256:efffa359cc69840c8793f0c05a7b663de6afa7b9078fa6c80309ee38b9db677d \ + --hash=sha256:f1f191befea279cb9669b57be97ab1785781c8bab805900e95742ebfaa9cbf1d \ + --hash=sha256:f3331a3684192659fa1090bf2b448db928152fcba08222e58106f44758ef25f7 \ + --hash=sha256:f40413d2859737ce6d95c29ce2dde0ef7cdc3063b5830ae4342fef5922c3bba7 \ + --hash=sha256:f7ea49ddf51d5ec0c3cbd95190dd15e077a3153c8d4b22a33da43b5dd2b3c640 \ + --hash=sha256:f82abb5c5b83dc30e96be99ce76239a030b62a73a13c64410e429660a5602bfd \ + --hash=sha256:fc20dadb102140dff63529e08ce6f9745dbd36e673ebb2b1c4a63e134bca81c2 \ + --hash=sha256:fd37ab9a24021821b715478357af1cf369d5a42ac7405e83e5822be00732f463 \ + --hash=sha256:ffd539d213c1ea2989ab92a5b9371ae7159c8c03cf2bcb9f2f594752f755ecd3 + # via + # jsonschema + # referencing +ruff==0.0.292 \ + --hash=sha256:02f29db018c9d474270c704e6c6b13b18ed0ecac82761e4fcf0faa3728430c96 \ + --hash=sha256:1093449e37dd1e9b813798f6ad70932b57cf614e5c2b5c51005bf67d55db33ac \ + --hash=sha256:69654e564342f507edfa09ee6897883ca76e331d4bbc3676d8a8403838e9fade \ + --hash=sha256:6bdfabd4334684a4418b99b3118793f2c13bb67bf1540a769d7816410402a205 \ + --hash=sha256:6c3c91859a9b845c33778f11902e7b26440d64b9d5110edd4e4fa1726c41e0a4 \ + --hash=sha256:7f67a69c8f12fbc8daf6ae6d36705037bde315abf8b82b6e1f4c9e74eb750f68 \ + --hash=sha256:87616771e72820800b8faea82edd858324b29bb99a920d6aa3d3949dd3f88fb0 \ + --hash=sha256:8e087b24d0d849c5c81516ec740bf4fd48bf363cfb104545464e0fca749b6af9 \ + --hash=sha256:9889bac18a0c07018aac75ef6c1e6511d8411724d67cb879103b01758e110a81 \ + --hash=sha256:aa7c77c53bfcd75dbcd4d1f42d6cabf2485d2e1ee0678da850f08e1ab13081a8 \ + --hash=sha256:ac153eee6dd4444501c4bb92bff866491d4bfb01ce26dd2fff7ca472c8df9ad0 \ + --hash=sha256:b76deb3bdbea2ef97db286cf953488745dd6424c122d275f05836c53f62d4016 \ + --hash=sha256:be8eb50eaf8648070b8e58ece8e69c9322d34afe367eec4210fdee9a555e4ca7 \ + --hash=sha256:e854b05408f7a8033a027e4b1c7f9889563dd2aca545d13d06711e5c39c3d003 \ + --hash=sha256:f160b5ec26be32362d0774964e218f3fcf0a7da299f7e220ef45ae9e3e67101a \ + --hash=sha256:f27282bedfd04d4c3492e5c3398360c9d86a295be00eccc63914438b4ac8a83c \ + --hash=sha256:f4476f1243af2d8c29da5f235c13dca52177117935e1f9393f9d90f9833f69e4 + # via -r /workspace/requirements-dev-common.in +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via + # dependency-injector + # pytest-profiling +snakeviz==2.2.0 \ + --hash=sha256:569e2d71c47f80a886aa6e70d6405cb6d30aa3520969ad956b06f824c5f02b8e \ + --hash=sha256:7bfd00be7ae147eb4a170a471578e1cd3f41f803238958b6b8efcf2c698a6aa9 + # via -r /workspace/requirements-dev-common.in +sniffio==1.3.0 \ + --hash=sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101 \ + --hash=sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384 + # via + # anyio + # httpcore + # httpx +stringcase==1.2.0 \ + --hash=sha256:48a06980661908efe8d9d34eab2b6c13aefa2163b3ced26972902e3bdfd87008 + # via -r /workspace/requirements-dev-common.in +testcontainers[kafka]==3.7.1 \ + --hash=sha256:7f48cef4bf0ccd78f1a4534d4b701a003a3bace851f24eae58a32f9e3f0aeba0 + # via -r /workspace/requirements-dev.in +tomli==2.0.1 \ + --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \ + --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f + # via + # -r /workspace/requirements-dev-common.in + # black + # build + # coverage + # mypy + # pip-tools + # pyproject-hooks + # pytest +tomli-w==1.0.0 \ + --hash=sha256:9f2a07e8be30a0729e533ec968016807069991ae2fd921a78d42f429ae5f4463 \ + --hash=sha256:f463434305e0336248cac9c2dc8076b707d8a12d019dd349f5c1e382dd1ae1b9 + # via -r /workspace/requirements-dev-common.in +tornado==6.3.3 \ + --hash=sha256:1bd19ca6c16882e4d37368e0152f99c099bad93e0950ce55e71daed74045908f \ + --hash=sha256:22d3c2fa10b5793da13c807e6fc38ff49a4f6e1e3868b0a6f4164768bb8e20f5 \ + --hash=sha256:502fba735c84450974fec147340016ad928d29f1e91f49be168c0a4c18181e1d \ + --hash=sha256:65ceca9500383fbdf33a98c0087cb975b2ef3bfb874cb35b8de8740cf7f41bd3 \ + --hash=sha256:71a8db65160a3c55d61839b7302a9a400074c9c753040455494e2af74e2501f2 \ + --hash=sha256:7ac51f42808cca9b3613f51ffe2a965c8525cb1b00b7b2d56828b8045354f76a \ + --hash=sha256:7d01abc57ea0dbb51ddfed477dfe22719d376119844e33c661d873bf9c0e4a16 \ + --hash=sha256:805d507b1f588320c26f7f097108eb4023bbaa984d63176d1652e184ba24270a \ + --hash=sha256:9dc4444c0defcd3929d5c1eb5706cbe1b116e762ff3e0deca8b715d14bf6ec17 \ + --hash=sha256:ceb917a50cd35882b57600709dd5421a418c29ddc852da8bcdab1f0db33406b0 \ + --hash=sha256:e7d8db41c0181c80d76c982aacc442c0783a2c54d6400fe028954201a2e032fe + # via snakeviz +typer==0.9.0 \ + --hash=sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2 \ + --hash=sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee + # via + # -r /workspace/requirements-dev-common.in + # ns (pyproject.toml) +typing-extensions==4.8.0 \ + --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \ + --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef + # via + # black + # mypy + # pydantic + # typer +urllib3==2.0.6 \ + --hash=sha256:7a7c7003b000adf9e7ca2a377c9688bbc54ed41b985789ed576570342a375cd2 \ + --hash=sha256:b19e1a85d206b56d7df1d5e683df4a7725252a964e3993648dd0fb5a1c157564 + # via + # -r /workspace/requirements-dev-common.in + # docker + # requests +virtualenv==20.24.5 \ + --hash=sha256:b80039f280f4919c77b30f1c23294ae357c4c8701042086e3fc005963e4e537b \ + --hash=sha256:e8361967f6da6fbdf1426483bfe9fca8287c242ac0bc30429905721cefbff752 + # via pre-commit +websocket-client==1.6.4 \ + --hash=sha256:084072e0a7f5f347ef2ac3d8698a5e0b4ffbfcab607628cadabc650fc9a83a24 \ + --hash=sha256:b3324019b3c28572086c4a319f91d1dcd44e6e11cd340232978c684a7650d0df + # via docker +wheel==0.41.2 \ + --hash=sha256:0c5ac5ff2afb79ac23ab82bab027a0be7b5dbcf2e54dc50efe4bf507de1f7985 \ + --hash=sha256:75909db2664838d015e3d9139004ee16711748a52c8f336b52882266540215d8 + # via pip-tools +wrapt==1.15.0 \ + --hash=sha256:02fce1852f755f44f95af51f69d22e45080102e9d00258053b79367d07af39c0 \ + --hash=sha256:077ff0d1f9d9e4ce6476c1a924a3332452c1406e59d90a2cf24aeb29eeac9420 \ + --hash=sha256:078e2a1a86544e644a68422f881c48b84fef6d18f8c7a957ffd3f2e0a74a0d4a \ + --hash=sha256:0970ddb69bba00670e58955f8019bec4a42d1785db3faa043c33d81de2bf843c \ + --hash=sha256:1286eb30261894e4c70d124d44b7fd07825340869945c79d05bda53a40caa079 \ + --hash=sha256:21f6d9a0d5b3a207cdf7acf8e58d7d13d463e639f0c7e01d82cdb671e6cb7923 \ + --hash=sha256:230ae493696a371f1dbffaad3dafbb742a4d27a0afd2b1aecebe52b740167e7f \ + --hash=sha256:26458da5653aa5b3d8dc8b24192f574a58984c749401f98fff994d41d3f08da1 \ + --hash=sha256:2cf56d0e237280baed46f0b5316661da892565ff58309d4d2ed7dba763d984b8 \ + --hash=sha256:2e51de54d4fb8fb50d6ee8327f9828306a959ae394d3e01a1ba8b2f937747d86 \ + --hash=sha256:2fbfbca668dd15b744418265a9607baa970c347eefd0db6a518aaf0cfbd153c0 \ + --hash=sha256:38adf7198f8f154502883242f9fe7333ab05a5b02de7d83aa2d88ea621f13364 \ + --hash=sha256:3a8564f283394634a7a7054b7983e47dbf39c07712d7b177b37e03f2467a024e \ + --hash=sha256:3abbe948c3cbde2689370a262a8d04e32ec2dd4f27103669a45c6929bcdbfe7c \ + --hash=sha256:3bbe623731d03b186b3d6b0d6f51865bf598587c38d6f7b0be2e27414f7f214e \ + --hash=sha256:40737a081d7497efea35ab9304b829b857f21558acfc7b3272f908d33b0d9d4c \ + --hash=sha256:41d07d029dd4157ae27beab04d22b8e261eddfc6ecd64ff7000b10dc8b3a5727 \ + --hash=sha256:46ed616d5fb42f98630ed70c3529541408166c22cdfd4540b88d5f21006b0eff \ + --hash=sha256:493d389a2b63c88ad56cdc35d0fa5752daac56ca755805b1b0c530f785767d5e \ + --hash=sha256:4ff0d20f2e670800d3ed2b220d40984162089a6e2c9646fdb09b85e6f9a8fc29 \ + --hash=sha256:54accd4b8bc202966bafafd16e69da9d5640ff92389d33d28555c5fd4f25ccb7 \ + --hash=sha256:56374914b132c702aa9aa9959c550004b8847148f95e1b824772d453ac204a72 \ + --hash=sha256:578383d740457fa790fdf85e6d346fda1416a40549fe8db08e5e9bd281c6a475 \ + --hash=sha256:58d7a75d731e8c63614222bcb21dd992b4ab01a399f1f09dd82af17bbfc2368a \ + --hash=sha256:5c5aa28df055697d7c37d2099a7bc09f559d5053c3349b1ad0c39000e611d317 \ + --hash=sha256:5fc8e02f5984a55d2c653f5fea93531e9836abbd84342c1d1e17abc4a15084c2 \ + --hash=sha256:63424c681923b9f3bfbc5e3205aafe790904053d42ddcc08542181a30a7a51bd \ + --hash=sha256:64b1df0f83706b4ef4cfb4fb0e4c2669100fd7ecacfb59e091fad300d4e04640 \ + --hash=sha256:74934ebd71950e3db69960a7da29204f89624dde411afbfb3b4858c1409b1e98 \ + --hash=sha256:75669d77bb2c071333417617a235324a1618dba66f82a750362eccbe5b61d248 \ + --hash=sha256:75760a47c06b5974aa5e01949bf7e66d2af4d08cb8c1d6516af5e39595397f5e \ + --hash=sha256:76407ab327158c510f44ded207e2f76b657303e17cb7a572ffe2f5a8a48aa04d \ + --hash=sha256:76e9c727a874b4856d11a32fb0b389afc61ce8aaf281ada613713ddeadd1cfec \ + --hash=sha256:77d4c1b881076c3ba173484dfa53d3582c1c8ff1f914c6461ab70c8428b796c1 \ + --hash=sha256:780c82a41dc493b62fc5884fb1d3a3b81106642c5c5c78d6a0d4cbe96d62ba7e \ + --hash=sha256:7dc0713bf81287a00516ef43137273b23ee414fe41a3c14be10dd95ed98a2df9 \ + --hash=sha256:7eebcdbe3677e58dd4c0e03b4f2cfa346ed4049687d839adad68cc38bb559c92 \ + --hash=sha256:896689fddba4f23ef7c718279e42f8834041a21342d95e56922e1c10c0cc7afb \ + --hash=sha256:96177eb5645b1c6985f5c11d03fc2dbda9ad24ec0f3a46dcce91445747e15094 \ + --hash=sha256:96e25c8603a155559231c19c0349245eeb4ac0096fe3c1d0be5c47e075bd4f46 \ + --hash=sha256:9d37ac69edc5614b90516807de32d08cb8e7b12260a285ee330955604ed9dd29 \ + --hash=sha256:9ed6aa0726b9b60911f4aed8ec5b8dd7bf3491476015819f56473ffaef8959bd \ + --hash=sha256:a487f72a25904e2b4bbc0817ce7a8de94363bd7e79890510174da9d901c38705 \ + --hash=sha256:a4cbb9ff5795cd66f0066bdf5947f170f5d63a9274f99bdbca02fd973adcf2a8 \ + --hash=sha256:a74d56552ddbde46c246b5b89199cb3fd182f9c346c784e1a93e4dc3f5ec9975 \ + --hash=sha256:a89ce3fd220ff144bd9d54da333ec0de0399b52c9ac3d2ce34b569cf1a5748fb \ + --hash=sha256:abd52a09d03adf9c763d706df707c343293d5d106aea53483e0ec8d9e310ad5e \ + --hash=sha256:abd8f36c99512755b8456047b7be10372fca271bf1467a1caa88db991e7c421b \ + --hash=sha256:af5bd9ccb188f6a5fdda9f1f09d9f4c86cc8a539bd48a0bfdc97723970348418 \ + --hash=sha256:b02f21c1e2074943312d03d243ac4388319f2456576b2c6023041c4d57cd7019 \ + --hash=sha256:b06fa97478a5f478fb05e1980980a7cdf2712015493b44d0c87606c1513ed5b1 \ + --hash=sha256:b0724f05c396b0a4c36a3226c31648385deb6a65d8992644c12a4963c70326ba \ + --hash=sha256:b130fe77361d6771ecf5a219d8e0817d61b236b7d8b37cc045172e574ed219e6 \ + --hash=sha256:b56d5519e470d3f2fe4aa7585f0632b060d532d0696c5bdfb5e8319e1d0f69a2 \ + --hash=sha256:b67b819628e3b748fd3c2192c15fb951f549d0f47c0449af0764d7647302fda3 \ + --hash=sha256:ba1711cda2d30634a7e452fc79eabcadaffedf241ff206db2ee93dd2c89a60e7 \ + --hash=sha256:bbeccb1aa40ab88cd29e6c7d8585582c99548f55f9b2581dfc5ba68c59a85752 \ + --hash=sha256:bd84395aab8e4d36263cd1b9308cd504f6cf713b7d6d3ce25ea55670baec5416 \ + --hash=sha256:c99f4309f5145b93eca6e35ac1a988f0dc0a7ccf9ccdcd78d3c0adf57224e62f \ + --hash=sha256:ca1cccf838cd28d5a0883b342474c630ac48cac5df0ee6eacc9c7290f76b11c1 \ + --hash=sha256:cd525e0e52a5ff16653a3fc9e3dd827981917d34996600bbc34c05d048ca35cc \ + --hash=sha256:cdb4f085756c96a3af04e6eca7f08b1345e94b53af8921b25c72f096e704e145 \ + --hash=sha256:ce42618f67741d4697684e501ef02f29e758a123aa2d669e2d964ff734ee00ee \ + --hash=sha256:d06730c6aed78cee4126234cf2d071e01b44b915e725a6cb439a879ec9754a3a \ + --hash=sha256:d5fe3e099cf07d0fb5a1e23d399e5d4d1ca3e6dfcbe5c8570ccff3e9208274f7 \ + --hash=sha256:d6bcbfc99f55655c3d93feb7ef3800bd5bbe963a755687cbf1f490a71fb7794b \ + --hash=sha256:d787272ed958a05b2c86311d3a4135d3c2aeea4fc655705f074130aa57d71653 \ + --hash=sha256:e169e957c33576f47e21864cf3fc9ff47c223a4ebca8960079b8bd36cb014fd0 \ + --hash=sha256:e20076a211cd6f9b44a6be58f7eeafa7ab5720eb796975d0c03f05b47d89eb90 \ + --hash=sha256:e826aadda3cae59295b95343db8f3d965fb31059da7de01ee8d1c40a60398b29 \ + --hash=sha256:eef4d64c650f33347c1f9266fa5ae001440b232ad9b98f1f43dfe7a79435c0a6 \ + --hash=sha256:f2e69b3ed24544b0d3dbe2c5c0ba5153ce50dcebb576fdc4696d52aa22db6034 \ + --hash=sha256:f87ec75864c37c4c6cb908d282e1969e79763e0d9becdfe9fe5473b7bb1e5f09 \ + --hash=sha256:fbec11614dba0424ca72f4e8ba3c420dba07b4a7c206c8c8e4e73f2e98f4c559 \ + --hash=sha256:fd69666217b62fa5d7c6aa88e507493a34dec4fa20c5bd925e4bc12fce586639 + # via testcontainers +zipp==3.17.0 \ + --hash=sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31 \ + --hash=sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0 + # via importlib-metadata --r requirements-dev-common.txt - -# additional requirements can be listed here -testcontainers[kafka]==3.4.1 -aiosmtpd==1.4.4.post2 +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes and the requirement is not +# satisfied by a package already installed. Consider using the --allow-unsafe flag. +# pip +# setuptools diff --git a/requirements.txt b/requirements.txt index 1783b07..165c8f5 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,405 @@ -# requirements for complete installation - -# the ".[all]" states that requirements including the "all" extra are taken from setup.cfg -.[all] +# +# 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/tmp8mqf6xoh/pyproject.toml +# +aiokafka==0.8.0 \ + --hash=sha256:021e9f0027ca63c6c04daccfdd0e985f7a56d51bd0d43f482f674a58fada52f5 \ + --hash=sha256:0e9d61912678ecae6b3d407107c1a935f21d55af4585b70d8f5dcc39ecb949ce \ + --hash=sha256:12457b59a06cff7369cace8d4460049b2ef2ab7f7cdc9c4924d577b9d4b48bf9 \ + --hash=sha256:1c3fd832a06fdd68e82f100fe678a800dd6dbf5e8db6af9521be333f965c325b \ + --hash=sha256:23f1fbdf54790a3751216e33e62228c8e1eb7feebcb19ef532cd3e4f13ae51ce \ + --hash=sha256:2567465ee6de4d248fc416f2eef7d33bbe246a79073410ae2368b5bdaeb758c1 \ + --hash=sha256:2760f095a8ffb5b9b97ad28a43a6a93f38d67cf3bc95b42e6b27462b614c8561 \ + --hash=sha256:4439a03820dc64a8c3aa5fe17809541e6a001f6f6196aad6b6b88e7ded2b5396 \ + --hash=sha256:49b30479f68ba9a484a0e3362fb9c48797d7320066db9fcd53e755451f389acb \ + --hash=sha256:5202073bb8d2350b72805d45ff0125c800ed101506a4ba7be2f03ad1ba8ad1e6 \ + --hash=sha256:539d8584652e354e7f7bbaf8843e936d91bfc28e224a53a82e1bcb64ac7f6dda \ + --hash=sha256:57aa55b48004da9bf5a5d37d3412c2d373b0bf32118bdc5c78cc5635998674cc \ + --hash=sha256:5a8038698a47333cdb0cd198cb4b3ccd2fbbc86ba9a4b9afc3eebe6544db0c2f \ + --hash=sha256:65e1d27a1c1cd38c66e0b22928af74b192f7598da9acd5bb939c6acea5bb5036 \ + --hash=sha256:6f50a940411ae6cd0d7bcaf2d821539e3a59b6de012f77de18a573565c9f638f \ + --hash=sha256:7e292841beda7cfdcd6939aab6cc2a623acd3d655b166f7ff97c658f14ced8c5 \ + --hash=sha256:881209100355a92696c6501ba1c2b32127bb1f7f2f318b400b3973ab0b52efed \ + --hash=sha256:8857cbd76e97186e54b98ebb3ea7778fb3618826bb9e4d01375bfab0a1d93d69 \ + --hash=sha256:9364eb81340b3a70a1222a4701c73a49ea0026a79bf138b4aec342f012d6f039 \ + --hash=sha256:95682f661f295fac2f5f3f0132aea7c44a1b6c92726161daa509af67ac506885 \ + --hash=sha256:9bf6d0da5804ae8888c357034d1a6750baa610999181e930678da0e87cec610d \ + --hash=sha256:b36066df820e30f56386deb56d72efba287ba65419848888ea4b42f9e2741cff \ + --hash=sha256:b86e3c1d649824103427c021593d75f44e01db1ffbc880b154e04098b534355f \ + --hash=sha256:d459ab92a360cac240cf10b9ce88e64c1e41d942c7f63b1df6c2aafe27f946d0 \ + --hash=sha256:dea214c2588237cf0d404624ccd99f466a2e853ca22d7153bb680b2d3f25cdde \ + --hash=sha256:dfb6dfef6c18726a783d102a6c1b0dfb6d43785a46ff34e967ddfa8f774532dd \ + --hash=sha256:e005b53597fe9bc6681a2a3b50728d235cf2fb8801e52790678c691c85383565 \ + --hash=sha256:e07f07290a150552273c02bc5109d0a40bc0f32abc0ae5aeaa1e54fb86369251 \ + --hash=sha256:ec896d114be157a886e3227bbe3f00658dc4d6f17b203bc44075650817703f0b \ + --hash=sha256:f0a216a27f05b050d5a5308fb3444014fa6bca5f0cd63468eaa169c5f19ea1dd \ + --hash=sha256:f3f96301337fa7f7242f46651619b8e9e8fa8f23902dc11416fe764436d662d3 + # via + # -c /workspace/requirements-dev.txt + # hexkit +async-timeout==4.0.3 \ + --hash=sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f \ + --hash=sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028 + # via + # -c /workspace/requirements-dev.txt + # aiokafka +attrs==23.1.0 \ + --hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \ + --hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015 + # via + # -c /workspace/requirements-dev.txt + # jsonschema + # referencing +click==8.1.7 \ + --hash=sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28 \ + --hash=sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de + # via + # -c /workspace/requirements-dev.txt + # typer +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 +dnspython==2.3.0 \ + --hash=sha256:224e32b03eb46be70e12ef6d64e0be123a64e621ab4c0822ff6d450d52a540b9 \ + --hash=sha256:89141536394f909066cabd112e3e1a37e4e654db00a25308b0f130bc3152eb46 + # via + # -c /workspace/requirements-dev.txt + # email-validator + # ghga-event-schemas +email-validator==2.0.0.post2 \ + --hash=sha256:1ff6e86044200c56ae23595695c54e9614f4a9551e0e393614f764860b3d7900 \ + --hash=sha256:2466ba57cda361fb7309fd3d5a225723c788ca4bbad32a0ebd5373b99730285c + # via + # -c /workspace/requirements-dev.txt + # pydantic +ghga-event-schemas==0.13.4 \ + --hash=sha256:8bdc98ad0c7d2d7d82b1dd9490a933fcf9c25424fcd6d28d6728fc7f5979e553 \ + --hash=sha256:eee2495a8b857016c8e03faa0b739ae7e03125d5a608a5ec31987e24a3433443 + # via + # -c /workspace/requirements-dev.txt + # ns (pyproject.toml) +hexkit[akafka]==0.10.2 \ + --hash=sha256:1495f2bc6ae7423874bc20367dd28555cd15a74ccf5cb4997e0fb8307757987e \ + --hash=sha256:436ea50e706ab616803eb85a9a9f5e7bec727379b750b966650d6e64d4ea5ef0 + # via + # -c /workspace/requirements-dev.txt + # ns (pyproject.toml) +idna==3.4 \ + --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ + --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 + # via + # -c /workspace/requirements-dev.txt + # email-validator +jsonschema==4.19.1 \ + --hash=sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e \ + --hash=sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf + # via + # -c /workspace/requirements-dev.txt + # ghga-event-schemas + # hexkit +jsonschema-specifications==2023.7.1 \ + --hash=sha256:05adf340b659828a004220a9613be00fa3f223f2b82002e273dee62fd50524b1 \ + --hash=sha256:c91a50404e88a1f6ba40636778e2ee08f6e24c5613fe4c53ac24578a5a7f72bb + # via + # -c /workspace/requirements-dev.txt + # jsonschema +kafka-python==2.0.2 \ + --hash=sha256:04dfe7fea2b63726cd6f3e79a2d86e709d608d74406638c5da33a01d45a9d7e3 \ + --hash=sha256:2d92418c7cb1c298fa6c7f0fb3519b520d0d7526ac6cb7ae2a4fc65a51a94b6e + # via + # -c /workspace/requirements-dev.txt + # aiokafka +packaging==23.2 \ + --hash=sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5 \ + --hash=sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7 + # via + # -c /workspace/requirements-dev.txt + # aiokafka +pydantic[email]==1.10.6 \ + --hash=sha256:012c99a9c0d18cfde7469aa1ebff922e24b0c706d03ead96940f5465f2c9cf62 \ + --hash=sha256:0abd9c60eee6201b853b6c4be104edfba4f8f6c5f3623f8e1dba90634d63eb35 \ + --hash=sha256:12e837fd320dd30bd625be1b101e3b62edc096a49835392dcf418f1a5ac2b832 \ + --hash=sha256:163e79386c3547c49366e959d01e37fc30252285a70619ffc1b10ede4758250a \ + --hash=sha256:189318051c3d57821f7233ecc94708767dd67687a614a4e8f92b4a020d4ffd06 \ + --hash=sha256:1c84583b9df62522829cbc46e2b22e0ec11445625b5acd70c5681ce09c9b11c4 \ + --hash=sha256:3091d2eaeda25391405e36c2fc2ed102b48bac4b384d42b2267310abae350ca6 \ + --hash=sha256:32937835e525d92c98a1512218db4eed9ddc8f4ee2a78382d77f54341972c0e7 \ + --hash=sha256:3a2be0a0f32c83265fd71a45027201e1278beaa82ea88ea5b345eea6afa9ac7f \ + --hash=sha256:3ac1cd4deed871dfe0c5f63721e29debf03e2deefa41b3ed5eb5f5df287c7b70 \ + --hash=sha256:3ce13a558b484c9ae48a6a7c184b1ba0e5588c5525482681db418268e5f86186 \ + --hash=sha256:415a3f719ce518e95a92effc7ee30118a25c3d032455d13e121e3840985f2efd \ + --hash=sha256:43cdeca8d30de9a897440e3fb8866f827c4c31f6c73838e3a01a14b03b067b1d \ + --hash=sha256:476f6674303ae7965730a382a8e8d7fae18b8004b7b69a56c3d8fa93968aa21c \ + --hash=sha256:4c19eb5163167489cb1e0161ae9220dadd4fc609a42649e7e84a8fa8fff7a80f \ + --hash=sha256:4ca83739c1263a044ec8b79df4eefc34bbac87191f0a513d00dd47d46e307a65 \ + --hash=sha256:528dcf7ec49fb5a84bf6fe346c1cc3c55b0e7603c2123881996ca3ad79db5bfc \ + --hash=sha256:53de12b4608290992a943801d7756f18a37b7aee284b9ffa794ee8ea8153f8e2 \ + --hash=sha256:587d92831d0115874d766b1f5fddcdde0c5b6c60f8c6111a394078ec227fca6d \ + --hash=sha256:60184e80aac3b56933c71c48d6181e630b0fbc61ae455a63322a66a23c14731a \ + --hash=sha256:6195ca908045054dd2d57eb9c39a5fe86409968b8040de8c2240186da0769da7 \ + --hash=sha256:61f1f08adfaa9cc02e0cbc94f478140385cbd52d5b3c5a657c2fceb15de8d1fb \ + --hash=sha256:72cb30894a34d3a7ab6d959b45a70abac8a2a93b6480fc5a7bfbd9c935bdc4fb \ + --hash=sha256:751f008cd2afe812a781fd6aa2fb66c620ca2e1a13b6a2152b1ad51553cb4b77 \ + --hash=sha256:89f15277d720aa57e173954d237628a8d304896364b9de745dcb722f584812c7 \ + --hash=sha256:8c32b6bba301490d9bb2bf5f631907803135e8085b6aa3e5fe5a770d46dd0160 \ + --hash=sha256:acc6783751ac9c9bc4680379edd6d286468a1dc8d7d9906cd6f1186ed682b2b0 \ + --hash=sha256:b1eb6610330a1dfba9ce142ada792f26bbef1255b75f538196a39e9e90388bf4 \ + --hash=sha256:b243b564cea2576725e77aeeda54e3e0229a168bc587d536cd69941e6797543d \ + --hash=sha256:b41822064585fea56d0116aa431fbd5137ce69dfe837b599e310034171996084 \ + --hash=sha256:bbd5c531b22928e63d0cb1868dee76123456e1de2f1cb45879e9e7a3f3f1779b \ + --hash=sha256:cf95adb0d1671fc38d8c43dd921ad5814a735e7d9b4d9e437c088002863854fd \ + --hash=sha256:e277bd18339177daa62a294256869bbe84df1fb592be2716ec62627bb8d7c81d \ + --hash=sha256:ea4e2a7cb409951988e79a469f609bba998a576e6d7b9791ae5d1e0619e1c0f2 \ + --hash=sha256:f9289065611c48147c1dd1fd344e9d57ab45f1d99b0fb26c51f1cf72cd9bcd31 \ + --hash=sha256:fd9b9e98068fa1068edfc9eabde70a7132017bdd4f362f8b4fd0abed79c33083 + # via + # -c /workspace/requirements-dev.txt + # ghga-event-schemas + # hexkit +pyyaml==6.0 \ + --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \ + --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ + --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ + --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ + --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ + --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ + --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ + --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ + --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ + --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ + --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ + --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ + --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \ + --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ + --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ + --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ + --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ + --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ + --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \ + --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ + --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ + --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ + --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ + --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ + --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ + --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \ + --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ + --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ + --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \ + --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ + --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ + --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ + --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \ + --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ + --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ + --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ + --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ + --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \ + --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ + --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 + # via + # -c /workspace/requirements-dev.txt + # hexkit +referencing==0.30.2 \ + --hash=sha256:449b6669b6121a9e96a7f9e410b245d471e8d48964c67113ce9afe50c8dd7bdf \ + --hash=sha256:794ad8003c65938edcdbc027f1933215e0d0ccc0291e3ce20a4d87432b59efc0 + # via + # -c /workspace/requirements-dev.txt + # jsonschema + # jsonschema-specifications +rpds-py==0.10.4 \ + --hash=sha256:00a88003db3cc953f8656b59fc9af9d0637a1fb93c235814007988f8c153b2f2 \ + --hash=sha256:049098dabfe705e9638c55a3321137a821399c50940041a6fcce267a22c70db2 \ + --hash=sha256:08f07150c8ebbdbce1d2d51b8e9f4d588749a2af6a98035485ebe45c7ad9394e \ + --hash=sha256:125776d5db15162fdd9135372bef7fe4fb7c5f5810cf25898eb74a06a0816aec \ + --hash=sha256:13cbd79ccedc6b39c279af31ebfb0aec0467ad5d14641ddb15738bf6e4146157 \ + --hash=sha256:18d5ff7fbd305a1d564273e9eb22de83ae3cd9cd6329fddc8f12f6428a711a6a \ + --hash=sha256:1c27942722cd5039bbf5098c7e21935a96243fed00ea11a9589f3c6c6424bd84 \ + --hash=sha256:255a23bded80605e9f3997753e3a4b89c9aec9efb07ec036b1ca81440efcc1a9 \ + --hash=sha256:2573ec23ad3a59dd2bc622befac845695972f3f2d08dc1a4405d017d20a6c225 \ + --hash=sha256:2603e084054351cc65097da326570102c4c5bd07426ba8471ceaefdb0b642cc9 \ + --hash=sha256:28b4942ec7d9d6114c1e08cace0157db92ef674636a38093cab779ace5742d3a \ + --hash=sha256:28e29dac59df890972f73c511948072897f512974714a803fe793635b80ff8c7 \ + --hash=sha256:2a97406d5e08b7095428f01dac0d3c091dc072351151945a167e7968d2755559 \ + --hash=sha256:2a9e864ec051a58fdb6bb2e6da03942adb20273897bc70067aee283e62bbac4d \ + --hash=sha256:2e0e2e01c5f61ddf47e3ed2d1fe1c9136e780ca6222d57a2517b9b02afd4710c \ + --hash=sha256:2e79eeeff8394284b09577f36316d410525e0cf0133abb3de10660e704d3d38e \ + --hash=sha256:2f2ac8bb01f705c5caaa7fe77ffd9b03f92f1b5061b94228f6ea5eaa0fca68ad \ + --hash=sha256:32819b662e3b4c26355a4403ea2f60c0a00db45b640fe722dd12db3d2ef807fb \ + --hash=sha256:3507c459767cf24c11e9520e2a37c89674266abe8e65453e5cb66398aa47ee7b \ + --hash=sha256:362faeae52dc6ccc50c0b6a01fa2ec0830bb61c292033f3749a46040b876f4ba \ + --hash=sha256:3650eae998dc718960e90120eb45d42bd57b18b21b10cb9ee05f91bff2345d48 \ + --hash=sha256:36ff30385fb9fb3ac23a28bffdd4a230a5229ed5b15704b708b7c84bfb7fce51 \ + --hash=sha256:3bc561c183684636c0099f9c3fbab8c1671841942edbce784bb01b4707d17924 \ + --hash=sha256:3bd38b80491ef9686f719c1ad3d24d14fbd0e069988fdd4e7d1a6ffcdd7f4a13 \ + --hash=sha256:3e37f1f134037601eb4b1f46854194f0cc082435dac2ee3de11e51529f7831f2 \ + --hash=sha256:40f6e53461b19ddbb3354fe5bcf3d50d4333604ae4bf25b478333d83ca68002c \ + --hash=sha256:49db6c0a0e6626c2b97f5e7f8f7074da21cbd8ec73340c25e839a2457c007efa \ + --hash=sha256:4bcb1abecd998a72ad4e36a0fca93577fd0c059a6aacc44f16247031b98f6ff4 \ + --hash=sha256:4cb55454a20d1b935f9eaab52e6ceab624a2efd8b52927c7ae7a43e02828dbe0 \ + --hash=sha256:4f92d2372ec992c82fd7c74aa21e2a1910b3dcdc6a7e6392919a138f21d528a3 \ + --hash=sha256:576d48e1e45c211e99fc02655ade65c32a75d3e383ccfd98ce59cece133ed02c \ + --hash=sha256:58bae860d1d116e6b4e1aad0cdc48a187d5893994f56d26db0c5534df7a47afd \ + --hash=sha256:5bb3f3cb6072c73e6ec1f865d8b80419b599f1597acf33f63fbf02252aab5a03 \ + --hash=sha256:5db93f9017b384a4f194e1d89e1ce82d0a41b1fafdbbd3e0c8912baf13f2950f \ + --hash=sha256:5e41d5b334e8de4bc3f38843f31b2afa9a0c472ebf73119d3fd55cde08974bdf \ + --hash=sha256:60018626e637528a1fa64bb3a2b3e46ab7bf672052316d61c3629814d5e65052 \ + --hash=sha256:6090ba604ea06b525a231450ae5d343917a393cbf50423900dea968daf61d16f \ + --hash=sha256:628fbb8be71a103499d10b189af7764996ab2634ed7b44b423f1e19901606e0e \ + --hash=sha256:6baea8a4f6f01e69e75cfdef3edd4a4d1c4b56238febbdf123ce96d09fbff010 \ + --hash=sha256:6c5ca3eb817fb54bfd066740b64a2b31536eb8fe0b183dc35b09a7bd628ed680 \ + --hash=sha256:70563a1596d2e0660ca2cebb738443437fc0e38597e7cbb276de0a7363924a52 \ + --hash=sha256:7089d8bfa8064b28b2e39f5af7bf12d42f61caed884e35b9b4ea9e6fb1175077 \ + --hash=sha256:72e9b1e92830c876cd49565d8404e4dcc9928302d348ea2517bc3f9e3a873a2a \ + --hash=sha256:7c7ca791bedda059e5195cf7c6b77384657a51429357cdd23e64ac1d4973d6dc \ + --hash=sha256:7f050ceffd8c730c1619a16bbf0b9cd037dcdb94b54710928ba38c7bde67e4a4 \ + --hash=sha256:83da147124499fe41ed86edf34b4e81e951b3fe28edcc46288aac24e8a5c8484 \ + --hash=sha256:86e8d6ff15fa7a9590c0addaf3ce52fb58bda4299cab2c2d0afa404db6848dab \ + --hash=sha256:8709eb4ab477c533b7d0a76cd3065d7d95c9e25e6b9f6e27caeeb8c63e8799c9 \ + --hash=sha256:8e69bbe0ede8f7fe2616e779421bbdb37f025c802335a90f6416e4d98b368a37 \ + --hash=sha256:8f90fc6dd505867514c8b8ef68a712dc0be90031a773c1ae2ad469f04062daef \ + --hash=sha256:9123ba0f3f98ff79780eebca9984a2b525f88563844b740f94cffb9099701230 \ + --hash=sha256:927e3461dae0c09b1f2e0066e50c1a9204f8a64a3060f596e9a6742d3b307785 \ + --hash=sha256:94876c21512535955a960f42a155213315e6ab06a4ce8ce372341a2a1b143eeb \ + --hash=sha256:98c0aecf661c175ce9cb17347fc51a5c98c3e9189ca57e8fcd9348dae18541db \ + --hash=sha256:9c7e7bd1fa1f535af71dfcd3700fc83a6dc261a1204f8f5327d8ffe82e52905d \ + --hash=sha256:9e7b3ad9f53ea9e085b3d27286dd13f8290969c0a153f8a52c8b5c46002c374b \ + --hash=sha256:9f9184744fb800c9f28e155a5896ecb54816296ee79d5d1978be6a2ae60f53c4 \ + --hash=sha256:a3628815fd170a64624001bfb4e28946fd515bd672e68a1902d9e0290186eaf3 \ + --hash=sha256:a5c330cb125983c5d380fef4a4155248a276297c86d64625fdaf500157e1981c \ + --hash=sha256:aa45cc71bf23a3181b8aa62466b5a2b7b7fb90fdc01df67ca433cd4fce7ec94d \ + --hash=sha256:aab24b9bbaa3d49e666e9309556591aa00748bd24ea74257a405f7fed9e8b10d \ + --hash=sha256:ac83f5228459b84fa6279e4126a53abfdd73cd9cc183947ee5084153880f65d7 \ + --hash=sha256:ad21c60fc880204798f320387164dcacc25818a7b4ec2a0bf6b6c1d57b007d23 \ + --hash=sha256:ae8a32ab77a84cc870bbfb60645851ca0f7d58fd251085ad67464b1445d632ca \ + --hash=sha256:b0f1d336786cb62613c72c00578c98e5bb8cd57b49c5bae5d4ab906ca7872f98 \ + --hash=sha256:b28b9668a22ca2cfca4433441ba9acb2899624a323787a509a3dc5fbfa79c49d \ + --hash=sha256:b953d11b544ca5f2705bb77b177d8e17ab1bfd69e0fd99790a11549d2302258c \ + --hash=sha256:b9d8884d58ea8801e5906a491ab34af975091af76d1a389173db491ee7e316bb \ + --hash=sha256:ba3246c60303eab3d0e562addf25a983d60bddc36f4d1edc2510f056d19df255 \ + --hash=sha256:bd0ad98c7d72b0e4cbfe89cdfa12cd07d2fd6ed22864341cdce12b318a383442 \ + --hash=sha256:bf032367f921201deaecf221d4cc895ea84b3decf50a9c73ee106f961885a0ad \ + --hash=sha256:c31ecfc53ac03dad4928a1712f3a2893008bfba1b3cde49e1c14ff67faae2290 \ + --hash=sha256:cbec8e43cace64e63398155dc585dc479a89fef1e57ead06c22d3441e1bd09c3 \ + --hash=sha256:cc688a59c100f038fa9fec9e4ab457c2e2d1fca350fe7ea395016666f0d0a2dc \ + --hash=sha256:cd7da2adc721ccf19ac7ec86cae3a4fcaba03d9c477d5bd64ded6e9bb817bf3f \ + --hash=sha256:cd7e62e7d5bcfa38a62d8397fba6d0428b970ab7954c2197501cd1624f7f0bbb \ + --hash=sha256:d0f7f77a77c37159c9f417b8dd847f67a29e98c6acb52ee98fc6b91efbd1b2b6 \ + --hash=sha256:d230fddc60caced271cc038e43e6fb8f4dd6b2dbaa44ac9763f2d76d05b0365a \ + --hash=sha256:d37f27ad80f742ef82796af3fe091888864958ad0bc8bab03da1830fa00c6004 \ + --hash=sha256:d5ad7b1a1f6964d19b1a8acfc14bf7864f39587b3e25c16ca04f6cd1815026b3 \ + --hash=sha256:d81359911c3bb31c899c6a5c23b403bdc0279215e5b3bc0d2a692489fed38632 \ + --hash=sha256:d98802b78093c7083cc51f83da41a5be5a57d406798c9f69424bd75f8ae0812a \ + --hash=sha256:db0589e0bf41ff6ce284ab045ca89f27be1adf19e7bce26c2e7de6739a70c18b \ + --hash=sha256:ddbd113a37307638f94be5ae232a325155fd24dbfae2c56455da8724b471e7be \ + --hash=sha256:e3ece9aa6d07e18c966f14b4352a4c6f40249f6174d3d2c694c1062e19c6adbb \ + --hash=sha256:e3f9c9e5dd8eba4768e15f19044e1b5e216929a43a54b4ab329e103aed9f3eda \ + --hash=sha256:e41824343c2c129599645373992b1ce17720bb8a514f04ff9567031e1c26951e \ + --hash=sha256:e5dba1c11e089b526379e74f6c636202e4c5bad9a48c7416502b8a5b0d026c91 \ + --hash=sha256:e791e3d13b14d0a7921804d0efe4d7bd15508bbcf8cb7a0c1ee1a27319a5f033 \ + --hash=sha256:ec001689402b9104700b50a005c2d3d0218eae90eaa8bdbbd776fe78fe8a74b7 \ + --hash=sha256:efffa359cc69840c8793f0c05a7b663de6afa7b9078fa6c80309ee38b9db677d \ + --hash=sha256:f1f191befea279cb9669b57be97ab1785781c8bab805900e95742ebfaa9cbf1d \ + --hash=sha256:f3331a3684192659fa1090bf2b448db928152fcba08222e58106f44758ef25f7 \ + --hash=sha256:f40413d2859737ce6d95c29ce2dde0ef7cdc3063b5830ae4342fef5922c3bba7 \ + --hash=sha256:f7ea49ddf51d5ec0c3cbd95190dd15e077a3153c8d4b22a33da43b5dd2b3c640 \ + --hash=sha256:f82abb5c5b83dc30e96be99ce76239a030b62a73a13c64410e429660a5602bfd \ + --hash=sha256:fc20dadb102140dff63529e08ce6f9745dbd36e673ebb2b1c4a63e134bca81c2 \ + --hash=sha256:fd37ab9a24021821b715478357af1cf369d5a42ac7405e83e5822be00732f463 \ + --hash=sha256:ffd539d213c1ea2989ab92a5b9371ae7159c8c03cf2bcb9f2f594752f755ecd3 + # via + # -c /workspace/requirements-dev.txt + # jsonschema + # referencing +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via + # -c /workspace/requirements-dev.txt + # dependency-injector +typer==0.9.0 \ + --hash=sha256:50922fd79aea2f4751a8e0408ff10d2662bd0c8bbfa84755a699f3bada2978b2 \ + --hash=sha256:5d96d986a21493606a358cae4461bd8cdf83cbf33a5aa950ae629ca3b51467ee + # via + # -c /workspace/requirements-dev.txt + # ns (pyproject.toml) +typing-extensions==4.8.0 \ + --hash=sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0 \ + --hash=sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef + # via + # -c /workspace/requirements-dev.txt + # pydantic + # typer diff --git a/scripts/get_package_name.py b/scripts/get_package_name.py index 7c6b79a..84d15fd 100755 --- a/scripts/get_package_name.py +++ b/scripts/get_package_name.py @@ -15,24 +15,24 @@ # See the License for the specific language governing permissions and # limitations under the License. -"""Extracts the package name from the setup.cfg""" +"""Extracts the package name from pyproject.toml""" from pathlib import Path REPO_ROOT_DIR = Path(__file__).parent.parent.resolve() -SETUP_CFG_PATH = REPO_ROOT_DIR / "setup.cfg" +PYPROJECT_TOML_PATH = REPO_ROOT_DIR / "pyproject.toml" NAME_PREFIX = "name = " def get_package_name() -> str: """Extracts the package name""" - with open(SETUP_CFG_PATH, "r", encoding="utf8") as setup_cfg: - for line in setup_cfg.readlines(): + with open(PYPROJECT_TOML_PATH, encoding="utf8") as pyproject_toml: + for line in pyproject_toml.readlines(): line_stripped = line.strip() if line_stripped.startswith(NAME_PREFIX): package_name = line_stripped[len(NAME_PREFIX) :] - return package_name + return package_name.strip('"') raise RuntimeError("Could not find package name.") diff --git a/scripts/license_checker.py b/scripts/license_checker.py index 0d43a1b..0ddc786 100755 --- a/scripts/license_checker.py +++ b/scripts/license_checker.py @@ -15,10 +15,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -# pylint: skip-file - """This script checks that the license and license headers -exists and that they are up to date. +exist and that they are up to date. """ import argparse @@ -26,7 +24,7 @@ import sys from datetime import date from pathlib import Path -from typing import List, Optional, Tuple, Union +from typing import Optional, Union # root directory of the package: ROOT_DIR = Path(__file__).parent.parent.resolve() @@ -48,11 +46,14 @@ "sdist", "wheels", "pip-wheel-metadata", + ".coveragerc", ".git", ".github", ".flake8", ".gitignore", ".pylintrc", + ".ruff.toml", + ".ruff_cache", "example_config.yaml", "config_schema.json", "LICENSE", # is checked but not for the license header @@ -74,6 +75,7 @@ # exclude file by file ending from license header check: EXCLUDE_ENDINGS = [ "html", + "in", "ini", "jinja", "json", @@ -81,6 +83,7 @@ "pub", "pyc", "sec", + "toml", "txt", "xml", "yaml", @@ -163,10 +166,10 @@ def __init__(self, file_path: Union[str, Path]): def get_target_files( target_dir: Path, - exclude: List[str] = EXCLUDE, - exclude_endings: List[str] = EXCLUDE_ENDINGS, - exclude_pattern: List[str] = EXCLUDE_PATTERN, -) -> List[Path]: + exclude: list[str] = EXCLUDE, + exclude_endings: list[str] = EXCLUDE_ENDINGS, + exclude_pattern: list[str] = EXCLUDE_PATTERN, +) -> list[Path]: """Get target files that are not match the exclude conditions. Args: target_dir (pathlib.Path): The target dir to search. @@ -200,7 +203,7 @@ def get_target_files( return target_files -def normalized_line(line: str, chars_to_trim: List[str] = COMMENT_CHARS) -> str: +def normalized_line(line: str, chars_to_trim: list[str] = COMMENT_CHARS) -> str: norm_line = line.strip() for char in chars_to_trim: @@ -209,11 +212,11 @@ def normalized_line(line: str, chars_to_trim: List[str] = COMMENT_CHARS) -> str: return norm_line.strip("\n").strip("\t").strip() -def normalized_text(text: str, chars_to_trim: List[str] = COMMENT_CHARS) -> str: +def normalized_text(text: str, chars_to_trim: list[str] = COMMENT_CHARS) -> str: "Normalize a license header text." lines = text.split("\n") - norm_lines: List[str] = [] + norm_lines: list[str] = [] for line in lines: stripped_line = line.strip() @@ -233,13 +236,13 @@ def normalized_text(text: str, chars_to_trim: List[str] = COMMENT_CHARS) -> str: def format_copyright_template(copyright_template: str, author: str) -> str: - """Formats license header by inserting the specified author for every occurence of + """Formats license header by inserting the specified author for every occurrence of "{author}" in the header template. """ return normalized_text(copyright_template.replace("{author}", author)) -def is_commented_line(line: str, comment_chars: List[str] = COMMENT_CHARS) -> bool: +def is_commented_line(line: str, comment_chars: list[str] = COMMENT_CHARS) -> bool: """Checks whether a line is a comment.""" line_stripped = line.strip() for comment_char in comment_chars: @@ -254,12 +257,12 @@ def is_empty_line(line: str) -> bool: return line.strip("\n").strip("\t").strip() == "" -def get_header(file_path: Path, comment_chars: List[str] = COMMENT_CHARS): +def get_header(file_path: Path, comment_chars: list[str] = COMMENT_CHARS): """Extracts the header from a file and normalizes it.""" - header_lines: List[str] = [] + header_lines: list[str] = [] try: - with open(file_path, "r") as file: + with open(file_path) as file: for line in file: if is_commented_line( line, comment_chars=comment_chars @@ -307,7 +310,7 @@ def check_copyright_notice( global_copyright: GlobalCopyrightNotice, copyright_template: str = COPYRIGHT_TEMPLATE, author: str = AUTHOR, - comment_chars: List[str] = COMMENT_CHARS, + comment_chars: list[str] = COMMENT_CHARS, min_year: int = MIN_YEAR, ) -> bool: """Checks the specified copyright text against a template. @@ -326,7 +329,7 @@ def check_copyright_notice( author (str, optional): The author that shall be included in the license header. It will replace any appearance of "{author}" in the license - header. This defaults to an auther info for GHGA. + header. This defaults to an author info for GHGA. """ # If the global_copyright is already set, check if the current copyright is @@ -372,12 +375,12 @@ def check_file_headers( global_copyright: GlobalCopyrightNotice, copyright_template: str = COPYRIGHT_TEMPLATE, author: str = AUTHOR, - exclude: List[str] = EXCLUDE, - exclude_endings: List[str] = EXCLUDE_ENDINGS, - exclude_pattern: List[str] = EXCLUDE_PATTERN, - comment_chars: List[str] = COMMENT_CHARS, + exclude: list[str] = EXCLUDE, + exclude_endings: list[str] = EXCLUDE_ENDINGS, + exclude_pattern: list[str] = EXCLUDE_PATTERN, + comment_chars: list[str] = COMMENT_CHARS, min_year: int = MIN_YEAR, -) -> Tuple[List[Path], List[Path]]: +) -> tuple[list[Path], list[Path]]: """Check files for presence of a license header and verify that the copyright notice is up to date (correct year). @@ -414,8 +417,8 @@ def check_file_headers( ) # check if license header present in file: - passed_files: List[Path] = [] - failed_files: List[Path] = [] + passed_files: list[Path] = [] + failed_files: list[Path] = [] for target_file in target_files: try: @@ -443,7 +446,7 @@ def check_license_file( global_copyright: GlobalCopyrightNotice, copyright_template: str = COPYRIGHT_TEMPLATE, author: str = AUTHOR, - comment_chars: List[str] = COMMENT_CHARS, + comment_chars: list[str] = COMMENT_CHARS, min_year: int = MIN_YEAR, ) -> bool: """Currently only checks if the copyright notice in the @@ -470,7 +473,7 @@ def check_license_file( print(f'Could not find license file "{str(license_file)}".') return False - with open(license_file, "r") as file_: + with open(license_file) as file_: license_text = normalized_text(file_.read()) # Extract the copyright notice: @@ -522,7 +525,7 @@ def run(): global_copyright = GlobalCopyrightNotice() # get global copyright from .devcontainer/license_header.txt file: - with open(GLOBAL_COPYRIGHT_FILE_PATH, "r") as global_copyright_file: + with open(GLOBAL_COPYRIGHT_FILE_PATH) as global_copyright_file: global_copyright.text = normalized_text(global_copyright_file.read()) if args.no_license_file_check: diff --git a/scripts/list_outdated_dependencies.py b/scripts/list_outdated_dependencies.py new file mode 100755 index 0000000..1aa15a1 --- /dev/null +++ b/scripts/list_outdated_dependencies.py @@ -0,0 +1,210 @@ +#!/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. +# +"""Check capped dependencies for newer versions.""" +import sys +from collections.abc import Sequence +from pathlib import Path +from typing import Any, NamedTuple + +import httpx +from packaging.requirements import Requirement + +from script_utils import cli, deps, lock_deps + +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" + + +class OutdatedDep(NamedTuple): + """Encapsulates data of an outdated dependency""" + + name: str + specified_version: str + pypi_version: str + + +def get_main_deps_pyproject(modified_pyproject: dict[str, Any]) -> list[Requirement]: + """Get a list of the dependencies from pyproject.toml""" + + dependencies: list[str] = [] + if "dependencies" in modified_pyproject["project"]: + dependencies = modified_pyproject["project"]["dependencies"] + + return [Requirement(dependency) for dependency in dependencies] + + +def get_optional_deps_pyproject( + modified_pyproject: dict[str, Any] +) -> list[Requirement]: + """Get a list of the optional dependencies from pyproject.toml""" + + dependencies: list[str] = [] + + if "optional-dependencies" in modified_pyproject["project"]: + for optional_dependency_list in modified_pyproject["project"][ + "optional-dependencies" + ]: + dependencies.extend( + modified_pyproject["project"]["optional-dependencies"][ + optional_dependency_list + ] + ) + + return [Requirement(dependency) for dependency in dependencies] + + +def get_deps_dev() -> list[Requirement]: + """Get a list of raw dependency strings from requirements-dev.in""" + with open(DEV_DEPS_PATH, encoding="utf-8") as dev_deps: + dependencies = [ + line + 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 + ] + + return [Requirement(dependency) for dependency in dependencies] + + +def get_version_from_pypi(package_name: str, client: httpx.Client) -> str: + """Make a call to PyPI to get the version information about `package_name`.""" + try: + response = client.get(f"https://pypi.org/pypi/{package_name}/json") + body = response.json() + version = body["info"]["version"] + except (httpx.RequestError, KeyError): + cli.echo_failure(f"Unable to retrieve information for package '{package_name}'") + sys.exit(1) + + return version + + +def get_outdated_deps( + requirements: list[Requirement], strip: bool = False +) -> list[OutdatedDep]: + """Determine which packages have updates available outside of pinned ranges.""" + outdated: list[OutdatedDep] = [] + with httpx.Client(timeout=10) as client: + for requirement in requirements: + pypi_version = get_version_from_pypi(requirement.name, client) + + specified = str(requirement.specifier) + + # Strip the specifier symbols from the front of the string if desired + if strip: + specified = specified.lstrip("<=>!~") + + # append package name, specified version, and latest available version + if not requirement.specifier.contains(pypi_version): + outdated.append(OutdatedDep(requirement.name, specified, pypi_version)) + outdated.sort() + return outdated + + +def print_table( + rows: Sequence[tuple[str, ...]], + headers: tuple[str, ...], + delimiter: str = " | ", +): + """ + List outdated dependencies in a formatted table. + + Args: + `outdated`: A sequence of tuples containing strings. + `headers`: A tuple containing the header strings for the table columns. + """ + if rows and len(rows[0]) != len(headers): + raise RuntimeError("Number of headers doesn't match number of columns") + + header_lengths = [len(header) for header in headers] + + # Find the maximum length of each column + col_widths = [max(len(str(cell)) for cell in col) for col in zip(*rows)] + + # Create a row format based on the maximum column widths + row_format = delimiter.join( + f"{{:<{max(width, header_len)}}}" + for width, header_len in zip(col_widths, header_lengths) + ) + + print(" " + row_format.format(*headers)) + for dependency in rows: + print(" " + row_format.format(*dependency)) + + +def main(transitive: bool = False): + """Check capped dependencies for newer versions. + + Examine `pyproject.toml` and `requirements-dev.in` for capped dependencies. + Make a call to PyPI to see if any newer versions exist. + + Use `transitive` to show outdated transitive dependencies. + """ + modified_pyproject: dict[str, Any] = deps.get_modified_pyproject( + PYPROJECT_TOML_PATH + ) + main_dependencies = get_main_deps_pyproject(modified_pyproject) + optional_dependencies = get_optional_deps_pyproject(modified_pyproject) + dev_dependencies = get_deps_dev() + + outdated_main = get_outdated_deps(main_dependencies) + outdated_optional = get_outdated_deps(optional_dependencies) + outdated_dev = get_outdated_deps(dev_dependencies) + + found_outdated = any([outdated_main, outdated_optional, outdated_dev]) + transitive_headers = ("PACKAGE", "SPECIFIED", "AVAILABLE") + if outdated_main: + location = PYPROJECT_TOML_PATH.name + " - dependencies" + cli.echo_failure(f"Outdated dependencies from {location}:") + print_table(outdated_main, transitive_headers) + if outdated_optional: + location = PYPROJECT_TOML_PATH.name + " - optional-dependencies" + cli.echo_failure(f"Outdated dependencies from {location}:") + print_table(outdated_optional, transitive_headers) + if outdated_dev: + cli.echo_failure(f"Outdated dependencies from {DEV_DEPS_PATH.name}:") + print_table(outdated_dev, transitive_headers) + + if not found_outdated: + cli.echo_success("All top-level dependencies up to date.") + + if transitive: + top_level: set[str] = { + item.name for item in outdated_main + outdated_optional + outdated_dev + } + + print("\nRetrieving transitive dependency information...") + transitive_dependencies = lock_deps.get_lock_file_deps( + LOCK_FILE_PATH, exclude=top_level + ) + outdated_transitive = get_outdated_deps(transitive_dependencies, strip=True) + + if outdated_transitive: + transitive_headers = ("PACKAGE", "PINNED", "AVAILABLE") + + cli.echo_failure("Outdated transitive dependencies:") + print_table(outdated_transitive, transitive_headers) + else: + cli.echo_success("All transitive dependencies up to date.") + + +if __name__ == "__main__": + cli.run(main) diff --git a/scripts/script_utils/deps.py b/scripts/script_utils/deps.py new file mode 100644 index 0000000..5d65cf7 --- /dev/null +++ b/scripts/script_utils/deps.py @@ -0,0 +1,74 @@ +# 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. +# +"""Contains utils for working with dependencies, lock files, etc.""" +from copy import deepcopy +from pathlib import Path +from typing import Any + +import stringcase +import tomli + + +def exclude_from_dependency_list(*, package_name: str, dependencies: list) -> list: + """Exclude the specified package from the provided dependency list.""" + + return [ + dependency + for dependency in dependencies + if not dependency.startswith(package_name) + ] + + +def remove_self_dependencies(pyproject: dict) -> dict: + """Filter out self dependencies (dependencies of the package on it self) from the + dependencies and optional-dependencies in the provided pyproject metadata.""" + + if "project" not in pyproject: + return pyproject + + modified_pyproject = deepcopy(pyproject) + + project_metadata = modified_pyproject["project"] + + package_name = stringcase.spinalcase(project_metadata.get("name")) + + if not package_name: + raise ValueError("The provided project metadata does not contain a name.") + + if "dependencies" in project_metadata: + project_metadata["dependencies"] = exclude_from_dependency_list( + package_name=package_name, dependencies=project_metadata["dependencies"] + ) + + if "optional-dependencies" in project_metadata: + for group in project_metadata["optional-dependencies"]: + project_metadata["optional-dependencies"][ + group + ] = exclude_from_dependency_list( + package_name=package_name, + dependencies=project_metadata["optional-dependencies"][group], + ) + + return modified_pyproject + + +def get_modified_pyproject(pyproject_toml_path: Path) -> dict[str, Any]: + """Get a copy of pyproject.toml with any self-referencing dependencies removed.""" + with open(pyproject_toml_path, "rb") as pyproject_toml: + pyproject = tomli.load(pyproject_toml) + + modified_pyproject = remove_self_dependencies(pyproject) + return modified_pyproject diff --git a/scripts/script_utils/lock_deps.py b/scripts/script_utils/lock_deps.py new file mode 100644 index 0000000..60d857e --- /dev/null +++ b/scripts/script_utils/lock_deps.py @@ -0,0 +1,46 @@ +# 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. +# +"""Provides a function to get all dependencies from the lock file""" +import re +from pathlib import Path +from typing import Optional + +from packaging.requirements import Requirement + + +def get_lock_file_deps( + lock_file_path: Path, + exclude: Optional[set[str]] = None, +) -> list[Requirement]: + """Inspect the lock file to get the dependencies. + + Return a list of Requirements objects that contain the dependency info. + """ + dependency_pattern = re.compile(r"([^=\s]+==[^\s]*?)\s") + + # Get the set of dependencies from the provided lock file + with open(lock_file_path, encoding="utf-8") as lock_file: + lines = lock_file.readlines() + + dependencies: list[Requirement] = [] + for line in lines: + if match := re.match(dependency_pattern, line): + dependency_string = match.group(1) + requirement = Requirement(dependency_string) + if not exclude or requirement.name not in exclude: + dependencies.append(requirement) + + return dependencies diff --git a/scripts/update_config_docs.py b/scripts/update_config_docs.py index c5457ad..b1be57a 100755 --- a/scripts/update_config_docs.py +++ b/scripts/update_config_docs.py @@ -25,10 +25,11 @@ import sys from difflib import unified_diff from pathlib import Path -from typing import Any, Type +from typing import Any import yaml from pydantic import BaseSettings + from script_utils.cli import echo_failure, echo_success, run HERE = Path(__file__).parent.resolve() @@ -43,7 +44,7 @@ class ValidationError(RuntimeError): """Raised when validation of config documentation fails.""" -def get_config_class() -> Type[BaseSettings]: +def get_config_class() -> type[BaseSettings]: """ Dynamically imports and returns the Config class from the current service. This makes the script service repo agnostic. @@ -121,7 +122,7 @@ def check_docs(): """ example_expected = get_example() - with open(EXAMPLE_CONFIG_YAML, "r", encoding="utf-8") as example_file: + with open(EXAMPLE_CONFIG_YAML, encoding="utf-8") as example_file: example_observed = example_file.read() if example_expected != example_observed: print_diff(example_expected, example_observed) @@ -130,7 +131,7 @@ def check_docs(): ) schema_expected = get_schema() - with open(CONFIG_SCHEMA_JSON, "r", encoding="utf-8") as schema_file: + with open(CONFIG_SCHEMA_JSON, encoding="utf-8") as schema_file: schema_observed = schema_file.read() if schema_expected != schema_observed: raise ValidationError( diff --git a/scripts/update_hook_revs.py b/scripts/update_hook_revs.py new file mode 100755 index 0000000..3d653f8 --- /dev/null +++ b/scripts/update_hook_revs.py @@ -0,0 +1,132 @@ +#!/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. +# +"""Script to ensure the pre-commit hook revs match what is installed.""" +import re +import sys +from functools import partial +from pathlib import Path + +from packaging.requirements import Requirement + +from script_utils import cli, lock_deps + +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" + + +def make_dependency_dict(requirements: list[Requirement]) -> dict[str, str]: + """Accept a list of Requirement objects and convert to dict""" + processed = { + req.name: str(req.specifier).removeprefix("==") for req in requirements + } + + return processed + + +def get_repl_value(match, dependencies: dict[str, str], outdated_hooks: list[str]): + """Look up pre-commit hook id in list of dependencies. If there's a match, update + `outdated_hooks` and return the hook version stored in the dictionary""" + ver, name = match.groups() + if name in dependencies: + new_ver = dependencies[name].strip() + + # Use the v prefix if it was used before + if ver.startswith("v"): + new_ver = ver[0] + new_ver + + # Make a list of what's outdated + if new_ver != ver: + msg = f"\t{name} (configured: {ver}, expected: {new_ver})" + outdated_hooks.append(msg) + return new_ver + return ver + + +def get_config(): + """Obtain the current pre-commit hook config from .pre-commit-config.yaml""" + with open(PRE_COMMIT_CFG_PATH, encoding="utf-8") as pre_commit_config: + return pre_commit_config.read() + + +def process_config(dependencies: dict[str, str], config: str) -> tuple[str, list[str]]: + """Compare pre-commit config with lock file dependencies. + + Create a modified copy of the existing config file contents with the hook versions + synchronized to the lock file dependencies. + + Returns: + `new_config`: the updated/synchronized pre-commit config. + + `outdated_hooks`: a list of any outdated hooks with version discrepancy details. + """ + outdated_hooks: list[str] = [] + + hook_rev = re.compile(r"([^\s\n]+)(?=\s*hooks:\s*- id: ([^\s]+))") + + new_config = re.sub( + hook_rev, + repl=partial( + get_repl_value, dependencies=dependencies, outdated_hooks=outdated_hooks + ), + string=config, + ) + + return new_config, outdated_hooks + + +def update_config(new_config: str): + """Write `new_config` to .pre-commit-config.yaml""" + with open(PRE_COMMIT_CFG_PATH, "w", encoding="utf-8") as pre_commit_config: + pre_commit_config.write(new_config) + cli.echo_success(f"Updated '{PRE_COMMIT_CFG_PATH}'") + + +def output_failure(outdated_hooks: list[str]): + """Notify the user that some pre-commit hooks are outdated, and list those hooks.""" + cli.echo_failure("The following pre-commit hook versions are outdated:") + for hook in outdated_hooks: + print(hook) + print("Run 'scripts/update_hook_revs.py' to update") + sys.exit(1) + + +def main(check: bool = False): + """Compare configured pre-commit hooks with the installed dependencies. + + For the set that overlap (e.g. `black`, `mypy`, `ruff`, etc.), make sure the + versions match. If running with `--check`, exit with status code 1 if anything is + outdated. If running without `--check`, update `.pre-commit-config.yaml` as needed. + """ + + dependencies: list[Requirement] = lock_deps.get_lock_file_deps(LOCK_FILE_PATH) + dependency_dict: dict[str, str] = make_dependency_dict(dependencies) + config = get_config() + new_config, outdated_hooks = process_config(dependency_dict, config) + + if config != new_config: + if check: + output_failure(outdated_hooks) + else: + update_config(new_config) + else: + cli.echo_success("Pre-commit hooks are up to date.") + + +if __name__ == "__main__": + cli.run(main) diff --git a/scripts/update_lock.py b/scripts/update_lock.py new file mode 100755 index 0000000..825aade --- /dev/null +++ b/scripts/update_lock.py @@ -0,0 +1,210 @@ +#!/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. +# + +"""Update the dependency lock files located at 'requirements.txt' and +'requirements-dev.txt'. +""" + +import os +import re +import subprocess +from pathlib import Path +from tempfile import TemporaryDirectory + +import tomli_w + +from script_utils import cli, deps + +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" +OUTPUT_LOCK_PATH = REPO_ROOT_DIR / "requirements.txt" +OUTPUT_DEV_LOCK_PATH = REPO_ROOT_DIR / "requirements-dev.txt" + + +def fix_temp_dir_comments(file_path: Path): + """Fix the temp_dir comments so they don't cause a noisy diff + + This will leave the top compile message intact as a point of sanity to verify that + the requirements are indeed being generated if nothing else changes. + """ + + with open(file_path, encoding="utf-8") as file: + lines = file.readlines() + + with open(file_path, "w", encoding="utf-8") as file: + for line in lines: + # Remove random temp directory name + line = re.sub( + r"\([^\)\(]*?pyproject\.toml\)", + "(pyproject.toml)", + line, + ) + file.write(line) + + +def is_file_outdated(old_file: Path, new_file: Path) -> bool: + """Compares two lock files and returns True if there is a difference, else False""" + + header_comment = "# pip-compile" + outdated = False + + with open(old_file, encoding="utf-8") as old: + with open(new_file, encoding="utf-8") as new: + old_lines = old.readlines() + new_lines = new.readlines() + if len(old_lines) != len(new_lines): + outdated = True + if not outdated: + for old_line, new_line in zip(old_lines, new_lines): + if old_line.startswith(header_comment): + continue + if old_line != new_line: + outdated = True + break + if outdated: + cli.echo_failure(f"{str(old_file)} is out of date!") + return outdated + + +def compile_lock_file( + sources: list[Path], + output: Path, + upgrade: bool, + extras: bool, +) -> None: + """From the specified sources compile a lock file using pip-compile from pip-tools + and write it to the specified output location. + """ + + print(f"Updating '{output.name}'...") + + command = [ + "pip-compile", + "--rebuild", + "--generate-hashes", + "--annotate", + ] + + if upgrade: + command.append("--upgrade") + + if extras: + command.append("--all-extras") + + command.extend(["--output-file", str(output.absolute())]) + + command.extend([str(source.absolute()) for source in sources]) + + # constrain the production deps by what's pinned in requirements-dev.txt + if output.name == OUTPUT_LOCK_PATH.name: + command.extend(["-c", str(OUTPUT_DEV_LOCK_PATH)]) + + completed_process = subprocess.run( + args=command, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + check=False, + ) + if completed_process.returncode != 0: + std_out = completed_process.stdout + log = std_out.decode("utf-8") if std_out else "no log available." + raise RuntimeError(f"Failed to compile lock file:\n{log}") + + fix_temp_dir_comments(output.absolute()) + + +def ensure_lock_files_exist(): + """Make sure that the lock files exist if in check mode""" + for output in [OUTPUT_DEV_LOCK_PATH, OUTPUT_LOCK_PATH]: + if not os.path.exists(output): + cli.echo_failure(f"{output} is missing") + return + + +def main(upgrade: bool = False, check: bool = False): + """Update the dependency lock files located at 'requirements.txt' and + 'requirements-dev.txt'. + + For the 'requirements.txt' only the package with its dependencies being defined in + the 'pyproject.toml' are considered. Thereby, all recursive dependencies of the + package on itself are removed. + + For the 'requirements-dev.txt', in addition to the filtered 'pyproject.toml' the + 'requirements-dev.in' is considered. + + The `upgrade` parameter can be used to indicate that dependencies found in existing + lock files should be upgraded. Default pip-compile behavior is to leave them as is. + """ + + # if --check is used, quickly ensure that there is something to compare against + if check: + ensure_lock_files_exist() + + modified_pyproject = deps.get_modified_pyproject(PYPROJECT_TOML_PATH) + + extras = ( + "optional-dependencies" in modified_pyproject["project"] + and modified_pyproject["project"]["optional-dependencies"] + ) + with TemporaryDirectory() as temp_dir: + modified_pyproject_path = Path(temp_dir) / "pyproject.toml" + with open(modified_pyproject_path, "wb") as modified_pyproject_toml: + tomli_w.dump(modified_pyproject, modified_pyproject_toml) + + # make src dir next to TOML to satisfy build system + os.makedirs(Path(temp_dir) / "src") + + # temporary test files + check_dev_path = Path(temp_dir) / OUTPUT_DEV_LOCK_PATH.name + check_prod_path = Path(temp_dir) / OUTPUT_LOCK_PATH.name + + # compile requirements-dev.txt (includes all dependencies) + compile_lock_file( + sources=[modified_pyproject_path, DEV_DEPS_PATH], + output=check_dev_path if check else OUTPUT_DEV_LOCK_PATH, + upgrade=upgrade, + extras=extras, + ) + + if check and is_file_outdated(OUTPUT_DEV_LOCK_PATH, check_dev_path): + return + + # compile requirements.txt (only includes production-related subset of above) + compile_lock_file( + sources=[modified_pyproject_path], + output=check_prod_path if check else OUTPUT_LOCK_PATH, + upgrade=upgrade, + extras=extras, + ) + + if check and is_file_outdated(OUTPUT_LOCK_PATH, check_prod_path): + return + + if check: + cli.echo_success("Lock files are up to date.") + else: + cli.echo_success( + f"Successfully updated lock files at '{OUTPUT_LOCK_PATH}' and" + + f" '{OUTPUT_DEV_LOCK_PATH}'." + ) + + +if __name__ == "__main__": + cli.run(main) diff --git a/scripts/update_readme.py b/scripts/update_readme.py index 594aedf..244d0ba 100755 --- a/scripts/update_readme.py +++ b/scripts/update_readme.py @@ -24,13 +24,14 @@ from string import Template import jsonschema2md +import tomli from pydantic import BaseModel, Field -from script_utils.cli import echo_failure, echo_success, run -from setuptools.config.setupcfg import read_configuration from stringcase import spinalcase, titlecase +from script_utils.cli import echo_failure, echo_success, run + ROOT_DIR = Path(__file__).parent.parent.resolve() -SETUP_CFG_PATH = ROOT_DIR / "setup.cfg" +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" @@ -89,16 +90,17 @@ class PackageDetails(PackageHeader, PackageName): ) -def read_package_header() -> PackageHeader: - """Read basic information about the package from the setup.cfg.""" +def read_toml_package_header() -> PackageHeader: + """Read basic information about the package from the pyproject.toml""" - setup_config = read_configuration(SETUP_CFG_PATH) - setup_metadata = setup_config["metadata"] - return PackageHeader( - shortname=setup_metadata["name"], - version=setup_metadata["version"], - summary=setup_metadata["description"], - ) + with open(PYPROJECT_TOML_PATH, "rb") as pyproject_toml: + pyproject = tomli.load(pyproject_toml) + pyproject_project = pyproject["project"] + return PackageHeader( + shortname=pyproject_project["name"], + version=pyproject_project["version"], + summary=pyproject_project["description"], + ) def read_package_name() -> PackageName: @@ -141,12 +143,12 @@ def generate_config_docs() -> str: examples_as_yaml=False, show_examples="all", ) - with open(CONFIG_SCHEMA_PATH, "r", encoding="utf-8") as json_file: + with open(CONFIG_SCHEMA_PATH, encoding="utf-8") as json_file: config_schema = json.load(json_file) md_lines = parser.parse_schema(config_schema) - # ignore everything before the properites header: + # ignore everything before the properties header: properties_index = md_lines.index("## Properties\n\n") md_lines = md_lines[properties_index + 1 :] @@ -173,7 +175,7 @@ def generate_openapi_docs() -> str: def get_package_details() -> PackageDetails: """Get details required to build documentation for the package.""" - header = read_package_header() + header = read_toml_package_header() name = read_package_name() description = read_package_description() config_description = generate_config_docs() diff --git a/scripts/update_template_files.py b/scripts/update_template_files.py index 952fe2c..d3313fd 100755 --- a/scripts/update_template_files.py +++ b/scripts/update_template_files.py @@ -58,7 +58,7 @@ class ValidationError(RuntimeError): 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 - with open(list_path, "r", encoding="utf8") as list_file: + with open(list_path, encoding="utf8") as list_file: file_list = [ clean_line for clean_line in ( @@ -127,7 +127,7 @@ def check_file(relative_file_path: str, diff: bool = False) -> bool: print(f" - {local_file_path}: cannot check, remote is missing") return True - with open(local_file_path, "r", encoding="utf8") as file: + with open(local_file_path, encoding="utf8") as file: return diff_content(local_file_path, file.read(), template_file_content) return False @@ -153,7 +153,7 @@ def update_file(relative_file_path: str, diff: bool = False) -> bool: return True if diff and local_file_path.exists(): - with open(local_file_path, "r", encoding="utf8") as file: + with open(local_file_path, encoding="utf8") as file: if file.read() == template_file_content: return False diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4ac3e4c..0000000 --- a/setup.cfg +++ /dev/null @@ -1,52 +0,0 @@ -# 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. - -[metadata] -name = ns -version = attr: ns.__version__ -description = The Notification Service (NS) handles notification kafka events. -url = https://github.com/ghga-de/notification-service -long_description = file: README.md -long_description_content_type = text/markdown; charset=UTF-8 -author = German Human Genome Phenome Archive (GHGA) -author_email = contact@ghga.de -license = Apache 2.0 -classifiers = - Operating System :: POSIX :: Linux - Programming Language :: Python :: 3.9 - License :: OSI Approved :: Apache Software License - Topic :: Internet :: WWW/HTTP :: HTTP Servers - Topic :: Scientific/Engineering :: Bio-Informatics - -[options] -zip_safe = False -include_package_data = True -packages = find: -install_requires = - typer==0.7.0 - ghga-event-schemas==0.13.1 - hexkit[akafka]==0.10.0 - -python_requires = >= 3.9 - -[options.entry_points] -console_scripts = - ns = ns.__main__:run - -[options.extras_require] -all = - -[options.packages.find] -exclude = tests diff --git a/setup.py b/setup.py deleted file mode 100755 index bee8984..0000000 --- a/setup.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/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. - -"""Setup script for pip. This setup configs are specified in the `setup.cfg` file""" - -import setuptools - -if __name__ == "__main__": - setuptools.setup() diff --git a/ns/__init__.py b/src/ns/__init__.py similarity index 91% rename from ns/__init__.py rename to src/ns/__init__.py index 506d8be..81e7e7f 100644 --- a/ns/__init__.py +++ b/src/ns/__init__.py @@ -15,4 +15,6 @@ """The Notification Service (NS) handles notification kafka events. """ -__version__ = "0.1.2" +from importlib.metadata import version + +__version__ = version(__package__) diff --git a/ns/__main__.py b/src/ns/__main__.py similarity index 100% rename from ns/__main__.py rename to src/ns/__main__.py diff --git a/ns/adapters/__init__.py b/src/ns/adapters/__init__.py similarity index 100% rename from ns/adapters/__init__.py rename to src/ns/adapters/__init__.py diff --git a/ns/adapters/inbound/__init__.py b/src/ns/adapters/inbound/__init__.py similarity index 100% rename from ns/adapters/inbound/__init__.py rename to src/ns/adapters/inbound/__init__.py diff --git a/ns/adapters/inbound/akafka.py b/src/ns/adapters/inbound/akafka.py similarity index 100% rename from ns/adapters/inbound/akafka.py rename to src/ns/adapters/inbound/akafka.py diff --git a/ns/adapters/outbound/__init__.py b/src/ns/adapters/outbound/__init__.py similarity index 100% rename from ns/adapters/outbound/__init__.py rename to src/ns/adapters/outbound/__init__.py diff --git a/ns/adapters/outbound/smtp_client.py b/src/ns/adapters/outbound/smtp_client.py similarity index 92% rename from ns/adapters/outbound/smtp_client.py rename to src/ns/adapters/outbound/smtp_client.py index 648571e..144ffbe 100644 --- a/ns/adapters/outbound/smtp_client.py +++ b/src/ns/adapters/outbound/smtp_client.py @@ -44,6 +44,11 @@ def __init__(self, config: SmtpClientConfig): self._config = config def send_email_message(self, message: EmailMessage): + """Send an email message. + + Creates an ssl security context if configured, then log in with the configured + credentials and send the provided email message. + """ try: with smtplib.SMTP(self._config.smtp_host, self._config.smtp_port) as server: if self._config.use_starttls: @@ -60,4 +65,4 @@ def send_email_message(self, message: EmailMessage): raise self.ConnectionError() server.send_message(msg=message) except smtplib.SMTPException as exc: - raise self.GeneralSmtpException(error_info=exc.args[0]) + raise self.GeneralSmtpException(error_info=exc.args[0]) from exc diff --git a/ns/config.py b/src/ns/config.py similarity index 100% rename from ns/config.py rename to src/ns/config.py diff --git a/ns/container.py b/src/ns/container.py similarity index 100% rename from ns/container.py rename to src/ns/container.py diff --git a/ns/core/__init__.py b/src/ns/core/__init__.py similarity index 100% rename from ns/core/__init__.py rename to src/ns/core/__init__.py diff --git a/ns/core/notifier.py b/src/ns/core/notifier.py similarity index 100% rename from ns/core/notifier.py rename to src/ns/core/notifier.py diff --git a/ns/main.py b/src/ns/main.py similarity index 99% rename from ns/main.py rename to src/ns/main.py index e2dab74..7b64fcc 100644 --- a/ns/main.py +++ b/src/ns/main.py @@ -21,7 +21,6 @@ def get_configured_container(*, config: Config) -> Container: """Create and configure a DI container.""" - container = Container() container.config.load_config(config) diff --git a/ns/ports/__init__.py b/src/ns/ports/__init__.py similarity index 100% rename from ns/ports/__init__.py rename to src/ns/ports/__init__.py diff --git a/ns/ports/inbound/__init__.py b/src/ns/ports/inbound/__init__.py similarity index 100% rename from ns/ports/inbound/__init__.py rename to src/ns/ports/inbound/__init__.py diff --git a/ns/ports/inbound/notifier.py b/src/ns/ports/inbound/notifier.py similarity index 100% rename from ns/ports/inbound/notifier.py rename to src/ns/ports/inbound/notifier.py diff --git a/ns/ports/outbound/__init__.py b/src/ns/ports/outbound/__init__.py similarity index 100% rename from ns/ports/outbound/__init__.py rename to src/ns/ports/outbound/__init__.py diff --git a/ns/ports/outbound/smtp_client.py b/src/ns/ports/outbound/smtp_client.py similarity index 100% rename from ns/ports/outbound/smtp_client.py rename to src/ns/ports/outbound/smtp_client.py diff --git a/tests/fixtures/config.py b/tests/fixtures/config.py index dc366a9..3ebc3d2 100644 --- a/tests/fixtures/config.py +++ b/tests/fixtures/config.py @@ -16,7 +16,7 @@ """Test config""" from pathlib import Path -from typing import Dict, List, Optional +from typing import Optional from pydantic.env_settings import BaseSettings @@ -28,12 +28,13 @@ def get_config( - sources: Optional[List[BaseSettings]] = None, + sources: Optional[list[BaseSettings]] = None, default_config_yaml: Path = TEST_CONFIG_YAML, ) -> Config: """Merges parameters from the default TEST_CONFIG_YAML with params inferred - from testcontainers.""" - sources_dict: Dict[str, object] = {} + from testcontainers. + """ + sources_dict: dict[str, object] = {} if sources is not None: for source in sources: diff --git a/tests/fixtures/joint.py b/tests/fixtures/joint.py index 1a420ac..8c842f9 100644 --- a/tests/fixtures/joint.py +++ b/tests/fixtures/joint.py @@ -13,9 +13,9 @@ # See the License for the specific language governing permissions and # limitations under the License. # - +"""Bundle test fixtures into one fixture""" +from collections.abc import AsyncGenerator from dataclasses import dataclass -from typing import AsyncGenerator import pytest_asyncio from hexkit.providers.akafka.testutils import KafkaFixture, kafka_fixture # noqa: F401 @@ -40,7 +40,6 @@ async def joint_fixture( kafka_fixture: KafkaFixture, # noqa: F811 ) -> AsyncGenerator[JointFixture, None]: """A fixture that embeds all other fixtures for integration testing""" - # merge configs from different sources with the default one: config = get_config(sources=[kafka_fixture.config]) diff --git a/tests/fixtures/server.py b/tests/fixtures/server.py index 1c9a884..68a9858 100644 --- a/tests/fixtures/server.py +++ b/tests/fixtures/server.py @@ -33,6 +33,7 @@ def __init__(self, user: str, password: str): self._password = password def __call__(self, server, session, envelope, mechanism, auth_data): + """Authenticate the credentials""" login = str(auth_data.login, encoding="utf-8") password = str(auth_data.password, encoding="utf-8") @@ -49,7 +50,7 @@ def __init__(self): self.email_received: Envelope super().__init__() - async def handle_DATA(self, server, session, envelope): + async def handle_DATA(self, server, session, envelope): # noqa: N802 """Handler function for email message which closes controller upon use""" self.email_received = envelope @@ -87,6 +88,7 @@ def __init__(self, *, expected_email: EmailMessage, controller: Controller): self._controller = controller async def __aenter__(self): + """Async context manager entry method""" try: self._controller.start() @@ -95,6 +97,7 @@ async def __aenter__(self): raise RuntimeError(err.args[0]) from err async def __aexit__(self, *args): + """Async context manager exit method""" if self._controller.loop.is_running(): self._controller.stop() @@ -103,7 +106,7 @@ class DummyServer: """Test server for making sure emails are received as intended""" def __init__(self, *, config: Config): - """assign config""" + """Assign config""" self._config = config self.login = self._config.login_user self.password = self._config.login_password @@ -117,7 +120,8 @@ def _record_email( @asynccontextmanager async def expect_email(self, expected_email: EmailMessage): """Yields an async context manager with a single-use SMTP message handler, - and compares the received message envelope with the original EmailMessage""" + and compares the received message envelope with the original EmailMessage + """ handler = CustomHandler() controller = Controller( handler, From 641aba216810bb8112d8b1f7822df48f5672a5cd Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 9 Oct 2023 15:44:06 +0000 Subject: [PATCH 2/3] Update the readme --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 7029e7c..89d5446 100644 --- a/README.md +++ b/README.md @@ -33,13 +33,13 @@ We recommend using the provided Docker container. A pre-build version is available at [docker hub](https://hub.docker.com/repository/docker/ghga/notification-service): ```bash -docker pull ghga/notification-service:0.1.2 +docker pull ghga/notification-service:0.1.3 ``` Or you can build the container yourself from the [`./Dockerfile`](./Dockerfile): ```bash # Execute in the repo's root dir: -docker build -t ghga/notification-service:0.1.2 . +docker build -t ghga/notification-service:0.1.3 . ``` For production-ready deployment, we recommend using Kubernetes, however, @@ -47,7 +47,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/notification-service:0.1.2 --help +docker run -p 8080:8080 ghga/notification-service:0.1.3 --help ``` If you prefer not to use containers, you may install the service from source: @@ -67,7 +67,7 @@ The service requires the following configuration parameters: - **`html_email_template`** *(string)*: The HTML template to use for email notifications. -- **`from_address`** *(string)*: The sender's address. +- **`from_address`** *(string, format: email)*: The sender's address. - **`smtp_host`** *(string)*: The mail server host to connect to. @@ -77,13 +77,13 @@ The service requires the following configuration parameters: - **`login_password`** *(string)*: The login password. -- **`use_starttls`** *(boolean)*: Boolean flag indicating the use of STARTTLS. Default: `True`. +- **`use_starttls`** *(boolean)*: Boolean flag indicating the use of STARTTLS. Default: `true`. - **`notification_event_topic`** *(string)*: Name of the event topic used to track notification events. - **`notification_event_type`** *(string)*: The type to use for events containing content to be sent. -- **`service_name`** *(string)*: Default: `ns`. +- **`service_name`** *(string)*: Default: `"ns"`. - **`service_instance_id`** *(string)*: A string that uniquely identifies this instance across all instances of this service. A globally unique Kafka client ID will be created by concatenating the service_name and the service_instance_id. @@ -150,7 +150,7 @@ Moreover, inside the devcontainer, a convenience commands `dev_install` is avail It installs the service with all development dependencies, installs pre-commit. The installation is performed automatically when you build the devcontainer. However, -if you update dependencies in the [`./setup.cfg`](./setup.cfg) or the +if you update dependencies in the [`./pyproject.toml`](./pyproject.toml) or the [`./requirements-dev.txt`](./requirements-dev.txt), please run it again. ## License From 50db7ed49aa383dc5bb1472ba1b1b1c6963d9f36 Mon Sep 17 00:00:00 2001 From: TheByronHimes Date: Mon, 9 Oct 2023 15:50:24 +0000 Subject: [PATCH 3/3] Quiet mypy --- src/ns/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ns/main.py b/src/ns/main.py index 7b64fcc..2f83280 100644 --- a/src/ns/main.py +++ b/src/ns/main.py @@ -29,7 +29,7 @@ def get_configured_container(*, config: Config) -> Container: async def consume_events(run_forever: bool = True): """Start consuming events with kafka""" - config = Config() + config = Config() # type: ignore [call-arg] async with get_configured_container(config=config) as container: event_consumer = await container.kafka_event_subscriber()