From 869c33af3caaaeac3fa84008a1c49d4cdcf378d9 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Thu, 19 Jun 2025 15:36:28 -0400 Subject: [PATCH 01/18] update cookie cutter for django project, added ruff linting and formatting --- cookiecutter.json | 4 ++-- {{cookiecutter.git_repo_name}}/Makefile | 11 ++++++++++- {{cookiecutter.git_repo_name}}/requirements-dev.txt | 1 + {{cookiecutter.git_repo_name}}/requirements.txt | 6 ++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index 2ca6e96..a814149 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -46,8 +46,8 @@ "ssh", "https" ], - "__template_repo": "https://github.com/btr1975/cookiecutter-python-fastapi-openapi", - "__template_version": "2.0.2", + "__template_repo": "https://github.com/naturalblaze/cookiecutter-python-django", + "__template_version": "1.0.0", "_new_lines": "\n", "_copy_without_render": [ "{{cookiecutter.__app_name}}/templates", diff --git a/{{cookiecutter.git_repo_name}}/Makefile b/{{cookiecutter.git_repo_name}}/Makefile index d7ff444..6ebd1d0 100644 --- a/{{cookiecutter.git_repo_name}}/Makefile +++ b/{{cookiecutter.git_repo_name}}/Makefile @@ -18,6 +18,8 @@ info: @echo " format To format the code with black" @echo " pylint To run pylint" @echo " pytest To run pytest with verbose option" + @echo " ruff-format To run ruff formatter" + @echo " ruff-lint To run ruff linter" @echo " start-container To start the container" @echo " stop-container To stop the container" @echo " remove-container To remove the container" @@ -45,7 +47,7 @@ pytest: @pytest --cov -vvv dev-run: - @python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r + @python manage.py runserver check-vuln: @pip-audit -r requirements.txt @@ -80,6 +82,13 @@ pylint: pytest: @uv run pytest --cov -vvv +ruff-format: + @uv run ruff format {{cookiecutter.__app_name}}/ + @uv run ruff format tests/ + +ruff-lint: + @uv run ruff check {{cookiecutter.__app_name}}/ + dev-run: @uv run python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r diff --git a/{{cookiecutter.git_repo_name}}/requirements-dev.txt b/{{cookiecutter.git_repo_name}}/requirements-dev.txt index 306ae57..5640d3e 100644 --- a/{{cookiecutter.git_repo_name}}/requirements-dev.txt +++ b/{{cookiecutter.git_repo_name}}/requirements-dev.txt @@ -15,4 +15,5 @@ sphinxcontrib-mermaid httpx twine bandit +ruff {% if cookiecutter.use_requests == 'y' %}requests-mock{% endif %} diff --git a/{{cookiecutter.git_repo_name}}/requirements.txt b/{{cookiecutter.git_repo_name}}/requirements.txt index 368f6ac..2f16d0f 100644 --- a/{{cookiecutter.git_repo_name}}/requirements.txt +++ b/{{cookiecutter.git_repo_name}}/requirements.txt @@ -1,8 +1,6 @@ # These are the libraries required to run your app -# They DO NOT inculde libraries needed to develop or test our app +# They DO NOT include libraries needed to develop or test our app # -fastapi -pydantic -uvicorn +django {% if cookiecutter.use_requests == 'y' %}requests{% endif %} {% if cookiecutter.use_cryptography == 'y' %}cryptography{% endif %} From 1bbaf8549f0326206fa3a8c2ed0c2bd6a6c5dba1 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Thu, 26 Jun 2025 13:07:29 -0400 Subject: [PATCH 02/18] pytest-django for testing --- README.md | 6 ++ cookiecutter.json | 16 ++--- .../.github/ISSUE_TEMPLATE/config.yml | 9 +-- {{cookiecutter.git_repo_name}}/Makefile | 1 + .../containers/Containerfile | 1 + {{cookiecutter.git_repo_name}}/pyproject.toml | 7 ++- .../requirements-dev.txt | 1 + .../requirements.txt | 1 + .../{{cookiecutter.__app_name}}/__init__.py | 5 -- .../routers/__init__.py | 3 - .../routers/example.py | 42 ------------- .../routers/hello_world.py | 61 ------------------- .../static/README.md | 5 -- .../templates/README.md | 1 - .../templates/base.jinja2 | 28 --------- .../templates/index.jinja2 | 9 --- .../utils/__init__.py | 3 - .../utils/schemas.py | 9 --- .../{{cookiecutter.__app_name}}/version.py | 8 --- .../{{cookiecutter.__app_name}}/web_app.py | 31 ---------- .../{{cookiecutter.__app_name}}_cli.py | 57 ----------------- 21 files changed, 25 insertions(+), 279 deletions(-) delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/__init__.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/__init__.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/example.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/hello_world.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/static/README.md delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/README.md delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/base.jinja2 delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/index.jinja2 delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/__init__.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/schemas.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/version.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/web_app.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/{{cookiecutter.__app_name}}_cli.py diff --git a/README.md b/README.md index 9121f39..24824df 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,12 @@ cookiecutter https://github.com/btr1975/cookiecutter-python-fastapi-openapi -c 1 cookiecutter git@github.com:btr1975/cookiecutter-python-fastapi-openapi -c 1.0.1 ``` +### UV + +```text +uvx cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop +``` + 4. Now you will be asked a series of questions. This is an example **THE QUESTIONS MAY NOT BE THE EXACT FOR THIS COOKIECUTTER**, also if you have downloaded it before you will be asked if you want to download it again, always say yes to get the latest version. diff --git a/cookiecutter.json b/cookiecutter.json index a814149..7cd83e2 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -26,15 +26,15 @@ "uv", "pip" ], - "use_requests": [ + "use_django_markdownx": [ "n", "y" ], - "use_cryptography": [ + "use_requests": [ "n", "y" ], - "include_webpages": [ + "use_cryptography": [ "n", "y" ], @@ -84,6 +84,11 @@ "uv": "UV By Astral", "pip": "PIP (The built in Python Package Installer)" }, + "use_django_markdownx": { + "__prompt__": "Will you use the Django MarkdownX library", + "n": "No", + "y": "Yes" + }, "use_requests": { "__prompt__": "Will you use the requests library", "n": "No", @@ -94,11 +99,6 @@ "n": "No", "y": "Yes" }, - "include_webpages": { - "__prompt__": "Include webpages starter", - "n": "No", - "y": "Yes" - }, "container_runtime": { "__prompt__": "Which container runtime will be used", "podman": "Podman", diff --git a/{{cookiecutter.git_repo_name}}/.github/ISSUE_TEMPLATE/config.yml b/{{cookiecutter.git_repo_name}}/.github/ISSUE_TEMPLATE/config.yml index 14d9a5b..09e4e19 100644 --- a/{{cookiecutter.git_repo_name}}/.github/ISSUE_TEMPLATE/config.yml +++ b/{{cookiecutter.git_repo_name}}/.github/ISSUE_TEMPLATE/config.yml @@ -4,9 +4,6 @@ contact_links: - name: Python Information url: https://www.python.org/ about: Python Org Website - - name: FastAPI Information - url: https://fastapi.tiangolo.com/ - about: FastAPI Website - - name: pydantic Information - url: https://pydantic-docs.helpmanual.io/ - about: pydantic Website + - name: Django Information + url: https://docs.djangoproject.com/ + about: Django Website diff --git a/{{cookiecutter.git_repo_name}}/Makefile b/{{cookiecutter.git_repo_name}}/Makefile index 6ebd1d0..823399a 100644 --- a/{{cookiecutter.git_repo_name}}/Makefile +++ b/{{cookiecutter.git_repo_name}}/Makefile @@ -89,6 +89,7 @@ ruff-format: ruff-lint: @uv run ruff check {{cookiecutter.__app_name}}/ +# Need to change for django dev-run: @uv run python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r diff --git a/{{cookiecutter.git_repo_name}}/containers/Containerfile b/{{cookiecutter.git_repo_name}}/containers/Containerfile index 7dab0b3..18559bb 100644 --- a/{{cookiecutter.git_repo_name}}/containers/Containerfile +++ b/{{cookiecutter.git_repo_name}}/containers/Containerfile @@ -25,4 +25,5 @@ RUN --mount=type=ssh,required=true \ EXPOSE 8080/tcp +# Need to change this for django ENTRYPOINT ["{{ cookiecutter.git_repo_name }}-cli", "start", "-p", "8080"] diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index 2b35170..ec9f7e2 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -57,9 +57,8 @@ classifiers = [ {% if cookiecutter.package_manager == 'uv' %} dependencies = [ - "fastapi", - "pydantic", - "uvicorn", + "django", + {% if cookiecutter.use_django_markdownx == 'y' %}"django-markdownx",{% endif %} {% if cookiecutter.use_requests == 'y' %}"requests",{% endif %} {% if cookiecutter.use_cryptography == 'y' %}"cryptography",{% endif %} ] @@ -76,6 +75,7 @@ dev = [ "sphinxcontrib-mermaid", "httpx", "bandit", + "ruff", {% if cookiecutter.use_requests == 'y' %}"requests-mock",{% endif %} ] {% endif %} @@ -85,6 +85,7 @@ Documentation = "https://{{ cookiecutter.git_repo_name }}.readthedocs.io/en/late Source = "{{ cookiecutter.git_url }}" Tracker = "{{ cookiecutter.git_url }}/issues" +# Need to adjust for django [project.scripts] {{ cookiecutter.git_repo_name }}-cli = "{{cookiecutter.__app_name}}:cli" diff --git a/{{cookiecutter.git_repo_name}}/requirements-dev.txt b/{{cookiecutter.git_repo_name}}/requirements-dev.txt index 5640d3e..5fd9307 100644 --- a/{{cookiecutter.git_repo_name}}/requirements-dev.txt +++ b/{{cookiecutter.git_repo_name}}/requirements-dev.txt @@ -6,6 +6,7 @@ build pip-audit black tomli +pytest-django pytest-cov sphinx pylint diff --git a/{{cookiecutter.git_repo_name}}/requirements.txt b/{{cookiecutter.git_repo_name}}/requirements.txt index 2f16d0f..c509ee2 100644 --- a/{{cookiecutter.git_repo_name}}/requirements.txt +++ b/{{cookiecutter.git_repo_name}}/requirements.txt @@ -2,5 +2,6 @@ # They DO NOT include libraries needed to develop or test our app # django +{% if cookiecutter.use_django_markdownx == 'y' %}django-markdownx{% endif %} {% if cookiecutter.use_requests == 'y' %}requests{% endif %} {% if cookiecutter.use_cryptography == 'y' %}cryptography{% endif %} diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/__init__.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/__init__.py deleted file mode 100644 index 99e6301..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -init for {{cookiecutter.__app_name}} -""" -from {{cookiecutter.__app_name}}.web_app import web_app -from {{cookiecutter.__app_name}}.{{cookiecutter.__app_name}}_cli import cli diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/__init__.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/__init__.py deleted file mode 100644 index 69a3d0c..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -init for routes -""" diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/example.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/example.py deleted file mode 100644 index f1788a1..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/example.py +++ /dev/null @@ -1,42 +0,0 @@ -""" -This is an example FIXME: Example delete this -""" -from fastapi import APIRouter, HTTPException -from pydantic import BaseModel # pylint: disable=no-name-in-module -from {{cookiecutter.__app_name}}.utils.schemas import ErrorSchema - - -router = APIRouter( - prefix='/api/v1', - responses={400: {'model': ErrorSchema}, 401: {'model': ErrorSchema}}, - tags=['example'] -) - - -class ResponseSchema(BaseModel): # pylint: disable=too-few-public-methods - """Schema for example""" - response: str - - -@router.get('/example/{name}', - responses={200: {'model': ResponseSchema}}, - description='This is an example', - name='Example endpoint') -async def get_example(name: str) -> ResponseSchema: - """Function for the example endpoint - - :type name: String - :param name: A name - - :rtype: ResponseSchema - :returns: The JSON Data - - :raises HTTPException: If anything goes wrong - """ - try: - result = ResponseSchema(response=name) - - except Exception as error: # pragma: no cover - raise HTTPException(status_code=400, detail=f'{error}') from error - - return result diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/hello_world.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/hello_world.py deleted file mode 100644 index af37112..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/routers/hello_world.py +++ /dev/null @@ -1,61 +0,0 @@ -""" -Hello World Example # FIXME: This is an example you should delete it -""" -import os -from fastapi import APIRouter, Request -from fastapi.responses import HTMLResponse -from fastapi.templating import Jinja2Templates - -router = APIRouter( -) - -templates_path = os.path.join(os.path.split(os.path.abspath(os.path.dirname(__file__)))[0], 'templates') -templates = Jinja2Templates(directory=templates_path) - - -@router.get('/hello', response_class=HTMLResponse, response_model=None, - description='Hello World', name='Hello World', include_in_schema=False) -async def get_hello(request: Request) -> templates.TemplateResponse: - """Function to display the Hello World - :type request: fastapi.Request - :param request: The request from the user - :rtype: fastapi.templating.Jinja2Templates.TemplateResponse - :returns: The webpage - """ - error = None - - try: - pass - - except Exception as err: # pylint: disable=broad-except - error = f'{err}' - - data = { - 'page': 'Hello World from {{ cookiecutter.git_repo_name }}', - 'error': error - } - return templates.TemplateResponse('index.jinja2', {'request': request, 'data': data}) - - -@router.get('/hello-error', response_class=HTMLResponse, response_model=None, - description='Hello World', name='Hello World', include_in_schema=False) -async def get_hello_error(request: Request) -> templates.TemplateResponse: - """Function to display the Hello World - :type request: fastapi.Request - :param request: The request from the user - :rtype: fastapi.templating.Jinja2Templates.TemplateResponse - :returns: The webpage - """ - error = 'OH NO THERE WAS SOME ERROR!!' - - try: - pass - - except Exception as err: # pylint: disable=broad-except - error = f'{err}' - - data = { - 'page': 'Hello World Error from {{ cookiecutter.git_repo_name }}', - 'error': error - } - return templates.TemplateResponse('index.jinja2', {'request': request, 'data': data}) diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/static/README.md b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/static/README.md deleted file mode 100644 index d1c0f8e..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/static/README.md +++ /dev/null @@ -1,5 +0,0 @@ -## Static files, and directories - -* JavaScript -* Images -* css diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/README.md b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/README.md deleted file mode 100644 index 9014397..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/README.md +++ /dev/null @@ -1 +0,0 @@ -## Jinja2 Templates diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/base.jinja2 b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/base.jinja2 deleted file mode 100644 index cb38483..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/base.jinja2 +++ /dev/null @@ -1,28 +0,0 @@ - - - - {{ data.page }} - - - - - -
- -
-

{{ data.page }}

-
- - {% block content %} - {% endblock %} - - {% if data.error %} -
- {{ data.error }} -
- {% endif %} - -
- - - \ No newline at end of file diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/index.jinja2 b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/index.jinja2 deleted file mode 100644 index e2f34d8..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/templates/index.jinja2 +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "base.jinja2" %} - -{% block content %} - -
-

