├── doc └── .gitkeep ├── packages └── .gitkeep ├── services └── .gitkeep ├── templates ├── package │ ├── README.md │ ├── doc │ │ └── .gitkeep │ ├── src │ │ └── package_name │ │ │ └── __init__.py │ ├── tests │ │ └── test_dummy.py │ ├── scripts │ │ ├── install.sh │ │ ├── test.sh │ │ ├── lint.sh │ │ └── format.sh │ ├── pyproject.toml │ ├── Makefile │ └── poetry.lock └── service │ ├── README.md │ ├── doc │ └── .gitkeep │ ├── src │ ├── service_name │ │ └── __init__.py │ └── run.py │ ├── tests │ └── test_dummy.py │ ├── scripts │ ├── install.sh │ ├── run.sh │ ├── docker-run.sh │ ├── test.sh │ ├── lint.sh │ ├── format.sh │ └── docker-build.sh │ ├── pyproject.toml │ ├── Makefile │ ├── Dockerfile │ └── poetry.lock ├── Makefile ├── .github └── workflows │ ├── test_all_services_and_packages.yaml │ └── test_service_or_package.yaml ├── .pre-commit-config.yaml ├── LICENSE ├── pyproject.toml ├── scripts ├── new-package.sh └── new-service.sh ├── .gitignore └── README.md /doc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /services/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/package/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/service/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/package/doc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/service/doc/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/package/src/package_name/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/service/src/service_name/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /templates/package/tests/test_dummy.py: -------------------------------------------------------------------------------- 1 | def test_dummy() -> None: 2 | assert True 3 | -------------------------------------------------------------------------------- /templates/service/tests/test_dummy.py: -------------------------------------------------------------------------------- 1 | def test_dummy() -> None: 2 | assert True 3 | -------------------------------------------------------------------------------- /templates/package/scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | ARGS=$@ 3 | poetry install $ARGS 4 | -------------------------------------------------------------------------------- /templates/service/scripts/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ARGS="$@" 4 | poetry install $ARGS 5 | -------------------------------------------------------------------------------- /templates/service/scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ARGS="$@" 4 | poetry run python src/run.py $ARGS 5 | -------------------------------------------------------------------------------- /templates/service/src/run.py: -------------------------------------------------------------------------------- 1 | def main() -> None: 2 | print("Hello from !") # noqa: T201 3 | 4 | 5 | if __name__ == "__main__": 6 | main() 7 | -------------------------------------------------------------------------------- /templates/service/scripts/docker-run.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ARGS="$@" 4 | 5 | docker run -it --rm \ 6 | --name \ 7 | :latest \ 8 | $ARGS 9 | -------------------------------------------------------------------------------- /templates/package/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PACKAGE_ROOT=$(realpath $(dirname $0)/../) 4 | TESTS_FOLDER=$PACKAGE_ROOT/tests 5 | ARGS=$@ 6 | 7 | poetry run pytest -rav $TESTS_FOLDER $ARGS 8 | -------------------------------------------------------------------------------- /templates/service/scripts/test.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SERVICE_ROOT=$(realpath $(dirname $0)/../) 4 | TESTS_FOLDER=$SERVICE_ROOT/tests 5 | ARGS=$@ 6 | 7 | poetry run pytest -rav $TESTS_FOLDER $ARGS 8 | -------------------------------------------------------------------------------- /templates/package/scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PACKAGE_ROOT=$(realpath $(dirname $0)/../) 4 | SRC_FOLDER=$PACKAGE_ROOT/src 5 | TESTS_FOLDER=$PACKAGE_ROOT/tests 6 | ARGS=$@ 7 | 8 | poetry run ruff $SRC_FOLDER $TESTS_FOLDER $ARGS 9 | -------------------------------------------------------------------------------- /templates/service/scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SERVICE_ROOT=$(realpath $(dirname $0)/../) 4 | SRC_FOLDER=$SERVICE_ROOT/src 5 | TESTS_FOLDER=$SERVICE_ROOT/tests 6 | ARGS=$@ 7 | 8 | poetry run ruff $SRC_FOLDER $TESTS_FOLDER $ARGS 9 | -------------------------------------------------------------------------------- /templates/package/scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | PACKAGE_ROOT=$(realpath $(dirname $0)/../) 4 | SRC_FOLDER=$PACKAGE_ROOT/src 5 | TESTS_FOLDER=$PACKAGE_ROOT/tests 6 | ARGS=$@ 7 | 8 | poetry run black $SRC_FOLDER $TESTS_FOLDER $ARGS 9 | -------------------------------------------------------------------------------- /templates/service/scripts/format.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SERVICE_ROOT=$(realpath $(dirname $0)/../) 4 | SRC_FOLDER=$SERVICE_ROOT/src 5 | TESTS_FOLDER=$SERVICE_ROOT/tests 6 | ARGS=$@ 7 | 8 | poetry run black $SRC_FOLDER $TESTS_FOLDER $ARGS 9 | -------------------------------------------------------------------------------- /templates/service/scripts/docker-build.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | SERVICE_ROOT=$(realpath $(dirname $0)/../) 4 | DOCKERFILE_PATH=${SERVICE_ROOT}/Dockerfile 5 | ARGS=("$@") 6 | 7 | docker build -t :latest -f ${DOCKERFILE_PATH} ${SERVICE_ROOT} ${ARGS[@]} 8 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | new-service: ## Create a new service 2 | @bash scripts/new-service.sh $(name) 3 | 4 | new-package: ## Create a new package 5 | @bash scripts/new-package.sh $(name) 6 | 7 | .PHONY: help 8 | help: 9 | @awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 10 | -------------------------------------------------------------------------------- /templates/package/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "" 3 | version = "0.1.0" 4 | description = "" 5 | authors = [] 6 | packages = [{include = "", from = "src"}] 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.11" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "*" 13 | pre-commit = "*" 14 | pytest = "*" 15 | ruff = "*" 16 | 17 | [build-system] 18 | requires = ["poetry-core"] 19 | build-backend = "poetry.core.masonry.api" 20 | -------------------------------------------------------------------------------- /templates/service/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "" 3 | version = "0.1.0" 4 | description = "" 5 | authors = [] 6 | packages = [{include = "", from = "src"}] 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.11" 10 | 11 | [tool.poetry.group.dev.dependencies] 12 | black = "*" 13 | pre-commit = "*" 14 | pytest = "*" 15 | ruff = "*" 16 | 17 | [build-system] 18 | requires = ["poetry-core"] 19 | build-backend = "poetry.core.masonry.api" 20 | -------------------------------------------------------------------------------- /templates/package/Makefile: -------------------------------------------------------------------------------- 1 | install: ## Install the package 2 | @bash scripts/install.sh $(args) 3 | 4 | format: ## Format the code 5 | @bash scripts/format.sh $(args) 6 | 7 | lint: ## Lint the code 8 | @bash scripts/lint.sh $(args) 9 | 10 | test: ## Run the tests 11 | @bash scripts/test.sh $(args) 12 | 13 | .PHONY: help 14 | help: 15 | @awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 16 | -------------------------------------------------------------------------------- /.github/workflows/test_all_services_and_packages.yaml: -------------------------------------------------------------------------------- 1 | name: Test All Services and Packages 2 | 3 | on: 4 | pull_request: 5 | branches: [ main ] 6 | push: 7 | # branches: [ main ] 8 | workflow_dispatch: 9 | 10 | jobs: 11 | test: 12 | runs-on: ubuntu-latest 13 | 14 | strategy: 15 | matrix: 16 | folder: [services/*, packages/*] 17 | 18 | steps: 19 | - name: Checkout code 20 | uses: actions/checkout@v2 21 | 22 | - name: Test ${{ matrix.folder }} 23 | uses: ./.github/actions/test-service-or-package 24 | with: 25 | target_path: ${{ matrix.folder }} 26 | -------------------------------------------------------------------------------- /templates/service/Makefile: -------------------------------------------------------------------------------- 1 | install: ## Install dependencies 2 | @bash scripts/install.sh $(args) 3 | 4 | run: ## Run the service 5 | @bash scripts/run.sh $(args) 6 | 7 | format: ## Format the code 8 | @bash scripts/format.sh $(args) 9 | 10 | lint: ## Lint the code 11 | @bash scripts/lint.sh $(args) 12 | 13 | test: ## Run the tests 14 | @bash scripts/test.sh $(args) 15 | 16 | docker-build: ## Build the docker image 17 | @bash scripts/docker-build.sh $(args) 18 | 19 | docker-run: ## Run the docker image 20 | @bash scripts/docker-run.sh $(args) 21 | 22 | .PHONY: help 23 | help: 24 | @awk 'BEGIN {FS = ":.*##"; printf "Usage: make \033[36m\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-10s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) 25 | -------------------------------------------------------------------------------- /templates/service/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11 2 | 3 | # install Poetry 4 | RUN pip install --no-cache-dir poetry 5 | 6 | # set the home directory 7 | ENV APP_HOME /opt 8 | ENV SERVICE_HOME $APP_HOME/services/ 9 | 10 | # copy `facefx-worker` Poetry files 11 | WORKDIR $SERVICE_HOME 12 | COPY pyproject.toml . 13 | COPY poetry.lock . 14 | 15 | # create a dummy package to satisfy Poetry 16 | RUN mkdir -p src/ && touch src//__init__.py 17 | 18 | # install requirements 19 | RUN poetry install --only main -n && rm -rf ~/.cache/pypoetry/cache 20 | 21 | # copy source code 22 | COPY src src 23 | 24 | # store the git branch and commit hash as env variables 25 | ARG GIT_BRANCH 26 | ARG GIT_COMMIT_HASH 27 | ENV GIT_BRANCH=${GIT_BRANCH} 28 | ENV GIT_COMMIT_HASH=${GIT_COMMIT_HASH} 29 | 30 | # set starting command 31 | WORKDIR $SERVICE_HOME 32 | CMD poetry run python src/run.py 33 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v3.2.0 6 | hooks: 7 | - id: trailing-whitespace 8 | - id: end-of-file-fixer 9 | - id: check-yaml 10 | - id: check-added-large-files 11 | 12 | - repo: https://github.com/psf/black 13 | rev: 23.3.0 14 | hooks: 15 | - id: black 16 | # It is recommended to specify the latest version of Python 17 | # supported by your project here, or alternatively use 18 | # pre-commit's default_language_version, see 19 | # https://pre-commit.com/#top_level-default_language_version 20 | language_version: python3.11 21 | 22 | - repo: https://github.com/charliermarsh/ruff-pre-commit 23 | rev: 'v0.0.261' 24 | hooks: 25 | - id: ruff 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 matanby 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.github/workflows/test_service_or_package.yaml: -------------------------------------------------------------------------------- 1 | name: Validate Code 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | target_path: 7 | description: 'The path of the package or service to validate' 8 | required: true 9 | 10 | jobs: 11 | validate_code: 12 | runs-on: ubuntu-latest 13 | strategy: 14 | matrix: 15 | python-version: ["3.11"] 16 | steps: 17 | - uses: actions/checkout@v2 18 | 19 | - name: Set up Python ${{ matrix.python-version }} 20 | uses: actions/setup-python@v2 21 | with: 22 | python-version: ${{ matrix.python-version }} 23 | 24 | - name: Install Poetry 25 | run: pip install poetry 26 | 27 | - name: Install Dependencies 28 | run: poetry install 29 | working-directory: ${{ github.workspace }}/${{ github.event.inputs.target_path }} 30 | 31 | - name: Lint 32 | run: make -f Makefile lint 33 | working-directory: ${{ github.workspace }}/${{ github.event.inputs.target_path }} 34 | 35 | - name: Format 36 | run: make -f Makefile format args="--check" 37 | working-directory: ${{ github.workspace }}/${{ github.event.inputs.target_path }} 38 | 39 | - name: Test 40 | run: make -f Makefile test 41 | working-directory: ${{ github.workspace }}/${{ github.event.inputs.target_path }} 42 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "python-monorepo-template" 3 | version = "0.1.0" 4 | description = "" 5 | authors = [] 6 | readme = "README.md" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.9" 10 | 11 | [build-system] 12 | requires = ["poetry-core"] 13 | build-backend = "poetry.core.masonry.api" 14 | 15 | [tool.black] 16 | line-length = 100 17 | 18 | [tool.ruff] 19 | select = [ 20 | "E", # pycodestyle 21 | "F", # pyflakes 22 | "W", # pycodestyle (warnings) 23 | "I", # isort 24 | "N", # pep8-naming 25 | "UP", # pyupgrade 26 | "ANN", # flake8-annotations 27 | "B", # flake8-bugbear 28 | "A", # flake8-builtins 29 | "COM", # flake8-commas 30 | "C4", # flake8-comprehensions 31 | "DTZ", # flake8-datetimez 32 | "EXE", # flake8-executable 33 | "PIE", # flake8-pie 34 | "T20", # flake8-print 35 | "PT", # flake8-pytest 36 | "SIM", # flake8-simplify 37 | "ARG", # flake8-unused-arguments 38 | "PTH", # flake8--use-pathlib 39 | "ERA", # flake8-eradicate 40 | "RUF", # ruff specific rules 41 | "PL", # pylint 42 | ] 43 | ignore = [ 44 | "ANN101", # Missing type annotation for self in method 45 | "ANN204", # Missing type annotation for special method 46 | ] 47 | line-length = 100 48 | target-version = "py311" 49 | -------------------------------------------------------------------------------- /scripts/new-package.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Change folder to the root of the project 4 | cd "$(dirname "$0")/.." 5 | 6 | # Get the package name from the first argument 7 | PACKAGE_NAME=$1 8 | 9 | # If package name is empty, exit 10 | if [ -z "$PACKAGE_NAME" ]; then 11 | echo "Package name is required" 12 | exit 1 13 | fi 14 | 15 | # Validate the package name, must be alphanumeric, non empty, and no spaces. Dashes is allowed. 16 | if [[ ! $PACKAGE_NAME =~ ^[a-zA-Z0-9-]+$ ]]; then 17 | echo "Invalid package name: $PACKAGE_NAME" 18 | echo "Package name must be alphanumeric, non empty, and no spaces. Dashes is allowed." 19 | exit 1 20 | fi 21 | 22 | # If package already exists, exit 23 | if [ -d "packages/$PACKAGE_NAME" ]; then 24 | echo "Package already exists: $PACKAGE_NAME" 25 | exit 1 26 | fi 27 | 28 | # Create a copy of the package name, while replacing dashes with underscores 29 | PACKAGE_NAME_UNDERSCORES=$(echo $PACKAGE_NAME | sed 's/-/_/g') 30 | 31 | # Set the package folder 32 | PACKAGE_FOLDER=packages/$PACKAGE_NAME_UNDERSCORES 33 | 34 | # Copy the package template to the packages directory 35 | cp -r templates/package $PACKAGE_FOLDER 36 | 37 | # Rename the package template files to the package name 38 | mv $PACKAGE_FOLDER/src/package_name $PACKAGE_FOLDER/src/$PACKAGE_NAME_UNDERSCORES 39 | 40 | export LC_ALL=C 41 | # Replace all instances of "" with the package name, in all files in the package directory 42 | find $PACKAGE_FOLDER -type f -exec sed -i '' "s//$PACKAGE_NAME_UNDERSCORES/g" {} \; 43 | 44 | # Replace all instances of "" with the package name, in all files in the package directory 45 | find $PACKAGE_FOLDER -type f -exec sed -i '' "s//$PACKAGE_NAME/g" {} \; 46 | 47 | # Greet the user 48 | echo "Package created in $PACKAGE_FOLDER" 49 | -------------------------------------------------------------------------------- /scripts/new-service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Change folder to the root of the project 4 | cd "$(dirname "$0")/.." 5 | 6 | # Get the service name from the first argument 7 | SERVICE_NAME=$1 8 | 9 | # If service name is empty, exit 10 | if [ -z "$SERVICE_NAME" ]; then 11 | echo "Service name is required" 12 | exit 1 13 | fi 14 | 15 | # Validate the service name, must be alphanumeric, non empty, and no spaces. Dashes is allowed. 16 | if [[ ! $SERVICE_NAME =~ ^[a-zA-Z0-9-]+$ ]]; then 17 | echo "Invalid service name: $SERVICE_NAME" 18 | echo "Service name must be alphanumeric, non empty, and no spaces. Dashes is allowed." 19 | exit 1 20 | fi 21 | 22 | # If service already exists, exit 23 | if [ -d "services/$SERVICE_NAME" ]; then 24 | echo "Service already exists: $SERVICE_NAME" 25 | exit 1 26 | fi 27 | 28 | # Create a copy of the service name, while replacing dashes with underscores 29 | SERVICE_NAME_UNDERSCORES=$(echo $SERVICE_NAME | sed 's/-/_/g') 30 | 31 | # Set the service folder 32 | SERVICE_FOLDER=services/$SERVICE_NAME_UNDERSCORES 33 | 34 | # Copy the service template to the services directory 35 | cp -r templates/service $SERVICE_FOLDER 36 | 37 | # Rename the service template files to the service name 38 | mv $SERVICE_FOLDER/src/service_name $SERVICE_FOLDER/src/$SERVICE_NAME_UNDERSCORES 39 | 40 | export LC_ALL=C 41 | # Replace all instances of "" with the service name, in all files in the service directory 42 | find $SERVICE_FOLDER -type f -exec sed -i '' "s//$SERVICE_NAME_UNDERSCORES/g" {} \; 43 | 44 | # Replace all instances of "" with the service name, in all files in the service directory 45 | find $SERVICE_FOLDER -type f -exec sed -i '' "s//$SERVICE_NAME/g" {} \; 46 | 47 | # Greet the user 48 | echo "Service created in $SERVICE_FOLDER" 49 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Python template 2 | # Byte-compiled / optimized / DLL files 3 | __pycache__/ 4 | *.py[cod] 5 | *$py.class 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | cover/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | local_settings.py 62 | db.sqlite3 63 | db.sqlite3-journal 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | .pybuilder/ 77 | target/ 78 | 79 | # Jupyter Notebook 80 | .ipynb_checkpoints 81 | 82 | # IPython 83 | profile_default/ 84 | ipython_config.py 85 | 86 | # pyenv 87 | # For a library or package, you might want to ignore these files since the code is 88 | # intended to run in multiple environments; otherwise, check them in: 89 | # .python-version 90 | 91 | # pipenv 92 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 93 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 94 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 95 | # install all needed dependencies. 96 | #Pipfile.lock 97 | 98 | # poetry 99 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. 100 | # This is especially recommended for binary packages to ensure reproducibility, and is more 101 | # commonly ignored for libraries. 102 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control 103 | #poetry.lock 104 | 105 | # pdm 106 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. 107 | #pdm.lock 108 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it 109 | # in version control. 110 | # https://pdm.fming.dev/#use-with-ide 111 | .pdm.toml 112 | 113 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm 114 | __pypackages__/ 115 | 116 | # Celery stuff 117 | celerybeat-schedule 118 | celerybeat.pid 119 | 120 | # SageMath parsed files 121 | *.sage.py 122 | 123 | # Environments 124 | .env 125 | .venv 126 | env/ 127 | venv/ 128 | ENV/ 129 | env.bak/ 130 | venv.bak/ 131 | 132 | # Spyder project settings 133 | .spyderproject 134 | .spyproject 135 | 136 | # Rope project settings 137 | .ropeproject 138 | 139 | # mkdocs documentation 140 | /site 141 | 142 | # mypy 143 | .mypy_cache/ 144 | .dmypy.json 145 | dmypy.json 146 | 147 | # Pyre type checker 148 | .pyre/ 149 | 150 | # pytype static type analyzer 151 | .pytype/ 152 | 153 | # Cython debug symbols 154 | cython_debug/ 155 | 156 | # PyCharm 157 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can 158 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore 159 | # and can be added to the global gitignore or merged into this file. For a more nuclear 160 | # option (not recommended) you can uncomment the following to ignore the entire idea folder. 161 | .idea/ 162 | 163 | # ruff cache 164 | **/.ruff-cache/ 165 | 166 | # pytest cache 167 | **/.pytest_cache/ 168 | 169 | # TODO files 170 | **/TODO 171 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Python Mono-Repo Template 2 | This is a template for creating a Python mono-repository that allows storing multiple separate services and packages 3 | that can be dependencies of these services. The template serves as a skeleton that allows easy creation of new services 4 | and packages, and takes care of different aspects such as code linting, unit testing, and building Docker images. 5 | 6 | ### Features: 7 | * 🐍 [Monorepo](https://en.wikipedia.org/wiki/Monorepo)-ready: multiple separate services and packages in a single repository 8 | * 📦 [Poetry](https://github.com/python-poetry/poetry) for dependency management 9 | * 📝 Easy creation of new services and packages with a Makefile and templates 10 | * 🖋️ Python code formatting using [Black](https://github.com/psf/black) (The uncompromising Python code formatter) 11 | * ⚡ Code linting using [Ruff](https://github.com/charliermarsh/ruff) (An extremely fast Python linter, written in Rust.) 12 | * 🐳 Preconfigured Dockerfiles for services 13 | * 🪝 [Pre-commit](https://github.com/pre-commit/pre-commit) hooks for linting and formatting 14 | * 🚀 GitHub Actions for linting and testing 15 | 16 | --- 17 | 18 | ## Features 19 | #### 🐍 Templates for Python packages and services: 20 | This template provides a set of templates for creating new Python 21 | packages and services. These templates include boilerplate code and configuration files that make it easy to get started 22 | and ensure consistency across all the components in your repository. 23 | 24 | 25 | #### 📦 Dependency management with Poetry: 26 | This repository uses Poetry as the preferred way to track dependencies for 27 | Python packages and services. Poetry provides a simple and reliable way to manage dependencies, and is recommended over 28 | the old setup.py files and requirements.txt files. With Poetry, you can easily add and remove dependencies, generate 29 | lockfiles for reproducible builds, and manage virtual environments for different projects. 30 | 31 | 32 | #### 🖋️ Python code formatting using Black: 33 | This project uses Black, a Python code formatter, to ensure that code is consistently formatted and adheres to 34 | PEP 8 guidelines. Black takes care of automatic code formatting, saving you time and energy that would be spent on 35 | manual formatting. 36 | 37 | 38 | #### ⚡️Code linting using Ruff: 39 | This project uses Ruff, a new super fast Python linter written in Rust, to check code for syntax errors, style 40 | violations, and potential bugs. Ruff is designed to be extremely fast, making it a good choice for large codebases. 41 | 42 | 43 | #### 🐳 Preconfigured Dockerfiles: 44 | This template includes a basic Dockerfile that can be used to build and run services in containers. 45 | This makes it easy to deploy your services to different environments and helps ensure that your code runs consistently 46 | across different machines.* 47 | 48 | 49 | #### 🪝 Pre-commit hooks for linting and formatting: 50 | This template comes with pre-commit hooks that automatically check 51 | your code for formatting errors, style issues, and other problems before you commit changes to Git. This helps ensure 52 | that your code is consistent and adheres to the project's standards. 53 | 54 | 55 | #### 🚀 GitHub Actions for linting and testing: 56 | This template includes GitHub Actions that automatically run linting and 57 | testing scripts whenever you push changes to your repository. This helps catch errors and issues early on, before they 58 | can cause problems in production. 59 | 60 | 61 | #### 🛠️ Makefile for running common commands: 62 | This template includes a Makefile that provides a set of common commands for 63 | working with the repository, such as running tests, building Docker images, and cleaning up temporary files. 64 | 65 | --- 66 | 67 | ## Getting Started 68 | To use this template, simply clone the repository and start creating new services and packages based on the provided 69 | templates. You can customize the pre-commit hooks, GitHub Actions, and other configuration files to meet your specific needs. 70 | 71 | 72 | ### File Structure 73 | ``` 74 | ├── doc # Project-level documentation folder 75 | ├── packages # Packages root folder 76 | ├── scripts # Project-level scripts folder 77 | ├── services # Services root folder 78 | ├── templates # Template folder for new packages and services 79 | │   ├── package # Package template folder 80 | │   │   ├── doc # Package documentation folder 81 | │   │   ├── scripts # Package scripts folder 82 | │   │   ├── src # Package source code folder 83 | │   │   ├── tests # Package test folder 84 | │   │   ├── Makefile # Package Makefile for running common commands 85 | │   │   ├── README.md # Package README file 86 | │   │   ├── poetry.lock # Poetry lock file for package dependencies 87 | │   │   └── pyproject.toml # Poetry configuration file for the package 88 | │   └── service # Service template folder 89 | │   ├── doc # Service documentation folder 90 | │   ├── scripts # Service scripts folder 91 | │   ├── src # Service source code folder 92 | │   ├── tests # Service test folder 93 | │   ├── Dockerfile # Dockerfile for building the service 94 | │   ├── Makefile # Service Makefile for running common commands 95 | │   ├── README.md # Service README file 96 | │   ├── poetry.lock # Poetry lock file for service dependencies 97 | │   └── pyproject.toml # Poetry configuration file for the service 98 | ├── LICENSE # License file 99 | ├── Makefile # Project-level Makefile for running common commands for the entire repo 100 | ├── README.md # README file for the entire repo 101 | └── pyproject.toml # Poetry configuration file for the entire repo 102 | ``` 103 | 104 | ### Creating New Services and Packages 105 | This repository includes a Makefile that provides convenient targets for creating new services and packages. 106 | These targets are implemented using shell scripts located in the scripts directory, and provide boilerplate code and 107 | configuration files to help get started with new projects. 108 | 109 | To create a new service, run the new-service target from the command line and provide a name for your service: 110 | 111 | ```shell 112 | make new-service name= 113 | ``` 114 | 115 | This will create a new service directory in the services directory with the provided name. 116 | The directory will contain a Dockerfile for building the service, a pyproject.toml file for listing dependencies, 117 | and a basic project structure. 118 | 119 | To create a new package, run the new-package target from the command line and provide a name for your package: 120 | 121 | ```shell 122 | make new-package name= 123 | ``` 124 | 125 | This will create a new Python package in the packages directory with the provided name. 126 | The directory will contain a basic project structure with a pyproject.toml file for listing dependencies. 127 | 128 | These targets are designed to help you get started quickly and provide a consistent project structure across all your 129 | services and packages. You can modify the shell scripts to suit your own needs or create your own targets in the 130 | Makefile as needed. 131 | 132 | --- 133 | 134 | ## Using the Makefile 135 | 136 | This repository includes a Makefile with targets that automate common tasks for Python services. 137 | These targets are implemented using shell scripts located in the scripts directory and can be invoked from the command 138 | line using the make command. 139 | 140 | Here are the available targets: 141 | 142 | ### Installation 143 | This target installs the service and its dependencies into a virtual environment. 144 | It uses Poetry to manage dependencies and installs them according to the configuration in the pyproject.toml file. 145 | 146 | To use this target, run the following command from the root directory of your service: 147 | ```shell 148 | make install 149 | ``` 150 | 151 | ### Code formatting 152 | This target formats the code using Black, a Python code formatter. It applies a consistent coding style to your 153 | codebase and ensures that it follows the PEP 8 guidelines. 154 | 155 | To use this target, run the following command from the root directory of your service: 156 | 157 | ```shell 158 | make format 159 | ``` 160 | 161 | ### Linting 162 | This target lints the code using Ruff, a fast Python linter written in Rust. It checks your codebase for syntax errors, 163 | style violations, and potential bugs, and provides a report of any issues found. 164 | 165 | To use this target, run the following command from the root directory of your service: 166 | ```shell 167 | make lint 168 | ``` 169 | 170 | ### Unit testing 171 | This target runs the unit tests for your service using Pytest, a Python testing framework. It discovers and runs all 172 | tests in the tests directory and provides a report of the test results. 173 | 174 | To use this target, run the following command from the root directory of your service: 175 | ```shell 176 | make test 177 | ``` 178 | 179 | ## Contributing 180 | If you find any issues with this template or have suggestions for improvements, please feel free to contribute to the 181 | project. You can open issues, submit pull requests, or contact the project maintainers directly. 182 | 183 | ## License 184 | This project is licensed under the MIT License - see the LICENSE file for details. 185 | -------------------------------------------------------------------------------- /templates/package/poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "attrs" 5 | version = "22.2.0" 6 | description = "Classes Without Boilerplate" 7 | category = "dev" 8 | optional = false 9 | python-versions = ">=3.6" 10 | files = [ 11 | {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, 12 | {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, 13 | ] 14 | 15 | [package.extras] 16 | cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] 17 | dev = ["attrs[docs,tests]"] 18 | docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] 19 | tests = ["attrs[tests-no-zope]", "zope.interface"] 20 | tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] 21 | 22 | [[package]] 23 | name = "black" 24 | version = "23.3.0" 25 | description = "The uncompromising code formatter." 26 | category = "dev" 27 | optional = false 28 | python-versions = ">=3.7" 29 | files = [ 30 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, 31 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, 32 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, 33 | {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, 34 | {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, 35 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, 36 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, 37 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, 38 | {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, 39 | {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, 40 | {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, 41 | {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, 42 | {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, 43 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, 44 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, 45 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, 46 | {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, 47 | {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, 48 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, 49 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, 50 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, 51 | {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, 52 | {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, 53 | {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, 54 | {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, 55 | ] 56 | 57 | [package.dependencies] 58 | click = ">=8.0.0" 59 | mypy-extensions = ">=0.4.3" 60 | packaging = ">=22.0" 61 | pathspec = ">=0.9.0" 62 | platformdirs = ">=2" 63 | 64 | [package.extras] 65 | colorama = ["colorama (>=0.4.3)"] 66 | d = ["aiohttp (>=3.7.4)"] 67 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 68 | uvloop = ["uvloop (>=0.15.2)"] 69 | 70 | [[package]] 71 | name = "cfgv" 72 | version = "3.3.1" 73 | description = "Validate configuration and produce human readable error messages." 74 | category = "dev" 75 | optional = false 76 | python-versions = ">=3.6.1" 77 | files = [ 78 | {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, 79 | {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, 80 | ] 81 | 82 | [[package]] 83 | name = "click" 84 | version = "8.1.3" 85 | description = "Composable command line interface toolkit" 86 | category = "dev" 87 | optional = false 88 | python-versions = ">=3.7" 89 | files = [ 90 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, 91 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, 92 | ] 93 | 94 | [package.dependencies] 95 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 96 | 97 | [[package]] 98 | name = "colorama" 99 | version = "0.4.6" 100 | description = "Cross-platform colored terminal text." 101 | category = "dev" 102 | optional = false 103 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 104 | files = [ 105 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 106 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 107 | ] 108 | 109 | [[package]] 110 | name = "distlib" 111 | version = "0.3.6" 112 | description = "Distribution utilities" 113 | category = "dev" 114 | optional = false 115 | python-versions = "*" 116 | files = [ 117 | {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, 118 | {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, 119 | ] 120 | 121 | [[package]] 122 | name = "filelock" 123 | version = "3.11.0" 124 | description = "A platform independent file lock." 125 | category = "dev" 126 | optional = false 127 | python-versions = ">=3.7" 128 | files = [ 129 | {file = "filelock-3.11.0-py3-none-any.whl", hash = "sha256:f08a52314748335c6460fc8fe40cd5638b85001225db78c2aa01c8c0db83b318"}, 130 | {file = "filelock-3.11.0.tar.gz", hash = "sha256:3618c0da67adcc0506b015fd11ef7faf1b493f0b40d87728e19986b536890c37"}, 131 | ] 132 | 133 | [package.extras] 134 | docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] 135 | testing = ["covdefaults (>=2.3)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] 136 | 137 | [[package]] 138 | name = "identify" 139 | version = "2.5.22" 140 | description = "File identification library for Python" 141 | category = "dev" 142 | optional = false 143 | python-versions = ">=3.7" 144 | files = [ 145 | {file = "identify-2.5.22-py2.py3-none-any.whl", hash = "sha256:f0faad595a4687053669c112004178149f6c326db71ee999ae4636685753ad2f"}, 146 | {file = "identify-2.5.22.tar.gz", hash = "sha256:f7a93d6cf98e29bd07663c60728e7a4057615068d7a639d132dc883b2d54d31e"}, 147 | ] 148 | 149 | [package.extras] 150 | license = ["ukkonen"] 151 | 152 | [[package]] 153 | name = "iniconfig" 154 | version = "2.0.0" 155 | description = "brain-dead simple config-ini parsing" 156 | category = "dev" 157 | optional = false 158 | python-versions = ">=3.7" 159 | files = [ 160 | {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, 161 | {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, 162 | ] 163 | 164 | [[package]] 165 | name = "mypy-extensions" 166 | version = "1.0.0" 167 | description = "Type system extensions for programs checked with the mypy type checker." 168 | category = "dev" 169 | optional = false 170 | python-versions = ">=3.5" 171 | files = [ 172 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 173 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 174 | ] 175 | 176 | [[package]] 177 | name = "nodeenv" 178 | version = "1.7.0" 179 | description = "Node.js virtual environment builder" 180 | category = "dev" 181 | optional = false 182 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" 183 | files = [ 184 | {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, 185 | {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, 186 | ] 187 | 188 | [package.dependencies] 189 | setuptools = "*" 190 | 191 | [[package]] 192 | name = "packaging" 193 | version = "23.0" 194 | description = "Core utilities for Python packages" 195 | category = "dev" 196 | optional = false 197 | python-versions = ">=3.7" 198 | files = [ 199 | {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, 200 | {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, 201 | ] 202 | 203 | [[package]] 204 | name = "pathspec" 205 | version = "0.11.1" 206 | description = "Utility library for gitignore style pattern matching of file paths." 207 | category = "dev" 208 | optional = false 209 | python-versions = ">=3.7" 210 | files = [ 211 | {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, 212 | {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, 213 | ] 214 | 215 | [[package]] 216 | name = "platformdirs" 217 | version = "3.2.0" 218 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 219 | category = "dev" 220 | optional = false 221 | python-versions = ">=3.7" 222 | files = [ 223 | {file = "platformdirs-3.2.0-py3-none-any.whl", hash = "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e"}, 224 | {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"}, 225 | ] 226 | 227 | [package.extras] 228 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] 229 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] 230 | 231 | [[package]] 232 | name = "pluggy" 233 | version = "1.0.0" 234 | description = "plugin and hook calling mechanisms for python" 235 | category = "dev" 236 | optional = false 237 | python-versions = ">=3.6" 238 | files = [ 239 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 240 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 241 | ] 242 | 243 | [package.extras] 244 | dev = ["pre-commit", "tox"] 245 | testing = ["pytest", "pytest-benchmark"] 246 | 247 | [[package]] 248 | name = "pre-commit" 249 | version = "3.2.2" 250 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 251 | category = "dev" 252 | optional = false 253 | python-versions = ">=3.8" 254 | files = [ 255 | {file = "pre_commit-3.2.2-py2.py3-none-any.whl", hash = "sha256:0b4210aea813fe81144e87c5a291f09ea66f199f367fa1df41b55e1d26e1e2b4"}, 256 | {file = "pre_commit-3.2.2.tar.gz", hash = "sha256:5b808fcbda4afbccf6d6633a56663fed35b6c2bc08096fd3d47ce197ac351d9d"}, 257 | ] 258 | 259 | [package.dependencies] 260 | cfgv = ">=2.0.0" 261 | identify = ">=1.0.0" 262 | nodeenv = ">=0.11.1" 263 | pyyaml = ">=5.1" 264 | virtualenv = ">=20.10.0" 265 | 266 | [[package]] 267 | name = "pytest" 268 | version = "7.2.2" 269 | description = "pytest: simple powerful testing with Python" 270 | category = "dev" 271 | optional = false 272 | python-versions = ">=3.7" 273 | files = [ 274 | {file = "pytest-7.2.2-py3-none-any.whl", hash = "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"}, 275 | {file = "pytest-7.2.2.tar.gz", hash = "sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"}, 276 | ] 277 | 278 | [package.dependencies] 279 | attrs = ">=19.2.0" 280 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 281 | iniconfig = "*" 282 | packaging = "*" 283 | pluggy = ">=0.12,<2.0" 284 | 285 | [package.extras] 286 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] 287 | 288 | [[package]] 289 | name = "pyyaml" 290 | version = "6.0" 291 | description = "YAML parser and emitter for Python" 292 | category = "dev" 293 | optional = false 294 | python-versions = ">=3.6" 295 | files = [ 296 | {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, 297 | {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, 298 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, 299 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, 300 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, 301 | {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, 302 | {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, 303 | {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, 304 | {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, 305 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, 306 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, 307 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, 308 | {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, 309 | {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, 310 | {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, 311 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, 312 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, 313 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, 314 | {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, 315 | {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, 316 | {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, 317 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, 318 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, 319 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, 320 | {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, 321 | {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, 322 | {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, 323 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, 324 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, 325 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, 326 | {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, 327 | {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, 328 | {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, 329 | {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, 330 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, 331 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, 332 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, 333 | {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, 334 | {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, 335 | {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, 336 | ] 337 | 338 | [[package]] 339 | name = "ruff" 340 | version = "0.0.261" 341 | description = "An extremely fast Python linter, written in Rust." 342 | category = "dev" 343 | optional = false 344 | python-versions = ">=3.7" 345 | files = [ 346 | {file = "ruff-0.0.261-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:6624a966c4a21110cee6780333e2216522a831364896f3d98f13120936eff40a"}, 347 | {file = "ruff-0.0.261-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:2dba68a9e558ab33e6dd5d280af798a2d9d3c80c913ad9c8b8e97d7b287f1cc9"}, 348 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd0cee5a81b0785dc0feeb2640c1e31abe93f0d77c5233507ac59731a626f1"}, 349 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:581e64fa1518df495ca890a605ee65065101a86db56b6858f848bade69fc6489"}, 350 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc970f6ece0b4950e419f0252895ee42e9e8e5689c6494d18f5dc2c6ebb7f798"}, 351 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8fa98e747e0fe185d65a40b0ea13f55c492f3b5f9a032a1097e82edaddb9e52e"}, 352 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f268d52a71bf410aa45c232870c17049df322a7d20e871cfe622c9fc784aab7b"}, 353 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1293acc64eba16a11109678dc4743df08c207ed2edbeaf38b3e10eb2597321b"}, 354 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d95596e2f4cafead19a6d1ec0b86f8fda45ba66fe934de3956d71146a87959b3"}, 355 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4bcec45abdf65c1328a269cf6cc193f7ff85b777fa2865c64cf2c96b80148a2c"}, 356 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6c5f397ec0af42a434ad4b6f86565027406c5d0d0ebeea0d5b3f90c4bf55bc82"}, 357 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_i686.whl", hash = "sha256:39abd02342cec0c131b2ddcaace08b2eae9700cab3ca7dba64ae5fd4f4881bd0"}, 358 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:aaa4f52a6e513f8daa450dac4859e80390d947052f592f0d8e796baab24df2fc"}, 359 | {file = "ruff-0.0.261-py3-none-win32.whl", hash = "sha256:daff64b4e86e42ce69e6367d63aab9562fc213cd4db0e146859df8abc283dba0"}, 360 | {file = "ruff-0.0.261-py3-none-win_amd64.whl", hash = "sha256:0fbc689c23609edda36169c8708bb91bab111d8f44cb4a88330541757770ab30"}, 361 | {file = "ruff-0.0.261-py3-none-win_arm64.whl", hash = "sha256:d2eddc60ae75fc87f8bb8fd6e8d5339cf884cd6de81e82a50287424309c187ba"}, 362 | {file = "ruff-0.0.261.tar.gz", hash = "sha256:c1c715b0d1e18f9c509d7c411ca61da3543a4aa459325b1b1e52b8301d65c6d2"}, 363 | ] 364 | 365 | [[package]] 366 | name = "setuptools" 367 | version = "67.6.1" 368 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 369 | category = "dev" 370 | optional = false 371 | python-versions = ">=3.7" 372 | files = [ 373 | {file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"}, 374 | {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"}, 375 | ] 376 | 377 | [package.extras] 378 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 379 | testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 380 | testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] 381 | 382 | [[package]] 383 | name = "virtualenv" 384 | version = "20.21.0" 385 | description = "Virtual Python Environment builder" 386 | category = "dev" 387 | optional = false 388 | python-versions = ">=3.7" 389 | files = [ 390 | {file = "virtualenv-20.21.0-py3-none-any.whl", hash = "sha256:31712f8f2a17bd06234fa97fdf19609e789dd4e3e4bf108c3da71d710651adbc"}, 391 | {file = "virtualenv-20.21.0.tar.gz", hash = "sha256:f50e3e60f990a0757c9b68333c9fdaa72d7188caa417f96af9e52407831a3b68"}, 392 | ] 393 | 394 | [package.dependencies] 395 | distlib = ">=0.3.6,<1" 396 | filelock = ">=3.4.1,<4" 397 | platformdirs = ">=2.4,<4" 398 | 399 | [package.extras] 400 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] 401 | test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] 402 | 403 | [metadata] 404 | lock-version = "2.0" 405 | python-versions = "^3.11" 406 | content-hash = "bf431a151cb77fc848508fae750f5ad8ebc617f0ff37df5601c014f26c8afb46" 407 | -------------------------------------------------------------------------------- /templates/service/poetry.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. 2 | 3 | [[package]] 4 | name = "attrs" 5 | version = "22.2.0" 6 | description = "Classes Without Boilerplate" 7 | category = "dev" 8 | optional = false 9 | python-versions = ">=3.6" 10 | files = [ 11 | {file = "attrs-22.2.0-py3-none-any.whl", hash = "sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836"}, 12 | {file = "attrs-22.2.0.tar.gz", hash = "sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99"}, 13 | ] 14 | 15 | [package.extras] 16 | cov = ["attrs[tests]", "coverage-enable-subprocess", "coverage[toml] (>=5.3)"] 17 | dev = ["attrs[docs,tests]"] 18 | docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope.interface"] 19 | tests = ["attrs[tests-no-zope]", "zope.interface"] 20 | tests-no-zope = ["cloudpickle", "cloudpickle", "hypothesis", "hypothesis", "mypy (>=0.971,<0.990)", "mypy (>=0.971,<0.990)", "pympler", "pympler", "pytest (>=4.3.0)", "pytest (>=4.3.0)", "pytest-mypy-plugins", "pytest-mypy-plugins", "pytest-xdist[psutil]", "pytest-xdist[psutil]"] 21 | 22 | [[package]] 23 | name = "black" 24 | version = "23.3.0" 25 | description = "The uncompromising code formatter." 26 | category = "dev" 27 | optional = false 28 | python-versions = ">=3.7" 29 | files = [ 30 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, 31 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, 32 | {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, 33 | {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, 34 | {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, 35 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, 36 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, 37 | {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, 38 | {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, 39 | {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, 40 | {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, 41 | {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, 42 | {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, 43 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, 44 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, 45 | {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, 46 | {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, 47 | {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, 48 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, 49 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, 50 | {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, 51 | {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, 52 | {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, 53 | {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, 54 | {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, 55 | ] 56 | 57 | [package.dependencies] 58 | click = ">=8.0.0" 59 | mypy-extensions = ">=0.4.3" 60 | packaging = ">=22.0" 61 | pathspec = ">=0.9.0" 62 | platformdirs = ">=2" 63 | 64 | [package.extras] 65 | colorama = ["colorama (>=0.4.3)"] 66 | d = ["aiohttp (>=3.7.4)"] 67 | jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] 68 | uvloop = ["uvloop (>=0.15.2)"] 69 | 70 | [[package]] 71 | name = "cfgv" 72 | version = "3.3.1" 73 | description = "Validate configuration and produce human readable error messages." 74 | category = "dev" 75 | optional = false 76 | python-versions = ">=3.6.1" 77 | files = [ 78 | {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, 79 | {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, 80 | ] 81 | 82 | [[package]] 83 | name = "click" 84 | version = "8.1.3" 85 | description = "Composable command line interface toolkit" 86 | category = "dev" 87 | optional = false 88 | python-versions = ">=3.7" 89 | files = [ 90 | {file = "click-8.1.3-py3-none-any.whl", hash = "sha256:bb4d8133cb15a609f44e8213d9b391b0809795062913b383c62be0ee95b1db48"}, 91 | {file = "click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, 92 | ] 93 | 94 | [package.dependencies] 95 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 96 | 97 | [[package]] 98 | name = "colorama" 99 | version = "0.4.6" 100 | description = "Cross-platform colored terminal text." 101 | category = "dev" 102 | optional = false 103 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" 104 | files = [ 105 | {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, 106 | {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, 107 | ] 108 | 109 | [[package]] 110 | name = "distlib" 111 | version = "0.3.6" 112 | description = "Distribution utilities" 113 | category = "dev" 114 | optional = false 115 | python-versions = "*" 116 | files = [ 117 | {file = "distlib-0.3.6-py2.py3-none-any.whl", hash = "sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e"}, 118 | {file = "distlib-0.3.6.tar.gz", hash = "sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46"}, 119 | ] 120 | 121 | [[package]] 122 | name = "filelock" 123 | version = "3.11.0" 124 | description = "A platform independent file lock." 125 | category = "dev" 126 | optional = false 127 | python-versions = ">=3.7" 128 | files = [ 129 | {file = "filelock-3.11.0-py3-none-any.whl", hash = "sha256:f08a52314748335c6460fc8fe40cd5638b85001225db78c2aa01c8c0db83b318"}, 130 | {file = "filelock-3.11.0.tar.gz", hash = "sha256:3618c0da67adcc0506b015fd11ef7faf1b493f0b40d87728e19986b536890c37"}, 131 | ] 132 | 133 | [package.extras] 134 | docs = ["furo (>=2023.3.27)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] 135 | testing = ["covdefaults (>=2.3)", "coverage (>=7.2.2)", "diff-cover (>=7.5)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] 136 | 137 | [[package]] 138 | name = "identify" 139 | version = "2.5.22" 140 | description = "File identification library for Python" 141 | category = "dev" 142 | optional = false 143 | python-versions = ">=3.7" 144 | files = [ 145 | {file = "identify-2.5.22-py2.py3-none-any.whl", hash = "sha256:f0faad595a4687053669c112004178149f6c326db71ee999ae4636685753ad2f"}, 146 | {file = "identify-2.5.22.tar.gz", hash = "sha256:f7a93d6cf98e29bd07663c60728e7a4057615068d7a639d132dc883b2d54d31e"}, 147 | ] 148 | 149 | [package.extras] 150 | license = ["ukkonen"] 151 | 152 | [[package]] 153 | name = "iniconfig" 154 | version = "2.0.0" 155 | description = "brain-dead simple config-ini parsing" 156 | category = "dev" 157 | optional = false 158 | python-versions = ">=3.7" 159 | files = [ 160 | {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, 161 | {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, 162 | ] 163 | 164 | [[package]] 165 | name = "mypy-extensions" 166 | version = "1.0.0" 167 | description = "Type system extensions for programs checked with the mypy type checker." 168 | category = "dev" 169 | optional = false 170 | python-versions = ">=3.5" 171 | files = [ 172 | {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, 173 | {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, 174 | ] 175 | 176 | [[package]] 177 | name = "nodeenv" 178 | version = "1.7.0" 179 | description = "Node.js virtual environment builder" 180 | category = "dev" 181 | optional = false 182 | python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" 183 | files = [ 184 | {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, 185 | {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, 186 | ] 187 | 188 | [package.dependencies] 189 | setuptools = "*" 190 | 191 | [[package]] 192 | name = "packaging" 193 | version = "23.0" 194 | description = "Core utilities for Python packages" 195 | category = "dev" 196 | optional = false 197 | python-versions = ">=3.7" 198 | files = [ 199 | {file = "packaging-23.0-py3-none-any.whl", hash = "sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2"}, 200 | {file = "packaging-23.0.tar.gz", hash = "sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97"}, 201 | ] 202 | 203 | [[package]] 204 | name = "pathspec" 205 | version = "0.11.1" 206 | description = "Utility library for gitignore style pattern matching of file paths." 207 | category = "dev" 208 | optional = false 209 | python-versions = ">=3.7" 210 | files = [ 211 | {file = "pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, 212 | {file = "pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, 213 | ] 214 | 215 | [[package]] 216 | name = "platformdirs" 217 | version = "3.2.0" 218 | description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." 219 | category = "dev" 220 | optional = false 221 | python-versions = ">=3.7" 222 | files = [ 223 | {file = "platformdirs-3.2.0-py3-none-any.whl", hash = "sha256:ebe11c0d7a805086e99506aa331612429a72ca7cd52a1f0d277dc4adc20cb10e"}, 224 | {file = "platformdirs-3.2.0.tar.gz", hash = "sha256:d5b638ca397f25f979350ff789db335903d7ea010ab28903f57b27e1b16c2b08"}, 225 | ] 226 | 227 | [package.extras] 228 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-autodoc-typehints (>=1.22,!=1.23.4)"] 229 | test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.2.2)", "pytest-cov (>=4)", "pytest-mock (>=3.10)"] 230 | 231 | [[package]] 232 | name = "pluggy" 233 | version = "1.0.0" 234 | description = "plugin and hook calling mechanisms for python" 235 | category = "dev" 236 | optional = false 237 | python-versions = ">=3.6" 238 | files = [ 239 | {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, 240 | {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, 241 | ] 242 | 243 | [package.extras] 244 | dev = ["pre-commit", "tox"] 245 | testing = ["pytest", "pytest-benchmark"] 246 | 247 | [[package]] 248 | name = "pre-commit" 249 | version = "3.2.2" 250 | description = "A framework for managing and maintaining multi-language pre-commit hooks." 251 | category = "dev" 252 | optional = false 253 | python-versions = ">=3.8" 254 | files = [ 255 | {file = "pre_commit-3.2.2-py2.py3-none-any.whl", hash = "sha256:0b4210aea813fe81144e87c5a291f09ea66f199f367fa1df41b55e1d26e1e2b4"}, 256 | {file = "pre_commit-3.2.2.tar.gz", hash = "sha256:5b808fcbda4afbccf6d6633a56663fed35b6c2bc08096fd3d47ce197ac351d9d"}, 257 | ] 258 | 259 | [package.dependencies] 260 | cfgv = ">=2.0.0" 261 | identify = ">=1.0.0" 262 | nodeenv = ">=0.11.1" 263 | pyyaml = ">=5.1" 264 | virtualenv = ">=20.10.0" 265 | 266 | [[package]] 267 | name = "pytest" 268 | version = "7.2.2" 269 | description = "pytest: simple powerful testing with Python" 270 | category = "dev" 271 | optional = false 272 | python-versions = ">=3.7" 273 | files = [ 274 | {file = "pytest-7.2.2-py3-none-any.whl", hash = "sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e"}, 275 | {file = "pytest-7.2.2.tar.gz", hash = "sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4"}, 276 | ] 277 | 278 | [package.dependencies] 279 | attrs = ">=19.2.0" 280 | colorama = {version = "*", markers = "sys_platform == \"win32\""} 281 | iniconfig = "*" 282 | packaging = "*" 283 | pluggy = ">=0.12,<2.0" 284 | 285 | [package.extras] 286 | testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "xmlschema"] 287 | 288 | [[package]] 289 | name = "pyyaml" 290 | version = "6.0" 291 | description = "YAML parser and emitter for Python" 292 | category = "dev" 293 | optional = false 294 | python-versions = ">=3.6" 295 | files = [ 296 | {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, 297 | {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, 298 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, 299 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, 300 | {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, 301 | {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, 302 | {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, 303 | {file = "PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, 304 | {file = "PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, 305 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, 306 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, 307 | {file = "PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, 308 | {file = "PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, 309 | {file = "PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, 310 | {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, 311 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, 312 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, 313 | {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, 314 | {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, 315 | {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, 316 | {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, 317 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, 318 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, 319 | {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, 320 | {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, 321 | {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, 322 | {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, 323 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, 324 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, 325 | {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, 326 | {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, 327 | {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, 328 | {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, 329 | {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, 330 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, 331 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, 332 | {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, 333 | {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, 334 | {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, 335 | {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, 336 | ] 337 | 338 | [[package]] 339 | name = "ruff" 340 | version = "0.0.261" 341 | description = "An extremely fast Python linter, written in Rust." 342 | category = "dev" 343 | optional = false 344 | python-versions = ">=3.7" 345 | files = [ 346 | {file = "ruff-0.0.261-py3-none-macosx_10_7_x86_64.whl", hash = "sha256:6624a966c4a21110cee6780333e2216522a831364896f3d98f13120936eff40a"}, 347 | {file = "ruff-0.0.261-py3-none-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:2dba68a9e558ab33e6dd5d280af798a2d9d3c80c913ad9c8b8e97d7b287f1cc9"}, 348 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dbd0cee5a81b0785dc0feeb2640c1e31abe93f0d77c5233507ac59731a626f1"}, 349 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:581e64fa1518df495ca890a605ee65065101a86db56b6858f848bade69fc6489"}, 350 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc970f6ece0b4950e419f0252895ee42e9e8e5689c6494d18f5dc2c6ebb7f798"}, 351 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8fa98e747e0fe185d65a40b0ea13f55c492f3b5f9a032a1097e82edaddb9e52e"}, 352 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f268d52a71bf410aa45c232870c17049df322a7d20e871cfe622c9fc784aab7b"}, 353 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1293acc64eba16a11109678dc4743df08c207ed2edbeaf38b3e10eb2597321b"}, 354 | {file = "ruff-0.0.261-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d95596e2f4cafead19a6d1ec0b86f8fda45ba66fe934de3956d71146a87959b3"}, 355 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4bcec45abdf65c1328a269cf6cc193f7ff85b777fa2865c64cf2c96b80148a2c"}, 356 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6c5f397ec0af42a434ad4b6f86565027406c5d0d0ebeea0d5b3f90c4bf55bc82"}, 357 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_i686.whl", hash = "sha256:39abd02342cec0c131b2ddcaace08b2eae9700cab3ca7dba64ae5fd4f4881bd0"}, 358 | {file = "ruff-0.0.261-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:aaa4f52a6e513f8daa450dac4859e80390d947052f592f0d8e796baab24df2fc"}, 359 | {file = "ruff-0.0.261-py3-none-win32.whl", hash = "sha256:daff64b4e86e42ce69e6367d63aab9562fc213cd4db0e146859df8abc283dba0"}, 360 | {file = "ruff-0.0.261-py3-none-win_amd64.whl", hash = "sha256:0fbc689c23609edda36169c8708bb91bab111d8f44cb4a88330541757770ab30"}, 361 | {file = "ruff-0.0.261-py3-none-win_arm64.whl", hash = "sha256:d2eddc60ae75fc87f8bb8fd6e8d5339cf884cd6de81e82a50287424309c187ba"}, 362 | {file = "ruff-0.0.261.tar.gz", hash = "sha256:c1c715b0d1e18f9c509d7c411ca61da3543a4aa459325b1b1e52b8301d65c6d2"}, 363 | ] 364 | 365 | [[package]] 366 | name = "setuptools" 367 | version = "67.6.1" 368 | description = "Easily download, build, install, upgrade, and uninstall Python packages" 369 | category = "dev" 370 | optional = false 371 | python-versions = ">=3.7" 372 | files = [ 373 | {file = "setuptools-67.6.1-py3-none-any.whl", hash = "sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078"}, 374 | {file = "setuptools-67.6.1.tar.gz", hash = "sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a"}, 375 | ] 376 | 377 | [package.extras] 378 | docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] 379 | testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] 380 | testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] 381 | 382 | [[package]] 383 | name = "virtualenv" 384 | version = "20.21.0" 385 | description = "Virtual Python Environment builder" 386 | category = "dev" 387 | optional = false 388 | python-versions = ">=3.7" 389 | files = [ 390 | {file = "virtualenv-20.21.0-py3-none-any.whl", hash = "sha256:31712f8f2a17bd06234fa97fdf19609e789dd4e3e4bf108c3da71d710651adbc"}, 391 | {file = "virtualenv-20.21.0.tar.gz", hash = "sha256:f50e3e60f990a0757c9b68333c9fdaa72d7188caa417f96af9e52407831a3b68"}, 392 | ] 393 | 394 | [package.dependencies] 395 | distlib = ">=0.3.6,<1" 396 | filelock = ">=3.4.1,<4" 397 | platformdirs = ">=2.4,<4" 398 | 399 | [package.extras] 400 | docs = ["furo (>=2022.12.7)", "proselint (>=0.13)", "sphinx (>=6.1.3)", "sphinx-argparse (>=0.4)", "sphinxcontrib-towncrier (>=0.2.1a0)", "towncrier (>=22.12)"] 401 | test = ["covdefaults (>=2.2.2)", "coverage (>=7.1)", "coverage-enable-subprocess (>=1)", "flaky (>=3.7)", "packaging (>=23)", "pytest (>=7.2.1)", "pytest-env (>=0.8.1)", "pytest-freezegun (>=0.4.2)", "pytest-mock (>=3.10)", "pytest-randomly (>=3.12)", "pytest-timeout (>=2.1)"] 402 | 403 | [metadata] 404 | lock-version = "2.0" 405 | python-versions = "^3.11" 406 | content-hash = "bf431a151cb77fc848508fae750f5ad8ebc617f0ff37df5601c014f26c8afb46" 407 | --------------------------------------------------------------------------------