-
- -{% endblock %} \ No newline at end of file diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/__init__.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/__init__.py deleted file mode 100644 index 1c6aa00..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -init for utils -""" diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/schemas.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/schemas.py deleted file mode 100644 index 8fb1699..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/utils/schemas.py +++ /dev/null @@ -1,9 +0,0 @@ -""" -pydantic schemas -""" -from pydantic import BaseModel # pylint: disable=no-name-in-module - - -class ErrorSchema(BaseModel): # pylint: disable=too-few-public-methods - """Schema for simple Errors""" - detail: str diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/version.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/version.py deleted file mode 100644 index f1cd966..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/version.py +++ /dev/null @@ -1,8 +0,0 @@ -""" -Holds the version information for the package -""" -__copyright__ = 'Copyright (c) {% now 'local', '%Y' %} {{ cookiecutter.full_name }}' -__status__ = 'prod' -{% set version_info = cookiecutter.app_version.split('.') %} -__version_info__ = ({{ version_info[0] }}, {{ version_info[1] }}, {{ version_info[2] }}) -__version__ = '.'.join(map(str, __version_info__)) diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/web_app.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/web_app.py deleted file mode 100644 index 10fcca9..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/web_app.py +++ /dev/null @@ -1,31 +0,0 @@ -""" -FastAPI WebApp -""" -{% if cookiecutter.include_webpages == "y" %} -import os -from fastapi.staticfiles import StaticFiles -{% endif %} -from fastapi import FastAPI -from {{cookiecutter.__app_name}}.version import __version__ -from {{cookiecutter.__app_name}}.routers import example -{% if cookiecutter.include_webpages == "y" %} -from {{cookiecutter.__app_name}}.routers import hello_world - -static_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'static') -{% endif %} - -# Used to config swagger UI -# Reference : https://swagger.io/docs/open-source-tools/swagger-ui/usage/configuration/ -swagger_ui_parameters = { - 'docExpansion': 'none', - 'filter': 'true' -} - -web_app = FastAPI(title='{{ cookiecutter.git_repo_name }}', version=__version__, - description='{{ cookiecutter.app_description }}', swagger_ui_parameters=swagger_ui_parameters) -web_app.include_router(example.router) -{% if cookiecutter.include_webpages == "y" %} -web_app.include_router(hello_world.router) - -web_app.mount("/static", StaticFiles(directory=static_path), name="static") -{% endif %} diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/{{cookiecutter.__app_name}}_cli.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/{{cookiecutter.__app_name}}_cli.py deleted file mode 100644 index c9ddb37..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__app_name}}/{{cookiecutter.__app_name}}_cli.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -CLI for {{cookiecutter.__app_name}} -""" -from argparse import ArgumentParser -import uvicorn - - -def cli_argument_parser() -> ArgumentParser: - """Function to create the argument parser - - :rtype: ArgumentParser - :returns: The argument parser - """ - arg_parser = ArgumentParser(description='{{cookiecutter.git_repo_name}}-cli') - subparsers = arg_parser.add_subparsers(title='commands', description='Valid commands: a single command is required', - help='CLI Help', dest='a single command please see the -h option') - subparsers.required = True - - # This is the sub parser to print start - arg_parser_start = subparsers.add_parser('start', help='Start FastAPI') - arg_parser_start.set_defaults(which_sub='start') - arg_parser_start.add_argument('-p', '--port', help='TCP Port') - arg_parser_start.add_argument('-r', '--reload', action='store_true', help='Allow Auto Reload') - - return arg_parser - -def cli() -> None: - """Function to run the command line - :rtype: None - :returns: Nothing it is the CLI - """ - arg_parser = None - - try: - arg_parser = cli_argument_parser() - - args = arg_parser.parse_args() - - if args.which_sub == 'start': - uvicorn.run('{{cookiecutter.__app_name}}:web_app', reload=args.reload, - host='0.0.0.0', port=int(args.port)) - - except AttributeError as error: - print(f'\n !!! {error} !!! \n') - arg_parser.print_help() - - except FileNotFoundError as error: - print(f'\n !!! {error} !!! \n') - arg_parser.print_help() - - except FileExistsError as error: - print(f'\n !!! {error} !!! \n') - arg_parser.print_help() - - except Exception as error: # pylint: disable=broad-exception-caught - print(f'\n !!! {error} !!! \n') - arg_parser.print_help() From d23f76c3e2f4192cc45c446c9e932b35b02d9fb4 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Fri, 27 Jun 2025 10:27:11 -0400 Subject: [PATCH 03/18] remove uneeded post_gen_project.py --- hooks/post_gen_project.py | 6 ------ {{cookiecutter.git_repo_name}}/tests/conftest.py | 5 ----- 2 files changed, 11 deletions(-) diff --git a/hooks/post_gen_project.py b/hooks/post_gen_project.py index ca110db..2fe5043 100644 --- a/hooks/post_gen_project.py +++ b/hooks/post_gen_project.py @@ -6,11 +6,6 @@ import os import shutil -REMOVE_PATHS_NO_WEBPAGES = [ - '{% if cookiecutter.include_webpages != "y" %}{{cookiecutter.__app_name}}/routers/hello_world.py{% endif %}', - '{% if cookiecutter.include_webpages != "y" %}{{cookiecutter.__app_name}}/static{% endif %}', - '{% if cookiecutter.include_webpages != "y" %}{{cookiecutter.__app_name}}/templates{% endif %}', -] REMOVE_PATHS_PODMAN = [ '{% if cookiecutter.container_runtime == "podman" %}containers/Dockerfile{% endif %}', @@ -50,7 +45,6 @@ def remove_paths(paths_to_remove: List[str]) -> None: if __name__ == "__main__": - remove_paths(REMOVE_PATHS_NO_WEBPAGES) remove_paths(REMOVE_PATHS_PODMAN) remove_paths(REMOVE_PATHS_DOCKER) remove_paths(REMOVE_PATHS_UV) diff --git a/{{cookiecutter.git_repo_name}}/tests/conftest.py b/{{cookiecutter.git_repo_name}}/tests/conftest.py index f4df5da..595f008 100644 --- a/{{cookiecutter.git_repo_name}}/tests/conftest.py +++ b/{{cookiecutter.git_repo_name}}/tests/conftest.py @@ -1,11 +1,6 @@ import os, sys import pytest -from fastapi.testclient import TestClient base_path = os.path.join(os.path.abspath(os.path.dirname(__name__))) sys.path.append(os.path.join(base_path)) -from {{cookiecutter.__app_name}}.web_app import web_app -@pytest.fixture -def fastapi_mock_client(): - yield TestClient(web_app) From a882ffab7102c54e4734105c7a2307bc6f0b7802 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 19:28:05 -0400 Subject: [PATCH 04/18] README.md documentation update, cookiecutter.json updated options, pyproject.toml updated project configs --- README.md | 11 +++++----- cookiecutter.json | 21 ++++++------------- {{cookiecutter.git_repo_name}}/pyproject.toml | 9 ++------ 3 files changed, 13 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 24824df..06f7162 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,4 @@ -# cookiecutter-python-fastapi-openapi - +# cookiecutter-python-django | BRANCH | STATUS | | ------ |--------| | main | [![Unit-Testing, Coverage, Linting](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml/badge.svg?branch=main)](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml) | @@ -25,13 +24,13 @@ pip install cookiecutter ### HTTPS ```text -cookiecutter https://github.com/btr1975/cookiecutter-python-fastapi-openapi +cookiecutter https://github.com/naturalblaze/cookiecutter-python-django ``` ### SSH ```text -cookiecutter git@github.com:btr1975/cookiecutter-python-fastapi-openapi +cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git ``` * Use a specific version @@ -39,13 +38,13 @@ cookiecutter git@github.com:btr1975/cookiecutter-python-fastapi-openapi ### HTTPS ```text -cookiecutter https://github.com/btr1975/cookiecutter-python-fastapi-openapi -c 1.0.1 +cookiecutter https://github.com/naturalblaze/cookiecutter-python-django.git -c 1.0.1 ``` ### SSH ```text -cookiecutter git@github.com:btr1975/cookiecutter-python-fastapi-openapi -c 1.0.1 +cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git -c 1.0.1 ``` ### UV diff --git a/cookiecutter.json b/cookiecutter.json index 7cd83e2..a4cd7b1 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -26,15 +26,11 @@ "uv", "pip" ], - "use_django_markdownx": [ - "n", - "y" - ], - "use_requests": [ + "use_django-environ": [ "n", "y" ], - "use_cryptography": [ + "use_django_markdownx": [ "n", "y" ], @@ -84,18 +80,13 @@ "uv": "UV By Astral", "pip": "PIP (The built in Python Package Installer)" }, - "use_django_markdownx": { - "__prompt__": "Will you use the Django MarkdownX library", - "n": "No", - "y": "Yes" - }, - "use_requests": { - "__prompt__": "Will you use the requests library", + "use_django-environ": { + "__prompt__": "Will you use the Django Environment library", "n": "No", "y": "Yes" }, - "use_cryptography": { - "__prompt__": "Will you use the cryptography library", + "use_django_markdownx": { + "__prompt__": "Will you use the Django MarkdownX library", "n": "No", "y": "Yes" }, diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index ec9f7e2..e7a9b3e 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -59,8 +59,7 @@ classifiers = [ dependencies = [ "django", {% if cookiecutter.use_django_markdownx == 'y' %}"django-markdownx",{% endif %} - {% if cookiecutter.use_requests == 'y' %}"requests",{% endif %} - {% if cookiecutter.use_cryptography == 'y' %}"cryptography",{% endif %} + {% if cookiecutter.use_django-environ == 'y' %}"django-environ",{% endif %} ] [dependency-groups] @@ -68,6 +67,7 @@ dev = [ "black", "tomli", "pytest-cov", + "pytest-django", "sphinx", "pylint", "myst-parser", @@ -76,7 +76,6 @@ dev = [ "httpx", "bandit", "ruff", - {% if cookiecutter.use_requests == 'y' %}"requests-mock",{% endif %} ] {% endif %} @@ -85,10 +84,6 @@ Documentation = "https://{{ cookiecutter.git_repo_name }}.readthedocs.io/en/late Source = "{{ cookiecutter.git_url }}" Tracker = "{{ cookiecutter.git_url }}/issues" -# Need to adjust for django -[project.scripts] -{{ cookiecutter.git_repo_name }}-cli = "{{cookiecutter.__app_name}}:cli" - [tool.setuptools.packages.find] include = [ "{{cookiecutter.__app_name}}*", From e4a92ce3539a227884e7f0868a9b1769f07639a2 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 19:36:28 -0400 Subject: [PATCH 05/18] requirements-dev.txt remove requests-mock, README.md add uvx command with input file --- README.md | 5 +++++ {{cookiecutter.git_repo_name}}/requirements-dev.txt | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 06f7162..8f6b2da 100644 --- a/README.md +++ b/README.md @@ -53,6 +53,11 @@ cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git -c 1.0.1 uvx cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop ``` +### UV with input file +```text +uvx cookiecutter -f --no-input --config-file test-repo.yml git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop +``` + 4. Now you will be asked a series of questions. This is an example **THE QUESTIONS MAY NOT BE THE EXACT FOR THIS COOKIECUTTER**, also if you have downloaded it before you will be asked if you want to download it again, always say yes to get the latest version. diff --git a/{{cookiecutter.git_repo_name}}/requirements-dev.txt b/{{cookiecutter.git_repo_name}}/requirements-dev.txt index 5fd9307..628d6c8 100644 --- a/{{cookiecutter.git_repo_name}}/requirements-dev.txt +++ b/{{cookiecutter.git_repo_name}}/requirements-dev.txt @@ -17,4 +17,3 @@ httpx twine bandit ruff -{% if cookiecutter.use_requests == 'y' %}requests-mock{% endif %} From cbd0d50bab0a6cb31b46712467ca4c6d94c4409c Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 19:42:01 -0400 Subject: [PATCH 06/18] cookiecutter.json, pyproject.toml, requirements.txt update use_django-environ to use underscore --- cookiecutter.json | 4 ++-- {{cookiecutter.git_repo_name}}/pyproject.toml | 2 +- {{cookiecutter.git_repo_name}}/requirements.txt | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index a4cd7b1..2ec0829 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -26,7 +26,7 @@ "uv", "pip" ], - "use_django-environ": [ + "use_django_environ": [ "n", "y" ], @@ -80,7 +80,7 @@ "uv": "UV By Astral", "pip": "PIP (The built in Python Package Installer)" }, - "use_django-environ": { + "use_django_environ": { "__prompt__": "Will you use the Django Environment library", "n": "No", "y": "Yes" diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index e7a9b3e..bbbb55c 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -59,7 +59,7 @@ classifiers = [ dependencies = [ "django", {% if cookiecutter.use_django_markdownx == 'y' %}"django-markdownx",{% endif %} - {% if cookiecutter.use_django-environ == 'y' %}"django-environ",{% endif %} + {% if cookiecutter.use_django_environ == 'y' %}"django-environ",{% endif %} ] [dependency-groups] diff --git a/{{cookiecutter.git_repo_name}}/requirements.txt b/{{cookiecutter.git_repo_name}}/requirements.txt index c509ee2..36839bf 100644 --- a/{{cookiecutter.git_repo_name}}/requirements.txt +++ b/{{cookiecutter.git_repo_name}}/requirements.txt @@ -3,5 +3,4 @@ # django {% if cookiecutter.use_django_markdownx == 'y' %}django-markdownx{% endif %} -{% if cookiecutter.use_requests == 'y' %}requests{% endif %} -{% if cookiecutter.use_cryptography == 'y' %}cryptography{% endif %} +{% if cookiecutter.use_django_environ == 'y' %}django-environ{% endif %} From 2c2ca75a39f8cd15a59eab7f6d68172797eeb4a5 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 20:48:16 -0400 Subject: [PATCH 07/18] cookiecutter.json: change app_name to project_name, README.md update commands, Added project folder back with __init__.py and version.py, pyproject.toml: changed app_name to project_name --- cookiecutter.json | 2 +- {{cookiecutter.git_repo_name}}/README.md | 17 +++++++++++++++++ {{cookiecutter.git_repo_name}}/pyproject.toml | 2 +- .../{{cookiecutter.__project_name}}/__init__.py | 0 .../{{cookiecutter.__project_name}}/version.py | 8 ++++++++ 5 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py create mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py diff --git a/cookiecutter.json b/cookiecutter.json index 2ec0829..50d35f0 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -14,7 +14,7 @@ "sphinx_rtd_theme", "alabaster" ], - "__app_name": "{{ cookiecutter.git_repo_name.lower().replace(' ', '_').replace('-', '_') }}", + "__project_name": "{{ cookiecutter.git_repo_name.lower().replace(' ', '_').replace('-', '_') }}", "minimum_python_version": [ "3.9", "3.10", diff --git a/{{cookiecutter.git_repo_name}}/README.md b/{{cookiecutter.git_repo_name}}/README.md index dd392ed..fe74345 100644 --- a/{{cookiecutter.git_repo_name}}/README.md +++ b/{{cookiecutter.git_repo_name}}/README.md @@ -3,6 +3,23 @@ ## Description * {{ cookiecutter.app_description }} +## Setup `UV` +- Create Python Virtual Environment +```bash +uv venv +``` + +- Activate `venv` +```bash +source .venv/bin/activate +``` + +- Install requirement libraries +```bash +uv sync +``` + + #### Generated by CookieCutter * Repository: [GitHub]({{ cookiecutter.__template_repo }}) * Version: {{ cookiecutter.__template_version }} diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index bbbb55c..26c660e 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -86,7 +86,7 @@ Tracker = "{{ cookiecutter.git_url }}/issues" [tool.setuptools.packages.find] include = [ - "{{cookiecutter.__app_name}}*", + "{{cookiecutter.__project_name}}*", ] # Add or remove file extensions to include the data diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py new file mode 100644 index 0000000..62be7f6 --- /dev/null +++ b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py @@ -0,0 +1,8 @@ +""" +Holds the version information for the package +""" +__copyright__ = 'Copyright (c) {% now 'local', '%Y' %} {{ cookiecutter.full_name }}' +__status__ = 'prod' +{% set version_info = cookiecutter.app_version.split('.') %} +__version_info__ = ({{ version_info[0] }}, {{ version_info[1] }}, {{ version_info[2] }}) +__version__ = '.'.join(map(str, __version_info__)) \ No newline at end of file From 2585db28fafe75bce3f27d2bd482e306d3c466a3 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 20:52:03 -0400 Subject: [PATCH 08/18] change _app_name to _project_name --- cookiecutter.json | 2 +- {{cookiecutter.git_repo_name}}/Makefile | 18 +++++++------- {{cookiecutter.git_repo_name}}/docs/conf.py | 2 +- {{cookiecutter.git_repo_name}}/make.bat | 24 +++++++++---------- {{cookiecutter.git_repo_name}}/pyproject.toml | 4 ++-- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/cookiecutter.json b/cookiecutter.json index 50d35f0..e411102 100644 --- a/cookiecutter.json +++ b/cookiecutter.json @@ -46,7 +46,7 @@ "__template_version": "1.0.0", "_new_lines": "\n", "_copy_without_render": [ - "{{cookiecutter.__app_name}}/templates", + "{{cookiecutter.__project_name}}/templates", ".github" ], "__prompts__": { diff --git a/{{cookiecutter.git_repo_name}}/Makefile b/{{cookiecutter.git_repo_name}}/Makefile index 823399a..aa4a575 100644 --- a/{{cookiecutter.git_repo_name}}/Makefile +++ b/{{cookiecutter.git_repo_name}}/Makefile @@ -37,11 +37,11 @@ coverage: @pytest --cov --cov-report=html -vvv format: - @black {{cookiecutter.__app_name}}/ + @black {{cookiecutter.__project_name}}/ @black tests/ pylint: - @pylint {{cookiecutter.__app_name}}/ + @pylint {{cookiecutter.__project_name}}/ pytest: @pytest --cov -vvv @@ -58,7 +58,7 @@ check-security: {% if cookiecutter.app_documents_location == 'github-pages' %} gh-pages: @rm -rf ./docs/source/code - @sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__app_name}} + @sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} @sphinx-build ./docs ./docs/gh-pages {% endif %} @@ -73,25 +73,25 @@ coverage: @uv run pytest --cov --cov-report=html -vvv format: - @uv run black {{cookiecutter.__app_name}}/ + @uv run black {{cookiecutter.__project_name}}/ @uv run black tests/ pylint: - @uv run pylint {{cookiecutter.__app_name}}/ + @uv run pylint {{cookiecutter.__project_name}}/ pytest: @uv run pytest --cov -vvv ruff-format: - @uv run ruff format {{cookiecutter.__app_name}}/ + @uv run ruff format {{cookiecutter.__project_name}}/ @uv run ruff format tests/ ruff-lint: - @uv run ruff check {{cookiecutter.__app_name}}/ + @uv run ruff check {{cookiecutter.__project_name}}/ # Need to change for django dev-run: - @uv run python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r + @uv run python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r check-security: @uv run bandit -c pyproject.toml -r . @@ -103,7 +103,7 @@ pip-export: {% if cookiecutter.app_documents_location == 'github-pages' %} gh-pages: @rm -rf ./docs/source/code - @uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__app_name}} + @uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} @uv run sphinx-build ./docs ./docs/gh-pages {% endif %} diff --git a/{{cookiecutter.git_repo_name}}/docs/conf.py b/{{cookiecutter.git_repo_name}}/docs/conf.py index 858e909..ad7b388 100644 --- a/{{cookiecutter.git_repo_name}}/docs/conf.py +++ b/{{cookiecutter.git_repo_name}}/docs/conf.py @@ -19,7 +19,7 @@ # Reads version.py and converts to a dict of keys version_py = {} -with open(os.path.join(base_path, '{{cookiecutter.__app_name}}', 'version.py'), 'r', encoding='utf-8') as f: +with open(os.path.join(base_path, '{{cookiecutter.__project_name}}', 'version.py'), 'r', encoding='utf-8') as f: exec(f.read(), version_py) # Reads pyproject.toml and converts to python objects diff --git a/{{cookiecutter.git_repo_name}}/make.bat b/{{cookiecutter.git_repo_name}}/make.bat index 23ff15d..64d1841 100644 --- a/{{cookiecutter.git_repo_name}}/make.bat +++ b/{{cookiecutter.git_repo_name}}/make.bat @@ -13,9 +13,9 @@ IF "%option%" == "" ( {% if cookiecutter.package_manager == 'pip' %} IF "%option%" == "all" ( - black {{cookiecutter.__app_name}}/ + black {{cookiecutter.__project_name}}/ black tests/ - pylint {{cookiecutter.__app_name}}\ + pylint {{cookiecutter.__project_name}}\ pytest --cov --cov-report=html -vvv bandit -c pyproject.toml -r . pip-audit -r requirements.txt @@ -33,7 +33,7 @@ IF "%option%" == "coverage" ( ) IF "%option%" == "pylint" ( - pylint {{cookiecutter.__app_name}}\ + pylint {{cookiecutter.__project_name}}\ GOTO END ) @@ -43,12 +43,12 @@ IF "%option%" == "pytest" ( ) IF "%option%" == "dev-run" ( - python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r + python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r GOTO END ) IF "%option%" == "format" ( - black {{cookiecutter.__app_name}}/ + black {{cookiecutter.__project_name}}/ black tests/ GOTO END ) @@ -66,7 +66,7 @@ IF "%option%" == "check-security" ( {% if cookiecutter.app_documents_location == 'github-pages' %} IF "%option%" == "gh-pages" ( rmdir /s /q docs\source\code - sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__app_name}} + sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} sphinx-build ./docs ./docs/gh-pages GOTO END ) @@ -75,9 +75,9 @@ IF "%option%" == "gh-pages" ( {% elif cookiecutter.package_manager == 'uv' %} IF "%option%" == "all" ( - uv run black {{cookiecutter.__app_name}}/ + uv run black {{cookiecutter.__project_name}}/ uv run black tests/ - uv run pylint {{cookiecutter.__app_name}}\ + uv run pylint {{cookiecutter.__project_name}}\ uv run pytest --cov --cov-report=html -vvv uv run bandit -c pyproject.toml -r . uv export --no-dev --no-emit-project --no-editable > requirements.txt @@ -96,7 +96,7 @@ IF "%option%" == "coverage" ( ) IF "%option%" == "pylint" ( - uv run pylint {{cookiecutter.__app_name}}\ + uv run pylint {{cookiecutter.__project_name}}\ GOTO END ) @@ -106,12 +106,12 @@ IF "%option%" == "pytest" ( ) IF "%option%" == "dev-run" ( - uv run python -c "from {{cookiecutter.__app_name}} import cli;cli()" start -p 8080 -r + uv run python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r GOTO END ) IF "%option%" == "format" ( - uv run black {{cookiecutter.__app_name}}/ + uv run black {{cookiecutter.__project_name}}/ uv run black tests/ GOTO END ) @@ -130,7 +130,7 @@ IF "%option%" == "pip-export" ( {% if cookiecutter.app_documents_location == 'github-pages' %} IF "%option%" == "gh-pages" ( rmdir /s /q docs\source\code - uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__app_name}} + uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} uv run sphinx-build ./docs ./docs/gh-pages GOTO END ) diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index 26c660e..1b11973 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -97,7 +97,7 @@ include = [ zip-safe = false [tool.setuptools.dynamic] -version = {attr = "{{cookiecutter.__app_name}}.version.__version__"} +version = {attr = "{{cookiecutter.__project_name}}.version.__version__"} readme = {file = "README.md", content-type = "text/markdown"} {% if cookiecutter.package_manager == 'pip' %} dependencies = {file = "requirements.txt"} @@ -114,7 +114,7 @@ command_line= "-m pytest -vvv" [tool.coverage.report] include = [ - "{{cookiecutter.__app_name}}/*" + "{{cookiecutter.__project_name}}/*" ] fail_under = 70 From 28b920bc260101d987782632b1141b3f8c1e25d6 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 21:09:30 -0400 Subject: [PATCH 09/18] pyproject.toml: update django --- {{cookiecutter.git_repo_name}}/pyproject.toml | 12 ++++++------ .../{{cookiecutter.__project_name}}/__init__.py | 0 .../{{cookiecutter.__project_name}}/version.py | 8 -------- 3 files changed, 6 insertions(+), 14 deletions(-) delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py delete mode 100644 {{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index 1b11973..7aea81b 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -7,11 +7,12 @@ build-backend = "setuptools.build_meta" [project] name = "{{ cookiecutter.git_repo_name }}" -{% if cookiecutter.package_manager == 'pip' %} -dynamic = ["version", "readme", "dependencies"] -{% elif cookiecutter.package_manager == 'uv' %} -dynamic = ["version", "readme"] -{% endif %} +{%- if cookiecutter.package_manager == 'pip' %} +dynamic = ["readme", "dependencies"] +{%- elif cookiecutter.package_manager == 'uv' %} +dynamic = ["readme"] +{% endif -%} +version = "{{ cookiecutter.app_version }}" requires-python = ">={{ cookiecutter.minimum_python_version }}" description = "{{ cookiecutter.app_description }}" keywords = [ @@ -97,7 +98,6 @@ include = [ zip-safe = false [tool.setuptools.dynamic] -version = {attr = "{{cookiecutter.__project_name}}.version.__version__"} readme = {file = "README.md", content-type = "text/markdown"} {% if cookiecutter.package_manager == 'pip' %} dependencies = {file = "requirements.txt"} diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py b/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py deleted file mode 100644 index 62be7f6..0000000 --- a/{{cookiecutter.git_repo_name}}/{{cookiecutter.__project_name}}/version.py +++ /dev/null @@ -1,8 +0,0 @@ -""" -Holds the version information for the package -""" -__copyright__ = 'Copyright (c) {% now 'local', '%Y' %} {{ cookiecutter.full_name }}' -__status__ = 'prod' -{% set version_info = cookiecutter.app_version.split('.') %} -__version_info__ = ({{ version_info[0] }}, {{ version_info[1] }}, {{ version_info[2] }}) -__version__ = '.'.join(map(str, __version_info__)) \ No newline at end of file From d84ba4e5dfaf40b6ed622c6e7f32f42cd8c88d13 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 21:45:41 -0400 Subject: [PATCH 10/18] README.md and pyproject.toml fixes --- {{cookiecutter.git_repo_name}}/README.md | 6 ++++++ {{cookiecutter.git_repo_name}}/pyproject.toml | 15 +++++++++------ 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/{{cookiecutter.git_repo_name}}/README.md b/{{cookiecutter.git_repo_name}}/README.md index fe74345..8876dd4 100644 --- a/{{cookiecutter.git_repo_name}}/README.md +++ b/{{cookiecutter.git_repo_name}}/README.md @@ -19,6 +19,12 @@ source .venv/bin/activate uv sync ``` +- Initilize Django project +```bash +django-admin startproject +``` + + #### Generated by CookieCutter * Repository: [GitHub]({{ cookiecutter.__template_repo }}) diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index 7aea81b..c5756a6 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -78,16 +78,18 @@ dev = [ "bandit", "ruff", ] -{% endif %} +{% endif -%} [project.urls] Documentation = "https://{{ cookiecutter.git_repo_name }}.readthedocs.io/en/latest/" Source = "{{ cookiecutter.git_url }}" Tracker = "{{ cookiecutter.git_url }}/issues" +# Add your project folder and app folders [tool.setuptools.packages.find] include = [ - "{{cookiecutter.__project_name}}*", + "*", + "*", ] # Add or remove file extensions to include the data @@ -112,9 +114,11 @@ markers = [ [tool.coverage.run] command_line= "-m pytest -vvv" +# Add your project folder and app folders [tool.coverage.report] include = [ - "{{cookiecutter.__project_name}}/*" + "*", + "*", ] fail_under = 70 @@ -137,11 +141,10 @@ exclude_dirs = [ "docs", ] -{% if cookiecutter.package_manager == 'uv' %} +{%- if cookiecutter.package_manager == 'uv' %} # UV settings reference https://docs.astral.sh/uv/reference/settings/ - [tool.uv] keyring-provider = "subprocess" native-tls = true -{% endif %} +{% endif -%} From 17e692882074d425bcbee230963ee06736ec7e9c Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 22:54:52 -0400 Subject: [PATCH 11/18] README.md update setup steps, make.bat and Makefile changed project_folder to a variable --- {{cookiecutter.git_repo_name}}/Makefile | 19 +++++++------- {{cookiecutter.git_repo_name}}/README.md | 25 ++++++++++++++++--- {{cookiecutter.git_repo_name}}/make.bat | 25 ++++++++++--------- {{cookiecutter.git_repo_name}}/pyproject.toml | 4 +-- 4 files changed, 47 insertions(+), 26 deletions(-) diff --git a/{{cookiecutter.git_repo_name}}/Makefile b/{{cookiecutter.git_repo_name}}/Makefile index aa4a575..e72eb81 100644 --- a/{{cookiecutter.git_repo_name}}/Makefile +++ b/{{cookiecutter.git_repo_name}}/Makefile @@ -2,6 +2,7 @@ # Author: Ben Trachtenberg # Version: 2.0.0 # +PROJECT = .PHONY: all info build build-container coverage format pylint pytest gh-pages build dev-run start-container \ stop-container remove-container check-vuln check-security pip-export @@ -37,11 +38,11 @@ coverage: @pytest --cov --cov-report=html -vvv format: - @black {{cookiecutter.__project_name}}/ + @black $(PROJECT)/ @black tests/ pylint: - @pylint {{cookiecutter.__project_name}}/ + @pylint $(PROJECT)/ pytest: @pytest --cov -vvv @@ -58,7 +59,7 @@ check-security: {% if cookiecutter.app_documents_location == 'github-pages' %} gh-pages: @rm -rf ./docs/source/code - @sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} + @sphinx-apidoc -o ./docs/source/code ./$(PROJECT) @sphinx-build ./docs ./docs/gh-pages {% endif %} @@ -73,25 +74,25 @@ coverage: @uv run pytest --cov --cov-report=html -vvv format: - @uv run black {{cookiecutter.__project_name}}/ + @uv run black $(PROJECT)/ @uv run black tests/ pylint: - @uv run pylint {{cookiecutter.__project_name}}/ + @uv run pylint $(PROJECT)/ pytest: @uv run pytest --cov -vvv ruff-format: - @uv run ruff format {{cookiecutter.__project_name}}/ + @uv run ruff format $(PROJECT)/ @uv run ruff format tests/ ruff-lint: - @uv run ruff check {{cookiecutter.__project_name}}/ + @uv run ruff check $(PROJECT)/ # Need to change for django dev-run: - @uv run python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r + @uv run python manage.py runserver check-security: @uv run bandit -c pyproject.toml -r . @@ -103,7 +104,7 @@ pip-export: {% if cookiecutter.app_documents_location == 'github-pages' %} gh-pages: @rm -rf ./docs/source/code - @uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} + @uv run sphinx-apidoc -o ./docs/source/code ./$(PROJECT) @uv run sphinx-build ./docs ./docs/gh-pages {% endif %} diff --git a/{{cookiecutter.git_repo_name}}/README.md b/{{cookiecutter.git_repo_name}}/README.md index 8876dd4..624a699 100644 --- a/{{cookiecutter.git_repo_name}}/README.md +++ b/{{cookiecutter.git_repo_name}}/README.md @@ -1,9 +1,11 @@ # {{ cookiecutter.git_repo_name }} + ## Description * {{ cookiecutter.app_description }} -## Setup `UV` + +## Setup Project and test server with `UV` - Create Python Virtual Environment ```bash uv venv @@ -19,11 +21,28 @@ source .venv/bin/activate uv sync ``` -- Initilize Django project +- Initialize Django project +> [!NOTE] +> Note the `.` at the end of the command. This will create the project files and structure directly within the current directory. You do not have to use this option but if you don't then `manage.py` will be nested in the `` folder with another `` folder with the project files. + ```bash -django-admin startproject +django-admin startproject . ``` +- Add the `` folder name to your `pyproject.toml` in the `tool.setuptools.packages.find` and `tool.coverage.report` sections + +- Add the `` folder name to your `Makefile` and `make.bat` variables + +- Test starting the server +```bash +python manage.py runserver +``` + +- Test server is running: [Django Local Server](http://127.0.0.1:8000/) + + +## **🎉 Happy Django Developing 🎉** + #### Generated by CookieCutter diff --git a/{{cookiecutter.git_repo_name}}/make.bat b/{{cookiecutter.git_repo_name}}/make.bat index 64d1841..878796f 100644 --- a/{{cookiecutter.git_repo_name}}/make.bat +++ b/{{cookiecutter.git_repo_name}}/make.bat @@ -5,6 +5,7 @@ REM Version: 2.0.0 REM SET option=%1 +SET PROJECT= IF "%option%" == "" ( GOTO BAD_OPTIONS @@ -13,9 +14,9 @@ IF "%option%" == "" ( {% if cookiecutter.package_manager == 'pip' %} IF "%option%" == "all" ( - black {{cookiecutter.__project_name}}/ + black %PROJECT%/ black tests/ - pylint {{cookiecutter.__project_name}}\ + pylint %PROJECT%\ pytest --cov --cov-report=html -vvv bandit -c pyproject.toml -r . pip-audit -r requirements.txt @@ -33,7 +34,7 @@ IF "%option%" == "coverage" ( ) IF "%option%" == "pylint" ( - pylint {{cookiecutter.__project_name}}\ + pylint %PROJECT%\ GOTO END ) @@ -43,12 +44,12 @@ IF "%option%" == "pytest" ( ) IF "%option%" == "dev-run" ( - python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r + python -c "from %PROJECT% import cli;cli()" start -p 8080 -r GOTO END ) IF "%option%" == "format" ( - black {{cookiecutter.__project_name}}/ + black %PROJECT%/ black tests/ GOTO END ) @@ -66,7 +67,7 @@ IF "%option%" == "check-security" ( {% if cookiecutter.app_documents_location == 'github-pages' %} IF "%option%" == "gh-pages" ( rmdir /s /q docs\source\code - sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} + sphinx-apidoc -o ./docs/source/code ./%PROJECT% sphinx-build ./docs ./docs/gh-pages GOTO END ) @@ -75,9 +76,9 @@ IF "%option%" == "gh-pages" ( {% elif cookiecutter.package_manager == 'uv' %} IF "%option%" == "all" ( - uv run black {{cookiecutter.__project_name}}/ + uv run black %PROJECT%/ uv run black tests/ - uv run pylint {{cookiecutter.__project_name}}\ + uv run pylint %PROJECT%\ uv run pytest --cov --cov-report=html -vvv uv run bandit -c pyproject.toml -r . uv export --no-dev --no-emit-project --no-editable > requirements.txt @@ -96,7 +97,7 @@ IF "%option%" == "coverage" ( ) IF "%option%" == "pylint" ( - uv run pylint {{cookiecutter.__project_name}}\ + uv run pylint %PROJECT%\ GOTO END ) @@ -106,12 +107,12 @@ IF "%option%" == "pytest" ( ) IF "%option%" == "dev-run" ( - uv run python -c "from {{cookiecutter.__project_name}} import cli;cli()" start -p 8080 -r + uv run python manage.py runserver GOTO END ) IF "%option%" == "format" ( - uv run black {{cookiecutter.__project_name}}/ + uv run black %PROJECT%/ uv run black tests/ GOTO END ) @@ -130,7 +131,7 @@ IF "%option%" == "pip-export" ( {% if cookiecutter.app_documents_location == 'github-pages' %} IF "%option%" == "gh-pages" ( rmdir /s /q docs\source\code - uv run sphinx-apidoc -o ./docs/source/code ./{{cookiecutter.__project_name}} + uv run sphinx-apidoc -o ./docs/source/code ./%PROJECT% uv run sphinx-build ./docs ./docs/gh-pages GOTO END ) diff --git a/{{cookiecutter.git_repo_name}}/pyproject.toml b/{{cookiecutter.git_repo_name}}/pyproject.toml index c5756a6..fa766ae 100644 --- a/{{cookiecutter.git_repo_name}}/pyproject.toml +++ b/{{cookiecutter.git_repo_name}}/pyproject.toml @@ -89,7 +89,7 @@ Tracker = "{{ cookiecutter.git_url }}/issues" [tool.setuptools.packages.find] include = [ "*", - "*", + # "*", ] # Add or remove file extensions to include the data @@ -118,7 +118,7 @@ command_line= "-m pytest -vvv" [tool.coverage.report] include = [ "*", - "*", + # "*", ] fail_under = 70 From a1b44404677cc2cba39a30e8cc34bd05872f0817 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Tue, 26 Aug 2025 23:35:07 -0400 Subject: [PATCH 12/18] README.md updates, conf.py: removed version.py references --- {{cookiecutter.git_repo_name}}/README.md | 3 +-- {{cookiecutter.git_repo_name}}/docs/conf.py | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/{{cookiecutter.git_repo_name}}/README.md b/{{cookiecutter.git_repo_name}}/README.md index 624a699..798c5f2 100644 --- a/{{cookiecutter.git_repo_name}}/README.md +++ b/{{cookiecutter.git_repo_name}}/README.md @@ -22,8 +22,7 @@ uv sync ``` - Initialize Django project -> [!NOTE] -> Note the `.` at the end of the command. This will create the project files and structure directly within the current directory. You do not have to use this option but if you don't then `manage.py` will be nested in the `` folder with another `` folder with the project files. +> :exclamation: Note the `.` at the end of the command. This will create the project files and structure directly within the current directory. You do not have to use this option but if you don't then `manage.py` will be nested in the `` folder with another `` folder with the project files. ```bash django-admin startproject . diff --git a/{{cookiecutter.git_repo_name}}/docs/conf.py b/{{cookiecutter.git_repo_name}}/docs/conf.py index ad7b388..adc14dd 100644 --- a/{{cookiecutter.git_repo_name}}/docs/conf.py +++ b/{{cookiecutter.git_repo_name}}/docs/conf.py @@ -13,15 +13,11 @@ import os import sys import tomli +from datetime import date base_path = os.path.split(os.path.join(os.path.abspath(os.path.dirname(__name__))))[0] sys.path.append(base_path) sys.path.append(os.path.join(base_path, 'docs', '_ext')) -# Reads version.py and converts to a dict of keys -version_py = {} -with open(os.path.join(base_path, '{{cookiecutter.__project_name}}', 'version.py'), 'r', encoding='utf-8') as f: - exec(f.read(), version_py) - # Reads pyproject.toml and converts to python objects with open(os.path.join(base_path, 'pyproject.toml'), 'r', encoding='utf-8') as file: toml = file.read() @@ -35,9 +31,9 @@ # -- Project information ----------------------------------------------------- -release = version_py['__version__'] +release = pyproject_toml["project"]["version"] project = f"{pyproject_toml['project']['name']} v{release}" -copyright = version_py['__copyright__'] +copyright = f"Copyright (c) {date.today().year}, {pyproject_toml['project']['authors'][0]['name']}" # Reads authors from pyproject.toml and adds name to list authors = [] From ed5158de29571ef6a85b48a1f7d830ffbf6542f7 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Wed, 27 Aug 2025 16:36:25 -0400 Subject: [PATCH 13/18] pyproject.toml updates for django, conftest.py: updated all tests for django project, test_cookies.py: updates tests for django projects, test_pre_gen_project.py: updates tests for django options, Containerfile and Dockerfile adjusted statup commands --- pyproject.toml | 54 + tests/conftest.py | 73 +- tests/test_cookies.py | 182 ++- tests/test_pre_gen_project.py | 11 + uv.lock | 1023 +++++++++++++++++ {{cookiecutter.git_repo_name}}/.dockerignore | 0 .../containers/Containerfile | 3 +- .../containers/Dockerfile | 2 +- 8 files changed, 1173 insertions(+), 175 deletions(-) create mode 100644 uv.lock create mode 100644 {{cookiecutter.git_repo_name}}/.dockerignore diff --git a/pyproject.toml b/pyproject.toml index bf9ca46..d3cd42e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,57 @@ +[project] +name = "cookiecutter-python-django" +dynamic = ["readme"] +version = "0.1.0" +requires-python = ">=3.10" +description = "CookieCutter for creating Python Django project" +keywords = [ +] +authors = [ + { name="Blaze Bryant", email="naturalblaze@gmail.com" }, +] +maintainers = [ + {name = "Blaze Bryant", email = "naturalblaze@gmail.com"}, +] +license = "MIT" +license-files = [ + "LICENSE" +] +classifiers = [ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Natural Language :: English", + "Operating System :: MacOS :: MacOS X", + "Operating System :: POSIX", + "Operating System :: POSIX :: BSD", + "Operating System :: POSIX :: Linux", + "Operating System :: Microsoft :: Windows", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3 :: Only", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", + ] + + +dependencies = [ + "cookiecutter", +] + +[dependency-groups] +dev = [ + "pytest-cov", + "pytest-cookies", + "pylint", + "pip-audit", + "black", + "bandit", + "pip-audit", +] + +[tool.setuptools.dynamic] +readme = {file = "README.md", content-type = "text/markdown"} + [tool.pytest.ini_options] addopts = "--strict-markers" markers = [ diff --git a/tests/conftest.py b/tests/conftest.py index 6711159..1592154 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,13 +7,12 @@ @pytest.fixture -def bake_project_api_only_podman() -> dict: +def bake_project_podman_pip() -> dict: options = { - "git_repo_name": "api-only", - "include_webpages": "n", + "git_repo_name": "podman-project-pip", "email": "name@example.com", "git_username": "some-username", - "git_url": "https://github.com/some-username/python-with-cli", + "git_url": "https://github.com/some-username/python-django", "package_manager": "pip", } @@ -21,10 +20,9 @@ def bake_project_api_only_podman() -> dict: @pytest.fixture -def bake_project_uv_api_only_podman() -> dict: +def bake_project_podman_uv() -> dict: options = { - "git_repo_name": "api-only", - "include_webpages": "n", + "git_repo_name": "podman-project-uv", "email": "name@example.com", "git_username": "some-username", "git_url": "https://github.com/some-username/python-with-cli", @@ -35,10 +33,9 @@ def bake_project_uv_api_only_podman() -> dict: @pytest.fixture -def bake_project_api_only_docker() -> dict: +def bake_project_docker_pip() -> dict: options = { - "git_repo_name": "api-only", - "include_webpages": "n", + "git_repo_name": "docker-project-pip", "email": "name@example.com", "git_username": "some-username", "git_url": "https://github.com/some-username/python-with-cli", @@ -50,10 +47,9 @@ def bake_project_api_only_docker() -> dict: @pytest.fixture -def bake_project_uv_api_only_docker() -> dict: +def bake_project_docker_uv() -> dict: options = { - "git_repo_name": "api-only", - "include_webpages": "n", + "git_repo_name": "docker-project-uv", "email": "name@example.com", "git_username": "some-username", "git_url": "https://github.com/some-username/python-with-cli", @@ -65,58 +61,15 @@ def bake_project_uv_api_only_docker() -> dict: @pytest.fixture -def bake_project_api_with_webpages_podman() -> dict: - options = { - "git_repo_name": "api-with-webpages", - "include_webpages": "y", - "email": "name@example.com", - "git_username": "some-username", - "git_url": "https://github.com/some-username/python-with-cli", - "package_manager": "pip", - } - - return options - - -@pytest.fixture -def bake_project_uv_api_with_webpages_podman() -> dict: - options = { - "git_repo_name": "api-with-webpages", - "include_webpages": "y", - "email": "name@example.com", - "git_username": "some-username", - "git_url": "https://github.com/some-username/python-with-cli", - "package_manager": "uv", - } - - return options - - -@pytest.fixture -def bake_project_api_with_webpages_docker() -> dict: - options = { - "git_repo_name": "api-with-webpages", - "include_webpages": "y", - "email": "name@example.com", - "git_username": "some-username", - "git_url": "https://github.com/some-username/python-with-cli", - "container_runtime": "docker", - "package_manager": "pip", - } - - return options - - -@pytest.fixture -def bake_project_uv_api_with_webpages_docker() -> dict: +def bake_project_django_addons() -> dict: options = { - "git_repo_name": "api-with-webpages", - "include_webpages": "y", + "git_repo_name": "django-project-addons", "email": "name@example.com", "git_username": "some-username", "git_url": "https://github.com/some-username/python-with-cli", - "container_runtime": "docker", "package_manager": "uv", + "use_django_environ": "y", + "use_django_markdownx": "y", } return options diff --git a/tests/test_cookies.py b/tests/test_cookies.py index 486f602..b514ccb 100644 --- a/tests/test_cookies.py +++ b/tests/test_cookies.py @@ -1,182 +1,140 @@ -def test_bake_project_api_only_podman(cookies, bake_project_api_only_podman): - result = cookies.bake(extra_context=bake_project_api_only_podman) +"""Tests for cookiecutter-python-django project template.""" +import os +import tomli + +def test_bake_project_podman(cookies, bake_project_podman_pip:dict): + """Test baking project with podman and pip + + Args: + cookies (pytest-cookie): pytest-cookie function + bake_project_podman_pip (dict): fixture with podman and pip options + """ + result = cookies.bake(extra_context=bake_project_podman_pip) assert result.exit_code == 0 assert result.exception is None - assert result.project_path.name == "api-only" + assert result.project_path.name == "podman-project-pip" assert result.project_path.is_dir() assert result.project_path.joinpath("README.md").is_file() assert result.project_path.joinpath("requirements.txt").is_file() assert result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_only").is_dir() assert result.project_path.joinpath("containers").is_dir() assert result.project_path.joinpath("containers", "Containerfile").is_file() assert not result.project_path.joinpath("containers", "Dockerfile").is_file() - assert not result.project_path.joinpath("api_only", "static").is_dir() - assert not result.project_path.joinpath("api_only", "templates").is_dir() - assert not result.project_path.joinpath("api_only", "routers", "hello_world.py").is_file() + assert result.project_path.joinpath("tests").is_dir() + assert result.project_path.joinpath("tests", "conftest.py").is_file() + assert result.project_path.joinpath("tests", "data").is_dir() + assert result.project_path.joinpath("tests", "data", "README.md").is_file() assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() -def test_bake_project_uv_api_only_podman(cookies, bake_project_uv_api_only_podman): - result = cookies.bake(extra_context=bake_project_uv_api_only_podman) +def test_bake_project_podman_uv(cookies, bake_project_podman_uv: dict): + """Test baking project with podman and uv + + Args: + cookies (pytest-cookie): pytest-cookie function + bake_project_podman_pip (dict): fixture with podman and uv options + """ + result = cookies.bake(extra_context=bake_project_podman_uv) assert result.exit_code == 0 assert result.exception is None - assert result.project_path.name == "api-only" + assert result.project_path.name == "podman-project-uv" assert result.project_path.is_dir() assert result.project_path.joinpath("README.md").is_file() assert not result.project_path.joinpath("requirements.txt").is_file() assert not result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_only").is_dir() assert result.project_path.joinpath("containers").is_dir() assert result.project_path.joinpath("containers", "Containerfile").is_file() assert not result.project_path.joinpath("containers", "Dockerfile").is_file() - assert not result.project_path.joinpath("api_only", "static").is_dir() - assert not result.project_path.joinpath("api_only", "templates").is_dir() - assert not result.project_path.joinpath("api_only", "routers", "hello_world.py").is_file() + assert result.project_path.joinpath("tests").is_dir() + assert result.project_path.joinpath("tests", "conftest.py").is_file() + assert result.project_path.joinpath("tests", "data").is_dir() + assert result.project_path.joinpath("tests", "data", "README.md").is_file() assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() -def test_bake_project_api_only_docker(cookies, bake_project_api_only_docker): - result = cookies.bake(extra_context=bake_project_api_only_docker) +def test_bake_project_docker_pip(cookies, bake_project_docker_pip: dict): + """Test baking project with docker and pip + + Args: + cookies (pytest-cookie): pytest-cookie function + bake_project_docker_pip (dict): fixture with docker and pip options + """ + result = cookies.bake(extra_context=bake_project_docker_pip) assert result.exit_code == 0 assert result.exception is None - assert result.project_path.name == "api-only" + assert result.project_path.name == "docker-project-pip" assert result.project_path.is_dir() assert result.project_path.joinpath("README.md").is_file() assert result.project_path.joinpath("requirements.txt").is_file() assert result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_only").is_dir() assert result.project_path.joinpath("containers").is_dir() assert not result.project_path.joinpath("containers", "Containerfile").is_file() assert result.project_path.joinpath("containers", "Dockerfile").is_file() - assert not result.project_path.joinpath("api_only", "static").is_dir() - assert not result.project_path.joinpath("api_only", "templates").is_dir() - assert not result.project_path.joinpath("api_only", "routers", "hello_world.py").is_file() + assert result.project_path.joinpath("tests").is_dir() + assert result.project_path.joinpath("tests", "conftest.py").is_file() + assert result.project_path.joinpath("tests", "data").is_dir() + assert result.project_path.joinpath("tests", "data", "README.md").is_file() assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() -def test_bake_project_uv_api_only_docker(cookies, bake_project_uv_api_only_docker): - result = cookies.bake(extra_context=bake_project_uv_api_only_docker) +def test_bake_project_docker_uv(cookies, bake_project_docker_uv: dict): + """Test baking project with docker and uv + + Args: + cookies (pytest-cookie): pytest-cookie function + bake_project_docker_uv (dict): fixture with docker and uv options + """ + result = cookies.bake(extra_context=bake_project_docker_uv) assert result.exit_code == 0 assert result.exception is None - assert result.project_path.name == "api-only" + assert result.project_path.name == "docker-project-uv" assert result.project_path.is_dir() assert result.project_path.joinpath("README.md").is_file() assert not result.project_path.joinpath("requirements.txt").is_file() assert not result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_only").is_dir() assert result.project_path.joinpath("containers").is_dir() assert not result.project_path.joinpath("containers", "Containerfile").is_file() assert result.project_path.joinpath("containers", "Dockerfile").is_file() - assert not result.project_path.joinpath("api_only", "static").is_dir() - assert not result.project_path.joinpath("api_only", "templates").is_dir() - assert not result.project_path.joinpath("api_only", "routers", "hello_world.py").is_file() + assert result.project_path.joinpath("tests").is_dir() + assert result.project_path.joinpath("tests", "conftest.py").is_file() + assert result.project_path.joinpath("tests", "data").is_dir() + assert result.project_path.joinpath("tests", "data", "README.md").is_file() assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() -def test_bake_project_api_with_webpages_podman(cookies, bake_project_api_with_webpages_podman): - result = cookies.bake(extra_context=bake_project_api_with_webpages_podman) +def test_bake_project_django_addons(cookies, bake_project_django_addons: dict): + """Test baking project with django addons - assert result.exit_code == 0 - assert result.exception is None - assert result.project_path.name == "api-with-webpages" - assert result.project_path.is_dir() - assert result.project_path.joinpath("README.md").is_file() - assert result.project_path.joinpath("requirements.txt").is_file() - assert result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_with_webpages").is_dir() - assert result.project_path.joinpath("containers").is_dir() - assert result.project_path.joinpath("containers", "Containerfile").is_file() - assert not result.project_path.joinpath("containers", "Dockerfile").is_file() - assert result.project_path.joinpath("api_with_webpages", "static").is_dir() - assert result.project_path.joinpath("api_with_webpages", "templates").is_dir() - assert result.project_path.joinpath("api_with_webpages", "routers", "hello_world.py").is_file() - assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() + Args: + cookies (pytest-cookie): pytest-cookie function + bake_project_django_addons (dict): fixture with django addons options + """ + result = cookies.bake(extra_context=bake_project_django_addons) - -def test_bake_project_uv_api_with_webpages_podman(cookies, bake_project_uv_api_with_webpages_podman): - result = cookies.bake(extra_context=bake_project_uv_api_with_webpages_podman) + # Reads pyproject.toml and converts to python objects + with open(result.project_path.joinpath("pyproject.toml"), 'r', encoding='utf-8') as file: + toml = file.read() + pyproject_toml = tomli.loads(toml) assert result.exit_code == 0 assert result.exception is None - assert result.project_path.name == "api-with-webpages" + assert result.project_path.name == "django-project-addons" assert result.project_path.is_dir() - assert result.project_path.joinpath("README.md").is_file() - assert not result.project_path.joinpath("requirements.txt").is_file() - assert not result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_with_webpages").is_dir() - assert result.project_path.joinpath("containers").is_dir() - assert result.project_path.joinpath("containers", "Containerfile").is_file() - assert not result.project_path.joinpath("containers", "Dockerfile").is_file() - assert result.project_path.joinpath("api_with_webpages", "static").is_dir() - assert result.project_path.joinpath("api_with_webpages", "templates").is_dir() - assert result.project_path.joinpath("api_with_webpages", "routers", "hello_world.py").is_file() - assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() - - -def test_bake_project_api_with_webpages_docker(cookies, bake_project_api_with_webpages_docker): - result = cookies.bake(extra_context=bake_project_api_with_webpages_docker) - - assert result.exit_code == 0 - assert result.exception is None - assert result.project_path.name == "api-with-webpages" - assert result.project_path.is_dir() - assert result.project_path.joinpath("README.md").is_file() - assert result.project_path.joinpath("requirements.txt").is_file() - assert result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_with_webpages").is_dir() - assert result.project_path.joinpath("containers").is_dir() - assert not result.project_path.joinpath("containers", "Containerfile").is_file() - assert result.project_path.joinpath("containers", "Dockerfile").is_file() - assert result.project_path.joinpath("api_with_webpages", "static").is_dir() - assert result.project_path.joinpath("api_with_webpages", "templates").is_dir() - assert result.project_path.joinpath("api_with_webpages", "routers", "hello_world.py").is_file() - assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() - - -def test_bake_project_uv_api_with_webpages_docker(cookies, bake_project_uv_api_with_webpages_docker): - result = cookies.bake(extra_context=bake_project_uv_api_with_webpages_docker) - - assert result.exit_code == 0 - assert result.exception is None - assert result.project_path.name == "api-with-webpages" - assert result.project_path.is_dir() - assert result.project_path.joinpath("README.md").is_file() - assert not result.project_path.joinpath("requirements.txt").is_file() - assert not result.project_path.joinpath("requirements-dev.txt").is_file() - assert result.project_path.joinpath("api_with_webpages").is_dir() - assert result.project_path.joinpath("containers").is_dir() - assert not result.project_path.joinpath("containers", "Containerfile").is_file() - assert result.project_path.joinpath("containers", "Dockerfile").is_file() - assert result.project_path.joinpath("api_with_webpages", "static").is_dir() - assert result.project_path.joinpath("api_with_webpages", "templates").is_dir() - assert result.project_path.joinpath("api_with_webpages", "routers", "hello_world.py").is_file() - assert not result.project_path.joinpath(".github", "workflows", "publish-to-pypi.yml").is_file() - assert not result.project_path.joinpath(".github", "workflows", "test-coverage-lint.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "publish-to-pypi-uv.yml").is_file() - assert result.project_path.joinpath(".github", "workflows", "test-coverage-lint-uv.yml").is_file() + assert pyproject_toml["project"]["dependencies"].count("django-environ") == 1 + assert pyproject_toml["project"]["dependencies"].count("django-markdownx") == 1 diff --git a/tests/test_pre_gen_project.py b/tests/test_pre_gen_project.py index 0f52a00..dcd4f29 100644 --- a/tests/test_pre_gen_project.py +++ b/tests/test_pre_gen_project.py @@ -1,3 +1,4 @@ +"""Tests for pre_gen_project.py hook functions.""" import pytest from hooks.pre_gen_project import ( validate_no_spaces, @@ -9,12 +10,14 @@ def test_validate_no_spaces(): + """Validate no spaces in the arg_name""" validate_no_spaces("test", "test") validate_no_spaces("test-test", "test") validate_no_spaces("test_test.test", "test") def test_validate_no_spaces_bad(): + """Validate no spaces in the arg_name bad""" with pytest.raises(SystemExit): validate_no_spaces("test test", "test") @@ -26,12 +29,14 @@ def test_validate_no_spaces_bad(): def test_validate_no_spaces_begin_or_end(): + """Validate no spaces beginning or ending in the arg_name1d""" validate_no_spaces_begin_or_end("test test", "test") validate_no_spaces_begin_or_end("test test test", "test") validate_no_spaces_begin_or_end("test test test", "test") def test_validate_no_spaces_begin_or_end_bad(): + """Validate no spaces beginning or ending in the arg_name bad""" with pytest.raises(SystemExit): validate_no_spaces_begin_or_end(" test test", "test") @@ -40,6 +45,7 @@ def test_validate_no_spaces_begin_or_end_bad(): def test_validate_semantic_version(): + """Validate semantic version in the arg_name""" validate_semantic_version("1.0.0", "test") validate_semantic_version("0.0.0", "test") validate_semantic_version("0.0.1", "test") @@ -49,6 +55,7 @@ def test_validate_semantic_version(): def test_validate_semantic_version_bad(): + """Validate semantic version in the arg_name bad""" with pytest.raises(SystemExit): validate_semantic_version("1.0", "test") @@ -57,10 +64,12 @@ def test_validate_semantic_version_bad(): def test_validate_https_url(): + """Validate https url in the arg_name""" validate_https_url("https://something.com", "test") def test_validate_https_url_bad(): + """Validate https url in the arg_name bad""" with pytest.raises(SystemExit): validate_https_url("http://something.com", "test") @@ -69,6 +78,7 @@ def test_validate_https_url_bad(): def test_validate_numbers_letters_hyphens(): + """Validate numbers letters hyphens in the arg_name""" validate_numbers_letters_hyphens("test", "test") validate_numbers_letters_hyphens("test-test", "test") validate_numbers_letters_hyphens("test-test-test", "test") @@ -78,6 +88,7 @@ def test_validate_numbers_letters_hyphens(): def test_validate_numbers_letters_hyphens_bad(): + """Validate numbers letters hyphens in the arg_name bad""" with pytest.raises(SystemExit): validate_numbers_letters_hyphens("test test", "test") diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000..fa721e9 --- /dev/null +++ b/uv.lock @@ -0,0 +1,1023 @@ +version = 1 +revision = 2 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version >= '3.12'", + "python_full_version == '3.11.*'", + "python_full_version < '3.11'", +] + +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960, upload-time = "2023-09-30T22:11:18.25Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419, upload-time = "2023-09-30T22:11:16.072Z" }, +] + +[[package]] +name = "astroid" +version = "3.3.11" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/74/dfb75f9ccd592bbedb175d4a32fc643cf569d7c218508bfbd6ea7ef9c091/astroid-3.3.11.tar.gz", hash = "sha256:1e5a5011af2920c7c67a53f65d536d65bfa7116feeaf2354d8b94f29573bb0ce", size = 400439, upload-time = "2025-07-13T18:04:23.177Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/0f/3b8fdc946b4d9cc8cc1e8af42c4e409468c84441b933d037e101b3d72d86/astroid-3.3.11-py3-none-any.whl", hash = "sha256:54c760ae8322ece1abd213057c4b5bba7c49818853fc901ef09719a60dbf9dec", size = 275612, upload-time = "2025-07-13T18:04:21.07Z" }, +] + +[[package]] +name = "bandit" +version = "1.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "pyyaml" }, + { name = "rich" }, + { name = "stevedore" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/b5/7eb834e213d6f73aace21938e5e90425c92e5f42abafaf8a6d5d21beed51/bandit-1.8.6.tar.gz", hash = "sha256:dbfe9c25fc6961c2078593de55fd19f2559f9e45b99f1272341f5b95dea4e56b", size = 4240271, upload-time = "2025-07-06T03:10:50.9Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/ca/ba5f909b40ea12ec542d5d7bdd13ee31c4d65f3beed20211ef81c18fa1f3/bandit-1.8.6-py3-none-any.whl", hash = "sha256:3348e934d736fcdb68b6aa4030487097e23a501adf3e7827b63658df464dddd0", size = 133808, upload-time = "2025-07-06T03:10:49.134Z" }, +] + +[[package]] +name = "binaryornot" +version = "0.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "chardet" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/fe/7ebfec74d49f97fc55cd38240c7a7d08134002b1e14be8c3897c0dd5e49b/binaryornot-0.4.4.tar.gz", hash = "sha256:359501dfc9d40632edc9fac890e19542db1a287bbcfa58175b66658392018061", size = 371054, upload-time = "2017-08-03T15:55:25.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/7e/f7b6f453e6481d1e233540262ccbfcf89adcd43606f44a028d7f5fae5eb2/binaryornot-0.4.4-py2.py3-none-any.whl", hash = "sha256:b8b71173c917bddcd2c16070412e369c3ed7f0528926f70cac18a6c97fd563e4", size = 9006, upload-time = "2017-08-03T15:55:31.23Z" }, +] + +[[package]] +name = "black" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/94/49/26a7b0f3f35da4b5a65f081943b7bcd22d7002f5f0fb8098ec1ff21cb6ef/black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666", size = 649449, upload-time = "2025-01-29T04:15:40.373Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/3b/4ba3f93ac8d90410423fdd31d7541ada9bcee1df32fb90d26de41ed40e1d/black-25.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759e7ec1e050a15f89b770cefbf91ebee8917aac5c20483bc2d80a6c3a04df32", size = 1629419, upload-time = "2025-01-29T05:37:06.642Z" }, + { url = "https://files.pythonhosted.org/packages/b4/02/0bde0485146a8a5e694daed47561785e8b77a0466ccc1f3e485d5ef2925e/black-25.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e519ecf93120f34243e6b0054db49c00a35f84f195d5bce7e9f5cfc578fc2da", size = 1461080, upload-time = "2025-01-29T05:37:09.321Z" }, + { url = "https://files.pythonhosted.org/packages/52/0e/abdf75183c830eaca7589144ff96d49bce73d7ec6ad12ef62185cc0f79a2/black-25.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:055e59b198df7ac0b7efca5ad7ff2516bca343276c466be72eb04a3bcc1f82d7", size = 1766886, upload-time = "2025-01-29T04:18:24.432Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a6/97d8bb65b1d8a41f8a6736222ba0a334db7b7b77b8023ab4568288f23973/black-25.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:db8ea9917d6f8fc62abd90d944920d95e73c83a5ee3383493e35d271aca872e9", size = 1419404, upload-time = "2025-01-29T04:19:04.296Z" }, + { url = "https://files.pythonhosted.org/packages/7e/4f/87f596aca05c3ce5b94b8663dbfe242a12843caaa82dd3f85f1ffdc3f177/black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0", size = 1614372, upload-time = "2025-01-29T05:37:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/e7/d0/2c34c36190b741c59c901e56ab7f6e54dad8df05a6272a9747ecef7c6036/black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299", size = 1442865, upload-time = "2025-01-29T05:37:14.309Z" }, + { url = "https://files.pythonhosted.org/packages/21/d4/7518c72262468430ead45cf22bd86c883a6448b9eb43672765d69a8f1248/black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096", size = 1749699, upload-time = "2025-01-29T04:18:17.688Z" }, + { url = "https://files.pythonhosted.org/packages/58/db/4f5beb989b547f79096e035c4981ceb36ac2b552d0ac5f2620e941501c99/black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2", size = 1428028, upload-time = "2025-01-29T04:18:51.711Z" }, + { url = "https://files.pythonhosted.org/packages/83/71/3fe4741df7adf015ad8dfa082dd36c94ca86bb21f25608eb247b4afb15b2/black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b", size = 1650988, upload-time = "2025-01-29T05:37:16.707Z" }, + { url = "https://files.pythonhosted.org/packages/13/f3/89aac8a83d73937ccd39bbe8fc6ac8860c11cfa0af5b1c96d081facac844/black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc", size = 1453985, upload-time = "2025-01-29T05:37:18.273Z" }, + { url = "https://files.pythonhosted.org/packages/6f/22/b99efca33f1f3a1d2552c714b1e1b5ae92efac6c43e790ad539a163d1754/black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f", size = 1783816, upload-time = "2025-01-29T04:18:33.823Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/a27c3ad3822b6f2e0e00d63d58ff6299a99a5b3aee69fa77cd4b0076b261/black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba", size = 1440860, upload-time = "2025-01-29T04:19:12.944Z" }, + { url = "https://files.pythonhosted.org/packages/98/87/0edf98916640efa5d0696e1abb0a8357b52e69e82322628f25bf14d263d1/black-25.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f0b18a02996a836cc9c9c78e5babec10930862827b1b724ddfe98ccf2f2fe4f", size = 1650673, upload-time = "2025-01-29T05:37:20.574Z" }, + { url = "https://files.pythonhosted.org/packages/52/e5/f7bf17207cf87fa6e9b676576749c6b6ed0d70f179a3d812c997870291c3/black-25.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:afebb7098bfbc70037a053b91ae8437c3857482d3a690fefc03e9ff7aa9a5fd3", size = 1453190, upload-time = "2025-01-29T05:37:22.106Z" }, + { url = "https://files.pythonhosted.org/packages/e3/ee/adda3d46d4a9120772fae6de454c8495603c37c4c3b9c60f25b1ab6401fe/black-25.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:030b9759066a4ee5e5aca28c3c77f9c64789cdd4de8ac1df642c40b708be6171", size = 1782926, upload-time = "2025-01-29T04:18:58.564Z" }, + { url = "https://files.pythonhosted.org/packages/cc/64/94eb5f45dcb997d2082f097a3944cfc7fe87e071907f677e80788a2d7b7a/black-25.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:a22f402b410566e2d1c950708c77ebf5ebd5d0d88a6a2e87c86d9fb48afa0d18", size = 1442613, upload-time = "2025-01-29T04:19:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/09/71/54e999902aed72baf26bca0d50781b01838251a462612966e9fc4891eadd/black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717", size = 207646, upload-time = "2025-01-29T04:15:38.082Z" }, +] + +[[package]] +name = "boolean-py" +version = "5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/cf/85379f13b76f3a69bca86b60237978af17d6aa0bc5998978c3b8cf05abb2/boolean_py-5.0.tar.gz", hash = "sha256:60cbc4bad079753721d32649545505362c754e121570ada4658b852a3a318d95", size = 37047, upload-time = "2025-04-03T10:39:49.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/ca/78d423b324b8d77900030fa59c4aa9054261ef0925631cd2501dd015b7b7/boolean_py-5.0-py3-none-any.whl", hash = "sha256:ef28a70bd43115208441b53a045d1549e2f0ec6e3d08a9d142cbc41c1938e8d9", size = 26577, upload-time = "2025-04-03T10:39:48.449Z" }, +] + +[[package]] +name = "cachecontrol" +version = "0.14.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "msgpack" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/3a/0cbeb04ea57d2493f3ec5a069a117ab467f85e4a10017c6d854ddcbff104/cachecontrol-0.14.3.tar.gz", hash = "sha256:73e7efec4b06b20d9267b441c1f733664f989fb8688391b670ca812d70795d11", size = 28985, upload-time = "2025-04-30T16:45:06.135Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/4c/800b0607b00b3fd20f1087f80ab53d6b4d005515b0f773e4831e37cfa83f/cachecontrol-0.14.3-py3-none-any.whl", hash = "sha256:b35e44a3113f17d2a31c1e6b27b9de6d4405f84ae51baa8c1d3cc5b633010cae", size = 21802, upload-time = "2025-04-30T16:45:03.863Z" }, +] + +[package.optional-dependencies] +filecache = [ + { name = "filelock" }, +] + +[[package]] +name = "certifi" +version = "2025.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, +] + +[[package]] +name = "chardet" +version = "5.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/0d/f7b6ab21ec75897ed80c17d79b15951a719226b9fababf1e40ea74d69079/chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7", size = 2069618, upload-time = "2023-08-01T19:23:02.662Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/6f/f5fbc992a329ee4e0f288c1fe0e2ad9485ed064cac731ed2fe47dcc38cbf/chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970", size = 199385, upload-time = "2023-08-01T19:23:00.661Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d6/98/f3b8013223728a99b908c9344da3aa04ee6e3fa235f19409033eda92fb78/charset_normalizer-3.4.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fb7f67a1bfa6e40b438170ebdc8158b78dc465a5a67b6dde178a46987b244a72", size = 207695, upload-time = "2025-08-09T07:55:36.452Z" }, + { url = "https://files.pythonhosted.org/packages/21/40/5188be1e3118c82dcb7c2a5ba101b783822cfb413a0268ed3be0468532de/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cc9370a2da1ac13f0153780040f465839e6cccb4a1e44810124b4e22483c93fe", size = 147153, upload-time = "2025-08-09T07:55:38.467Z" }, + { url = "https://files.pythonhosted.org/packages/37/60/5d0d74bc1e1380f0b72c327948d9c2aca14b46a9efd87604e724260f384c/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:07a0eae9e2787b586e129fdcbe1af6997f8d0e5abaa0bc98c0e20e124d67e601", size = 160428, upload-time = "2025-08-09T07:55:40.072Z" }, + { url = "https://files.pythonhosted.org/packages/85/9a/d891f63722d9158688de58d050c59dc3da560ea7f04f4c53e769de5140f5/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:74d77e25adda8581ffc1c720f1c81ca082921329452eba58b16233ab1842141c", size = 157627, upload-time = "2025-08-09T07:55:41.706Z" }, + { url = "https://files.pythonhosted.org/packages/65/1a/7425c952944a6521a9cfa7e675343f83fd82085b8af2b1373a2409c683dc/charset_normalizer-3.4.3-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0e909868420b7049dafd3a31d45125b31143eec59235311fc4c57ea26a4acd2", size = 152388, upload-time = "2025-08-09T07:55:43.262Z" }, + { url = "https://files.pythonhosted.org/packages/f0/c9/a2c9c2a355a8594ce2446085e2ec97fd44d323c684ff32042e2a6b718e1d/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:c6f162aabe9a91a309510d74eeb6507fab5fff92337a15acbe77753d88d9dcf0", size = 150077, upload-time = "2025-08-09T07:55:44.903Z" }, + { url = "https://files.pythonhosted.org/packages/3b/38/20a1f44e4851aa1c9105d6e7110c9d020e093dfa5836d712a5f074a12bf7/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:4ca4c094de7771a98d7fbd67d9e5dbf1eb73efa4f744a730437d8a3a5cf994f0", size = 161631, upload-time = "2025-08-09T07:55:46.346Z" }, + { url = "https://files.pythonhosted.org/packages/a4/fa/384d2c0f57edad03d7bec3ebefb462090d8905b4ff5a2d2525f3bb711fac/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:02425242e96bcf29a49711b0ca9f37e451da7c70562bc10e8ed992a5a7a25cc0", size = 159210, upload-time = "2025-08-09T07:55:47.539Z" }, + { url = "https://files.pythonhosted.org/packages/33/9e/eca49d35867ca2db336b6ca27617deed4653b97ebf45dfc21311ce473c37/charset_normalizer-3.4.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:78deba4d8f9590fe4dae384aeff04082510a709957e968753ff3c48399f6f92a", size = 153739, upload-time = "2025-08-09T07:55:48.744Z" }, + { url = "https://files.pythonhosted.org/packages/2a/91/26c3036e62dfe8de8061182d33be5025e2424002125c9500faff74a6735e/charset_normalizer-3.4.3-cp310-cp310-win32.whl", hash = "sha256:d79c198e27580c8e958906f803e63cddb77653731be08851c7df0b1a14a8fc0f", size = 99825, upload-time = "2025-08-09T07:55:50.305Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c6/f05db471f81af1fa01839d44ae2a8bfeec8d2a8b4590f16c4e7393afd323/charset_normalizer-3.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:c6e490913a46fa054e03699c70019ab869e990270597018cef1d8562132c2669", size = 107452, upload-time = "2025-08-09T07:55:51.461Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b5/991245018615474a60965a7c9cd2b4efbaabd16d582a5547c47ee1c7730b/charset_normalizer-3.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b256ee2e749283ef3ddcff51a675ff43798d92d746d1a6e4631bf8c707d22d0b", size = 204483, upload-time = "2025-08-09T07:55:53.12Z" }, + { url = "https://files.pythonhosted.org/packages/c7/2a/ae245c41c06299ec18262825c1569c5d3298fc920e4ddf56ab011b417efd/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13faeacfe61784e2559e690fc53fa4c5ae97c6fcedb8eb6fb8d0a15b475d2c64", size = 145520, upload-time = "2025-08-09T07:55:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a4/b3b6c76e7a635748c4421d2b92c7b8f90a432f98bda5082049af37ffc8e3/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:00237675befef519d9af72169d8604a067d92755e84fe76492fef5441db05b91", size = 158876, upload-time = "2025-08-09T07:55:56.024Z" }, + { url = "https://files.pythonhosted.org/packages/e2/e6/63bb0e10f90a8243c5def74b5b105b3bbbfb3e7bb753915fe333fb0c11ea/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:585f3b2a80fbd26b048a0be90c5aae8f06605d3c92615911c3a2b03a8a3b796f", size = 156083, upload-time = "2025-08-09T07:55:57.582Z" }, + { url = "https://files.pythonhosted.org/packages/87/df/b7737ff046c974b183ea9aa111b74185ac8c3a326c6262d413bd5a1b8c69/charset_normalizer-3.4.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e78314bdc32fa80696f72fa16dc61168fda4d6a0c014e0380f9d02f0e5d8a07", size = 150295, upload-time = "2025-08-09T07:55:59.147Z" }, + { url = "https://files.pythonhosted.org/packages/61/f1/190d9977e0084d3f1dc169acd060d479bbbc71b90bf3e7bf7b9927dec3eb/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:96b2b3d1a83ad55310de8c7b4a2d04d9277d5591f40761274856635acc5fcb30", size = 148379, upload-time = "2025-08-09T07:56:00.364Z" }, + { url = "https://files.pythonhosted.org/packages/4c/92/27dbe365d34c68cfe0ca76f1edd70e8705d82b378cb54ebbaeabc2e3029d/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:939578d9d8fd4299220161fdd76e86c6a251987476f5243e8864a7844476ba14", size = 160018, upload-time = "2025-08-09T07:56:01.678Z" }, + { url = "https://files.pythonhosted.org/packages/99/04/baae2a1ea1893a01635d475b9261c889a18fd48393634b6270827869fa34/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fd10de089bcdcd1be95a2f73dbe6254798ec1bda9f450d5828c96f93e2536b9c", size = 157430, upload-time = "2025-08-09T07:56:02.87Z" }, + { url = "https://files.pythonhosted.org/packages/2f/36/77da9c6a328c54d17b960c89eccacfab8271fdaaa228305330915b88afa9/charset_normalizer-3.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e8ac75d72fa3775e0b7cb7e4629cec13b7514d928d15ef8ea06bca03ef01cae", size = 151600, upload-time = "2025-08-09T07:56:04.089Z" }, + { url = "https://files.pythonhosted.org/packages/64/d4/9eb4ff2c167edbbf08cdd28e19078bf195762e9bd63371689cab5ecd3d0d/charset_normalizer-3.4.3-cp311-cp311-win32.whl", hash = "sha256:6cf8fd4c04756b6b60146d98cd8a77d0cdae0e1ca20329da2ac85eed779b6849", size = 99616, upload-time = "2025-08-09T07:56:05.658Z" }, + { url = "https://files.pythonhosted.org/packages/f4/9c/996a4a028222e7761a96634d1820de8a744ff4327a00ada9c8942033089b/charset_normalizer-3.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:31a9a6f775f9bcd865d88ee350f0ffb0e25936a7f930ca98995c05abf1faf21c", size = 107108, upload-time = "2025-08-09T07:56:07.176Z" }, + { url = "https://files.pythonhosted.org/packages/e9/5e/14c94999e418d9b87682734589404a25854d5f5d0408df68bc15b6ff54bb/charset_normalizer-3.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e28e334d3ff134e88989d90ba04b47d84382a828c061d0d1027b1b12a62b39b1", size = 205655, upload-time = "2025-08-09T07:56:08.475Z" }, + { url = "https://files.pythonhosted.org/packages/7d/a8/c6ec5d389672521f644505a257f50544c074cf5fc292d5390331cd6fc9c3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0cacf8f7297b0c4fcb74227692ca46b4a5852f8f4f24b3c766dd94a1075c4884", size = 146223, upload-time = "2025-08-09T07:56:09.708Z" }, + { url = "https://files.pythonhosted.org/packages/fc/eb/a2ffb08547f4e1e5415fb69eb7db25932c52a52bed371429648db4d84fb1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c6fd51128a41297f5409deab284fecbe5305ebd7e5a1f959bee1c054622b7018", size = 159366, upload-time = "2025-08-09T07:56:11.326Z" }, + { url = "https://files.pythonhosted.org/packages/82/10/0fd19f20c624b278dddaf83b8464dcddc2456cb4b02bb902a6da126b87a1/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cfb2aad70f2c6debfbcb717f23b7eb55febc0bb23dcffc0f076009da10c6392", size = 157104, upload-time = "2025-08-09T07:56:13.014Z" }, + { url = "https://files.pythonhosted.org/packages/16/ab/0233c3231af734f5dfcf0844aa9582d5a1466c985bbed6cedab85af9bfe3/charset_normalizer-3.4.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1606f4a55c0fd363d754049cdf400175ee96c992b1f8018b993941f221221c5f", size = 151830, upload-time = "2025-08-09T07:56:14.428Z" }, + { url = "https://files.pythonhosted.org/packages/ae/02/e29e22b4e02839a0e4a06557b1999d0a47db3567e82989b5bb21f3fbbd9f/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:027b776c26d38b7f15b26a5da1044f376455fb3766df8fc38563b4efbc515154", size = 148854, upload-time = "2025-08-09T07:56:16.051Z" }, + { url = "https://files.pythonhosted.org/packages/05/6b/e2539a0a4be302b481e8cafb5af8792da8093b486885a1ae4d15d452bcec/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:42e5088973e56e31e4fa58eb6bd709e42fc03799c11c42929592889a2e54c491", size = 160670, upload-time = "2025-08-09T07:56:17.314Z" }, + { url = "https://files.pythonhosted.org/packages/31/e7/883ee5676a2ef217a40ce0bffcc3d0dfbf9e64cbcfbdf822c52981c3304b/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cc34f233c9e71701040d772aa7490318673aa7164a0efe3172b2981218c26d93", size = 158501, upload-time = "2025-08-09T07:56:18.641Z" }, + { url = "https://files.pythonhosted.org/packages/c1/35/6525b21aa0db614cf8b5792d232021dca3df7f90a1944db934efa5d20bb1/charset_normalizer-3.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320e8e66157cc4e247d9ddca8e21f427efc7a04bbd0ac8a9faf56583fa543f9f", size = 153173, upload-time = "2025-08-09T07:56:20.289Z" }, + { url = "https://files.pythonhosted.org/packages/50/ee/f4704bad8201de513fdc8aac1cabc87e38c5818c93857140e06e772b5892/charset_normalizer-3.4.3-cp312-cp312-win32.whl", hash = "sha256:fb6fecfd65564f208cbf0fba07f107fb661bcd1a7c389edbced3f7a493f70e37", size = 99822, upload-time = "2025-08-09T07:56:21.551Z" }, + { url = "https://files.pythonhosted.org/packages/39/f5/3b3836ca6064d0992c58c7561c6b6eee1b3892e9665d650c803bd5614522/charset_normalizer-3.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:86df271bf921c2ee3818f0522e9a5b8092ca2ad8b065ece5d7d9d0e9f4849bcc", size = 107543, upload-time = "2025-08-09T07:56:23.115Z" }, + { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, + { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, + { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, + { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, + { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, + { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, + { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, + { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, + { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, + { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, + { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, + { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, + { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, + { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, + { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, + { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, +] + +[[package]] +name = "click" +version = "8.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "cookiecutter" +version = "2.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, + { name = "binaryornot" }, + { name = "click" }, + { name = "jinja2" }, + { name = "python-slugify" }, + { name = "pyyaml" }, + { name = "requests" }, + { name = "rich" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/17/9f2cd228eb949a91915acd38d3eecdc9d8893dde353b603f0db7e9f6be55/cookiecutter-2.6.0.tar.gz", hash = "sha256:db21f8169ea4f4fdc2408d48ca44859349de2647fbe494a9d6c3edfc0542c21c", size = 158767, upload-time = "2024-02-21T18:02:41.949Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/d9/0137658a353168ffa9d0fc14b812d3834772040858ddd1cb6eeaf09f7a44/cookiecutter-2.6.0-py3-none-any.whl", hash = "sha256:a54a8e37995e4ed963b3e82831072d1ad4b005af736bb17b99c2cbd9d41b6e2d", size = 39177, upload-time = "2024-02-21T18:02:39.569Z" }, +] + +[[package]] +name = "cookiecutter-python-django" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "cookiecutter" }, +] + +[package.dev-dependencies] +dev = [ + { name = "bandit" }, + { name = "black" }, + { name = "pip-audit" }, + { name = "pylint" }, + { name = "pytest-cookies" }, + { name = "pytest-cov" }, +] + +[package.metadata] +requires-dist = [{ name = "cookiecutter" }] + +[package.metadata.requires-dev] +dev = [ + { name = "bandit" }, + { name = "black" }, + { name = "pip-audit" }, + { name = "pylint" }, + { name = "pytest-cookies" }, + { name = "pytest-cov" }, +] + +[[package]] +name = "coverage" +version = "7.10.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/61/83/153f54356c7c200013a752ce1ed5448573dca546ce125801afca9e1ac1a4/coverage-7.10.5.tar.gz", hash = "sha256:f2e57716a78bc3ae80b2207be0709a3b2b63b9f2dcf9740ee6ac03588a2015b6", size = 821662, upload-time = "2025-08-23T14:42:44.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/70/e77b0061a6c7157bfce645c6b9a715a08d4c86b3360a7b3252818080b817/coverage-7.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c6a5c3414bfc7451b879141ce772c546985163cf553f08e0f135f0699a911801", size = 216774, upload-time = "2025-08-23T14:40:26.301Z" }, + { url = "https://files.pythonhosted.org/packages/91/08/2a79de5ecf37ee40f2d898012306f11c161548753391cec763f92647837b/coverage-7.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:bc8e4d99ce82f1710cc3c125adc30fd1487d3cf6c2cd4994d78d68a47b16989a", size = 217175, upload-time = "2025-08-23T14:40:29.142Z" }, + { url = "https://files.pythonhosted.org/packages/64/57/0171d69a699690149a6ba6a4eb702814448c8d617cf62dbafa7ce6bfdf63/coverage-7.10.5-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:02252dc1216e512a9311f596b3169fad54abcb13827a8d76d5630c798a50a754", size = 243931, upload-time = "2025-08-23T14:40:30.735Z" }, + { url = "https://files.pythonhosted.org/packages/15/06/3a67662c55656702bd398a727a7f35df598eb11104fcb34f1ecbb070291a/coverage-7.10.5-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:73269df37883e02d460bee0cc16be90509faea1e3bd105d77360b512d5bb9c33", size = 245740, upload-time = "2025-08-23T14:40:32.302Z" }, + { url = "https://files.pythonhosted.org/packages/00/f4/f8763aabf4dc30ef0d0012522d312f0b7f9fede6246a1f27dbcc4a1e523c/coverage-7.10.5-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1f8a81b0614642f91c9effd53eec284f965577591f51f547a1cbeb32035b4c2f", size = 247600, upload-time = "2025-08-23T14:40:33.66Z" }, + { url = "https://files.pythonhosted.org/packages/9c/31/6632219a9065e1b83f77eda116fed4c76fb64908a6a9feae41816dab8237/coverage-7.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6a29f8e0adb7f8c2b95fa2d4566a1d6e6722e0a637634c6563cb1ab844427dd9", size = 245640, upload-time = "2025-08-23T14:40:35.248Z" }, + { url = "https://files.pythonhosted.org/packages/6e/e2/3dba9b86037b81649b11d192bb1df11dde9a81013e434af3520222707bc8/coverage-7.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fcf6ab569436b4a647d4e91accba12509ad9f2554bc93d3aee23cc596e7f99c3", size = 243659, upload-time = "2025-08-23T14:40:36.815Z" }, + { url = "https://files.pythonhosted.org/packages/02/b9/57170bd9f3e333837fc24ecc88bc70fbc2eb7ccfd0876854b0c0407078c3/coverage-7.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:90dc3d6fb222b194a5de60af8d190bedeeddcbc7add317e4a3cd333ee6b7c879", size = 244537, upload-time = "2025-08-23T14:40:38.737Z" }, + { url = "https://files.pythonhosted.org/packages/b3/1c/93ac36ef1e8b06b8d5777393a3a40cb356f9f3dab980be40a6941e443588/coverage-7.10.5-cp310-cp310-win32.whl", hash = "sha256:414a568cd545f9dc75f0686a0049393de8098414b58ea071e03395505b73d7a8", size = 219285, upload-time = "2025-08-23T14:40:40.342Z" }, + { url = "https://files.pythonhosted.org/packages/30/95/23252277e6e5fe649d6cd3ed3f35d2307e5166de4e75e66aa7f432abc46d/coverage-7.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:e551f9d03347196271935fd3c0c165f0e8c049220280c1120de0084d65e9c7ff", size = 220185, upload-time = "2025-08-23T14:40:42.026Z" }, + { url = "https://files.pythonhosted.org/packages/cb/f2/336d34d2fc1291ca7c18eeb46f64985e6cef5a1a7ef6d9c23720c6527289/coverage-7.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c177e6ffe2ebc7c410785307758ee21258aa8e8092b44d09a2da767834f075f2", size = 216890, upload-time = "2025-08-23T14:40:43.627Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/92448b07cc1cf2b429d0ce635f59cf0c626a5d8de21358f11e92174ff2a6/coverage-7.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:14d6071c51ad0f703d6440827eaa46386169b5fdced42631d5a5ac419616046f", size = 217287, upload-time = "2025-08-23T14:40:45.214Z" }, + { url = "https://files.pythonhosted.org/packages/96/ba/ad5b36537c5179c808d0ecdf6e4aa7630b311b3c12747ad624dcd43a9b6b/coverage-7.10.5-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:61f78c7c3bc272a410c5ae3fde7792b4ffb4acc03d35a7df73ca8978826bb7ab", size = 247683, upload-time = "2025-08-23T14:40:46.791Z" }, + { url = "https://files.pythonhosted.org/packages/28/e5/fe3bbc8d097029d284b5fb305b38bb3404895da48495f05bff025df62770/coverage-7.10.5-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f39071caa126f69d63f99b324fb08c7b1da2ec28cbb1fe7b5b1799926492f65c", size = 249614, upload-time = "2025-08-23T14:40:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/69/9c/a1c89a8c8712799efccb32cd0a1ee88e452f0c13a006b65bb2271f1ac767/coverage-7.10.5-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:343a023193f04d46edc46b2616cdbee68c94dd10208ecd3adc56fcc54ef2baa1", size = 251719, upload-time = "2025-08-23T14:40:49.349Z" }, + { url = "https://files.pythonhosted.org/packages/e9/be/5576b5625865aa95b5633315f8f4142b003a70c3d96e76f04487c3b5cc95/coverage-7.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:585ffe93ae5894d1ebdee69fc0b0d4b7c75d8007983692fb300ac98eed146f78", size = 249411, upload-time = "2025-08-23T14:40:50.624Z" }, + { url = "https://files.pythonhosted.org/packages/94/0a/e39a113d4209da0dbbc9385608cdb1b0726a4d25f78672dc51c97cfea80f/coverage-7.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0ef4e66f006ed181df29b59921bd8fc7ed7cd6a9289295cd8b2824b49b570df", size = 247466, upload-time = "2025-08-23T14:40:52.362Z" }, + { url = "https://files.pythonhosted.org/packages/40/cb/aebb2d8c9e3533ee340bea19b71c5b76605a0268aa49808e26fe96ec0a07/coverage-7.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eb7b0bbf7cc1d0453b843eca7b5fa017874735bef9bfdfa4121373d2cc885ed6", size = 248104, upload-time = "2025-08-23T14:40:54.064Z" }, + { url = "https://files.pythonhosted.org/packages/08/e6/26570d6ccce8ff5de912cbfd268e7f475f00597cb58da9991fa919c5e539/coverage-7.10.5-cp311-cp311-win32.whl", hash = "sha256:1d043a8a06987cc0c98516e57c4d3fc2c1591364831e9deb59c9e1b4937e8caf", size = 219327, upload-time = "2025-08-23T14:40:55.424Z" }, + { url = "https://files.pythonhosted.org/packages/79/79/5f48525e366e518b36e66167e3b6e5db6fd54f63982500c6a5abb9d3dfbd/coverage-7.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:fefafcca09c3ac56372ef64a40f5fe17c5592fab906e0fdffd09543f3012ba50", size = 220213, upload-time = "2025-08-23T14:40:56.724Z" }, + { url = "https://files.pythonhosted.org/packages/40/3c/9058128b7b0bf333130c320b1eb1ae485623014a21ee196d68f7737f8610/coverage-7.10.5-cp311-cp311-win_arm64.whl", hash = "sha256:7e78b767da8b5fc5b2faa69bb001edafcd6f3995b42a331c53ef9572c55ceb82", size = 218893, upload-time = "2025-08-23T14:40:58.011Z" }, + { url = "https://files.pythonhosted.org/packages/27/8e/40d75c7128f871ea0fd829d3e7e4a14460cad7c3826e3b472e6471ad05bd/coverage-7.10.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c2d05c7e73c60a4cecc7d9b60dbfd603b4ebc0adafaef371445b47d0f805c8a9", size = 217077, upload-time = "2025-08-23T14:40:59.329Z" }, + { url = "https://files.pythonhosted.org/packages/18/a8/f333f4cf3fb5477a7f727b4d603a2eb5c3c5611c7fe01329c2e13b23b678/coverage-7.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:32ddaa3b2c509778ed5373b177eb2bf5662405493baeff52278a0b4f9415188b", size = 217310, upload-time = "2025-08-23T14:41:00.628Z" }, + { url = "https://files.pythonhosted.org/packages/ec/2c/fbecd8381e0a07d1547922be819b4543a901402f63930313a519b937c668/coverage-7.10.5-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:dd382410039fe062097aa0292ab6335a3f1e7af7bba2ef8d27dcda484918f20c", size = 248802, upload-time = "2025-08-23T14:41:02.012Z" }, + { url = "https://files.pythonhosted.org/packages/3f/bc/1011da599b414fb6c9c0f34086736126f9ff71f841755786a6b87601b088/coverage-7.10.5-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7fa22800f3908df31cea6fb230f20ac49e343515d968cc3a42b30d5c3ebf9b5a", size = 251550, upload-time = "2025-08-23T14:41:03.438Z" }, + { url = "https://files.pythonhosted.org/packages/4c/6f/b5c03c0c721c067d21bc697accc3642f3cef9f087dac429c918c37a37437/coverage-7.10.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f366a57ac81f5e12797136552f5b7502fa053c861a009b91b80ed51f2ce651c6", size = 252684, upload-time = "2025-08-23T14:41:04.85Z" }, + { url = "https://files.pythonhosted.org/packages/f9/50/d474bc300ebcb6a38a1047d5c465a227605d6473e49b4e0d793102312bc5/coverage-7.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5f1dc8f1980a272ad4a6c84cba7981792344dad33bf5869361576b7aef42733a", size = 250602, upload-time = "2025-08-23T14:41:06.719Z" }, + { url = "https://files.pythonhosted.org/packages/4a/2d/548c8e04249cbba3aba6bd799efdd11eee3941b70253733f5d355d689559/coverage-7.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2285c04ee8676f7938b02b4936d9b9b672064daab3187c20f73a55f3d70e6b4a", size = 248724, upload-time = "2025-08-23T14:41:08.429Z" }, + { url = "https://files.pythonhosted.org/packages/e2/96/a7c3c0562266ac39dcad271d0eec8fc20ab576e3e2f64130a845ad2a557b/coverage-7.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c2492e4dd9daab63f5f56286f8a04c51323d237631eb98505d87e4c4ff19ec34", size = 250158, upload-time = "2025-08-23T14:41:09.749Z" }, + { url = "https://files.pythonhosted.org/packages/f3/75/74d4be58c70c42ef0b352d597b022baf12dbe2b43e7cb1525f56a0fb1d4b/coverage-7.10.5-cp312-cp312-win32.whl", hash = "sha256:38a9109c4ee8135d5df5505384fc2f20287a47ccbe0b3f04c53c9a1989c2bbaf", size = 219493, upload-time = "2025-08-23T14:41:11.095Z" }, + { url = "https://files.pythonhosted.org/packages/4f/08/364e6012d1d4d09d1e27437382967efed971d7613f94bca9add25f0c1f2b/coverage-7.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:6b87f1ad60b30bc3c43c66afa7db6b22a3109902e28c5094957626a0143a001f", size = 220302, upload-time = "2025-08-23T14:41:12.449Z" }, + { url = "https://files.pythonhosted.org/packages/db/d5/7c8a365e1f7355c58af4fe5faf3f90cc8e587590f5854808d17ccb4e7077/coverage-7.10.5-cp312-cp312-win_arm64.whl", hash = "sha256:672a6c1da5aea6c629819a0e1461e89d244f78d7b60c424ecf4f1f2556c041d8", size = 218936, upload-time = "2025-08-23T14:41:13.872Z" }, + { url = "https://files.pythonhosted.org/packages/9f/08/4166ecfb60ba011444f38a5a6107814b80c34c717bc7a23be0d22e92ca09/coverage-7.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ef3b83594d933020f54cf65ea1f4405d1f4e41a009c46df629dd964fcb6e907c", size = 217106, upload-time = "2025-08-23T14:41:15.268Z" }, + { url = "https://files.pythonhosted.org/packages/25/d7/b71022408adbf040a680b8c64bf6ead3be37b553e5844f7465643979f7ca/coverage-7.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2b96bfdf7c0ea9faebce088a3ecb2382819da4fbc05c7b80040dbc428df6af44", size = 217353, upload-time = "2025-08-23T14:41:16.656Z" }, + { url = "https://files.pythonhosted.org/packages/74/68/21e0d254dbf8972bb8dd95e3fe7038f4be037ff04ba47d6d1b12b37510ba/coverage-7.10.5-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:63df1fdaffa42d914d5c4d293e838937638bf75c794cf20bee12978fc8c4e3bc", size = 248350, upload-time = "2025-08-23T14:41:18.128Z" }, + { url = "https://files.pythonhosted.org/packages/90/65/28752c3a896566ec93e0219fc4f47ff71bd2b745f51554c93e8dcb659796/coverage-7.10.5-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8002dc6a049aac0e81ecec97abfb08c01ef0c1fbf962d0c98da3950ace89b869", size = 250955, upload-time = "2025-08-23T14:41:19.577Z" }, + { url = "https://files.pythonhosted.org/packages/a5/eb/ca6b7967f57f6fef31da8749ea20417790bb6723593c8cd98a987be20423/coverage-7.10.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:63d4bb2966d6f5f705a6b0c6784c8969c468dbc4bcf9d9ded8bff1c7e092451f", size = 252230, upload-time = "2025-08-23T14:41:20.959Z" }, + { url = "https://files.pythonhosted.org/packages/bc/29/17a411b2a2a18f8b8c952aa01c00f9284a1fbc677c68a0003b772ea89104/coverage-7.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1f672efc0731a6846b157389b6e6d5d5e9e59d1d1a23a5c66a99fd58339914d5", size = 250387, upload-time = "2025-08-23T14:41:22.644Z" }, + { url = "https://files.pythonhosted.org/packages/c7/89/97a9e271188c2fbb3db82235c33980bcbc733da7da6065afbaa1d685a169/coverage-7.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:3f39cef43d08049e8afc1fde4a5da8510fc6be843f8dea350ee46e2a26b2f54c", size = 248280, upload-time = "2025-08-23T14:41:24.061Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c6/0ad7d0137257553eb4706b4ad6180bec0a1b6a648b092c5bbda48d0e5b2c/coverage-7.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2968647e3ed5a6c019a419264386b013979ff1fb67dd11f5c9886c43d6a31fc2", size = 249894, upload-time = "2025-08-23T14:41:26.165Z" }, + { url = "https://files.pythonhosted.org/packages/84/56/fb3aba936addb4c9e5ea14f5979393f1c2466b4c89d10591fd05f2d6b2aa/coverage-7.10.5-cp313-cp313-win32.whl", hash = "sha256:0d511dda38595b2b6934c2b730a1fd57a3635c6aa2a04cb74714cdfdd53846f4", size = 219536, upload-time = "2025-08-23T14:41:27.694Z" }, + { url = "https://files.pythonhosted.org/packages/fc/54/baacb8f2f74431e3b175a9a2881feaa8feb6e2f187a0e7e3046f3c7742b2/coverage-7.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:9a86281794a393513cf117177fd39c796b3f8e3759bb2764259a2abba5cce54b", size = 220330, upload-time = "2025-08-23T14:41:29.081Z" }, + { url = "https://files.pythonhosted.org/packages/64/8a/82a3788f8e31dee51d350835b23d480548ea8621f3effd7c3ba3f7e5c006/coverage-7.10.5-cp313-cp313-win_arm64.whl", hash = "sha256:cebd8e906eb98bb09c10d1feed16096700b1198d482267f8bf0474e63a7b8d84", size = 218961, upload-time = "2025-08-23T14:41:30.511Z" }, + { url = "https://files.pythonhosted.org/packages/d8/a1/590154e6eae07beee3b111cc1f907c30da6fc8ce0a83ef756c72f3c7c748/coverage-7.10.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0520dff502da5e09d0d20781df74d8189ab334a1e40d5bafe2efaa4158e2d9e7", size = 217819, upload-time = "2025-08-23T14:41:31.962Z" }, + { url = "https://files.pythonhosted.org/packages/0d/ff/436ffa3cfc7741f0973c5c89405307fe39b78dcf201565b934e6616fc4ad/coverage-7.10.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:d9cd64aca68f503ed3f1f18c7c9174cbb797baba02ca8ab5112f9d1c0328cd4b", size = 218040, upload-time = "2025-08-23T14:41:33.472Z" }, + { url = "https://files.pythonhosted.org/packages/a0/ca/5787fb3d7820e66273913affe8209c534ca11241eb34ee8c4fd2aaa9dd87/coverage-7.10.5-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0913dd1613a33b13c4f84aa6e3f4198c1a21ee28ccb4f674985c1f22109f0aae", size = 259374, upload-time = "2025-08-23T14:41:34.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/89/21af956843896adc2e64fc075eae3c1cadb97ee0a6960733e65e696f32dd/coverage-7.10.5-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1b7181c0feeb06ed8a02da02792f42f829a7b29990fef52eff257fef0885d760", size = 261551, upload-time = "2025-08-23T14:41:36.333Z" }, + { url = "https://files.pythonhosted.org/packages/e1/96/390a69244ab837e0ac137989277879a084c786cf036c3c4a3b9637d43a89/coverage-7.10.5-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:36d42b7396b605f774d4372dd9c49bed71cbabce4ae1ccd074d155709dd8f235", size = 263776, upload-time = "2025-08-23T14:41:38.25Z" }, + { url = "https://files.pythonhosted.org/packages/00/32/cfd6ae1da0a521723349f3129b2455832fc27d3f8882c07e5b6fefdd0da2/coverage-7.10.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b4fdc777e05c4940b297bf47bf7eedd56a39a61dc23ba798e4b830d585486ca5", size = 261326, upload-time = "2025-08-23T14:41:40.343Z" }, + { url = "https://files.pythonhosted.org/packages/4c/c4/bf8d459fb4ce2201e9243ce6c015936ad283a668774430a3755f467b39d1/coverage-7.10.5-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:42144e8e346de44a6f1dbd0a56575dd8ab8dfa7e9007da02ea5b1c30ab33a7db", size = 259090, upload-time = "2025-08-23T14:41:42.106Z" }, + { url = "https://files.pythonhosted.org/packages/f4/5d/a234f7409896468e5539d42234016045e4015e857488b0b5b5f3f3fa5f2b/coverage-7.10.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:66c644cbd7aed8fe266d5917e2c9f65458a51cfe5eeff9c05f15b335f697066e", size = 260217, upload-time = "2025-08-23T14:41:43.591Z" }, + { url = "https://files.pythonhosted.org/packages/f3/ad/87560f036099f46c2ddd235be6476dd5c1d6be6bb57569a9348d43eeecea/coverage-7.10.5-cp313-cp313t-win32.whl", hash = "sha256:2d1b73023854068c44b0c554578a4e1ef1b050ed07cf8b431549e624a29a66ee", size = 220194, upload-time = "2025-08-23T14:41:45.051Z" }, + { url = "https://files.pythonhosted.org/packages/36/a8/04a482594fdd83dc677d4a6c7e2d62135fff5a1573059806b8383fad9071/coverage-7.10.5-cp313-cp313t-win_amd64.whl", hash = "sha256:54a1532c8a642d8cc0bd5a9a51f5a9dcc440294fd06e9dda55e743c5ec1a8f14", size = 221258, upload-time = "2025-08-23T14:41:46.44Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ad/7da28594ab66fe2bc720f1bc9b131e62e9b4c6e39f044d9a48d18429cc21/coverage-7.10.5-cp313-cp313t-win_arm64.whl", hash = "sha256:74d5b63fe3f5f5d372253a4ef92492c11a4305f3550631beaa432fc9df16fcff", size = 219521, upload-time = "2025-08-23T14:41:47.882Z" }, + { url = "https://files.pythonhosted.org/packages/d3/7f/c8b6e4e664b8a95254c35a6c8dd0bf4db201ec681c169aae2f1256e05c85/coverage-7.10.5-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:68c5e0bc5f44f68053369fa0d94459c84548a77660a5f2561c5e5f1e3bed7031", size = 217090, upload-time = "2025-08-23T14:41:49.327Z" }, + { url = "https://files.pythonhosted.org/packages/44/74/3ee14ede30a6e10a94a104d1d0522d5fb909a7c7cac2643d2a79891ff3b9/coverage-7.10.5-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:cf33134ffae93865e32e1e37df043bef15a5e857d8caebc0099d225c579b0fa3", size = 217365, upload-time = "2025-08-23T14:41:50.796Z" }, + { url = "https://files.pythonhosted.org/packages/41/5f/06ac21bf87dfb7620d1f870dfa3c2cae1186ccbcdc50b8b36e27a0d52f50/coverage-7.10.5-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ad8fa9d5193bafcf668231294241302b5e683a0518bf1e33a9a0dfb142ec3031", size = 248413, upload-time = "2025-08-23T14:41:52.5Z" }, + { url = "https://files.pythonhosted.org/packages/21/bc/cc5bed6e985d3a14228539631573f3863be6a2587381e8bc5fdf786377a1/coverage-7.10.5-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:146fa1531973d38ab4b689bc764592fe6c2f913e7e80a39e7eeafd11f0ef6db2", size = 250943, upload-time = "2025-08-23T14:41:53.922Z" }, + { url = "https://files.pythonhosted.org/packages/8d/43/6a9fc323c2c75cd80b18d58db4a25dc8487f86dd9070f9592e43e3967363/coverage-7.10.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6013a37b8a4854c478d3219ee8bc2392dea51602dd0803a12d6f6182a0061762", size = 252301, upload-time = "2025-08-23T14:41:56.528Z" }, + { url = "https://files.pythonhosted.org/packages/69/7c/3e791b8845f4cd515275743e3775adb86273576596dc9f02dca37357b4f2/coverage-7.10.5-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:eb90fe20db9c3d930fa2ad7a308207ab5b86bf6a76f54ab6a40be4012d88fcae", size = 250302, upload-time = "2025-08-23T14:41:58.171Z" }, + { url = "https://files.pythonhosted.org/packages/5c/bc/5099c1e1cb0c9ac6491b281babea6ebbf999d949bf4aa8cdf4f2b53505e8/coverage-7.10.5-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:384b34482272e960c438703cafe63316dfbea124ac62006a455c8410bf2a2262", size = 248237, upload-time = "2025-08-23T14:41:59.703Z" }, + { url = "https://files.pythonhosted.org/packages/7e/51/d346eb750a0b2f1e77f391498b753ea906fde69cc11e4b38dca28c10c88c/coverage-7.10.5-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:467dc74bd0a1a7de2bedf8deaf6811f43602cb532bd34d81ffd6038d6d8abe99", size = 249726, upload-time = "2025-08-23T14:42:01.343Z" }, + { url = "https://files.pythonhosted.org/packages/a3/85/eebcaa0edafe427e93286b94f56ea7e1280f2c49da0a776a6f37e04481f9/coverage-7.10.5-cp314-cp314-win32.whl", hash = "sha256:556d23d4e6393ca898b2e63a5bca91e9ac2d5fb13299ec286cd69a09a7187fde", size = 219825, upload-time = "2025-08-23T14:42:03.263Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f7/6d43e037820742603f1e855feb23463979bf40bd27d0cde1f761dcc66a3e/coverage-7.10.5-cp314-cp314-win_amd64.whl", hash = "sha256:f4446a9547681533c8fa3e3c6cf62121eeee616e6a92bd9201c6edd91beffe13", size = 220618, upload-time = "2025-08-23T14:42:05.037Z" }, + { url = "https://files.pythonhosted.org/packages/4a/b0/ed9432e41424c51509d1da603b0393404b828906236fb87e2c8482a93468/coverage-7.10.5-cp314-cp314-win_arm64.whl", hash = "sha256:5e78bd9cf65da4c303bf663de0d73bf69f81e878bf72a94e9af67137c69b9fe9", size = 219199, upload-time = "2025-08-23T14:42:06.662Z" }, + { url = "https://files.pythonhosted.org/packages/2f/54/5a7ecfa77910f22b659c820f67c16fc1e149ed132ad7117f0364679a8fa9/coverage-7.10.5-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:5661bf987d91ec756a47c7e5df4fbcb949f39e32f9334ccd3f43233bbb65e508", size = 217833, upload-time = "2025-08-23T14:42:08.262Z" }, + { url = "https://files.pythonhosted.org/packages/4e/0e/25672d917cc57857d40edf38f0b867fb9627115294e4f92c8fcbbc18598d/coverage-7.10.5-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a46473129244db42a720439a26984f8c6f834762fc4573616c1f37f13994b357", size = 218048, upload-time = "2025-08-23T14:42:10.247Z" }, + { url = "https://files.pythonhosted.org/packages/cb/7c/0b2b4f1c6f71885d4d4b2b8608dcfc79057adb7da4143eb17d6260389e42/coverage-7.10.5-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1f64b8d3415d60f24b058b58d859e9512624bdfa57a2d1f8aff93c1ec45c429b", size = 259549, upload-time = "2025-08-23T14:42:11.811Z" }, + { url = "https://files.pythonhosted.org/packages/94/73/abb8dab1609abec7308d83c6aec547944070526578ee6c833d2da9a0ad42/coverage-7.10.5-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:44d43de99a9d90b20e0163f9770542357f58860a26e24dc1d924643bd6aa7cb4", size = 261715, upload-time = "2025-08-23T14:42:13.505Z" }, + { url = "https://files.pythonhosted.org/packages/0b/d1/abf31de21ec92731445606b8d5e6fa5144653c2788758fcf1f47adb7159a/coverage-7.10.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a931a87e5ddb6b6404e65443b742cb1c14959622777f2a4efd81fba84f5d91ba", size = 263969, upload-time = "2025-08-23T14:42:15.422Z" }, + { url = "https://files.pythonhosted.org/packages/9c/b3/ef274927f4ebede96056173b620db649cc9cb746c61ffc467946b9d0bc67/coverage-7.10.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:f9559b906a100029274448f4c8b8b0a127daa4dade5661dfd821b8c188058842", size = 261408, upload-time = "2025-08-23T14:42:16.971Z" }, + { url = "https://files.pythonhosted.org/packages/20/fc/83ca2812be616d69b4cdd4e0c62a7bc526d56875e68fd0f79d47c7923584/coverage-7.10.5-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b08801e25e3b4526ef9ced1aa29344131a8f5213c60c03c18fe4c6170ffa2874", size = 259168, upload-time = "2025-08-23T14:42:18.512Z" }, + { url = "https://files.pythonhosted.org/packages/fc/4f/e0779e5716f72d5c9962e709d09815d02b3b54724e38567308304c3fc9df/coverage-7.10.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ed9749bb8eda35f8b636fb7632f1c62f735a236a5d4edadd8bbcc5ea0542e732", size = 260317, upload-time = "2025-08-23T14:42:20.005Z" }, + { url = "https://files.pythonhosted.org/packages/2b/fe/4247e732f2234bb5eb9984a0888a70980d681f03cbf433ba7b48f08ca5d5/coverage-7.10.5-cp314-cp314t-win32.whl", hash = "sha256:609b60d123fc2cc63ccee6d17e4676699075db72d14ac3c107cc4976d516f2df", size = 220600, upload-time = "2025-08-23T14:42:22.027Z" }, + { url = "https://files.pythonhosted.org/packages/a7/a0/f294cff6d1034b87839987e5b6ac7385bec599c44d08e0857ac7f164ad0c/coverage-7.10.5-cp314-cp314t-win_amd64.whl", hash = "sha256:0666cf3d2c1626b5a3463fd5b05f5e21f99e6aec40a3192eee4d07a15970b07f", size = 221714, upload-time = "2025-08-23T14:42:23.616Z" }, + { url = "https://files.pythonhosted.org/packages/23/18/fa1afdc60b5528d17416df440bcbd8fd12da12bfea9da5b6ae0f7a37d0f7/coverage-7.10.5-cp314-cp314t-win_arm64.whl", hash = "sha256:bc85eb2d35e760120540afddd3044a5bf69118a91a296a8b3940dfc4fdcfe1e2", size = 219735, upload-time = "2025-08-23T14:42:25.156Z" }, + { url = "https://files.pythonhosted.org/packages/08/b6/fff6609354deba9aeec466e4bcaeb9d1ed3e5d60b14b57df2a36fb2273f2/coverage-7.10.5-py3-none-any.whl", hash = "sha256:0be24d35e4db1d23d0db5c0f6a74a962e2ec83c426b5cac09f4234aadef38e4a", size = 208736, upload-time = "2025-08-23T14:42:43.145Z" }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cyclonedx-python-lib" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "license-expression" }, + { name = "packageurl-python" }, + { name = "py-serializable" }, + { name = "sortedcontainers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/fc/abaad5482f7b59c9a0a9d8f354ce4ce23346d582a0d85730b559562bbeb4/cyclonedx_python_lib-9.1.0.tar.gz", hash = "sha256:86935f2c88a7b47a529b93c724dbd3e903bc573f6f8bd977628a7ca1b5dadea1", size = 1048735, upload-time = "2025-02-27T17:23:40.367Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/f1/f3be2e9820a2c26fa77622223e91f9c504e1581830930d477e06146073f4/cyclonedx_python_lib-9.1.0-py3-none-any.whl", hash = "sha256:55693fca8edaecc3363b24af14e82cc6e659eb1e8353e58b587c42652ce0fb52", size = 374968, upload-time = "2025-02-27T17:23:37.766Z" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + +[[package]] +name = "dill" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/12/80/630b4b88364e9a8c8c5797f4602d0f76ef820909ee32f0bacb9f90654042/dill-0.4.0.tar.gz", hash = "sha256:0633f1d2df477324f53a895b02c901fb961bdbf65a17122586ea7019292cbcf0", size = 186976, upload-time = "2025-04-16T00:41:48.867Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/3d/9373ad9c56321fdab5b41197068e1d8c25883b3fea29dd361f9b55116869/dill-0.4.0-py3-none-any.whl", hash = "sha256:44f54bf6412c2c8464c14e8243eb163690a9800dbe2c367330883b19c7561049", size = 119668, upload-time = "2025-04-16T00:41:47.671Z" }, +] + +[[package]] +name = "exceptiongroup" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/f4/c6e662dade71f56cd2f3735141b265c3c79293c109549c1e6933b0651ffc/exceptiongroup-1.3.0-py3-none-any.whl", hash = "sha256:4d111e6e0c13d0644cad6ddaa7ed0261a0b36971f6d23e7ec9b4b9097da78a10", size = 16674, upload-time = "2025-05-10T17:42:49.33Z" }, +] + +[[package]] +name = "filelock" +version = "3.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/40/bb/0ab3e58d22305b6f5440629d20683af28959bf793d98d11950e305c1c326/filelock-3.19.1.tar.gz", hash = "sha256:66eda1888b0171c998b35be2bcc0f6d75c388a7ce20c3f3f37aa8e96c2dddf58", size = 17687, upload-time = "2025-08-14T16:56:03.016Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/14/42b2651a2f46b022ccd948bca9f2d5af0fd8929c4eec235b8d6d844fbe67/filelock-3.19.1-py3-none-any.whl", hash = "sha256:d38e30481def20772f5baf097c122c3babc4fcdb7e14e57049eb9d88c6dc017d", size = 15988, upload-time = "2025-08-14T16:56:01.633Z" }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/97/ebf4da567aa6827c909642694d71c9fcf53e5b504f2d96afea02718862f3/iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7", size = 4793, upload-time = "2025-03-19T20:09:59.721Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/e1/e6716421ea10d38022b952c159d5161ca1193197fb744506875fbb87ea7b/iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760", size = 6050, upload-time = "2025-03-19T20:10:01.071Z" }, +] + +[[package]] +name = "isort" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b8/21/1e2a441f74a653a144224d7d21afe8f4169e6c7c20bb13aec3a2dc3815e0/isort-6.0.1.tar.gz", hash = "sha256:1cb5df28dfbc742e490c5e41bad6da41b805b0a8be7bc93cd0fb2a8a890ac450", size = 821955, upload-time = "2025-02-26T21:13:16.955Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/11/114d0a5f4dabbdcedc1125dee0888514c3c3b16d3e9facad87ed96fad97c/isort-6.0.1-py3-none-any.whl", hash = "sha256:2dc5d7f65c9678d94c88dfc29161a320eec67328bc97aad576874cb4be1e9615", size = 94186, upload-time = "2025-02-26T21:13:14.911Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + +[[package]] +name = "license-expression" +version = "30.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "boolean-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/40/71/d89bb0e71b1415453980fd32315f2a037aad9f7f70f695c7cec7035feb13/license_expression-30.4.4.tar.gz", hash = "sha256:73448f0aacd8d0808895bdc4b2c8e01a8d67646e4188f887375398c761f340fd", size = 186402, upload-time = "2025-07-22T11:13:32.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/40/791891d4c0c4dab4c5e187c17261cedc26285fd41541577f900470a45a4d/license_expression-30.4.4-py3-none-any.whl", hash = "sha256:421788fdcadb41f049d2dc934ce666626265aeccefddd25e162a26f23bcbf8a4", size = 120615, upload-time = "2025-07-22T11:13:31.217Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/f5/4ec618ed16cc4f8fb3b701563655a69816155e79e24a17b651541804721d/markdown_it_py-4.0.0.tar.gz", hash = "sha256:cb0a2b4aa34f932c007117b194e945bd74e0ec24133ceb5bac59009cda1cb9f3", size = 73070, upload-time = "2025-08-11T12:57:52.854Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl", hash = "sha256:87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147", size = 87321, upload-time = "2025-08-11T12:57:51.923Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357, upload-time = "2024-10-18T15:20:51.44Z" }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393, upload-time = "2024-10-18T15:20:52.426Z" }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732, upload-time = "2024-10-18T15:20:53.578Z" }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866, upload-time = "2024-10-18T15:20:55.06Z" }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964, upload-time = "2024-10-18T15:20:55.906Z" }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977, upload-time = "2024-10-18T15:20:57.189Z" }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366, upload-time = "2024-10-18T15:20:58.235Z" }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091, upload-time = "2024-10-18T15:20:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065, upload-time = "2024-10-18T15:21:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514, upload-time = "2024-10-18T15:21:01.122Z" }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353, upload-time = "2024-10-18T15:21:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392, upload-time = "2024-10-18T15:21:02.941Z" }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984, upload-time = "2024-10-18T15:21:03.953Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120, upload-time = "2024-10-18T15:21:06.495Z" }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032, upload-time = "2024-10-18T15:21:07.295Z" }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057, upload-time = "2024-10-18T15:21:08.073Z" }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359, upload-time = "2024-10-18T15:21:09.318Z" }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306, upload-time = "2024-10-18T15:21:10.185Z" }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094, upload-time = "2024-10-18T15:21:11.005Z" }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521, upload-time = "2024-10-18T15:21:12.911Z" }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274, upload-time = "2024-10-18T15:21:13.777Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348, upload-time = "2024-10-18T15:21:14.822Z" }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149, upload-time = "2024-10-18T15:21:15.642Z" }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118, upload-time = "2024-10-18T15:21:17.133Z" }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993, upload-time = "2024-10-18T15:21:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178, upload-time = "2024-10-18T15:21:18.859Z" }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319, upload-time = "2024-10-18T15:21:19.671Z" }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352, upload-time = "2024-10-18T15:21:20.971Z" }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097, upload-time = "2024-10-18T15:21:22.646Z" }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601, upload-time = "2024-10-18T15:21:23.499Z" }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658, upload-time = "2022-01-24T01:14:51.113Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350, upload-time = "2022-01-24T01:14:49.62Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "msgpack" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/45/b1/ea4f68038a18c77c9467400d166d74c4ffa536f34761f7983a104357e614/msgpack-1.1.1.tar.gz", hash = "sha256:77b79ce34a2bdab2594f490c8e80dd62a02d650b91a75159a63ec413b8d104cd", size = 173555, upload-time = "2025-06-13T06:52:51.324Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/52/f30da112c1dc92cf64f57d08a273ac771e7b29dea10b4b30369b2d7e8546/msgpack-1.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:353b6fc0c36fde68b661a12949d7d49f8f51ff5fa019c1e47c87c4ff34b080ed", size = 81799, upload-time = "2025-06-13T06:51:37.228Z" }, + { url = "https://files.pythonhosted.org/packages/e4/35/7bfc0def2f04ab4145f7f108e3563f9b4abae4ab0ed78a61f350518cc4d2/msgpack-1.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:79c408fcf76a958491b4e3b103d1c417044544b68e96d06432a189b43d1215c8", size = 78278, upload-time = "2025-06-13T06:51:38.534Z" }, + { url = "https://files.pythonhosted.org/packages/e8/c5/df5d6c1c39856bc55f800bf82778fd4c11370667f9b9e9d51b2f5da88f20/msgpack-1.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78426096939c2c7482bf31ef15ca219a9e24460289c00dd0b94411040bb73ad2", size = 402805, upload-time = "2025-06-13T06:51:39.538Z" }, + { url = "https://files.pythonhosted.org/packages/20/8e/0bb8c977efecfe6ea7116e2ed73a78a8d32a947f94d272586cf02a9757db/msgpack-1.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b17ba27727a36cb73aabacaa44b13090feb88a01d012c0f4be70c00f75048b4", size = 408642, upload-time = "2025-06-13T06:51:41.092Z" }, + { url = "https://files.pythonhosted.org/packages/59/a1/731d52c1aeec52006be6d1f8027c49fdc2cfc3ab7cbe7c28335b2910d7b6/msgpack-1.1.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a17ac1ea6ec3c7687d70201cfda3b1e8061466f28f686c24f627cae4ea8efd0", size = 395143, upload-time = "2025-06-13T06:51:42.575Z" }, + { url = "https://files.pythonhosted.org/packages/2b/92/b42911c52cda2ba67a6418ffa7d08969edf2e760b09015593c8a8a27a97d/msgpack-1.1.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:88d1e966c9235c1d4e2afac21ca83933ba59537e2e2727a999bf3f515ca2af26", size = 395986, upload-time = "2025-06-13T06:51:43.807Z" }, + { url = "https://files.pythonhosted.org/packages/61/dc/8ae165337e70118d4dab651b8b562dd5066dd1e6dd57b038f32ebc3e2f07/msgpack-1.1.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:f6d58656842e1b2ddbe07f43f56b10a60f2ba5826164910968f5933e5178af75", size = 402682, upload-time = "2025-06-13T06:51:45.534Z" }, + { url = "https://files.pythonhosted.org/packages/58/27/555851cb98dcbd6ce041df1eacb25ac30646575e9cd125681aa2f4b1b6f1/msgpack-1.1.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:96decdfc4adcbc087f5ea7ebdcfd3dee9a13358cae6e81d54be962efc38f6338", size = 406368, upload-time = "2025-06-13T06:51:46.97Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/39a26add4ce16f24e99eabb9005e44c663db00e3fce17d4ae1ae9d61df99/msgpack-1.1.1-cp310-cp310-win32.whl", hash = "sha256:6640fd979ca9a212e4bcdf6eb74051ade2c690b862b679bfcb60ae46e6dc4bfd", size = 65004, upload-time = "2025-06-13T06:51:48.582Z" }, + { url = "https://files.pythonhosted.org/packages/7d/18/73dfa3e9d5d7450d39debde5b0d848139f7de23bd637a4506e36c9800fd6/msgpack-1.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:8b65b53204fe1bd037c40c4148d00ef918eb2108d24c9aaa20bc31f9810ce0a8", size = 71548, upload-time = "2025-06-13T06:51:49.558Z" }, + { url = "https://files.pythonhosted.org/packages/7f/83/97f24bf9848af23fe2ba04380388216defc49a8af6da0c28cc636d722502/msgpack-1.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:71ef05c1726884e44f8b1d1773604ab5d4d17729d8491403a705e649116c9558", size = 82728, upload-time = "2025-06-13T06:51:50.68Z" }, + { url = "https://files.pythonhosted.org/packages/aa/7f/2eaa388267a78401f6e182662b08a588ef4f3de6f0eab1ec09736a7aaa2b/msgpack-1.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:36043272c6aede309d29d56851f8841ba907a1a3d04435e43e8a19928e243c1d", size = 79279, upload-time = "2025-06-13T06:51:51.72Z" }, + { url = "https://files.pythonhosted.org/packages/f8/46/31eb60f4452c96161e4dfd26dbca562b4ec68c72e4ad07d9566d7ea35e8a/msgpack-1.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a32747b1b39c3ac27d0670122b57e6e57f28eefb725e0b625618d1b59bf9d1e0", size = 423859, upload-time = "2025-06-13T06:51:52.749Z" }, + { url = "https://files.pythonhosted.org/packages/45/16/a20fa8c32825cc7ae8457fab45670c7a8996d7746ce80ce41cc51e3b2bd7/msgpack-1.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a8b10fdb84a43e50d38057b06901ec9da52baac6983d3f709d8507f3889d43f", size = 429975, upload-time = "2025-06-13T06:51:53.97Z" }, + { url = "https://files.pythonhosted.org/packages/86/ea/6c958e07692367feeb1a1594d35e22b62f7f476f3c568b002a5ea09d443d/msgpack-1.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba0c325c3f485dc54ec298d8b024e134acf07c10d494ffa24373bea729acf704", size = 413528, upload-time = "2025-06-13T06:51:55.507Z" }, + { url = "https://files.pythonhosted.org/packages/75/05/ac84063c5dae79722bda9f68b878dc31fc3059adb8633c79f1e82c2cd946/msgpack-1.1.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:88daaf7d146e48ec71212ce21109b66e06a98e5e44dca47d853cbfe171d6c8d2", size = 413338, upload-time = "2025-06-13T06:51:57.023Z" }, + { url = "https://files.pythonhosted.org/packages/69/e8/fe86b082c781d3e1c09ca0f4dacd457ede60a13119b6ce939efe2ea77b76/msgpack-1.1.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8b55ea20dc59b181d3f47103f113e6f28a5e1c89fd5b67b9140edb442ab67f2", size = 422658, upload-time = "2025-06-13T06:51:58.419Z" }, + { url = "https://files.pythonhosted.org/packages/3b/2b/bafc9924df52d8f3bb7c00d24e57be477f4d0f967c0a31ef5e2225e035c7/msgpack-1.1.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4a28e8072ae9779f20427af07f53bbb8b4aa81151054e882aee333b158da8752", size = 427124, upload-time = "2025-06-13T06:51:59.969Z" }, + { url = "https://files.pythonhosted.org/packages/a2/3b/1f717e17e53e0ed0b68fa59e9188f3f610c79d7151f0e52ff3cd8eb6b2dc/msgpack-1.1.1-cp311-cp311-win32.whl", hash = "sha256:7da8831f9a0fdb526621ba09a281fadc58ea12701bc709e7b8cbc362feabc295", size = 65016, upload-time = "2025-06-13T06:52:01.294Z" }, + { url = "https://files.pythonhosted.org/packages/48/45/9d1780768d3b249accecc5a38c725eb1e203d44a191f7b7ff1941f7df60c/msgpack-1.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5fd1b58e1431008a57247d6e7cc4faa41c3607e8e7d4aaf81f7c29ea013cb458", size = 72267, upload-time = "2025-06-13T06:52:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/e3/26/389b9c593eda2b8551b2e7126ad3a06af6f9b44274eb3a4f054d48ff7e47/msgpack-1.1.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ae497b11f4c21558d95de9f64fff7053544f4d1a17731c866143ed6bb4591238", size = 82359, upload-time = "2025-06-13T06:52:03.909Z" }, + { url = "https://files.pythonhosted.org/packages/ab/65/7d1de38c8a22cf8b1551469159d4b6cf49be2126adc2482de50976084d78/msgpack-1.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33be9ab121df9b6b461ff91baac6f2731f83d9b27ed948c5b9d1978ae28bf157", size = 79172, upload-time = "2025-06-13T06:52:05.246Z" }, + { url = "https://files.pythonhosted.org/packages/0f/bd/cacf208b64d9577a62c74b677e1ada005caa9b69a05a599889d6fc2ab20a/msgpack-1.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f64ae8fe7ffba251fecb8408540c34ee9df1c26674c50c4544d72dbf792e5ce", size = 425013, upload-time = "2025-06-13T06:52:06.341Z" }, + { url = "https://files.pythonhosted.org/packages/4d/ec/fd869e2567cc9c01278a736cfd1697941ba0d4b81a43e0aa2e8d71dab208/msgpack-1.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a494554874691720ba5891c9b0b39474ba43ffb1aaf32a5dac874effb1619e1a", size = 426905, upload-time = "2025-06-13T06:52:07.501Z" }, + { url = "https://files.pythonhosted.org/packages/55/2a/35860f33229075bce803a5593d046d8b489d7ba2fc85701e714fc1aaf898/msgpack-1.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb643284ab0ed26f6957d969fe0dd8bb17beb567beb8998140b5e38a90974f6c", size = 407336, upload-time = "2025-06-13T06:52:09.047Z" }, + { url = "https://files.pythonhosted.org/packages/8c/16/69ed8f3ada150bf92745fb4921bd621fd2cdf5a42e25eb50bcc57a5328f0/msgpack-1.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d275a9e3c81b1093c060c3837e580c37f47c51eca031f7b5fb76f7b8470f5f9b", size = 409485, upload-time = "2025-06-13T06:52:10.382Z" }, + { url = "https://files.pythonhosted.org/packages/c6/b6/0c398039e4c6d0b2e37c61d7e0e9d13439f91f780686deb8ee64ecf1ae71/msgpack-1.1.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4fd6b577e4541676e0cc9ddc1709d25014d3ad9a66caa19962c4f5de30fc09ef", size = 412182, upload-time = "2025-06-13T06:52:11.644Z" }, + { url = "https://files.pythonhosted.org/packages/b8/d0/0cf4a6ecb9bc960d624c93effaeaae75cbf00b3bc4a54f35c8507273cda1/msgpack-1.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bb29aaa613c0a1c40d1af111abf025f1732cab333f96f285d6a93b934738a68a", size = 419883, upload-time = "2025-06-13T06:52:12.806Z" }, + { url = "https://files.pythonhosted.org/packages/62/83/9697c211720fa71a2dfb632cad6196a8af3abea56eece220fde4674dc44b/msgpack-1.1.1-cp312-cp312-win32.whl", hash = "sha256:870b9a626280c86cff9c576ec0d9cbcc54a1e5ebda9cd26dab12baf41fee218c", size = 65406, upload-time = "2025-06-13T06:52:14.271Z" }, + { url = "https://files.pythonhosted.org/packages/c0/23/0abb886e80eab08f5e8c485d6f13924028602829f63b8f5fa25a06636628/msgpack-1.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:5692095123007180dca3e788bb4c399cc26626da51629a31d40207cb262e67f4", size = 72558, upload-time = "2025-06-13T06:52:15.252Z" }, + { url = "https://files.pythonhosted.org/packages/a1/38/561f01cf3577430b59b340b51329803d3a5bf6a45864a55f4ef308ac11e3/msgpack-1.1.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3765afa6bd4832fc11c3749be4ba4b69a0e8d7b728f78e68120a157a4c5d41f0", size = 81677, upload-time = "2025-06-13T06:52:16.64Z" }, + { url = "https://files.pythonhosted.org/packages/09/48/54a89579ea36b6ae0ee001cba8c61f776451fad3c9306cd80f5b5c55be87/msgpack-1.1.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8ddb2bcfd1a8b9e431c8d6f4f7db0773084e107730ecf3472f1dfe9ad583f3d9", size = 78603, upload-time = "2025-06-13T06:52:17.843Z" }, + { url = "https://files.pythonhosted.org/packages/a0/60/daba2699b308e95ae792cdc2ef092a38eb5ee422f9d2fbd4101526d8a210/msgpack-1.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:196a736f0526a03653d829d7d4c5500a97eea3648aebfd4b6743875f28aa2af8", size = 420504, upload-time = "2025-06-13T06:52:18.982Z" }, + { url = "https://files.pythonhosted.org/packages/20/22/2ebae7ae43cd8f2debc35c631172ddf14e2a87ffcc04cf43ff9df9fff0d3/msgpack-1.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d592d06e3cc2f537ceeeb23d38799c6ad83255289bb84c2e5792e5a8dea268a", size = 423749, upload-time = "2025-06-13T06:52:20.211Z" }, + { url = "https://files.pythonhosted.org/packages/40/1b/54c08dd5452427e1179a40b4b607e37e2664bca1c790c60c442c8e972e47/msgpack-1.1.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4df2311b0ce24f06ba253fda361f938dfecd7b961576f9be3f3fbd60e87130ac", size = 404458, upload-time = "2025-06-13T06:52:21.429Z" }, + { url = "https://files.pythonhosted.org/packages/2e/60/6bb17e9ffb080616a51f09928fdd5cac1353c9becc6c4a8abd4e57269a16/msgpack-1.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e4141c5a32b5e37905b5940aacbc59739f036930367d7acce7a64e4dec1f5e0b", size = 405976, upload-time = "2025-06-13T06:52:22.995Z" }, + { url = "https://files.pythonhosted.org/packages/ee/97/88983e266572e8707c1f4b99c8fd04f9eb97b43f2db40e3172d87d8642db/msgpack-1.1.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b1ce7f41670c5a69e1389420436f41385b1aa2504c3b0c30620764b15dded2e7", size = 408607, upload-time = "2025-06-13T06:52:24.152Z" }, + { url = "https://files.pythonhosted.org/packages/bc/66/36c78af2efaffcc15a5a61ae0df53a1d025f2680122e2a9eb8442fed3ae4/msgpack-1.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4147151acabb9caed4e474c3344181e91ff7a388b888f1e19ea04f7e73dc7ad5", size = 424172, upload-time = "2025-06-13T06:52:25.704Z" }, + { url = "https://files.pythonhosted.org/packages/8c/87/a75eb622b555708fe0427fab96056d39d4c9892b0c784b3a721088c7ee37/msgpack-1.1.1-cp313-cp313-win32.whl", hash = "sha256:500e85823a27d6d9bba1d057c871b4210c1dd6fb01fbb764e37e4e8847376323", size = 65347, upload-time = "2025-06-13T06:52:26.846Z" }, + { url = "https://files.pythonhosted.org/packages/ca/91/7dc28d5e2a11a5ad804cf2b7f7a5fcb1eb5a4966d66a5d2b41aee6376543/msgpack-1.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:6d489fba546295983abd142812bda76b57e33d0b9f5d5b71c09a583285506f69", size = 72341, upload-time = "2025-06-13T06:52:27.835Z" }, +] + +[[package]] +name = "mypy-extensions" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/6e/371856a3fb9d31ca8dac321cda606860fa4548858c0cc45d9d1d4ca2628b/mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558", size = 6343, upload-time = "2025-04-22T14:54:24.164Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/7b/2c79738432f5c924bef5071f933bcc9efd0473bac3b4aa584a6f7c1c8df8/mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505", size = 4963, upload-time = "2025-04-22T14:54:22.983Z" }, +] + +[[package]] +name = "packageurl-python" +version = "0.17.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/f0/de0ac00a4484c0d87b71e3d9985518278d89797fa725e90abd3453bccb42/packageurl_python-0.17.5.tar.gz", hash = "sha256:a7be3f3ba70d705f738ace9bf6124f31920245a49fa69d4b416da7037dd2de61", size = 43832, upload-time = "2025-08-06T14:08:20.235Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/78/9dbb7d2ef240d20caf6f79c0f66866737c9d0959601fd783ff635d1d019d/packageurl_python-0.17.5-py3-none-any.whl", hash = "sha256:f0e55452ab37b5c192c443de1458e3f3b4d8ac27f747df6e8c48adeab081d321", size = 30544, upload-time = "2025-08-06T14:08:19.055Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, +] + +[[package]] +name = "pip" +version = "25.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/16/650289cd3f43d5a2fadfd98c68bd1e1e7f2550a1a5326768cddfbcedb2c5/pip-25.2.tar.gz", hash = "sha256:578283f006390f85bb6282dffb876454593d637f5d1be494b5202ce4877e71f2", size = 1840021, upload-time = "2025-07-30T21:50:15.401Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/3f/945ef7ab14dc4f9d7f40288d2df998d1837ee0888ec3659c813487572faa/pip-25.2-py3-none-any.whl", hash = "sha256:6d67a2b4e7f14d8b31b8b52648866fa717f45a1eb70e83002f4331d07e953717", size = 1752557, upload-time = "2025-07-30T21:50:13.323Z" }, +] + +[[package]] +name = "pip-api" +version = "0.0.34" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pip" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/f1/ee85f8c7e82bccf90a3c7aad22863cc6e20057860a1361083cd2adacb92e/pip_api-0.0.34.tar.gz", hash = "sha256:9b75e958f14c5a2614bae415f2adf7eeb54d50a2cfbe7e24fd4826471bac3625", size = 123017, upload-time = "2024-07-09T20:32:30.641Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/f7/ebf5003e1065fd00b4cbef53bf0a65c3d3e1b599b676d5383ccb7a8b88ba/pip_api-0.0.34-py3-none-any.whl", hash = "sha256:8b2d7d7c37f2447373aa2cf8b1f60a2f2b27a84e1e9e0294a3f6ef10eb3ba6bb", size = 120369, upload-time = "2024-07-09T20:32:29.099Z" }, +] + +[[package]] +name = "pip-audit" +version = "2.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cachecontrol", extra = ["filecache"] }, + { name = "cyclonedx-python-lib" }, + { name = "packaging" }, + { name = "pip-api" }, + { name = "pip-requirements-parser" }, + { name = "platformdirs" }, + { name = "requests" }, + { name = "rich" }, + { name = "toml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/7f/28fad19a9806f796f13192ab6974c07c4a04d9cbb8e30dd895c3c11ce7ee/pip_audit-2.9.0.tar.gz", hash = "sha256:0b998410b58339d7a231e5aa004326a294e4c7c6295289cdc9d5e1ef07b1f44d", size = 52089, upload-time = "2025-04-07T16:45:23.679Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/9e/f4dfd9d3dadb6d6dc9406f1111062f871e2e248ed7b584cca6020baf2ac1/pip_audit-2.9.0-py3-none-any.whl", hash = "sha256:348b16e60895749a0839875d7cc27ebd692e1584ebe5d5cb145941c8e25a80bd", size = 58634, upload-time = "2025-04-07T16:45:22.056Z" }, +] + +[[package]] +name = "pip-requirements-parser" +version = "32.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pyparsing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5e/2a/63b574101850e7f7b306ddbdb02cb294380d37948140eecd468fae392b54/pip-requirements-parser-32.0.1.tar.gz", hash = "sha256:b4fa3a7a0be38243123cf9d1f3518da10c51bdb165a2b2985566247f9155a7d3", size = 209359, upload-time = "2022-12-21T15:25:22.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/d0/d04f1d1e064ac901439699ee097f58688caadea42498ec9c4b4ad2ef84ab/pip_requirements_parser-32.0.1-py3-none-any.whl", hash = "sha256:4659bc2a667783e7a15d190f6fccf8b2486685b6dba4c19c3876314769c57526", size = 35648, upload-time = "2022-12-21T15:25:21.046Z" }, +] + +[[package]] +name = "platformdirs" +version = "4.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "py-serializable" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "defusedxml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/21/d250cfca8ff30c2e5a7447bc13861541126ce9bd4426cd5d0c9f08b5547d/py_serializable-2.1.0.tar.gz", hash = "sha256:9d5db56154a867a9b897c0163b33a793c804c80cee984116d02d49e4578fc103", size = 52368, upload-time = "2025-07-21T09:56:48.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/bf/7595e817906a29453ba4d99394e781b6fabe55d21f3c15d240f85dd06bb1/py_serializable-2.1.0-py3-none-any.whl", hash = "sha256:b56d5d686b5a03ba4f4db5e769dc32336e142fc3bd4d68a8c25579ebb0a67304", size = 23045, upload-time = "2025-07-21T09:56:46.848Z" }, +] + +[[package]] +name = "pygments" +version = "2.19.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, +] + +[[package]] +name = "pylint" +version = "3.3.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/58/1f614a84d3295c542e9f6e2c764533eea3f318f4592dc1ea06c797114767/pylint-3.3.8.tar.gz", hash = "sha256:26698de19941363037e2937d3db9ed94fb3303fdadf7d98847875345a8bb6b05", size = 1523947, upload-time = "2025-08-09T09:12:57.234Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/1a/711e93a7ab6c392e349428ea56e794a3902bb4e0284c1997cff2d7efdbc1/pylint-3.3.8-py3-none-any.whl", hash = "sha256:7ef94aa692a600e82fabdd17102b73fc226758218c97473c7ad67bd4cb905d83", size = 523153, upload-time = "2025-08-09T09:12:54.836Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, +] + +[[package]] +name = "pytest" +version = "8.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "pygments" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, +] + +[[package]] +name = "pytest-cookies" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cookiecutter" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/2e/11a3e1abb4bbf10e0af3f194ba4c55600de3fe52417ef3594c18d28ecdbe/pytest-cookies-0.7.0.tar.gz", hash = "sha256:1aaa6b4def8238d0d1709d3d773b423351bfb671c1e3438664d824e0859d6308", size = 8840, upload-time = "2023-03-22T11:07:29.595Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/f7/438af2f3a6c58f81d22c126707ee5d079f653a76961f4fb7d995e526a9c4/pytest_cookies-0.7.0-py3-none-any.whl", hash = "sha256:52770f090d77b16428f6a24a208e6be76addb2e33458035714087b4de49389ea", size = 6386, upload-time = "2023-03-22T11:07:28.068Z" }, +] + +[[package]] +name = "pytest-cov" +version = "6.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pluggy" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, +] + +[[package]] +name = "python-slugify" +version = "8.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "text-unidecode" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/c7/5e1547c44e31da50a460df93af11a535ace568ef89d7a811069ead340c4a/python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856", size = 10921, upload-time = "2024-02-08T18:32:45.488Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/62/02da182e544a51a5c3ccf4b03ab79df279f9c60c5e82d5e8bec7ca26ac11/python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8", size = 10051, upload-time = "2024-02-08T18:32:43.911Z" }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199, upload-time = "2024-08-06T20:31:40.178Z" }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758, upload-time = "2024-08-06T20:31:42.173Z" }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463, upload-time = "2024-08-06T20:31:44.263Z" }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280, upload-time = "2024-08-06T20:31:50.199Z" }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239, upload-time = "2024-08-06T20:31:52.292Z" }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802, upload-time = "2024-08-06T20:31:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527, upload-time = "2024-08-06T20:31:55.565Z" }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052, upload-time = "2024-08-06T20:31:56.914Z" }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774, upload-time = "2024-08-06T20:31:58.304Z" }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +] + +[[package]] +name = "requests" +version = "2.32.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, +] + +[[package]] +name = "rich" +version = "14.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/75/af448d8e52bf1d8fa6a9d089ca6c07ff4453d86c65c145d0a300bb073b9b/rich-14.1.0.tar.gz", hash = "sha256:e497a48b844b0320d45007cdebfeaeed8db2a4f4bcf49f15e455cfc4af11eaa8", size = 224441, upload-time = "2025-07-25T07:32:58.125Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e3/30/3c4d035596d3cf444529e0b2953ad0466f6049528a879d27534700580395/rich-14.1.0-py3-none-any.whl", hash = "sha256:536f5f1785986d6dbdea3c75205c473f970777b4a0d6c6dd1b696aa05a3fa04f", size = 243368, upload-time = "2025-07-25T07:32:56.73Z" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "sortedcontainers" +version = "2.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/c4/ba2f8066cceb6f23394729afe52f3bf7adec04bf9ed2c820b39e19299111/sortedcontainers-2.4.0.tar.gz", hash = "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", size = 30594, upload-time = "2021-05-16T22:03:42.897Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" }, +] + +[[package]] +name = "stevedore" +version = "5.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/5f/8418daad5c353300b7661dd8ce2574b0410a6316a8be650a189d5c68d938/stevedore-5.5.0.tar.gz", hash = "sha256:d31496a4f4df9825e1a1e4f1f74d19abb0154aff311c3b376fcc89dae8fccd73", size = 513878, upload-time = "2025-08-25T12:54:26.806Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/c5/0c06759b95747882bb50abda18f5fb48c3e9b0fbfc6ebc0e23550b52415d/stevedore-5.5.0-py3-none-any.whl", hash = "sha256:18363d4d268181e8e8452e71a38cd77630f345b2ef6b4a8d5614dac5ee0d18cf", size = 49518, upload-time = "2025-08-25T12:54:25.445Z" }, +] + +[[package]] +name = "text-unidecode" +version = "1.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93", size = 76885, upload-time = "2019-08-30T21:36:45.405Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8", size = 78154, upload-time = "2019-08-30T21:37:03.543Z" }, +] + +[[package]] +name = "toml" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/ba/1f744cdc819428fc6b5084ec34d9b30660f6f9daaf70eead706e3203ec3c/toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f", size = 22253, upload-time = "2020-11-01T01:40:22.204Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/6f/7120676b6d73228c96e17f1f794d8ab046fc910d781c8d151120c3f1569e/toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", size = 16588, upload-time = "2020-11-01T01:40:20.672Z" }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175, upload-time = "2024-11-27T22:38:36.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077, upload-time = "2024-11-27T22:37:54.956Z" }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429, upload-time = "2024-11-27T22:37:56.698Z" }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067, upload-time = "2024-11-27T22:37:57.63Z" }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030, upload-time = "2024-11-27T22:37:59.344Z" }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898, upload-time = "2024-11-27T22:38:00.429Z" }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894, upload-time = "2024-11-27T22:38:02.094Z" }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319, upload-time = "2024-11-27T22:38:03.206Z" }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273, upload-time = "2024-11-27T22:38:04.217Z" }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310, upload-time = "2024-11-27T22:38:05.908Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309, upload-time = "2024-11-27T22:38:06.812Z" }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762, upload-time = "2024-11-27T22:38:07.731Z" }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453, upload-time = "2024-11-27T22:38:09.384Z" }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486, upload-time = "2024-11-27T22:38:10.329Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349, upload-time = "2024-11-27T22:38:11.443Z" }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159, upload-time = "2024-11-27T22:38:13.099Z" }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243, upload-time = "2024-11-27T22:38:14.766Z" }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645, upload-time = "2024-11-27T22:38:15.843Z" }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584, upload-time = "2024-11-27T22:38:17.645Z" }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875, upload-time = "2024-11-27T22:38:19.159Z" }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418, upload-time = "2024-11-27T22:38:20.064Z" }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708, upload-time = "2024-11-27T22:38:21.659Z" }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582, upload-time = "2024-11-27T22:38:22.693Z" }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543, upload-time = "2024-11-27T22:38:24.367Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691, upload-time = "2024-11-27T22:38:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170, upload-time = "2024-11-27T22:38:27.921Z" }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530, upload-time = "2024-11-27T22:38:29.591Z" }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666, upload-time = "2024-11-27T22:38:30.639Z" }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954, upload-time = "2024-11-27T22:38:31.702Z" }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724, upload-time = "2024-11-27T22:38:32.837Z" }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383, upload-time = "2024-11-27T22:38:34.455Z" }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257, upload-time = "2024-11-27T22:38:35.385Z" }, +] + +[[package]] +name = "tomlkit" +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/18/0bbf3884e9eaa38819ebe46a7bd25dcd56b67434402b66a58c4b8e552575/tomlkit-0.13.3.tar.gz", hash = "sha256:430cf247ee57df2b94ee3fbe588e71d362a941ebb545dec29b53961d61add2a1", size = 185207, upload-time = "2025-06-05T07:13:44.947Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/75/8539d011f6be8e29f339c42e633aae3cb73bffa95dd0f9adec09b9c58e85/tomlkit-0.13.3-py3-none-any.whl", hash = "sha256:c89c649d79ee40629a9fda55f8ace8c6a1b42deb912b2a8fd8d942ddadb606b0", size = 38901, upload-time = "2025-06-05T07:13:43.546Z" }, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20250822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/0a/775f8551665992204c756be326f3575abba58c4a3a52eef9909ef4536428/types_python_dateutil-2.9.0.20250822.tar.gz", hash = "sha256:84c92c34bd8e68b117bff742bc00b692a1e8531262d4507b33afcc9f7716cd53", size = 16084, upload-time = "2025-08-22T03:02:00.613Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/d9/a29dfa84363e88b053bf85a8b7f212a04f0d7343a4d24933baa45c06e08b/types_python_dateutil-2.9.0.20250822-py3-none-any.whl", hash = "sha256:849d52b737e10a6dc6621d2bd7940ec7c65fcb69e6aa2882acf4e56b2b508ddc", size = 17892, upload-time = "2025-08-22T03:01:59.436Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, +] + +[[package]] +name = "urllib3" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, +] diff --git a/{{cookiecutter.git_repo_name}}/.dockerignore b/{{cookiecutter.git_repo_name}}/.dockerignore new file mode 100644 index 0000000..e69de29 diff --git a/{{cookiecutter.git_repo_name}}/containers/Containerfile b/{{cookiecutter.git_repo_name}}/containers/Containerfile index 18559bb..209f772 100644 --- a/{{cookiecutter.git_repo_name}}/containers/Containerfile +++ b/{{cookiecutter.git_repo_name}}/containers/Containerfile @@ -25,5 +25,4 @@ RUN --mount=type=ssh,required=true \ EXPOSE 8080/tcp -# Need to change this for django -ENTRYPOINT ["{{ cookiecutter.git_repo_name }}-cli", "start", "-p", "8080"] +ENTRYPOINT ["python", "manage.py", "runserver"] diff --git a/{{cookiecutter.git_repo_name}}/containers/Dockerfile b/{{cookiecutter.git_repo_name}}/containers/Dockerfile index 7dab0b3..209f772 100644 --- a/{{cookiecutter.git_repo_name}}/containers/Dockerfile +++ b/{{cookiecutter.git_repo_name}}/containers/Dockerfile @@ -25,4 +25,4 @@ RUN --mount=type=ssh,required=true \ EXPOSE 8080/tcp -ENTRYPOINT ["{{ cookiecutter.git_repo_name }}-cli", "start", "-p", "8080"] +ENTRYPOINT ["python", "manage.py", "runserver"] From 1851e8f2032095fea1f17d53bb759f8a4987ccde Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Wed, 27 Aug 2025 16:36:53 -0400 Subject: [PATCH 14/18] remove uv.lock from repo --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 158efcd..7ea4623 100644 --- a/.gitignore +++ b/.gitignore @@ -109,6 +109,7 @@ venv/ ENV/ env.bak/ venv.bak/ +uv.lock # Spyder project settings .spyderproject From 98d6163f49ec8f43388ff34ce76e68511d9238a1 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Wed, 27 Aug 2025 16:44:47 -0400 Subject: [PATCH 15/18] added missing required library tomli --- pyproject.toml | 1 + requirements-dev.txt | 1 + tests/test_cookies.py | 6 ++++-- tests/test_pre_gen_project.py | 1 + uv.lock | 6 +++++- 5 files changed, 12 insertions(+), 3 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d3cd42e..e215f36 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,7 @@ dev = [ "black", "bandit", "pip-audit", + "tomli", ] [tool.setuptools.dynamic] diff --git a/requirements-dev.txt b/requirements-dev.txt index 30f58a0..420905b 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,3 +6,4 @@ pip-audit~=2.7.3 black~=24.10.0 bandit~=1.8.3 pip-audit~=2.7.3 +tomli~=2.2.1 \ No newline at end of file diff --git a/tests/test_cookies.py b/tests/test_cookies.py index b514ccb..cd6e3fc 100644 --- a/tests/test_cookies.py +++ b/tests/test_cookies.py @@ -1,8 +1,10 @@ """Tests for cookiecutter-python-django project template.""" + import os import tomli -def test_bake_project_podman(cookies, bake_project_podman_pip:dict): + +def test_bake_project_podman(cookies, bake_project_podman_pip: dict): """Test baking project with podman and pip Args: @@ -128,7 +130,7 @@ def test_bake_project_django_addons(cookies, bake_project_django_addons: dict): result = cookies.bake(extra_context=bake_project_django_addons) # Reads pyproject.toml and converts to python objects - with open(result.project_path.joinpath("pyproject.toml"), 'r', encoding='utf-8') as file: + with open(result.project_path.joinpath("pyproject.toml"), "r", encoding="utf-8") as file: toml = file.read() pyproject_toml = tomli.loads(toml) diff --git a/tests/test_pre_gen_project.py b/tests/test_pre_gen_project.py index dcd4f29..ae0b6a3 100644 --- a/tests/test_pre_gen_project.py +++ b/tests/test_pre_gen_project.py @@ -1,4 +1,5 @@ """Tests for pre_gen_project.py hook functions.""" + import pytest from hooks.pre_gen_project import ( validate_no_spaces, diff --git a/uv.lock b/uv.lock index fa721e9..2f7231b 100644 --- a/uv.lock +++ b/uv.lock @@ -248,6 +248,7 @@ version = "0.1.0" source = { virtual = "." } dependencies = [ { name = "cookiecutter" }, + { name = "tomli" }, ] [package.dev-dependencies] @@ -261,7 +262,10 @@ dev = [ ] [package.metadata] -requires-dist = [{ name = "cookiecutter" }] +requires-dist = [ + { name = "cookiecutter" }, + { name = "tomli", specifier = ">=2.2.1" }, +] [package.metadata.requires-dev] dev = [ From c20375d018ea2c528a245284c2e140c7bec67163 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Wed, 27 Aug 2025 16:49:42 -0400 Subject: [PATCH 16/18] updated develop badge for README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8f6b2da..a26e7b8 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # cookiecutter-python-django | BRANCH | STATUS | | ------ |--------| -| main | [![Unit-Testing, Coverage, Linting](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml/badge.svg?branch=main)](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml) | -| develop | [![Unit-Testing, Coverage, Linting](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml/badge.svg?branch=develop)](https://github.com/btr1975/cookiecutter-python-fastapi-openapi/actions/workflows/test-bake.yml) | +| main | | +| develop | [![Unit-Testing, Coverage, Linting](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml/badge.svg)](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml) | * This is a "cookiecutter" repository designed to be used as a framework to create repository structure. From 6cdc7dc758939d997e5318abc7710a8acc084fed Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Thu, 28 Aug 2025 08:14:12 -0400 Subject: [PATCH 17/18] README.md add status badge, .gitignore leave uv.lock in repo --- .gitignore | 1 - README.md | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 7ea4623..158efcd 100644 --- a/.gitignore +++ b/.gitignore @@ -109,7 +109,6 @@ venv/ ENV/ env.bak/ venv.bak/ -uv.lock # Spyder project settings .spyderproject diff --git a/README.md b/README.md index a26e7b8..7f28cd0 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # cookiecutter-python-django | BRANCH | STATUS | | ------ |--------| -| main | | +| main | [![Unit-Testing, Coverage, Linting](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml/badge.svg)](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml) | | develop | [![Unit-Testing, Coverage, Linting](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml/badge.svg)](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml) | * This is a "cookiecutter" repository designed to be used as a framework to create repository structure. From 1355ea41d53c8a5f48053509c14b0cbc58331ec7 Mon Sep 17 00:00:00 2001 From: Blaze Bryant Date: Fri, 29 Aug 2025 10:52:51 -0400 Subject: [PATCH 18/18] pyproject.toml: update version to 1.0.0, pull_request_template.md: remove blank space at end of line 4, README.md: updated documentation and examples --- .github/pull_request_template.md | 2 +- README.md | 170 +++++++++++++++++++++---------- pyproject.toml | 3 +- 3 files changed, 121 insertions(+), 54 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 2c11421..4bbbaf7 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,7 +1,7 @@ # Description Please include a summary of the change and which issue is fixed if applicable. Please also include relevant motivation -and context. +and context. List any dependencies that are required for this change. diff --git a/README.md b/README.md index 7f28cd0..34bd640 100644 --- a/README.md +++ b/README.md @@ -1,83 +1,149 @@ # cookiecutter-python-django + | BRANCH | STATUS | | ------ |--------| | main | [![Unit-Testing, Coverage, Linting](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml/badge.svg)](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml) | | develop | [![Unit-Testing, Coverage, Linting](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml/badge.svg)](https://github.com/naturalblaze/cookiecutter-python-django/actions/workflows/test-bake.yml) | -* This is a "cookiecutter" repository designed to be used as a framework to create repository structure. +* This is a "cookiecutter" repository designed to be used as a framework to create repository structure for Python Django projects. ## How to use a "cookiecutter" repository 1. First install the python library called [cookiecutter](https://cookiecutter.readthedocs.io/en/stable/) -```text -pip install cookiecutter -``` + ```bash + # Via pip + pip install cookiecutter + + # Via uv + uv add cookiecutter + ``` -2. Create a **TOTALLY** empty repository in a GIT based system. In my example I am creating a repo called +1. Create a **TOTALLY** empty repository in a GIT based system. In my example I am creating a repo called throw-me-away. -3. Use the cookiecutter repository to create your structure. +1. Use the cookiecutter repository to create your structure. + + * Use the latest -* Use the latest + * HTTPS -### HTTPS + ```bash + cookiecutter https://github.com/naturalblaze/cookiecutter-python-django + ``` -```text -cookiecutter https://github.com/naturalblaze/cookiecutter-python-django -``` + * SSH -### SSH + ```bash + cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git + ``` -```text -cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git -``` + * Use a specific version -* Use a specific version + * HTTPS -### HTTPS + ```bash + cookiecutter https://github.com/naturalblaze/cookiecutter-python-django.git -c 1.0.1 + ``` -```text -cookiecutter https://github.com/naturalblaze/cookiecutter-python-django.git -c 1.0.1 -``` + * SSH -### SSH + ```bash + cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git -c 1.0.1 + ``` -```text -cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git -c 1.0.1 -``` + * Use a specific branch with `UV` -### UV + ```bash + uvx cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop + ``` -```text -uvx cookiecutter git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop -``` + * Use a `YAML` configuration input file with `UV` -### UV with input file -```text -uvx cookiecutter -f --no-input --config-file test-repo.yml git@github.com:naturalblaze/cookiecutter-python-django.git --checkout develop -``` + ```bash + uvx cookiecutter -f --no-input --config-file test-repo.yml git@github.com:naturalblaze/cookiecutter-python-django.git + ``` -4. Now you will be asked a series of questions. This is an example +1. Now you will be asked a series of questions. This is an example **THE QUESTIONS MAY NOT BE THE EXACT FOR THIS COOKIECUTTER**, also if you have downloaded it before you will be asked if you want to download it again, always say yes to get the latest version. -```text -full_name [Your Full Name]: Ben T -email [Your E-Mail Address]: somename@example.com -git_username [Your GitHub Username]: btr1975 -git_repo_name [The Repository Name]: throw-me-away -git_url [The GIT URL]: https://github.com/btr1975/throw-me-away -app_description [A short description]: This is great -app_version [0.1.0]: -``` - -5. Now initialize it and push it up to the GIT based system. - -```text -git init -b main -git add --all -git commit -m "First" -git remote add origin https://github.com/btr1975/throw-me-away.git -git push -u origin main -``` + ```bash + [1/15] Your Full Name (Firstname Lastname): Blaze B + [2/15] Your E-Mail Address (example@example.com): somename@example.com + [3/15] Your GitHub Username or GitHub Organization Name (some-username): naturalblaze + [4/15] The Repository Name (some-repo-name): throw-me-away + [5/15] The full GIT URL (https://github.com/some-username/some-repo-name): https://github.com/naturalblaze/throw-me-away + [6/15] A short description (A short description): Super Awesome Django Project + [7/15] Library Version (0.1.0): 0.1.0 + [8/15] Where will the documentation be hosted + 1 - Read the Docs + 2 - GitHub Pages + Choose from [1/2] (1): 1 + [9/15] Which theme will be used for the documentation + 1 - Read the Docs Theme + 2 - Alabaster Theme + Choose from [1/2] (1): 1 + [10/15] Which minimum Python version will be supported + 1 - 3.9 + 2 - 3.10 + 3 - 3.11 + 4 - 3.12 + 5 - 3.13 + Choose from [1/2/3/4/5] (1): 2 + [11/15] Which pacakge manager for Python will be supported + 1 - UV By Astral + 2 - PIP (The built in Python Package Installer) + Choose from [1/2] (1): 1 + [12/15] Will you use the Django Environment library + 1 - No + 2 - Yes + Choose from [1/2] (1): 2 + [13/15] Will you use the Django MarkdownX library + 1 - No + 2 - Yes + Choose from [1/2] (1): 2 + [14/15] Which container runtime will be used + 1 - Podman + 2 - Docker + Choose from [1/2] (1): 1 + [15/15] Which protocol will be used for installing in the container + 1 - SSH + 2 - HTTPS + Choose from [1/2] (1): 1 + ``` + + ### Input file example + + ```yaml + --- + default_context: + full_name: "Blaze B" + email: "nsomename@example.com" + git_username: "naturalblaze" + git_repo_name: "throw-me-away" + git_url: "https://github.com/naturalblaze/throw-me-away" + app_description: "Super Awesome Django Project" + app_version: "0.1.0" + app_documents_location: "readthedocs.io" or "github-pages" + app_documents_theme: "sphinx_rtd_theme" or "alabaster" + minimum_python_version: 3.9" or "3.10" or "3.11" or "3.12" or "3.13" + package_manager: "uv" or "pip" + use_django_environ: "y" or "n" + use_django_markdownx: "y" or "n" + container_runtime: "podman" or "docker" + container_git_protocol: "ssh" or "https" + ``` + +1. Now initialize it and push it up to the GIT based system. + + ```bash + cd / + git init -b main + git add --all + git commit -m "Cookiecutter bake" + git remote add origin https://github.com/naturalblaze/throw-me-away.git + git push -u origin main + ``` + +1. Follow the `README.md` instructions in your repo to initialize your project diff --git a/pyproject.toml b/pyproject.toml index e215f36..c21d345 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "cookiecutter-python-django" dynamic = ["readme"] -version = "0.1.0" +version = "1.0.0" requires-python = ">=3.10" description = "CookieCutter for creating Python Django project" keywords = [ @@ -87,6 +87,7 @@ line-length = 120 exclude_dirs = [ "tests", "venv", + ".venv", "docs", "{{cookiecutter.git_repo_name}}", ]