From 670ee3466ea17d1c551901b6307e2751003a1459 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:08:08 +0800 Subject: [PATCH 01/65] ci: remove semantic-release and add mkdocs build --- .github/workflows/docs.yml | 34 +++++++ .github/workflows/main.yml | 41 +++++++++ mkdocs.yml | 184 +++++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 .github/workflows/main.yml create mode 100644 mkdocs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..780d4bc --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,34 @@ +name: mkdocs +on: + push: + branches: [ main ] + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@main + with: + # get full git commit to adjust for git-revision-date-localized plugin + fetch-depth: 0 + - name: Configure Git Credentials + run: | + git config user.name github-actions[bot] + git config user.email 41898282+github-actions[bot]@users.noreply.github.com + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + enable-cache: true + + - name: install dependencies and deploy + run: | + uv sync --only-group docs + uv run mkdocs gh-deploy --force + +# Reference +# 1. https://squidfunk.github.io/mkdocs-material/publishing-your-site/ +# 2. https://github.com/Kludex/python-template/blob/main/.github/workflows/docs.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..34b911e --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,41 @@ +name: Test And Release + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + +jobs: + test: + name: Run Tests / OS ${{ matrix.os }} / Python ${{ matrix.python-version }} + strategy: + matrix: + os: [ ubuntu-latest ] + python-version: ["3.10", "3.11", "3.12", "3.13"] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v4 + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + enable-cache: true + + - name: Set up Python ${{ matrix.python-version }} + run: uv python install ${{ matrix.python-version }} + + - name: Install dependencies + run: uv sync --python ${{ matrix.python-version }} --all-extras --dev + + - name: Run tests + run: uv run bash scripts/test.sh + + - name: Run linters + run: uv run bash scripts/lint.sh + + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4 + env: + CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..9df793e --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,184 @@ +# Copyright (c) 2016-2024 A.J.Zeller + +# Project information +site_name: fastapi_supabase_template +site_url: https://atticuszz.github.io/fastapi_supabase_template + +# Repository +# To display a link to the repository of your project as part of your documentation: https://squidfunk.github.io/mkdocs-material/setup/adding-a-git-repository/?h=edit+uri#code-actions-edit-this-page:~:text=In%20order%20to%20display%20a%20link%20to%20the%20repository%20of%20your%20project%20as%20part%20of%20your%20documentation +repo_url: https://github.com/Atticuszz/fastapi_supabase_template +repo_name: fastapi_supabase_template +edit_uri: edit/main/docs + +# Copyright +copyright: Copyright © 2016 - 2024 A.J.Zeller + +# Configuration +theme: + name: 'material' + features: + # code + - content.code.copy + - content.action.edit + # footnotes + - content.footnote.tooltips + + ## navigation + # The site_url setting must be set + - navigation.instant + # The progress indicator will only show if the page hasn't finished loading after 400ms + - navigation.instant.progress + # top-level selection move to top tabs + - navigation.tabs + # default to be expand + # - navigation.expand + # enable turn to before or after page in page button + - navigation.footer + # back to top + - navigation.top + # When anchor tracking is enabled, the URL in the address bar is automatically updated with the active anchor as highlighted in the table of contents + - navigation.tracking + + # When anchor following for the table of contents is enabled, the sidebar is automatically scrolled so that the active anchor is always visible + - toc.follow + + # search + - search.suggest + - search.highlight + - search.share + palette: + + # Light mode + - media: "(prefers-color-scheme: light)" + scheme: default + primary: white + accent: green + toggle: + icon: material/brightness-7 + name: Switch to dark mode + + # Dark mode + - media: "(prefers-color-scheme: dark)" + scheme: slate + primary: black + accent: deep purple + toggle: + icon: material/brightness-4 + name: Switch to light mode + + font: + text: 'Lora' + code: 'JetBrains Mono' + + # # logo from https://obsidian.md/brand + # favicon: assets/logo/logo.svg + # logo: assets/logo/logo.svg + + icon: + edit: material/pencil + repo: fontawesome/brands/git-alt + +plugins: + # The git-revision-date-localized plugin adds support for adding the date of last update and creation of a document at the bottom of each page + - git-revision-date-localized: + enable_creation_date: true + type: iso_datetime + # adjust to obsidian path + - obsidian-bridge + - pub-obsidian: # https://mkdocs-publisher.github.io/setup/installation/ + obsidian_dir: .obsidian + backlinks: + enabled: true + callouts: + enabled: true + indentation: spaces + # links: + # wikilinks_enabled: true + # img_lazy: true + # image zoom + - glightbox + - search + # - blog + # - rss: + # match_path: blog/posts/.* + # date_from_meta: + # as_creation: date + # categories: + # - categories + # - tags + +extra: + social: + - icon: fontawesome/solid/paper-plane + link: mailto:zhouge1831@gmail.com + - icon: fontawesome/brands/github + link: https://github.com/Atticuszz + - icon: fontawesome/brands/linkedin + link: https://hk.linkedin.com/in/atticus-zhou-250a88323 + + + +markdown_extensions: + ## page + # The Table of Contents extension automatically generates a table of contents from a document + - toc: + permalink: true + ## basic markdown + # attr_list + - attr_list + - markdown.extensions.codehilite: + guess_lang: true + - markdown.extensions.toc: + permalink: true + # The BetterEm extension improves the detection of Markup to emphasize text in Markdown using special characters, i.e. for **bold** and _italic_ formatting. + - pymdownx.betterem: + smart_enable: all + # list + - def_list + - pymdownx.tasklist: + custom_checkbox: true + + # highlight + - pymdownx.mark + # strikethrough + - pymdownx.tilde + # admonition setting: https://squidfunk.github.io/mkdocs-material/reference/admonitions/#inline-blocks-inline-end:~:text=Custom%20admonitions-,Admonitions,-%C2%B6 + - admonition + - pymdownx.details + # table + - tables + # footnotes + - footnotes + #code + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + # math + - pymdownx.arithmatex: + generic: true + # mermaid + # - pymdownx.superfences: + # custom_fences: + # - name: mermaid + # class: mermaid + # format: !!python/name:pymdownx.superfences.fence_code_format + # emoji + # - pymdownx.emoji: + # emoji_index: !!python/name:material.extensions.emoji.twemoji + # emoji_generator: !!python/name:material.extensions.emoji.to_svg + # Image + - md_in_html + +# math and mermaid +extra_javascript: + # - js/katex.js + # - https://unpkg.com/katex@0/dist/katex.min.js + - https://unpkg.com/katex@0/dist/contrib/auto-render.min.js + - https://unpkg.com/mermaid/dist/mermaid.min.js + +# extra_css: +# # katex.js +# - https://unpkg.com/katex@0/dist/katex.min.css From 97f1ffeb3d90db7fdb75f7eaaa1af9d71f09849f Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:10:42 +0800 Subject: [PATCH 02/65] chore(git): pre-commit upgrade to ruff --- .gitignore | 98 +++++++++++++++++++++++++++++--- .pre-commit-config.yaml | 122 ++++++++++++---------------------------- 2 files changed, 127 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index a81036e..3248dfb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,12 @@ +# Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class + +# C extensions *.so + +# Distribution / packaging .Python build/ develop-eggs/ @@ -20,8 +25,18 @@ share/python-wheels/ .installed.cfg *.egg MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs pip-log.txt pip-delete-this-directory.txt + +# Unit test / coverage reports htmlcov/ .tox/ .nox/ @@ -35,32 +50,79 @@ coverage.xml .hypothesis/ .pytest_cache/ cover/ + +# Translations *.mo *.pot -__pypackages__/ -.Trashes -.metadata_never_index -.fseventsd/ -boot_out.txt -*.manifest -*.spec + +# Django stuff: *.log local_settings.py db.sqlite3 db.sqlite3-journal + +# Flask stuff: instance/ .webassets-cache + +# Scrapy stuff: .scrapy + +# Sphinx documentation docs/_build/ + +# PyBuilder .pybuilder/ target/ + +# Jupyter Notebook .ipynb_checkpoints + +# IPython profile_default/ ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide .pdm.toml + +# UV +.ruff_cache/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff celerybeat-schedule celerybeat.pid + +# SageMath parsed files *.sage.py + +# Environments .env .venv env/ @@ -68,14 +130,34 @@ venv/ ENV/ env.bak/ venv.bak/ + +# Spyder project settings .spyderproject .spyproject + +# Rope project settings .ropeproject + +# mkdocs documentation /site + +# mypy .mypy_cache/ .dmypy.json dmypy.json + +# Pyre type checker .pyre/ + +# pytype static type analyzer .pytype/ + +# Cython debug symbols cython_debug/ -/.idea + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b98881e..1a583aa 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,98 +1,50 @@ -exclude: '^.*\.(md|MD|xml|ini|cfg|txt)$|^\.idea/' +# https://pre-commit.com/ +# `pre-commit install` to set up the git hook scripts +# `pre-commit autoupdate` to update repos +# `pre-commit run --all-files` run hooks for all file +exclude: (^|/)\..* # exclude hidden files or folder repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v5.0.0 + rev: v4.2.0 hooks: + - id: check-toml - id: check-yaml - # 检查YAML文件是否格式正确 + args: ["--unsafe"] - id: check-json - # 检查JSON文件是否格式正确 - - id: trailing-whitespace - # 删除行尾空格 - id: check-added-large-files - # 检查是否有大文件被错误地添加到git + args: ["--maxkb=51200"] + - id: debug-statements - id: end-of-file-fixer - # 确保文件以一个空行结尾 - - id: mixed-line-ending - # 统一文件的行结束符(例如,将CRLF转换为LF) - args: [ "--fix=lf" ] - + - id: trailing-whitespace + - id: detect-private-key + - id: destroyed-symlinks + - id: check-vcs-permalinks + # spell check - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: - id: codespell - files: \.(py|sh|rst|yml|yaml)$ + files: \.(py|sh|rst|yml|yaml|md)$ args: [--write-changes] - - repo: https://github.com/pycqa/isort - rev: 5.13.2 - hooks: - - id: isort - # 对Python的import语句进行排序和格式化 - args: - [ - "--profile", - "black", - "--multi-line=3", - "--trailing-comma", - "--force-grid-wrap=0", - "--use-parentheses", - "--line-width=88", - ] - - - repo: https://github.com/PyCQA/autoflake - rev: v2.3.1 - hooks: - - id: autoflake - # 移除未使用的导入和变量 - args: - [ - "--in-place", - "--remove-all-unused-imports", - "--ignore-init-module-imports", - ] - - - repo: https://github.com/asottile/pyupgrade - rev: v3.19.0 - hooks: - - id: pyupgrade - # 将Python代码升级到新版本的Python语法 - args: [ "--py310-plus" ] - - - repo: https://github.com/psf/black - rev: "24.10.0" - hooks: - - id: black - # 自动格式化Python代码,符合PEP 8风格指南 - args: [--line-length=88] - - - repo: https://github.com/commitizen-tools/commitizen - rev: v3.30.0 - hooks: - - id: commitizen - # 确保commit信息遵循Conventional Commits标准 - stages: [ commit-msg ] - - - repo: 'https://github.com/PyCQA/flake8' - rev: 7.1.1 - hooks: - - id: flake8 - args: - - '--max-line-length=88' - - '--ignore=E203,W503,F401' - language: python - types: [ python ] - - - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.13.0 - hooks: - - id: mypy - args: [ --ignore-missing-imports,--disallow-untyped-defs, --show-error-codes ] -# additional_dependencies: [ types-requests, types-setuptools ] # 如果需要额外的类型存根 - + # lint and format + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.8 + hooks: + - id: ruff + args: [ --fix ] + - id: ruff-format + # - repo: https://github.com/hadolint/hadolint + # rev: v2.12.0 + # hooks: + # - id: hadolint + # name: Lint Dockerfiles + # description: Runs hadolint to lint Dockerfiles + # language: system + # types: ["dockerfile"] + # entry: hadolint ci: - # Settings for the https://pre-commit.ci/ continuous integration service - autofix_prs: True - # Default message is more verbose - autoupdate_commit_msg: '[pre-commit.ci] autoupdate' - # Default is weekly - autoupdate_schedule: monthly + # Settings for the https://pre-commit.ci/ continuous integration service + autofix_prs: True + autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks + autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate + autoupdate_schedule: monthly From f2fc1a3331ac42b0b14b1af8eb8b1cffb2f0703b Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:14:16 +0800 Subject: [PATCH 03/65] refactor: move src/app to top level of dir as app/ --- {src/app => app}/__init__.py | 0 {src/app => app}/api/__init__.py | 0 {src/app => app}/api/api_v1/__init__.py | 0 {src/app => app}/api/api_v1/api.py | 0 {src/app => app}/api/api_v1/endpoints/__init__.py | 0 {src/app => app}/api/api_v1/endpoints/items.py | 0 {src/app => app}/api/deps.py | 5 +++-- {src/app => app}/core/__init__.py | 0 {src/app => app}/core/config.py | 2 +- {src/app => app}/core/events.py | 2 +- {src/app => app}/crud/__init__.py | 2 +- {src/app => app}/crud/base.py | 0 {src/app => app}/crud/crud_item.py | 0 {src/app => app}/main.py | 0 {src/app => app}/schemas/__init__.py | 2 ++ {src/app => app}/schemas/auth.py | 8 ++++---- {src/app => app}/schemas/base.py | 0 {src/app => app}/schemas/item.py | 0 {src/app => app}/schemas/msg.py | 0 {src/app => app}/services/__init__.py | 0 {src/app => app}/utils/__init__.py | 0 21 files changed, 12 insertions(+), 9 deletions(-) rename {src/app => app}/__init__.py (100%) rename {src/app => app}/api/__init__.py (100%) rename {src/app => app}/api/api_v1/__init__.py (100%) rename {src/app => app}/api/api_v1/api.py (100%) rename {src/app => app}/api/api_v1/endpoints/__init__.py (100%) rename {src/app => app}/api/api_v1/endpoints/items.py (100%) rename {src/app => app}/api/deps.py (93%) rename {src/app => app}/core/__init__.py (100%) rename {src/app => app}/core/config.py (96%) rename {src/app => app}/core/events.py (82%) rename {src/app => app}/crud/__init__.py (93%) rename {src/app => app}/crud/base.py (100%) rename {src/app => app}/crud/crud_item.py (100%) rename {src/app => app}/main.py (100%) rename {src/app => app}/schemas/__init__.py (56%) rename {src/app => app}/schemas/auth.py (72%) rename {src/app => app}/schemas/base.py (100%) rename {src/app => app}/schemas/item.py (100%) rename {src/app => app}/schemas/msg.py (100%) rename {src/app => app}/services/__init__.py (100%) rename {src/app => app}/utils/__init__.py (100%) diff --git a/src/app/__init__.py b/app/__init__.py similarity index 100% rename from src/app/__init__.py rename to app/__init__.py diff --git a/src/app/api/__init__.py b/app/api/__init__.py similarity index 100% rename from src/app/api/__init__.py rename to app/api/__init__.py diff --git a/src/app/api/api_v1/__init__.py b/app/api/api_v1/__init__.py similarity index 100% rename from src/app/api/api_v1/__init__.py rename to app/api/api_v1/__init__.py diff --git a/src/app/api/api_v1/api.py b/app/api/api_v1/api.py similarity index 100% rename from src/app/api/api_v1/api.py rename to app/api/api_v1/api.py diff --git a/src/app/api/api_v1/endpoints/__init__.py b/app/api/api_v1/endpoints/__init__.py similarity index 100% rename from src/app/api/api_v1/endpoints/__init__.py rename to app/api/api_v1/endpoints/__init__.py diff --git a/src/app/api/api_v1/endpoints/items.py b/app/api/api_v1/endpoints/items.py similarity index 100% rename from src/app/api/api_v1/endpoints/items.py rename to app/api/api_v1/endpoints/items.py diff --git a/src/app/api/deps.py b/app/api/deps.py similarity index 93% rename from src/app/api/deps.py rename to app/api/deps.py index e7671fb..e5e23e5 100644 --- a/src/app/api/deps.py +++ b/app/api/deps.py @@ -1,9 +1,10 @@ import logging +from collections.abc import AsyncGenerator from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer -from gotrue.errors import AuthApiError +from gotrue.errors import AuthApiError # type: ignore from supabase._async.client import AsyncClient, create_client from supabase.lib.client_options import ClientOptions @@ -48,7 +49,7 @@ async def get_current_user(access_token: AccessTokenDep) -> UserIn: CurrentUser = Annotated[UserIn, Depends(get_current_user)] -async def get_db(user: CurrentUser) -> AsyncClient: +async def get_db(user: CurrentUser) -> AsyncGenerator[AsyncClient, None]: client: AsyncClient | None = None try: client = await create_client( diff --git a/src/app/core/__init__.py b/app/core/__init__.py similarity index 100% rename from src/app/core/__init__.py rename to app/core/__init__.py diff --git a/src/app/core/config.py b/app/core/config.py similarity index 96% rename from src/app/core/config.py rename to app/core/config.py index 5697b0a..ba5d4e6 100644 --- a/src/app/core/config.py +++ b/app/core/config.py @@ -28,7 +28,7 @@ class Settings(BaseSettings): SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv("SUPERUSER_EMAIL")) SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv("SUPERUSER_PASSWORD")) # SERVER_NAME: str - SERVER_HOST: AnyHttpUrl = "https://localhost" + SERVER_HOST: AnyHttpUrl = AnyHttpUrl("https://localhost") SERVER_PORT: int = 8000 # # TODO: the following need to follow the newest version of fastapi # # BACKEND_CORS_ORIGINS is a JSON-formatted list of origins diff --git a/src/app/core/events.py b/app/core/events.py similarity index 82% rename from src/app/core/events.py rename to app/core/events.py index decb802..f84c46f 100644 --- a/src/app/core/events.py +++ b/app/core/events.py @@ -12,7 +12,7 @@ @asynccontextmanager -async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: +async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 """life span events""" try: await init_super_client() diff --git a/src/app/crud/__init__.py b/app/crud/__init__.py similarity index 93% rename from src/app/crud/__init__.py rename to app/crud/__init__.py index 8dd20e1..b74e2ba 100644 --- a/src/app/crud/__init__.py +++ b/app/crud/__init__.py @@ -1,7 +1,7 @@ from .crud_item import item # For a new basic set of CRUD operations you could just do - +__all__ = ["item"] # from .base import CRUDBase # from app.models.item import Item # from app.schemas.item import ItemCreate, ItemUpdate diff --git a/src/app/crud/base.py b/app/crud/base.py similarity index 100% rename from src/app/crud/base.py rename to app/crud/base.py diff --git a/src/app/crud/crud_item.py b/app/crud/crud_item.py similarity index 100% rename from src/app/crud/crud_item.py rename to app/crud/crud_item.py diff --git a/src/app/main.py b/app/main.py similarity index 100% rename from src/app/main.py rename to app/main.py diff --git a/src/app/schemas/__init__.py b/app/schemas/__init__.py similarity index 56% rename from src/app/schemas/__init__.py rename to app/schemas/__init__.py index 182716d..a4d5f94 100644 --- a/src/app/schemas/__init__.py +++ b/app/schemas/__init__.py @@ -1,3 +1,5 @@ from .auth import Token from .item import Item, ItemCreate, ItemInDB, ItemUpdate from .msg import Massage + +__all__ = ["Token", "Item", "ItemCreate", "ItemInDB", "ItemUpdate", "Massage"] diff --git a/src/app/schemas/auth.py b/app/schemas/auth.py similarity index 72% rename from src/app/schemas/auth.py rename to app/schemas/auth.py index aece823..c076809 100644 --- a/src/app/schemas/auth.py +++ b/app/schemas/auth.py @@ -1,4 +1,4 @@ -from gotrue import User, UserAttributes +from gotrue import User, UserAttributes # type: ignore from pydantic import BaseModel @@ -9,7 +9,7 @@ class Token(BaseModel): # request -class UserIn(Token, User): +class UserIn(Token, User): # type: ignore pass @@ -21,7 +21,7 @@ class UserCreate(BaseModel): # Properties to receive via API on update # in -class UserUpdate(UserAttributes): +class UserUpdate(UserAttributes): # type: ignore pass @@ -39,5 +39,5 @@ class UserOut(Token): # Properties properties stored in DB -class UserInDB(User): +class UserInDB(User): # type: ignore pass diff --git a/src/app/schemas/base.py b/app/schemas/base.py similarity index 100% rename from src/app/schemas/base.py rename to app/schemas/base.py diff --git a/src/app/schemas/item.py b/app/schemas/item.py similarity index 100% rename from src/app/schemas/item.py rename to app/schemas/item.py diff --git a/src/app/schemas/msg.py b/app/schemas/msg.py similarity index 100% rename from src/app/schemas/msg.py rename to app/schemas/msg.py diff --git a/src/app/services/__init__.py b/app/services/__init__.py similarity index 100% rename from src/app/services/__init__.py rename to app/services/__init__.py diff --git a/src/app/utils/__init__.py b/app/utils/__init__.py similarity index 100% rename from src/app/utils/__init__.py rename to app/utils/__init__.py From d676a13c243ecafa94b8f5c7be2fb9bafbb2b6d0 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:15:14 +0800 Subject: [PATCH 04/65] docs: add docs dir for mkdocs --- README.md | 10 +- docs/README.md | 168 ++++++++++++++++++ .../fastapi-supabase-template-for-llm.png | Bin {assets => docs/assets}/img.png | Bin {assets => docs/assets}/logo.png | Bin {assets => docs/assets}/supafast.drawio.png | Bin {assets => docs/assets}/usage.gif | Bin 7 files changed, 173 insertions(+), 5 deletions(-) create mode 100644 docs/README.md rename {assets => docs/assets}/fastapi-supabase-template-for-llm.png (100%) rename {assets => docs/assets}/img.png (100%) rename {assets => docs/assets}/logo.png (100%) rename {assets => docs/assets}/supafast.drawio.png (100%) rename {assets => docs/assets}/usage.gif (100%) diff --git a/README.md b/README.md index 63f4eec..e6a5d99 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- Logo + Logo

@@ -26,7 +26,7 @@ ___ > supabase & fastapi crud template -![supafast.drawio.png](assets%2Fsupafast.drawio.png) +![supafast.drawio.png](docs/assets/supafast.drawio.png) ## Features 🚀 @@ -57,11 +57,11 @@ ___ ## How to use it ___ -![](assets/usage.gif) +![](docs/assets/usage.gif) 1. create your github repo and config it 1. allow ci to access your repo - ![img.png](assets/img.png) + ![img.png](docs/assets/img.png) 2. config ci_tokens 1. `CODECOV_TOKEN` for codecov in `.github/workflows/ci.yml` ,`semantic-release` is optional for auto release 2. `ATTICUS_PAT`should replace with your GitHub token for latest_changes.yml in `.github/workflows/latest_changes.yml` @@ -73,7 +73,7 @@ ___ 2. cd your repo and install dependencies with [uv](https://github.com/astral-sh/uv), which is an extremely fast Python package and project manager, written in Rust. ```shell -uv sync --all-extras --dev +uv sync ``` 3. set your supabase env diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..e6a5d99 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,168 @@ +

+ Logo +

+ +

+ + License: MIT + + + codecov + + + CI + + + GitHub release + + Python + + Made with Supabase + +

+ +# ⚡SupaFast⚡ + +___ +> supabase & fastapi crud template + +![supafast.drawio.png](docs/assets/supafast.drawio.png) + +## Features 🚀 + +___ + +### FastAPI&supabase + +1. works of authorization all handled by supabase-py and fastapi **dependency** without any extra code +2. supabase-py crud integration with **pydantic** model validation + +### Pytest + +1. pytest integration with **pytest-cov** +2. pytest **fixtures** for fastapi client and supabase client +3. pytest **fixtures** for access_token and refresh_token +4. test for **CRUD** operations +5. test for **api** operations + +### CI/CD + +1. **codecov** for coverage report +2. **poetry** for dependency management and pytest integration +3. **pre-commit** for code quality +4. **latest_changes.yml** for auto update README.md +5. **Semantic Release** for auto release and changelog +6. **docker** for deployment + +## How to use it + +___ +![](docs/assets/usage.gif) + +1. create your github repo and config it + 1. allow ci to access your repo + ![img.png](docs/assets/img.png) + 2. config ci_tokens + 1. `CODECOV_TOKEN` for codecov in `.github/workflows/ci.yml` ,`semantic-release` is optional for auto release + 2. `ATTICUS_PAT`should replace with your GitHub token for latest_changes.yml in `.github/workflows/latest_changes.yml` + 3. `DOCKER_USERNAME` and `DOCKER_PASSWORD` for docker-image.yml in `.github/workflows/docker-image.yml` + 4. replace `tags: atticuszhou/supafast:latest` with your docker repo in `.github/workflows/docker-image.yml` + 3. config fastapi setting in `your_project\src\app\core\config.py` + 4. config `pyproject.toml` with your project name and description,etc + +2. cd your repo and install dependencies with [uv](https://github.com/astral-sh/uv), which is an extremely fast Python package and project manager, written in Rust. + +```shell +uv sync +``` +3. set your supabase env + +```shell +export SUPABASE_URL=your_supabase_url +export SUPABASE_KEY=your_supabase_key +export SUPERUSER_EMAIL=your_superuser_email +export SUPERUSER_PASSWORD=your_superuser_password +``` +4. config fastapi settings +```python +# src/app/core/config.py +class Settings(BaseSettings): + API_V1_STR: str = "/api/v1" + SUPABASE_URL: str = Field(default_factory=lambda: os.getenv("SUPABASE_URL")) + SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv("SUPABASE_KEY")) + SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv("SUPERUSER_EMAIL")) + SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv("SUPERUSER_PASSWORD")) + # SERVER_NAME: str + SERVER_HOST: AnyHttpUrl = "https://localhost" + SERVER_PORT: int = 8000 + BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = [] + PROJECT_NAME: str = "fastapi supabase template" + Config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) +``` + +5. run server +```shell +uv run uvicorn src.app.main:app --reload +``` + +## Roadmap 🫶 +___ + +- [x] FastAPI backend + - [x] **standard** structure + for **FastAPI** project + ```text + ── src + │ └── app + │ ├── api + │ │ ├── api_v1 + │ │ │ ├── endpoints + │ │ │ │ ├── __init__.py + │ │ │ │ └── items.py + │ │ │ ├── __init__.py + │ │ │ └── api.py + │ │ ├── __init__.py + │ │ └── deps.py + │ ├── core + │ │ ├── __init__.py + │ │ ├── config.py + │ │ └── events.py + │ ├── crud + │ │ ├── __init__.py + │ │ ├── base.py + │ │ └── crud_item.py + │ ├── schemas + │ │ ├── __init__.py + │ │ ├── auth.py + │ │ ├── base.py + │ │ ├── item.py + │ │ └── msg.py + │ ├── services + │ │ └── __init__.py + │ ├── utils + │ │ └── __init__.py + │ ├── __init__.py + │ └── main.py + ... + ``` + - [x] **auto-auth** by fastapi dependency with supabase-auth + - [x] **CRUD** operations pytest + - [x] **api** requests pytest +- [ ] Supabase integration + - [x] crud supabase-postgresql + - [ ] websocket with supabase-realtime + - [ ] curd supabase-storage + - [ ] supafunc integration +- [x] deployment + - [x] Full **Docker** integration (Docker based). +- [ ] clone + - [ ] cookiecutter +## Release Notes 🥸 + +___ + +### Latest Changes + +## License + +This project is licensed under the terms of the MIT license. diff --git a/assets/fastapi-supabase-template-for-llm.png b/docs/assets/fastapi-supabase-template-for-llm.png similarity index 100% rename from assets/fastapi-supabase-template-for-llm.png rename to docs/assets/fastapi-supabase-template-for-llm.png diff --git a/assets/img.png b/docs/assets/img.png similarity index 100% rename from assets/img.png rename to docs/assets/img.png diff --git a/assets/logo.png b/docs/assets/logo.png similarity index 100% rename from assets/logo.png rename to docs/assets/logo.png diff --git a/assets/supafast.drawio.png b/docs/assets/supafast.drawio.png similarity index 100% rename from assets/supafast.drawio.png rename to docs/assets/supafast.drawio.png diff --git a/assets/usage.gif b/docs/assets/usage.gif similarity index 100% rename from assets/usage.gif rename to docs/assets/usage.gif From 0054c9a0523d92c66eb2007dc697b66ce923cb5f Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:17:43 +0800 Subject: [PATCH 05/65] chore: add scripts for test and lint etc. --- scripts/bump.sh | 8 ++++++++ scripts/format.sh | 5 +++++ scripts/lint.sh | 8 ++++++++ scripts/test.sh | 8 ++++++++ 4 files changed, 29 insertions(+) create mode 100755 scripts/bump.sh create mode 100755 scripts/format.sh create mode 100755 scripts/lint.sh create mode 100755 scripts/test.sh diff --git a/scripts/bump.sh b/scripts/bump.sh new file mode 100755 index 0000000..6ec275b --- /dev/null +++ b/scripts/bump.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +# update CHANGELOG.md use GITHUB_REPO ENV as github token +git-cliff -o -v --github-repo "atticuszz/python-uv" +# bump version and commit with tags +bump-my-version bump patch +# push remote +git push origin main --tags diff --git a/scripts/format.sh b/scripts/format.sh new file mode 100755 index 0000000..7be2f81 --- /dev/null +++ b/scripts/format.sh @@ -0,0 +1,5 @@ +#!/bin/sh -e +set -x + +ruff check app scripts --fix +ruff format app scripts diff --git a/scripts/lint.sh b/scripts/lint.sh new file mode 100755 index 0000000..1be0606 --- /dev/null +++ b/scripts/lint.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e +set -x + +mypy app # type check +ruff check app # linter +ruff format app --check # formatter diff --git a/scripts/test.sh b/scripts/test.sh new file mode 100755 index 0000000..97c2033 --- /dev/null +++ b/scripts/test.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e +set -x + +coverage run --source=src -m pytest +coverage report --show-missing +coverage html --title "${@-coverage}" From 9f6ca19274c3f3af397c47a5bb0ef53850c19c1d Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:18:17 +0800 Subject: [PATCH 06/65] fix: lint error --- tests/api/api_v1/test_items.py | 46 +++++++++------------------------- tests/conftest.py | 11 +++----- tests/crud/test_item.py | 5 ++-- 3 files changed, 17 insertions(+), 45 deletions(-) diff --git a/tests/api/api_v1/test_items.py b/tests/api/api_v1/test_items.py index 20cebb2..e7b0f7c 100644 --- a/tests/api/api_v1/test_items.py +++ b/tests/api/api_v1/test_items.py @@ -1,10 +1,10 @@ # Additional assertions based on your application's logic import pytest +from app.schemas import Token from faker import Faker from starlette.testclient import TestClient from supabase._async.client import AsyncClient -from app.schemas import Token from tests.utils import get_auth_header @@ -17,9 +17,7 @@ async def test_create_item(client: TestClient, token: Token) -> None: # 发送请求,同时设置cookie response = client.post( - "/api/v1/items/create-item", - headers=headers, - json={"test_data": test_data}, + "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) assert response.status_code == 200 assert response.json()["test_data"] == test_data @@ -29,10 +27,7 @@ async def test_create_item(client: TestClient, token: Token) -> None: async def test_read_all_items(client: TestClient, token: Token) -> None: headers = get_auth_header(token.access_token) - response = client.get( - "/api/v1/items/read-all-item", - headers=headers, - ) + response = client.get("/api/v1/items/read-all-item", headers=headers) assert response.status_code == 200 assert isinstance(response.json(), list) @@ -44,17 +39,14 @@ async def test_read_item_by_id(client: TestClient, token: Token) -> None: # 创建条目 create_response = client.post( - "/api/v1/items/create-item", - headers=headers, - json={"test_data": test_data}, + "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) assert create_response.status_code == 200 created_item_id = create_response.json()["id"] # 按ID读取条目 read_response = client.get( - f"/api/v1/items/get-by-id/{created_item_id}", - headers=headers, + f"/api/v1/items/get-by-id/{created_item_id}", headers=headers ) assert read_response.status_code == 200 assert read_response.json()["id"] == created_item_id @@ -69,18 +61,13 @@ async def test_read_item_by_owner( test_data = Faker().sentence() client.post( - "/api/v1/items/create-item", - headers=headers, - json={"test_data": test_data}, + "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) user = await db.auth.get_user(jwt=token.access_token) user_id = user.user.id - read_response = client.get( - "/api/v1/items/get-by-owner", - headers=headers, - ) + read_response = client.get("/api/v1/items/get-by-owner", headers=headers) assert read_response.status_code == 200 items = read_response.json() assert isinstance(items, list) @@ -93,9 +80,7 @@ async def test_update_item(client: TestClient, token: Token) -> None: headers = get_auth_header(token.access_token) test_data = Faker().sentence() create_response = client.post( - "/api/v1/items/create-item", - headers=headers, - json={"test_data": test_data}, + "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) assert create_response.status_code == 200 created_item = create_response.json() @@ -105,9 +90,7 @@ async def test_update_item(client: TestClient, token: Token) -> None: updated_data = {"test_data": Faker().sentence(), "id": created_item_id} update_response = client.put( - "/api/v1/items/update-item", - headers=headers, - json=updated_data, + "/api/v1/items/update-item", headers=headers, json=updated_data ) assert update_response.status_code == 200 assert update_response.json()["test_data"] == updated_data["test_data"] @@ -115,26 +98,21 @@ async def test_update_item(client: TestClient, token: Token) -> None: @pytest.mark.anyio async def test_delete_item(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) test_data = Faker().sentence() create_response = client.post( - "/api/v1/items/create-item", - headers=headers, - json={"test_data": test_data}, + "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) assert create_response.status_code == 200 created_item_id = create_response.json()["id"] delete_response = client.delete( - f"/api/v1/items/delete/{created_item_id}", - headers=headers, + f"/api/v1/items/delete/{created_item_id}", headers=headers ) assert delete_response.status_code == 200 get_response = client.get( - f"/api/v1/items/get-by-id/{created_item_id}", - headers=headers, + f"/api/v1/items/get-by-id/{created_item_id}", headers=headers ) assert get_response.status_code == 200 assert get_response.json() is None diff --git a/tests/conftest.py b/tests/conftest.py index 4a92b9c..608f95b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -48,7 +48,7 @@ def anyio_backend() -> str: return "asyncio" -def pytest_configure(config: ConfigDict) -> None: +def pytest_configure(config: ConfigDict) -> None: # noqa ARG001 load_dotenv() @@ -74,9 +74,7 @@ async def token() -> AsyncGenerator[Token, None]: assert response.user.id is not None assert response.session.access_token is not None - yield Token( - access_token=response.session.access_token, - ) + yield Token(access_token=response.session.access_token) @pytest.fixture(scope="module") @@ -103,9 +101,6 @@ async def db() -> AsyncGenerator[AsyncClient, None]: async def test_read_all_items(client: TestClient, token: Token) -> None: headers = get_auth_header(token.access_token) - response = client.get( - "/api/v1/items/read-all-item", - headers=headers, - ) + response = client.get("/api/v1/items/read-all-item", headers=headers) assert response.status_code == 200 assert isinstance(response.json(), list) diff --git a/tests/crud/test_item.py b/tests/crud/test_item.py index 8a2a5c0..0f1ef0d 100644 --- a/tests/crud/test_item.py +++ b/tests/crud/test_item.py @@ -1,9 +1,8 @@ import pytest -from faker import Faker -from supabase._async.client import AsyncClient - from app import crud from app.schemas.item import Item, ItemCreate, ItemUpdate +from faker import Faker +from supabase._async.client import AsyncClient @pytest.mark.anyio From 7c351cc0f01bc35d55b8be7217413abb7316126e Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:18:51 +0800 Subject: [PATCH 07/65] chore(deps): upgrade pyproject.toml --- .coveragerc | 5 - .github/workflows/ci.yml | 66 - .vscode/PythonImportHelper-v2-Completion.json | 323 ++- CHANGELOG.md | 2017 +---------------- pyproject.toml | 242 +- scripts.py | 23 - uv.lock | 966 ++++---- 7 files changed, 1027 insertions(+), 2615 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .github/workflows/ci.yml delete mode 100644 scripts.py diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index dde2e41..0000000 --- a/.coveragerc +++ /dev/null @@ -1,5 +0,0 @@ -[run] -omit = - docs/* - examples/* - tests/* diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index e380092..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,66 +0,0 @@ -name: CI/CD - -on: - push: - branches: - - main - pull_request: - branches: - - main - workflow_dispatch: - -jobs: - test: - name: Run Tests / OS ${{ matrix.os }} / Python ${{ matrix.python-version }} - strategy: - matrix: - os: [ ubuntu-latest ] - python-version: [ "3.10", "3.11", "3.12"] - runs-on: ${{ matrix.os }} - steps: - - uses: actions/checkout@v4 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - - name: Install dependencies with uv - run: | - # Install latest uv version using the installer - curl -LsSf https://astral.sh/uv/install.sh | sh - uv sync --all-extras --dev - - - name: Run tests - run: uv run scripts.py - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - semantic-release: - name: Semantic Release and Publish - runs-on: ubuntu-latest - needs: test - if: github.ref == 'refs/heads/main' && (github.event_name == 'push' || github.event.pull_request.merged == true) - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 - token: ${{ secrets.ATTICUS_PAT }} - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - name: Install dependencies with uv - run: | - # Install latest uv version using the installer - curl -LsSf https://astral.sh/uv/install.sh | sh - uv sync --all-extras --dev - - - name: Pull latest changes - run: git pull origin main - - name: Python Semantic Release - uses: python-semantic-release/python-semantic-release@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json index e5d469a..1f4fa7e 100644 --- a/.vscode/PythonImportHelper-v2-Completion.json +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -212,6 +212,38 @@ "detail": "logging", "documentation": {} }, + { + "label": "AsyncGenerator", + "importPath": "collections.abc", + "description": "collections.abc", + "isExtraImport": true, + "detail": "collections.abc", + "documentation": {} + }, + { + "label": "AsyncGenerator", + "importPath": "collections.abc", + "description": "collections.abc", + "isExtraImport": true, + "detail": "collections.abc", + "documentation": {} + }, + { + "label": "AsyncGenerator", + "importPath": "collections.abc", + "description": "collections.abc", + "isExtraImport": true, + "detail": "collections.abc", + "documentation": {} + }, + { + "label": "Generator", + "importPath": "collections.abc", + "description": "collections.abc", + "isExtraImport": true, + "detail": "collections.abc", + "documentation": {} + }, { "label": "Annotated", "importPath": "typing", @@ -476,30 +508,6 @@ "detail": "pydantic_settings", "documentation": {} }, - { - "label": "AsyncGenerator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "AsyncGenerator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "Generator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, { "label": "asynccontextmanager", "importPath": "contextlib", @@ -742,15 +750,6 @@ "detail": "app.main", "documentation": {} }, - { - "label": "subprocess", - "kind": 6, - "isExtraImport": true, - "importPath": "subprocess", - "description": "subprocess", - "detail": "subprocess", - "documentation": {} - }, { "label": "bin_dir", "kind": 5, @@ -835,325 +834,325 @@ { "label": "router", "kind": 5, - "importPath": "src.app.api.api_v1.endpoints.items", - "description": "src.app.api.api_v1.endpoints.items", + "importPath": "app.api.api_v1.endpoints.items", + "description": "app.api.api_v1.endpoints.items", "peekOfCode": "router = APIRouter()\n@router.post(\"/create-item\")\nasync def create_item(item_in: ItemCreate, session: SessionDep) -> Item:\n return await item.create(session, obj_in=item_in)\n@router.get(\"/read-all-item\")\nasync def read_items(session: SessionDep) -> list[Item]:\n return await item.get_all(session)\n@router.get(\"/get-by-id/{id}\")\nasync def read_item_by_id(id: str, session: SessionDep) -> Item | None:\n return await item.get(session, id=id)", - "detail": "src.app.api.api_v1.endpoints.items", + "detail": "app.api.api_v1.endpoints.items", "documentation": {} }, { "label": "api_router", "kind": 5, - "importPath": "src.app.api.api_v1.api", - "description": "src.app.api.api_v1.api", + "importPath": "app.api.api_v1.api", + "description": "app.api.api_v1.api", "peekOfCode": "api_router = APIRouter()\napi_router.include_router(items.router, prefix=\"/items\", tags=[\"items\"])", - "detail": "src.app.api.api_v1.api", + "detail": "app.api.api_v1.api", "documentation": {} }, { "label": "reusable_oauth2", "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", + "importPath": "app.api.deps", + "description": "app.api.deps", "peekOfCode": "reusable_oauth2 = OAuth2PasswordBearer(\n tokenUrl=\"please login by supabase-js to get token\"\n)\nAccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:", - "detail": "src.app.api.deps", + "detail": "app.api.deps", "documentation": {} }, { "label": "AccessTokenDep", "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", + "importPath": "app.api.deps", + "description": "app.api.deps", "peekOfCode": "AccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:\n logging.error(\"User not found\")\n raise HTTPException(status_code=404, detail=\"User not found\")\n return UserIn(**user_rsp.user.model_dump(), access_token=access_token)", - "detail": "src.app.api.deps", + "detail": "app.api.deps", "documentation": {} }, { "label": "CurrentUser", "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", - "peekOfCode": "CurrentUser = Annotated[UserIn, Depends(get_current_user)]\nasync def get_db(user: CurrentUser) -> AsyncClient:\n client: AsyncClient | None = None\n try:\n client = await create_client(\n settings.SUPABASE_URL,\n settings.SUPABASE_KEY,\n options=ClientOptions(\n postgrest_client_timeout=30,\n storage_client_timeout=30,", - "detail": "src.app.api.deps", + "importPath": "app.api.deps", + "description": "app.api.deps", + "peekOfCode": "CurrentUser = Annotated[UserIn, Depends(get_current_user)]\nasync def get_db(user: CurrentUser) -> AsyncGenerator[AsyncClient, None]:\n client: AsyncClient | None = None\n try:\n client = await create_client(\n settings.SUPABASE_URL,\n settings.SUPABASE_KEY,\n options=ClientOptions(\n postgrest_client_timeout=30,\n storage_client_timeout=30,", + "detail": "app.api.deps", "documentation": {} }, { "label": "SessionDep", "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", + "importPath": "app.api.deps", + "description": "app.api.deps", "peekOfCode": "SessionDep = Annotated[AsyncClient, Depends(get_db)]", - "detail": "src.app.api.deps", + "detail": "app.api.deps", "documentation": {} }, { "label": "Settings", "kind": 6, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "class Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = \"https://localhost\"\n SERVER_PORT: int = 8000\n # # TODO: the following need to follow the newest version of fastapi", - "detail": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", + "peekOfCode": "class Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")\n SERVER_PORT: int = 8000\n # # TODO: the following need to follow the newest version of fastapi", + "detail": "app.core.config", "documentation": {} }, { "label": "log_format", "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", "peekOfCode": "log_format = logging.Formatter(\"%(asctime)s : %(levelname)s - %(message)s\")\n# root logger\nroot_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()", - "detail": "src.app.core.config", + "detail": "app.core.config", "documentation": {} }, { "label": "root_logger", "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", "peekOfCode": "root_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"", - "detail": "src.app.core.config", + "detail": "app.core.config", "documentation": {} }, { "label": "stream_handler", "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", "peekOfCode": "stream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))", - "detail": "src.app.core.config", + "detail": "app.core.config", "documentation": {} }, { "label": "logger", "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "logger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = \"https://localhost\"", - "detail": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", + "peekOfCode": "logger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")", + "detail": "app.core.config", "documentation": {} }, { "label": "settings", "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", + "importPath": "app.core.config", + "description": "app.core.config", "peekOfCode": "settings = Settings()", - "detail": "src.app.core.config", + "detail": "app.core.config", "documentation": {} }, { "label": "CRUDBase", "kind": 6, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", + "importPath": "app.crud.base", + "description": "app.crud.base", "peekOfCode": "class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data\n return self.model(**got[0]) if got else None", - "detail": "src.app.crud.base", + "detail": "app.crud.base", "documentation": {} }, { "label": "ModelType", "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", + "importPath": "app.crud.base", + "description": "app.crud.base", "peekOfCode": "ModelType = TypeVar(\"ModelType\", bound=ResponseBase)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()", - "detail": "src.app.crud.base", + "detail": "app.crud.base", "documentation": {} }, { "label": "CreateSchemaType", "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", + "importPath": "app.crud.base", + "description": "app.crud.base", "peekOfCode": "CreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )", - "detail": "src.app.crud.base", + "detail": "app.crud.base", "documentation": {} }, { "label": "UpdateSchemaType", "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", + "importPath": "app.crud.base", + "description": "app.crud.base", "peekOfCode": "UpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data", - "detail": "src.app.crud.base", + "detail": "app.crud.base", "documentation": {} }, { "label": "CRUDItem", "kind": 6, - "importPath": "src.app.crud.crud_item", - "description": "src.app.crud.crud_item", + "importPath": "app.crud.crud_item", + "description": "app.crud.crud_item", "peekOfCode": "class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]):\n async def create(self, db: AsyncClient, *, obj_in: ItemCreate) -> Item:\n return await super().create(db, obj_in=obj_in)\n async def get(self, db: AsyncClient, *, id: str) -> Item | None:\n return await super().get(db, id=id)\n async def get_all(self, db: AsyncClient) -> list[Item]:\n return await super().get_all(db)\n async def get_multi_by_owner(self, db: AsyncClient, *, user: UserIn) -> list[Item]:\n return await super().get_multi_by_owner(db, user=user)\n async def update(self, db: AsyncClient, *, obj_in: ItemUpdate) -> Item:", - "detail": "src.app.crud.crud_item", + "detail": "app.crud.crud_item", "documentation": {} }, { "label": "item", "kind": 5, - "importPath": "src.app.crud.crud_item", - "description": "src.app.crud.crud_item", + "importPath": "app.crud.crud_item", + "description": "app.crud.crud_item", "peekOfCode": "item = CRUDItem(Item)", - "detail": "src.app.crud.crud_item", + "detail": "app.crud.crud_item", "documentation": {} }, { "label": "Token", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class Token(BaseModel):\n access_token: str | None = None\n refresh_token: str | None = None\n# request\nclass UserIn(Token, User):\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class Token(BaseModel):\n access_token: str | None = None\n refresh_token: str | None = None\n# request\nclass UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserIn", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserIn(Token, User):\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes):\n pass", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserCreate", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes):\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserUpdate", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserUpdate(UserAttributes):\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserInDBBase", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User):\n pass", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserOut", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User):\n pass", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "UserInDB", "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserInDB(User):\n pass", - "detail": "src.app.schemas.auth", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "peekOfCode": "class UserInDB(User): # type: ignore\n pass", + "detail": "app.schemas.auth", "documentation": {} }, { "label": "CreateBase", "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", + "importPath": "app.schemas.base", + "description": "app.schemas.base", "peekOfCode": "class CreateBase(BaseModel):\n # inherent to add more properties for creating\n pass\n# Properties to receive on item update\n# in\nclass UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB", - "detail": "src.app.schemas.base", + "detail": "app.schemas.base", "documentation": {} }, { "label": "UpdateBase", "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", + "importPath": "app.schemas.base", + "description": "app.schemas.base", "peekOfCode": "class UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB\nclass InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client", - "detail": "src.app.schemas.base", + "detail": "app.schemas.base", "documentation": {} }, { "label": "InDBBase", "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", + "importPath": "app.schemas.base", + "description": "app.schemas.base", "peekOfCode": "class InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client\n# curd model\n# out\nclass ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()", - "detail": "src.app.schemas.base", + "detail": "app.schemas.base", "documentation": {} }, { "label": "ResponseBase", "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", + "importPath": "app.schemas.base", + "description": "app.schemas.base", "peekOfCode": "class ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()\n Config: ClassVar[ConfigDict] = ConfigDict(\n extra=\"ignore\", arbitrary_types_allowed=True\n )", - "detail": "src.app.schemas.base", + "detail": "app.schemas.base", "documentation": {} }, { "label": "ItemCreate", "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", + "importPath": "app.schemas.item", + "description": "app.schemas.item", "peekOfCode": "class ItemCreate(CreateBase):\n test_data: str\n# Properties to receive on item update\n# in\nclass ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):", - "detail": "src.app.schemas.item", + "detail": "app.schemas.item", "documentation": {} }, { "label": "ItemUpdate", "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", + "importPath": "app.schemas.item", + "description": "app.schemas.item", "peekOfCode": "class ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):", - "detail": "src.app.schemas.item", + "detail": "app.schemas.item", "documentation": {} }, { "label": "Item", "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", + "importPath": "app.schemas.item", + "description": "app.schemas.item", "peekOfCode": "class Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):\n test_data: str", - "detail": "src.app.schemas.item", + "detail": "app.schemas.item", "documentation": {} }, { "label": "ItemInDB", "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", + "importPath": "app.schemas.item", + "description": "app.schemas.item", "peekOfCode": "class ItemInDB(InDBBase):\n test_data: str", - "detail": "src.app.schemas.item", + "detail": "app.schemas.item", "documentation": {} }, { "label": "Massage", "kind": 6, - "importPath": "src.app.schemas.msg", - "description": "src.app.schemas.msg", + "importPath": "app.schemas.msg", + "description": "app.schemas.msg", "peekOfCode": "class Massage(BaseModel):\n msg: str", - "detail": "src.app.schemas.msg", + "detail": "app.schemas.msg", "documentation": {} }, { "label": "create_app", "kind": 2, - "importPath": "src.app.main", - "description": "src.app.main", + "importPath": "app.main", + "description": "app.main", "peekOfCode": "def create_app() -> FastAPI:\n # init FastAPI with lifespan\n app = FastAPI(\n lifespan=lifespan,\n title=settings.PROJECT_NAME,\n openapi_url=f\"{settings.API_V1_STR}/openapi.json\",\n generate_unique_id_function=lambda router: f\"{router.tags[0]}-{router.name}\",\n )\n # set CORS\n # Set all CORS enabled origins", - "detail": "src.app.main", + "detail": "app.main", "documentation": {} }, { "label": "app", "kind": 5, - "importPath": "src.app.main", - "description": "src.app.main", + "importPath": "app.main", + "description": "app.main", "peekOfCode": "app = create_app()\nif __name__ == \"__main__\":\n host = \"localhost\"\n port = 5000\n uvicorn.run(app, host=host, port=port)", - "detail": "src.app.main", + "detail": "app.main", "documentation": {} }, { @@ -1170,7 +1169,7 @@ "kind": 2, "importPath": "tests.conftest", "description": "tests.conftest", - "peekOfCode": "def anyio_backend() -> str:\n return \"asyncio\"\ndef pytest_configure(config: ConfigDict) -> None:\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:", + "peekOfCode": "def anyio_backend() -> str:\n return \"asyncio\"\ndef pytest_configure(config: ConfigDict) -> None: # noqa ARG001\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:", "detail": "tests.conftest", "documentation": {} }, @@ -1179,7 +1178,7 @@ "kind": 2, "importPath": "tests.conftest", "description": "tests.conftest", - "peekOfCode": "def pytest_configure(config: ConfigDict) -> None:\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:\n url = os.environ.get(\"SUPABASE_TEST_URL\")\n assert url is not None, \"Must provide SUPABASE_TEST_URL environment variable\"", + "peekOfCode": "def pytest_configure(config: ConfigDict) -> None: # noqa ARG001\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:\n url = os.environ.get(\"SUPABASE_TEST_URL\")\n assert url is not None, \"Must provide SUPABASE_TEST_URL environment variable\"", "detail": "tests.conftest", "documentation": {} }, @@ -1209,23 +1208,5 @@ "peekOfCode": "def get_auth_header(access_token: str | None) -> dict[str, str]:\n if not access_token:\n raise HTTPException(status_code=401, detail=\"No access token\")\n return {\"Authorization\": f\"Bearer {access_token}\"}", "detail": "tests.utils", "documentation": {} - }, - { - "label": "run_cmd", - "kind": 2, - "importPath": "scripts", - "description": "scripts", - "peekOfCode": "def run_cmd(cmd: str) -> None:\n subprocess.run(cmd, shell=True, check=True)\ndef run_tests() -> None:\n # Install requirements by poetry\n run_cmd(\"uv sync --all-extras --dev\")\n # Run pre-commit tests\n # run_cmd(\"poetry run pre-commit autoupdate\")\n # run_cmd(\"poetry run pre-commit clean\")\n # run_cmd(\"poetry run pre-commit install\")\n run_cmd(\"uv run pre-commit run --all-files\")", - "detail": "scripts", - "documentation": {} - }, - { - "label": "run_tests", - "kind": 2, - "importPath": "scripts", - "description": "scripts", - "peekOfCode": "def run_tests() -> None:\n # Install requirements by poetry\n run_cmd(\"uv sync --all-extras --dev\")\n # Run pre-commit tests\n # run_cmd(\"poetry run pre-commit autoupdate\")\n # run_cmd(\"poetry run pre-commit clean\")\n # run_cmd(\"poetry run pre-commit install\")\n run_cmd(\"uv run pre-commit run --all-files\")\n # Generate coverage report --cov=./ --cov-report=xml --cov-report=html -vv\n run_cmd(\"uv run pytest --cov=./ --cov-report=xml --cov-report=html -vv\")", - "detail": "scripts", - "documentation": {} } ] \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a67f031..62b11da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,1997 +1,138 @@ -# CHANGELOG +# Changelog -## v0.4.1 (2024-09-18) +All notable changes to this project will be documented in this file. -### Chore +## unreleased -* chore: remove ci ([`ff95b88`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ff95b88472158cf6f0133207ba904a4df0fd5e52)) +### 🐛 Bug Fixes -* chore: update README.md ([`7844c99`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7844c990fa58c846f29e71e83e1972d41e80346b)) +- Lint error -### Fix +### 🚜 Refactor -* fix: Merge pull request #139 from Atticuszz/work-with-supabase-py +- Move src/app to top level of dir as app/ -fix: remove supabase-py-async with supabase-py ([`4864352`](https://github.com/Atticuszz/fastapi_supabase_template/commit/48643527cd753128bf7dd3e552f07f09635a6e99)) +### 📚 Documentation -* fix: remove supabase-py-async with supabase-py ([`a9bdc3a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a9bdc3a7df2c992b653b1398f7296e8b5f5c673b)) +- Add docs dir for mkdocs -* fix: remove supabase-py-async with supabase-py ([`e4db077`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e4db077b211b93dbd9c532f55681132a645eb646)) +### ⚙️ Miscellaneous Tasks -### Unknown +- Vscode import +- Remove semantic-release and add mkdocs build +- *(git)* Pre-commit upgrade to ruff +- Add scripts for test and lint etc. -* [pre-commit.ci] auto fixes from pre-commit.com hooks +## 0.4.1 - 2024-09-18 -for more information, see https://pre-commit.ci ([`a0c0143`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a0c01438fad3c87bcebaa5aefed0dc2130379759)) +### 🐛 Bug Fixes -* pre-commit ([`508c1ff`](https://github.com/Atticuszz/fastapi_supabase_template/commit/508c1ffc7f663eef9eacdd11f471c86a67a9caf9)) +- Remove supabase-py-async with supabase-py +- Merge pull request #139 from Atticuszz/work-with-supabase-py in #139 -* Merge pull request #136 from Atticuszz/pre-commit-ci-update-config +### ⚙️ Miscellaneous Tasks -[pre-commit.ci] autoupdate ([`4f4a7f1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4f4a7f17aa9ad12d49fa3b66ac55868ad5443ede)) +- Update README.md +- Remove ci -* [pre-commit.ci] autoupdate +## 0.4.0 - 2024-08-30 -updates: -- [github.com/commitizen-tools/commitizen: v3.28.0 → v3.29.0](https://github.com/commitizen-tools/commitizen/compare/v3.28.0...v3.29.0) -- [github.com/pre-commit/mirrors-mypy: v1.11.1 → v1.11.2](https://github.com/pre-commit/mirrors-mypy/compare/v1.11.1...v1.11.2) ([`a77848b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a77848b60a363005e5a939374490563adad549fe)) +### 🚀 Features -## v0.4.0 (2024-08-30) +- Use uv to manage venvs -### Chore +### 🐛 Bug Fixes -* chore(release): bump version to v0.4.0 ([`0214da5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0214da5e5b900081954ca77e8c2f447e636d7f89)) +- Remove ci +- Ci docker push +- Ci -### Feature +## 0.3.2 - 2024-07-30 -* feat: use uv to manage venvs ([`3b8bf2b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3b8bf2b293eb1d65807213deb730a849887fc891)) +### 🐛 Bug Fixes -### Fix +- Update deps -* fix: ci ([`6ab7d76`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6ab7d7654d201c2c6656174b051738696a766aa0)) +### ⚙️ Miscellaneous Tasks -* fix: ci ([`abe41b3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/abe41b30fbf5664de0d61b0e95dac51e6e1e8bf1)) +- Update README.md -* fix: ci docker push ([`4d333be`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4d333be57415c7978dae20367ec3e4bb13597b65)) +## 0.3.1 - 2024-01-15 -* fix: remove ci ([`b5e45b2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b5e45b2a133fce2e362d682752caed41c9d54f60)) +### 🐛 Bug Fixes -### Unknown +- Bump version to 0.3.1 -* fix ([`f11b28d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f11b28dc5d3d3ae887ed7a96fb50fd22c52d3797)) +### ⚙️ Miscellaneous Tasks -* Merge pull request #128 from Atticuszz/dependabot/pip/uvicorn-0.30.6 +- Delete .idea directory +- Update README.md -⬆ Bump uvicorn from 0.30.4 to 0.30.6 ([`27b168d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/27b168d7a8443eb9757ad70afc7d1ad0d8f28364)) +## 0.3.0 - 2024-01-13 -* ⬆ Bump uvicorn from 0.30.4 to 0.30.6 +### 🚀 Features -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.30.4 to 0.30.6. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.30.4...0.30.6) +- Add Dockerfile +- Add Dockerfile and image push ci ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-patch -... +### ⚙️ Miscellaneous Tasks -Signed-off-by: dependabot[bot] <support@github.com> ([`8881662`](https://github.com/Atticuszz/fastapi_supabase_template/commit/88816626b0e937051bf2a17f1c1cd8ccba0020f9)) +- Update README.md +- RUN pre-commit-hooks +- Add Dockerfile -* Merge pull request #135 from Atticuszz/dependabot/pip/aiohttp-3.10.2 +## 0.2.1 - 2024-01-13 -⬆ Bump aiohttp from 3.9.4 to 3.10.2 ([`3ae51e8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3ae51e87f32dba85fb9baea38882630b25c4dc42)) +### ⚙️ Miscellaneous Tasks -* ⬆ Bump aiohttp from 3.9.4 to 3.10.2 +- Update README.md +- Add latest_changes.yml in #22 +- Update latest_changes.yml +- Update ci.yml -Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.4 to 3.10.2. -- [Release notes](https://github.com/aio-libs/aiohttp/releases) -- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) -- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.4...v3.10.2) +## 0.2.0 - 2024-01-13 ---- -updated-dependencies: -- dependency-name: aiohttp - dependency-type: indirect -... +### 🚀 Features -Signed-off-by: dependabot[bot] <support@github.com> ([`266f615`](https://github.com/Atticuszz/fastapi_supabase_template/commit/266f615680f36226716beaa697145bbf788e5a50)) +- Release in #21 -* Merge pull request #133 from Atticuszz/dependabot/pip/faker-28.0.0 +## 0.1.0 - 2024-01-13 -⬆ Bump faker from 26.1.0 to 28.0.0 ([`f2995d1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f2995d1340e751ddbd35982589bd7d8efaa2da8b)) +### 🚀 Features -* ⬆ Bump faker from 26.1.0 to 28.0.0 +- Update ci and README.md +- Release in #20 -Bumps [faker](https://github.com/joke2k/faker) from 26.1.0 to 28.0.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v26.1.0...v28.0.0) +### 🐛 Bug Fixes ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-major -... +- Add latest_changes.yml -Signed-off-by: dependabot[bot] <support@github.com> ([`a8c59b8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a8c59b869ede6cf68ac6c863f818843d676cfd79)) +### ⚙️ Miscellaneous Tasks -* Merge pull request #125 from Atticuszz/pre-commit-ci-update-config +- Update ci -[pre-commit.ci] autoupdate ([`db32e5b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/db32e5bddc066552a64509419b3773569a9aef16)) +## 0.0.2 - 2024-01-13 -* [pre-commit.ci] autoupdate +### ⚙️ Miscellaneous Tasks -updates: -- [github.com/asottile/pyupgrade: v3.16.0 → v3.17.0](https://github.com/asottile/pyupgrade/compare/v3.16.0...v3.17.0) -- [github.com/psf/black: 24.4.2 → 24.8.0](https://github.com/psf/black/compare/24.4.2...24.8.0) -- [github.com/commitizen-tools/commitizen: v3.27.0 → v3.28.0](https://github.com/commitizen-tools/commitizen/compare/v3.27.0...v3.28.0) -- [github.com/PyCQA/flake8: 7.1.0 → 7.1.1](https://github.com/PyCQA/flake8/compare/7.1.0...7.1.1) -- [github.com/pre-commit/mirrors-mypy: v1.10.1 → v1.11.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.1...v1.11.1) ([`a03ba13`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a03ba133037492f4d20c5b41eb13defa6a706ec9)) +- Remove latest-changes: ci +- Set pro-commit-hooks autofix_prs -> True +- Update ci +- Update README.md -* Merge pull request #124 from Atticuszz/dependabot/pip/faker-26.1.0 +### Bugs -⬆ Bump faker from 26.0.0 to 26.1.0 ([`747f170`](https://github.com/Atticuszz/fastapi_supabase_template/commit/747f17067fcf30d8c86c3b77af1e288cdb62208c)) +- Failed to auth as dep on new user by access token -* ⬆ Bump faker from 26.0.0 to 26.1.0 +### Upgrade -Bumps [faker](https://github.com/joke2k/faker) from 26.0.0 to 26.1.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v26.0.0...v26.1.0) +- Release 0.1.0 ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... +## 0.0.1 - 2024-01-11 -Signed-off-by: dependabot[bot] <support@github.com> ([`f1adfc4`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f1adfc49a3216b2bfec0311de43755472271bbe2)) +### ⚙️ Miscellaneous Tasks -* Merge pull request #121 from Atticuszz/dependabot/pip/uvicorn-0.30.4 +- Update ci,add changelog as pushed ,Publish to GitHub Releases as test passed and merged from PR +- Update ci -⬆ Bump uvicorn from 0.30.1 to 0.30.4 ([`555dc7c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/555dc7c3f5267659be803b18276fdf7b4872e3f1)) - -* ⬆ Bump uvicorn from 0.30.1 to 0.30.4 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.30.1 to 0.30.4. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.30.1...0.30.4) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`6fc9326`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6fc93260a0c8359bf48743a46e56360e5d875a22)) - -* Merge pull request #119 from Atticuszz/dependabot/pip/pre-commit-3.8.0 - -⬆ Bump pre-commit from 3.7.1 to 3.8.0 ([`dea4717`](https://github.com/Atticuszz/fastapi_supabase_template/commit/dea47172e2869338102d00fef7f142c173b76131)) - -* ⬆ Bump pre-commit from 3.7.1 to 3.8.0 - -Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.7.1 to 3.8.0. -- [Release notes](https://github.com/pre-commit/pre-commit/releases) -- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) -- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.7.1...v3.8.0) - ---- -updated-dependencies: -- dependency-name: pre-commit - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`eca2d97`](https://github.com/Atticuszz/fastapi_supabase_template/commit/eca2d97e29a34e645c9d5cf8607d2a917d5a14a4)) - -## v0.3.2 (2024-07-30) - -### Chore - -* chore(release): bump version to v0.3.2 ([`2418fac`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2418face6defed2073aefd0496ce90d85d2e4e00)) - -* chore: update README.md ([`b791786`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b7917861ecfb92eb27091a8f6c1981e3d3831009)) - -* chore: update README.md ([`9833dd7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9833dd77e47db59a077714831099e04f3de8d837)) - -* chore: update README.md ([`c2a87cb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c2a87cbde31435032f804af04278a89139f22d4c)) - -* chore: update README.md ([`baf9bdc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/baf9bdc42efe2d02ba8a726fd9a7f6e5c659893f)) - -* chore: update README.md ([`f3680ea`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f3680eaf8e6154537601e03690e0f55a6edbb258)) - -* chore: update README.md ([`f8e2bbf`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f8e2bbfd217e75e9157143a2d6c7919df349d48a)) - -* chore: update README.md ([`5da4579`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5da4579dd4a6015f1a2641c345593ad89a5cf187)) - -* chore: update README.md ([`97ba1a1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/97ba1a140ba4a288ab10afc619ed35d7315f2d2f)) - -* chore: update README.md ([`f8e996a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f8e996a36834c6295fe5cf61aa7ea1e41953bb6c)) - -* chore: update README.md ([`d10a143`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d10a1431b0d32dabea78c4edb8407731c1227d1c)) - -* chore: update README.md ([`8cce6d8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8cce6d8442b796acce089bbe5c985d439432bd4e)) - -* chore: update README.md ([`5bb4e0c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5bb4e0cb3797143e0647ffc41b0ba15be011c796)) - -* chore: update README.md ([`ecd7155`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ecd7155bbf193611e8d047930ca08875f4951326)) - -* chore: update README.md ([`2bf9173`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2bf917354f3eb83e94d5f6dca582e0719029449d)) - -* chore: update README.md ([`48c15ce`](https://github.com/Atticuszz/fastapi_supabase_template/commit/48c15cefae54dfad61a86310dda6f48d409bad23)) - -* chore: update README.md ([`0f67413`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0f6741311447d8384f0a4aaceb122e7956d68d2c)) - -* chore: update README.md ([`70c871f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/70c871f221214f8e3474e80d2f6c65ed1c9b47cf)) - -* chore: update README.md ([`5c3c373`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5c3c3735b015d0725418143aa51ab400055191a1)) - -* chore: update README.md ([`2b8f414`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2b8f4144d8004bb975ea5fd1424eed2449b9da85)) - -* chore: update README.md ([`ef062e1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ef062e1c53517def28b7830cb7df9267f90d63e9)) - -* chore: update README.md ([`b0751f6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b0751f6f9fb6735f5089d474edace72fe15517e9)) - -* chore: update README.md ([`f71f018`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f71f0186390d282b4ff1243c45d10c0079e9f089)) - -* chore: update README.md ([`e2daec3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e2daec3f6c8d14e49053109445afc90e14701cad)) - -* chore: update README.md ([`3d42ef2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3d42ef2f19edacac52e3b50c5dcbdac1af9b0bca)) - -* chore: update README.md ([`fc71183`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fc711838fe0d610c338e68ba1dec76e9f2875401)) - -* chore: update README.md ([`955ce53`](https://github.com/Atticuszz/fastapi_supabase_template/commit/955ce533308c0c160d45c69abd1b6b0f8f59e575)) - -* chore: update README.md ([`944f72e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/944f72ed5a2efe9d55d4679e8c43c85027029337)) - -* chore: update README.md ([`5c2e67c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5c2e67c30a90ea58b5e3f4103f56daa0eb33026d)) - -* chore: update README.md ([`cf9c20b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cf9c20b965faa6673aec672fb91dfa3dc3433c7b)) - -* chore: update README.md ([`1c958c6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1c958c6617649dc851141ac4f926b0b215e89460)) - -* chore: update README.md ([`eca5bc6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/eca5bc6bbf8f28524cf4c55bbf87f79f19518ffb)) - -* chore: update README.md ([`936df3b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/936df3b8511d8837e7caf8b8091a36c0f94f9780)) - -* chore: update README.md ([`3a5ae33`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3a5ae333e47e5e5eb9dbc4832f238f3108f104ee)) - -* chore: update README.md ([`c582ea5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c582ea50212569dd63782cbd5084530a0eaf213b)) - -* chore: update README.md ([`2862473`](https://github.com/Atticuszz/fastapi_supabase_template/commit/28624736e8b5d883b19718ccd9657d04c09044b9)) - -* chore: update README.md ([`b53f090`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b53f090955deaa5d8c3a05cef12e1e27263b4b7d)) - -* chore: update README.md ([`104df20`](https://github.com/Atticuszz/fastapi_supabase_template/commit/104df20f6a0c6a05c1c6ed91df83b8e3fe6427c4)) - -* chore: update README.md ([`73bbdcb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/73bbdcbed352cc3ddb4456bf7e71011456121111)) - -* chore: update README.md ([`cb31b48`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cb31b4846f366c98edfa5c77da0e2ffdf64e0cc6)) - -* chore: update README.md ([`ed111d6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ed111d6ecfa24960f282680225f6643681a04b76)) - -* chore: update README.md ([`51f08ce`](https://github.com/Atticuszz/fastapi_supabase_template/commit/51f08ce9cbccb6daaeb6061edeca3ff15c95d473)) - -* chore: update README.md ([`f908731`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f908731ea780bdf62f4a2da1cea8d96a1768a2ee)) - -* chore: update README.md ([`5a56ca8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5a56ca858d4d36ecca4cce981166cd0869aeefa7)) - -* chore: update README.md ([`57beef1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/57beef1f0b2851adda4739ac1b5887e064601de1)) - -* chore: update README.md ([`d171ca5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d171ca5679534c431d36ccbc6ee0c27f16cd8789)) - -* chore: update README.md ([`39cafd7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/39cafd78b353c8b61120e0278c93f46ab2b75dab)) - -* chore: update README.md ([`cd09d76`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cd09d765b33bc4923b14eb655f22e030a89ee386)) - -* chore: update README.md ([`ed6c2e3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ed6c2e3659f23a179a97208b5cc49627e6f9bf0e)) - -* chore: update README.md ([`18fefd0`](https://github.com/Atticuszz/fastapi_supabase_template/commit/18fefd0abf53e8474d9c921d37113cc18696ab6c)) - -* chore: update README.md ([`27934ae`](https://github.com/Atticuszz/fastapi_supabase_template/commit/27934ae1e830a60342fa16301650511cd4fba6c5)) - -* chore: update README.md ([`1dfc4b2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1dfc4b2ec80ff0faffaa3eff2de1397dcf46ffb6)) - -* chore: update README.md ([`7d407fd`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7d407fd43b07bca983d7e2be407853131a966d45)) - -* chore: update README.md ([`c7cc7f8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c7cc7f8ef398fa245804b56881d75072a444c31d)) - -* chore: update README.md ([`51ce504`](https://github.com/Atticuszz/fastapi_supabase_template/commit/51ce5047615d7e0a2953faaaf5b125c7a1e8a3cb)) - -* chore: update README.md ([`034c5bc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/034c5bc9e74819fd0e71ad17d7723cdbab24e6f3)) - -* chore: update README.md ([`8aca934`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8aca934d33944c9106b1da84dd31fa627b06a08c)) - -* chore: update README.md ([`9d464d7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9d464d7283c4807e4943effec1b2e365b861ed4a)) - -### Fix - -* fix: Update deps ([`d1dff97`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d1dff97ec9a3132b88b32a07d0eff3aa11c26cca)) - -### Unknown - -* Merge pull request #120 from Atticuszz/dependabot/pip/pydantic-settings-2.4.0 - -⬆ Bump pydantic-settings from 2.2.1 to 2.4.0 ([`c910430`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c9104309e77b49c75cbe89b9f904410f907d5fd4)) - -* ⬆ Bump pydantic-settings from 2.2.1 to 2.4.0 - -Bumps [pydantic-settings](https://github.com/pydantic/pydantic-settings) from 2.2.1 to 2.4.0. -- [Release notes](https://github.com/pydantic/pydantic-settings/releases) -- [Commits](https://github.com/pydantic/pydantic-settings/compare/v2.2.1...v2.4.0) - ---- -updated-dependencies: -- dependency-name: pydantic-settings - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`314c3c6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/314c3c683ec325376bbef281aef8140a86b3b9e0)) - -* Merge pull request #118 from Atticuszz/dependabot/pip/pytest-8.3.2 - -⬆ Bump pytest from 8.2.1 to 8.3.2 ([`574f6e1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/574f6e112af089fa3a97b6f1519fa6223e8c13ff)) - -* ⬆ Bump pytest from 8.2.1 to 8.3.2 - -Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.2.1 to 8.3.2. -- [Release notes](https://github.com/pytest-dev/pytest/releases) -- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest/compare/8.2.1...8.3.2) - ---- -updated-dependencies: -- dependency-name: pytest - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`fd43b45`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fd43b454f930923d475b5b448dc6f065655b284c)) - -* Merge pull request #114 from Atticuszz/dependabot/pip/python-semantic-release-9.8.5 - -⬆ bump python-semantic-release from 9.4.1 to 9.8.5 ([`c6bfcfd`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c6bfcfd024031d5182a98544345aee82db9bad19)) - -* ⬆ bump python-semantic-release from 9.4.1 to 9.8.5 - -Bumps [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) from 9.4.1 to 9.8.5. -- [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) -- [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.md) -- [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.4.1...v9.8.5) - ---- -updated-dependencies: -- dependency-name: python-semantic-release - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`18a8879`](https://github.com/Atticuszz/fastapi_supabase_template/commit/18a887977c8001ced23bf9170380749523bbf850)) - -* Merge pull request #105 from Atticuszz/dependabot/pip/faker-26.0.0 - -⬆ bump faker from 24.8.0 to 26.0.0 ([`853a5aa`](https://github.com/Atticuszz/fastapi_supabase_template/commit/853a5aa4b24831b95ea60a5505ad9b519059881b)) - -* ⬆ bump faker from 24.8.0 to 26.0.0 - -Bumps [faker](https://github.com/joke2k/faker) from 24.8.0 to 26.0.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v24.8.0...v26.0.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`32b9654`](https://github.com/Atticuszz/fastapi_supabase_template/commit/32b96547576e6388b77ae8c9ba26ce86f1ad8720)) - -* Merge pull request #113 from Atticuszz/dependabot/pip/anyio-4.4.0 - -⬆ bump anyio from 4.3.0 to 4.4.0 ([`199f9cb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/199f9cbf2296f652a32cff0e05c8d8794b3521cc)) - -* ⬆ bump anyio from 4.3.0 to 4.4.0 - -Bumps [anyio](https://github.com/agronholm/anyio) from 4.3.0 to 4.4.0. -- [Release notes](https://github.com/agronholm/anyio/releases) -- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst) -- [Commits](https://github.com/agronholm/anyio/compare/4.3.0...4.4.0) - ---- -updated-dependencies: -- dependency-name: anyio - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`9d25281`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9d252816918602d966ec067e1253023284580a1b)) - -* Merge pull request #107 from Atticuszz/dependabot/pip/uvicorn-0.30.1 - -⬆ bump uvicorn from 0.29.0 to 0.30.1 ([`da12741`](https://github.com/Atticuszz/fastapi_supabase_template/commit/da127410763e6b1dcf40191261eae39d207fc09a)) - -* ⬆ bump uvicorn from 0.29.0 to 0.30.1 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.29.0 to 0.30.1. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.29.0...0.30.1) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`ad847fe`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ad847fed0d407ae58576054581334c3a589f7cc6)) - -* Merge pull request #111 from Atticuszz/dependabot/pip/fastapi-0.111.1 - -⬆ bump fastapi from 0.110.0 to 0.111.1 ([`9adc54e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9adc54e8b9fbd0d37f34899bee94322f520db626)) - -* ⬆ bump fastapi from 0.110.0 to 0.111.1 - -Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.110.0 to 0.111.1. -- [Release notes](https://github.com/tiangolo/fastapi/releases) -- [Commits](https://github.com/tiangolo/fastapi/compare/0.110.0...0.111.1) - ---- -updated-dependencies: -- dependency-name: fastapi - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`b490f7b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b490f7b85da9f1192cbf2e6e9da124674495952f)) - -* Merge pull request #110 from Atticuszz/dependabot/pip/zipp-3.19.1 - -⬆ bump zipp from 3.17.0 to 3.19.1 ([`4746da1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4746da1e80742268d53326aae805d696e263ee8f)) - -* ⬆ bump zipp from 3.17.0 to 3.19.1 - -Bumps [zipp](https://github.com/jaraco/zipp) from 3.17.0 to 3.19.1. -- [Release notes](https://github.com/jaraco/zipp/releases) -- [Changelog](https://github.com/jaraco/zipp/blob/main/NEWS.rst) -- [Commits](https://github.com/jaraco/zipp/compare/v3.17.0...v3.19.1) - ---- -updated-dependencies: -- dependency-name: zipp - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`628f2c5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/628f2c5294bab90ed5a46f294cfdb9c351c11d4b)) - -* Merge pull request #104 from Atticuszz/dependabot/pip/pydantic-2.8.2 - -⬆ bump pydantic from 2.7.0 to 2.8.2 ([`bc5b4c4`](https://github.com/Atticuszz/fastapi_supabase_template/commit/bc5b4c439fa34021262f55a1ecdf8411153fa625)) - -* ⬆ bump pydantic from 2.7.0 to 2.8.2 - -Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.7.0 to 2.8.2. -- [Release notes](https://github.com/pydantic/pydantic/releases) -- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) -- [Commits](https://github.com/pydantic/pydantic/compare/v2.7.0...v2.8.2) - ---- -updated-dependencies: -- dependency-name: pydantic - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`758d22f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/758d22f85d40e472596f1fa566e56bb3c2167496)) - -* Merge pull request #92 from Atticuszz/dependabot/pip/aiohttp-3.9.4 - -⬆ bump aiohttp from 3.9.2 to 3.9.4 ([`173efea`](https://github.com/Atticuszz/fastapi_supabase_template/commit/173efea2631f45486f9ea9906c63a37ac01c9a67)) - -* ⬆ bump aiohttp from 3.9.2 to 3.9.4 - -Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.2 to 3.9.4. -- [Release notes](https://github.com/aio-libs/aiohttp/releases) -- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) -- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.2...v3.9.4) - ---- -updated-dependencies: -- dependency-name: aiohttp - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`fd17dbe`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fd17dbec3b097a50767c72011fa0801a69ebd18e)) - -* Merge pull request #89 from Atticuszz/dependabot/pip/idna-3.7 - -⬆ bump idna from 3.6 to 3.7 ([`f0b4a28`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f0b4a28d0bcad0d69cb2bee9e007e7875bd78b9e)) - -* ⬆ bump idna from 3.6 to 3.7 - -Bumps [idna](https://github.com/kjd/idna) from 3.6 to 3.7. -- [Release notes](https://github.com/kjd/idna/releases) -- [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.rst) -- [Commits](https://github.com/kjd/idna/compare/v3.6...v3.7) - ---- -updated-dependencies: -- dependency-name: idna - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`6f34f44`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6f34f441bd69d3dca8f784d183681f07c878a2b3)) - -* Merge pull request #91 from Atticuszz/dependabot/pip/dnspython-2.6.1 - -⬆ bump dnspython from 2.4.2 to 2.6.1 ([`710c77e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/710c77e951b19445d70d7473630b8aab63b36369)) - -* ⬆ bump dnspython from 2.4.2 to 2.6.1 - -Bumps [dnspython](https://github.com/rthalley/dnspython) from 2.4.2 to 2.6.1. -- [Release notes](https://github.com/rthalley/dnspython/releases) -- [Changelog](https://github.com/rthalley/dnspython/blob/main/doc/whatsnew.rst) -- [Commits](https://github.com/rthalley/dnspython/compare/v2.4.2...v2.6.1) - ---- -updated-dependencies: -- dependency-name: dnspython - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`9d0c5cc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9d0c5ccda3d7f1f28f91b297ab2ae6674b5ff938)) - -* Merge pull request #95 from Atticuszz/dependabot/pip/jinja2-3.1.4 - -⬆ bump jinja2 from 3.1.3 to 3.1.4 ([`7945718`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7945718fcd9321c072b1d8ded3759fa2ca1b3440)) - -* ⬆ bump jinja2 from 3.1.3 to 3.1.4 - -Bumps [jinja2](https://github.com/pallets/jinja) from 3.1.3 to 3.1.4. -- [Release notes](https://github.com/pallets/jinja/releases) -- [Changelog](https://github.com/pallets/jinja/blob/main/CHANGES.rst) -- [Commits](https://github.com/pallets/jinja/compare/3.1.3...3.1.4) - ---- -updated-dependencies: -- dependency-name: jinja2 - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`40c924c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/40c924cda4a7f83b3c5b630fe1daebdaa6b83de5)) - -* Merge pull request #98 from Atticuszz/dependabot/pip/requests-2.32.0 - -⬆ bump requests from 2.31.0 to 2.32.0 ([`513c9e1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/513c9e1011e25a8d0646ae29b2a6cfd124e113ae)) - -* - ---- -updated-dependencies: -- dependency-name: requests - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`2b1231b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2b1231bcadb187f303bfb786050899410337b0af)) - -* Merge pull request #100 from Atticuszz/dependabot/github_actions/docker/build-push-action-6 - -⬆ bump docker/build-push-action from 5 to 6 ([`8a57b30`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8a57b3028b87356386b8c58f978e2ed7af46a9f3)) - -* ⬆ bump docker/build-push-action from 5 to 6 - -Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 6. -- [Release notes](https://github.com/docker/build-push-action/releases) -- [Commits](https://github.com/docker/build-push-action/compare/v5...v6) - ---- -updated-dependencies: -- dependency-name: docker/build-push-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`cc185df`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cc185dfb922a75132fb495fb020404dfcd9d7da1)) - -* Merge pull request #103 from Atticuszz/dependabot/pip/certifi-2024.7.4 - -⬆ bump certifi from 2023.11.17 to 2024.7.4 ([`715b67c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/715b67c722f226f05e5a672761737bf58cf09373)) - -* ⬆ bump certifi from 2023.11.17 to 2024.7.4 - -Bumps [certifi](https://github.com/certifi/python-certifi) from 2023.11.17 to 2024.7.4. -- [Commits](https://github.com/certifi/python-certifi/compare/2023.11.17...2024.07.04) - ---- -updated-dependencies: -- dependency-name: certifi - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`77d26d4`](https://github.com/Atticuszz/fastapi_supabase_template/commit/77d26d41ec3ee1acf35ad8e1c9aa9b993bf5260c)) - -* Merge pull request #102 from Atticuszz/pre-commit-ci-update-config - -[pre-commit.ci] autoupdate ([`4a97cf3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4a97cf3f7ce11c83e3ee0f4d55edb34ae44b9eea)) - -* [pre-commit.ci] autoupdate - -updates: -- [github.com/asottile/pyupgrade: v3.15.2 → v3.16.0](https://github.com/asottile/pyupgrade/compare/v3.15.2...v3.16.0) -- [github.com/PyCQA/flake8: 7.0.0 → 7.1.0](https://github.com/PyCQA/flake8/compare/7.0.0...7.1.0) -- [github.com/pre-commit/mirrors-mypy: v1.10.0 → v1.10.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.10.0...v1.10.1) ([`169ab54`](https://github.com/Atticuszz/fastapi_supabase_template/commit/169ab54c639dc3ae0de4b46a53065c3dc3d5ef7e)) - -* Merge pull request #101 from Atticuszz/dependabot/pip/urllib3-2.2.2 - -⬆ bump urllib3 from 2.1.0 to 2.2.2 ([`f59ec3b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f59ec3b7c74ec344d1365b83ff4f99835544b9a8)) - -* ⬆ bump urllib3 from 2.1.0 to 2.2.2 - -Bumps [urllib3](https://github.com/urllib3/urllib3) from 2.1.0 to 2.2.2. -- [Release notes](https://github.com/urllib3/urllib3/releases) -- [Changelog](https://github.com/urllib3/urllib3/blob/main/CHANGES.rst) -- [Commits](https://github.com/urllib3/urllib3/compare/2.1.0...2.2.2) - ---- -updated-dependencies: -- dependency-name: urllib3 - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`4b940ae`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4b940ae6a0f94118a17dfb14e0b94a795c452af9)) - -* Merge pull request #99 from Atticuszz/pre-commit-ci-update-config - -[pre-commit.ci] autoupdate ([`3bbbec9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3bbbec9d1cc2053c00e0b8761b0b251a8d9f4016)) - -* [pre-commit.ci] autoupdate - -updates: -- [github.com/codespell-project/codespell: v2.2.6 → v2.3.0](https://github.com/codespell-project/codespell/compare/v2.2.6...v2.3.0) -- [github.com/commitizen-tools/commitizen: v3.25.0 → v3.27.0](https://github.com/commitizen-tools/commitizen/compare/v3.25.0...v3.27.0) ([`abb44bb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/abb44bb7389ada3a2a60c1145c504e2acc770df8)) - -* Merge pull request #97 from Atticuszz/dependabot/pip/pytest-8.2.1 - -⬆ bump pytest from 8.1.0 to 8.2.1 ([`6a62dfc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6a62dfc4a9b3cb8878f8a0c257df36361b0e30d0)) - -* ⬆ bump pytest from 8.1.0 to 8.2.1 - -Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.1.0 to 8.2.1. -- [Release notes](https://github.com/pytest-dev/pytest/releases) -- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest/compare/8.1.0...8.2.1) - ---- -updated-dependencies: -- dependency-name: pytest - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`793fed3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/793fed39a80d8eabd2095b99e9f24bd9c7af4e93)) - -* Merge pull request #96 from Atticuszz/dependabot/pip/pre-commit-3.7.1 - -⬆ bump pre-commit from 3.6.2 to 3.7.1 ([`7494a8c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7494a8c50663ed3b0706307d4f0afe61f4666438)) - -* ⬆ bump pre-commit from 3.6.2 to 3.7.1 - -Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.6.2 to 3.7.1. -- [Release notes](https://github.com/pre-commit/pre-commit/releases) -- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) -- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.6.2...v3.7.1) - ---- -updated-dependencies: -- dependency-name: pre-commit - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`f2ff849`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f2ff8490bce4b8a22f3cb08276201dbc92b36023)) - -* Merge pull request #94 from Atticuszz/pre-commit-ci-update-config - -[pre-commit.ci] autoupdate ([`3945191`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3945191482430e35f0f9356d6fa5d26e30737067)) - -* [pre-commit.ci] autoupdate - -updates: -- [github.com/pre-commit/pre-commit-hooks: v4.5.0 → v4.6.0](https://github.com/pre-commit/pre-commit-hooks/compare/v4.5.0...v4.6.0) -- [github.com/psf/black: 24.3.0 → 24.4.2](https://github.com/psf/black/compare/24.3.0...24.4.2) -- [github.com/commitizen-tools/commitizen: v3.21.3 → v3.25.0](https://github.com/commitizen-tools/commitizen/compare/v3.21.3...v3.25.0) -- [github.com/pre-commit/mirrors-mypy: v1.9.0 → v1.10.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.9.0...v1.10.0) ([`f90dbee`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f90dbee019d9c2dbfb1b325c0e4295637a4d5435)) - -* Merge pull request #87 from Atticuszz/dependabot/pip/pytest-cov-5.0.0 - -⬆ bump pytest-cov from 4.1.0 to 5.0.0 ([`48c3841`](https://github.com/Atticuszz/fastapi_supabase_template/commit/48c3841687d43cdb351283081602652034fa565a)) - -* ⬆ bump pytest-cov from 4.1.0 to 5.0.0 - -Bumps [pytest-cov](https://github.com/pytest-dev/pytest-cov) from 4.1.0 to 5.0.0. -- [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.1.0...v5.0.0) - ---- -updated-dependencies: -- dependency-name: pytest-cov - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`78526a9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/78526a981d0cf339de9031d5c3930bed0563b842)) - -* Merge pull request #76 from Atticuszz/dependabot/pip/uvicorn-0.29.0 - -⬆ bump uvicorn from 0.27.1 to 0.29.0 ([`b236a17`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b236a17453561f6d1930d42a0b50c3dc910af594)) - -* ⬆ bump uvicorn from 0.27.1 to 0.29.0 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.27.1 to 0.29.0. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.27.1...0.29.0) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`e8acd0b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e8acd0b48da01ddc9e0f3eba44884dd46984885b)) - -* Merge pull request #90 from Atticuszz/dependabot/pip/pydantic-2.7.0 - -⬆ bump pydantic from 2.6.1 to 2.7.0 ([`6a10663`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6a10663ee211aa4da62e4e137aa9bfbf1605b79f)) - -* ⬆ bump pydantic from 2.6.1 to 2.7.0 - -Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.6.1 to 2.7.0. -- [Release notes](https://github.com/pydantic/pydantic/releases) -- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) -- [Commits](https://github.com/pydantic/pydantic/compare/v2.6.1...v2.7.0) - ---- -updated-dependencies: -- dependency-name: pydantic - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`dc58453`](https://github.com/Atticuszz/fastapi_supabase_template/commit/dc58453cc262e495862aa19250404caeba34cda4)) - -* Merge pull request #85 from Atticuszz/dependabot/pip/supabase-py-async-2.5.6 - -⬆ bump supabase-py-async from 2.5.5 to 2.5.6 ([`6b9e478`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6b9e478fa387cf729019365c3f74bfdc4b723069)) - -* ⬆ bump supabase-py-async from 2.5.5 to 2.5.6 - -Bumps [supabase-py-async](https://github.com/Atticuszz/supabase-py_async) from 2.5.5 to 2.5.6. -- [Release notes](https://github.com/Atticuszz/supabase-py_async/releases) -- [Changelog](https://github.com/Atticuszz/supabase-py-async/blob/main/CHANGELOG.md) -- [Commits](https://github.com/Atticuszz/supabase-py_async/compare/v2.5.5...v2.5.6) - ---- -updated-dependencies: -- dependency-name: supabase-py-async - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`13fbfdb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/13fbfdb27c6177b50389b65363ee9564b4129470)) - -* Merge pull request #86 from Atticuszz/dependabot/pip/faker-24.8.0 - -⬆ bump faker from 24.2.0 to 24.8.0 ([`37d1638`](https://github.com/Atticuszz/fastapi_supabase_template/commit/37d1638078e82c232ee93ec9fc17a13818370a9e)) - -* ⬆ bump faker from 24.2.0 to 24.8.0 - -Bumps [faker](https://github.com/joke2k/faker) from 24.2.0 to 24.8.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v24.2.0...v24.8.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`4796648`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4796648844ee47f35142658c0869c01b3fb0263d)) - -* Merge pull request #84 from Atticuszz/dependabot/pip/python-semantic-release-9.4.1 - -⬆ bump python-semantic-release from 9.1.0 to 9.4.1 ([`51a36c1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/51a36c1a6979443830cbe41e92dcba2357253bef)) - -* ⬆ bump python-semantic-release from 9.1.0 to 9.4.1 - -Bumps [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) from 9.1.0 to 9.4.1. -- [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) -- [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.md) -- [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.1.0...v9.4.1) - ---- -updated-dependencies: -- dependency-name: python-semantic-release - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`21de03b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/21de03b78a02c2b92d11a60b2f045f5e2d5e5483)) - -* Merge pull request #82 from Atticuszz/pre-commit-ci-update-config - -[pre-commit.ci] autoupdate ([`ee70d4f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ee70d4f337d4e05c6568acdf6e368371e4c03c1c)) - -* [pre-commit.ci] autoupdate - -updates: -- [github.com/PyCQA/autoflake: v2.2.1 → v2.3.1](https://github.com/PyCQA/autoflake/compare/v2.2.1...v2.3.1) -- [github.com/asottile/pyupgrade: v3.15.0 → v3.15.2](https://github.com/asottile/pyupgrade/compare/v3.15.0...v3.15.2) -- [github.com/psf/black: 24.1.1 → 24.3.0](https://github.com/psf/black/compare/24.1.1...24.3.0) -- [github.com/commitizen-tools/commitizen: v3.14.1 → v3.21.3](https://github.com/commitizen-tools/commitizen/compare/v3.14.1...v3.21.3) -- [github.com/pre-commit/mirrors-mypy: v1.8.0 → v1.9.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.8.0...v1.9.0) ([`8fced35`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8fced357b8f402d07d03b77b21e8ca203f25fc86)) - -* Merge pull request #67 from Atticuszz/dependabot/pip/supabase-py-async-2.5.5 - -⬆ bump supabase-py-async from 2.5.4 to 2.5.5 ([`fafcf0c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fafcf0c64159fd1e534f8e6135d14aea36f3e993)) - -* ⬆ bump supabase-py-async from 2.5.4 to 2.5.5 - -Bumps [supabase-py-async](https://github.com/Atticuszz/supabase-py_async) from 2.5.4 to 2.5.5. -- [Release notes](https://github.com/Atticuszz/supabase-py_async/releases) -- [Changelog](https://github.com/Atticuszz/supabase-py-async/blob/main/CHANGELOG.md) -- [Commits](https://github.com/Atticuszz/supabase-py_async/compare/v2.5.4...v2.5.5) - ---- -updated-dependencies: -- dependency-name: supabase-py-async - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`5bf5f4e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5bf5f4e47db09af0a653e526f6311eb14f3eeb88)) - -* Merge pull request #53 from Atticuszz/dependabot/pip/anyio-4.3.0 - -⬆ bump anyio from 4.2.0 to 4.3.0 ([`6fb6529`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6fb65291ea506bde82f1ac6b30870077181cf353)) - -* ⬆ bump anyio from 4.2.0 to 4.3.0 - -Bumps [anyio](https://github.com/agronholm/anyio) from 4.2.0 to 4.3.0. -- [Release notes](https://github.com/agronholm/anyio/releases) -- [Changelog](https://github.com/agronholm/anyio/blob/master/docs/versionhistory.rst) -- [Commits](https://github.com/agronholm/anyio/compare/4.2.0...4.3.0) - ---- -updated-dependencies: -- dependency-name: anyio - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`b4f0c48`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b4f0c48a13ac174d73fe25b32a862438becfb4a2)) - -* Merge pull request #70 from Atticuszz/dependabot/pip/faker-24.2.0 - -⬆ bump faker from 23.0.0 to 24.2.0 ([`9273cb2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9273cb25bd7e9a43453853f7c173895b15fc9f19)) - -* ⬆ bump faker from 23.0.0 to 24.2.0 - -Bumps [faker](https://github.com/joke2k/faker) from 23.0.0 to 24.2.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v23.0.0...v24.2.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`479b467`](https://github.com/Atticuszz/fastapi_supabase_template/commit/479b4673bdbc98aec6bf29f51fbdb833d98acb23)) - -* Merge pull request #65 from Atticuszz/dependabot/pip/pytest-8.1.0 - -⬆ bump pytest from 8.0.2 to 8.1.0 ([`8549048`](https://github.com/Atticuszz/fastapi_supabase_template/commit/85490483e5bbbeeb1b7407151c2837fa793481c5)) - -* ⬆ bump pytest from 8.0.2 to 8.1.0 - -Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.2 to 8.1.0. -- [Release notes](https://github.com/pytest-dev/pytest/releases) -- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.2...8.1.0) - ---- -updated-dependencies: -- dependency-name: pytest - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`6688fe1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6688fe1039a092d37d5ae49d74d0e204d22e4424)) - -* Merge pull request #62 from Atticuszz/dependabot/pip/supabase-py-async-2.5.4 - -⬆ bump supabase-py-async from 2.5.1 to 2.5.4 ([`db85999`](https://github.com/Atticuszz/fastapi_supabase_template/commit/db85999ccdf4c51c3a822ae15710285729a4b9b6)) - -* ⬆ bump supabase-py-async from 2.5.1 to 2.5.4 - -Bumps [supabase-py-async](https://github.com/Atticuszz/supabase-py_async) from 2.5.1 to 2.5.4. -- [Release notes](https://github.com/Atticuszz/supabase-py_async/releases) -- [Changelog](https://github.com/Atticuszz/supabase-py-async/blob/main/CHANGELOG.md) -- [Commits](https://github.com/Atticuszz/supabase-py_async/compare/v2.5.1...v2.5.4) - ---- -updated-dependencies: -- dependency-name: supabase-py-async - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`b613cf9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b613cf9ffb1b8e41ea788628dd0226f81de2a33a)) - -* Merge pull request #61 from Atticuszz/dependabot/pip/fastapi-0.110.0 - -⬆ bump fastapi from 0.109.2 to 0.110.0 ([`c112a88`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c112a8812b3ebe4c5360e93910ccbc79afadcecf)) - -* ⬆ bump fastapi from 0.109.2 to 0.110.0 - -Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.109.2 to 0.110.0. -- [Release notes](https://github.com/tiangolo/fastapi/releases) -- [Commits](https://github.com/tiangolo/fastapi/compare/0.109.2...0.110.0) - ---- -updated-dependencies: -- dependency-name: fastapi - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`8fd7d5b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8fd7d5bf4b79a42b39baf595efc55184e6437a0b)) - -* Merge pull request #58 from Atticuszz/dependabot/pip/pytest-8.0.2 - -⬆ bump pytest from 8.0.0 to 8.0.2 ([`f32b617`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f32b617c08cbcc0aec1a8f5454afbabfe8e0149f)) - -* ⬆ bump pytest from 8.0.0 to 8.0.2 - -Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.0 to 8.0.2. -- [Release notes](https://github.com/pytest-dev/pytest/releases) -- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.0...8.0.2) - ---- -updated-dependencies: -- dependency-name: pytest - dependency-type: direct:development - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`249cd06`](https://github.com/Atticuszz/fastapi_supabase_template/commit/249cd0692552652e14e26b0c5f712ddc5f881e7b)) - -* Merge pull request #56 from Atticuszz/dependabot/pip/pre-commit-3.6.2 - -⬆ bump pre-commit from 3.6.0 to 3.6.2 ([`8ba005c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8ba005cb7c29ab118b37f23dc7acb16d2391a965)) - -* ⬆ bump pre-commit from 3.6.0 to 3.6.2 - -Bumps [pre-commit](https://github.com/pre-commit/pre-commit) from 3.6.0 to 3.6.2. -- [Release notes](https://github.com/pre-commit/pre-commit/releases) -- [Changelog](https://github.com/pre-commit/pre-commit/blob/main/CHANGELOG.md) -- [Commits](https://github.com/pre-commit/pre-commit/compare/v3.6.0...v3.6.2) - ---- -updated-dependencies: -- dependency-name: pre-commit - dependency-type: direct:development - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`ebbd802`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ebbd8024ef87be711e8ff0f7904b2c92b2ede1dd)) - -* Merge pull request #57 from Atticuszz/dependabot/pip/pydantic-settings-2.2.1 - -⬆ bump pydantic-settings from 2.1.0 to 2.2.1 ([`d85ec51`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d85ec5117dc3b528c81ca66841892a93a1722611)) - -* ⬆ bump pydantic-settings from 2.1.0 to 2.2.1 - -Bumps [pydantic-settings](https://github.com/pydantic/pydantic-settings) from 2.1.0 to 2.2.1. -- [Release notes](https://github.com/pydantic/pydantic-settings/releases) -- [Commits](https://github.com/pydantic/pydantic-settings/compare/v2.1.0...v2.2.1) - ---- -updated-dependencies: -- dependency-name: pydantic-settings - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`0c82c87`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0c82c876eb27778a2bfb1ee9ec08d3ca8d9ae7eb)) - -* Merge pull request #50 from Atticuszz/dependabot/pip/python-semantic-release-9.1.0 - -⬆ bump python-semantic-release from 9.0.3 to 9.1.0 ([`bbf0fd0`](https://github.com/Atticuszz/fastapi_supabase_template/commit/bbf0fd000b62aacf571f668a849afdcc9a22dc18)) - -* ⬆ bump python-semantic-release from 9.0.3 to 9.1.0 - -Bumps [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) from 9.0.3 to 9.1.0. -- [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) -- [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.md) -- [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v9.0.3...v9.1.0) - ---- -updated-dependencies: -- dependency-name: python-semantic-release - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`38bf7d9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/38bf7d9d5258aae8fafc5ab42ca89c50b3aa628d)) - -* Merge pull request #42 from Atticuszz/dependabot/pip/pydantic-2.6.1 - -⬆ bump pydantic from 2.6.0 to 2.6.1 ([`861202d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/861202d96f5257393768872ee4cfde4d08837f87)) - -* ⬆ bump pydantic from 2.6.0 to 2.6.1 - -Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.6.0 to 2.6.1. -- [Release notes](https://github.com/pydantic/pydantic/releases) -- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) -- [Commits](https://github.com/pydantic/pydantic/compare/v2.6.0...v2.6.1) - ---- -updated-dependencies: -- dependency-name: pydantic - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`15a1882`](https://github.com/Atticuszz/fastapi_supabase_template/commit/15a1882b9a22f3abb426cc8405367e5410834c1b)) - -* Merge pull request #49 from Atticuszz/dependabot/pip/python-multipart-0.0.9 - -⬆ bump python-multipart from 0.0.7 to 0.0.9 ([`f6deb4c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f6deb4c3b20a17b06f7e3e5935b676215a43a2c7)) - -* ⬆ bump python-multipart from 0.0.7 to 0.0.9 - -Bumps [python-multipart](https://github.com/andrew-d/python-multipart) from 0.0.7 to 0.0.9. -- [Release notes](https://github.com/andrew-d/python-multipart/releases) -- [Changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md) -- [Commits](https://github.com/andrew-d/python-multipart/compare/0.0.7...0.0.9) - ---- -updated-dependencies: -- dependency-name: python-multipart - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`6a943e0`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6a943e0a86c6dcb1f74addb15cce99b988d3cd08)) - -* Merge pull request #47 from Atticuszz/dependabot/pip/uvicorn-0.27.1 - -⬆ bump uvicorn from 0.27.0.post1 to 0.27.1 ([`1295b7a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1295b7aa42092fd2d088df40176338b5036a7b48)) - -* ⬆ bump uvicorn from 0.27.0.post1 to 0.27.1 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.27.0.post1 to 0.27.1. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.27.0.post1...0.27.1) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`f4a0f1d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f4a0f1dbc483eb7a34de80dda23a8e2a02484893)) - -* Merge pull request #46 from Atticuszz/dependabot/pip/python-semantic-release-9.0.3 - -⬆ bump python-semantic-release from 8.7.0 to 9.0.3 ([`11a2bde`](https://github.com/Atticuszz/fastapi_supabase_template/commit/11a2bdeab0ebde628bf73a11b56e97c713542f85)) - -* ⬆ bump python-semantic-release from 8.7.0 to 9.0.3 - -Bumps [python-semantic-release](https://github.com/python-semantic-release/python-semantic-release) from 8.7.0 to 9.0.3. -- [Release notes](https://github.com/python-semantic-release/python-semantic-release/releases) -- [Changelog](https://github.com/python-semantic-release/python-semantic-release/blob/master/CHANGELOG.md) -- [Commits](https://github.com/python-semantic-release/python-semantic-release/compare/v8.7.0...v9.0.3) - ---- -updated-dependencies: -- dependency-name: python-semantic-release - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`aa9fc43`](https://github.com/Atticuszz/fastapi_supabase_template/commit/aa9fc43e3dba41a00bd745b98a73d0add69593cb)) - -* Merge pull request #40 from Atticuszz/dependabot/pip/fastapi-0.109.2 - -⬆ Bump fastapi from 0.109.0 to 0.109.2 ([`ad9649e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ad9649e494861a41745b959775c13046e240b357)) - -* ⬆ Bump fastapi from 0.109.0 to 0.109.2 - -Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.109.0 to 0.109.2. -- [Release notes](https://github.com/tiangolo/fastapi/releases) -- [Commits](https://github.com/tiangolo/fastapi/compare/0.109.0...0.109.2) - ---- -updated-dependencies: -- dependency-name: fastapi - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`680a75c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/680a75ca13a9c268f914b5b20da35ae47d509d29)) - -* Merge pull request #44 from Atticuszz/dependabot/pip/faker-23.0.0 - -⬆ bump faker from 22.7.0 to 23.0.0 ([`bc74ed9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/bc74ed9c613ad50e956430a2ca9eb3979270c333)) - -* ⬆ bump faker from 22.7.0 to 23.0.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.7.0 to 23.0.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.7.0...v23.0.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`923ba19`](https://github.com/Atticuszz/fastapi_supabase_template/commit/923ba19ceb7a93052fb80afe79c2fb5f6d8f32b9)) - -* Merge pull request #43 from Atticuszz/dependabot/pip/faker-22.7.0 - -⬆ bump faker from 22.6.0 to 22.7.0 ([`563652e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/563652e4b0bbfc1947f796e2f4a8ac5dc3348dd5)) - -* ⬆ bump faker from 22.6.0 to 22.7.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.6.0 to 22.7.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.6.0...v22.7.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`a2a9b70`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a2a9b70d289d2ce952e0f9055869485f4c38d9b7)) - -* Merge pull request #35 from Atticuszz/dependabot/pip/faker-22.6.0 - -⬆ Bump faker from 22.5.1 to 22.6.0 ([`96ef611`](https://github.com/Atticuszz/fastapi_supabase_template/commit/96ef6115eb357a5d26f22ade2cbe7fc7ce06d848)) - -* ⬆ Bump faker from 22.5.1 to 22.6.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.5.1 to 22.6.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.5.1...v22.6.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`22772f8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/22772f8a4f1fa8a221de8239e24204e60d073a8a)) - -* Merge pull request #41 from Atticuszz/pre-commit-ci-update-config - -[pre-commit.ci] autoupdate ([`5c418a7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5c418a75669039ec3faff696c4f2e1c713cea5a9)) - -* [pre-commit.ci] auto fixes from pre-commit.com hooks - -for more information, see https://pre-commit.ci ([`8415ddc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8415ddc9d67129c45ecbd594abdcf8c43c12801f)) - -* [pre-commit.ci] autoupdate - -updates: -- https://github.com/myint/autoflake.git → https://github.com/PyCQA/autoflake -- [github.com/psf/black: 23.12.1 → 24.1.1](https://github.com/psf/black/compare/23.12.1...24.1.1) -- [github.com/commitizen-tools/commitizen: v3.13.0 → v3.14.1](https://github.com/commitizen-tools/commitizen/compare/v3.13.0...v3.14.1) ([`ac7e873`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ac7e873435ba7424e8d81dded544b7427a0f8174)) - -* Merge pull request #39 from Atticuszz/dependabot/pip/python-multipart-0.0.7 - -⬆ Bump python-multipart from 0.0.6 to 0.0.7 ([`1e3fb31`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1e3fb31025e261bad376c465876f881c41e5339d)) - -* ⬆ Bump python-multipart from 0.0.6 to 0.0.7 - -Bumps [python-multipart](https://github.com/andrew-d/python-multipart) from 0.0.6 to 0.0.7. -- [Changelog](https://github.com/andrew-d/python-multipart/blob/master/CHANGELOG.md) -- [Commits](https://github.com/andrew-d/python-multipart/compare/0.0.6...0.0.7) - ---- -updated-dependencies: -- dependency-name: python-multipart - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`7735e6f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7735e6f79cf8c4773ec2f3964a33ad0985a0af06)) - -* Merge pull request #38 from Atticuszz/dependabot/pip/supabase-py-async-2.5.1 - -⬆ Bump supabase-py-async from 2.5.0 to 2.5.1 ([`6f00043`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6f0004311f749dc9c2f697f3e56b0b197fa87201)) - -* ⬆ Bump supabase-py-async from 2.5.0 to 2.5.1 - -Bumps [supabase-py-async](https://github.com/Atticuszz/supabase-py_async) from 2.5.0 to 2.5.1. -- [Release notes](https://github.com/Atticuszz/supabase-py_async/releases) -- [Changelog](https://github.com/Atticuszz/supabase-py-async/blob/main/CHANGELOG.md) -- [Commits](https://github.com/Atticuszz/supabase-py_async/compare/v2.5.0...v2.5.1) - ---- -updated-dependencies: -- dependency-name: supabase-py-async - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`202af35`](https://github.com/Atticuszz/fastapi_supabase_template/commit/202af356f49578471b94ca612aa228caad5d39a3)) - -* Merge pull request #37 from Atticuszz/dependabot/github_actions/codecov/codecov-action-4 - -⬆ Bump codecov/codecov-action from 3 to 4 ([`a972c39`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a972c3905e2f5c0d81ccbbdb9c4ea83e0112d388)) - -* ⬆ Bump codecov/codecov-action from 3 to 4 - -Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3 to 4. -- [Release notes](https://github.com/codecov/codecov-action/releases) -- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) -- [Commits](https://github.com/codecov/codecov-action/compare/v3...v4) - ---- -updated-dependencies: -- dependency-name: codecov/codecov-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`05247e2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/05247e208015e1f82abb0d7d7d144a8fa8895f77)) - -* Update latest_changes.yml ([`71da6bf`](https://github.com/Atticuszz/fastapi_supabase_template/commit/71da6bf2298a88c9d53ed04bfa3954ae58c5c0fa)) - -* Merge pull request #36 from Atticuszz/dependabot/pip/pydantic-2.6.0 - -⬆ Bump pydantic from 2.5.3 to 2.6.0 ([`f814449`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f81444974397a60c5c011ea635147975e304be60)) - -* ⬆ Bump pydantic from 2.5.3 to 2.6.0 - -Bumps [pydantic](https://github.com/pydantic/pydantic) from 2.5.3 to 2.6.0. -- [Release notes](https://github.com/pydantic/pydantic/releases) -- [Changelog](https://github.com/pydantic/pydantic/blob/main/HISTORY.md) -- [Commits](https://github.com/pydantic/pydantic/compare/v2.5.3...v2.6.0) - ---- -updated-dependencies: -- dependency-name: pydantic - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`af53220`](https://github.com/Atticuszz/fastapi_supabase_template/commit/af5322045a2dbe6aca26dca7a1d6fc13efe09610)) - -* Merge pull request #34 from Atticuszz/dependabot/pip/aiohttp-3.9.2 - -⬆ Bump aiohttp from 3.9.1 to 3.9.2 ([`2915686`](https://github.com/Atticuszz/fastapi_supabase_template/commit/29156865e985a276f948a07b85de97c79a188030)) - -* ⬆ Bump aiohttp from 3.9.1 to 3.9.2 - -Bumps [aiohttp](https://github.com/aio-libs/aiohttp) from 3.9.1 to 3.9.2. -- [Release notes](https://github.com/aio-libs/aiohttp/releases) -- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst) -- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.9.1...v3.9.2) - ---- -updated-dependencies: -- dependency-name: aiohttp - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`9f46533`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9f4653352ee8195db6a66c0fcc3d1118929b853e)) - -* Merge pull request #33 from Atticuszz/dependabot/pip/pytest-8.0.0 - -⬆ Bump pytest from 7.4.4 to 8.0.0 ([`b70699c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b70699cd52afabf48eec77f97fab02d71a486287)) - -* ⬆ Bump pytest from 7.4.4 to 8.0.0 - -Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.0.0. -- [Release notes](https://github.com/pytest-dev/pytest/releases) -- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) -- [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.0.0) - ---- -updated-dependencies: -- dependency-name: pytest - dependency-type: direct:development - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`638ffee`](https://github.com/Atticuszz/fastapi_supabase_template/commit/638ffee86fc13e1bbd0b21b54982174475dbcb4c)) - -* Merge pull request #32 from Atticuszz/dependabot/pip/uvicorn-0.27.0.post1 - -⬆ Bump uvicorn from 0.27.0 to 0.27.0.post1 ([`c6c8241`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c6c824123d7ef55a5f94054e0fe1895b2a5a3a57)) - -* ⬆ Bump uvicorn from 0.27.0 to 0.27.0.post1 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.27.0 to 0.27.0.post1. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.27.0...0.27.0.post1) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`ff4da4f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ff4da4f73a47891568df4408502baa2500be52b7)) - -* Merge pull request #31 from Atticuszz/dependabot/pip/faker-22.5.1 - -⬆ Bump faker from 22.5.0 to 22.5.1 ([`813405f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/813405fa0dba5fbbde378d98f698b74983cacf73)) - -* ⬆ Bump faker from 22.5.0 to 22.5.1 - -Bumps [faker](https://github.com/joke2k/faker) from 22.5.0 to 22.5.1. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.5.0...v22.5.1) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`bd061a7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/bd061a74bef7881e32334b933572db6281bcbba3)) - -* Merge pull request #29 from Atticuszz/dependabot/pip/python-dotenv-1.0.1 - -⬆ Bump python-dotenv from 1.0.0 to 1.0.1 ([`16086c2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/16086c21f29f6a6e1d07b2fb7327c28867ea6c3e)) - -* ⬆ Bump python-dotenv from 1.0.0 to 1.0.1 - -Bumps [python-dotenv](https://github.com/theskumar/python-dotenv) from 1.0.0 to 1.0.1. -- [Release notes](https://github.com/theskumar/python-dotenv/releases) -- [Changelog](https://github.com/theskumar/python-dotenv/blob/main/CHANGELOG.md) -- [Commits](https://github.com/theskumar/python-dotenv/compare/v1.0.0...v1.0.1) - ---- -updated-dependencies: -- dependency-name: python-dotenv - dependency-type: direct:production - update-type: version-update:semver-patch -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`7bc5361`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7bc5361d28f9680bc5fad640358601fe5d46b9bb)) - -* Merge pull request #28 from Atticuszz/dependabot/pip/uvicorn-0.27.0 - -⬆ Bump uvicorn from 0.26.0 to 0.27.0 ([`44af2fb`](https://github.com/Atticuszz/fastapi_supabase_template/commit/44af2fbe8192f527cb3a32b58cdba3a73487a924)) - -* ⬆ Bump uvicorn from 0.26.0 to 0.27.0 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.26.0 to 0.27.0. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.26.0...0.27.0) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`f5059c2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f5059c2014922b2acdadeb8d8d50d234c89f23a2)) - -* Merge pull request #30 from Atticuszz/dependabot/pip/faker-22.5.0 - -⬆ Bump faker from 22.4.0 to 22.5.0 ([`cb1052d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cb1052d126e6e6ec482401393533b46c3780d099)) - -* ⬆ Bump faker from 22.4.0 to 22.5.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.4.0 to 22.5.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.4.0...v22.5.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`79c0204`](https://github.com/Atticuszz/fastapi_supabase_template/commit/79c02046d9b74506f9cacbc17ddb8c55a7c35060)) - -* Merge pull request #27 from Atticuszz/dependabot/pip/faker-22.4.0 - -⬆ Bump faker from 22.2.0 to 22.4.0 ([`cdc09d6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cdc09d67fc9e82efff4dddef080668e2308640d5)) - -* ⬆ Bump faker from 22.2.0 to 22.4.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.2.0 to 22.4.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.2.0...v22.4.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`37a15a7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/37a15a77f0190217948e31fb247e806a33a0842f)) - -* Merge pull request #26 from Atticuszz/dependabot/pip/uvicorn-0.26.0 - -⬆ Bump uvicorn from 0.25.0 to 0.26.0 ([`f9982a2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f9982a2d27e87e45ad9960652ccf74720af565ee)) - -* ⬆ Bump uvicorn from 0.25.0 to 0.26.0 - -Bumps [uvicorn](https://github.com/encode/uvicorn) from 0.25.0 to 0.26.0. -- [Release notes](https://github.com/encode/uvicorn/releases) -- [Changelog](https://github.com/encode/uvicorn/blob/master/CHANGELOG.md) -- [Commits](https://github.com/encode/uvicorn/compare/0.25.0...0.26.0) - ---- -updated-dependencies: -- dependency-name: uvicorn - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`157fbd0`](https://github.com/Atticuszz/fastapi_supabase_template/commit/157fbd0b2f88b81f55948b68b865d8b3c116f870)) - -* Merge pull request #24 from Atticuszz/dependabot/github_actions/docker/build-push-action-5 - -⬆ Bump docker/build-push-action from 2 to 5 ([`82c37ae`](https://github.com/Atticuszz/fastapi_supabase_template/commit/82c37aefae42d881d02b5a7c62be9693ca8e3f4c)) - -* ⬆ Bump docker/build-push-action from 2 to 5 - -Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 2 to 5. -- [Release notes](https://github.com/docker/build-push-action/releases) -- [Commits](https://github.com/docker/build-push-action/compare/v2...v5) - ---- -updated-dependencies: -- dependency-name: docker/build-push-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`558b3f8`](https://github.com/Atticuszz/fastapi_supabase_template/commit/558b3f83bf01f36e03c102338baf175a58885f81)) - -* Merge pull request #25 from Atticuszz/dependabot/github_actions/docker/login-action-3 - -⬆ Bump docker/login-action from 1 to 3 ([`a4861d2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a4861d25f933d8a2c29cd01e4b10dfa7cc01c87d)) - -* ⬆ Bump docker/login-action from 1 to 3 - -Bumps [docker/login-action](https://github.com/docker/login-action) from 1 to 3. -- [Release notes](https://github.com/docker/login-action/releases) -- [Commits](https://github.com/docker/login-action/compare/v1...v3) - ---- -updated-dependencies: -- dependency-name: docker/login-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`81cfb92`](https://github.com/Atticuszz/fastapi_supabase_template/commit/81cfb92f7d69050335431d6ab72b63c65189a7cc)) - -## v0.3.1 (2024-01-15) - -### Chore - -* chore(release): bump version to v0.3.1 ([`3983912`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3983912cacd42c3a97cc0ccb349bf57dbf90ae6f)) - -* chore: update README.md ([`fa73822`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fa73822af2dfcd5baff78e7ddc75f7840e1c7a4f)) - -* chore: update README.md ([`90dc099`](https://github.com/Atticuszz/fastapi_supabase_template/commit/90dc0994d14beabd76c4048e4f3d71fb677eae82)) - -* chore: Delete .idea directory ([`0e5f4d9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0e5f4d9eb16c65f2f1989e66b9651b83a05c0f92)) - -### Fix - -* fix: bump version to 0.3.1 ([`31d3469`](https://github.com/Atticuszz/fastapi_supabase_template/commit/31d346934e00d627d5116efc0c8186df31244adc)) - -### Unknown - -* chore:Update ci.yml ([`1dfec09`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1dfec094a5c5e36b372aab864b792c13917463de)) - -* Merge branch 'main' of github.com:/Atticuszz/fastapi_supabase_template ([`4a6601f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4a6601f732df054d4c264b5288e36d9d9e8aabfd)) - -* Merge branch 'main' of github.com:/Atticuszz/fastapi_supabase_template ([`39373de`](https://github.com/Atticuszz/fastapi_supabase_template/commit/39373dead79ae45f8afe5deea06f71b4a656c269)) - -## v0.3.0 (2024-01-13) - -### Chore - -* chore(release): bump version to v0.3.0 ([`ee43372`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ee4337261961babf31b9ec5a79a175ea6ca801b7)) - -* chore: update README.md ([`270a350`](https://github.com/Atticuszz/fastapi_supabase_template/commit/270a3500aa70056ebddc3dff01f8d95bd94e98e9)) - -* chore: add Dockerfile ([`1b89e1c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1b89e1c2a79d41236f6ff3cff299d6a0beef8c9e)) - -* chore: RUN pre-commit-hooks ([`f80de2c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f80de2c6884bcb3ae41f01b653992f2f4e30d458)) - -* chore: update README.md ([`59cee0a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/59cee0a091445bdb75a6503e136221ef6831ad42)) - -### Feature - -* feat: add Dockerfile and image push ci ([`421572d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/421572d86354b6f93ec8980a1fa67614237e6ce3)) - -* feat: add Dockerfile ([`2ab91f5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2ab91f59fe152ac5537d612cdc9e62e68061b609)) - -### Fix - -* fix: no need to pass refresh token for validation ,only access_token -chore: bump supabase_py_async to 2.5.0 ([`6c77e46`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6c77e4669049cd234bf4bfe6f36700e400a187b0)) - -### Unknown - -* Merge branch 'main' of github.com:/Atticuszz/fastapi_supabase_template ([`528a197`](https://github.com/Atticuszz/fastapi_supabase_template/commit/528a1973a0e6043d4091995743d0c1c99b358387)) - -* 已添加 supafast.drawio.png ([`b9cace9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b9cace90d44169cc15944c56488f4f2a9bf95ad8)) - -* 更新supafast.drawio.svg ([`e5f8c5b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e5f8c5bfb3158781ec3f5567fdf25323c3f49ad5)) - -* 已添加 supafast.drawio.svg ([`d16864e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d16864e2b53d47048fd6bf5aa55e52a4c2d98fc7)) - -## v0.2.1 (2024-01-13) - -### Chore - -* chore(release): bump version to v0.2.1 ([`ebb6ed6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ebb6ed68a33c190263cad0261a0008f9e7a825e9)) - -* chore: Update ci.yml ([`6c454b7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6c454b702808800d0873621925b7804eb72e538a)) - -* chore: update README.md ([`3844c4f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3844c4f2c978f02c44c09ce3be0523ece7e601a3)) - -* chore: update latest_changes.yml ([`e535440`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e535440224881ec616dd7580a03368d07fbab1dd)) - -* chore: update README.md ([`6efca18`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6efca18086fae9039b2ead2980537603683fdf1a)) - -* chore: add latest_changes.yml ([`dca85c3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/dca85c3cdf96c9f396e750e0a97c2fd19dad1e74)) - -* chore: update README.md ([`0295d3e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0295d3e6edb84793473858eed69aee1d6236d5bd)) - -* chore: update README.md ([`0e55bc6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0e55bc6c3023f720c8fee1e86628c68c34f949a9)) - -* chore: add latest_changes.yml - -Merge pull request #22 from Atticuszz/debuging ([`d6db3a5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d6db3a56bc0e65de708078a7f01dfb9f2d5b46c4)) - -* chore: update README.md ([`9732760`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9732760e6fad463c6f5e4b9a3dc85a1904ef8216)) - -### Unknown - -* chore:update ci - -debuging ([`2fbb785`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2fbb7853bf975a095ec68d1cc6c1eafdc9d4e9fa)) - -* Merge branch 'main' into debuging ([`ea6077e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ea6077e06aa6ddef23550564d058e2b984a3f430)) - -## v0.2.0 (2024-01-13) - -### Chore - -* chore(release): bump version to v0.2.0 ([`0f3cb92`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0f3cb92c3f651a0e128ff174797b2f8162ac5dd6)) - -### Feature - -* feat: release - -debuging ([`e198aef`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e198aefda642ef54be24e4e5aadcbeda1e1d3ae8)) - -## v0.1.0 (2024-01-13) - -### Chore - -* chore(release): bump version to v0.1.0 ([`cecd1e3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cecd1e3848bed23086811ad3477f139564d3dcc4)) - -* chore: update ci ([`aa40254`](https://github.com/Atticuszz/fastapi_supabase_template/commit/aa4025472ebbd5c2d57cd421e1185a6bec74a1fa)) - -### Feature - -* feat: release - -Merge pull request #20 from Atticuszz/debuging ([`57a8f19`](https://github.com/Atticuszz/fastapi_supabase_template/commit/57a8f19a2ed24889d15204e69a2a910277aad8d3)) - -* feat: update ci and README.md ([`e01ae29`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e01ae29f4bde167d5a31e4c500d2040845f61a57)) - -* feat: update ci and README.md ([`971125f`](https://github.com/Atticuszz/fastapi_supabase_template/commit/971125f3e51d741dd80d59a3a074a2f6ff8d733b)) - -* feat: update ci and README.md ([`a491d7d`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a491d7d4b8678f2aedebee74650ec9750e25f785)) - -* feat: update ci and README.md ([`1f4f88c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1f4f88c530d2d6f2fb53460b29efcddd26dbc6c8)) - -### Fix - -* fix: add latest_changes.yml ([`d15b2fa`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d15b2fa7766a7fb12d13ee68cd0acc056c81bfa9)) - -* fix: add latest_changes.yml ([`24927ee`](https://github.com/Atticuszz/fastapi_supabase_template/commit/24927ee71b41ed3846c56f036d81afe3f638a9f0)) - -* fix: add latest_changes.yml ([`9110a7b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9110a7b568b996b6d774fce2dfbad2308bda5293)) - -* fix: add latest_changes.yml ([`c2d9e69`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c2d9e699e44f39f62b2783574c1608bc4a672549)) - -* fix: add latest_changes.yml ([`7d66ee3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7d66ee37db6674d6e467b117665d26b233b45e04)) - -### Unknown - -* Merge pull request #19 from Atticuszz/debuging - -chore:update ci ([`2ad605e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2ad605e0b9342d745dcc0c5c4d1eb91fbff74163)) - -* Merge pull request #18 from Atticuszz/debuging - -fix: update ci latest changes ([`3a30288`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3a30288f6b2bbc97f579218c005c8a7a3a97d2e4)) - -* Merge pull request #17 from Atticuszz/debuging - -feat: upgrade to the first version 0.1.0 ([`d895131`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d89513113601632e784dbd32204e0c07b7db1f4f)) - -* Merge remote-tracking branch 'origin/debuging' into debuging ([`dbd4ca6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/dbd4ca6d1209c86c38f39cd6d1bb07594e63e78a)) - -* Merge branch 'main' into debuging ([`dd3047b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/dd3047b8b0898d194ecb1740a337efc46383dcb1)) - -## v0.0.2 (2024-01-13) - -### Chore - -* chore(release): bump version to v0.0.2 ([`26f5e3b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/26f5e3bb947335bbb359617ffef530be8599767d)) - -* chore(release): bump version to v0.0.2 ([`3fe22f0`](https://github.com/Atticuszz/fastapi_supabase_template/commit/3fe22f0ab60ba97944ab536aa217ae1c41432158)) - -* chore: update README.md ([`8c8fbb5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8c8fbb50f2c5f9cf6321bda5ef93beca80a911aa)) - -* chore: update README.md ([`552f934`](https://github.com/Atticuszz/fastapi_supabase_template/commit/552f934a9c821e018b676d5c55ed461350ef819a)) - -* chore: update ci ([`6608ef7`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6608ef7a19c63bcd89ef7bdb82672f1eed047b3b)) - -* chore: set pro-commit-hooks autofix_prs -> True ([`1bad181`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1bad181c3d093089e0a061a5bce438b02f84d238)) - -* chore: remove latest-changes: ci ([`53dc692`](https://github.com/Atticuszz/fastapi_supabase_template/commit/53dc69258c457e4ce878e7e286dcc12653799810)) - -### Fix - -* fix: fix pytest bug of failed test gotrue client in trio, -feat: add crud test ([`0d22fb1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0d22fb1fd833d815d29e141a913a36e07d7cabdc)) - -### Unknown - -* Merge pull request #16 from Atticuszz/Atticuszz-patch-1 - -Create LICENSE ([`68bd36b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/68bd36be36bbada8c0912a37a64b958013d083f1)) - -* Create LICENSE ([`89e348a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/89e348aa52042bb1507f6faf6a14581352ad35b1)) - -* Merge pull request #15 from Atticuszz/release - -release ([`00adb68`](https://github.com/Atticuszz/fastapi_supabase_template/commit/00adb68e1ccab3fc4f299c2c13bc6f6487d16f07)) - -* Merge pull request #14 from Atticuszz/dependabot/pip/fastapi-0.109.0 - -⬆ Bump fastapi from 0.108.0 to 0.109.0 ([`20ca637`](https://github.com/Atticuszz/fastapi_supabase_template/commit/20ca637f7059c7ffb9add1e68fdba51639235589)) - -* ⬆ Bump fastapi from 0.108.0 to 0.109.0 - -Bumps [fastapi](https://github.com/tiangolo/fastapi) from 0.108.0 to 0.109.0. -- [Release notes](https://github.com/tiangolo/fastapi/releases) -- [Commits](https://github.com/tiangolo/fastapi/compare/0.108.0...0.109.0) - ---- -updated-dependencies: -- dependency-name: fastapi - dependency-type: direct:production - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`7f805e3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7f805e3d6cdb9ab3a999301b9785aa189b9479b8)) - -* Merge pull request #13 from Atticuszz/dependabot/github_actions/abatilo/actions-poetry-3.0.0 - -⬆ Bump abatilo/actions-poetry from 2.4.0 to 3.0.0 ([`c583f38`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c583f389e1ab7ef837693df279f8b27c0f974bc2)) - -* ⬆ Bump abatilo/actions-poetry from 2.4.0 to 3.0.0 - -Bumps [abatilo/actions-poetry](https://github.com/abatilo/actions-poetry) from 2.4.0 to 3.0.0. -- [Release notes](https://github.com/abatilo/actions-poetry/releases) -- [Changelog](https://github.com/abatilo/actions-poetry/blob/master/.releaserc) -- [Commits](https://github.com/abatilo/actions-poetry/compare/v2.4.0...v3.0.0) - ---- -updated-dependencies: -- dependency-name: abatilo/actions-poetry - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`908985a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/908985a01c3d9c22b3d8da17da022de810fa0b7c)) - -* Merge pull request #12 from Atticuszz/dependabot/github_actions/codecov/codecov-action-3 - -⬆ Bump codecov/codecov-action from 1 to 3 ([`56685c3`](https://github.com/Atticuszz/fastapi_supabase_template/commit/56685c32490b2f462d628fe848ad1cb5074223e9)) - -* ⬆ Bump codecov/codecov-action from 1 to 3 - -Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 3. -- [Release notes](https://github.com/codecov/codecov-action/releases) -- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) -- [Commits](https://github.com/codecov/codecov-action/compare/v1...v3) - ---- -updated-dependencies: -- dependency-name: codecov/codecov-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`809a94c`](https://github.com/Atticuszz/fastapi_supabase_template/commit/809a94ce17441dd8bc2ddff42667a3f45e48eb8c)) - -* Merge pull request #11 from Atticuszz/dependabot/github_actions/actions/checkout-4 - -⬆ Bump actions/checkout from 2 to 4 ([`18709da`](https://github.com/Atticuszz/fastapi_supabase_template/commit/18709dabf02b846aec35b85f2c0ec0c6f5ca0665)) - -* ⬆ Bump actions/checkout from 2 to 4 - -Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. -- [Release notes](https://github.com/actions/checkout/releases) -- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) -- [Commits](https://github.com/actions/checkout/compare/v2...v4) - ---- -updated-dependencies: -- dependency-name: actions/checkout - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`f2d6175`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f2d6175f20eb6809b70b556423812973b8fc8037)) - -* Merge pull request #10 from Atticuszz/dependabot/github_actions/actions/setup-python-5 - -⬆ Bump actions/setup-python from 2 to 5 ([`0bc92d4`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0bc92d40054424f005e74706aaf090722fa857a4)) - -* ⬆ Bump actions/setup-python from 2 to 5 - -Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 5. -- [Release notes](https://github.com/actions/setup-python/releases) -- [Commits](https://github.com/actions/setup-python/compare/v2...v5) - ---- -updated-dependencies: -- dependency-name: actions/setup-python - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`08b10dd`](https://github.com/Atticuszz/fastapi_supabase_template/commit/08b10dd163a5c1504257ffb1bf92e054a4ee8313)) - -* Merge pull request #9 from Atticuszz/release - -release ([`f5228f6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f5228f67b15a21ed5575c8c5f79311752f384b0c)) - -* Merge pull request #8 from Atticuszz/release - -release ([`6e9b807`](https://github.com/Atticuszz/fastapi_supabase_template/commit/6e9b8074f7f8c7112dee1b8ee1864a6f1c061d36)) - -* upgrade: release 0.1.0 ([`5738b0e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5738b0edbfc50043205e3cf749c9f8b0cb419d6b)) - -* bugs: failed to auth as dep on new user by access token ([`cba0fbd`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cba0fbdb71c98ddb63545ecbc619bd8d29ffff20)) - -* Merge branch 'main' of github.com:/Atticuszz/fastapi_supabase_template ([`59d9d45`](https://github.com/Atticuszz/fastapi_supabase_template/commit/59d9d45ae449fd6f48fc1d16f1f063b4feea361e)) - -## v0.0.1 (2024-01-11) - -### Chore - -* chore(release): bump version to v0.0.1 ([`4ee5548`](https://github.com/Atticuszz/fastapi_supabase_template/commit/4ee5548fb6d340f7f729f55ae38678817090d578)) - -* chore: update ci ([`80e4db2`](https://github.com/Atticuszz/fastapi_supabase_template/commit/80e4db23f17662b3f7e21ae10624712dfc989a59)) - -* chore: update ci ([`a0f5daa`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a0f5daabdca3cfe93b16db7ab60e499372c6bb69)) - -* chore: update ci,add changelog as pushed ,Publish to GitHub Releases as test passed and merged from PR ([`eeb3d37`](https://github.com/Atticuszz/fastapi_supabase_template/commit/eeb3d377b51198957b4ab2f4bde0aadd559e9cfc)) - -* chore: update ci,add changelog as pushed ,Publish to GitHub Releases as test passed and merged from PR ([`f7b2d7e`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f7b2d7e9798ef89a13d7081b7621a6b4b4c02d0c)) - -### Fix - -* fix: failed to yield AsyncClient -feat: add schema.base, add shared methods in CRUD.base for inheriting ,add anyio as async pytest plugin -to fix: CRUDBase create with wrong url ([`b06fc93`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b06fc936231faa9853f538b60a2d0edb994425be)) - -### Unknown - -* chore:Update pyproject.toml ([`295a2aa`](https://github.com/Atticuszz/fastapi_supabase_template/commit/295a2aac42c3d81d3b7e579f4822bd4b035d50e6)) - -* Chore:Update ci.yml ([`a405374`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a40537437d5e396fb7dcdca782a9b337a76d2e08)) - -* Merge pull request #6 from Atticuszz/dependabot/pip/faker-22.2.0 - -⬆ Bump faker from 22.1.0 to 22.2.0 ([`e1ad025`](https://github.com/Atticuszz/fastapi_supabase_template/commit/e1ad02516a6645758a35910a7b10824fda6b92fe)) - -* ⬆ Bump faker from 22.1.0 to 22.2.0 - -Bumps [faker](https://github.com/joke2k/faker) from 22.1.0 to 22.2.0. -- [Release notes](https://github.com/joke2k/faker/releases) -- [Changelog](https://github.com/joke2k/faker/blob/master/CHANGELOG.md) -- [Commits](https://github.com/joke2k/faker/compare/v22.1.0...v22.2.0) - ---- -updated-dependencies: -- dependency-name: faker - dependency-type: direct:development - update-type: version-update:semver-minor -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`a7dd995`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a7dd995097b5e7fdab7eb86ff96a4eb4ed98199b)) - -* chore:Update ci.yml ([`0ea92f6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0ea92f6de18b76e50d3f3dbd5abb4c133e81ed7d)) - -* Merge branch 'main' of github.com:/Atticuszz/fastapi_supabase_template - -# Conflicts: -# .github/workflows/ci.yml ([`fa0b993`](https://github.com/Atticuszz/fastapi_supabase_template/commit/fa0b99306e116ff25c4f454f158b1a76041e8085)) - -* Merge pull request #2 from Atticuszz/dependabot/github_actions/codecov/codecov-action-3 - -⬆ Bump codecov/codecov-action from 1 to 3 ([`2b93b49`](https://github.com/Atticuszz/fastapi_supabase_template/commit/2b93b49bc8a8e4511881a7482ba73bf9e339c762)) - -* ⬆ Bump codecov/codecov-action from 1 to 3 - -Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 1 to 3. -- [Release notes](https://github.com/codecov/codecov-action/releases) -- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) -- [Commits](https://github.com/codecov/codecov-action/compare/v1...v3) - ---- -updated-dependencies: -- dependency-name: codecov/codecov-action - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`8425445`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8425445a98d3f0016f302486a86a8b01ea381851)) - -* Merge pull request #5 from Atticuszz/dependabot/pip/gitpython-3.1.41 - -⬆ Bump gitpython from 3.1.40 to 3.1.41 ([`9543321`](https://github.com/Atticuszz/fastapi_supabase_template/commit/95433211bae3a51222c138dd39ff111fc709f254)) - -* ⬆ Bump gitpython from 3.1.40 to 3.1.41 - -Bumps [gitpython](https://github.com/gitpython-developers/GitPython) from 3.1.40 to 3.1.41. -- [Release notes](https://github.com/gitpython-developers/GitPython/releases) -- [Changelog](https://github.com/gitpython-developers/GitPython/blob/main/CHANGES) -- [Commits](https://github.com/gitpython-developers/GitPython/compare/3.1.40...3.1.41) - ---- -updated-dependencies: -- dependency-name: gitpython - dependency-type: indirect -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`783ba60`](https://github.com/Atticuszz/fastapi_supabase_template/commit/783ba60e1ca7763110c9c89f596631a4f4608f96)) - -* Merge pull request #4 from Atticuszz/dependabot/github_actions/actions/checkout-4 - -⬆ Bump actions/checkout from 2 to 4 ([`b768155`](https://github.com/Atticuszz/fastapi_supabase_template/commit/b768155e3e53a326a837b96380e1a8b3620a25a2)) - -* ⬆ Bump actions/checkout from 2 to 4 - -Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 4. -- [Release notes](https://github.com/actions/checkout/releases) -- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) -- [Commits](https://github.com/actions/checkout/compare/v2...v4) - ---- -updated-dependencies: -- dependency-name: actions/checkout - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`c4dbf9b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/c4dbf9bb530354e7fc3c3835ca2cc091392fd178)) - -* Merge pull request #3 from Atticuszz/dependabot/github_actions/actions/setup-python-5 - -⬆ Bump actions/setup-python from 2 to 5 ([`d31480b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d31480b79b7c6571eb6cd9d6acef494fbb88afe3)) - -* ⬆ Bump actions/setup-python from 2 to 5 - -Bumps [actions/setup-python](https://github.com/actions/setup-python) from 2 to 5. -- [Release notes](https://github.com/actions/setup-python/releases) -- [Commits](https://github.com/actions/setup-python/compare/v2...v5) - ---- -updated-dependencies: -- dependency-name: actions/setup-python - dependency-type: direct:production - update-type: version-update:semver-major -... - -Signed-off-by: dependabot[bot] <support@github.com> ([`7653a09`](https://github.com/Atticuszz/fastapi_supabase_template/commit/7653a09f1bbf86f1355b20e4351fa8dd818bc899)) - -* add ci ([`cf8644a`](https://github.com/Atticuszz/fastapi_supabase_template/commit/cf8644aa4a80f2ab48ecb49e4e9f00a64098cee9)) - -* add ci ([`1d42ded`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1d42ded51b0f09218d13c9940b5d4e5b1c54dfe7)) - -* removed the auth part ([`d5243b5`](https://github.com/Atticuszz/fastapi_supabase_template/commit/d5243b563a377255d1fa8b79792d013bae583a43)) - -* Update config.py ([`42c0fe1`](https://github.com/Atticuszz/fastapi_supabase_template/commit/42c0fe1fe1cecd606a81b00e43a46c6387485909)) - -* Update main.py ([`150a177`](https://github.com/Atticuszz/fastapi_supabase_template/commit/150a1779b7d16ce9a7df4a771473c4100a646f40)) - -* Update main.py ([`31318df`](https://github.com/Atticuszz/fastapi_supabase_template/commit/31318df05f4340e25fd72cb523f5d1fe2300a5e8)) - -* Update __init__.py ([`8c5e538`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8c5e53866360d0c9ebbd4606b90114c14be68b6f)) - -* Update auth.py ([`0bf8050`](https://github.com/Atticuszz/fastapi_supabase_template/commit/0bf80508649eba5327444db52817e5aeeb71d071)) - -* Update auth.py ([`8f44341`](https://github.com/Atticuszz/fastapi_supabase_template/commit/8f443419e639b59c41aee27f9713bc3d4ddbffc3)) - -* Update auth.py ([`be89b8b`](https://github.com/Atticuszz/fastapi_supabase_template/commit/be89b8b04304635cec109733f280a4fbf26c7062)) - -* Update item.py ([`a838580`](https://github.com/Atticuszz/fastapi_supabase_template/commit/a83858080e891b536c391ed4398aec9f34f8a2b1)) - -* Update item.py ([`5a8f8f4`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5a8f8f4ada8f992fa310f75a1ffec1157716ca7e)) - -* Update auth.py ([`57d63fe`](https://github.com/Atticuszz/fastapi_supabase_template/commit/57d63fe4791209c74fe9e8e513fccf1d4858eb97)) - -* finished item,auth ,crud,router ([`46fb284`](https://github.com/Atticuszz/fastapi_supabase_template/commit/46fb284157a4df7a230a01ba4c44361d95bb9c45)) - -* reshaping ([`f265960`](https://github.com/Atticuszz/fastapi_supabase_template/commit/f2659604fa072363a300163c4c4179dec6a63e41)) - -* reshaping ([`ca81469`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ca81469f82bb0f8da8a4051f9c9413be4a407860)) - -* reshaping ([`686d201`](https://github.com/Atticuszz/fastapi_supabase_template/commit/686d2012174dd1a7f3de05d9c468be4df3f203f6)) - -* reshaping ([`9f6f1e9`](https://github.com/Atticuszz/fastapi_supabase_template/commit/9f6f1e96b005135b3aca4c9b3140e98c8801b1d3)) - -* Create deps.py ([`faf2489`](https://github.com/Atticuszz/fastapi_supabase_template/commit/faf2489ab1dab412d69f417e15cdcc027205a7ae)) - -* Create auth.py ([`1c6f384`](https://github.com/Atticuszz/fastapi_supabase_template/commit/1c6f3844ad00970de0e167816f8ee59f5b06854b)) - -* Delete src/api ([`ad62dbe`](https://github.com/Atticuszz/fastapi_supabase_template/commit/ad62dbe01b8200f9796340f4f9c2ee7cd78aa78f)) - -* init ([`938a3a6`](https://github.com/Atticuszz/fastapi_supabase_template/commit/938a3a63e9a835b56e86c2fdb40b5511735a985e)) - -* Initial commit ([`5a6cbfc`](https://github.com/Atticuszz/fastapi_supabase_template/commit/5a6cbfc56fb876239e5b735a8a9b500a1c72597c)) + diff --git a/pyproject.toml b/pyproject.toml index 40bb5b0..ce1b6c6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,47 +1,245 @@ [project] name = "fastapi_supabase_template" -version = "0.3.1" +version = "0.4.1" description = "" authors = [ {name = "Atticuszz", email = "1831768457@qq.com"}, ] readme = "README.md" -requires-python = ">=3.9,<3.13" +requires-python = ">=3.10" dependencies = [ - "fastapi[full]>=0.111.1", "python-dotenv>=1.0.1", "uvicorn>=0.30.6", "pydantic[email]>=2.8.2", "pydantic-settings>=2.4.0", "python-multipart>=0.0.9", "supabase>=2.7.4", + "fastapi>=0.112.2", ] -[project.optional-dependencies] +[dependency-groups] dev = [ - "pytest-dotenv>=0.5.2", - "pytest>=8.3.2", + "anyio>=4.4.0", + "coverage>=7.6.1", "faker>=28.0.0", - "python-semantic-release>=9.8.5", + "mypy>=1.13.0", "pre-commit>=3.8.0", - "pytest-cov>=5.0.0", - "anyio>=4.4.0", + "pytest>=8.3.2", + "pytest-dotenv>=0.5.2", + "typos>=1.27.0", + "git-cliff>=2.6.1", ] +docs = [ + "mkdocs-git-revision-date-localized-plugin>=1.2.9", + "mkdocs-glightbox>=0.4.0", + "mkdocs-material>=9.5.39", + "mkdocs-obsidian-bridge>=1.1.1", + "mkdocs-publisher>=1.4.2", + "pymdown-extensions>=10.11.1", +] + +## Test +[tool.mypy] +strict = true +exclude = ["venv", ".venv"] + +[tool.pytest.ini_options] +# Set additional command line options for pytest= +# -r= show extra test summary info +# X= show extra info on xfailed tests +# s= don't capture stdout (allow print statements) +# --strict-config= any warnings about configuration are treated as errors +# --strict-markers= treat unregistered markers as errors +addopts = "-rXs --strict-config --strict-markers" +xfail_strict = true # Treat tests that are marked as xfail but pass as test failures +filterwarnings = ["error"] # Treat all warnings as errors + +[tool.coverage.run] +branch = true + +[tool.coverage.report] +skip_covered = true +show_missing = true +precision = 2 +exclude_lines = [ + 'def __repr__', + 'pragma= no cover', + 'raise NotImplementedError', + 'if TYPE_CHECKING=', + 'if typing.TYPE_CHECKING=', + '@overload', + '@typing.overload', + '\(Protocol\)=$', + 'typing.assert_never', + 'assert_never', + 'if __name__ == .__main__.=', +] + + +## Linter and formatter +[tool.ruff] +# cover and extend the default config in https=//docs.astral.sh/ruff/configuration/ +extend-exclude = [""] +target-version = "py310" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "UP", # pyupgrade + "ARG001", # unused arguments in functions +] +ignore = [ + "E501", # line too long, handled by black + "B008", # do not perform function calls in argument defaults + "W191", # indentation contains tabs + "B904", # Allow raising exceptions without from e, for HTTPException + "COM819", # Trailing comma prohibited + "D100", # Missing docstring in public module(file) + "D104", # Missing docstring in public package + "D203", # 1 blank line required before class docstring + "E201", # Whitespace after '(' + "E202", # Whitespace before ')' + "E203", # Whitespace before '=' + "E221", # Multiple spaces before operator + "E241", # Multiple spaces after ',' + "E251", # Unexpected spaces around keyword / parameter equals + "W291", # Trailing whitespace + "W293", # Blank line contains whitespace +] + +isort = { combine-as-imports = true, split-on-trailing-comma = false } + +# Avoid trying to fix flake8-bugbear (`B`) violations. +unfixable = ["B"] + +[tool.ruff.format] +docstring-code-format = true +skip-magic-trailing-comma = true + +# Reference +# 1. https=//github.com/Kludex/python-template/blob/main/template/%7B%7B%20project_slug%20%7D%7D/pyproject.toml.jinja +# 2. https=//github.com/fastapi/full-stack-fastapi-template/blob/master/backend/pyproject.toml +# 3. https=//github.com/pydantic/logfire +# 4. https=//coverage.readthedocs.io/en/latest/index.html + + +## VCS +[tool.git-cliff.remote.github] +owner = "atticuszz" +repo = "fastapi_supabase_template" + +[tool.git-cliff.changelog] +# template for the changelog header +header = """ +# Changelog\n +All notable changes to this project will be documented in this file.\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#introduction +body = """ +{% if version %}\ + ## {{ version | trim_start_matches(pat="v") }} - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## unreleased +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | striptags | trim | upper_first }} + {% for commit in commits| unique(attribute="message") %} + - {% if commit.scope %}*({{ commit.scope }})* {% endif %}\ + {% if commit.breaking %}[**breaking**] {% endif %}\ + {{ commit.message | upper_first }}\ + {% if commit.remote.pr_number %} in #{{ commit.remote.pr_number }}{%- endif %}\ + {% endfor %} +{% endfor %}\n +""" +# template for the changelog footer +footer = """ + +""" +# remove the leading and trailings +trim = true +# postprocessors +# postprocessors = [ +# { pattern = '', replace = "https://github.com/atticuszz/python-uv" }, # replace repository URL +# ] +# render body even when there are no releases to process +render_always = true +# output file path +output = "CHANGELOG.md" + +[tool.git-cliff.git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = true +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + # If the spelling is incorrect, it will be automatically fixed. + { pattern = '.*', replace_command = 'typos --write-changes -' } +] +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "🚀 Features" }, + { message = "^fix", group = "🐛 Bug Fixes" }, + { message = "^doc", group = "📚 Documentation" }, + { message = "^perf", group = "⚡ Performance" }, + { message = "^refactor", group = "🚜 Refactor" }, + { message = "^style", group = "🎨 Styling" }, + { message = "^test", group = "🧪 Testing" }, + { message = "^chore\\(release\\)", skip = true }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" }, + { body = ".*security", group = "🛡️ Security" }, + { message = "^revert", group = "◀️ Revert" }, +] +# filter out the commits that are not matched by commit parsers +filter_commits = false +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" + + +[tool.bumpversion] +current_version = "0.4.1" +parse = "(?P\\d+)\\.(?P\\d+)\\.(?P\\d+)" +serialize = ["{major}.{minor}.{patch}"] +search = "{current_version}" +replace = "{new_version}" +regex = false +ignore_missing_version = false +ignore_missing_files = false +tag = true +sign_tags = false +tag_name = "v{new_version}" +tag_message = "chore(release): {current_version} → {new_version}" +allow_dirty = true # git-cliff first then bump patch +commit = true +message = "chore(release): {current_version} → {new_version}" +commit_args = "" +setup_hooks = [] +pre_commit_hooks = [] +post_commit_hooks = [] +[[tool.bumpversion.files]] +filename = "pyproject.toml" +search = 'version = "{current_version}"' +replace = 'version = "{new_version}"' +[[tool.bumpversion.files]] +filename = "CHANGELOG.md" +search = "unreleased" +replace = "{new_version} - {now:%Y-%m-%d}" -[build-system] -requires = ["hatchling"] -build-backend = "hatchling.build" -[tool.hatch.build.targets.wheel] -packages = ["src/app"] -[tool.semantic_release] -version_variable = "pyproject.toml:project.version" -branch = "main" -upload_to_PyPI = false -upload_to_release = true -build_command = "pip install build && python -m build" -commit_message = "chore(release): bump version to v{version}" -changelog_components = "semantic_release.changelog.changelog_headers,semantic_release.changelog.compare_url" +# https://callowayproject.github.io/bump-my-version/reference/search-and-replace-config/ diff --git a/scripts.py b/scripts.py deleted file mode 100644 index 6fec3d1..0000000 --- a/scripts.py +++ /dev/null @@ -1,23 +0,0 @@ -import subprocess - - -def run_cmd(cmd: str) -> None: - subprocess.run(cmd, shell=True, check=True) - - -def run_tests() -> None: - # Install requirements by poetry - run_cmd("uv sync --all-extras --dev") - - # Run pre-commit tests - # run_cmd("poetry run pre-commit autoupdate") - # run_cmd("poetry run pre-commit clean") - # run_cmd("poetry run pre-commit install") - run_cmd("uv run pre-commit run --all-files") - - # Generate coverage report --cov=./ --cov-report=xml --cov-report=html -vv - run_cmd("uv run pytest --cov=./ --cov-report=xml --cov-report=html -vv") - - -if __name__ == "__main__": - run_tests() diff --git a/uv.lock b/uv.lock index fa62575..b504765 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,9 @@ version = 1 -requires-python = ">=3.9, <3.13" +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.13'", + "python_full_version >= '3.13'", +] [[package]] name = "aiohappyeyeballs" @@ -85,21 +89,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d5/bc/d01ff0810b3f5e26896f76d44225ed78b088ddd33079b85cd1a23514318b/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987", size = 1299976 }, { url = "https://files.pythonhosted.org/packages/3e/c9/50a297c4f7ab57a949f4add2d3eafe5f3e68bb42f739e933f8b32a092bda/aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04", size = 355609 }, { url = "https://files.pythonhosted.org/packages/65/28/aee9d04fb0b3b1f90622c338a08e54af5198e704a910e20947c473298fd0/aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022", size = 375697 }, - { url = "https://files.pythonhosted.org/packages/7d/0f/6bcda6528ba2ae65c58e62d63c31ada74b0d761efbb6678d19a447520392/aiohttp-3.10.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7e2fe37ac654032db1f3499fe56e77190282534810e2a8e833141a021faaab0e", size = 588725 }, - { url = "https://files.pythonhosted.org/packages/3b/db/c818fd1c254bcb7af4ca75b69c89ee58807e11d9338348065d1b549a9ee7/aiohttp-3.10.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f5bf3ead3cb66ab990ee2561373b009db5bc0e857549b6c9ba84b20bc462e172", size = 398568 }, - { url = "https://files.pythonhosted.org/packages/6a/56/4a1e41e632c97d2848dfb866a87f6802b9541c0720cc1017a5002cd58873/aiohttp-3.10.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1b2c16a919d936ca87a3c5f0e43af12a89a3ce7ccbce59a2d6784caba945b68b", size = 389860 }, - { url = "https://files.pythonhosted.org/packages/86/d0/c0eb2bbdc2808b80432b6c1a56e2db433fac8c84247f895a30f13be2b68d/aiohttp-3.10.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad146dae5977c4dd435eb31373b3fe9b0b1bf26858c6fc452bf6af394067e10b", size = 1253862 }, - { url = "https://files.pythonhosted.org/packages/8e/61/2f46f41bf4491cdfb6d599a486bc426332f103773a4e8003b2b09d2b7b2e/aiohttp-3.10.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c5c6fa16412b35999320f5c9690c0f554392dc222c04e559217e0f9ae244b92", size = 1289926 }, - { url = "https://files.pythonhosted.org/packages/88/83/e846ae7546a056e271823c02c3002cc6e722c95bce32582cf3e8578c7b0b/aiohttp-3.10.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:95c4dc6f61d610bc0ee1edc6f29d993f10febfe5b76bb470b486d90bbece6b22", size = 1325020 }, - { url = "https://files.pythonhosted.org/packages/23/69/200bf165b56c17854d54975f894de10dababc4d0226c07600c9abc679e7e/aiohttp-3.10.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:da452c2c322e9ce0cfef392e469a26d63d42860f829026a63374fde6b5c5876f", size = 1246350 }, - { url = "https://files.pythonhosted.org/packages/ca/45/d5f6ec14e948d1c72c91f743de5b5f26a476c81151082910002b59c84e0b/aiohttp-3.10.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:898715cf566ec2869d5cb4d5fb4be408964704c46c96b4be267442d265390f32", size = 1216314 }, - { url = "https://files.pythonhosted.org/packages/9b/c7/2078ebb25cfcd0ebadbc451b508f09fe37e3ca3a2fbe3b2791d00912d31c/aiohttp-3.10.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:391cc3a9c1527e424c6865e087897e766a917f15dddb360174a70467572ac6ce", size = 1216766 }, - { url = "https://files.pythonhosted.org/packages/d9/59/25f96afdc4f6ba845feb607026b632181b37fc4e3242e4dce3d71a0afaa1/aiohttp-3.10.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:380f926b51b92d02a34119d072f178d80bbda334d1a7e10fa22d467a66e494db", size = 1216190 }, - { url = "https://files.pythonhosted.org/packages/f1/cb/2b6e003cdd3388454b183aabb91b15db9ac5b47eb224d3b6436f938e7380/aiohttp-3.10.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce91db90dbf37bb6fa0997f26574107e1b9d5ff939315247b7e615baa8ec313b", size = 1271316 }, - { url = "https://files.pythonhosted.org/packages/71/1c/1ce6e7a0376ebb861521c96ed47eda1e0c2e9c80c0407e431b46cecc4bfb/aiohttp-3.10.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9093a81e18c45227eebe4c16124ebf3e0d893830c6aca7cc310bfca8fe59d857", size = 1288007 }, - { url = "https://files.pythonhosted.org/packages/01/0c/4e8db6e6d8f3b655d762530a083ea729b5d1ed479ddc55881d845bcd4795/aiohttp-3.10.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:ee40b40aa753d844162dcc80d0fe256b87cba48ca0054f64e68000453caead11", size = 1238304 }, - { url = "https://files.pythonhosted.org/packages/4c/bd/69a87f5fd0070e339eb4f62d0ca61e87f85bde492746401852cd40f5113c/aiohttp-3.10.5-cp39-cp39-win32.whl", hash = "sha256:03f2645adbe17f274444953bdea69f8327e9d278d961d85657cb0d06864814c1", size = 360755 }, - { url = "https://files.pythonhosted.org/packages/8d/e9/cfdf2e0132860976514439c8a50b57fc8d65715d77eeec0e5b150e9c6a96/aiohttp-3.10.5-cp39-cp39-win_amd64.whl", hash = "sha256:d17920f18e6ee090bdd3d0bfffd769d9f2cb4c8ffde3eb203777a3895c128862", size = 379781 }, ] [[package]] @@ -156,6 +145,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, ] +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + [[package]] name = "certifi" version = "2024.8.30" @@ -176,71 +186,71 @@ wheels = [ [[package]] name = "charset-normalizer" -version = "3.3.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/63/09/c1bc53dab74b1816a00d8d030de5bf98f724c52c1635e07681d312f20be8/charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5", size = 104809 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2b/61/095a0aa1a84d1481998b534177c8566fdc50bb1233ea9a0478cd3cc075bd/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3", size = 194219 }, - { url = "https://files.pythonhosted.org/packages/cc/94/f7cf5e5134175de79ad2059edf2adce18e0685ebdb9227ff0139975d0e93/charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027", size = 122521 }, - { url = "https://files.pythonhosted.org/packages/46/6a/d5c26c41c49b546860cc1acabdddf48b0b3fb2685f4f5617ac59261b44ae/charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03", size = 120383 }, - { url = "https://files.pythonhosted.org/packages/b8/60/e2f67915a51be59d4539ed189eb0a2b0d292bf79270410746becb32bc2c3/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d", size = 138223 }, - { url = "https://files.pythonhosted.org/packages/05/8c/eb854996d5fef5e4f33ad56927ad053d04dc820e4a3d39023f35cad72617/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e", size = 148101 }, - { url = "https://files.pythonhosted.org/packages/f6/93/bb6cbeec3bf9da9b2eba458c15966658d1daa8b982c642f81c93ad9b40e1/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6", size = 140699 }, - { url = "https://files.pythonhosted.org/packages/da/f1/3702ba2a7470666a62fd81c58a4c40be00670e5006a67f4d626e57f013ae/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5", size = 142065 }, - { url = "https://files.pythonhosted.org/packages/3f/ba/3f5e7be00b215fa10e13d64b1f6237eb6ebea66676a41b2bcdd09fe74323/charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537", size = 144505 }, - { url = "https://files.pythonhosted.org/packages/33/c3/3b96a435c5109dd5b6adc8a59ba1d678b302a97938f032e3770cc84cd354/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c", size = 139425 }, - { url = "https://files.pythonhosted.org/packages/43/05/3bf613e719efe68fb3a77f9c536a389f35b95d75424b96b426a47a45ef1d/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12", size = 145287 }, - { url = "https://files.pythonhosted.org/packages/58/78/a0bc646900994df12e07b4ae5c713f2b3e5998f58b9d3720cce2aa45652f/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f", size = 149929 }, - { url = "https://files.pythonhosted.org/packages/eb/5c/97d97248af4920bc68687d9c3b3c0f47c910e21a8ff80af4565a576bd2f0/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269", size = 141605 }, - { url = "https://files.pythonhosted.org/packages/a8/31/47d018ef89f95b8aded95c589a77c072c55e94b50a41aa99c0a2008a45a4/charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519", size = 142646 }, - { url = "https://files.pythonhosted.org/packages/ae/d5/4fecf1d58bedb1340a50f165ba1c7ddc0400252d6832ff619c4568b36cc0/charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73", size = 92846 }, - { url = "https://files.pythonhosted.org/packages/a2/a0/4af29e22cb5942488cf45630cbdd7cefd908768e69bdd90280842e4e8529/charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09", size = 100343 }, - { url = "https://files.pythonhosted.org/packages/68/77/02839016f6fbbf808e8b38601df6e0e66c17bbab76dff4613f7511413597/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db", size = 191647 }, - { url = "https://files.pythonhosted.org/packages/3e/33/21a875a61057165e92227466e54ee076b73af1e21fe1b31f1e292251aa1e/charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96", size = 121434 }, - { url = "https://files.pythonhosted.org/packages/dd/51/68b61b90b24ca35495956b718f35a9756ef7d3dd4b3c1508056fa98d1a1b/charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e", size = 118979 }, - { url = "https://files.pythonhosted.org/packages/e4/a6/7ee57823d46331ddc37dd00749c95b0edec2c79b15fc0d6e6efb532e89ac/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f", size = 136582 }, - { url = "https://files.pythonhosted.org/packages/74/f1/0d9fe69ac441467b737ba7f48c68241487df2f4522dd7246d9426e7c690e/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574", size = 146645 }, - { url = "https://files.pythonhosted.org/packages/05/31/e1f51c76db7be1d4aef220d29fbfa5dbb4a99165d9833dcbf166753b6dc0/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4", size = 139398 }, - { url = "https://files.pythonhosted.org/packages/40/26/f35951c45070edc957ba40a5b1db3cf60a9dbb1b350c2d5bef03e01e61de/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8", size = 140273 }, - { url = "https://files.pythonhosted.org/packages/07/07/7e554f2bbce3295e191f7e653ff15d55309a9ca40d0362fcdab36f01063c/charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc", size = 142577 }, - { url = "https://files.pythonhosted.org/packages/d8/b5/eb705c313100defa57da79277d9207dc8d8e45931035862fa64b625bfead/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae", size = 137747 }, - { url = "https://files.pythonhosted.org/packages/19/28/573147271fd041d351b438a5665be8223f1dd92f273713cb882ddafe214c/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887", size = 143375 }, - { url = "https://files.pythonhosted.org/packages/cf/7c/f3b682fa053cc21373c9a839e6beba7705857075686a05c72e0f8c4980ca/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/1e/49/7ab74d4ac537ece3bc3334ee08645e231f39f7d6df6347b29a74b0537103/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce", size = 140232 }, - { url = "https://files.pythonhosted.org/packages/2d/dc/9dacba68c9ac0ae781d40e1a0c0058e26302ea0660e574ddf6797a0347f7/charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f", size = 140859 }, - { url = "https://files.pythonhosted.org/packages/6c/c2/4a583f800c0708dd22096298e49f887b49d9746d0e78bfc1d7e29816614c/charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab", size = 92509 }, - { url = "https://files.pythonhosted.org/packages/57/ec/80c8d48ac8b1741d5b963797b7c0c869335619e13d4744ca2f67fc11c6fc/charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77", size = 99870 }, - { url = "https://files.pythonhosted.org/packages/d1/b2/fcedc8255ec42afee97f9e6f0145c734bbe104aac28300214593eb326f1d/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8", size = 192892 }, - { url = "https://files.pythonhosted.org/packages/2e/7d/2259318c202f3d17f3fe6438149b3b9e706d1070fe3fcbb28049730bb25c/charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b", size = 122213 }, - { url = "https://files.pythonhosted.org/packages/3a/52/9f9d17c3b54dc238de384c4cb5a2ef0e27985b42a0e5cc8e8a31d918d48d/charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6", size = 119404 }, - { url = "https://files.pythonhosted.org/packages/99/b0/9c365f6d79a9f0f3c379ddb40a256a67aa69c59609608fe7feb6235896e1/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a", size = 137275 }, - { url = "https://files.pythonhosted.org/packages/91/33/749df346e93d7a30cdcb90cbfdd41a06026317bfbfb62cd68307c1a3c543/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389", size = 147518 }, - { url = "https://files.pythonhosted.org/packages/72/1a/641d5c9f59e6af4c7b53da463d07600a695b9824e20849cb6eea8a627761/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa", size = 140182 }, - { url = "https://files.pythonhosted.org/packages/ee/fb/14d30eb4956408ee3ae09ad34299131fb383c47df355ddb428a7331cfa1e/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b", size = 141869 }, - { url = "https://files.pythonhosted.org/packages/df/3e/a06b18788ca2eb6695c9b22325b6fde7dde0f1d1838b1792a0076f58fe9d/charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed", size = 144042 }, - { url = "https://files.pythonhosted.org/packages/45/59/3d27019d3b447a88fe7e7d004a1e04be220227760264cc41b405e863891b/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26", size = 138275 }, - { url = "https://files.pythonhosted.org/packages/7b/ef/5eb105530b4da8ae37d506ccfa25057961b7b63d581def6f99165ea89c7e/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d", size = 144819 }, - { url = "https://files.pythonhosted.org/packages/a2/51/e5023f937d7f307c948ed3e5c29c4b7a3e42ed2ee0b8cdf8f3a706089bf0/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068", size = 149415 }, - { url = "https://files.pythonhosted.org/packages/24/9d/2e3ef673dfd5be0154b20363c5cdcc5606f35666544381bee15af3778239/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143", size = 141212 }, - { url = "https://files.pythonhosted.org/packages/5b/ae/ce2c12fcac59cb3860b2e2d76dc405253a4475436b1861d95fe75bdea520/charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4", size = 142167 }, - { url = "https://files.pythonhosted.org/packages/ed/3a/a448bf035dce5da359daf9ae8a16b8a39623cc395a2ffb1620aa1bce62b0/charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7", size = 93041 }, - { url = "https://files.pythonhosted.org/packages/b6/7c/8debebb4f90174074b827c63242c23851bdf00a532489fba57fef3416e40/charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001", size = 100397 }, - { url = "https://files.pythonhosted.org/packages/f7/9d/bcf4a449a438ed6f19790eee543a86a740c77508fbc5ddab210ab3ba3a9a/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4", size = 194198 }, - { url = "https://files.pythonhosted.org/packages/66/fe/c7d3da40a66a6bf2920cce0f436fa1f62ee28aaf92f412f0bf3b84c8ad6c/charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d", size = 122494 }, - { url = "https://files.pythonhosted.org/packages/2a/9d/a6d15bd1e3e2914af5955c8eb15f4071997e7078419328fee93dfd497eb7/charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0", size = 120393 }, - { url = "https://files.pythonhosted.org/packages/3d/85/5b7416b349609d20611a64718bed383b9251b5a601044550f0c8983b8900/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269", size = 138331 }, - { url = "https://files.pythonhosted.org/packages/79/66/8946baa705c588521afe10b2d7967300e49380ded089a62d38537264aece/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c", size = 148097 }, - { url = "https://files.pythonhosted.org/packages/44/80/b339237b4ce635b4af1c73742459eee5f97201bd92b2371c53e11958392e/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519", size = 140711 }, - { url = "https://files.pythonhosted.org/packages/98/69/5d8751b4b670d623aa7a47bef061d69c279e9f922f6705147983aa76c3ce/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796", size = 142251 }, - { url = "https://files.pythonhosted.org/packages/1f/8d/33c860a7032da5b93382cbe2873261f81467e7b37f4ed91e25fed62fd49b/charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185", size = 144636 }, - { url = "https://files.pythonhosted.org/packages/c2/65/52aaf47b3dd616c11a19b1052ce7fa6321250a7a0b975f48d8c366733b9f/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c", size = 139514 }, - { url = "https://files.pythonhosted.org/packages/51/fd/0ee5b1c2860bb3c60236d05b6e4ac240cf702b67471138571dad91bcfed8/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458", size = 145528 }, - { url = "https://files.pythonhosted.org/packages/e1/9c/60729bf15dc82e3aaf5f71e81686e42e50715a1399770bcde1a9e43d09db/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2", size = 149804 }, - { url = "https://files.pythonhosted.org/packages/53/cd/aa4b8a4d82eeceb872f83237b2d27e43e637cac9ffaef19a1321c3bafb67/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8", size = 141708 }, - { url = "https://files.pythonhosted.org/packages/54/7f/cad0b328759630814fcf9d804bfabaf47776816ad4ef2e9938b7e1123d04/charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561", size = 142708 }, - { url = "https://files.pythonhosted.org/packages/c1/9d/254a2f1bcb0ce9acad838e94ed05ba71a7cb1e27affaa4d9e1ca3958cdb6/charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f", size = 92830 }, - { url = "https://files.pythonhosted.org/packages/2f/0e/d7303ccae9735ff8ff01e36705ad6233ad2002962e8668a970fc000c5e1b/charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d", size = 100376 }, - { url = "https://files.pythonhosted.org/packages/28/76/e6222113b83e3622caa4bb41032d0b1bf785250607392e1b778aca0b8a7d/charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc", size = 48543 }, +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, + { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, + { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, + { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, + { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, + { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, + { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, + { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, + { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, + { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, + { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, + { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, + { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, + { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, + { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, + { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, + { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, + { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, + { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, + { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, + { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, + { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, + { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, + { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, + { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, + { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, + { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, + { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, + { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, + { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, + { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, + { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, + { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, + { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, + { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, + { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, + { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, + { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, + { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, + { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, + { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, + { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, + { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, + { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, + { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, + { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, + { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, + { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, + { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, + { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, + { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, + { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, + { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, + { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, + { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, + { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, + { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, + { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, + { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, + { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, + { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, ] [[package]] @@ -255,18 +265,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, ] -[[package]] -name = "click-option-group" -version = "0.5.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e7/b8/91054601a2e05fd9060cb1baf56be5b24145817b059e078669e1099529c7/click-option-group-0.5.6.tar.gz", hash = "sha256:97d06703873518cc5038509443742b25069a3c7562d1ea72ff08bfadde1ce777", size = 16517 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/75/81ea958bc0f7e410257cb2a42531b93a7695a31930cde87192c010a52c50/click_option_group-0.5.6-py3-none-any.whl", hash = "sha256:38a26d963ee3ad93332ddf782f9259c5bdfe405e73408d943ef5e7d0c3767ec7", size = 12467 }, -] - [[package]] name = "colorama" version = "0.4.6" @@ -332,24 +330,9 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598 }, { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307 }, { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453 }, - { url = "https://files.pythonhosted.org/packages/19/d3/d54c5aa83268779d54c86deb39c1c4566e5d45c155369ca152765f8db413/coverage-7.6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abd5fd0db5f4dc9289408aaf34908072f805ff7792632250dcb36dc591d24255", size = 206688 }, - { url = "https://files.pythonhosted.org/packages/a5/fe/137d5dca72e4a258b1bc17bb04f2e0196898fe495843402ce826a7419fe3/coverage-7.6.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:547f45fa1a93154bd82050a7f3cddbc1a7a4dd2a9bf5cb7d06f4ae29fe94eaf8", size = 207120 }, - { url = "https://files.pythonhosted.org/packages/78/5b/a0a796983f3201ff5485323b225d7c8b74ce30c11f456017e23d8e8d1945/coverage-7.6.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:645786266c8f18a931b65bfcefdbf6952dd0dea98feee39bd188607a9d307ed2", size = 235249 }, - { url = "https://files.pythonhosted.org/packages/4e/e1/76089d6a5ef9d68f018f65411fcdaaeb0141b504587b901d74e8587606ad/coverage-7.6.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e0b2df163b8ed01d515807af24f63de04bebcecbd6c3bfeff88385789fdf75a", size = 233237 }, - { url = "https://files.pythonhosted.org/packages/9a/6f/eef79b779a540326fee9520e5542a8b428cc3bfa8b7c8f1022c1ee4fc66c/coverage-7.6.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:609b06f178fe8e9f89ef676532760ec0b4deea15e9969bf754b37f7c40326dbc", size = 234311 }, - { url = "https://files.pythonhosted.org/packages/75/e1/656d65fb126c29a494ef964005702b012f3498db1a30dd562958e85a4049/coverage-7.6.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:702855feff378050ae4f741045e19a32d57d19f3e0676d589df0575008ea5004", size = 233453 }, - { url = "https://files.pythonhosted.org/packages/68/6a/45f108f137941a4a1238c85f28fd9d048cc46b5466d6b8dda3aba1bb9d4f/coverage-7.6.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:2bdb062ea438f22d99cba0d7829c2ef0af1d768d1e4a4f528087224c90b132cb", size = 231958 }, - { url = "https://files.pythonhosted.org/packages/9b/e7/47b809099168b8b8c72ae311efc3e88c8d8a1162b3ba4b8da3cfcdb85743/coverage-7.6.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c56863d44bd1c4fe2abb8a4d6f5371d197f1ac0ebdee542f07f35895fc07f36", size = 232938 }, - { url = "https://files.pythonhosted.org/packages/52/80/052222ba7058071f905435bad0ba392cc12006380731c37afaf3fe749b88/coverage-7.6.1-cp39-cp39-win32.whl", hash = "sha256:6e2cd258d7d927d09493c8df1ce9174ad01b381d4729a9d8d4e38670ca24774c", size = 209352 }, - { url = "https://files.pythonhosted.org/packages/b8/d8/1b92e0b3adcf384e98770a00ca095da1b5f7b483e6563ae4eb5e935d24a1/coverage-7.6.1-cp39-cp39-win_amd64.whl", hash = "sha256:06a737c882bd26d0d6ee7269b20b12f14a8704807a01056c80bb881a4b2ce6ca", size = 210153 }, { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926 }, ] -[package.optional-dependencies] -toml = [ - { name = "tomli", marker = "python_full_version <= '3.11'" }, -] - [[package]] name = "deprecation" version = "2.1.0" @@ -380,15 +363,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 }, ] -[[package]] -name = "dotty-dict" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/6a/ab/88d67f02024700b48cd8232579ad1316aa9df2272c63049c27cc094229d6/dotty_dict-1.3.1.tar.gz", hash = "sha256:4b016e03b8ae265539757a53eba24b9bfda506fb94fbce0bee843c6f05541a15", size = 7699 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1a/91/e0d457ee03ec33d79ee2cd8d212debb1bc21dfb99728ae35efdb5832dc22/dotty_dict-1.3.1-py3-none-any.whl", hash = "sha256:5022d234d9922f13aa711b4950372a06a6d64cb6d6db9ba43d0ba133ebfce31f", size = 7014 }, -] - [[package]] name = "email-validator" version = "2.2.0" @@ -439,8 +413,8 @@ wheels = [ [[package]] name = "fastapi-supabase-template" -version = "0.3.1" -source = { editable = "." } +version = "0.4.1" +source = { virtual = "." } dependencies = [ { name = "fastapi" }, { name = "pydantic", extra = ["email"] }, @@ -451,35 +425,59 @@ dependencies = [ { name = "uvicorn" }, ] -[package.optional-dependencies] +[package.dev-dependencies] dev = [ { name = "anyio" }, + { name = "coverage" }, { name = "faker" }, + { name = "git-cliff" }, + { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, - { name = "pytest-cov" }, { name = "pytest-dotenv" }, - { name = "python-semantic-release" }, + { name = "typos" }, +] +docs = [ + { name = "mkdocs-git-revision-date-localized-plugin" }, + { name = "mkdocs-glightbox" }, + { name = "mkdocs-material" }, + { name = "mkdocs-obsidian-bridge" }, + { name = "mkdocs-publisher" }, + { name = "pymdown-extensions" }, ] [package.metadata] requires-dist = [ - { name = "anyio", marker = "extra == 'dev'", specifier = ">=4.4.0" }, - { name = "faker", marker = "extra == 'dev'", specifier = ">=28.0.0" }, - { name = "fastapi", extras = ["full"], specifier = ">=0.111.1" }, - { name = "pre-commit", marker = "extra == 'dev'", specifier = ">=3.8.0" }, + { name = "fastapi", specifier = ">=0.112.2" }, { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, { name = "pydantic-settings", specifier = ">=2.4.0" }, - { name = "pytest", marker = "extra == 'dev'", specifier = ">=8.3.2" }, - { name = "pytest-cov", marker = "extra == 'dev'", specifier = ">=5.0.0" }, - { name = "pytest-dotenv", marker = "extra == 'dev'", specifier = ">=0.5.2" }, { name = "python-dotenv", specifier = ">=1.0.1" }, { name = "python-multipart", specifier = ">=0.0.9" }, - { name = "python-semantic-release", marker = "extra == 'dev'", specifier = ">=9.8.5" }, { name = "supabase", specifier = ">=2.7.4" }, { name = "uvicorn", specifier = ">=0.30.6" }, ] +[package.metadata.requires-dev] +dev = [ + { name = "anyio", specifier = ">=4.4.0" }, + { name = "coverage", specifier = ">=7.6.1" }, + { name = "faker", specifier = ">=28.0.0" }, + { name = "git-cliff", specifier = ">=2.6.1" }, + { name = "mypy", specifier = ">=1.13.0" }, + { name = "pre-commit", specifier = ">=3.8.0" }, + { name = "pytest", specifier = ">=8.3.2" }, + { name = "pytest-dotenv", specifier = ">=0.5.2" }, + { name = "typos", specifier = ">=1.27.0" }, +] +docs = [ + { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2.9" }, + { name = "mkdocs-glightbox", specifier = ">=0.4.0" }, + { name = "mkdocs-material", specifier = ">=9.5.39" }, + { name = "mkdocs-obsidian-bridge", specifier = ">=1.1.1" }, + { name = "mkdocs-publisher", specifier = ">=1.4.2" }, + { name = "pymdown-extensions", specifier = ">=10.11.1" }, +] + [[package]] name = "filelock" version = "3.15.4" @@ -540,24 +538,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, - { url = "https://files.pythonhosted.org/packages/d3/fb/6f2a22086065bc16797f77168728f0e59d5b89be76dd184e06b404f1e43b/frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e", size = 97291 }, - { url = "https://files.pythonhosted.org/packages/4d/23/7f01123d0e5adcc65cbbde5731378237dea7db467abd19e391f1ddd4130d/frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d", size = 55249 }, - { url = "https://files.pythonhosted.org/packages/8b/c9/a81e9af48291954a883d35686f32308238dc968043143133b8ac9e2772af/frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8", size = 53676 }, - { url = "https://files.pythonhosted.org/packages/57/15/172af60c7e150a1d88ecc832f2590721166ae41eab582172fe1e9844eab4/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0", size = 239365 }, - { url = "https://files.pythonhosted.org/packages/8c/a4/3dc43e259960ad268ef8f2bf92912c2d2cd2e5275a4838804e03fd6f085f/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b", size = 265592 }, - { url = "https://files.pythonhosted.org/packages/a0/c1/458cf031fc8cd29a751e305b1ec773785ce486106451c93986562c62a21e/frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0", size = 261274 }, - { url = "https://files.pythonhosted.org/packages/4a/32/21329084b61a119ecce0b2942d30312a34a7a0dccd01dcf7b40bda80f22c/frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897", size = 230787 }, - { url = "https://files.pythonhosted.org/packages/70/b0/6f1ebdabfb604e39a0f84428986b89ab55f246b64cddaa495f2c953e1f6b/frozenlist-1.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89aa2c2eeb20957be2d950b85974b30a01a762f3308cd02bb15e1ad632e22dc7", size = 240674 }, - { url = "https://files.pythonhosted.org/packages/a3/05/50c53f1cdbfdf3d2cb9582a4ea5e12cd939ce33bd84403e6d07744563486/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742", size = 255712 }, - { url = "https://files.pythonhosted.org/packages/b8/3d/cbc6f057f7d10efb7f1f410e458ac090f30526fd110ed2b29bb56ec38fe1/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea", size = 247618 }, - { url = "https://files.pythonhosted.org/packages/96/86/d5e9cd583aed98c9ee35a3aac2ce4d022ce9de93518e963aadf34a18143b/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5", size = 266868 }, - { url = "https://files.pythonhosted.org/packages/0f/6e/542af762beb9113f13614a590cafe661e0e060cddddee6107c8833605776/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9", size = 266439 }, - { url = "https://files.pythonhosted.org/packages/ea/db/8b611e23fda75da5311b698730a598df54cfe6236678001f449b1dedb241/frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6", size = 256677 }, - { url = "https://files.pythonhosted.org/packages/eb/06/732cefc0c46c638e4426a859a372a50e4c9d62e65dbfa7ddcf0b13e6a4f2/frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932", size = 44825 }, - { url = "https://files.pythonhosted.org/packages/29/eb/2110c4be2f622e87864e433efd7c4ee6e4f8a59ff2a93c1aa426ee50a8b8/frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0", size = 50652 }, { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, ] +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034 }, +] + +[[package]] +name = "git-cliff" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/b2/266a376450ed2d2779e6881f73f3ecb6e7651eaf1641543f0d246d25d156/git_cliff-2.6.1.tar.gz", hash = "sha256:5a6ab41efb547c01d09d0354f4132aa3a46e2aab5e60c576bca1def6f6efec9f", size = 80951 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/35/a085eaaffc04ba73bea83479aae4f36bdaccb716c069f1edd0b9e5cb1b1a/git_cliff-2.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c7bf47e3cccc5aaab360231428efc3e5fc868b16add6188947dbfd397e0b752f", size = 6475059 }, + { url = "https://files.pythonhosted.org/packages/e1/f8/08833e6e33b91ce0440718006c07176c54edeee873cf2ae8e3eb483bf395/git_cliff-2.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ba81968e13f2d91a3da062313c04818c5d9b8eb65a0fa799668d4217182fe1e", size = 6030702 }, + { url = "https://files.pythonhosted.org/packages/a0/fd/8d3eb58d609e89083ed838be27d5fb5f50de2e7f7e23fc98deff6f390780/git_cliff-2.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:903dddef02eea4a77a8d20242a9a78c09e3cf8132fd447eb40ee4f90d5705199", size = 6370975 }, + { url = "https://files.pythonhosted.org/packages/fd/9a/85c3b7696947ebf8377df105bed670d1dd494c12a13d5c7cb0d0f53cd03c/git_cliff-2.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be626d41b461b889c4e6a6944115bd1df37bd16428881680d12ffde57c460a2d", size = 6817707 }, + { url = "https://files.pythonhosted.org/packages/76/f6/c7e7ae1fcbde4bf09de65c24f3ec22af9403f73adabf2b5e5e559bfaefe0/git_cliff-2.6.1-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:56636d2c1a73ba687a528befbef96dcc79cdd94ec7c166d17362ce4e336a6538", size = 6419227 }, + { url = "https://files.pythonhosted.org/packages/e8/ff/32aed7902bd1e1a0748cf5775d88c614865d5f97dcac70d881a8a662fe5f/git_cliff-2.6.1-py3-none-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:401acf2f65d7fab41afacc72d7c225a8a58b127821b7e23ec7420e61407d1df2", size = 6670198 }, + { url = "https://files.pythonhosted.org/packages/14/d4/8ca20b1a28119aa4ff85553102334054056d3f4e754259c384c1406e9280/git_cliff-2.6.1-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f18d6c485f7198fe4e430fc059488d033ea9ccca122427c7647617ae1d3f4d33", size = 7065947 }, + { url = "https://files.pythonhosted.org/packages/e8/09/35237627f7f731324c7bfc77cfef11c4bd85b1c23d30d796926f7fea4b4f/git_cliff-2.6.1-py3-none-win32.whl", hash = "sha256:f5b943b071bfdbdf1027ba0da529590305ec1be018d4236f0bacf5cf31e60b86", size = 6164541 }, + { url = "https://files.pythonhosted.org/packages/a5/00/432b89766f1b3172a569b70d7f873b2d7c41e43e293b86d3ac75f0126d7d/git_cliff-2.6.1-py3-none-win_amd64.whl", hash = "sha256:59fb3f42b51eb23cf32686f5bb72f4d82b63e28c09c41db8706c9cfee3e9fab6", size = 6878759 }, +] + [[package]] name = "gitdb" version = "4.0.11" @@ -687,18 +699,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", size = 66894 }, ] -[[package]] -name = "importlib-resources" -version = "6.4.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "zipp", marker = "python_full_version < '3.10'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0e/6a/3ac38d1458685a04fafa299dce821713a4f65e5ec30466bec07113f2f891/importlib_resources-6.4.4.tar.gz", hash = "sha256:20600c8b7361938dc0bb2d5ec0297802e575df486f5a544fa414da65e13721f7", size = 42721 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/2a/728c8ae66011600fac5731a7db030d23c42f1321fd9547654f0c3b2b32d7/importlib_resources-6.4.4-py3-none-any.whl", hash = "sha256:dda242603d1c9cd836c3368b1174ed74cb4049ecd209e7a1a0104620c18c5c11", size = 35608 }, -] - [[package]] name = "iniconfig" version = "2.0.0" @@ -721,72 +721,201 @@ wheels = [ ] [[package]] -name = "markdown-it-py" -version = "3.0.0" +name = "markdown" +version = "3.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, +] + +[[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 } +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +] + +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354 }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "mdurl" }, + { name = "click" }, + { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159 } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451 }, ] [[package]] -name = "markupsafe" -version = "2.1.5" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/5b/aae44c6655f3801e81aa3eef09dbbf012431987ba564d7231722f68df02d/MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b", size = 19384 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/54/ad5eb37bf9d51800010a74e4665425831a9db4e7c4e0fde4352e391e808e/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc", size = 18206 }, - { url = "https://files.pythonhosted.org/packages/6a/4a/a4d49415e600bacae038c67f9fecc1d5433b9d3c71a4de6f33537b89654c/MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5", size = 14079 }, - { url = "https://files.pythonhosted.org/packages/0a/7b/85681ae3c33c385b10ac0f8dd025c30af83c78cec1c37a6aa3b55e67f5ec/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46", size = 26620 }, - { url = "https://files.pythonhosted.org/packages/7c/52/2b1b570f6b8b803cef5ac28fdf78c0da318916c7d2fe9402a84d591b394c/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f", size = 25818 }, - { url = "https://files.pythonhosted.org/packages/29/fe/a36ba8c7ca55621620b2d7c585313efd10729e63ef81e4e61f52330da781/MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900", size = 25493 }, - { url = "https://files.pythonhosted.org/packages/60/ae/9c60231cdfda003434e8bd27282b1f4e197ad5a710c14bee8bea8a9ca4f0/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff", size = 30630 }, - { url = "https://files.pythonhosted.org/packages/65/dc/1510be4d179869f5dafe071aecb3f1f41b45d37c02329dfba01ff59e5ac5/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad", size = 29745 }, - { url = "https://files.pythonhosted.org/packages/30/39/8d845dd7d0b0613d86e0ef89549bfb5f61ed781f59af45fc96496e897f3a/MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd", size = 30021 }, - { url = "https://files.pythonhosted.org/packages/c7/5c/356a6f62e4f3c5fbf2602b4771376af22a3b16efa74eb8716fb4e328e01e/MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4", size = 16659 }, - { url = "https://files.pythonhosted.org/packages/69/48/acbf292615c65f0604a0c6fc402ce6d8c991276e16c80c46a8f758fbd30c/MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5", size = 17213 }, - { url = "https://files.pythonhosted.org/packages/11/e7/291e55127bb2ae67c64d66cef01432b5933859dfb7d6949daa721b89d0b3/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f", size = 18219 }, - { url = "https://files.pythonhosted.org/packages/6b/cb/aed7a284c00dfa7c0682d14df85ad4955a350a21d2e3b06d8240497359bf/MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2", size = 14098 }, - { url = "https://files.pythonhosted.org/packages/1c/cf/35fe557e53709e93feb65575c93927942087e9b97213eabc3fe9d5b25a55/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced", size = 29014 }, - { url = "https://files.pythonhosted.org/packages/97/18/c30da5e7a0e7f4603abfc6780574131221d9148f323752c2755d48abad30/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5", size = 28220 }, - { url = "https://files.pythonhosted.org/packages/0c/40/2e73e7d532d030b1e41180807a80d564eda53babaf04d65e15c1cf897e40/MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c", size = 27756 }, - { url = "https://files.pythonhosted.org/packages/18/46/5dca760547e8c59c5311b332f70605d24c99d1303dd9a6e1fc3ed0d73561/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f", size = 33988 }, - { url = "https://files.pythonhosted.org/packages/6d/c5/27febe918ac36397919cd4a67d5579cbbfa8da027fa1238af6285bb368ea/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a", size = 32718 }, - { url = "https://files.pythonhosted.org/packages/f8/81/56e567126a2c2bc2684d6391332e357589a96a76cb9f8e5052d85cb0ead8/MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f", size = 33317 }, - { url = "https://files.pythonhosted.org/packages/00/0b/23f4b2470accb53285c613a3ab9ec19dc944eaf53592cb6d9e2af8aa24cc/MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906", size = 16670 }, - { url = "https://files.pythonhosted.org/packages/b7/a2/c78a06a9ec6d04b3445a949615c4c7ed86a0b2eb68e44e7541b9d57067cc/MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617", size = 17224 }, - { url = "https://files.pythonhosted.org/packages/53/bd/583bf3e4c8d6a321938c13f49d44024dbe5ed63e0a7ba127e454a66da974/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1", size = 18215 }, - { url = "https://files.pythonhosted.org/packages/48/d6/e7cd795fc710292c3af3a06d80868ce4b02bfbbf370b7cee11d282815a2a/MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4", size = 14069 }, - { url = "https://files.pythonhosted.org/packages/51/b5/5d8ec796e2a08fc814a2c7d2584b55f889a55cf17dd1a90f2beb70744e5c/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee", size = 29452 }, - { url = "https://files.pythonhosted.org/packages/0a/0d/2454f072fae3b5a137c119abf15465d1771319dfe9e4acbb31722a0fff91/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5", size = 28462 }, - { url = "https://files.pythonhosted.org/packages/2d/75/fd6cb2e68780f72d47e6671840ca517bda5ef663d30ada7616b0462ad1e3/MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b", size = 27869 }, - { url = "https://files.pythonhosted.org/packages/b0/81/147c477391c2750e8fc7705829f7351cf1cd3be64406edcf900dc633feb2/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a", size = 33906 }, - { url = "https://files.pythonhosted.org/packages/8b/ff/9a52b71839d7a256b563e85d11050e307121000dcebc97df120176b3ad93/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f", size = 32296 }, - { url = "https://files.pythonhosted.org/packages/88/07/2dc76aa51b481eb96a4c3198894f38b480490e834479611a4053fbf08623/MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169", size = 33038 }, - { url = "https://files.pythonhosted.org/packages/96/0c/620c1fb3661858c0e37eb3cbffd8c6f732a67cd97296f725789679801b31/MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad", size = 16572 }, - { url = "https://files.pythonhosted.org/packages/3f/14/c3554d512d5f9100a95e737502f4a2323a1959f6d0d01e0d0997b35f7b10/MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb", size = 17127 }, - { url = "https://files.pythonhosted.org/packages/0f/31/780bb297db036ba7b7bbede5e1d7f1e14d704ad4beb3ce53fb495d22bc62/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf", size = 18193 }, - { url = "https://files.pythonhosted.org/packages/6c/77/d77701bbef72892affe060cdacb7a2ed7fd68dae3b477a8642f15ad3b132/MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2", size = 14073 }, - { url = "https://files.pythonhosted.org/packages/d9/a7/1e558b4f78454c8a3a0199292d96159eb4d091f983bc35ef258314fe7269/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8", size = 26486 }, - { url = "https://files.pythonhosted.org/packages/5f/5a/360da85076688755ea0cceb92472923086993e86b5613bbae9fbc14136b0/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3", size = 25685 }, - { url = "https://files.pythonhosted.org/packages/6a/18/ae5a258e3401f9b8312f92b028c54d7026a97ec3ab20bfaddbdfa7d8cce8/MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465", size = 25338 }, - { url = "https://files.pythonhosted.org/packages/0b/cc/48206bd61c5b9d0129f4d75243b156929b04c94c09041321456fd06a876d/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e", size = 30439 }, - { url = "https://files.pythonhosted.org/packages/d1/06/a41c112ab9ffdeeb5f77bc3e331fdadf97fa65e52e44ba31880f4e7f983c/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea", size = 29531 }, - { url = "https://files.pythonhosted.org/packages/02/8c/ab9a463301a50dab04d5472e998acbd4080597abc048166ded5c7aa768c8/MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6", size = 29823 }, - { url = "https://files.pythonhosted.org/packages/bc/29/9bc18da763496b055d8e98ce476c8e718dcfd78157e17f555ce6dd7d0895/MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf", size = 16658 }, - { url = "https://files.pythonhosted.org/packages/f6/f8/4da07de16f10551ca1f640c92b5f316f9394088b183c6a57183df6de5ae4/MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5", size = 17211 }, -] - -[[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 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +name = "mkdocs-get-deps" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 }, +] + +[[package]] +name = "mkdocs-git-revision-date-localized-plugin" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "gitpython" }, + { name = "mkdocs" }, + { name = "pytz" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/85/6dc9d4eca486ed5734a05f7fd5c612a8e60a35e65610dad6aa9c58118c3f/mkdocs_git_revision_date_localized_plugin-1.3.0.tar.gz", hash = "sha256:439e2f14582204050a664c258861c325064d97cdc848c541e48bb034a6c4d0cb", size = 384797 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/e5/ffeb92db53af8c3aa2d92e21a3cf6b5f83eee7e03b9cf9234ef6b30230d5/mkdocs_git_revision_date_localized_plugin-1.3.0-py3-none-any.whl", hash = "sha256:c99377ee119372d57a9e47cff4e68f04cce634a74831c06bc89b33e456e840a1", size = 22549 }, +] + +[[package]] +name = "mkdocs-glightbox" +version = "0.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/5a/0bc456397ba0acc684b5b1daa4ca232ed717938fd37198251d8bcc4053bf/mkdocs-glightbox-0.4.0.tar.gz", hash = "sha256:392b34207bf95991071a16d5f8916d1d2f2cd5d5bb59ae2997485ccd778c70d9", size = 32010 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/72/b0c2128bb569c732c11ae8e49a777089e77d83c05946062caa19b841e6fb/mkdocs_glightbox-0.4.0-py3-none-any.whl", hash = "sha256:e0107beee75d3eb7380ac06ea2d6eac94c999eaa49f8c3cbab0e7be2ac006ccf", size = 31154 }, +] + +[[package]] +name = "mkdocs-material" +version = "9.5.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "colorama" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "mkdocs" }, + { name = "mkdocs-material-extensions" }, + { name = "paginate" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "regex" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f7/56/182d8121db9ab553cdf9bc58d5972b89833f60b63272f693c1f2b849b640/mkdocs_material-9.5.44.tar.gz", hash = "sha256:f3a6c968e524166b3f3ed1fb97d3ed3e0091183b0545cedf7156a2a6804c56c0", size = 3964306 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/eb/a801d00e0e210d82184aacce596906ec065422c78a7319244ba0771c4ded/mkdocs_material-9.5.44-py3-none-any.whl", hash = "sha256:47015f9c167d58a5ff5e682da37441fc4d66a1c79334bfc08d774763cacf69ca", size = 8674509 }, +] + +[[package]] +name = "mkdocs-material-extensions" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, +] + +[[package]] +name = "mkdocs-obsidian-bridge" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "mkdocs" }, + { name = "obsidian-media" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3e/49/19e5dddea68b1383a60df206d38a852e275ddae92959721662a0c134411e/mkdocs_obsidian_bridge-1.1.1.tar.gz", hash = "sha256:9ee0b89c881982a908a18dfc3108d4a8e225c1fc22776052ce4ad2efd17b14f2", size = 49201 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/c5/45b9d09745196cf394ea5ce79e84e9c6f518c9a0687be7c47cf49fe56b20/mkdocs_obsidian_bridge-1.1.1-py3-none-any.whl", hash = "sha256:1c16e45a266e54ae969d5d4dc5457742c991aeafc529878a2598b5a13eb513eb", size = 9727 }, +] + +[[package]] +name = "mkdocs-publisher" +version = "1.4.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "mkdocs" }, + { name = "mkdocs-material" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/20/b544c914fadc31b094aefffa3dcbd216542d74a44f7fdf9aa6c7ca97976a/mkdocs_publisher-1.4.3.tar.gz", hash = "sha256:93589b7cf622337f6d8d6f3b1b6a2d18d241c81577ac3633e1aebe69c6fcd04e", size = 44810 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/53/8cb97ff9bee2210585c61f43bd39877baca530f172044853e0c4a2bc3413/mkdocs_publisher-1.4.3-py3-none-any.whl", hash = "sha256:dc29352cd4c3384ff2f8ac154d2fd6dd2c54a8c9c541720254fbefcad0536a35", size = 92215 }, ] [[package]] @@ -858,24 +987,52 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519 }, { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426 }, { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531 }, - { url = "https://files.pythonhosted.org/packages/e7/c9/9e153a6572b38ac5ff4434113af38acf8d5e9957897cdb1f513b3d6614ed/multidict-6.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:4e18b656c5e844539d506a0a06432274d7bd52a7487e6828c63a63d69185626c", size = 48550 }, - { url = "https://files.pythonhosted.org/packages/76/f5/79565ddb629eba6c7f704f09a09df085c8dc04643b12506f10f718cee37a/multidict-6.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a185f876e69897a6f3325c3f19f26a297fa058c5e456bfcff8015e9a27e83ae1", size = 29298 }, - { url = "https://files.pythonhosted.org/packages/60/1b/9851878b704bc98e641a3e0bce49382ae9e05743dac6d97748feb5b7baba/multidict-6.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ab7c4ceb38d91570a650dba194e1ca87c2b543488fe9309b4212694174fd539c", size = 29641 }, - { url = "https://files.pythonhosted.org/packages/89/87/d451d45aab9e422cb0fb2f7720c31a4c1d3012c740483c37f642eba568fb/multidict-6.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e617fb6b0b6953fffd762669610c1c4ffd05632c138d61ac7e14ad187870669c", size = 126202 }, - { url = "https://files.pythonhosted.org/packages/fa/b4/27cbe9f3e2e469359887653f2e45470272eef7295139916cc21107c6b48c/multidict-6.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16e5f4bf4e603eb1fdd5d8180f1a25f30056f22e55ce51fb3d6ad4ab29f7d96f", size = 133925 }, - { url = "https://files.pythonhosted.org/packages/4d/a3/afc841899face8adfd004235ce759a37619f6ec99eafd959650c5ce4df57/multidict-6.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f4c035da3f544b1882bac24115f3e2e8760f10a0107614fc9839fd232200b875", size = 129039 }, - { url = "https://files.pythonhosted.org/packages/5e/41/0d0fb18c1ad574f807196f5f3d99164edf9de3e169a58c6dc2d6ed5742b9/multidict-6.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:957cf8e4b6e123a9eea554fa7ebc85674674b713551de587eb318a2df3e00255", size = 124072 }, - { url = "https://files.pythonhosted.org/packages/00/22/defd7a2e71a44e6e5b9a5428f972e5b572e7fe28e404dfa6519bbf057c93/multidict-6.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:483a6aea59cb89904e1ceabd2b47368b5600fb7de78a6e4a2c2987b2d256cf30", size = 116532 }, - { url = "https://files.pythonhosted.org/packages/91/25/f7545102def0b1d456ab6449388eed2dfd822debba1d65af60194904a23a/multidict-6.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:87701f25a2352e5bf7454caa64757642734da9f6b11384c1f9d1a8e699758057", size = 128173 }, - { url = "https://files.pythonhosted.org/packages/45/79/3dbe8d35fc99f5ea610813a72ab55f426cb9cf482f860fa8496e5409be11/multidict-6.1.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:682b987361e5fd7a139ed565e30d81fd81e9629acc7d925a205366877d8c8657", size = 122654 }, - { url = "https://files.pythonhosted.org/packages/97/cb/209e735eeab96e1b160825b5d0b36c56d3862abff828fc43999bb957dcad/multidict-6.1.0-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce2186a7df133a9c895dea3331ddc5ddad42cdd0d1ea2f0a51e5d161e4762f28", size = 133197 }, - { url = "https://files.pythonhosted.org/packages/e4/3a/a13808a7ada62808afccea67837a79d00ad6581440015ef00f726d064c2d/multidict-6.1.0-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:9f636b730f7e8cb19feb87094949ba54ee5357440b9658b2a32a5ce4bce53972", size = 129754 }, - { url = "https://files.pythonhosted.org/packages/77/dd/8540e139eafb240079242da8f8ffdf9d3f4b4ad1aac5a786cd4050923783/multidict-6.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:73eae06aa53af2ea5270cc066dcaf02cc60d2994bbb2c4ef5764949257d10f43", size = 126402 }, - { url = "https://files.pythonhosted.org/packages/86/99/e82e1a275d8b1ea16d3a251474262258dbbe41c05cce0c01bceda1fc8ea5/multidict-6.1.0-cp39-cp39-win32.whl", hash = "sha256:1ca0083e80e791cffc6efce7660ad24af66c8d4079d2a750b29001b53ff59ada", size = 26421 }, - { url = "https://files.pythonhosted.org/packages/86/1c/9fa630272355af7e4446a2c7550c259f11ee422ab2d30ff90a0a71cf3d9e/multidict-6.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:aa466da5b15ccea564bdab9c89175c762bc12825f4659c11227f515cee76fa4a", size = 28791 }, { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, ] +[[package]] +name = "mypy" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, + { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, + { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, + { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, + { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, + { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, + { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, + { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, + { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, + { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, + { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, + { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, + { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, + { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, + { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, + { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, + { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, + { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, + { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, + { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + [[package]] name = "nodeenv" version = "1.9.1" @@ -885,6 +1042,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, ] +[[package]] +name = "obsidian-media" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/fa/99965ada8a2c84195dcd26ca72efc2f4bf515059a075625bcc8269d2abb7/obsidian_media-2.0.0.tar.gz", hash = "sha256:32ba18569f60d2ea747f8fdb72f979bbd265b2ef1305c95ef82d5efe21c7fca5", size = 11348 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/18/11/f83635e9bb098cbda2ad035bd1f27f48f6cce27aa954a0e11fb735184b4d/obsidian_media-2.0.0-py3-none-any.whl", hash = "sha256:9c1370cf2f6c488ab18fdfd1be1b07ae475d30983c8481dc6ba7836e85f75970", size = 6019 }, +] + [[package]] name = "packaging" version = "24.1" @@ -894,6 +1063,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, ] +[[package]] +name = "paginate" +version = "0.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, +] + +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + [[package]] name = "platformdirs" version = "4.2.2" @@ -1019,18 +1206,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5d/1f/f378631574ead46d636b9a04a80ff878b9365d4b361b1905ef1667d4182a/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0", size = 2118920 }, { url = "https://files.pythonhosted.org/packages/7a/ea/e4943f17df7a3031d709481fe4363d4624ae875a6409aec34c28c9e6cf59/pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e", size = 1717397 }, { url = "https://files.pythonhosted.org/packages/13/63/b95781763e8d84207025071c0cec16d921c0163c7a9033ae4b9a0e020dc7/pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20", size = 1898013 }, - { url = "https://files.pythonhosted.org/packages/17/c3/803028de61ce9a1fe1643f77ff845807c76298bf1995fa216c4ae853c6b9/pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c", size = 1838087 }, - { url = "https://files.pythonhosted.org/packages/77/f7/25f1fba7ea1ae052e20b234e4c66d54b129e5b3f4d1e6c0da6534dbf57c3/pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6", size = 1722218 }, - { url = "https://files.pythonhosted.org/packages/57/53/fe2e1ae3795b7a69f81913584174f8ed36446b56df734565260830a3632b/pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2", size = 1788970 }, - { url = "https://files.pythonhosted.org/packages/13/80/d9c698486f8fb64b0945e0844c95eef3bcff920941eda30d556deadadbdf/pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a", size = 1775836 }, - { url = "https://files.pythonhosted.org/packages/0f/0c/ab6df185529c0ce1a6d916f9d159de389cc7de44eaa9362efc76495fb821/pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611", size = 1978099 }, - { url = "https://files.pythonhosted.org/packages/0e/9f/3094afeb286c60ec08088d938b661a561f3d23cd2e88a90a92ab0ecfce4f/pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b", size = 2693403 }, - { url = "https://files.pythonhosted.org/packages/9b/f1/a006955715be98093d092aa025f604c7c00721e83fe04bf467c49f31a685/pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006", size = 2061754 }, - { url = "https://files.pythonhosted.org/packages/32/f6/cd2e7bd0a52e2a72841f60c32e62b269995c34bdb13e4d1e799be834338a/pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1", size = 1895490 }, - { url = "https://files.pythonhosted.org/packages/ac/22/34ce27579901fcca525f8adce7747760407cf284c4f0fec6d4542265b451/pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09", size = 1968678 }, - { url = "https://files.pythonhosted.org/packages/2f/3a/80df9b0b5ea5e5b8939285c600dc9ce4a185317f5fb065a37e77a20cbdb3/pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab", size = 2110873 }, - { url = "https://files.pythonhosted.org/packages/ec/26/998c9b8dadcdeafbc833964ef5975cd0c7516b0157575b26300d078ae239/pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2", size = 1709309 }, - { url = "https://files.pythonhosted.org/packages/ed/36/67aeb15996618882c5cfe85dbeffefe09e2806cd86bdd37bca40753e82a1/pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669", size = 1905736 }, { url = "https://files.pythonhosted.org/packages/73/73/0c7265903f66cce39ed7ca939684fba344210cefc91ccc999cfd5b113fd3/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906", size = 1828190 }, { url = "https://files.pythonhosted.org/packages/27/55/60b8b0e58b49ee3ed36a18562dd7c6bc06a551c390e387af5872a238f2ec/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94", size = 1715252 }, { url = "https://files.pythonhosted.org/packages/28/3d/d66314bad6bb777a36559195a007b31e916bd9e2c198f7bb8f4ccdceb4fa/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f", size = 1782641 }, @@ -1039,14 +1214,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ac/76/450d9258c58dc7c70b9e3aadf6bebe23ddd99e459c365e2adbde80e238da/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc", size = 1960125 }, { url = "https://files.pythonhosted.org/packages/dd/9e/0309a7a4bea51771729515e413b3987be0789837de99087f7415e0db1f9b/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99", size = 2100407 }, { url = "https://files.pythonhosted.org/packages/af/93/06d44e08277b3b818b75bd5f25e879d7693e4b7dd3505fde89916fcc9ca2/pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6", size = 1914966 }, - { url = "https://files.pythonhosted.org/packages/ff/d0/639b12bc7c81ebcbbd5f946327e8970089b23fa5b11d7abb56495cbdc0de/pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331", size = 1829108 }, - { url = "https://files.pythonhosted.org/packages/f1/80/3b9d7fb8b4f8d36e24373334740c0b88d9ded08342543a72e9247b4fa410/pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad", size = 1716448 }, - { url = "https://files.pythonhosted.org/packages/2f/c6/f80ea0fac8c241c066245fe918cdc9d105985a1a8726aced9478548c9e37/pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1", size = 1783620 }, - { url = "https://files.pythonhosted.org/packages/d5/3e/9af260156f79347ed3e64149836d69bfe1e0c5efadec6116a879fc31c9ec/pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86", size = 1929929 }, - { url = "https://files.pythonhosted.org/packages/d1/fe/8c3e928e10a97eb8e85b18a53ed3288d039cf0fd7b0fe8d3258f14e8500a/pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e", size = 1886708 }, - { url = "https://files.pythonhosted.org/packages/31/26/b670bd58f1de902c099ff623fe62b9820448a20d70437e7698a57b922d3a/pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0", size = 1960709 }, - { url = "https://files.pythonhosted.org/packages/de/ee/322cad098a0cffc81e985ac2a298d3f29a1da25efe7dc1fb5cd2615c5b04/pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a", size = 2101218 }, - { url = "https://files.pythonhosted.org/packages/07/8b/30233f741e16b35499fa2fad2f4a69eb127eec6c850a1b14af26e7b08b73/pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7", size = 1915399 }, ] [[package]] @@ -1071,6 +1238,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, ] +[[package]] +name = "pymdown-extensions" +version = "10.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/0b/32f05854cfd432e9286bb41a870e0d1a926b72df5f5cdb6dec962b2e369e/pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7", size = 840790 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/53/32/95a164ddf533bd676cbbe878e36e89b4ade3efde8dd61d0148c90cbbe57e/pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77", size = 263448 }, +] + [[package]] name = "pytest" version = "8.3.2" @@ -1088,19 +1268,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802 }, ] -[[package]] -name = "pytest-cov" -version = "5.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "coverage", extra = ["toml"] }, - { name = "pytest" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, -] - [[package]] name = "pytest-dotenv" version = "0.5.2" @@ -1135,19 +1302,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, ] -[[package]] -name = "python-gitlab" -version = "4.10.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "requests" }, - { name = "requests-toolbelt" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/89/b5/e2cc1cf8f89ed8e6e8f0fa63103acec20e92d67f108dbf6c529f61cb241a/python_gitlab-4.10.0.tar.gz", hash = "sha256:86f99c1915088e2d2573817aca8bf6bab5e4f12d42b04ef6b2df2abb528d57fd", size = 478822 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/b4/9dec090e1b5790089b878ccb76d1e101599a595d4aaa7ee0197a7a901d77/python_gitlab-4.10.0-py3-none-any.whl", hash = "sha256:53ea6d977fb26d256390636616ca91d127cd04bdefc6c5ce2d7711b8e5100b2a", size = 143256 }, -] - [[package]] name = "python-multipart" version = "0.0.9" @@ -1158,26 +1312,12 @@ wheels = [ ] [[package]] -name = "python-semantic-release" -version = "9.8.7" +name = "pytz" +version = "2024.2" source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "click-option-group" }, - { name = "dotty-dict" }, - { name = "gitpython" }, - { name = "importlib-resources" }, - { name = "jinja2" }, - { name = "pydantic" }, - { name = "python-gitlab" }, - { name = "requests" }, - { name = "rich" }, - { name = "shellingham" }, - { name = "tomlkit" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/68/26/a24b7dcd1ed4a680dd0a2131f32980fad824fb59866cbf2cdf7b7d15ee43/python_semantic_release-9.8.7.tar.gz", hash = "sha256:0781e615c3c12583bee78c7e772f14b75078de17f81ab2527bb71a1e13706b74", size = 186456 } +sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/f4/36214e30f2f0fa32d8e51f0ffb89fbd51231033fe7e66af4cb0a1127f5ca/python_semantic_release-9.8.7-py3-none-any.whl", hash = "sha256:ed26c69878dd5439ad1dc8120e5f4251088277b1a760278b60bf7957f0e88630", size = 87797 }, + { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, ] [[package]] @@ -1222,15 +1362,18 @@ wheels = [ { 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 }, { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, - { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777 }, - { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318 }, - { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891 }, - { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614 }, - { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360 }, - { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006 }, - { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577 }, - { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593 }, - { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312 }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 }, ] [[package]] @@ -1248,6 +1391,75 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a3/75/3307fae4fd06288b4211d5e8af960ed30718817a9f6f17e86560a0eca4b8/realtime-2.0.2-py3-none-any.whl", hash = "sha256:2634c915bc38807f2013f21e8bcc4d2f79870dfd81460ddb9393883d0489928a", size = 20222 }, ] +[[package]] +name = "regex" +version = "2024.9.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/63/12/497bd6599ce8a239ade68678132296aec5ee25ebea45fc8ba91aa60fceec/regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", size = 482488 }, + { url = "https://files.pythonhosted.org/packages/c1/24/595ddb9bec2a9b151cdaf9565b0c9f3da9f0cb1dca6c158bc5175332ddf8/regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", size = 287443 }, + { url = "https://files.pythonhosted.org/packages/69/a8/b2fb45d9715b1469383a0da7968f8cacc2f83e9fbbcd6b8713752dd980a6/regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/88/87/1ce4a5357216b19b7055e7d3b0efc75a6e426133bf1e7d094321df514257/regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", size = 783177 }, + { url = "https://files.pythonhosted.org/packages/3c/65/b9f002ab32f7b68e7d1dcabb67926f3f47325b8dbc22cc50b6a043e1d07c/regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", size = 823193 }, + { url = "https://files.pythonhosted.org/packages/22/91/8339dd3abce101204d246e31bc26cdd7ec07c9f91598472459a3a902aa41/regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", size = 809950 }, + { url = "https://files.pythonhosted.org/packages/cb/19/556638aa11c2ec9968a1da998f07f27ec0abb9bf3c647d7c7985ca0b8eea/regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", size = 782661 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/7a5bc4c6ef8d9cd2bdd83a667888fc35320da96a4cc4da5fa084330f53db/regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", size = 772348 }, + { url = "https://files.pythonhosted.org/packages/f1/0b/29f2105bfac3ed08e704914c38e93b07c784a6655f8a015297ee7173e95b/regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", size = 697460 }, + { url = "https://files.pythonhosted.org/packages/71/3a/52ff61054d15a4722605f5872ad03962b319a04c1ebaebe570b8b9b7dde1/regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", size = 769151 }, + { url = "https://files.pythonhosted.org/packages/97/07/37e460ab5ca84be8e1e197c3b526c5c86993dcc9e13cbc805c35fc2463c1/regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", size = 777478 }, + { url = "https://files.pythonhosted.org/packages/65/7b/953075723dd5ab00780043ac2f9de667306ff9e2a85332975e9f19279174/regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", size = 845373 }, + { url = "https://files.pythonhosted.org/packages/40/b8/3e9484c6230b8b6e8f816ab7c9a080e631124991a4ae2c27a81631777db0/regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", size = 845369 }, + { url = "https://files.pythonhosted.org/packages/b7/99/38434984d912edbd2e1969d116257e869578f67461bd7462b894c45ed874/regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", size = 773935 }, + { url = "https://files.pythonhosted.org/packages/ab/67/43174d2b46fa947b7b9dfe56b6c8a8a76d44223f35b1d64645a732fd1d6f/regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", size = 261624 }, + { url = "https://files.pythonhosted.org/packages/c4/2a/4f9c47d9395b6aff24874c761d8d620c0232f97c43ef3cf668c8b355e7a7/regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", size = 274020 }, + { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, + { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, + { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, + { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, + { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, + { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, + { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, + { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, + { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, + { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, + { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, + { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, + { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, + { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, + { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, + { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, + { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, + { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, + { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, + { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, + { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, + { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, + { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, + { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, + { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, + { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, + { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, + { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, + { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, + { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, + { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, + { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, + { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, + { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, + { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, + { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, + { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, + { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, + { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, + { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, + { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, + { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, + { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, + { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, + { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, +] + [[package]] name = "requests" version = "2.32.3" @@ -1263,40 +1475,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, ] -[[package]] -name = "requests-toolbelt" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481 }, -] - -[[package]] -name = "rich" -version = "13.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown-it-py" }, - { name = "pygments" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cf/60/5959113cae0ce512cf246a6871c623117330105a0d5f59b4e26138f2c9cc/rich-13.8.0.tar.gz", hash = "sha256:a5ac1f1cd448ade0d59cc3356f7db7a7ccda2c8cbae9c7a90c28ff463d3e91f4", size = 222072 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/d9/c2a126eeae791e90ea099d05cb0515feea3688474b978343f3cdcfe04523/rich-13.8.0-py3-none-any.whl", hash = "sha256:2e85306a063b9492dffc86278197a60cbece75bcb766022f3436f567cae11bdc", size = 241597 }, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, -] - [[package]] name = "six" version = "1.16.0" @@ -1324,13 +1502,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + [[package]] name = "starlette" version = "0.38.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, - { name = "typing-extensions", marker = "python_full_version < '3.10'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/43/e2/d49a94ecb665b3a1c34b40c78165a737abc384fcabc843ccb14a3bd3dc37/starlette-0.38.2.tar.gz", hash = "sha256:c7c0441065252160993a1a37cf2a73bb64d271b17303e0b0c1eb7191cfb12d75", size = 2844770 } wheels = [ @@ -1399,30 +1585,38 @@ wheels = [ ] [[package]] -name = "tomlkit" -version = "0.13.2" +name = "typing-extensions" +version = "4.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, ] [[package]] -name = "typing-extensions" -version = "4.12.2" +name = "typos" +version = "1.27.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/7e/14/9339fffca6831ddb5c003cbfa22841aff2f0f21ae78821960b58e8f46564/typos-1.27.0.tar.gz", hash = "sha256:1ace06f2f107a939d3ddd2cc3517250b08d8ae95297c3722f48f39b899f3c1af", size = 1121281 } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/61/a9/534ccebf318b3fa6e46ad6cde12219cc424f548daa79aed963c326e25ce6/typos-1.27.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4902c9e03c514d8515387301a6509632f45a88db6d86940ee5aee57945d20eb6", size = 3004813 }, + { url = "https://files.pythonhosted.org/packages/51/04/97ae0f5f2f48c802acb58383af71d9543e16e4fb614644d33fd9d7a56739/typos-1.27.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:410b2b23021bb11be49ba7d49ef76be56d400ee04b0aef8a40185dd1f15de366", size = 2907982 }, + { url = "https://files.pythonhosted.org/packages/20/8e/dacd4e4ca5aded54b20ac54eb041997ce815e1cd6abdb2ccc8a1cf360794/typos-1.27.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98b444ebbe052ec04ef79c351efa8373e5913960ef05c6be910d9c75303f5def", size = 4309079 }, + { url = "https://files.pythonhosted.org/packages/49/ac/ea163be3ee8d33299e9875ac42c38e1a25a5e8975344d77f14b972249f00/typos-1.27.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b2480fdab0e6e01270cf3d0840d6356cacfe2822894cdaf5c6dc9e1f0be5a6e", size = 3379525 }, + { url = "https://files.pythonhosted.org/packages/0b/ab/a258e3c916caf1f5e4945c260cb811b391d66d8f63f183bca4560df90914/typos-1.27.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64f59c0e9c51d279aafd9fdfc8a392eab4ab56ba0786e3e578755c99592433f4", size = 4093616 }, + { url = "https://files.pythonhosted.org/packages/c2/4b/ad5af38a987cf92079dd967864ce9a88d4149eea08514968380fddcbb4c3/typos-1.27.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:07f2ea4f5ef7079c71116f4427074c330c17531b7ee75ca6693f3bd7fbbae4b0", size = 3911242 }, + { url = "https://files.pythonhosted.org/packages/f0/5f/d4ab810a9168d5d0cf0ea4842f3fc3537d325dcfd12ffc417a69552502e0/typos-1.27.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:984568803b5d87f63d8e1bb26cc16a17e4d942ca0732e01c36ac4311f0809b0f", size = 4096152 }, + { url = "https://files.pythonhosted.org/packages/18/71/0b8f06c7a29edfb7a7e58b4752fa3ae6c7de2ffb9471b1224dafed3347b7/typos-1.27.0-py3-none-win32.whl", hash = "sha256:d93da7e3b1c332378acbaab5b326fbf42b5075860044e11d14f51b310f0e3f03", size = 2431750 }, + { url = "https://files.pythonhosted.org/packages/de/6a/56fe95c40b4d966755d49fabb022ac1fadcbff5469e81a51226d51789c72/typos-1.27.0-py3-none-win_amd64.whl", hash = "sha256:97f799d8428d2f6f2889655a322e582117c6108df4b7de5fb4902d40e3e60850", size = 2562380 }, ] [[package]] name = "urllib3" -version = "2.2.2" +version = "2.2.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/6d/fa469ae21497ddc8bc93e5877702dca7cb8f911e337aca7452b5724f1bb6/urllib3-2.2.2.tar.gz", hash = "sha256:dd505485549a7a552833da5e6063639d0d177c04f23bc3864e41e5dc5f612168", size = 292266 } +sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ca/1c/89ffc63a9605b583d5df2be791a27bc1a42b7c32bab68d3c8f2f73a98cd4/urllib3-2.2.2-py3-none-any.whl", hash = "sha256:a448b2f64d686155468037e1ace9f2d2199776e17f0a46610480d311f73e3472", size = 121444 }, + { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, ] [[package]] @@ -1453,6 +1647,38 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/07/4d/410156100224c5e2f0011d435e477b57aed9576fc7fe137abcf14ec16e11/virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589", size = 5684792 }, ] +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, +] + [[package]] name = "websockets" version = "12.0" @@ -1492,27 +1718,11 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3c/98/1261f289dff7e65a38d59d2f591de6ed0a2580b729aebddec033c4d10881/websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", size = 136083 }, { url = "https://files.pythonhosted.org/packages/a9/1c/f68769fba63ccb9c13fe0a25b616bd5aebeef1c7ddebc2ccc32462fb784d/websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", size = 124460 }, { url = "https://files.pythonhosted.org/packages/20/52/8915f51f9aaef4e4361c89dd6cf69f72a0159f14e0d25026c81b6ad22525/websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", size = 124985 }, - { url = "https://files.pythonhosted.org/packages/69/af/c52981023e7afcdfdb50c4697f702659b3dedca54f71e3cc99b8581f5647/websockets-12.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ab3d732ad50a4fbd04a4490ef08acd0517b6ae6b77eb967251f4c263011a990d", size = 124014 }, - { url = "https://files.pythonhosted.org/packages/c5/db/2d12649006d6686802308831f4f8a1190105ea34afb68c52f098de689ad8/websockets-12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a1d9697f3337a89691e3bd8dc56dea45a6f6d975f92e7d5f773bc715c15dde28", size = 121251 }, - { url = "https://files.pythonhosted.org/packages/0d/a4/ec1043bc6acf5bc405762ecc1327f3573441185571122ae50fc00c6d3130/websockets-12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1df2fbd2c8a98d38a66f5238484405b8d1d16f929bb7a33ed73e4801222a6f53", size = 121322 }, - { url = "https://files.pythonhosted.org/packages/25/a9/a3e03f9f3c4425a914e5875dd09f2c2559d61b44edd52cf1e6b73f938898/websockets-12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23509452b3bc38e3a057382c2e941d5ac2e01e251acce7adc74011d7d8de434c", size = 130706 }, - { url = "https://files.pythonhosted.org/packages/7b/9f/f5aae5c49b0fc04ca68c723386f0d97f17363384525c6566cd382912a022/websockets-12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2e5fc14ec6ea568200ea4ef46545073da81900a2b67b3e666f04adf53ad452ec", size = 129708 }, - { url = "https://files.pythonhosted.org/packages/06/dd/e8535f54b4aaded1ed44041ca8eb9de8786ce719ff148b56b4a903ef93e6/websockets-12.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46e71dbbd12850224243f5d2aeec90f0aaa0f2dde5aeeb8fc8df21e04d99eff9", size = 130011 }, - { url = "https://files.pythonhosted.org/packages/67/cc/6fd14e45c5149e6c81c6771550ee5a4911321014e620f69baf1490001a80/websockets-12.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b81f90dcc6c85a9b7f29873beb56c94c85d6f0dac2ea8b60d995bd18bf3e2aae", size = 134686 }, - { url = "https://files.pythonhosted.org/packages/1b/9f/84d42c8c3e510f2a9ad09ae178c31cc89cc838b143a04bf41ff0653ca018/websockets-12.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a02413bc474feda2849c59ed2dfb2cddb4cd3d2f03a2fedec51d6e959d9b608b", size = 133934 }, - { url = "https://files.pythonhosted.org/packages/9c/5b/648db3556d8a441aa9705e1132b3ddae76204b57410952f85cf4a953623a/websockets-12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bbe6013f9f791944ed31ca08b077e26249309639313fff132bfbf3ba105673b9", size = 134559 }, - { url = "https://files.pythonhosted.org/packages/bb/07/050a8f6b06eb8a876a51c56f752dd51f59982dda37f2a1788bfd2a26952e/websockets-12.0-cp39-cp39-win32.whl", hash = "sha256:cbe83a6bbdf207ff0541de01e11904827540aa069293696dd528a6640bd6a5f6", size = 124449 }, - { url = "https://files.pythonhosted.org/packages/94/92/5dc1202332df60422869fdb6c86213ff6987b1b06c329eed329cc49966f7/websockets-12.0-cp39-cp39-win_amd64.whl", hash = "sha256:fc4e7fa5414512b481a2483775a8e8be7803a35b30ca805afa4998a84f9fd9e8", size = 124966 }, { url = "https://files.pythonhosted.org/packages/43/8b/554a8a8bb6da9dd1ce04c44125e2192af7b7beebf6e3dbfa5d0e285cc20f/websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", size = 121110 }, { url = "https://files.pythonhosted.org/packages/b0/8e/58b8812940d746ad74d395fb069497255cb5ef50748dfab1e8b386b1f339/websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", size = 123216 }, { url = "https://files.pythonhosted.org/packages/81/ee/272cb67ace1786ce6d9f39d47b3c55b335e8b75dd1972a7967aad39178b6/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", size = 122821 }, { url = "https://files.pythonhosted.org/packages/a8/03/387fc902b397729df166763e336f4e5cec09fe7b9d60f442542c94a21be1/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", size = 122768 }, { url = "https://files.pythonhosted.org/packages/50/f0/5939fbc9bc1979d79a774ce5b7c4b33c0cefe99af22fb70f7462d0919640/websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", size = 125009 }, - { url = "https://files.pythonhosted.org/packages/01/ae/d48aebf121726d2a26e48170cd7558627b09e0d47186ddfa1be017c81663/websockets-12.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:00700340c6c7ab788f176d118775202aadea7602c5cc6be6ae127761c16d6b0b", size = 121107 }, - { url = "https://files.pythonhosted.org/packages/c6/1a/142fa072b2292ca0897c282d12f48d5b18bdda5ac32774e3d6f9bddfd8fe/websockets-12.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e469d01137942849cff40517c97a30a93ae79917752b34029f0ec72df6b46399", size = 123209 }, - { url = "https://files.pythonhosted.org/packages/03/72/e4752b208241a606625da8d8757d98c3bfc6c69c0edc47603180c208f857/websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffefa1374cd508d633646d51a8e9277763a9b78ae71324183693959cf94635a7", size = 122820 }, - { url = "https://files.pythonhosted.org/packages/2d/73/a337e1275e4c3a9752896fbe467d2c6b5f25e983a2de0992e1dfaca04dbe/websockets-12.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba0cab91b3956dfa9f512147860783a1829a8d905ee218a9837c18f683239611", size = 122765 }, - { url = "https://files.pythonhosted.org/packages/c6/68/ed11b1b1a24fb0fa1a8275f72464e2f1038e25cab0137a09747cd1f40836/websockets-12.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:2cb388a5bfb56df4d9a406783b7f9dbefb888c09b71629351cc6b036e9259370", size = 125005 }, { url = "https://files.pythonhosted.org/packages/79/4d/9cc401e7b07e80532ebc8c8e993f42541534da9e9249c59ee0139dcb0352/websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", size = 118370 }, ] @@ -1586,29 +1796,5 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/14/b5/b93c70d9a462b802c8df65c64b85f49d86b4ba70c393fbad95cf7ec053cb/yarl-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da", size = 491776 }, { url = "https://files.pythonhosted.org/packages/03/0f/5a52eaa402a6a93265ba82f42c6f6085ccbe483e1b058ad34207e75812b1/yarl-1.11.1-cp313-cp313-win32.whl", hash = "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979", size = 485250 }, { url = "https://files.pythonhosted.org/packages/dd/97/946d26a5d82706a6769399cabd472c59f9a3227ce1432afb4739b9c29572/yarl-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367", size = 492590 }, - { url = "https://files.pythonhosted.org/packages/66/dd/c65267bc85cb3726d3b0b3d0b50f96d868fe90cc5e5fccd28608d0eea241/yarl-1.11.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:884eab2ce97cbaf89f264372eae58388862c33c4f551c15680dd80f53c89a269", size = 191166 }, - { url = "https://files.pythonhosted.org/packages/97/32/a54abf14f380e99b29fc0f03b310934f10b4fcd567264e95dc0134812f5f/yarl-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a336eaa7ee7e87cdece3cedb395c9657d227bfceb6781295cf56abcd3386a26", size = 115912 }, - { url = "https://files.pythonhosted.org/packages/41/e9/8ecf8233b016389b94ab520f6eb178f00586eef5e4b6bd550cef8a227b41/yarl-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87f020d010ba80a247c4abc335fc13421037800ca20b42af5ae40e5fd75e7909", size = 113835 }, - { url = "https://files.pythonhosted.org/packages/e7/68/7409309a0b3aec7ae1a18dd5a09cd9447e018421f5f79d6fd29930f347d5/yarl-1.11.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:637c7ddb585a62d4469f843dac221f23eec3cbad31693b23abbc2c366ad41ff4", size = 449180 }, - { url = "https://files.pythonhosted.org/packages/60/73/9862f1d7c836a6f6681e4b6d5f8037b09bd77e3af347fd5ec88b395f140a/yarl-1.11.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48dfd117ab93f0129084577a07287376cc69c08138694396f305636e229caa1a", size = 476414 }, - { url = "https://files.pythonhosted.org/packages/c8/30/7a76451b7621317c61d7bd1f29ea1936a96558738e20a57beb8ed8e6c13b/yarl-1.11.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e0ae31fb5ccab6eda09ba1494e87eb226dcbd2372dae96b87800e1dcc98804", size = 469102 }, - { url = "https://files.pythonhosted.org/packages/ff/be/78953a3d5154b974af49ce367f1a8d4751ababdf26a66ae607b4ae625d99/yarl-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f46f81501160c28d0c0b7333b4f7be8983dbbc161983b6fb814024d1b4952f79", size = 453981 }, - { url = "https://files.pythonhosted.org/packages/36/10/36ad3a314d7791439bb8e580997a4952f236d4a6fc741128bd040edc91fc/yarl-1.11.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:04293941646647b3bfb1719d1d11ff1028e9c30199509a844da3c0f5919dc520", size = 438686 }, - { url = "https://files.pythonhosted.org/packages/8e/8d/f118c3b744514e71dd93c755c393705a034e1ebec7525c6598c941b8d1ea/yarl-1.11.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:250e888fa62d73e721f3041e3a9abf427788a1934b426b45e1b92f62c1f68366", size = 450933 }, - { url = "https://files.pythonhosted.org/packages/1d/6e/9eb29d7291253d7ae94c292e30fe7bfa4236439a4f97d736e72aee9cca26/yarl-1.11.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:e8f63904df26d1a66aabc141bfd258bf738b9bc7bc6bdef22713b4f5ef789a4c", size = 454471 }, - { url = "https://files.pythonhosted.org/packages/16/08/8f450fee2be068e06c683ec1e43b25f335fa4e1f2f468dd0cf23ea2e348c/yarl-1.11.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:aac44097d838dda26526cffb63bdd8737a2dbdf5f2c68efb72ad83aec6673c7e", size = 480037 }, - { url = "https://files.pythonhosted.org/packages/3f/57/37f89174e82534f4c77e301d046481315619cd36cf2866ac993993c10d46/yarl-1.11.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:267b24f891e74eccbdff42241c5fb4f974de2d6271dcc7d7e0c9ae1079a560d9", size = 477252 }, - { url = "https://files.pythonhosted.org/packages/98/76/83d5888796b061519697c96a134e39e403be0da549a23b594814a5107d36/yarl-1.11.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6907daa4b9d7a688063ed098c472f96e8181733c525e03e866fb5db480a424df", size = 465282 }, - { url = "https://files.pythonhosted.org/packages/e4/05/4087620c4a73f4acaccc2a3ec4600760418db4f5e295e380d5b6e83ce684/yarl-1.11.1-cp39-cp39-win32.whl", hash = "sha256:14438dfc5015661f75f85bc5adad0743678eefee266ff0c9a8e32969d5d69f74", size = 102205 }, - { url = "https://files.pythonhosted.org/packages/d8/6a/db7c41f53faa10df3e52bd10be5bab6bf9018f0c90e0e5b06b48fd83e12a/yarl-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:94d0caaa912bfcdc702a4204cd5e2bb01eb917fc4f5ea2315aa23962549561b0", size = 111338 }, { url = "https://files.pythonhosted.org/packages/5b/b3/841f7d706137bdc8b741c6826106b6f703155076d58f1830f244da857451/yarl-1.11.1-py3-none-any.whl", hash = "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38", size = 38648 }, ] - -[[package]] -name = "zipp" -version = "3.20.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d3/8b/1239a3ef43a0d0ebdca623fb6413bc7702c321400c5fdd574f0b7aa0fbb4/zipp-3.20.1.tar.gz", hash = "sha256:c22b14cc4763c5a5b04134207736c107db42e9d3ef2d9779d465f5f1bcba572b", size = 23848 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/9e/c96f7a4cd0bf5625bb409b7e61e99b1130dc63a98cb8b24aeabae62d43e8/zipp-3.20.1-py3-none-any.whl", hash = "sha256:9960cd8967c8f85a56f920d5d507274e74f9ff813a0ab8889a5b5be2daf44064", size = 8988 }, -] From 495028934579916a0c5c8a42dc7fe0368c1d6618 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 13:45:32 +0800 Subject: [PATCH 08/65] docs: update README.md for install supabase locally --- .vscode/extensions.json | 3 + .vscode/settings.json | 34 +++++- README.md | 45 ++++--- supabase/.gitignore | 4 + supabase/config.toml | 256 ++++++++++++++++++++++++++++++++++++++++ 5 files changed, 322 insertions(+), 20 deletions(-) create mode 100644 .vscode/extensions.json create mode 100644 supabase/.gitignore create mode 100644 supabase/config.toml diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..74baffc --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["denoland.vscode-deno"] +} diff --git a/.vscode/settings.json b/.vscode/settings.json index af01b0b..57c3f94 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,8 +1,30 @@ { - "DockerRun.DisableAutoGenerateConfig": true, - "python.testing.pytestArgs": [ - "tests" - ], - "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true + "DockerRun.DisableAutoGenerateConfig": true, + "[typescript]": { + "editor.defaultFormatter": "denoland.vscode-deno" + }, + "deno.enablePaths": [ + "supabase/functions" + ], + "deno.lint": true, + "deno.unstable": [ + "bare-node-builtins", + "byonm", + "sloppy-imports", + "unsafe-proto", + "webgpu", + "broadcast-channel", + "worker-options", + "cron", + "kv", + "ffi", + "fs", + "http", + "net" + ], + "python.testing.pytestArgs": [ + "tests" + ], + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false } diff --git a/README.md b/README.md index e6a5d99..a0836ea 100644 --- a/README.md +++ b/README.md @@ -75,7 +75,17 @@ ___ ```shell uv sync ``` -3. set your supabase env + +3. [start your supabase locally](https://supabase.com/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=linux&queryGroups=access-method&access-method=postgres) + +```bash +# brew in linux https://brew.sh/ +brew install supabase/tap/supabase +supabase init +supabase start +``` + +4. set your supabase env ```shell export SUPABASE_URL=your_supabase_url @@ -83,7 +93,9 @@ export SUPABASE_KEY=your_supabase_key export SUPERUSER_EMAIL=your_superuser_email export SUPERUSER_PASSWORD=your_superuser_password ``` -4. config fastapi settings + +5. config fastapi settings + ```python # src/app/core/config.py class Settings(BaseSettings): @@ -100,17 +112,20 @@ class Settings(BaseSettings): Config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) ``` -5. run server +6. run server + ```shell -uv run uvicorn src.app.main:app --reload +uv run uvicorn app.main:app --reload ``` ## Roadmap 🫶 + ___ - [x] FastAPI backend - - [x] **standard** structure + - [x] **standard** structure for **FastAPI** project + ```text ── src │ └── app @@ -145,18 +160,20 @@ ___ │ └── main.py ... ``` - - [x] **auto-auth** by fastapi dependency with supabase-auth - - [x] **CRUD** operations pytest - - [x] **api** requests pytest + + - [x] **auto-auth** by fastapi dependency with supabase-auth + - [x] **CRUD** operations pytest + - [x] **api** requests pytest - [ ] Supabase integration - - [x] crud supabase-postgresql - - [ ] websocket with supabase-realtime - - [ ] curd supabase-storage - - [ ] supafunc integration + - [x] crud supabase-postgresql + - [ ] websocket with supabase-realtime + - [ ] curd supabase-storage + - [ ] supafunc integration - [x] deployment - - [x] Full **Docker** integration (Docker based). + - [x] Full **Docker** integration (Docker based). - [ ] clone - - [ ] cookiecutter + - [ ] cookiecutter + ## Release Notes 🥸 ___ diff --git a/supabase/.gitignore b/supabase/.gitignore new file mode 100644 index 0000000..a3ad880 --- /dev/null +++ b/supabase/.gitignore @@ -0,0 +1,4 @@ +# Supabase +.branches +.temp +.env diff --git a/supabase/config.toml b/supabase/config.toml new file mode 100644 index 0000000..0f39a75 --- /dev/null +++ b/supabase/config.toml @@ -0,0 +1,256 @@ +# A string used to distinguish different Supabase projects on the same host. Defaults to the +# working directory name when running `supabase init`. +project_id = "fastapi_supabase_template" + +[api] +enabled = true +# Port to use for the API URL. +port = 54321 +# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API +# endpoints. `public` is always included. +schemas = ["public", "graphql_public"] +# Extra schemas to add to the search_path of every request. `public` is always included. +extra_search_path = ["public", "extensions"] +# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size +# for accidental or malicious requests. +max_rows = 1000 + +[api.tls] +enabled = false + +[db] +# Port to use for the local database URL. +port = 54322 +# Port used by db diff command to initialize the shadow database. +shadow_port = 54320 +# The database major version to use. This has to be the same as your remote database's. Run `SHOW +# server_version;` on the remote database to check. +major_version = 15 + +[db.pooler] +enabled = false +# Port to use for the local connection pooler. +port = 54329 +# Specifies when a server connection can be reused by other clients. +# Configure one of the supported pooler modes: `transaction`, `session`. +pool_mode = "transaction" +# How many server connections to allow per user/database pair. +default_pool_size = 20 +# Maximum number of client connections allowed. +max_client_conn = 100 + +[db.seed] +# If enabled, seeds the database after migrations during a db reset. +enabled = true +# Specifies an ordered list of seed files to load during db reset. +# Supports glob patterns relative to supabase directory. For example: +# sql_paths = ['./seeds/*.sql', '../project-src/seeds/*-load-testing.sql'] +sql_paths = ['./seed.sql'] + +[realtime] +enabled = true +# Bind realtime via either IPv4 or IPv6. (default: IPv4) +# ip_version = "IPv6" +# The maximum length in bytes of HTTP request headers. (default: 4096) +# max_header_length = 4096 + +[studio] +enabled = true +# Port to use for Supabase Studio. +port = 54323 +# External URL of the API server that frontend connects to. +api_url = "http://127.0.0.1" +# OpenAI API Key to use for Supabase AI in the Supabase Studio. +openai_api_key = "env(OPENAI_API_KEY)" + +# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they +# are monitored, and you can view the emails that would have been sent from the web interface. +[inbucket] +enabled = true +# Port to use for the email testing server web interface. +port = 54324 +# Uncomment to expose additional ports for testing user applications that send emails. +# smtp_port = 54325 +# pop3_port = 54326 + +[storage] +enabled = true +# The maximum file size allowed (e.g. "5MB", "500KB"). +file_size_limit = "50MiB" + +[storage.image_transformation] +enabled = true + +# Uncomment to configure local storage buckets +# [storage.buckets.images] +# public = false +# file_size_limit = "50MiB" +# allowed_mime_types = ["image/png", "image/jpeg"] +# objects_path = "./images" + +[auth] +enabled = true +# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used +# in emails. +site_url = "http://127.0.0.1:3000" +# A list of *exact* URLs that auth providers are permitted to redirect to post authentication. +additional_redirect_urls = ["https://127.0.0.1:3000"] +# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 (1 week). +jwt_expiry = 3600 +# If disabled, the refresh token will never expire. +enable_refresh_token_rotation = true +# Allows refresh tokens to be reused after expiry, up to the specified interval in seconds. +# Requires enable_refresh_token_rotation = true. +refresh_token_reuse_interval = 10 +# Allow/disallow new user signups to your project. +enable_signup = true +# Allow/disallow anonymous sign-ins to your project. +enable_anonymous_sign_ins = false +# Allow/disallow testing manual linking of accounts +enable_manual_linking = false + +[auth.email] +# Allow/disallow new user signups via email to your project. +enable_signup = true +# If enabled, a user will be required to confirm any email change on both the old, and new email +# addresses. If disabled, only the new email is required to confirm. +double_confirm_changes = true +# If enabled, users need to confirm their email address before signing in. +enable_confirmations = false +# If enabled, users will need to reauthenticate or have logged in recently to change their password. +secure_password_change = false +# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email. +max_frequency = "1s" +# Number of characters used in the email OTP. +otp_length = 6 +# Number of seconds before the email OTP expires (defaults to 1 hour). +otp_expiry = 3600 + +# Use a production-ready SMTP server +# [auth.email.smtp] +# host = "smtp.sendgrid.net" +# port = 587 +# user = "apikey" +# pass = "env(SENDGRID_API_KEY)" +# admin_email = "admin@email.com" +# sender_name = "Admin" + +# Uncomment to customize email template +# [auth.email.template.invite] +# subject = "You have been invited" +# content_path = "./supabase/templates/invite.html" + +[auth.sms] +# Allow/disallow new user signups via SMS to your project. +enable_signup = true +# If enabled, users need to confirm their phone number before signing in. +enable_confirmations = false +# Template for sending OTP to users +template = "Your code is {{ .Code }} ." +# Controls the minimum amount of time that must pass before sending another sms otp. +max_frequency = "5s" + +# Use pre-defined map of phone number to OTP for testing. +# [auth.sms.test_otp] +# 4152127777 = "123456" + +# Configure logged in session timeouts. +# [auth.sessions] +# Force log out after the specified duration. +# timebox = "24h" +# Force log out if the user has been inactive longer than the specified duration. +# inactivity_timeout = "8h" + +# This hook runs before a token is issued and allows you to add additional claims based on the authentication method used. +# [auth.hook.custom_access_token] +# enabled = true +# uri = "pg-functions:////" + +# Configure one of the supported SMS providers: `twilio`, `twilio_verify`, `messagebird`, `textlocal`, `vonage`. +[auth.sms.twilio] +enabled = false +account_sid = "" +message_service_sid = "" +# DO NOT commit your Twilio auth token to git. Use environment variable substitution instead: +auth_token = "env(SUPABASE_AUTH_SMS_TWILIO_AUTH_TOKEN)" + +[auth.mfa] +# Control how many MFA factors can be enrolled at once per user. +max_enrolled_factors = 10 + +# Control use of MFA via App Authenticator (TOTP) +[auth.mfa.totp] +enroll_enabled = true +verify_enabled = true + +# Configure Multi-factor-authentication via Phone Messaging +# [auth.mfa.phone] +# enroll_enabled = true +# verify_enabled = true +# otp_length = 6 +# template = "Your code is {{ .Code }} ." +# max_frequency = "10s" + +# Configure Multi-factor-authentication via WebAuthn +# [auth.mfa.web_authn] +# enroll_enabled = true +# verify_enabled = true + +# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`, +# `discord`, `facebook`, `github`, `gitlab`, `google`, `keycloak`, `linkedin_oidc`, `notion`, `twitch`, +# `twitter`, `slack`, `spotify`, `workos`, `zoom`. +[auth.external.apple] +enabled = false +client_id = "" +# DO NOT commit your OAuth provider secret to git. Use environment variable substitution instead: +secret = "env(SUPABASE_AUTH_EXTERNAL_APPLE_SECRET)" +# Overrides the default auth redirectUrl. +redirect_uri = "" +# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure, +# or any other third-party OIDC providers. +url = "" +# If enabled, the nonce check will be skipped. Required for local sign in with Google auth. +skip_nonce_check = false + +# Use Firebase Auth as a third-party provider alongside Supabase Auth. +[auth.third_party.firebase] +enabled = false +# project_id = "my-firebase-project" + +# Use Auth0 as a third-party provider alongside Supabase Auth. +[auth.third_party.auth0] +enabled = false +# tenant = "my-auth0-tenant" +# tenant_region = "us" + +# Use AWS Cognito (Amplify) as a third-party provider alongside Supabase Auth. +[auth.third_party.aws_cognito] +enabled = false +# user_pool_id = "my-user-pool-id" +# user_pool_region = "us-east-1" + +[edge_runtime] +enabled = true +# Configure one of the supported request policies: `oneshot`, `per_worker`. +# Use `oneshot` for hot reload, or `per_worker` for load testing. +policy = "oneshot" +inspector_port = 8083 + +[analytics] +enabled = true +port = 54327 +# Configure one of the supported backends: `postgres`, `bigquery`. +backend = "postgres" + +# Experimental features may be deprecated any time +[experimental] +# Configures Postgres storage engine to use OrioleDB (S3) +orioledb_version = "" +# Configures S3 bucket URL, eg. .s3-.amazonaws.com +s3_host = "env(S3_HOST)" +# Configures S3 bucket region, eg. us-east-1 +s3_region = "env(S3_REGION)" +# Configures AWS_ACCESS_KEY_ID for S3 bucket +s3_access_key = "env(S3_ACCESS_KEY)" +# Configures AWS_SECRET_ACCESS_KEY for S3 bucket +s3_secret_key = "env(S3_SECRET_KEY)" From 3eb164ef8199006c1f69b358624665195a09f43f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 05:45:56 +0000 Subject: [PATCH 09/65] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20f?= =?UTF-8?q?ormat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a0836ea..aaf418a 100644 --- a/README.md +++ b/README.md @@ -79,7 +79,7 @@ uv sync 3. [start your supabase locally](https://supabase.com/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=linux&queryGroups=access-method&access-method=postgres) ```bash -# brew in linux https://brew.sh/ +# brew in linux https://brew.sh/ brew install supabase/tap/supabase supabase init supabase start From a2ba1d9e1cc7e2c6ff5e7a7c10d956b3f0bc117c Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 19:32:48 +0800 Subject: [PATCH 10/65] chore: move app to src/app and add 'pythonpath=src' to pytest config --- pyproject.toml | 1 + {app => src/app}/__init__.py | 0 {app => src/app}/api/__init__.py | 0 {app => src/app}/api/api_v1/__init__.py | 0 {app => src/app}/api/api_v1/api.py | 0 {app => src/app}/api/api_v1/endpoints/__init__.py | 0 {app => src/app}/api/api_v1/endpoints/items.py | 0 {app => src/app}/api/deps.py | 0 {app => src/app}/core/__init__.py | 0 {app => src/app}/core/config.py | 0 {app => src/app}/core/events.py | 0 {app => src/app}/crud/__init__.py | 0 {app => src/app}/crud/base.py | 0 {app => src/app}/crud/crud_item.py | 0 {app => src/app}/main.py | 0 {app => src/app}/schemas/__init__.py | 0 {app => src/app}/schemas/auth.py | 0 {app => src/app}/schemas/base.py | 0 {app => src/app}/schemas/item.py | 0 {app => src/app}/schemas/msg.py | 0 {app => src/app}/services/__init__.py | 0 {app => src/app}/utils/__init__.py | 0 22 files changed, 1 insertion(+) rename {app => src/app}/__init__.py (100%) rename {app => src/app}/api/__init__.py (100%) rename {app => src/app}/api/api_v1/__init__.py (100%) rename {app => src/app}/api/api_v1/api.py (100%) rename {app => src/app}/api/api_v1/endpoints/__init__.py (100%) rename {app => src/app}/api/api_v1/endpoints/items.py (100%) rename {app => src/app}/api/deps.py (100%) rename {app => src/app}/core/__init__.py (100%) rename {app => src/app}/core/config.py (100%) rename {app => src/app}/core/events.py (100%) rename {app => src/app}/crud/__init__.py (100%) rename {app => src/app}/crud/base.py (100%) rename {app => src/app}/crud/crud_item.py (100%) rename {app => src/app}/main.py (100%) rename {app => src/app}/schemas/__init__.py (100%) rename {app => src/app}/schemas/auth.py (100%) rename {app => src/app}/schemas/base.py (100%) rename {app => src/app}/schemas/item.py (100%) rename {app => src/app}/schemas/msg.py (100%) rename {app => src/app}/services/__init__.py (100%) rename {app => src/app}/utils/__init__.py (100%) diff --git a/pyproject.toml b/pyproject.toml index ce1b6c6..a1258ad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -53,6 +53,7 @@ exclude = ["venv", ".venv"] addopts = "-rXs --strict-config --strict-markers" xfail_strict = true # Treat tests that are marked as xfail but pass as test failures filterwarnings = ["error"] # Treat all warnings as errors +pythonpath = "src" [tool.coverage.run] branch = true diff --git a/app/__init__.py b/src/app/__init__.py similarity index 100% rename from app/__init__.py rename to src/app/__init__.py diff --git a/app/api/__init__.py b/src/app/api/__init__.py similarity index 100% rename from app/api/__init__.py rename to src/app/api/__init__.py diff --git a/app/api/api_v1/__init__.py b/src/app/api/api_v1/__init__.py similarity index 100% rename from app/api/api_v1/__init__.py rename to src/app/api/api_v1/__init__.py diff --git a/app/api/api_v1/api.py b/src/app/api/api_v1/api.py similarity index 100% rename from app/api/api_v1/api.py rename to src/app/api/api_v1/api.py diff --git a/app/api/api_v1/endpoints/__init__.py b/src/app/api/api_v1/endpoints/__init__.py similarity index 100% rename from app/api/api_v1/endpoints/__init__.py rename to src/app/api/api_v1/endpoints/__init__.py diff --git a/app/api/api_v1/endpoints/items.py b/src/app/api/api_v1/endpoints/items.py similarity index 100% rename from app/api/api_v1/endpoints/items.py rename to src/app/api/api_v1/endpoints/items.py diff --git a/app/api/deps.py b/src/app/api/deps.py similarity index 100% rename from app/api/deps.py rename to src/app/api/deps.py diff --git a/app/core/__init__.py b/src/app/core/__init__.py similarity index 100% rename from app/core/__init__.py rename to src/app/core/__init__.py diff --git a/app/core/config.py b/src/app/core/config.py similarity index 100% rename from app/core/config.py rename to src/app/core/config.py diff --git a/app/core/events.py b/src/app/core/events.py similarity index 100% rename from app/core/events.py rename to src/app/core/events.py diff --git a/app/crud/__init__.py b/src/app/crud/__init__.py similarity index 100% rename from app/crud/__init__.py rename to src/app/crud/__init__.py diff --git a/app/crud/base.py b/src/app/crud/base.py similarity index 100% rename from app/crud/base.py rename to src/app/crud/base.py diff --git a/app/crud/crud_item.py b/src/app/crud/crud_item.py similarity index 100% rename from app/crud/crud_item.py rename to src/app/crud/crud_item.py diff --git a/app/main.py b/src/app/main.py similarity index 100% rename from app/main.py rename to src/app/main.py diff --git a/app/schemas/__init__.py b/src/app/schemas/__init__.py similarity index 100% rename from app/schemas/__init__.py rename to src/app/schemas/__init__.py diff --git a/app/schemas/auth.py b/src/app/schemas/auth.py similarity index 100% rename from app/schemas/auth.py rename to src/app/schemas/auth.py diff --git a/app/schemas/base.py b/src/app/schemas/base.py similarity index 100% rename from app/schemas/base.py rename to src/app/schemas/base.py diff --git a/app/schemas/item.py b/src/app/schemas/item.py similarity index 100% rename from app/schemas/item.py rename to src/app/schemas/item.py diff --git a/app/schemas/msg.py b/src/app/schemas/msg.py similarity index 100% rename from app/schemas/msg.py rename to src/app/schemas/msg.py diff --git a/app/services/__init__.py b/src/app/services/__init__.py similarity index 100% rename from app/services/__init__.py rename to src/app/services/__init__.py diff --git a/app/utils/__init__.py b/src/app/utils/__init__.py similarity index 100% rename from app/utils/__init__.py rename to src/app/utils/__init__.py From dbeba3a0fbc3a75a1713e14faaacbfc1d3e52020 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 19:35:57 +0800 Subject: [PATCH 11/65] ci: add github release --- .github/workflows/main.yml | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 34b911e..5e04255 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -39,3 +39,38 @@ jobs: uses: codecov/codecov-action@v4 env: CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} + release: + name: Bump Version and Release + needs: test + runs-on: ubuntu-latest + if: startsWith(github.ref, 'refs/tags/') + + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + enable-cache: true + + - name: Install dependencies + run: uv sync --dev + + - name: Generate a changelog + env: + ATTICUS_PAT: ${{ secrets.ATTICUS_PAT }} + run: uv run git-cliff -vv --latest --strip header --github-token "$ATTICUS_PAT" -o CHANGES.md + + - name: Release + uses: softprops/action-gh-release@v2 + with: + body_path: CHANGES.md + token: ${{ secrets.GITHUB_TOKEN }} + +# Reference +# 1. https://docs.astral.sh/uv/guides/integration/github/#syncing-and-running +# 2. https://github.com/Kludex/python-template/blob/main/.github/workflows/main.yml +# 3. https://github.com/softprops/action-gh-release/tree/master/ + From 71d6ed5dc11bea6832ad23b8c19003b4abecb270 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 21:18:00 +0800 Subject: [PATCH 12/65] fix: lint dir --- scripts/format.sh | 4 ++-- scripts/lint.sh | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/format.sh b/scripts/format.sh index 7be2f81..4606558 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -1,5 +1,5 @@ #!/bin/sh -e set -x -ruff check app scripts --fix -ruff format app scripts +ruff check src/app scripts --fix +ruff format src/app scripts diff --git a/scripts/lint.sh b/scripts/lint.sh index 1be0606..d141e02 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -3,6 +3,6 @@ set -e set -x -mypy app # type check -ruff check app # linter -ruff format app --check # formatter +mypy src/app # type check +ruff check src/app # linter +ruff format src/app --check # formatter From 340199db5084390f2a1f6932b9f788cb9b8e167b Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 21:18:34 +0800 Subject: [PATCH 13/65] chore: format --- src/app/api/deps.py | 4 ++-- src/app/crud/base.py | 3 +-- tests/api/api_v1/test_items.py | 13 +++++-------- tests/conftest.py | 16 ++++++++-------- 4 files changed, 16 insertions(+), 20 deletions(-) diff --git a/src/app/api/deps.py b/src/app/api/deps.py index e5e23e5..448fe1a 100644 --- a/src/app/api/deps.py +++ b/src/app/api/deps.py @@ -5,11 +5,11 @@ from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer from gotrue.errors import AuthApiError # type: ignore -from supabase._async.client import AsyncClient, create_client -from supabase.lib.client_options import ClientOptions from app.core.config import settings from app.schemas.auth import UserIn +from supabase._async.client import AsyncClient, create_client +from supabase.lib.client_options import ClientOptions super_client: AsyncClient | None = None diff --git a/src/app/crud/base.py b/src/app/crud/base.py index dd4f9ea..8670ed7 100644 --- a/src/app/crud/base.py +++ b/src/app/crud/base.py @@ -1,9 +1,8 @@ from typing import Generic, TypeVar -from supabase._async.client import AsyncClient - from app.schemas.auth import UserIn from app.schemas.base import CreateBase, ResponseBase, UpdateBase +from supabase._async.client import AsyncClient ModelType = TypeVar("ModelType", bound=ResponseBase) CreateSchemaType = TypeVar("CreateSchemaType", bound=CreateBase) diff --git a/tests/api/api_v1/test_items.py b/tests/api/api_v1/test_items.py index e7b0f7c..774d8e0 100644 --- a/tests/api/api_v1/test_items.py +++ b/tests/api/api_v1/test_items.py @@ -3,19 +3,19 @@ from app.schemas import Token from faker import Faker from starlette.testclient import TestClient -from supabase._async.client import AsyncClient +from supabase._async.client import AsyncClient from tests.utils import get_auth_header @pytest.mark.anyio async def test_create_item(client: TestClient, token: Token) -> None: - # 获取认证头 + headers = get_auth_header(token.access_token) test_data = Faker().sentence() - # 发送请求,同时设置cookie + response = client.post( "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) @@ -37,14 +37,14 @@ async def test_read_item_by_id(client: TestClient, token: Token) -> None: headers = get_auth_header(token.access_token) test_data = Faker().sentence() - # 创建条目 + create_response = client.post( "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} ) assert create_response.status_code == 200 created_item_id = create_response.json()["id"] - # 按ID读取条目 + read_response = client.get( f"/api/v1/items/get-by-id/{created_item_id}", headers=headers ) @@ -76,7 +76,6 @@ async def test_read_item_by_owner( @pytest.mark.anyio async def test_update_item(client: TestClient, token: Token) -> None: - # 创建条目 headers = get_auth_header(token.access_token) test_data = Faker().sentence() create_response = client.post( @@ -85,8 +84,6 @@ async def test_update_item(client: TestClient, token: Token) -> None: assert create_response.status_code == 200 created_item = create_response.json() created_item_id = created_item["id"] - - # 更新条目 updated_data = {"test_data": Faker().sentence(), "id": created_item_id} update_response = client.put( diff --git a/tests/conftest.py b/tests/conftest.py index 608f95b..7c01e94 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -5,14 +5,14 @@ from pathlib import Path import pytest +from app.main import app +from app.schemas import Token from dotenv import load_dotenv from faker import Faker from fastapi.testclient import TestClient from pydantic import ConfigDict -from supabase._async.client import AsyncClient, create_client -from app.main import app -from app.schemas import Token +from supabase._async.client import AsyncClient, create_client from tests.utils import get_auth_header LOG_FILE = Path(__file__).parent / "scripts.log" @@ -84,11 +84,11 @@ async def db() -> AsyncGenerator[AsyncClient, None]: key = os.environ.get("SUPABASE_TEST_KEY") assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" db_client = await create_client(url, key) - await db_client.auth.sign_in_with_password( - {"email": "zhouge1831@gmail.com", "password": "Zz030327#"} - ) - get_session = await db_client.auth.get_session() - assert get_session.user is not None + # await db_client.auth.sign_in_with_password( + # {"email": "zhouge1831@gmail.com", "password": "Zz030327#"} + # ) + # get_session = await db_client.auth.get_session() + # assert get_session.user is not None # logging.info("db_client.get_session", get_session.user.model_dump()) try: yield db_client From db0bad5516c9c945350c149df4e20cee652b1eae Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 21:19:29 +0800 Subject: [PATCH 14/65] fix: update supabase env with local url --- .env | 4 ++-- tests/.env | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.env b/.env index 13ad488..fcf7f24 100644 --- a/.env +++ b/.env @@ -1,4 +1,4 @@ -SUPABASE_URL=https://vtqsboqphlisizfwhrtg.supabase.co -SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ0cXNib3FwaGxpc2l6ZndocnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDQ1MzY4NzIsImV4cCI6MjAyMDExMjg3Mn0.OgApaTXDr7llopKTplpXCsUzDubjbiQFXlaaFf6wlbY +SUPABASE_URL=http://localhost:54321 +SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU SUPERUSER_EMAIL=zhouge1831@gmail.com SUPERUSER_PASSWORD=Zz030327# diff --git a/tests/.env b/tests/.env index c2caf80..a01f9ae 100644 --- a/tests/.env +++ b/tests/.env @@ -1,2 +1,3 @@ -SUPABASE_TEST_URL=https://vtqsboqphlisizfwhrtg.supabase.co -SUPABASE_TEST_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InZ0cXNib3FwaGxpc2l6ZndocnRnIiwicm9sZSI6ImFub24iLCJpYXQiOjE3MDQ1MzY4NzIsImV4cCI6MjAyMDExMjg3Mn0.OgApaTXDr7llopKTplpXCsUzDubjbiQFXlaaFf6wlbY +SUPABASE_TEST_URL=http://localhost:54321 + +SUPABASE_TEST_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU From fa38960fd7f6d2b626d7a53e88a3d12fecaed455 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 6 Nov 2024 21:19:48 +0800 Subject: [PATCH 15/65] chore: vscode python import --- .vscode/PythonImportHelper-v2-Completion.json | 312 +++++++++--------- 1 file changed, 156 insertions(+), 156 deletions(-) diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json index 1f4fa7e..ec2c26f 100644 --- a/.vscode/PythonImportHelper-v2-Completion.json +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -308,6 +308,46 @@ "detail": "gotrue.errors", "documentation": {} }, + { + "label": "settings", + "importPath": "app.core.config", + "description": "app.core.config", + "isExtraImport": true, + "detail": "app.core.config", + "documentation": {} + }, + { + "label": "settings", + "importPath": "app.core.config", + "description": "app.core.config", + "isExtraImport": true, + "detail": "app.core.config", + "documentation": {} + }, + { + "label": "UserIn", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "isExtraImport": true, + "detail": "app.schemas.auth", + "documentation": {} + }, + { + "label": "UserIn", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "isExtraImport": true, + "detail": "app.schemas.auth", + "documentation": {} + }, + { + "label": "UserIn", + "importPath": "app.schemas.auth", + "description": "app.schemas.auth", + "isExtraImport": true, + "detail": "app.schemas.auth", + "documentation": {} + }, { "label": "AsyncClient", "importPath": "supabase._async.client", @@ -380,46 +420,6 @@ "detail": "supabase.lib.client_options", "documentation": {} }, - { - "label": "settings", - "importPath": "app.core.config", - "description": "app.core.config", - "isExtraImport": true, - "detail": "app.core.config", - "documentation": {} - }, - { - "label": "settings", - "importPath": "app.core.config", - "description": "app.core.config", - "isExtraImport": true, - "detail": "app.core.config", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, { "label": "load_dotenv", "importPath": "dotenv", @@ -734,14 +734,6 @@ "detail": "pathlib", "documentation": {} }, - { - "label": "TestClient", - "importPath": "fastapi.testclient", - "description": "fastapi.testclient", - "isExtraImport": true, - "detail": "fastapi.testclient", - "documentation": {} - }, { "label": "app", "importPath": "app.main", @@ -750,6 +742,14 @@ "detail": "app.main", "documentation": {} }, + { + "label": "TestClient", + "importPath": "fastapi.testclient", + "description": "fastapi.testclient", + "isExtraImport": true, + "detail": "fastapi.testclient", + "documentation": {} + }, { "label": "bin_dir", "kind": 5, @@ -834,325 +834,325 @@ { "label": "router", "kind": 5, - "importPath": "app.api.api_v1.endpoints.items", - "description": "app.api.api_v1.endpoints.items", + "importPath": "src.app.api.api_v1.endpoints.items", + "description": "src.app.api.api_v1.endpoints.items", "peekOfCode": "router = APIRouter()\n@router.post(\"/create-item\")\nasync def create_item(item_in: ItemCreate, session: SessionDep) -> Item:\n return await item.create(session, obj_in=item_in)\n@router.get(\"/read-all-item\")\nasync def read_items(session: SessionDep) -> list[Item]:\n return await item.get_all(session)\n@router.get(\"/get-by-id/{id}\")\nasync def read_item_by_id(id: str, session: SessionDep) -> Item | None:\n return await item.get(session, id=id)", - "detail": "app.api.api_v1.endpoints.items", + "detail": "src.app.api.api_v1.endpoints.items", "documentation": {} }, { "label": "api_router", "kind": 5, - "importPath": "app.api.api_v1.api", - "description": "app.api.api_v1.api", + "importPath": "src.app.api.api_v1.api", + "description": "src.app.api.api_v1.api", "peekOfCode": "api_router = APIRouter()\napi_router.include_router(items.router, prefix=\"/items\", tags=[\"items\"])", - "detail": "app.api.api_v1.api", + "detail": "src.app.api.api_v1.api", "documentation": {} }, { "label": "reusable_oauth2", "kind": 5, - "importPath": "app.api.deps", - "description": "app.api.deps", + "importPath": "src.app.api.deps", + "description": "src.app.api.deps", "peekOfCode": "reusable_oauth2 = OAuth2PasswordBearer(\n tokenUrl=\"please login by supabase-js to get token\"\n)\nAccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:", - "detail": "app.api.deps", + "detail": "src.app.api.deps", "documentation": {} }, { "label": "AccessTokenDep", "kind": 5, - "importPath": "app.api.deps", - "description": "app.api.deps", + "importPath": "src.app.api.deps", + "description": "src.app.api.deps", "peekOfCode": "AccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:\n logging.error(\"User not found\")\n raise HTTPException(status_code=404, detail=\"User not found\")\n return UserIn(**user_rsp.user.model_dump(), access_token=access_token)", - "detail": "app.api.deps", + "detail": "src.app.api.deps", "documentation": {} }, { "label": "CurrentUser", "kind": 5, - "importPath": "app.api.deps", - "description": "app.api.deps", + "importPath": "src.app.api.deps", + "description": "src.app.api.deps", "peekOfCode": "CurrentUser = Annotated[UserIn, Depends(get_current_user)]\nasync def get_db(user: CurrentUser) -> AsyncGenerator[AsyncClient, None]:\n client: AsyncClient | None = None\n try:\n client = await create_client(\n settings.SUPABASE_URL,\n settings.SUPABASE_KEY,\n options=ClientOptions(\n postgrest_client_timeout=30,\n storage_client_timeout=30,", - "detail": "app.api.deps", + "detail": "src.app.api.deps", "documentation": {} }, { "label": "SessionDep", "kind": 5, - "importPath": "app.api.deps", - "description": "app.api.deps", + "importPath": "src.app.api.deps", + "description": "src.app.api.deps", "peekOfCode": "SessionDep = Annotated[AsyncClient, Depends(get_db)]", - "detail": "app.api.deps", + "detail": "src.app.api.deps", "documentation": {} }, { "label": "Settings", "kind": 6, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "class Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")\n SERVER_PORT: int = 8000\n # # TODO: the following need to follow the newest version of fastapi", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "log_format", "kind": 5, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "log_format = logging.Formatter(\"%(asctime)s : %(levelname)s - %(message)s\")\n# root logger\nroot_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "root_logger", "kind": 5, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "root_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "stream_handler", "kind": 5, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "stream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "logger", "kind": 5, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "logger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "settings", "kind": 5, - "importPath": "app.core.config", - "description": "app.core.config", + "importPath": "src.app.core.config", + "description": "src.app.core.config", "peekOfCode": "settings = Settings()", - "detail": "app.core.config", + "detail": "src.app.core.config", "documentation": {} }, { "label": "CRUDBase", "kind": 6, - "importPath": "app.crud.base", - "description": "app.crud.base", + "importPath": "src.app.crud.base", + "description": "src.app.crud.base", "peekOfCode": "class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data\n return self.model(**got[0]) if got else None", - "detail": "app.crud.base", + "detail": "src.app.crud.base", "documentation": {} }, { "label": "ModelType", "kind": 5, - "importPath": "app.crud.base", - "description": "app.crud.base", + "importPath": "src.app.crud.base", + "description": "src.app.crud.base", "peekOfCode": "ModelType = TypeVar(\"ModelType\", bound=ResponseBase)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()", - "detail": "app.crud.base", + "detail": "src.app.crud.base", "documentation": {} }, { "label": "CreateSchemaType", "kind": 5, - "importPath": "app.crud.base", - "description": "app.crud.base", + "importPath": "src.app.crud.base", + "description": "src.app.crud.base", "peekOfCode": "CreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )", - "detail": "app.crud.base", + "detail": "src.app.crud.base", "documentation": {} }, { "label": "UpdateSchemaType", "kind": 5, - "importPath": "app.crud.base", - "description": "app.crud.base", + "importPath": "src.app.crud.base", + "description": "src.app.crud.base", "peekOfCode": "UpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data", - "detail": "app.crud.base", + "detail": "src.app.crud.base", "documentation": {} }, { "label": "CRUDItem", "kind": 6, - "importPath": "app.crud.crud_item", - "description": "app.crud.crud_item", + "importPath": "src.app.crud.crud_item", + "description": "src.app.crud.crud_item", "peekOfCode": "class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]):\n async def create(self, db: AsyncClient, *, obj_in: ItemCreate) -> Item:\n return await super().create(db, obj_in=obj_in)\n async def get(self, db: AsyncClient, *, id: str) -> Item | None:\n return await super().get(db, id=id)\n async def get_all(self, db: AsyncClient) -> list[Item]:\n return await super().get_all(db)\n async def get_multi_by_owner(self, db: AsyncClient, *, user: UserIn) -> list[Item]:\n return await super().get_multi_by_owner(db, user=user)\n async def update(self, db: AsyncClient, *, obj_in: ItemUpdate) -> Item:", - "detail": "app.crud.crud_item", + "detail": "src.app.crud.crud_item", "documentation": {} }, { "label": "item", "kind": 5, - "importPath": "app.crud.crud_item", - "description": "app.crud.crud_item", + "importPath": "src.app.crud.crud_item", + "description": "src.app.crud.crud_item", "peekOfCode": "item = CRUDItem(Item)", - "detail": "app.crud.crud_item", + "detail": "src.app.crud.crud_item", "documentation": {} }, { "label": "Token", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class Token(BaseModel):\n access_token: str | None = None\n refresh_token: str | None = None\n# request\nclass UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserIn", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserCreate", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserUpdate", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserInDBBase", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserOut", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "UserInDB", "kind": 6, - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", + "importPath": "src.app.schemas.auth", + "description": "src.app.schemas.auth", "peekOfCode": "class UserInDB(User): # type: ignore\n pass", - "detail": "app.schemas.auth", + "detail": "src.app.schemas.auth", "documentation": {} }, { "label": "CreateBase", "kind": 6, - "importPath": "app.schemas.base", - "description": "app.schemas.base", + "importPath": "src.app.schemas.base", + "description": "src.app.schemas.base", "peekOfCode": "class CreateBase(BaseModel):\n # inherent to add more properties for creating\n pass\n# Properties to receive on item update\n# in\nclass UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB", - "detail": "app.schemas.base", + "detail": "src.app.schemas.base", "documentation": {} }, { "label": "UpdateBase", "kind": 6, - "importPath": "app.schemas.base", - "description": "app.schemas.base", + "importPath": "src.app.schemas.base", + "description": "src.app.schemas.base", "peekOfCode": "class UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB\nclass InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client", - "detail": "app.schemas.base", + "detail": "src.app.schemas.base", "documentation": {} }, { "label": "InDBBase", "kind": 6, - "importPath": "app.schemas.base", - "description": "app.schemas.base", + "importPath": "src.app.schemas.base", + "description": "src.app.schemas.base", "peekOfCode": "class InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client\n# curd model\n# out\nclass ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()", - "detail": "app.schemas.base", + "detail": "src.app.schemas.base", "documentation": {} }, { "label": "ResponseBase", "kind": 6, - "importPath": "app.schemas.base", - "description": "app.schemas.base", + "importPath": "src.app.schemas.base", + "description": "src.app.schemas.base", "peekOfCode": "class ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()\n Config: ClassVar[ConfigDict] = ConfigDict(\n extra=\"ignore\", arbitrary_types_allowed=True\n )", - "detail": "app.schemas.base", + "detail": "src.app.schemas.base", "documentation": {} }, { "label": "ItemCreate", "kind": 6, - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "importPath": "src.app.schemas.item", + "description": "src.app.schemas.item", "peekOfCode": "class ItemCreate(CreateBase):\n test_data: str\n# Properties to receive on item update\n# in\nclass ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):", - "detail": "app.schemas.item", + "detail": "src.app.schemas.item", "documentation": {} }, { "label": "ItemUpdate", "kind": 6, - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "importPath": "src.app.schemas.item", + "description": "src.app.schemas.item", "peekOfCode": "class ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):", - "detail": "app.schemas.item", + "detail": "src.app.schemas.item", "documentation": {} }, { "label": "Item", "kind": 6, - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "importPath": "src.app.schemas.item", + "description": "src.app.schemas.item", "peekOfCode": "class Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):\n test_data: str", - "detail": "app.schemas.item", + "detail": "src.app.schemas.item", "documentation": {} }, { "label": "ItemInDB", "kind": 6, - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "importPath": "src.app.schemas.item", + "description": "src.app.schemas.item", "peekOfCode": "class ItemInDB(InDBBase):\n test_data: str", - "detail": "app.schemas.item", + "detail": "src.app.schemas.item", "documentation": {} }, { "label": "Massage", "kind": 6, - "importPath": "app.schemas.msg", - "description": "app.schemas.msg", + "importPath": "src.app.schemas.msg", + "description": "src.app.schemas.msg", "peekOfCode": "class Massage(BaseModel):\n msg: str", - "detail": "app.schemas.msg", + "detail": "src.app.schemas.msg", "documentation": {} }, { "label": "create_app", "kind": 2, - "importPath": "app.main", - "description": "app.main", + "importPath": "src.app.main", + "description": "src.app.main", "peekOfCode": "def create_app() -> FastAPI:\n # init FastAPI with lifespan\n app = FastAPI(\n lifespan=lifespan,\n title=settings.PROJECT_NAME,\n openapi_url=f\"{settings.API_V1_STR}/openapi.json\",\n generate_unique_id_function=lambda router: f\"{router.tags[0]}-{router.name}\",\n )\n # set CORS\n # Set all CORS enabled origins", - "detail": "app.main", + "detail": "src.app.main", "documentation": {} }, { "label": "app", "kind": 5, - "importPath": "app.main", - "description": "app.main", + "importPath": "src.app.main", + "description": "src.app.main", "peekOfCode": "app = create_app()\nif __name__ == \"__main__\":\n host = \"localhost\"\n port = 5000\n uvicorn.run(app, host=host, port=port)", - "detail": "app.main", + "detail": "src.app.main", "documentation": {} }, { From 0a14327ff8534f8ebd8e211ef15642cb54dc08ee Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 16:19:17 +0800 Subject: [PATCH 16/65] chore: update python import vscode plugin --- .vscode/PythonImportHelper-v2-Completion.json | 300 ++++++++---------- 1 file changed, 139 insertions(+), 161 deletions(-) diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json index ec2c26f..d8746e8 100644 --- a/.vscode/PythonImportHelper-v2-Completion.json +++ b/.vscode/PythonImportHelper-v2-Completion.json @@ -52,7 +52,7 @@ "documentation": {} }, { - "label": "APIRouter", + "label": "Depends", "importPath": "fastapi", "description": "fastapi", "isExtraImport": true, @@ -60,7 +60,7 @@ "documentation": {} }, { - "label": "Depends", + "label": "HTTPException", "importPath": "fastapi", "description": "fastapi", "isExtraImport": true, @@ -68,7 +68,7 @@ "documentation": {} }, { - "label": "HTTPException", + "label": "APIRouter", "importPath": "fastapi", "description": "fastapi", "isExtraImport": true, @@ -179,30 +179,6 @@ "detail": "app.schemas", "documentation": {} }, - { - "label": "Token", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "Token", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "items", - "importPath": "app.api.api_v1.endpoints", - "description": "app.api.api_v1.endpoints", - "isExtraImport": true, - "detail": "app.api.api_v1.endpoints", - "documentation": {} - }, { "label": "logging", "kind": 6, @@ -253,7 +229,31 @@ "documentation": {} }, { - "label": "ClassVar", + "label": "Annotated", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Any", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Literal", + "importPath": "typing", + "description": "typing", + "isExtraImport": true, + "detail": "typing", + "documentation": {} + }, + { + "label": "Self", "importPath": "typing", "description": "typing", "isExtraImport": true, @@ -389,7 +389,7 @@ "documentation": {} }, { - "label": "AsyncClient", + "label": "create_client", "importPath": "supabase._async.client", "description": "supabase._async.client", "isExtraImport": true, @@ -397,47 +397,49 @@ "documentation": {} }, { - "label": "AsyncClient", - "importPath": "supabase._async.client", - "description": "supabase._async.client", + "label": "ClientOptions", + "importPath": "supabase.lib.client_options", + "description": "supabase.lib.client_options", "isExtraImport": true, - "detail": "supabase._async.client", + "detail": "supabase.lib.client_options", "documentation": {} }, { - "label": "create_client", - "importPath": "supabase._async.client", - "description": "supabase._async.client", + "label": "items", + "importPath": "app.api.routes", + "description": "app.api.routes", "isExtraImport": true, - "detail": "supabase._async.client", + "detail": "app.api.routes", "documentation": {} }, { - "label": "ClientOptions", - "importPath": "supabase.lib.client_options", - "description": "supabase.lib.client_options", + "label": "secrets", + "kind": 6, "isExtraImport": true, - "detail": "supabase.lib.client_options", + "importPath": "secrets", + "description": "secrets", + "detail": "secrets", "documentation": {} }, { - "label": "load_dotenv", - "importPath": "dotenv", - "description": "dotenv", + "label": "warnings", + "kind": 6, "isExtraImport": true, - "detail": "dotenv", + "importPath": "warnings", + "description": "warnings", + "detail": "warnings", "documentation": {} }, { - "label": "load_dotenv", - "importPath": "dotenv", - "description": "dotenv", + "label": "AnyUrl", + "importPath": "pydantic", + "description": "pydantic", "isExtraImport": true, - "detail": "dotenv", + "detail": "pydantic", "documentation": {} }, { - "label": "AnyHttpUrl", + "label": "BeforeValidator", "importPath": "pydantic", "description": "pydantic", "isExtraImport": true, @@ -445,7 +447,7 @@ "documentation": {} }, { - "label": "ConfigDict", + "label": "PostgresDsn", "importPath": "pydantic", "description": "pydantic", "isExtraImport": true, @@ -453,7 +455,15 @@ "documentation": {} }, { - "label": "Field", + "label": "computed_field", + "importPath": "pydantic", + "description": "pydantic", + "isExtraImport": true, + "detail": "pydantic", + "documentation": {} + }, + { + "label": "model_validator", "importPath": "pydantic", "description": "pydantic", "isExtraImport": true, @@ -500,6 +510,14 @@ "detail": "pydantic", "documentation": {} }, + { + "label": "MultiHostUrl", + "importPath": "pydantic_core", + "description": "pydantic_core", + "isExtraImport": true, + "detail": "pydantic_core", + "documentation": {} + }, { "label": "BaseSettings", "importPath": "pydantic_settings", @@ -508,6 +526,14 @@ "detail": "pydantic_settings", "documentation": {} }, + { + "label": "SettingsConfigDict", + "importPath": "pydantic_settings", + "description": "pydantic_settings", + "isExtraImport": true, + "detail": "pydantic_settings", + "documentation": {} + }, { "label": "asynccontextmanager", "importPath": "contextlib", @@ -615,10 +641,10 @@ }, { "label": "api_router", - "importPath": "app.api.api_v1.api", - "description": "app.api.api_v1.api", + "importPath": "app.api.main", + "description": "app.api.main", "isExtraImport": true, - "detail": "app.api.api_v1.api", + "detail": "app.api.main", "documentation": {} }, { @@ -638,84 +664,20 @@ "detail": "pytest", "documentation": {} }, - { - "label": "Faker", - "importPath": "faker", - "description": "faker", - "isExtraImport": true, - "detail": "faker", - "documentation": {} - }, - { - "label": "Faker", - "importPath": "faker", - "description": "faker", - "isExtraImport": true, - "detail": "faker", - "documentation": {} - }, - { - "label": "Faker", - "importPath": "faker", - "description": "faker", - "isExtraImport": true, - "detail": "faker", - "documentation": {} - }, { "label": "TestClient", - "importPath": "starlette.testclient", - "description": "starlette.testclient", - "isExtraImport": true, - "detail": "starlette.testclient", - "documentation": {} - }, - { - "label": "get_auth_header", - "importPath": "tests.utils", - "description": "tests.utils", - "isExtraImport": true, - "detail": "tests.utils", - "documentation": {} - }, - { - "label": "get_auth_header", - "importPath": "tests.utils", - "description": "tests.utils", - "isExtraImport": true, - "detail": "tests.utils", - "documentation": {} - }, - { - "label": "crud", - "importPath": "app", - "description": "app", - "isExtraImport": true, - "detail": "app", - "documentation": {} - }, - { - "label": "Item", - "importPath": "app.schemas.item", - "description": "app.schemas.item", - "isExtraImport": true, - "detail": "app.schemas.item", - "documentation": {} - }, - { - "label": "ItemCreate", - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "importPath": "fastapi.testclient", + "description": "fastapi.testclient", "isExtraImport": true, - "detail": "app.schemas.item", + "detail": "fastapi.testclient", "documentation": {} }, { - "label": "ItemUpdate", - "importPath": "app.schemas.item", - "description": "app.schemas.item", + "label": "TestClient", + "importPath": "fastapi.testclient", + "description": "fastapi.testclient", "isExtraImport": true, - "detail": "app.schemas.item", + "detail": "fastapi.testclient", "documentation": {} }, { @@ -734,20 +696,36 @@ "detail": "pathlib", "documentation": {} }, + { + "label": "load_dotenv", + "importPath": "dotenv", + "description": "dotenv", + "isExtraImport": true, + "detail": "dotenv", + "documentation": {} + }, + { + "label": "Faker", + "importPath": "faker", + "description": "faker", + "isExtraImport": true, + "detail": "faker", + "documentation": {} + }, { "label": "app", - "importPath": "app.main", - "description": "app.main", + "importPath": "src.app.main", + "description": "src.app.main", "isExtraImport": true, - "detail": "app.main", + "detail": "src.app.main", "documentation": {} }, { - "label": "TestClient", - "importPath": "fastapi.testclient", - "description": "fastapi.testclient", + "label": "Token", + "importPath": "src.app.schemas", + "description": "src.app.schemas", "isExtraImport": true, - "detail": "fastapi.testclient", + "detail": "src.app.schemas", "documentation": {} }, { @@ -834,19 +812,10 @@ { "label": "router", "kind": 5, - "importPath": "src.app.api.api_v1.endpoints.items", - "description": "src.app.api.api_v1.endpoints.items", + "importPath": "src.app.api.routes.items", + "description": "src.app.api.routes.items", "peekOfCode": "router = APIRouter()\n@router.post(\"/create-item\")\nasync def create_item(item_in: ItemCreate, session: SessionDep) -> Item:\n return await item.create(session, obj_in=item_in)\n@router.get(\"/read-all-item\")\nasync def read_items(session: SessionDep) -> list[Item]:\n return await item.get_all(session)\n@router.get(\"/get-by-id/{id}\")\nasync def read_item_by_id(id: str, session: SessionDep) -> Item | None:\n return await item.get(session, id=id)", - "detail": "src.app.api.api_v1.endpoints.items", - "documentation": {} - }, - { - "label": "api_router", - "kind": 5, - "importPath": "src.app.api.api_v1.api", - "description": "src.app.api.api_v1.api", - "peekOfCode": "api_router = APIRouter()\napi_router.include_router(items.router, prefix=\"/items\", tags=[\"items\"])", - "detail": "src.app.api.api_v1.api", + "detail": "src.app.api.routes.items", "documentation": {} }, { @@ -885,12 +854,30 @@ "detail": "src.app.api.deps", "documentation": {} }, + { + "label": "api_router", + "kind": 5, + "importPath": "src.app.api.main", + "description": "src.app.api.main", + "peekOfCode": "api_router = APIRouter()\napi_router.include_router(items.router, prefix=\"/items\", tags=[\"items\"])", + "detail": "src.app.api.main", + "documentation": {} + }, { "label": "Settings", "kind": 6, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "class Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")\n SERVER_PORT: int = 8000\n # # TODO: the following need to follow the newest version of fastapi", + "peekOfCode": "class Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support\n model_config = SettingsConfigDict(\n # Use top level .env file (one level above ./backend/)\n env_file=\"../.env\",\n env_ignore_empty=True,\n extra=\"ignore\",\n )\n API_V1_STR: str = \"/api/v1\"", + "detail": "src.app.core.config", + "documentation": {} + }, + { + "label": "parse_cors", + "kind": 2, + "importPath": "src.app.core.config", + "description": "src.app.core.config", + "peekOfCode": "def parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)\nclass Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support\n model_config = SettingsConfigDict(", "detail": "src.app.core.config", "documentation": {} }, @@ -899,7 +886,7 @@ "kind": 5, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "log_format = logging.Formatter(\"%(asctime)s : %(levelname)s - %(message)s\")\n# root logger\nroot_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()", + "peekOfCode": "log_format = logging.Formatter(\"%(asctime)s : %(levelname)s - %(message)s\")\n# root logger\nroot_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:", "detail": "src.app.core.config", "documentation": {} }, @@ -908,7 +895,7 @@ "kind": 5, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "root_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"", + "peekOfCode": "root_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]", "detail": "src.app.core.config", "documentation": {} }, @@ -917,7 +904,7 @@ "kind": 5, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "stream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))", + "peekOfCode": "stream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)", "detail": "src.app.core.config", "documentation": {} }, @@ -926,7 +913,7 @@ "kind": 5, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "logger = logging.getLogger(__name__)\nload_dotenv()\nclass Settings(BaseSettings):\n API_V1_STR: str = \"/api/v1\"\n SUPABASE_URL: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_URL\"))\n SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv(\"SUPABASE_KEY\"))\n SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv(\"SUPERUSER_EMAIL\"))\n SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv(\"SUPERUSER_PASSWORD\"))\n # SERVER_NAME: str\n SERVER_HOST: AnyHttpUrl = AnyHttpUrl(\"https://localhost\")", + "peekOfCode": "logger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)\nclass Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support", "detail": "src.app.core.config", "documentation": {} }, @@ -935,7 +922,7 @@ "kind": 5, "importPath": "src.app.core.config", "description": "src.app.core.config", - "peekOfCode": "settings = Settings()", + "peekOfCode": "settings = Settings() # type: ignore[call-arg] # load args from env", "detail": "src.app.core.config", "documentation": {} }, @@ -1137,21 +1124,12 @@ "detail": "src.app.schemas.msg", "documentation": {} }, - { - "label": "create_app", - "kind": 2, - "importPath": "src.app.main", - "description": "src.app.main", - "peekOfCode": "def create_app() -> FastAPI:\n # init FastAPI with lifespan\n app = FastAPI(\n lifespan=lifespan,\n title=settings.PROJECT_NAME,\n openapi_url=f\"{settings.API_V1_STR}/openapi.json\",\n generate_unique_id_function=lambda router: f\"{router.tags[0]}-{router.name}\",\n )\n # set CORS\n # Set all CORS enabled origins", - "detail": "src.app.main", - "documentation": {} - }, { "label": "app", "kind": 5, "importPath": "src.app.main", "description": "src.app.main", - "peekOfCode": "app = create_app()\nif __name__ == \"__main__\":\n host = \"localhost\"\n port = 5000\n uvicorn.run(app, host=host, port=port)", + "peekOfCode": "app = FastAPI(\n lifespan=lifespan,\n title=settings.PROJECT_NAME,\n openapi_url=f\"{settings.API_V1_STR}/openapi.json\",\n generate_unique_id_function=lambda router: f\"{router.tags[0]}-{router.name}\",\n)\n# Set all CORS enabled origins\nif settings.all_cors_origins:\n app.add_middleware(\n CORSMiddleware,", "detail": "src.app.main", "documentation": {} }, From 356547d9ec35357e9a618d49e9864e03e5424aad Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 16:20:37 +0800 Subject: [PATCH 17/65] style: add tests/ into format --- scripts/format.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/format.sh b/scripts/format.sh index 4606558..6ff5f04 100755 --- a/scripts/format.sh +++ b/scripts/format.sh @@ -1,5 +1,5 @@ #!/bin/sh -e set -x -ruff check src/app scripts --fix -ruff format src/app scripts +ruff check src/app scripts tests --fix +ruff format src/app scripts tests From 7f7480a98acda39124b70d16620084b486f8916e Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 16:23:19 +0800 Subject: [PATCH 18/65] refactor: update fastapi config with db and etc. and move partial settings into `.envs` --- .env | 32 +++++++++- .gitignore | 2 +- src/app/core/config.py | 129 +++++++++++++++++++++++++++++------------ src/app/main.py | 49 +++++++--------- 4 files changed, 143 insertions(+), 69 deletions(-) diff --git a/.env b/.env index fcf7f24..3986cdd 100644 --- a/.env +++ b/.env @@ -1,4 +1,32 @@ +# Domain +# This would be set to the production domain with an env var on deployment +DOMAIN=localhost + +# FRONTEND_HOST=http://localhost:5173 + +# Environment: local, staging, production +ENVIRONMENT=local + +PROJECT_NAME="FastAPI Supabase Template" + +# Backend +BACKEND_CORS_ORIGINS="http://localhost" +SECRET_KEY=local_dev + +# run `supabase status` +# API URL SUPABASE_URL=http://localhost:54321 +# service_role key SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU -SUPERUSER_EMAIL=zhouge1831@gmail.com -SUPERUSER_PASSWORD=Zz030327# + +# Postgres +# DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres +POSTGRES_SERVER=localhost +POSTGRES_PORT=54322 +POSTGRES_DB=postgres +POSTGRES_USER=postgres +POSTGRES_PASSWORD=postgres + +# Configure these with your own Docker registry images +# DOCKER_IMAGE_BACKEND=backend +# DOCKER_IMAGE_FRONTEND=frontend diff --git a/.gitignore b/.gitignore index 3248dfb..85919c7 100644 --- a/.gitignore +++ b/.gitignore @@ -123,7 +123,7 @@ celerybeat.pid *.sage.py # Environments -.env +# .env .venv env/ venv/ diff --git a/src/app/core/config.py b/src/app/core/config.py index ba5d4e6..bf02681 100644 --- a/src/app/core/config.py +++ b/src/app/core/config.py @@ -1,10 +1,17 @@ import logging -import os -from typing import ClassVar +import secrets +import warnings +from typing import Annotated, Any, Literal, Self -from dotenv import load_dotenv -from pydantic import AnyHttpUrl, ConfigDict, Field -from pydantic_settings import BaseSettings +from pydantic import ( + AnyUrl, + BeforeValidator, + PostgresDsn, + computed_field, + model_validator, +) +from pydantic_core import MultiHostUrl +from pydantic_settings import BaseSettings, SettingsConfigDict log_format = logging.Formatter("%(asctime)s : %(levelname)s - %(message)s") @@ -18,39 +25,87 @@ root_logger.addHandler(stream_handler) logger = logging.getLogger(__name__) -load_dotenv() + + +def parse_cors(v: Any) -> list[str] | str: + if isinstance(v, str) and not v.startswith("["): + return [i.strip() for i in v.split(",")] + elif isinstance(v, list | str): + return v + raise ValueError(v) class Settings(BaseSettings): + """auto load config from .env and validate settings""" + + # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support + model_config = SettingsConfigDict( + # Use top level .env file (one level above ./backend/) + env_file="../.env", + env_ignore_empty=True, + extra="ignore", + ) API_V1_STR: str = "/api/v1" - SUPABASE_URL: str = Field(default_factory=lambda: os.getenv("SUPABASE_URL")) - SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv("SUPABASE_KEY")) - SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv("SUPERUSER_EMAIL")) - SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv("SUPERUSER_PASSWORD")) - # SERVER_NAME: str - SERVER_HOST: AnyHttpUrl = AnyHttpUrl("https://localhost") - SERVER_PORT: int = 8000 - # # TODO: the following need to follow the newest version of fastapi - # # BACKEND_CORS_ORIGINS is a JSON-formatted list of origins - # # e.g: '["http://localhost", "http://localhost:4200", "http://localhost:3000", \ - # # "http://localhost:8080", "http://local.dockertoolbox.tiangolo.com"]' - BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = [] - # - # @validator("BACKEND_CORS_ORIGINS", pre=True) - # def assemble_cors_origins(cls, v: Union[str, List[str]]) -> Union[List[str], str]: - # if isinstance(v, str) and not v.startswith("["): - # return [i.strip() for i in v.split(",")] - # elif isinstance(v, (list, str)): - # return v - # raise ValueError(v) - # - PROJECT_NAME: str = "fastapi supabase template" - - # class Config(ConfigDict): - # """sensitive to lowercase""" - # - # case_sensitive = True - Config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) - - -settings = Settings() + SECRET_KEY: str = secrets.token_urlsafe(32) + ENVIRONMENT: Literal["local", "staging", "production"] = "local" + + # FRONTEND_HOST: str = "http://localhost:5173" + BACKEND_CORS_ORIGINS: Annotated[ + list[AnyUrl] | str, BeforeValidator(parse_cors) + ] = [] + + @computed_field # type: ignore[prop-decorator] + @property + def all_cors_origins(self) -> list[str]: + return ( + [str(origin).rstrip("/") for origin in self.BACKEND_CORS_ORIGINS] + + [ + # self.FRONTEND_HOST + ] + ) + + PROJECT_NAME: str + + ## DB + SUPABASE_URL: str + # NOTE: super user key is service_role key instead of the anon key + SUPABASE_KEY: str + + POSTGRES_SERVER: str + POSTGRES_PORT: int = 5432 + POSTGRES_USER: str + POSTGRES_PASSWORD: str = "" + POSTGRES_DB: str = "" + + @computed_field # type: ignore[prop-decorator] + @property + def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: + return MultiHostUrl.build( + scheme="postgresql+psycopg", + username=self.POSTGRES_USER, + password=self.POSTGRES_PASSWORD, + host=self.POSTGRES_SERVER, + port=self.POSTGRES_PORT, + path=self.POSTGRES_DB, + ) + + def _check_default_secret(self, var_name: str, value: str | None) -> None: + if value == "changethis": + message = ( + f'The value of {var_name} is "changethis", ' + "for security, please change it, at least for deployments." + ) + if self.ENVIRONMENT == "local": + warnings.warn(message, stacklevel=1) + else: + raise ValueError(message) + + @model_validator(mode="after") + def _enforce_non_default_secrets(self) -> Self: + self._check_default_secret("SECRET_KEY", self.SECRET_KEY) + self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD) + + return self + + +settings = Settings() # type: ignore[call-arg] # load args from env diff --git a/src/app/main.py b/src/app/main.py index 6f6fa56..7203397 100644 --- a/src/app/main.py +++ b/src/app/main.py @@ -2,39 +2,30 @@ from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware -from app.api.api_v1.api import api_router +from app.api.main import api_router from app.core.config import settings from app.core.events import lifespan - -def create_app() -> FastAPI: - # init FastAPI with lifespan - app = FastAPI( - lifespan=lifespan, - title=settings.PROJECT_NAME, - openapi_url=f"{settings.API_V1_STR}/openapi.json", - generate_unique_id_function=lambda router: f"{router.tags[0]}-{router.name}", +# init FastAPI with lifespan +app = FastAPI( + lifespan=lifespan, + title=settings.PROJECT_NAME, + openapi_url=f"{settings.API_V1_STR}/openapi.json", + generate_unique_id_function=lambda router: f"{router.tags[0]}-{router.name}", +) + +# Set all CORS enabled origins +if settings.all_cors_origins: + app.add_middleware( + CORSMiddleware, + allow_origins=settings.all_cors_origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], ) - # set CORS - # Set all CORS enabled origins - if settings.BACKEND_CORS_ORIGINS: - app.add_middleware( - CORSMiddleware, - allow_origins=[str(origin) for origin in settings.BACKEND_CORS_ORIGINS], - allow_credentials=True, - allow_methods=["*"], - allow_headers=["*"], - ) - - # Include the routers - app.include_router(api_router, prefix=settings.API_V1_STR) - - return app - -app = create_app() +# Include the routers +app.include_router(api_router, prefix=settings.API_V1_STR) if __name__ == "__main__": - host = "localhost" - port = 5000 - uvicorn.run(app, host=host, port=port) + uvicorn.run(app, host="0.0.0.0", port=8000) From 6a12be0545b411959710ae34197f1251e04e2d56 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 16:24:32 +0800 Subject: [PATCH 19/65] test: add basic lifespan test --- tests/pre_start/test_main.py | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 tests/pre_start/test_main.py diff --git a/tests/pre_start/test_main.py b/tests/pre_start/test_main.py new file mode 100644 index 0000000..800229e --- /dev/null +++ b/tests/pre_start/test_main.py @@ -0,0 +1,8 @@ +import pytest +from fastapi.testclient import TestClient + + +@pytest.mark.anyio +async def test_read_main(client: TestClient) -> None: + response = client.get("/docs") + assert response.status_code == 200 From 3f804173c83b5c38b097371c9eda6ecf17886803 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 17:59:18 +0800 Subject: [PATCH 20/65] fix: add superuser into config --- .env | 2 ++ src/app/core/config.py | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.env b/.env index 3986cdd..0e4dca2 100644 --- a/.env +++ b/.env @@ -12,6 +12,8 @@ PROJECT_NAME="FastAPI Supabase Template" # Backend BACKEND_CORS_ORIGINS="http://localhost" SECRET_KEY=local_dev +FIRST_SUPERUSER=admin@example.com +FIRST_SUPERUSER_PASSWORD=admin # run `supabase status` # API URL diff --git a/src/app/core/config.py b/src/app/core/config.py index bf02681..8fbc4cd 100644 --- a/src/app/core/config.py +++ b/src/app/core/config.py @@ -25,6 +25,7 @@ root_logger.addHandler(stream_handler) logger = logging.getLogger(__name__) +# TODO: remove logger configs def parse_cors(v: Any) -> list[str] | str: @@ -89,6 +90,9 @@ def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: path=self.POSTGRES_DB, ) + FIRST_SUPERUSER: str + FIRST_SUPERUSER_PASSWORD: str + def _check_default_secret(self, var_name: str, value: str | None) -> None: if value == "changethis": message = ( @@ -104,7 +108,9 @@ def _check_default_secret(self, var_name: str, value: str | None) -> None: def _enforce_non_default_secrets(self) -> Self: self._check_default_secret("SECRET_KEY", self.SECRET_KEY) self._check_default_secret("POSTGRES_PASSWORD", self.POSTGRES_PASSWORD) - + self._check_default_secret( + "FIRST_SUPERUSER_PASSWORD", self.FIRST_SUPERUSER_PASSWORD + ) return self From 3e113f2d8adfd6896d1dd894580dab3184bf22db Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Fri, 8 Nov 2024 18:01:44 +0800 Subject: [PATCH 21/65] refactor: treat super_client as Depends --- src/app/api/deps.py | 62 ++++++++++++++---------------------------- src/app/core/events.py | 3 -- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/app/api/deps.py b/src/app/api/deps.py index 448fe1a..218c773 100644 --- a/src/app/api/deps.py +++ b/src/app/api/deps.py @@ -1,44 +1,40 @@ import logging -from collections.abc import AsyncGenerator +from collections.abc import Generator from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer -from gotrue.errors import AuthApiError # type: ignore +from sqlmodel import Session, create_engine from app.core.config import settings from app.schemas.auth import UserIn from supabase._async.client import AsyncClient, create_client from supabase.lib.client_options import ClientOptions -super_client: AsyncClient | None = None - -async def init_super_client() -> None: +async def get_super_client() -> AsyncClient: """for validation access_token init at life span event""" - global super_client super_client = await create_client( settings.SUPABASE_URL, settings.SUPABASE_KEY, options=ClientOptions(postgrest_client_timeout=10, storage_client_timeout=10), ) - # await super_client.auth.sign_in_with_password( - # {"email": settings.SUPERUSER_EMAIL, "password": settings.SUPERUSER_PASSWORD} - # ) + if not super_client: + raise HTTPException(status_code=500, detail="Super client not initialized") + return super_client +SuperClient = Annotated[AsyncClient, Depends(get_super_client)] + # auto get access_token from header -reusable_oauth2 = OAuth2PasswordBearer( - tokenUrl="please login by supabase-js to get token" -) +reusable_oauth2 = OAuth2PasswordBearer(tokenUrl="Token") AccessTokenDep = Annotated[str, Depends(reusable_oauth2)] -async def get_current_user(access_token: AccessTokenDep) -> UserIn: +async def get_current_user( + access_token: AccessTokenDep, super_client: SuperClient +) -> UserIn: """get current user from access_token and validate same time""" - if not super_client: - raise HTTPException(status_code=500, detail="Super client not initialized") - user_rsp = await super_client.auth.get_user(jwt=access_token) if not user_rsp: logging.error("User not found") @@ -49,28 +45,12 @@ async def get_current_user(access_token: AccessTokenDep) -> UserIn: CurrentUser = Annotated[UserIn, Depends(get_current_user)] -async def get_db(user: CurrentUser) -> AsyncGenerator[AsyncClient, None]: - client: AsyncClient | None = None - try: - client = await create_client( - settings.SUPABASE_URL, - settings.SUPABASE_KEY, - options=ClientOptions( - postgrest_client_timeout=30, - storage_client_timeout=30, - headers={"Authorization": f"Bearer {user.access_token}"}, - ), - ) - # checks all done in supabase-py ! - # await client.auth.set_session(token.access_token, token.refresh_token) - # session = await client.auth.get_session() - yield client - - except AuthApiError as e: - logging.error(e) - raise HTTPException( - status_code=401, detail="Invalid authentication credentials" - ) - - -SessionDep = Annotated[AsyncClient, Depends(get_db)] +engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI)) + + +def get_db() -> Generator[Session, None, None]: + with Session(engine) as session: + yield session + + +SessionDep = Annotated[Session, Depends(get_db)] diff --git a/src/app/core/events.py b/src/app/core/events.py index f84c46f..b6c27e8 100644 --- a/src/app/core/events.py +++ b/src/app/core/events.py @@ -8,14 +8,11 @@ from fastapi import FastAPI -from app.api.deps import init_super_client - @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 """life span events""" try: - await init_super_client() yield finally: logging.info("lifespan shutdown") From cfbbbaab15c106b90225bb1142ff71a7eb93bd1c Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 13:43:49 +0800 Subject: [PATCH 22/65] refactor: move src/app,supabase into backend/ --- {src => backend}/app/__init__.py | 0 {src => backend}/app/api/__init__.py | 0 backend/app/api/deps.py | 13 ++ .../api_v1/api.py => backend/app/api/main.py | 2 +- .../app/api/routes}/__init__.py | 0 .../app/api/routes}/items.py | 0 .../app/core}/__init__.py | 0 .../api/deps.py => backend/app/core/auth.py | 35 ++---- {src => backend}/app/core/config.py | 3 +- backend/app/core/db.py | 46 +++++++ {src => backend}/app/core/events.py | 1 + {src => backend}/app/crud/__init__.py | 0 {src => backend}/app/crud/base.py | 0 {src => backend}/app/crud/crud_item.py | 0 {src => backend}/app/main.py | 0 backend/app/models/__init__.py | 9 ++ backend/app/models/item.py | 39 ++++++ backend/app/models/user.py | 13 ++ {src => backend}/app/schemas/__init__.py | 0 {src => backend}/app/schemas/auth.py | 0 {src => backend}/app/schemas/base.py | 0 {src => backend}/app/schemas/item.py | 0 {src => backend}/app/schemas/msg.py | 0 .../core => backend/app/services}/__init__.py | 0 {tests => backend/app/tests}/.env | 0 .../app/tests}/__init__.py | 0 .../app/tests/api}/__init__.py | 0 .../app/tests/api/api_v1}/__init__.py | 0 backend/app/tests/api/api_v1/test_items.py | 115 ++++++++++++++++++ {tests => backend/app/tests}/conftest.py | 63 ++++------ .../app/tests/crud}/__init__.py | 0 backend/app/tests/crud/test_item.py | 50 ++++++++ backend/app/tests/pre_start/test_db.py | 16 +++ .../app/tests}/pre_start/test_main.py | 0 {tests => backend/app/tests}/utils.py | 0 .../api_v1 => backend/app/utils}/__init__.py | 0 {supabase => backend/supabase}/.gitignore | 0 {supabase => backend/supabase}/config.toml | 0 tests/api/api_v1/test_items.py | 115 ------------------ tests/crud/__init__.py | 0 tests/crud/test_item.py | 50 -------- 41 files changed, 342 insertions(+), 228 deletions(-) rename {src => backend}/app/__init__.py (100%) rename {src => backend}/app/api/__init__.py (100%) create mode 100644 backend/app/api/deps.py rename src/app/api/api_v1/api.py => backend/app/api/main.py (75%) rename {src/app/api/api_v1 => backend/app/api/routes}/__init__.py (100%) rename {src/app/api/api_v1/endpoints => backend/app/api/routes}/items.py (100%) rename {src/app/api/api_v1/endpoints => backend/app/core}/__init__.py (100%) rename src/app/api/deps.py => backend/app/core/auth.py (53%) rename {src => backend}/app/core/config.py (97%) create mode 100644 backend/app/core/db.py rename {src => backend}/app/core/events.py (90%) rename {src => backend}/app/crud/__init__.py (100%) rename {src => backend}/app/crud/base.py (100%) rename {src => backend}/app/crud/crud_item.py (100%) rename {src => backend}/app/main.py (100%) create mode 100644 backend/app/models/__init__.py create mode 100644 backend/app/models/item.py create mode 100644 backend/app/models/user.py rename {src => backend}/app/schemas/__init__.py (100%) rename {src => backend}/app/schemas/auth.py (100%) rename {src => backend}/app/schemas/base.py (100%) rename {src => backend}/app/schemas/item.py (100%) rename {src => backend}/app/schemas/msg.py (100%) rename {src/app/core => backend/app/services}/__init__.py (100%) rename {tests => backend/app/tests}/.env (100%) rename {src/app/services => backend/app/tests}/__init__.py (100%) rename {src/app/utils => backend/app/tests/api}/__init__.py (100%) rename {tests => backend/app/tests/api/api_v1}/__init__.py (100%) create mode 100644 backend/app/tests/api/api_v1/test_items.py rename {tests => backend/app/tests}/conftest.py (58%) rename {tests/api => backend/app/tests/crud}/__init__.py (100%) create mode 100644 backend/app/tests/crud/test_item.py create mode 100644 backend/app/tests/pre_start/test_db.py rename {tests => backend/app/tests}/pre_start/test_main.py (100%) rename {tests => backend/app/tests}/utils.py (100%) rename {tests/api/api_v1 => backend/app/utils}/__init__.py (100%) rename {supabase => backend/supabase}/.gitignore (100%) rename {supabase => backend/supabase}/config.toml (100%) delete mode 100644 tests/api/api_v1/test_items.py delete mode 100644 tests/crud/__init__.py delete mode 100644 tests/crud/test_item.py diff --git a/src/app/__init__.py b/backend/app/__init__.py similarity index 100% rename from src/app/__init__.py rename to backend/app/__init__.py diff --git a/src/app/api/__init__.py b/backend/app/api/__init__.py similarity index 100% rename from src/app/api/__init__.py rename to backend/app/api/__init__.py diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py new file mode 100644 index 0000000..d7eec92 --- /dev/null +++ b/backend/app/api/deps.py @@ -0,0 +1,13 @@ +from typing import Annotated + +from fastapi import Depends +from sqlmodel import Session + +from app.core.auth import get_current_user +from app.core.db import get_db +from app.schemas.auth import UserIn + +CurrentUser = Annotated[UserIn, Depends(get_current_user)] + + +SessionDep = Annotated[Session, Depends(get_db)] diff --git a/src/app/api/api_v1/api.py b/backend/app/api/main.py similarity index 75% rename from src/app/api/api_v1/api.py rename to backend/app/api/main.py index c464e55..1e9becb 100644 --- a/src/app/api/api_v1/api.py +++ b/backend/app/api/main.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -from app.api.api_v1.endpoints import items +from app.api.routes import items api_router = APIRouter() api_router.include_router(items.router, prefix="/items", tags=["items"]) diff --git a/src/app/api/api_v1/__init__.py b/backend/app/api/routes/__init__.py similarity index 100% rename from src/app/api/api_v1/__init__.py rename to backend/app/api/routes/__init__.py diff --git a/src/app/api/api_v1/endpoints/items.py b/backend/app/api/routes/items.py similarity index 100% rename from src/app/api/api_v1/endpoints/items.py rename to backend/app/api/routes/items.py diff --git a/src/app/api/api_v1/endpoints/__init__.py b/backend/app/core/__init__.py similarity index 100% rename from src/app/api/api_v1/endpoints/__init__.py rename to backend/app/core/__init__.py diff --git a/src/app/api/deps.py b/backend/app/core/auth.py similarity index 53% rename from src/app/api/deps.py rename to backend/app/core/auth.py index 218c773..ab1d440 100644 --- a/src/app/api/deps.py +++ b/backend/app/core/auth.py @@ -1,10 +1,8 @@ import logging -from collections.abc import Generator from typing import Annotated from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer -from sqlmodel import Session, create_engine from app.core.config import settings from app.schemas.auth import UserIn @@ -26,31 +24,18 @@ async def get_super_client() -> AsyncClient: SuperClient = Annotated[AsyncClient, Depends(get_super_client)] -# auto get access_token from header -reusable_oauth2 = OAuth2PasswordBearer(tokenUrl="Token") -AccessTokenDep = Annotated[str, Depends(reusable_oauth2)] +# auto get token from header +reusable_oauth2 = OAuth2PasswordBearer( + tokenUrl=f"{settings.API_V1_STR}/login/access-token" +) +TokenDep = Annotated[str, Depends(reusable_oauth2)] -async def get_current_user( - access_token: AccessTokenDep, super_client: SuperClient -) -> UserIn: - """get current user from access_token and validate same time""" - user_rsp = await super_client.auth.get_user(jwt=access_token) + +async def get_current_user(token: TokenDep, super_client: SuperClient) -> UserIn: + """get current user from token and validate same time""" + user_rsp = await super_client.auth.get_user(jwt=token) if not user_rsp: logging.error("User not found") raise HTTPException(status_code=404, detail="User not found") - return UserIn(**user_rsp.user.model_dump(), access_token=access_token) - - -CurrentUser = Annotated[UserIn, Depends(get_current_user)] - - -engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI)) - - -def get_db() -> Generator[Session, None, None]: - with Session(engine) as session: - yield session - - -SessionDep = Annotated[Session, Depends(get_db)] + return UserIn(**user_rsp.user.model_dump(), access_token=token) diff --git a/src/app/core/config.py b/backend/app/core/config.py similarity index 97% rename from src/app/core/config.py rename to backend/app/core/config.py index 8fbc4cd..921c506 100644 --- a/src/app/core/config.py +++ b/backend/app/core/config.py @@ -82,7 +82,8 @@ def all_cors_origins(self) -> list[str]: @property def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: return MultiHostUrl.build( - scheme="postgresql+psycopg", + # scheme="postgresql+psycopg", + scheme="postgresql+asyncpg", username=self.POSTGRES_USER, password=self.POSTGRES_PASSWORD, host=self.POSTGRES_SERVER, diff --git a/backend/app/core/db.py b/backend/app/core/db.py new file mode 100644 index 0000000..99b49f2 --- /dev/null +++ b/backend/app/core/db.py @@ -0,0 +1,46 @@ +from collections.abc import Generator +from typing import AsyncGenerator + +from sqlalchemy.ext.asyncio import create_async_engine +from sqlmodel import Session, select +from sqlmodel.ext.asyncio.session import AsyncSession + +from app.core.auth import get_super_client +from app.core.config import settings +from app.models import User + +# make sure all SQLModel models are imported (app.models) before initializing DB +# otherwise, SQLModel might fail to initialize relationships properly +# for more details: https://github.com/fastapi/full-stack-fastapi-template/issues/28 + +engine = create_async_engine(str(settings.SQLALCHEMY_DATABASE_URI), echo=True, future=True) + + +async def get_db() -> AsyncGenerator[AsyncSession, None]: + async with AsyncSession(engine) as session: + yield session + + +async def init_db(session: Session) -> None: + # Tables should be created with Alembic migrations + # But if you don't want to use migrations, create + # the tables un-commenting the next lines + # from sqlmodel import SQLModel + # # This works because the models are already imported and registered from app.models + # SQLModel.metadata.create_all(engine) + + user = session.exec( + select(User).where(User.email == settings.FIRST_SUPERUSER) + ).first() + + if not user: + super_client = await get_super_client() + response = await super_client.auth.sign_up( + { + "email": settings.FIRST_SUPERUSER, + "password": settings.FIRST_SUPERUSER_PASSWORD, + } + ) + assert response.user.email == settings.FIRST_SUPERUSER + assert response.user.id is not None + assert response.session.access_token is not None diff --git a/src/app/core/events.py b/backend/app/core/events.py similarity index 90% rename from src/app/core/events.py rename to backend/app/core/events.py index b6c27e8..4f2c1d6 100644 --- a/src/app/core/events.py +++ b/backend/app/core/events.py @@ -13,6 +13,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 """life span events""" try: + logging.info("lifespan start") yield finally: logging.info("lifespan shutdown") diff --git a/src/app/crud/__init__.py b/backend/app/crud/__init__.py similarity index 100% rename from src/app/crud/__init__.py rename to backend/app/crud/__init__.py diff --git a/src/app/crud/base.py b/backend/app/crud/base.py similarity index 100% rename from src/app/crud/base.py rename to backend/app/crud/base.py diff --git a/src/app/crud/crud_item.py b/backend/app/crud/crud_item.py similarity index 100% rename from src/app/crud/crud_item.py rename to backend/app/crud/crud_item.py diff --git a/src/app/main.py b/backend/app/main.py similarity index 100% rename from src/app/main.py rename to backend/app/main.py diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py new file mode 100644 index 0000000..10a1377 --- /dev/null +++ b/backend/app/models/__init__.py @@ -0,0 +1,9 @@ +from .item import Item +from .user import User +from sqlmodel import SQLModel +__all__ = ["User", "Item", "Message"] + + +# Generic message +class Message(SQLModel): + message: str diff --git a/backend/app/models/item.py b/backend/app/models/item.py new file mode 100644 index 0000000..aad2678 --- /dev/null +++ b/backend/app/models/item.py @@ -0,0 +1,39 @@ +import uuid + +from sqlmodel import Field, SQLModel + + +# Shared properties +class ItemBase(SQLModel): + title: str = Field(min_length=1, max_length=255) + description: str | None = Field(default=None, max_length=255) + + +# Properties to receive on item creation +class ItemCreate(ItemBase): + pass + + +# Properties to receive on item update +class ItemUpdate(ItemBase): + title: str | None = Field(default=None, min_length=1, max_length=255) # type: ignore + + +# Database model, database table inferred from class name +class Item(ItemBase, table=True): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + title: str = Field(max_length=255) + owner_id: uuid.UUID = Field( + foreign_key="user.id", nullable=False, ondelete="CASCADE" + ) + + +# Properties to return via API, id is always required +class ItemPublic(ItemBase): + id: uuid.UUID + owner_id: uuid.UUID + + +class ItemsPublic(SQLModel): + data: list[ItemPublic] + count: int diff --git a/backend/app/models/user.py b/backend/app/models/user.py new file mode 100644 index 0000000..a46259e --- /dev/null +++ b/backend/app/models/user.py @@ -0,0 +1,13 @@ +import uuid + +from pydantic import EmailStr +from sqlmodel import Field, Relationship, SQLModel + +from app.models import Item + + +class User(SQLModel, table=True): + # __table_args__ = {'extend_existing': True, 'autoload': True} + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + email: EmailStr = Field(max_length=255) + items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True) diff --git a/src/app/schemas/__init__.py b/backend/app/schemas/__init__.py similarity index 100% rename from src/app/schemas/__init__.py rename to backend/app/schemas/__init__.py diff --git a/src/app/schemas/auth.py b/backend/app/schemas/auth.py similarity index 100% rename from src/app/schemas/auth.py rename to backend/app/schemas/auth.py diff --git a/src/app/schemas/base.py b/backend/app/schemas/base.py similarity index 100% rename from src/app/schemas/base.py rename to backend/app/schemas/base.py diff --git a/src/app/schemas/item.py b/backend/app/schemas/item.py similarity index 100% rename from src/app/schemas/item.py rename to backend/app/schemas/item.py diff --git a/src/app/schemas/msg.py b/backend/app/schemas/msg.py similarity index 100% rename from src/app/schemas/msg.py rename to backend/app/schemas/msg.py diff --git a/src/app/core/__init__.py b/backend/app/services/__init__.py similarity index 100% rename from src/app/core/__init__.py rename to backend/app/services/__init__.py diff --git a/tests/.env b/backend/app/tests/.env similarity index 100% rename from tests/.env rename to backend/app/tests/.env diff --git a/src/app/services/__init__.py b/backend/app/tests/__init__.py similarity index 100% rename from src/app/services/__init__.py rename to backend/app/tests/__init__.py diff --git a/src/app/utils/__init__.py b/backend/app/tests/api/__init__.py similarity index 100% rename from src/app/utils/__init__.py rename to backend/app/tests/api/__init__.py diff --git a/tests/__init__.py b/backend/app/tests/api/api_v1/__init__.py similarity index 100% rename from tests/__init__.py rename to backend/app/tests/api/api_v1/__init__.py diff --git a/backend/app/tests/api/api_v1/test_items.py b/backend/app/tests/api/api_v1/test_items.py new file mode 100644 index 0000000..5d6b391 --- /dev/null +++ b/backend/app/tests/api/api_v1/test_items.py @@ -0,0 +1,115 @@ +# # Additional assertions based on your application's logic +# import pytest +# from app.schemas import Token +# from faker import Faker +# from starlette.testclient import TestClient + +# from supabase._async.client import AsyncClient +# from tests.utils import get_auth_header + + +# @pytest.mark.anyio +# async def test_create_item(client: TestClient, token: Token) -> None: + +# headers = get_auth_header(token.access_token) + +# test_data = Faker().sentence() + + +# response = client.post( +# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} +# ) +# assert response.status_code == 200 +# assert response.json()["test_data"] == test_data + + +# @pytest.mark.anyio +# async def test_read_all_items(client: TestClient, token: Token) -> None: +# headers = get_auth_header(token.access_token) + +# response = client.get("/api/v1/items/read-all-item", headers=headers) +# assert response.status_code == 200 +# assert isinstance(response.json(), list) + + +# @pytest.mark.anyio +# async def test_read_item_by_id(client: TestClient, token: Token) -> None: +# headers = get_auth_header(token.access_token) +# test_data = Faker().sentence() + + +# create_response = client.post( +# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} +# ) +# assert create_response.status_code == 200 +# created_item_id = create_response.json()["id"] + + +# read_response = client.get( +# f"/api/v1/items/get-by-id/{created_item_id}", headers=headers +# ) +# assert read_response.status_code == 200 +# assert read_response.json()["id"] == created_item_id +# assert read_response.json()["test_data"] == test_data + + +# @pytest.mark.anyio +# async def test_read_item_by_owner( +# client: TestClient, token: Token, db: AsyncClient +# ) -> None: +# headers = get_auth_header(token.access_token) +# test_data = Faker().sentence() + +# client.post( +# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} +# ) + +# user = await db.auth.get_user(jwt=token.access_token) +# user_id = user.user.id + +# read_response = client.get("/api/v1/items/get-by-owner", headers=headers) +# assert read_response.status_code == 200 +# items = read_response.json() +# assert isinstance(items, list) +# assert all(item["user_id"] == user_id for item in items) + + +# @pytest.mark.anyio +# async def test_update_item(client: TestClient, token: Token) -> None: +# headers = get_auth_header(token.access_token) +# test_data = Faker().sentence() +# create_response = client.post( +# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} +# ) +# assert create_response.status_code == 200 +# created_item = create_response.json() +# created_item_id = created_item["id"] +# updated_data = {"test_data": Faker().sentence(), "id": created_item_id} + +# update_response = client.put( +# "/api/v1/items/update-item", headers=headers, json=updated_data +# ) +# assert update_response.status_code == 200 +# assert update_response.json()["test_data"] == updated_data["test_data"] + + +# @pytest.mark.anyio +# async def test_delete_item(client: TestClient, token: Token) -> None: +# headers = get_auth_header(token.access_token) +# test_data = Faker().sentence() +# create_response = client.post( +# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} +# ) +# assert create_response.status_code == 200 +# created_item_id = create_response.json()["id"] + +# delete_response = client.delete( +# f"/api/v1/items/delete/{created_item_id}", headers=headers +# ) +# assert delete_response.status_code == 200 + +# get_response = client.get( +# f"/api/v1/items/get-by-id/{created_item_id}", headers=headers +# ) +# assert get_response.status_code == 200 +# assert get_response.json() is None diff --git a/tests/conftest.py b/backend/app/tests/conftest.py similarity index 58% rename from tests/conftest.py rename to backend/app/tests/conftest.py index 7c01e94..ab9e7c9 100644 --- a/tests/conftest.py +++ b/backend/app/tests/conftest.py @@ -5,15 +5,13 @@ from pathlib import Path import pytest -from app.main import app -from app.schemas import Token -from dotenv import load_dotenv from faker import Faker from fastapi.testclient import TestClient -from pydantic import ConfigDict +from sqlmodel import Session -from supabase._async.client import AsyncClient, create_client -from tests.utils import get_auth_header +from app.main import app +from app.schemas import Token +from supabase._async.client import create_client LOG_FILE = Path(__file__).parent / "scripts.log" @@ -48,8 +46,10 @@ def anyio_backend() -> str: return "asyncio" -def pytest_configure(config: ConfigDict) -> None: # noqa ARG001 - load_dotenv() +@pytest.fixture(scope="session", autouse=True) +def db() -> Generator[Session, None, None]: + with Session(engine) as session: + yield session @pytest.fixture(scope="module") @@ -70,37 +70,28 @@ async def token() -> AsyncGenerator[Token, None]: response = await db_client.auth.sign_up( {"email": fake_email, "password": fake_password} ) + assert response.user assert response.user.email == fake_email assert response.user.id is not None - assert response.session.access_token is not None yield Token(access_token=response.session.access_token) -@pytest.fixture(scope="module") -async def db() -> AsyncGenerator[AsyncClient, None]: - url = os.environ.get("SUPABASE_TEST_URL") - assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" - key = os.environ.get("SUPABASE_TEST_KEY") - assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" - db_client = await create_client(url, key) - # await db_client.auth.sign_in_with_password( - # {"email": "zhouge1831@gmail.com", "password": "Zz030327#"} - # ) - # get_session = await db_client.auth.get_session() - # assert get_session.user is not None - # logging.info("db_client.get_session", get_session.user.model_dump()) - try: - yield db_client - finally: - if db_client: - await db_client.auth.sign_out() - - -@pytest.mark.anyio -async def test_read_all_items(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) - - response = client.get("/api/v1/items/read-all-item", headers=headers) - assert response.status_code == 200 - assert isinstance(response.json(), list) +# @pytest.fixture(scope="module") +# async def db() -> AsyncGenerator[AsyncClient, None]: +# url = os.environ.get("SUPABASE_TEST_URL") +# assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" +# key = os.environ.get("SUPABASE_TEST_KEY") +# assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" +# db_client = await create_client(url, key) +# # await db_client.auth.sign_in_with_password( +# # {"email": "zhouge1831@gmail.com", "password": "Zz030327#"} +# # ) +# # get_session = await db_client.auth.get_session() +# # assert get_session.user is not None +# # logging.info("db_client.get_session", get_session.user.model_dump()) +# try: +# yield db_client +# finally: +# if db_client: +# await db_client.auth.sign_out() diff --git a/tests/api/__init__.py b/backend/app/tests/crud/__init__.py similarity index 100% rename from tests/api/__init__.py rename to backend/app/tests/crud/__init__.py diff --git a/backend/app/tests/crud/test_item.py b/backend/app/tests/crud/test_item.py new file mode 100644 index 0000000..45173d3 --- /dev/null +++ b/backend/app/tests/crud/test_item.py @@ -0,0 +1,50 @@ +# import pytest +# from app import crud +# from app.schemas.item import Item, ItemCreate, ItemUpdate +# from faker import Faker +# from supabase._async.client import AsyncClient + + +# @pytest.mark.anyio +# async def test_create_item(db: AsyncClient) -> None: +# test_data = Faker().text() +# item_in = ItemCreate(test_data=test_data) +# item: Item = await crud.item.create(db=db, obj_in=item_in) +# assert item.test_data == test_data + + +# @pytest.mark.anyio +# async def test_get_item(db: AsyncClient) -> None: +# test_data = Faker().text() +# item_in = ItemCreate(table_name="test_table", test_data=test_data) +# item: Item = await crud.item.create(db=db, obj_in=item_in) +# stored_item = await crud.item.get(db, id=item.id) +# assert stored_item +# assert item.id == stored_item.id +# assert item.test_data == stored_item.test_data + + +# @pytest.mark.anyio +# async def test_update_item(db: AsyncClient) -> None: +# test_data = Faker().text() +# item_in = ItemCreate(table_name="test_table", test_data=test_data) +# item: Item = await crud.item.create(db=db, obj_in=item_in) +# test_data2 = Faker().text() +# item_update = ItemUpdate(table_name="test_table", id=item.id, test_data=test_data2) +# item2 = await crud.item.update(db=db, obj_in=item_update) +# assert item.id == item2.id +# assert item.test_data != item2.test_data +# assert item2.test_data == test_data2 + + +# @pytest.mark.anyio +# async def test_delete_item(db: AsyncClient) -> None: +# test_data = Faker().text() +# item_in = ItemCreate(table_name="test_table", test_data=test_data) +# item: Item = await crud.item.create(db=db, obj_in=item_in) +# item2 = await crud.item.delete(db=db, id=item.id) +# item3 = await crud.item.get(db, id=item.id) +# assert item3 is None +# assert item.id == item2.id +# assert item.test_data == item2.test_data +# assert item2.test_data == test_data diff --git a/backend/app/tests/pre_start/test_db.py b/backend/app/tests/pre_start/test_db.py new file mode 100644 index 0000000..b1be969 --- /dev/null +++ b/backend/app/tests/pre_start/test_db.py @@ -0,0 +1,16 @@ +import logging + +import pytest +from sqlmodel import Session + +from src.app.api.deps import engine +from src.app.core.db import init_db + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +@pytest.mark.anyio +async def test_init_db() -> None: + with Session(engine) as session: + await init_db(session) diff --git a/tests/pre_start/test_main.py b/backend/app/tests/pre_start/test_main.py similarity index 100% rename from tests/pre_start/test_main.py rename to backend/app/tests/pre_start/test_main.py diff --git a/tests/utils.py b/backend/app/tests/utils.py similarity index 100% rename from tests/utils.py rename to backend/app/tests/utils.py diff --git a/tests/api/api_v1/__init__.py b/backend/app/utils/__init__.py similarity index 100% rename from tests/api/api_v1/__init__.py rename to backend/app/utils/__init__.py diff --git a/supabase/.gitignore b/backend/supabase/.gitignore similarity index 100% rename from supabase/.gitignore rename to backend/supabase/.gitignore diff --git a/supabase/config.toml b/backend/supabase/config.toml similarity index 100% rename from supabase/config.toml rename to backend/supabase/config.toml diff --git a/tests/api/api_v1/test_items.py b/tests/api/api_v1/test_items.py deleted file mode 100644 index 774d8e0..0000000 --- a/tests/api/api_v1/test_items.py +++ /dev/null @@ -1,115 +0,0 @@ -# Additional assertions based on your application's logic -import pytest -from app.schemas import Token -from faker import Faker -from starlette.testclient import TestClient - -from supabase._async.client import AsyncClient -from tests.utils import get_auth_header - - -@pytest.mark.anyio -async def test_create_item(client: TestClient, token: Token) -> None: - - headers = get_auth_header(token.access_token) - - test_data = Faker().sentence() - - - response = client.post( - "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} - ) - assert response.status_code == 200 - assert response.json()["test_data"] == test_data - - -@pytest.mark.anyio -async def test_read_all_items(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) - - response = client.get("/api/v1/items/read-all-item", headers=headers) - assert response.status_code == 200 - assert isinstance(response.json(), list) - - -@pytest.mark.anyio -async def test_read_item_by_id(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) - test_data = Faker().sentence() - - - create_response = client.post( - "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} - ) - assert create_response.status_code == 200 - created_item_id = create_response.json()["id"] - - - read_response = client.get( - f"/api/v1/items/get-by-id/{created_item_id}", headers=headers - ) - assert read_response.status_code == 200 - assert read_response.json()["id"] == created_item_id - assert read_response.json()["test_data"] == test_data - - -@pytest.mark.anyio -async def test_read_item_by_owner( - client: TestClient, token: Token, db: AsyncClient -) -> None: - headers = get_auth_header(token.access_token) - test_data = Faker().sentence() - - client.post( - "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} - ) - - user = await db.auth.get_user(jwt=token.access_token) - user_id = user.user.id - - read_response = client.get("/api/v1/items/get-by-owner", headers=headers) - assert read_response.status_code == 200 - items = read_response.json() - assert isinstance(items, list) - assert all(item["user_id"] == user_id for item in items) - - -@pytest.mark.anyio -async def test_update_item(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) - test_data = Faker().sentence() - create_response = client.post( - "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} - ) - assert create_response.status_code == 200 - created_item = create_response.json() - created_item_id = created_item["id"] - updated_data = {"test_data": Faker().sentence(), "id": created_item_id} - - update_response = client.put( - "/api/v1/items/update-item", headers=headers, json=updated_data - ) - assert update_response.status_code == 200 - assert update_response.json()["test_data"] == updated_data["test_data"] - - -@pytest.mark.anyio -async def test_delete_item(client: TestClient, token: Token) -> None: - headers = get_auth_header(token.access_token) - test_data = Faker().sentence() - create_response = client.post( - "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} - ) - assert create_response.status_code == 200 - created_item_id = create_response.json()["id"] - - delete_response = client.delete( - f"/api/v1/items/delete/{created_item_id}", headers=headers - ) - assert delete_response.status_code == 200 - - get_response = client.get( - f"/api/v1/items/get-by-id/{created_item_id}", headers=headers - ) - assert get_response.status_code == 200 - assert get_response.json() is None diff --git a/tests/crud/__init__.py b/tests/crud/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/crud/test_item.py b/tests/crud/test_item.py deleted file mode 100644 index 0f1ef0d..0000000 --- a/tests/crud/test_item.py +++ /dev/null @@ -1,50 +0,0 @@ -import pytest -from app import crud -from app.schemas.item import Item, ItemCreate, ItemUpdate -from faker import Faker -from supabase._async.client import AsyncClient - - -@pytest.mark.anyio -async def test_create_item(db: AsyncClient) -> None: - test_data = Faker().text() - item_in = ItemCreate(test_data=test_data) - item: Item = await crud.item.create(db=db, obj_in=item_in) - assert item.test_data == test_data - - -@pytest.mark.anyio -async def test_get_item(db: AsyncClient) -> None: - test_data = Faker().text() - item_in = ItemCreate(table_name="test_table", test_data=test_data) - item: Item = await crud.item.create(db=db, obj_in=item_in) - stored_item = await crud.item.get(db, id=item.id) - assert stored_item - assert item.id == stored_item.id - assert item.test_data == stored_item.test_data - - -@pytest.mark.anyio -async def test_update_item(db: AsyncClient) -> None: - test_data = Faker().text() - item_in = ItemCreate(table_name="test_table", test_data=test_data) - item: Item = await crud.item.create(db=db, obj_in=item_in) - test_data2 = Faker().text() - item_update = ItemUpdate(table_name="test_table", id=item.id, test_data=test_data2) - item2 = await crud.item.update(db=db, obj_in=item_update) - assert item.id == item2.id - assert item.test_data != item2.test_data - assert item2.test_data == test_data2 - - -@pytest.mark.anyio -async def test_delete_item(db: AsyncClient) -> None: - test_data = Faker().text() - item_in = ItemCreate(table_name="test_table", test_data=test_data) - item: Item = await crud.item.create(db=db, obj_in=item_in) - item2 = await crud.item.delete(db=db, id=item.id) - item3 = await crud.item.get(db, id=item.id) - assert item3 is None - assert item.id == item2.id - assert item.test_data == item2.test_data - assert item2.test_data == test_data From 8559a4e391079f08af53a36d1b0f1289bb3cc64d Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 13:45:19 +0800 Subject: [PATCH 23/65] chore: add deps --- pyproject.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index a1258ad..c0ec935 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,9 @@ dependencies = [ "python-multipart>=0.0.9", "supabase>=2.7.4", "fastapi>=0.112.2", + "sqlmodel>=0.0.22", + "asyncpg>=0.30.0", + "alembic>=1.14.0", ] [dependency-groups] @@ -73,7 +76,7 @@ exclude_lines = [ '\(Protocol\)=$', 'typing.assert_never', 'assert_never', - 'if __name__ == .__main__.=', + 'if __name__ == "__main__":', ] From a5543ea11c04a79e5d71be4409230f9256b096cf Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 13:47:30 +0800 Subject: [PATCH 24/65] chore(git): remove .vscode --- .gitignore | 3 + .vscode/PythonImportHelper-v2-Completion.json | 1190 ----------------- .vscode/extensions.json | 3 - .vscode/settings.json | 30 - 4 files changed, 3 insertions(+), 1223 deletions(-) delete mode 100644 .vscode/PythonImportHelper-v2-Completion.json delete mode 100644 .vscode/extensions.json delete mode 100644 .vscode/settings.json diff --git a/.gitignore b/.gitignore index 85919c7..c0dc42e 100644 --- a/.gitignore +++ b/.gitignore @@ -161,3 +161,6 @@ cython_debug/ # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. .idea/ + +# VSCode +.vscode/ diff --git a/.vscode/PythonImportHelper-v2-Completion.json b/.vscode/PythonImportHelper-v2-Completion.json deleted file mode 100644 index d8746e8..0000000 --- a/.vscode/PythonImportHelper-v2-Completion.json +++ /dev/null @@ -1,1190 +0,0 @@ -[ - { - "label": "runpy", - "kind": 6, - "isExtraImport": true, - "importPath": "runpy", - "description": "runpy", - "detail": "runpy", - "documentation": {} - }, - { - "label": "annotations", - "importPath": "__future__", - "description": "__future__", - "isExtraImport": true, - "detail": "__future__", - "documentation": {} - }, - { - "label": "os", - "kind": 6, - "isExtraImport": true, - "importPath": "os", - "description": "os", - "detail": "os", - "documentation": {} - }, - { - "label": "site", - "kind": 6, - "isExtraImport": true, - "importPath": "site", - "description": "site", - "detail": "site", - "documentation": {} - }, - { - "label": "sys", - "kind": 6, - "isExtraImport": true, - "importPath": "sys", - "description": "sys", - "detail": "sys", - "documentation": {} - }, - { - "label": "APIRouter", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "Depends", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "HTTPException", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "APIRouter", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "FastAPI", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "FastAPI", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "HTTPException", - "importPath": "fastapi", - "description": "fastapi", - "isExtraImport": true, - "detail": "fastapi", - "documentation": {} - }, - { - "label": "CurrentUser", - "importPath": "app.api.deps", - "description": "app.api.deps", - "isExtraImport": true, - "detail": "app.api.deps", - "documentation": {} - }, - { - "label": "SessionDep", - "importPath": "app.api.deps", - "description": "app.api.deps", - "isExtraImport": true, - "detail": "app.api.deps", - "documentation": {} - }, - { - "label": "init_super_client", - "importPath": "app.api.deps", - "description": "app.api.deps", - "isExtraImport": true, - "detail": "app.api.deps", - "documentation": {} - }, - { - "label": "item", - "importPath": "app.crud", - "description": "app.crud", - "isExtraImport": true, - "detail": "app.crud", - "documentation": {} - }, - { - "label": "Item", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "ItemCreate", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "ItemUpdate", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "Item", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "ItemCreate", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "ItemUpdate", - "importPath": "app.schemas", - "description": "app.schemas", - "isExtraImport": true, - "detail": "app.schemas", - "documentation": {} - }, - { - "label": "logging", - "kind": 6, - "isExtraImport": true, - "importPath": "logging", - "description": "logging", - "detail": "logging", - "documentation": {} - }, - { - "label": "AsyncGenerator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "AsyncGenerator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "AsyncGenerator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "Generator", - "importPath": "collections.abc", - "description": "collections.abc", - "isExtraImport": true, - "detail": "collections.abc", - "documentation": {} - }, - { - "label": "Annotated", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "Annotated", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "Any", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "Literal", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "Self", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "Generic", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "TypeVar", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "ClassVar", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "ClassVar", - "importPath": "typing", - "description": "typing", - "isExtraImport": true, - "detail": "typing", - "documentation": {} - }, - { - "label": "OAuth2PasswordBearer", - "importPath": "fastapi.security", - "description": "fastapi.security", - "isExtraImport": true, - "detail": "fastapi.security", - "documentation": {} - }, - { - "label": "AuthApiError", - "importPath": "gotrue.errors", - "description": "gotrue.errors", - "isExtraImport": true, - "detail": "gotrue.errors", - "documentation": {} - }, - { - "label": "settings", - "importPath": "app.core.config", - "description": "app.core.config", - "isExtraImport": true, - "detail": "app.core.config", - "documentation": {} - }, - { - "label": "settings", - "importPath": "app.core.config", - "description": "app.core.config", - "isExtraImport": true, - "detail": "app.core.config", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, - { - "label": "UserIn", - "importPath": "app.schemas.auth", - "description": "app.schemas.auth", - "isExtraImport": true, - "detail": "app.schemas.auth", - "documentation": {} - }, - { - "label": "AsyncClient", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "create_client", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "AsyncClient", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "AsyncClient", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "AsyncClient", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "create_client", - "importPath": "supabase._async.client", - "description": "supabase._async.client", - "isExtraImport": true, - "detail": "supabase._async.client", - "documentation": {} - }, - { - "label": "ClientOptions", - "importPath": "supabase.lib.client_options", - "description": "supabase.lib.client_options", - "isExtraImport": true, - "detail": "supabase.lib.client_options", - "documentation": {} - }, - { - "label": "items", - "importPath": "app.api.routes", - "description": "app.api.routes", - "isExtraImport": true, - "detail": "app.api.routes", - "documentation": {} - }, - { - "label": "secrets", - "kind": 6, - "isExtraImport": true, - "importPath": "secrets", - "description": "secrets", - "detail": "secrets", - "documentation": {} - }, - { - "label": "warnings", - "kind": 6, - "isExtraImport": true, - "importPath": "warnings", - "description": "warnings", - "detail": "warnings", - "documentation": {} - }, - { - "label": "AnyUrl", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "BeforeValidator", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "PostgresDsn", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "computed_field", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "model_validator", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "BaseModel", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "BaseModel", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "ConfigDict", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "BaseModel", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "ConfigDict", - "importPath": "pydantic", - "description": "pydantic", - "isExtraImport": true, - "detail": "pydantic", - "documentation": {} - }, - { - "label": "MultiHostUrl", - "importPath": "pydantic_core", - "description": "pydantic_core", - "isExtraImport": true, - "detail": "pydantic_core", - "documentation": {} - }, - { - "label": "BaseSettings", - "importPath": "pydantic_settings", - "description": "pydantic_settings", - "isExtraImport": true, - "detail": "pydantic_settings", - "documentation": {} - }, - { - "label": "SettingsConfigDict", - "importPath": "pydantic_settings", - "description": "pydantic_settings", - "isExtraImport": true, - "detail": "pydantic_settings", - "documentation": {} - }, - { - "label": "asynccontextmanager", - "importPath": "contextlib", - "description": "contextlib", - "isExtraImport": true, - "detail": "contextlib", - "documentation": {} - }, - { - "label": "CreateBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "ResponseBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "UpdateBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "CreateBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "InDBBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "ResponseBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "UpdateBase", - "importPath": "app.schemas.base", - "description": "app.schemas.base", - "isExtraImport": true, - "detail": "app.schemas.base", - "documentation": {} - }, - { - "label": "CRUDBase", - "importPath": "app.crud.base", - "description": "app.crud.base", - "isExtraImport": true, - "detail": "app.crud.base", - "documentation": {} - }, - { - "label": "User", - "importPath": "gotrue", - "description": "gotrue", - "isExtraImport": true, - "detail": "gotrue", - "documentation": {} - }, - { - "label": "UserAttributes", - "importPath": "gotrue", - "description": "gotrue", - "isExtraImport": true, - "detail": "gotrue", - "documentation": {} - }, - { - "label": "uvicorn", - "kind": 6, - "isExtraImport": true, - "importPath": "uvicorn", - "description": "uvicorn", - "detail": "uvicorn", - "documentation": {} - }, - { - "label": "CORSMiddleware", - "importPath": "fastapi.middleware.cors", - "description": "fastapi.middleware.cors", - "isExtraImport": true, - "detail": "fastapi.middleware.cors", - "documentation": {} - }, - { - "label": "api_router", - "importPath": "app.api.main", - "description": "app.api.main", - "isExtraImport": true, - "detail": "app.api.main", - "documentation": {} - }, - { - "label": "lifespan", - "importPath": "app.core.events", - "description": "app.core.events", - "isExtraImport": true, - "detail": "app.core.events", - "documentation": {} - }, - { - "label": "pytest", - "kind": 6, - "isExtraImport": true, - "importPath": "pytest", - "description": "pytest", - "detail": "pytest", - "documentation": {} - }, - { - "label": "TestClient", - "importPath": "fastapi.testclient", - "description": "fastapi.testclient", - "isExtraImport": true, - "detail": "fastapi.testclient", - "documentation": {} - }, - { - "label": "TestClient", - "importPath": "fastapi.testclient", - "description": "fastapi.testclient", - "isExtraImport": true, - "detail": "fastapi.testclient", - "documentation": {} - }, - { - "label": "RotatingFileHandler", - "importPath": "logging.handlers", - "description": "logging.handlers", - "isExtraImport": true, - "detail": "logging.handlers", - "documentation": {} - }, - { - "label": "Path", - "importPath": "pathlib", - "description": "pathlib", - "isExtraImport": true, - "detail": "pathlib", - "documentation": {} - }, - { - "label": "load_dotenv", - "importPath": "dotenv", - "description": "dotenv", - "isExtraImport": true, - "detail": "dotenv", - "documentation": {} - }, - { - "label": "Faker", - "importPath": "faker", - "description": "faker", - "isExtraImport": true, - "detail": "faker", - "documentation": {} - }, - { - "label": "app", - "importPath": "src.app.main", - "description": "src.app.main", - "isExtraImport": true, - "detail": "src.app.main", - "documentation": {} - }, - { - "label": "Token", - "importPath": "src.app.schemas", - "description": "src.app.schemas", - "isExtraImport": true, - "detail": "src.app.schemas", - "documentation": {} - }, - { - "label": "bin_dir", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "bin_dir = os.path.dirname(abs_file)\nbase = bin_dir[: -len(\"bin\") - 1] # strip away the bin part from the __file__, plus the path separator\n# prepend bin to PATH (this file is inside the bin directory)\nos.environ[\"PATH\"] = os.pathsep.join([bin_dir, *os.environ.get(\"PATH\", \"\").split(os.pathsep)])\nos.environ[\"VIRTUAL_ENV\"] = base # virtual env is right above bin directory\nos.environ[\"VIRTUAL_ENV_PROMPT\"] = \"\" or os.path.basename(base) # noqa: SIM222\n# add the virtual environments libraries to the host python import mechanism\nprev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "base", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "base = bin_dir[: -len(\"bin\") - 1] # strip away the bin part from the __file__, plus the path separator\n# prepend bin to PATH (this file is inside the bin directory)\nos.environ[\"PATH\"] = os.pathsep.join([bin_dir, *os.environ.get(\"PATH\", \"\").split(os.pathsep)])\nos.environ[\"VIRTUAL_ENV\"] = base # virtual env is right above bin directory\nos.environ[\"VIRTUAL_ENV_PROMPT\"] = \"\" or os.path.basename(base) # noqa: SIM222\n# add the virtual environments libraries to the host python import mechanism\nprev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))\n site.addsitedir(path)", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "os.environ[\"PATH\"]", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "os.environ[\"PATH\"] = os.pathsep.join([bin_dir, *os.environ.get(\"PATH\", \"\").split(os.pathsep)])\nos.environ[\"VIRTUAL_ENV\"] = base # virtual env is right above bin directory\nos.environ[\"VIRTUAL_ENV_PROMPT\"] = \"\" or os.path.basename(base) # noqa: SIM222\n# add the virtual environments libraries to the host python import mechanism\nprev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))\n site.addsitedir(path)\nsys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]\nsys.real_prefix = sys.prefix", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "os.environ[\"VIRTUAL_ENV\"]", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "os.environ[\"VIRTUAL_ENV\"] = base # virtual env is right above bin directory\nos.environ[\"VIRTUAL_ENV_PROMPT\"] = \"\" or os.path.basename(base) # noqa: SIM222\n# add the virtual environments libraries to the host python import mechanism\nprev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))\n site.addsitedir(path)\nsys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]\nsys.real_prefix = sys.prefix\nsys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "os.environ[\"VIRTUAL_ENV_PROMPT\"]", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "os.environ[\"VIRTUAL_ENV_PROMPT\"] = \"\" or os.path.basename(base) # noqa: SIM222\n# add the virtual environments libraries to the host python import mechanism\nprev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))\n site.addsitedir(path)\nsys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]\nsys.real_prefix = sys.prefix\nsys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "prev_length", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "prev_length = len(sys.path)\nfor lib in \"../lib/python3.12/site-packages\".split(os.pathsep):\n path = os.path.realpath(os.path.join(bin_dir, lib))\n site.addsitedir(path)\nsys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]\nsys.real_prefix = sys.prefix\nsys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "sys.path[:]", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "sys.path[:] = sys.path[prev_length:] + sys.path[0:prev_length]\nsys.real_prefix = sys.prefix\nsys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "sys.real_prefix", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "sys.real_prefix = sys.prefix\nsys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "sys.prefix", - "kind": 5, - "importPath": ".venv.bin.activate_this", - "description": ".venv.bin.activate_this", - "peekOfCode": "sys.prefix = base", - "detail": ".venv.bin.activate_this", - "documentation": {} - }, - { - "label": "router", - "kind": 5, - "importPath": "src.app.api.routes.items", - "description": "src.app.api.routes.items", - "peekOfCode": "router = APIRouter()\n@router.post(\"/create-item\")\nasync def create_item(item_in: ItemCreate, session: SessionDep) -> Item:\n return await item.create(session, obj_in=item_in)\n@router.get(\"/read-all-item\")\nasync def read_items(session: SessionDep) -> list[Item]:\n return await item.get_all(session)\n@router.get(\"/get-by-id/{id}\")\nasync def read_item_by_id(id: str, session: SessionDep) -> Item | None:\n return await item.get(session, id=id)", - "detail": "src.app.api.routes.items", - "documentation": {} - }, - { - "label": "reusable_oauth2", - "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", - "peekOfCode": "reusable_oauth2 = OAuth2PasswordBearer(\n tokenUrl=\"please login by supabase-js to get token\"\n)\nAccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:", - "detail": "src.app.api.deps", - "documentation": {} - }, - { - "label": "AccessTokenDep", - "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", - "peekOfCode": "AccessTokenDep = Annotated[str, Depends(reusable_oauth2)]\nasync def get_current_user(access_token: AccessTokenDep) -> UserIn:\n \"\"\"get current user from access_token and validate same time\"\"\"\n if not super_client:\n raise HTTPException(status_code=500, detail=\"Super client not initialized\")\n user_rsp = await super_client.auth.get_user(jwt=access_token)\n if not user_rsp:\n logging.error(\"User not found\")\n raise HTTPException(status_code=404, detail=\"User not found\")\n return UserIn(**user_rsp.user.model_dump(), access_token=access_token)", - "detail": "src.app.api.deps", - "documentation": {} - }, - { - "label": "CurrentUser", - "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", - "peekOfCode": "CurrentUser = Annotated[UserIn, Depends(get_current_user)]\nasync def get_db(user: CurrentUser) -> AsyncGenerator[AsyncClient, None]:\n client: AsyncClient | None = None\n try:\n client = await create_client(\n settings.SUPABASE_URL,\n settings.SUPABASE_KEY,\n options=ClientOptions(\n postgrest_client_timeout=30,\n storage_client_timeout=30,", - "detail": "src.app.api.deps", - "documentation": {} - }, - { - "label": "SessionDep", - "kind": 5, - "importPath": "src.app.api.deps", - "description": "src.app.api.deps", - "peekOfCode": "SessionDep = Annotated[AsyncClient, Depends(get_db)]", - "detail": "src.app.api.deps", - "documentation": {} - }, - { - "label": "api_router", - "kind": 5, - "importPath": "src.app.api.main", - "description": "src.app.api.main", - "peekOfCode": "api_router = APIRouter()\napi_router.include_router(items.router, prefix=\"/items\", tags=[\"items\"])", - "detail": "src.app.api.main", - "documentation": {} - }, - { - "label": "Settings", - "kind": 6, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "class Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support\n model_config = SettingsConfigDict(\n # Use top level .env file (one level above ./backend/)\n env_file=\"../.env\",\n env_ignore_empty=True,\n extra=\"ignore\",\n )\n API_V1_STR: str = \"/api/v1\"", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "parse_cors", - "kind": 2, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "def parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)\nclass Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support\n model_config = SettingsConfigDict(", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "log_format", - "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "log_format = logging.Formatter(\"%(asctime)s : %(levelname)s - %(message)s\")\n# root logger\nroot_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "root_logger", - "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "root_logger = logging.getLogger()\nroot_logger.setLevel(logging.INFO)\n# standard stream handler\nstream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "stream_handler", - "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "stream_handler = logging.StreamHandler()\nstream_handler.setFormatter(log_format)\nroot_logger.addHandler(stream_handler)\nlogger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "logger", - "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "logger = logging.getLogger(__name__)\ndef parse_cors(v: Any) -> list[str] | str:\n if isinstance(v, str) and not v.startswith(\"[\"):\n return [i.strip() for i in v.split(\",\")]\n elif isinstance(v, list | str):\n return v\n raise ValueError(v)\nclass Settings(BaseSettings):\n \"\"\"auto load config from .env and validate settings\"\"\"\n # https://docs.pydantic.dev/latest/concepts/pydantic_settings/#dotenv-env-support", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "settings", - "kind": 5, - "importPath": "src.app.core.config", - "description": "src.app.core.config", - "peekOfCode": "settings = Settings() # type: ignore[call-arg] # load args from env", - "detail": "src.app.core.config", - "documentation": {} - }, - { - "label": "CRUDBase", - "kind": 6, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", - "peekOfCode": "class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data\n return self.model(**got[0]) if got else None", - "detail": "src.app.crud.base", - "documentation": {} - }, - { - "label": "ModelType", - "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", - "peekOfCode": "ModelType = TypeVar(\"ModelType\", bound=ResponseBase)\nCreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()", - "detail": "src.app.crud.base", - "documentation": {} - }, - { - "label": "CreateSchemaType", - "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", - "peekOfCode": "CreateSchemaType = TypeVar(\"CreateSchemaType\", bound=CreateBase)\nUpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )", - "detail": "src.app.crud.base", - "documentation": {} - }, - { - "label": "UpdateSchemaType", - "kind": 5, - "importPath": "src.app.crud.base", - "description": "src.app.crud.base", - "peekOfCode": "UpdateSchemaType = TypeVar(\"UpdateSchemaType\", bound=UpdateBase)\nclass CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):\n def __init__(self, model: type[ModelType]):\n self.model = model\n async def get(self, db: AsyncClient, *, id: str) -> ModelType | None:\n \"\"\"get by table_name by id\"\"\"\n data, count = (\n await db.table(self.model.table_name).select(\"*\").eq(\"id\", id).execute()\n )\n _, got = data", - "detail": "src.app.crud.base", - "documentation": {} - }, - { - "label": "CRUDItem", - "kind": 6, - "importPath": "src.app.crud.crud_item", - "description": "src.app.crud.crud_item", - "peekOfCode": "class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]):\n async def create(self, db: AsyncClient, *, obj_in: ItemCreate) -> Item:\n return await super().create(db, obj_in=obj_in)\n async def get(self, db: AsyncClient, *, id: str) -> Item | None:\n return await super().get(db, id=id)\n async def get_all(self, db: AsyncClient) -> list[Item]:\n return await super().get_all(db)\n async def get_multi_by_owner(self, db: AsyncClient, *, user: UserIn) -> list[Item]:\n return await super().get_multi_by_owner(db, user=user)\n async def update(self, db: AsyncClient, *, obj_in: ItemUpdate) -> Item:", - "detail": "src.app.crud.crud_item", - "documentation": {} - }, - { - "label": "item", - "kind": 5, - "importPath": "src.app.crud.crud_item", - "description": "src.app.crud.crud_item", - "peekOfCode": "item = CRUDItem(Item)", - "detail": "src.app.crud.crud_item", - "documentation": {} - }, - { - "label": "Token", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class Token(BaseModel):\n access_token: str | None = None\n refresh_token: str | None = None\n# request\nclass UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserIn", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserIn(Token, User): # type: ignore\n pass\n# Properties to receive via API on creation\n# in\nclass UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserCreate", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserCreate(BaseModel):\n pass\n# Properties to receive via API on update\n# in\nclass UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserUpdate", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserUpdate(UserAttributes): # type: ignore\n pass\n# response\nclass UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserInDBBase", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserInDBBase(BaseModel):\n pass\n# Properties to return to client via api\n# out\nclass UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserOut", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserOut(Token):\n pass\n# Properties properties stored in DB\nclass UserInDB(User): # type: ignore\n pass", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "UserInDB", - "kind": 6, - "importPath": "src.app.schemas.auth", - "description": "src.app.schemas.auth", - "peekOfCode": "class UserInDB(User): # type: ignore\n pass", - "detail": "src.app.schemas.auth", - "documentation": {} - }, - { - "label": "CreateBase", - "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", - "peekOfCode": "class CreateBase(BaseModel):\n # inherent to add more properties for creating\n pass\n# Properties to receive on item update\n# in\nclass UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB", - "detail": "src.app.schemas.base", - "documentation": {} - }, - { - "label": "UpdateBase", - "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", - "peekOfCode": "class UpdateBase(BaseModel):\n # inherent to add more properties for updating\n id: str\n# response\n# Properties shared by models stored in DB\nclass InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client", - "detail": "src.app.schemas.base", - "documentation": {} - }, - { - "label": "InDBBase", - "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", - "peekOfCode": "class InDBBase(BaseModel):\n id: str\n user_id: str\n created_at: str\n# Properties to return to client\n# curd model\n# out\nclass ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()", - "detail": "src.app.schemas.base", - "documentation": {} - }, - { - "label": "ResponseBase", - "kind": 6, - "importPath": "src.app.schemas.base", - "description": "src.app.schemas.base", - "peekOfCode": "class ResponseBase(InDBBase):\n # inherent to add more properties for responding\n table_name: ClassVar[str] = \"ResponseBase\".lower()\n Config: ClassVar[ConfigDict] = ConfigDict(\n extra=\"ignore\", arbitrary_types_allowed=True\n )", - "detail": "src.app.schemas.base", - "documentation": {} - }, - { - "label": "ItemCreate", - "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", - "peekOfCode": "class ItemCreate(CreateBase):\n test_data: str\n# Properties to receive on item update\n# in\nclass ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):", - "detail": "src.app.schemas.item", - "documentation": {} - }, - { - "label": "ItemUpdate", - "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", - "peekOfCode": "class ItemUpdate(UpdateBase):\n test_data: str\n# Properties to return to client\n# curd model\n# out\nclass Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):", - "detail": "src.app.schemas.item", - "documentation": {} - }, - { - "label": "Item", - "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", - "peekOfCode": "class Item(ResponseBase):\n test_data: str\n table_name: ClassVar[str] = \"test_table\"\n# Properties properties stored in DB\nclass ItemInDB(InDBBase):\n test_data: str", - "detail": "src.app.schemas.item", - "documentation": {} - }, - { - "label": "ItemInDB", - "kind": 6, - "importPath": "src.app.schemas.item", - "description": "src.app.schemas.item", - "peekOfCode": "class ItemInDB(InDBBase):\n test_data: str", - "detail": "src.app.schemas.item", - "documentation": {} - }, - { - "label": "Massage", - "kind": 6, - "importPath": "src.app.schemas.msg", - "description": "src.app.schemas.msg", - "peekOfCode": "class Massage(BaseModel):\n msg: str", - "detail": "src.app.schemas.msg", - "documentation": {} - }, - { - "label": "app", - "kind": 5, - "importPath": "src.app.main", - "description": "src.app.main", - "peekOfCode": "app = FastAPI(\n lifespan=lifespan,\n title=settings.PROJECT_NAME,\n openapi_url=f\"{settings.API_V1_STR}/openapi.json\",\n generate_unique_id_function=lambda router: f\"{router.tags[0]}-{router.name}\",\n)\n# Set all CORS enabled origins\nif settings.all_cors_origins:\n app.add_middleware(\n CORSMiddleware,", - "detail": "src.app.main", - "documentation": {} - }, - { - "label": "setup_logging", - "kind": 2, - "importPath": "tests.conftest", - "description": "tests.conftest", - "peekOfCode": "def setup_logging(level: int = logging.INFO) -> None:\n logger = logging.getLogger()\n logger.setLevel(level)\n file_handler = RotatingFileHandler(\n LOG_FILE, maxBytes=1024 * 1024 * 5, backupCount=5\n )\n file_handler.setLevel(level)\n file_formatter = logging.Formatter(\n \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"\n )", - "detail": "tests.conftest", - "documentation": {} - }, - { - "label": "anyio_backend", - "kind": 2, - "importPath": "tests.conftest", - "description": "tests.conftest", - "peekOfCode": "def anyio_backend() -> str:\n return \"asyncio\"\ndef pytest_configure(config: ConfigDict) -> None: # noqa ARG001\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:", - "detail": "tests.conftest", - "documentation": {} - }, - { - "label": "pytest_configure", - "kind": 2, - "importPath": "tests.conftest", - "description": "tests.conftest", - "peekOfCode": "def pytest_configure(config: ConfigDict) -> None: # noqa ARG001\n load_dotenv()\n@pytest.fixture(scope=\"module\")\ndef client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:\n url = os.environ.get(\"SUPABASE_TEST_URL\")\n assert url is not None, \"Must provide SUPABASE_TEST_URL environment variable\"", - "detail": "tests.conftest", - "documentation": {} - }, - { - "label": "client", - "kind": 2, - "importPath": "tests.conftest", - "description": "tests.conftest", - "peekOfCode": "def client() -> Generator[TestClient, None, None]:\n with TestClient(app) as c:\n yield c\n@pytest.fixture(scope=\"module\")\nasync def token() -> AsyncGenerator[Token, None]:\n url = os.environ.get(\"SUPABASE_TEST_URL\")\n assert url is not None, \"Must provide SUPABASE_TEST_URL environment variable\"\n key = os.environ.get(\"SUPABASE_TEST_KEY\")\n assert key is not None, \"Must provide SUPABASE_TEST_KEY environment variable\"\n db_client = await create_client(url, key)", - "detail": "tests.conftest", - "documentation": {} - }, - { - "label": "LOG_FILE", - "kind": 5, - "importPath": "tests.conftest", - "description": "tests.conftest", - "peekOfCode": "LOG_FILE = Path(__file__).parent / \"scripts.log\"\ndef setup_logging(level: int = logging.INFO) -> None:\n logger = logging.getLogger()\n logger.setLevel(level)\n file_handler = RotatingFileHandler(\n LOG_FILE, maxBytes=1024 * 1024 * 5, backupCount=5\n )\n file_handler.setLevel(level)\n file_formatter = logging.Formatter(\n \"%(asctime)s - %(name)s - %(levelname)s - %(message)s\"", - "detail": "tests.conftest", - "documentation": {} - }, - { - "label": "get_auth_header", - "kind": 2, - "importPath": "tests.utils", - "description": "tests.utils", - "peekOfCode": "def get_auth_header(access_token: str | None) -> dict[str, str]:\n if not access_token:\n raise HTTPException(status_code=401, detail=\"No access token\")\n return {\"Authorization\": f\"Bearer {access_token}\"}", - "detail": "tests.utils", - "documentation": {} - } -] \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json deleted file mode 100644 index 74baffc..0000000 --- a/.vscode/extensions.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "recommendations": ["denoland.vscode-deno"] -} diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 57c3f94..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "DockerRun.DisableAutoGenerateConfig": true, - "[typescript]": { - "editor.defaultFormatter": "denoland.vscode-deno" - }, - "deno.enablePaths": [ - "supabase/functions" - ], - "deno.lint": true, - "deno.unstable": [ - "bare-node-builtins", - "byonm", - "sloppy-imports", - "unsafe-proto", - "webgpu", - "broadcast-channel", - "worker-options", - "cron", - "kv", - "ffi", - "fs", - "http", - "net" - ], - "python.testing.pytestArgs": [ - "tests" - ], - "python.testing.pytestEnabled": true, - "python.testing.unittestEnabled": false -} From fbe18bf01cb9d7d1fc9c960a57660a3130ecd4c0 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 15:27:04 +0800 Subject: [PATCH 25/65] feat: add timestamp logging --- backend/app/core/config.py | 15 --------------- backend/app/main.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 17 deletions(-) diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 921c506..1263d85 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -1,4 +1,3 @@ -import logging import secrets import warnings from typing import Annotated, Any, Literal, Self @@ -13,20 +12,6 @@ from pydantic_core import MultiHostUrl from pydantic_settings import BaseSettings, SettingsConfigDict -log_format = logging.Formatter("%(asctime)s : %(levelname)s - %(message)s") - -# root logger -root_logger = logging.getLogger() -root_logger.setLevel(logging.INFO) - -# standard stream handler -stream_handler = logging.StreamHandler() -stream_handler.setFormatter(log_format) -root_logger.addHandler(stream_handler) - -logger = logging.getLogger(__name__) -# TODO: remove logger configs - def parse_cors(v: Any) -> list[str] | str: if isinstance(v, str) and not v.startswith("["): diff --git a/backend/app/main.py b/backend/app/main.py index 7203397..4a79bf9 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -1,10 +1,27 @@ +import logging +from collections.abc import AsyncGenerator +from typing import Any + import uvicorn from fastapi import FastAPI +from fastapi.concurrency import asynccontextmanager from fastapi.middleware.cors import CORSMiddleware +from uvicorn.config import LOGGING_CONFIG from app.api.main import api_router from app.core.config import settings -from app.core.events import lifespan + +logger = logging.getLogger("uvicorn") + +@asynccontextmanager +async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 + """life span events""" + try: + logger.info("lifespan start") + yield + finally: + logger.info("lifespan exit") + # init FastAPI with lifespan app = FastAPI( @@ -27,5 +44,16 @@ # Include the routers app.include_router(api_router, prefix=settings.API_V1_STR) +# Logger +def timestamp_log_config(uvicorn_log_config: dict[str, Any]) -> dict[str, Any]: + """https://github.com/fastapi/fastapi/discussions/7457#discussioncomment-5565969""" + datefmt = '%d-%m-%Y %H:%M:%S' + formatters = uvicorn_log_config['formatters'] + formatters['default']['fmt'] = '%(levelprefix)s [%(asctime)s] %(message)s' + formatters['access']['fmt'] = '%(levelprefix)s [%(asctime)s] %(client_addr)s - "%(request_line)s" %(status_code)s' + formatters['access']['datefmt'] = datefmt + formatters['default']['datefmt'] = datefmt + return uvicorn_log_config + if __name__ == "__main__": - uvicorn.run(app, host="0.0.0.0", port=8000) + uvicorn.run(app, host="0.0.0.0", port=8000,log_config=timestamp_log_config(LOGGING_CONFIG)) From 5fae71b6694c1b840731eaa20f9977def8f08e70 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 15:28:14 +0800 Subject: [PATCH 26/65] chore: move scripts closer to backend/app --- backend/scripts/format.sh | 5 +++++ backend/scripts/lint.sh | 8 ++++++++ {scripts => backend/scripts}/test.sh | 0 scripts/format.sh | 5 ----- scripts/lint.sh | 8 -------- 5 files changed, 13 insertions(+), 13 deletions(-) create mode 100755 backend/scripts/format.sh create mode 100755 backend/scripts/lint.sh rename {scripts => backend/scripts}/test.sh (100%) delete mode 100755 scripts/format.sh delete mode 100755 scripts/lint.sh diff --git a/backend/scripts/format.sh b/backend/scripts/format.sh new file mode 100755 index 0000000..b1eb52e --- /dev/null +++ b/backend/scripts/format.sh @@ -0,0 +1,5 @@ +#!/bin/sh -e +set -x + +ruff check app scripts app/tests --fix +ruff format app scripts app/tests diff --git a/backend/scripts/lint.sh b/backend/scripts/lint.sh new file mode 100755 index 0000000..1be0606 --- /dev/null +++ b/backend/scripts/lint.sh @@ -0,0 +1,8 @@ +#!/usr/bin/env bash + +set -e +set -x + +mypy app # type check +ruff check app # linter +ruff format app --check # formatter diff --git a/scripts/test.sh b/backend/scripts/test.sh similarity index 100% rename from scripts/test.sh rename to backend/scripts/test.sh diff --git a/scripts/format.sh b/scripts/format.sh deleted file mode 100755 index 6ff5f04..0000000 --- a/scripts/format.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh -e -set -x - -ruff check src/app scripts tests --fix -ruff format src/app scripts tests diff --git a/scripts/lint.sh b/scripts/lint.sh deleted file mode 100755 index d141e02..0000000 --- a/scripts/lint.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env bash - -set -e -set -x - -mypy src/app # type check -ruff check src/app # linter -ruff format src/app --check # formatter From d68aff5a0b59d861c59d2c82b0d8e15451b36833 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 15:29:29 +0800 Subject: [PATCH 27/65] feat: add test_pre_start.py for testing connection of db --- backend/app/utils/test_pre_start.py | 40 +++++++++++++++++++++++++++++ backend/scripts/tests-start.sh | 7 +++++ pyproject.toml | 1 + 3 files changed, 48 insertions(+) create mode 100644 backend/app/utils/test_pre_start.py create mode 100755 backend/scripts/tests-start.sh diff --git a/backend/app/utils/test_pre_start.py b/backend/app/utils/test_pre_start.py new file mode 100644 index 0000000..2684669 --- /dev/null +++ b/backend/app/utils/test_pre_start.py @@ -0,0 +1,40 @@ +import asyncio +import logging + +from sqlalchemy.ext.asyncio import AsyncEngine +from sqlmodel import select +from sqlmodel.ext.asyncio.session import AsyncSession +from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed + +from app.core.db import engine + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +max_tries = 60 * 5 # 5 minutes +wait_seconds = 1 + + +@retry( + stop=stop_after_attempt(max_tries), + wait=wait_fixed(wait_seconds), + before=before_log(logger, logging.INFO), + after=after_log(logger, logging.WARN), +) +async def init(db_engine: AsyncEngine) -> None: + try: + async with AsyncSession(db_engine) as session: + await session.exec(select(1)) + except Exception as e: + logger.error(e) + raise e + + +async def main() -> None: + logger.info("Initializing service") + await init(engine) + logger.info("Service finished initializing") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/backend/scripts/tests-start.sh b/backend/scripts/tests-start.sh new file mode 100755 index 0000000..95d4050 --- /dev/null +++ b/backend/scripts/tests-start.sh @@ -0,0 +1,7 @@ +#! /usr/bin/env bash +set -e +set -x + +python -m app.utils.test_pre_start + +# bash scripts/test.sh "$@" diff --git a/pyproject.toml b/pyproject.toml index c0ec935..a7d1ded 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,6 +18,7 @@ dependencies = [ "sqlmodel>=0.0.22", "asyncpg>=0.30.0", "alembic>=1.14.0", + "tenacity>=9.0.0", ] [dependency-groups] From c0a9a563fbd54a4b91e230eb8047389b59469ff0 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sat, 9 Nov 2024 15:35:28 +0800 Subject: [PATCH 28/65] chore: update lockfile --- uv.lock | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/uv.lock b/uv.lock index b504765..9c4bc40 100644 --- a/uv.lock +++ b/uv.lock @@ -103,6 +103,20 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 }, ] +[[package]] +name = "alembic" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mako" }, + { name = "sqlalchemy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/1e/8cb8900ba1b6360431e46fb7a89922916d3a1b017a8908a7c0499cc7e5f6/alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b", size = 1916172 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/06/8b505aea3d77021b18dcbd8133aa1418f1a1e37e432a465b14c46b2c0eaa/alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25", size = 233482 }, +] + [[package]] name = "annotated-types" version = "0.7.0" @@ -136,6 +150,49 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, ] +[[package]] +name = "asyncpg" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143 }, + { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035 }, + { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384 }, + { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526 }, + { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390 }, + { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630 }, + { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760 }, + { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764 }, + { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506 }, + { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922 }, + { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565 }, + { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962 }, + { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791 }, + { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696 }, + { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358 }, + { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375 }, + { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162 }, + { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025 }, + { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243 }, + { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059 }, + { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596 }, + { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632 }, + { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186 }, + { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064 }, + { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, + { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, + { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, + { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, + { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, + { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, +] + [[package]] name = "attrs" version = "24.2.0" @@ -416,12 +473,16 @@ name = "fastapi-supabase-template" version = "0.4.1" source = { virtual = "." } dependencies = [ + { name = "alembic" }, + { name = "asyncpg" }, { name = "fastapi" }, { name = "pydantic", extra = ["email"] }, { name = "pydantic-settings" }, { name = "python-dotenv" }, { name = "python-multipart" }, + { name = "sqlmodel" }, { name = "supabase" }, + { name = "tenacity" }, { name = "uvicorn" }, ] @@ -448,12 +509,16 @@ docs = [ [package.metadata] requires-dist = [ + { name = "alembic", specifier = ">=1.14.0" }, + { name = "asyncpg", specifier = ">=0.30.0" }, { name = "fastapi", specifier = ">=0.112.2" }, { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, { name = "pydantic-settings", specifier = ">=2.4.0" }, { name = "python-dotenv", specifier = ">=1.0.1" }, { name = "python-multipart", specifier = ">=0.0.9" }, + { name = "sqlmodel", specifier = ">=0.0.22" }, { name = "supabase", specifier = ">=2.7.4" }, + { name = "tenacity", specifier = ">=9.0.0" }, { name = "uvicorn", specifier = ">=0.30.6" }, ] @@ -607,6 +672,57 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/18/ee/4aad2b25941393e956ccda6aea8b2e144dbd780adb893e7f5b7147f0527e/gotrue-2.8.1-py3-none-any.whl", hash = "sha256:97dff077d71cca629f046c35ba34fae132b69c55fe271651766ddcf6d8132468", size = 48388 }, ] +[[package]] +name = "greenlet" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235 }, + { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168 }, + { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826 }, + { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443 }, + { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295 }, + { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544 }, + { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456 }, + { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111 }, + { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392 }, + { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479 }, + { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404 }, + { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813 }, + { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517 }, + { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831 }, + { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413 }, + { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619 }, + { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198 }, + { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930 }, + { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, + { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, + { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, + { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, + { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, + { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, + { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, + { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, + { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, + { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, + { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, + { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, + { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, + { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, + { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, + { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, + { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, + { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, + { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, + { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, + { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, + { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, + { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, + { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, +] + [[package]] name = "h11" version = "0.14.0" @@ -720,6 +836,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, ] +[[package]] +name = "mako" +version = "1.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/0b/29bc5a230948bf209d3ed3165006d257e547c02c3c2a96f6286320dfe8dc/mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d", size = 390206 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/22/bc14c6f02e6dccaafb3eba95764c8f096714260c2aa5f76f654fd16a23dd/Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a", size = 78557 }, +] + [[package]] name = "markdown" version = "3.7" @@ -1511,6 +1639,64 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, ] +[[package]] +name = "sqlalchemy" +version = "2.0.36" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/65/9cbc9c4c3287bed2499e05033e207473504dc4df999ce49385fb1f8b058a/sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", size = 9574485 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/72/14ab694b8b3f0e35ef5beb74a8fea2811aa791ba1611c44dc90cdf46af17/SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", size = 2092604 }, + { url = "https://files.pythonhosted.org/packages/1e/59/333fcbca58b79f5b8b61853d6137530198823392151fa8fd9425f367519e/SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", size = 2083796 }, + { url = "https://files.pythonhosted.org/packages/6c/a0/ec3c188d2b0c1bc742262e76408d44104598d7247c23f5b06bb97ee21bfa/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", size = 3066165 }, + { url = "https://files.pythonhosted.org/packages/07/15/68ef91de5b8b7f80fb2d2b3b31ed42180c6227fe0a701aed9d01d34f98ec/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", size = 3074428 }, + { url = "https://files.pythonhosted.org/packages/e2/4c/9dfea5e63b87325eef6d9cdaac913459aa6a157a05a05ea6ff20004aee8e/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", size = 3030477 }, + { url = "https://files.pythonhosted.org/packages/16/a5/fcfde8e74ea5f683b24add22463bfc21e431d4a5531c8a5b55bc6fbea164/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", size = 3055942 }, + { url = "https://files.pythonhosted.org/packages/3c/ee/c22c415a771d791ae99146d72ffdb20e43625acd24835ea7fc157436d59f/SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", size = 2064960 }, + { url = "https://files.pythonhosted.org/packages/aa/af/ad9c25cadc79bd851bdb9d82b68af9bdb91ff05f56d0da2f8a654825974f/SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", size = 2089078 }, + { url = "https://files.pythonhosted.org/packages/00/4e/5a67963fd7cbc1beb8bd2152e907419f4c940ef04600b10151a751fe9e06/SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", size = 2093782 }, + { url = "https://files.pythonhosted.org/packages/b3/24/30e33b6389ebb5a17df2a4243b091bc709fb3dfc9a48c8d72f8e037c943d/SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", size = 2084180 }, + { url = "https://files.pythonhosted.org/packages/10/1e/70e9ed2143a27065246be40f78637ad5160ea0f5fd32f8cab819a31ff54d/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", size = 3202469 }, + { url = "https://files.pythonhosted.org/packages/b4/5f/95e0ed74093ac3c0db6acfa944d4d8ac6284ef5e1136b878a327ea1f975a/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", size = 3202464 }, + { url = "https://files.pythonhosted.org/packages/91/95/2cf9b85a6bc2ee660e40594dffe04e777e7b8617fd0c6d77a0f782ea96c9/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", size = 3139508 }, + { url = "https://files.pythonhosted.org/packages/92/ea/f0c01bc646456e4345c0fb5a3ddef457326285c2dc60435b0eb96b61bf31/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", size = 3159837 }, + { url = "https://files.pythonhosted.org/packages/a6/93/c8edbf153ee38fe529773240877bf1332ed95328aceef6254288f446994e/SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", size = 2064529 }, + { url = "https://files.pythonhosted.org/packages/b1/03/d12b7c1d36fd80150c1d52e121614cf9377dac99e5497af8d8f5b2a8db64/SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", size = 2089874 }, + { url = "https://files.pythonhosted.org/packages/b8/bf/005dc47f0e57556e14512d5542f3f183b94fde46e15ff1588ec58ca89555/SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", size = 2092378 }, + { url = "https://files.pythonhosted.org/packages/94/65/f109d5720779a08e6e324ec89a744f5f92c48bd8005edc814bf72fbb24e5/SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", size = 2082778 }, + { url = "https://files.pythonhosted.org/packages/60/f6/d9aa8c49c44f9b8c9b9dada1f12fa78df3d4c42aa2de437164b83ee1123c/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53", size = 3232191 }, + { url = "https://files.pythonhosted.org/packages/8a/ab/81d4514527c068670cb1d7ab62a81a185df53a7c379bd2a5636e83d09ede/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", size = 3243044 }, + { url = "https://files.pythonhosted.org/packages/35/b4/f87c014ecf5167dc669199cafdb20a7358ff4b1d49ce3622cc48571f811c/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", size = 3178511 }, + { url = "https://files.pythonhosted.org/packages/ea/09/badfc9293bc3ccba6ede05e5f2b44a760aa47d84da1fc5a326e963e3d4d9/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", size = 3205147 }, + { url = "https://files.pythonhosted.org/packages/c8/60/70e681de02a13c4b27979b7b78da3058c49bacc9858c89ba672e030f03f2/SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", size = 2062709 }, + { url = "https://files.pythonhosted.org/packages/b7/ed/f6cd9395e41bfe47dd253d74d2dfc3cab34980d4e20c8878cb1117306085/SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", size = 2088433 }, + { url = "https://files.pythonhosted.org/packages/78/5c/236398ae3678b3237726819b484f15f5c038a9549da01703a771f05a00d6/SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", size = 2087651 }, + { url = "https://files.pythonhosted.org/packages/a8/14/55c47420c0d23fb67a35af8be4719199b81c59f3084c28d131a7767b0b0b/SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", size = 2078132 }, + { url = "https://files.pythonhosted.org/packages/3d/97/1e843b36abff8c4a7aa2e37f9bea364f90d021754c2de94d792c2d91405b/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", size = 3164559 }, + { url = "https://files.pythonhosted.org/packages/7b/c5/07f18a897b997f6d6b234fab2bf31dccf66d5d16a79fe329aefc95cd7461/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", size = 3177897 }, + { url = "https://files.pythonhosted.org/packages/b3/cd/e16f3cbefd82b5c40b33732da634ec67a5f33b587744c7ab41699789d492/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", size = 3111289 }, + { url = "https://files.pythonhosted.org/packages/15/85/5b8a3b0bc29c9928aa62b5c91fcc8335f57c1de0a6343873b5f372e3672b/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", size = 3139491 }, + { url = "https://files.pythonhosted.org/packages/a1/95/81babb6089938680dfe2cd3f88cd3fd39cccd1543b7cb603b21ad881bff1/SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", size = 2060439 }, + { url = "https://files.pythonhosted.org/packages/c1/ce/5f7428df55660d6879d0522adc73a3364970b5ef33ec17fa125c5dbcac1d/SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", size = 2084574 }, + { url = "https://files.pythonhosted.org/packages/b8/49/21633706dd6feb14cd3f7935fc00b60870ea057686035e1a99ae6d9d9d53/SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", size = 1883787 }, +] + +[[package]] +name = "sqlmodel" +version = "0.0.22" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/39/8641040ab0d5e1d8a1c2325ae89a01ae659fc96c61a43d158fb71c9a0bf0/sqlmodel-0.0.22.tar.gz", hash = "sha256:7d37c882a30c43464d143e35e9ecaf945d88035e20117bf5ec2834a23cbe505e", size = 116392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/b1/3af5104b716c420e40a6ea1b09886cae3a1b9f4538343875f637755cae5b/sqlmodel-0.0.22-py3-none-any.whl", hash = "sha256:a1ed13e28a1f4057cbf4ff6cdb4fc09e85702621d3259ba17b3c230bfb2f941b", size = 28276 }, +] + [[package]] name = "starlette" version = "0.38.2" @@ -1575,6 +1761,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/93/ea/da0b3bd36ac21e91a7f3d43c3cc7884b79d96766cb07d1e55a83df0baadd/supafunc-0.5.1-py3-none-any.whl", hash = "sha256:b05e99a2b41270211a3f90ec843c04c5f27a5618f2d2d2eb8e07f41eb962a910", size = 6404 }, ] +[[package]] +name = "tenacity" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, +] + [[package]] name = "tomli" version = "2.0.1" From 19582328db5df3d21ca786f63de24a03f69ca0bd Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 14:09:33 +0800 Subject: [PATCH 29/65] refactor: move major deps of pyproject.toml into backend/ --- backend/pyproject.toml | 117 +++ backend/uv.lock | 1560 +++++++++++++++++++++++++++++++ pyproject.toml | 128 +-- scripts/bump.sh | 6 +- scripts/docs.sh | 9 + scripts/pre-commit.sh | 3 + uv.lock | 1990 +--------------------------------------- 7 files changed, 1694 insertions(+), 2119 deletions(-) create mode 100644 backend/pyproject.toml create mode 100644 backend/uv.lock create mode 100755 scripts/docs.sh create mode 100755 scripts/pre-commit.sh diff --git a/backend/pyproject.toml b/backend/pyproject.toml new file mode 100644 index 0000000..1222f8d --- /dev/null +++ b/backend/pyproject.toml @@ -0,0 +1,117 @@ +[project] +name = "app" +dynamic = ["version"] +requires-python = ">=3.10" +dependencies = [ + "uvicorn>=0.30.6", + "pydantic[email]>=2.8.2", + "pydantic-settings>=2.4.0", + "python-multipart>=0.0.9", + "supabase>=2.7.4", + "fastapi>=0.112.2", + "sqlmodel>=0.0.22", + "asyncpg>=0.30.0", + "alembic>=1.14.0", + "tenacity>=9.0.0", +] + +[dependency-groups] +dev = [ + "anyio>=4.4.0", + "coverage>=7.6.1", + "faker>=28.0.0", + "mypy>=1.13.0", + "pre-commit>=3.8.0", + "pytest-sugar>=1.0.0", + "pytest>=8.3.2", +] + +## Test +[tool.mypy] +strict = true +exclude = ["venv", ".venv"] + +[tool.pytest.ini_options] +# Set additional command line options for pytest= +# -r= show extra test summary info +# X= show extra info on xfailed tests +# s= don't capture stdout (allow print statements) +# --strict-config= any warnings about configuration are treated as errors +# --strict-markers= treat unregistered markers as errors +addopts = "-rXs --strict-config --strict-markers" +xfail_strict = true # Treat tests that are marked as xfail but pass as test failures +filterwarnings = ["error"] # Treat all warnings as errors +pythonpath = "backend" + +[tool.coverage.run] +branch = true + +[tool.coverage.report] +skip_covered = true +show_missing = true +precision = 2 +exclude_lines = [ + 'def __repr__', + 'pragma= no cover', + 'raise NotImplementedError', + 'if TYPE_CHECKING=', + 'if typing.TYPE_CHECKING=', + '@overload', + '@typing.overload', + '\(Protocol\)=$', + 'typing.assert_never', + 'assert_never', + 'if __name__ == "__main__":', +] + + +## Linter and formatter +[tool.ruff] +# cover and extend the default config in https=//docs.astral.sh/ruff/configuration/ +extend-exclude = [""] +target-version = "py310" + +[tool.ruff.lint] +select = [ + "E", # pycodestyle errors + "W", # pycodestyle warnings + "F", # pyflakes + "I", # isort + "B", # flake8-bugbear + "C4", # flake8-comprehensions + "UP", # pyupgrade + "ARG001", # unused arguments in functions +] +ignore = [ + "E501", # line too long, handled by black + "B008", # do not perform function calls in argument defaults + "W191", # indentation contains tabs + "B904", # Allow raising exceptions without from e, for HTTPException + "COM819", # Trailing comma prohibited + "D100", # Missing docstring in public module(file) + "D104", # Missing docstring in public package + "D203", # 1 blank line required before class docstring + "E201", # Whitespace after '(' + "E202", # Whitespace before ')' + "E203", # Whitespace before '=' + "E221", # Multiple spaces before operator + "E241", # Multiple spaces after ',' + "E251", # Unexpected spaces around keyword / parameter equals + "W291", # Trailing whitespace + "W293", # Blank line contains whitespace +] + +isort = { combine-as-imports = true, split-on-trailing-comma = false } + +# Avoid trying to fix flake8-bugbear (`B`) violations. +unfixable = ["B"] + +[tool.ruff.format] +docstring-code-format = true +skip-magic-trailing-comma = true + +# Reference +# 1. https=//github.com/Kludex/python-template/blob/main/template/%7B%7B%20project_slug%20%7D%7D/pyproject.toml.jinja +# 2. https=//github.com/fastapi/full-stack-fastapi-template/blob/master/backend/pyproject.toml +# 3. https=//github.com/pydantic/logfire +# 4. https=//coverage.readthedocs.io/en/latest/index.html diff --git a/backend/uv.lock b/backend/uv.lock new file mode 100644 index 0000000..6d35a70 --- /dev/null +++ b/backend/uv.lock @@ -0,0 +1,1560 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.13'", + "python_full_version >= '3.13'", +] + +[[package]] +name = "aiohappyeyeballs" +version = "2.4.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/69/2f6d5a019bd02e920a3417689a89887b39ad1e350b562f9955693d900c40/aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", size = 21809 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/d8/120cd0fe3e8530df0539e71ba9683eade12cae103dd7543e50d15f737917/aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572", size = 14742 }, +] + +[[package]] +name = "aiohttp" +version = "3.10.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohappyeyeballs" }, + { name = "aiosignal" }, + { name = "async-timeout", marker = "python_full_version < '3.11'" }, + { name = "attrs" }, + { name = "frozenlist" }, + { name = "multidict" }, + { name = "yarl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/7e/16e57e6cf20eb62481a2f9ce8674328407187950ccc602ad07c685279141/aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a", size = 7542993 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/dd/3d40c0e67e79c5c42671e3e268742f1ff96c6573ca43823563d01abd9475/aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f", size = 586969 }, + { url = "https://files.pythonhosted.org/packages/75/64/8de41b5555e5b43ef6d4ed1261891d33fe45ecc6cb62875bfafb90b9ab93/aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9", size = 399367 }, + { url = "https://files.pythonhosted.org/packages/96/36/27bd62ea7ce43906d1443a73691823fc82ffb8fa03276b0e2f7e1037c286/aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8", size = 390720 }, + { url = "https://files.pythonhosted.org/packages/e8/4d/d516b050d811ce0dd26325c383013c104ffa8b58bd361b82e52833f68e78/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1", size = 1228820 }, + { url = "https://files.pythonhosted.org/packages/53/94/964d9327a3e336d89aad52260836e4ec87fdfa1207176550fdf384eaffe7/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a", size = 1264616 }, + { url = "https://files.pythonhosted.org/packages/0c/20/70ce17764b685ca8f5bf4d568881b4e1f1f4ea5e8170f512fdb1a33859d2/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd", size = 1298402 }, + { url = "https://files.pythonhosted.org/packages/d1/d1/5248225ccc687f498d06c3bca5af2647a361c3687a85eb3aedcc247ee1aa/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026", size = 1222205 }, + { url = "https://files.pythonhosted.org/packages/f2/a3/9296b27cc5d4feadf970a14d0694902a49a985f3fae71b8322a5f77b0baa/aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b", size = 1193804 }, + { url = "https://files.pythonhosted.org/packages/d9/07/f3760160feb12ac51a6168a6da251a4a8f2a70733d49e6ceb9b3e6ee2f03/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d", size = 1193544 }, + { url = "https://files.pythonhosted.org/packages/7e/4c/93a70f9a4ba1c30183a6dd68bfa79cddbf9a674f162f9c62e823a74a5515/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7", size = 1193047 }, + { url = "https://files.pythonhosted.org/packages/ff/a3/36a1e23ff00c7a0cd696c5a28db05db25dc42bfc78c508bd78623ff62a4a/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a", size = 1247201 }, + { url = "https://files.pythonhosted.org/packages/55/ae/95399848557b98bb2c402d640b2276ce3a542b94dba202de5a5a1fe29abe/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc", size = 1264102 }, + { url = "https://files.pythonhosted.org/packages/38/f5/02e5c72c1b60d7cceb30b982679a26167e84ac029fd35a93dd4da52c50a3/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68", size = 1215760 }, + { url = "https://files.pythonhosted.org/packages/30/17/1463840bad10d02d0439068f37ce5af0b383884b0d5838f46fb027e233bf/aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257", size = 362678 }, + { url = "https://files.pythonhosted.org/packages/dd/01/a0ef707d93e867a43abbffee3a2cdf30559910750b9176b891628c7ad074/aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6", size = 381097 }, + { url = "https://files.pythonhosted.org/packages/72/31/3c351d17596194e5a38ef169a4da76458952b2497b4b54645b9d483cbbb0/aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f", size = 586501 }, + { url = "https://files.pythonhosted.org/packages/a4/a8/a559d09eb08478cdead6b7ce05b0c4a133ba27fcdfa91e05d2e62867300d/aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb", size = 398993 }, + { url = "https://files.pythonhosted.org/packages/c5/47/7736d4174613feef61d25332c3bd1a4f8ff5591fbd7331988238a7299485/aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871", size = 390647 }, + { url = "https://files.pythonhosted.org/packages/27/21/e9ba192a04b7160f5a8952c98a1de7cf8072ad150fa3abd454ead1ab1d7f/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c", size = 1306481 }, + { url = "https://files.pythonhosted.org/packages/cf/50/f364c01c8d0def1dc34747b2470969e216f5a37c7ece00fe558810f37013/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38", size = 1344652 }, + { url = "https://files.pythonhosted.org/packages/1d/c2/74f608e984e9b585649e2e83883facad6fa3fc1d021de87b20cc67e8e5ae/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb", size = 1378498 }, + { url = "https://files.pythonhosted.org/packages/9f/a7/05a48c7c0a7a80a5591b1203bf1b64ca2ed6a2050af918d09c05852dc42b/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7", size = 1292718 }, + { url = "https://files.pythonhosted.org/packages/7d/78/a925655018747e9790350180330032e27d6e0d7ed30bde545fae42f8c49c/aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911", size = 1251776 }, + { url = "https://files.pythonhosted.org/packages/47/9d/85c6b69f702351d1236594745a4fdc042fc43f494c247a98dac17e004026/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092", size = 1271716 }, + { url = "https://files.pythonhosted.org/packages/7f/a7/55fc805ff9b14af818903882ece08e2235b12b73b867b521b92994c52b14/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142", size = 1266263 }, + { url = "https://files.pythonhosted.org/packages/1f/ec/d2be2ca7b063e4f91519d550dbc9c1cb43040174a322470deed90b3d3333/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9", size = 1321617 }, + { url = "https://files.pythonhosted.org/packages/c9/a3/b29f7920e1cd0a9a68a45dd3eb16140074d2efb1518d2e1f3e140357dc37/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1", size = 1339227 }, + { url = "https://files.pythonhosted.org/packages/8a/81/34b67235c47e232d807b4bbc42ba9b927c7ce9476872372fddcfd1e41b3d/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a", size = 1299068 }, + { url = "https://files.pythonhosted.org/packages/04/1f/26a7fe11b6ad3184f214733428353c89ae9fe3e4f605a657f5245c5e720c/aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94", size = 362223 }, + { url = "https://files.pythonhosted.org/packages/10/91/85dcd93f64011434359ce2666bece981f08d31bc49df33261e625b28595d/aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959", size = 381576 }, + { url = "https://files.pythonhosted.org/packages/ae/99/4c5aefe5ad06a1baf206aed6598c7cdcbc7c044c46801cd0d1ecb758cae3/aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c", size = 583536 }, + { url = "https://files.pythonhosted.org/packages/a9/36/8b3bc49b49cb6d2da40ee61ff15dbcc44fd345a3e6ab5bb20844df929821/aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28", size = 395693 }, + { url = "https://files.pythonhosted.org/packages/e1/77/0aa8660dcf11fa65d61712dbb458c4989de220a844bd69778dff25f2d50b/aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f", size = 390898 }, + { url = "https://files.pythonhosted.org/packages/38/d2/b833d95deb48c75db85bf6646de0a697e7fb5d87bd27cbade4f9746b48b1/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138", size = 1312060 }, + { url = "https://files.pythonhosted.org/packages/aa/5f/29fd5113165a0893de8efedf9b4737e0ba92dfcd791415a528f947d10299/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742", size = 1350553 }, + { url = "https://files.pythonhosted.org/packages/ad/cc/f835f74b7d344428469200105236d44606cfa448be1e7c95ca52880d9bac/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7", size = 1392646 }, + { url = "https://files.pythonhosted.org/packages/bf/fe/1332409d845ca601893bbf2d76935e0b93d41686e5f333841c7d7a4a770d/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16", size = 1306310 }, + { url = "https://files.pythonhosted.org/packages/e4/a1/25a7633a5a513278a9892e333501e2e69c83e50be4b57a62285fb7a008c3/aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8", size = 1260255 }, + { url = "https://files.pythonhosted.org/packages/f2/39/30eafe89e0e2a06c25e4762844c8214c0c0cd0fd9ffc3471694a7986f421/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6", size = 1271141 }, + { url = "https://files.pythonhosted.org/packages/5b/fc/33125df728b48391ef1fcb512dfb02072158cc10d041414fb79803463020/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a", size = 1280244 }, + { url = "https://files.pythonhosted.org/packages/3b/61/e42bf2c2934b5caa4e2ec0b5e5fd86989adb022b5ee60c2572a9d77cf6fe/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9", size = 1316805 }, + { url = "https://files.pythonhosted.org/packages/18/32/f52a5e2ae9ad3bba10e026a63a7a23abfa37c7d97aeeb9004eaa98df3ce3/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a", size = 1343930 }, + { url = "https://files.pythonhosted.org/packages/05/be/6a403b464dcab3631fe8e27b0f1d906d9e45c5e92aca97ee007e5a895560/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205", size = 1306186 }, + { url = "https://files.pythonhosted.org/packages/8e/fd/bb50fe781068a736a02bf5c7ad5f3ab53e39f1d1e63110da6d30f7605edc/aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628", size = 359289 }, + { url = "https://files.pythonhosted.org/packages/70/9e/5add7e240f77ef67c275c82cc1d08afbca57b77593118c1f6e920ae8ad3f/aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf", size = 379313 }, + { url = "https://files.pythonhosted.org/packages/b1/eb/618b1b76c7fe8082a71c9d62e3fe84c5b9af6703078caa9ec57850a12080/aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28", size = 576114 }, + { url = "https://files.pythonhosted.org/packages/aa/37/3126995d7869f8b30d05381b81a2d4fb4ec6ad313db788e009bc6d39c211/aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d", size = 391901 }, + { url = "https://files.pythonhosted.org/packages/3e/f2/8fdfc845be1f811c31ceb797968523813f8e1263ee3e9120d61253f6848f/aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79", size = 387418 }, + { url = "https://files.pythonhosted.org/packages/60/d5/33d2061d36bf07e80286e04b7e0a4de37ce04b5ebfed72dba67659a05250/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e", size = 1287073 }, + { url = "https://files.pythonhosted.org/packages/00/52/affb55be16a4747740bd630b4c002dac6c5eac42f9bb64202fc3cf3f1930/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6", size = 1323612 }, + { url = "https://files.pythonhosted.org/packages/94/f2/cddb69b975387daa2182a8442566971d6410b8a0179bb4540d81c97b1611/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42", size = 1368406 }, + { url = "https://files.pythonhosted.org/packages/c1/e4/afba7327da4d932da8c6e29aecaf855f9d52dace53ac15bfc8030a246f1b/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e", size = 1282761 }, + { url = "https://files.pythonhosted.org/packages/9f/6b/364856faa0c9031ea76e24ef0f7fef79cddd9fa8e7dba9a1771c6acc56b5/aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc", size = 1236518 }, + { url = "https://files.pythonhosted.org/packages/46/af/c382846f8356fe64a7b5908bb9b477457aa23b71be7ed551013b7b7d4d87/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a", size = 1250344 }, + { url = "https://files.pythonhosted.org/packages/87/53/294f87fc086fd0772d0ab82497beb9df67f0f27a8b3dd5742a2656db2bc6/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414", size = 1248956 }, + { url = "https://files.pythonhosted.org/packages/86/30/7d746717fe11bdfefb88bb6c09c5fc985d85c4632da8bb6018e273899254/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3", size = 1293379 }, + { url = "https://files.pythonhosted.org/packages/48/b9/45d670a834458db67a24258e9139ba61fa3bd7d69b98ecf3650c22806f8f/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67", size = 1320108 }, + { url = "https://files.pythonhosted.org/packages/72/8c/804bb2e837a175635d2000a0659eafc15b2e9d92d3d81c8f69e141ecd0b0/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b", size = 1281546 }, + { url = "https://files.pythonhosted.org/packages/89/c0/862e6a9de3d6eeb126cd9d9ea388243b70df9b871ce1a42b193b7a4a77fc/aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8", size = 357516 }, + { url = "https://files.pythonhosted.org/packages/ae/63/3e1aee3e554263f3f1011cca50d78a4894ae16ce99bf78101ac3a2f0ef74/aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151", size = 376785 }, +] + +[[package]] +name = "aiosignal" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "frozenlist" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 }, +] + +[[package]] +name = "alembic" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mako" }, + { name = "sqlalchemy" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/1e/8cb8900ba1b6360431e46fb7a89922916d3a1b017a8908a7c0499cc7e5f6/alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b", size = 1916172 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/06/8b505aea3d77021b18dcbd8133aa1418f1a1e37e432a465b14c46b2c0eaa/alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25", size = 233482 }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, +] + +[[package]] +name = "anyio" +version = "4.6.2.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, +] + +[[package]] +name = "app" +version = "0.0.0" +source = { virtual = "." } +dependencies = [ + { name = "alembic" }, + { name = "asyncpg" }, + { name = "fastapi" }, + { name = "pydantic", extra = ["email"] }, + { name = "pydantic-settings" }, + { name = "python-multipart" }, + { name = "sqlmodel" }, + { name = "supabase" }, + { name = "tenacity" }, + { name = "uvicorn" }, +] + +[package.dev-dependencies] +dev = [ + { name = "anyio" }, + { name = "coverage" }, + { name = "faker" }, + { name = "mypy" }, + { name = "pre-commit" }, + { name = "pytest" }, + { name = "pytest-sugar" }, +] + +[package.metadata] +requires-dist = [ + { name = "alembic", specifier = ">=1.14.0" }, + { name = "asyncpg", specifier = ">=0.30.0" }, + { name = "fastapi", specifier = ">=0.112.2" }, + { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, + { name = "pydantic-settings", specifier = ">=2.4.0" }, + { name = "python-multipart", specifier = ">=0.0.9" }, + { name = "sqlmodel", specifier = ">=0.0.22" }, + { name = "supabase", specifier = ">=2.7.4" }, + { name = "tenacity", specifier = ">=9.0.0" }, + { name = "uvicorn", specifier = ">=0.30.6" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "anyio", specifier = ">=4.4.0" }, + { name = "coverage", specifier = ">=7.6.1" }, + { name = "faker", specifier = ">=28.0.0" }, + { name = "mypy", specifier = ">=1.13.0" }, + { name = "pre-commit", specifier = ">=3.8.0" }, + { name = "pytest", specifier = ">=8.3.2" }, + { name = "pytest-sugar", specifier = ">=1.0.0" }, +] + +[[package]] +name = "async-timeout" +version = "4.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, +] + +[[package]] +name = "asyncpg" +version = "0.30.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-timeout", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143 }, + { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035 }, + { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384 }, + { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526 }, + { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390 }, + { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630 }, + { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760 }, + { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764 }, + { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506 }, + { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922 }, + { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565 }, + { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962 }, + { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791 }, + { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696 }, + { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358 }, + { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375 }, + { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162 }, + { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025 }, + { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243 }, + { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059 }, + { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596 }, + { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632 }, + { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186 }, + { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064 }, + { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, + { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, + { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, + { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, + { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, + { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, + { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, + { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, +] + +[[package]] +name = "attrs" +version = "24.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, +] + +[[package]] +name = "certifi" +version = "2024.8.30" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, +] + +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, + { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, + { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, + { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, + { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, + { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, + { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, + { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, + { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, + { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, + { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, + { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, + { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, + { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, + { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, + { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, + { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, + { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, + { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, + { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, + { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, + { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, + { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, + { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, + { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, + { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, + { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, + { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, + { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, + { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, + { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, + { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, + { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, + { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, + { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, + { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, + { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, + { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, + { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, + { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, + { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, + { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, + { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, + { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, + { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, + { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, + { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, + { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, + { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +] + +[[package]] +name = "deprecation" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/d3/8ae2869247df154b64c1884d7346d412fed0c49df84db635aab2d1c40e62/deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff", size = 173788 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a", size = 11178 }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "dnspython" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/4a/263763cb2ba3816dd94b08ad3a33d5fdae34ecb856678773cc40a3605829/dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1", size = 345197 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/68/1b/e0a87d256e40e8c888847551b20a017a6b98139178505dc7ffb96f04e954/dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86", size = 313632 }, +] + +[[package]] +name = "email-validator" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dnspython" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "faker" +version = "30.8.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/df/7574c0d13f0bbab725e52bec4b00783aaa14163fe9093dde11a928a4c638/faker-30.8.2.tar.gz", hash = "sha256:aa31b52cdae3673d6a78b4857c7bcdc0e98f201a5cb77d7827fa9e6b5876da94", size = 1808329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/82/f7d0c0a4ab512fd1572a315eec903d50a578c75d5aa894cf3f5cc04025e5/Faker-30.8.2-py3-none-any.whl", hash = "sha256:4a82b2908cd19f3bba1a4da2060cc4eb18a40410ccdf9350d071d79dc92fe3ce", size = 1846458 }, +] + +[[package]] +name = "fastapi" +version = "0.115.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "starlette" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/db/5781f19bd30745885e0737ff3fdd4e63e7bc691710f9da691128bb0dc73b/fastapi-0.115.4.tar.gz", hash = "sha256:db653475586b091cb8b2fec2ac54a680ac6a158e07406e1abae31679e8826349", size = 300737 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/99/f6/af0d1f58f86002be0cf1e2665cdd6f7a4a71cdc8a7a9438cdc9e3b5375fe/fastapi-0.115.4-py3-none-any.whl", hash = "sha256:0b504a063ffb3cf96a5e27dc1bc32c80ca743a2528574f9cdc77daa2d31b4742", size = 94732 }, +] + +[[package]] +name = "filelock" +version = "3.16.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, +] + +[[package]] +name = "frozenlist" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8f/ed/0f4cec13a93c02c47ec32d81d11c0c1efbadf4a471e3f3ce7cad366cbbd3/frozenlist-1.5.0.tar.gz", hash = "sha256:81d5af29e61b9c8348e876d442253723928dce6433e0e76cd925cd83f1b4b817", size = 39930 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/79/29d44c4af36b2b240725dce566b20f63f9b36ef267aaaa64ee7466f4f2f8/frozenlist-1.5.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5b6a66c18b5b9dd261ca98dffcb826a525334b2f29e7caa54e182255c5f6a65a", size = 94451 }, + { url = "https://files.pythonhosted.org/packages/47/47/0c999aeace6ead8a44441b4f4173e2261b18219e4ad1fe9a479871ca02fc/frozenlist-1.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d1b3eb7b05ea246510b43a7e53ed1653e55c2121019a97e60cad7efb881a97bb", size = 54301 }, + { url = "https://files.pythonhosted.org/packages/8d/60/107a38c1e54176d12e06e9d4b5d755b677d71d1219217cee063911b1384f/frozenlist-1.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:15538c0cbf0e4fa11d1e3a71f823524b0c46299aed6e10ebb4c2089abd8c3bec", size = 52213 }, + { url = "https://files.pythonhosted.org/packages/17/62/594a6829ac5679c25755362a9dc93486a8a45241394564309641425d3ff6/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e79225373c317ff1e35f210dd5f1344ff31066ba8067c307ab60254cd3a78ad5", size = 240946 }, + { url = "https://files.pythonhosted.org/packages/7e/75/6c8419d8f92c80dd0ee3f63bdde2702ce6398b0ac8410ff459f9b6f2f9cb/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9272fa73ca71266702c4c3e2d4a28553ea03418e591e377a03b8e3659d94fa76", size = 264608 }, + { url = "https://files.pythonhosted.org/packages/88/3e/82a6f0b84bc6fb7e0be240e52863c6d4ab6098cd62e4f5b972cd31e002e8/frozenlist-1.5.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:498524025a5b8ba81695761d78c8dd7382ac0b052f34e66939c42df860b8ff17", size = 261361 }, + { url = "https://files.pythonhosted.org/packages/fd/85/14e5f9ccac1b64ff2f10c927b3ffdf88772aea875882406f9ba0cec8ad84/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:92b5278ed9d50fe610185ecd23c55d8b307d75ca18e94c0e7de328089ac5dcba", size = 231649 }, + { url = "https://files.pythonhosted.org/packages/ee/59/928322800306f6529d1852323014ee9008551e9bb027cc38d276cbc0b0e7/frozenlist-1.5.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f3c8c1dacd037df16e85227bac13cca58c30da836c6f936ba1df0c05d046d8d", size = 241853 }, + { url = "https://files.pythonhosted.org/packages/7d/bd/e01fa4f146a6f6c18c5d34cab8abdc4013774a26c4ff851128cd1bd3008e/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f2ac49a9bedb996086057b75bf93538240538c6d9b38e57c82d51f75a73409d2", size = 243652 }, + { url = "https://files.pythonhosted.org/packages/a5/bd/e4771fd18a8ec6757033f0fa903e447aecc3fbba54e3630397b61596acf0/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e66cc454f97053b79c2ab09c17fbe3c825ea6b4de20baf1be28919460dd7877f", size = 241734 }, + { url = "https://files.pythonhosted.org/packages/21/13/c83821fa5544af4f60c5d3a65d054af3213c26b14d3f5f48e43e5fb48556/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:5a3ba5f9a0dfed20337d3e966dc359784c9f96503674c2faf015f7fe8e96798c", size = 260959 }, + { url = "https://files.pythonhosted.org/packages/71/f3/1f91c9a9bf7ed0e8edcf52698d23f3c211d8d00291a53c9f115ceb977ab1/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:6321899477db90bdeb9299ac3627a6a53c7399c8cd58d25da094007402b039ab", size = 262706 }, + { url = "https://files.pythonhosted.org/packages/4c/22/4a256fdf5d9bcb3ae32622c796ee5ff9451b3a13a68cfe3f68e2c95588ce/frozenlist-1.5.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:76e4753701248476e6286f2ef492af900ea67d9706a0155335a40ea21bf3b2f5", size = 250401 }, + { url = "https://files.pythonhosted.org/packages/af/89/c48ebe1f7991bd2be6d5f4ed202d94960c01b3017a03d6954dd5fa9ea1e8/frozenlist-1.5.0-cp310-cp310-win32.whl", hash = "sha256:977701c081c0241d0955c9586ffdd9ce44f7a7795df39b9151cd9a6fd0ce4cfb", size = 45498 }, + { url = "https://files.pythonhosted.org/packages/28/2f/cc27d5f43e023d21fe5c19538e08894db3d7e081cbf582ad5ed366c24446/frozenlist-1.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:189f03b53e64144f90990d29a27ec4f7997d91ed3d01b51fa39d2dbe77540fd4", size = 51622 }, + { url = "https://files.pythonhosted.org/packages/79/43/0bed28bf5eb1c9e4301003b74453b8e7aa85fb293b31dde352aac528dafc/frozenlist-1.5.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fd74520371c3c4175142d02a976aee0b4cb4a7cc912a60586ffd8d5929979b30", size = 94987 }, + { url = "https://files.pythonhosted.org/packages/bb/bf/b74e38f09a246e8abbe1e90eb65787ed745ccab6eaa58b9c9308e052323d/frozenlist-1.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2f3f7a0fbc219fb4455264cae4d9f01ad41ae6ee8524500f381de64ffaa077d5", size = 54584 }, + { url = "https://files.pythonhosted.org/packages/2c/31/ab01375682f14f7613a1ade30149f684c84f9b8823a4391ed950c8285656/frozenlist-1.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f47c9c9028f55a04ac254346e92977bf0f166c483c74b4232bee19a6697e4778", size = 52499 }, + { url = "https://files.pythonhosted.org/packages/98/a8/d0ac0b9276e1404f58fec3ab6e90a4f76b778a49373ccaf6a563f100dfbc/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0996c66760924da6e88922756d99b47512a71cfd45215f3570bf1e0b694c206a", size = 276357 }, + { url = "https://files.pythonhosted.org/packages/ad/c9/c7761084fa822f07dac38ac29f841d4587570dd211e2262544aa0b791d21/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a2fe128eb4edeabe11896cb6af88fca5346059f6c8d807e3b910069f39157869", size = 287516 }, + { url = "https://files.pythonhosted.org/packages/a1/ff/cd7479e703c39df7bdab431798cef89dc75010d8aa0ca2514c5b9321db27/frozenlist-1.5.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a8ea951bbb6cacd492e3948b8da8c502a3f814f5d20935aae74b5df2b19cf3d", size = 283131 }, + { url = "https://files.pythonhosted.org/packages/59/a0/370941beb47d237eca4fbf27e4e91389fd68699e6f4b0ebcc95da463835b/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de537c11e4aa01d37db0d403b57bd6f0546e71a82347a97c6a9f0dcc532b3a45", size = 261320 }, + { url = "https://files.pythonhosted.org/packages/b8/5f/c10123e8d64867bc9b4f2f510a32042a306ff5fcd7e2e09e5ae5100ee333/frozenlist-1.5.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c2623347b933fcb9095841f1cc5d4ff0b278addd743e0e966cb3d460278840d", size = 274877 }, + { url = "https://files.pythonhosted.org/packages/fa/79/38c505601ae29d4348f21706c5d89755ceded02a745016ba2f58bd5f1ea6/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:cee6798eaf8b1416ef6909b06f7dc04b60755206bddc599f52232606e18179d3", size = 269592 }, + { url = "https://files.pythonhosted.org/packages/19/e2/39f3a53191b8204ba9f0bb574b926b73dd2efba2a2b9d2d730517e8f7622/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:f5f9da7f5dbc00a604fe74aa02ae7c98bcede8a3b8b9666f9f86fc13993bc71a", size = 265934 }, + { url = "https://files.pythonhosted.org/packages/d5/c9/3075eb7f7f3a91f1a6b00284af4de0a65a9ae47084930916f5528144c9dd/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:90646abbc7a5d5c7c19461d2e3eeb76eb0b204919e6ece342feb6032c9325ae9", size = 283859 }, + { url = "https://files.pythonhosted.org/packages/05/f5/549f44d314c29408b962fa2b0e69a1a67c59379fb143b92a0a065ffd1f0f/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:bdac3c7d9b705d253b2ce370fde941836a5f8b3c5c2b8fd70940a3ea3af7f4f2", size = 287560 }, + { url = "https://files.pythonhosted.org/packages/9d/f8/cb09b3c24a3eac02c4c07a9558e11e9e244fb02bf62c85ac2106d1eb0c0b/frozenlist-1.5.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:03d33c2ddbc1816237a67f66336616416e2bbb6beb306e5f890f2eb22b959cdf", size = 277150 }, + { url = "https://files.pythonhosted.org/packages/37/48/38c2db3f54d1501e692d6fe058f45b6ad1b358d82cd19436efab80cfc965/frozenlist-1.5.0-cp311-cp311-win32.whl", hash = "sha256:237f6b23ee0f44066219dae14c70ae38a63f0440ce6750f868ee08775073f942", size = 45244 }, + { url = "https://files.pythonhosted.org/packages/ca/8c/2ddffeb8b60a4bce3b196c32fcc30d8830d4615e7b492ec2071da801b8ad/frozenlist-1.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:0cc974cc93d32c42e7b0f6cf242a6bd941c57c61b618e78b6c0a96cb72788c1d", size = 51634 }, + { url = "https://files.pythonhosted.org/packages/79/73/fa6d1a96ab7fd6e6d1c3500700963eab46813847f01ef0ccbaa726181dd5/frozenlist-1.5.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:31115ba75889723431aa9a4e77d5f398f5cf976eea3bdf61749731f62d4a4a21", size = 94026 }, + { url = "https://files.pythonhosted.org/packages/ab/04/ea8bf62c8868b8eada363f20ff1b647cf2e93377a7b284d36062d21d81d1/frozenlist-1.5.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7437601c4d89d070eac8323f121fcf25f88674627505334654fd027b091db09d", size = 54150 }, + { url = "https://files.pythonhosted.org/packages/d0/9a/8e479b482a6f2070b26bda572c5e6889bb3ba48977e81beea35b5ae13ece/frozenlist-1.5.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7948140d9f8ece1745be806f2bfdf390127cf1a763b925c4a805c603df5e697e", size = 51927 }, + { url = "https://files.pythonhosted.org/packages/e3/12/2aad87deb08a4e7ccfb33600871bbe8f0e08cb6d8224371387f3303654d7/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:feeb64bc9bcc6b45c6311c9e9b99406660a9c05ca8a5b30d14a78555088b0b3a", size = 282647 }, + { url = "https://files.pythonhosted.org/packages/77/f2/07f06b05d8a427ea0060a9cef6e63405ea9e0d761846b95ef3fb3be57111/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:683173d371daad49cffb8309779e886e59c2f369430ad28fe715f66d08d4ab1a", size = 289052 }, + { url = "https://files.pythonhosted.org/packages/bd/9f/8bf45a2f1cd4aa401acd271b077989c9267ae8463e7c8b1eb0d3f561b65e/frozenlist-1.5.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7d57d8f702221405a9d9b40f9da8ac2e4a1a8b5285aac6100f3393675f0a85ee", size = 291719 }, + { url = "https://files.pythonhosted.org/packages/41/d1/1f20fd05a6c42d3868709b7604c9f15538a29e4f734c694c6bcfc3d3b935/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c72000fbcc35b129cb09956836c7d7abf78ab5416595e4857d1cae8d6251a6", size = 267433 }, + { url = "https://files.pythonhosted.org/packages/af/f2/64b73a9bb86f5a89fb55450e97cd5c1f84a862d4ff90d9fd1a73ab0f64a5/frozenlist-1.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:000a77d6034fbad9b6bb880f7ec073027908f1b40254b5d6f26210d2dab1240e", size = 283591 }, + { url = "https://files.pythonhosted.org/packages/29/e2/ffbb1fae55a791fd6c2938dd9ea779509c977435ba3940b9f2e8dc9d5316/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5d7f5a50342475962eb18b740f3beecc685a15b52c91f7d975257e13e029eca9", size = 273249 }, + { url = "https://files.pythonhosted.org/packages/2e/6e/008136a30798bb63618a114b9321b5971172a5abddff44a100c7edc5ad4f/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:87f724d055eb4785d9be84e9ebf0f24e392ddfad00b3fe036e43f489fafc9039", size = 271075 }, + { url = "https://files.pythonhosted.org/packages/ae/f0/4e71e54a026b06724cec9b6c54f0b13a4e9e298cc8db0f82ec70e151f5ce/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:6e9080bb2fb195a046e5177f10d9d82b8a204c0736a97a153c2466127de87784", size = 285398 }, + { url = "https://files.pythonhosted.org/packages/4d/36/70ec246851478b1c0b59f11ef8ade9c482ff447c1363c2bd5fad45098b12/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b93d7aaa36c966fa42efcaf716e6b3900438632a626fb09c049f6a2f09fc631", size = 294445 }, + { url = "https://files.pythonhosted.org/packages/37/e0/47f87544055b3349b633a03c4d94b405956cf2437f4ab46d0928b74b7526/frozenlist-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:52ef692a4bc60a6dd57f507429636c2af8b6046db8b31b18dac02cbc8f507f7f", size = 280569 }, + { url = "https://files.pythonhosted.org/packages/f9/7c/490133c160fb6b84ed374c266f42800e33b50c3bbab1652764e6e1fc498a/frozenlist-1.5.0-cp312-cp312-win32.whl", hash = "sha256:29d94c256679247b33a3dc96cce0f93cbc69c23bf75ff715919332fdbb6a32b8", size = 44721 }, + { url = "https://files.pythonhosted.org/packages/b1/56/4e45136ffc6bdbfa68c29ca56ef53783ef4c2fd395f7cbf99a2624aa9aaa/frozenlist-1.5.0-cp312-cp312-win_amd64.whl", hash = "sha256:8969190d709e7c48ea386db202d708eb94bdb29207a1f269bab1196ce0dcca1f", size = 51329 }, + { url = "https://files.pythonhosted.org/packages/da/3b/915f0bca8a7ea04483622e84a9bd90033bab54bdf485479556c74fd5eaf5/frozenlist-1.5.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7a1a048f9215c90973402e26c01d1cff8a209e1f1b53f72b95c13db61b00f953", size = 91538 }, + { url = "https://files.pythonhosted.org/packages/c7/d1/a7c98aad7e44afe5306a2b068434a5830f1470675f0e715abb86eb15f15b/frozenlist-1.5.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dd47a5181ce5fcb463b5d9e17ecfdb02b678cca31280639255ce9d0e5aa67af0", size = 52849 }, + { url = "https://files.pythonhosted.org/packages/3a/c8/76f23bf9ab15d5f760eb48701909645f686f9c64fbb8982674c241fbef14/frozenlist-1.5.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1431d60b36d15cda188ea222033eec8e0eab488f39a272461f2e6d9e1a8e63c2", size = 50583 }, + { url = "https://files.pythonhosted.org/packages/1f/22/462a3dd093d11df623179d7754a3b3269de3b42de2808cddef50ee0f4f48/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6482a5851f5d72767fbd0e507e80737f9c8646ae7fd303def99bfe813f76cf7f", size = 265636 }, + { url = "https://files.pythonhosted.org/packages/80/cf/e075e407fc2ae7328155a1cd7e22f932773c8073c1fc78016607d19cc3e5/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44c49271a937625619e862baacbd037a7ef86dd1ee215afc298a417ff3270608", size = 270214 }, + { url = "https://files.pythonhosted.org/packages/a1/58/0642d061d5de779f39c50cbb00df49682832923f3d2ebfb0fedf02d05f7f/frozenlist-1.5.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:12f78f98c2f1c2429d42e6a485f433722b0061d5c0b0139efa64f396efb5886b", size = 273905 }, + { url = "https://files.pythonhosted.org/packages/ab/66/3fe0f5f8f2add5b4ab7aa4e199f767fd3b55da26e3ca4ce2cc36698e50c4/frozenlist-1.5.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ce3aa154c452d2467487765e3adc730a8c153af77ad84096bc19ce19a2400840", size = 250542 }, + { url = "https://files.pythonhosted.org/packages/f6/b8/260791bde9198c87a465224e0e2bb62c4e716f5d198fc3a1dacc4895dbd1/frozenlist-1.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b7dc0c4338e6b8b091e8faf0db3168a37101943e687f373dce00959583f7439", size = 267026 }, + { url = "https://files.pythonhosted.org/packages/2e/a4/3d24f88c527f08f8d44ade24eaee83b2627793fa62fa07cbb7ff7a2f7d42/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:45e0896250900b5aa25180f9aec243e84e92ac84bd4a74d9ad4138ef3f5c97de", size = 257690 }, + { url = "https://files.pythonhosted.org/packages/de/9a/d311d660420b2beeff3459b6626f2ab4fb236d07afbdac034a4371fe696e/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:561eb1c9579d495fddb6da8959fd2a1fca2c6d060d4113f5844b433fc02f2641", size = 253893 }, + { url = "https://files.pythonhosted.org/packages/c6/23/e491aadc25b56eabd0f18c53bb19f3cdc6de30b2129ee0bc39cd387cd560/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:df6e2f325bfee1f49f81aaac97d2aa757c7646534a06f8f577ce184afe2f0a9e", size = 267006 }, + { url = "https://files.pythonhosted.org/packages/08/c4/ab918ce636a35fb974d13d666dcbe03969592aeca6c3ab3835acff01f79c/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:140228863501b44b809fb39ec56b5d4071f4d0aa6d216c19cbb08b8c5a7eadb9", size = 276157 }, + { url = "https://files.pythonhosted.org/packages/c0/29/3b7a0bbbbe5a34833ba26f686aabfe982924adbdcafdc294a7a129c31688/frozenlist-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7707a25d6a77f5d27ea7dc7d1fc608aa0a478193823f88511ef5e6b8a48f9d03", size = 264642 }, + { url = "https://files.pythonhosted.org/packages/ab/42/0595b3dbffc2e82d7fe658c12d5a5bafcd7516c6bf2d1d1feb5387caa9c1/frozenlist-1.5.0-cp313-cp313-win32.whl", hash = "sha256:31a9ac2b38ab9b5a8933b693db4939764ad3f299fcaa931a3e605bc3460e693c", size = 44914 }, + { url = "https://files.pythonhosted.org/packages/17/c4/b7db1206a3fea44bf3b838ca61deb6f74424a8a5db1dd53ecb21da669be6/frozenlist-1.5.0-cp313-cp313-win_amd64.whl", hash = "sha256:11aabdd62b8b9c4b84081a3c246506d1cddd2dd93ff0ad53ede5defec7886b28", size = 51167 }, + { url = "https://files.pythonhosted.org/packages/c6/c8/a5be5b7550c10858fcf9b0ea054baccab474da77d37f1e828ce043a3a5d4/frozenlist-1.5.0-py3-none-any.whl", hash = "sha256:d994863bba198a4a518b467bb971c56e1db3f180a25c6cf7bb1949c267f748c3", size = 11901 }, +] + +[[package]] +name = "gotrue" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx", extra = ["http2"] }, + { name = "pydantic" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/4e/52c5e1a360fd0e67e0cc4512cb663613473b198974de6ae9e0aaeabff471/gotrue-2.10.0.tar.gz", hash = "sha256:4edf4c251da3535f2b044e23deba221e848ca1210c17d0c7a9b19f79a1e3f3c0", size = 41364 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/03/06/dd3dfbb7722d0d8dfdce6b7c76695dfb4ea968dae4e46655f0d5310e27e1/gotrue-2.10.0-py3-none-any.whl", hash = "sha256:768e58207488e5184ffbdc4351b7280d913daf97962f4e9f2cca05c80004b042", size = 48596 }, +] + +[[package]] +name = "greenlet" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235 }, + { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168 }, + { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826 }, + { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443 }, + { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295 }, + { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544 }, + { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456 }, + { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111 }, + { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392 }, + { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479 }, + { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404 }, + { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813 }, + { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517 }, + { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831 }, + { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413 }, + { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619 }, + { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198 }, + { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930 }, + { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, + { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, + { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, + { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, + { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, + { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, + { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, + { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, + { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, + { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, + { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, + { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, + { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, + { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, + { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, + { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, + { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, + { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, + { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, + { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, + { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, + { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, + { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, + { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, + { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "h2" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack" }, + { name = "hyperframe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/32/fec683ddd10629ea4ea46d206752a95a2d8a48c22521edd70b142488efe1/h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb", size = 2145593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e5/db6d438da759efbb488c4f3fbdab7764492ff3c3f953132efa6b9f0e9e53/h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", size = 57488 }, +] + +[[package]] +name = "hpack" +version = "4.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3e/9b/fda93fb4d957db19b0f6b370e79d586b3e8528b20252c729c476a2c02954/hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095", size = 49117 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/34/e8b383f35b77c402d28563d2b8f83159319b509bc5f760b15d60b0abf165/hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", size = 32611 }, +] + +[[package]] +name = "httpcore" +version = "1.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b6/44/ed0fa6a17845fb033bd885c03e842f08c1b9406c86a2e60ac1ae1b9206a6/httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f", size = 85180 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/06/89/b161908e2f51be56568184aeb4a880fd287178d176fd1c860d2217f41106/httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", size = 78011 }, +] + +[[package]] +name = "httpx" +version = "0.27.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, + { name = "sniffio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, +] + +[package.optional-dependencies] +http2 = [ + { name = "h2" }, +] + +[[package]] +name = "hyperframe" +version = "6.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/2a/4747bff0a17f7281abe73e955d60d80aae537a5d203f417fa1c2e7578ebb/hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914", size = 25008 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/de/85a784bcc4a3779d1753a7ec2dee5de90e18c7bcf402e71b51fcf150b129/hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", size = 12389 }, +] + +[[package]] +name = "identify" +version = "2.6.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/79/7a520fc5011e02ca3f3285b5f6820eaf80443eb73e3733f73c02fb42ba0b/identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd", size = 99113 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/86/c4395700f3c5475424fb5c41e20c16be28d10c904aee4d005ba3217fc8e7/identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3", size = 98982 }, +] + +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "mako" +version = "1.3.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fa/0b/29bc5a230948bf209d3ed3165006d257e547c02c3c2a96f6286320dfe8dc/mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d", size = 390206 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/22/bc14c6f02e6dccaafb3eba95764c8f096714260c2aa5f76f654fd16a23dd/Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a", size = 78557 }, +] + +[[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 } +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, +] + +[[package]] +name = "multidict" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/be/504b89a5e9ca731cd47487e91c469064f8ae5af93b7259758dcfc2b9c848/multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a", size = 64002 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/29/68/259dee7fd14cf56a17c554125e534f6274c2860159692a414d0b402b9a6d/multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60", size = 48628 }, + { url = "https://files.pythonhosted.org/packages/50/79/53ba256069fe5386a4a9e80d4e12857ced9de295baf3e20c68cdda746e04/multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1", size = 29327 }, + { url = "https://files.pythonhosted.org/packages/ff/10/71f1379b05b196dae749b5ac062e87273e3f11634f447ebac12a571d90ae/multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53", size = 29689 }, + { url = "https://files.pythonhosted.org/packages/71/45/70bac4f87438ded36ad4793793c0095de6572d433d98575a5752629ef549/multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5", size = 126639 }, + { url = "https://files.pythonhosted.org/packages/80/cf/17f35b3b9509b4959303c05379c4bfb0d7dd05c3306039fc79cf035bbac0/multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581", size = 134315 }, + { url = "https://files.pythonhosted.org/packages/ef/1f/652d70ab5effb33c031510a3503d4d6efc5ec93153562f1ee0acdc895a57/multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56", size = 129471 }, + { url = "https://files.pythonhosted.org/packages/a6/64/2dd6c4c681688c0165dea3975a6a4eab4944ea30f35000f8b8af1df3148c/multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429", size = 124585 }, + { url = "https://files.pythonhosted.org/packages/87/56/e6ee5459894c7e554b57ba88f7257dc3c3d2d379cb15baaa1e265b8c6165/multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748", size = 116957 }, + { url = "https://files.pythonhosted.org/packages/36/9e/616ce5e8d375c24b84f14fc263c7ef1d8d5e8ef529dbc0f1df8ce71bb5b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db", size = 128609 }, + { url = "https://files.pythonhosted.org/packages/8c/4f/4783e48a38495d000f2124020dc96bacc806a4340345211b1ab6175a6cb4/multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056", size = 123016 }, + { url = "https://files.pythonhosted.org/packages/3e/b3/4950551ab8fc39862ba5e9907dc821f896aa829b4524b4deefd3e12945ab/multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76", size = 133542 }, + { url = "https://files.pythonhosted.org/packages/96/4d/f0ce6ac9914168a2a71df117935bb1f1781916acdecbb43285e225b484b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160", size = 130163 }, + { url = "https://files.pythonhosted.org/packages/be/72/17c9f67e7542a49dd252c5ae50248607dfb780bcc03035907dafefb067e3/multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7", size = 126832 }, + { url = "https://files.pythonhosted.org/packages/71/9f/72d719e248cbd755c8736c6d14780533a1606ffb3fbb0fbd77da9f0372da/multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0", size = 26402 }, + { url = "https://files.pythonhosted.org/packages/04/5a/d88cd5d00a184e1ddffc82aa2e6e915164a6d2641ed3606e766b5d2f275a/multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d", size = 28800 }, + { url = "https://files.pythonhosted.org/packages/93/13/df3505a46d0cd08428e4c8169a196131d1b0c4b515c3649829258843dde6/multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6", size = 48570 }, + { url = "https://files.pythonhosted.org/packages/f0/e1/a215908bfae1343cdb72f805366592bdd60487b4232d039c437fe8f5013d/multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156", size = 29316 }, + { url = "https://files.pythonhosted.org/packages/70/0f/6dc70ddf5d442702ed74f298d69977f904960b82368532c88e854b79f72b/multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb", size = 29640 }, + { url = "https://files.pythonhosted.org/packages/d8/6d/9c87b73a13d1cdea30b321ef4b3824449866bd7f7127eceed066ccb9b9ff/multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b", size = 131067 }, + { url = "https://files.pythonhosted.org/packages/cc/1e/1b34154fef373371fd6c65125b3d42ff5f56c7ccc6bfff91b9b3c60ae9e0/multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72", size = 138507 }, + { url = "https://files.pythonhosted.org/packages/fb/e0/0bc6b2bac6e461822b5f575eae85da6aae76d0e2a79b6665d6206b8e2e48/multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304", size = 133905 }, + { url = "https://files.pythonhosted.org/packages/ba/af/73d13b918071ff9b2205fcf773d316e0f8fefb4ec65354bbcf0b10908cc6/multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351", size = 129004 }, + { url = "https://files.pythonhosted.org/packages/74/21/23960627b00ed39643302d81bcda44c9444ebcdc04ee5bedd0757513f259/multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb", size = 121308 }, + { url = "https://files.pythonhosted.org/packages/8b/5c/cf282263ffce4a596ed0bb2aa1a1dddfe1996d6a62d08842a8d4b33dca13/multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3", size = 132608 }, + { url = "https://files.pythonhosted.org/packages/d7/3e/97e778c041c72063f42b290888daff008d3ab1427f5b09b714f5a8eff294/multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399", size = 127029 }, + { url = "https://files.pythonhosted.org/packages/47/ac/3efb7bfe2f3aefcf8d103e9a7162572f01936155ab2f7ebcc7c255a23212/multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423", size = 137594 }, + { url = "https://files.pythonhosted.org/packages/42/9b/6c6e9e8dc4f915fc90a9b7798c44a30773dea2995fdcb619870e705afe2b/multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3", size = 134556 }, + { url = "https://files.pythonhosted.org/packages/1d/10/8e881743b26aaf718379a14ac58572a240e8293a1c9d68e1418fb11c0f90/multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753", size = 130993 }, + { url = "https://files.pythonhosted.org/packages/45/84/3eb91b4b557442802d058a7579e864b329968c8d0ea57d907e7023c677f2/multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80", size = 26405 }, + { url = "https://files.pythonhosted.org/packages/9f/0b/ad879847ecbf6d27e90a6eabb7eff6b62c129eefe617ea45eae7c1f0aead/multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926", size = 28795 }, + { url = "https://files.pythonhosted.org/packages/fd/16/92057c74ba3b96d5e211b553895cd6dc7cc4d1e43d9ab8fafc727681ef71/multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa", size = 48713 }, + { url = "https://files.pythonhosted.org/packages/94/3d/37d1b8893ae79716179540b89fc6a0ee56b4a65fcc0d63535c6f5d96f217/multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436", size = 29516 }, + { url = "https://files.pythonhosted.org/packages/a2/12/adb6b3200c363062f805275b4c1e656be2b3681aada66c80129932ff0bae/multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761", size = 29557 }, + { url = "https://files.pythonhosted.org/packages/47/e9/604bb05e6e5bce1e6a5cf80a474e0f072e80d8ac105f1b994a53e0b28c42/multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e", size = 130170 }, + { url = "https://files.pythonhosted.org/packages/7e/13/9efa50801785eccbf7086b3c83b71a4fb501a4d43549c2f2f80b8787d69f/multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef", size = 134836 }, + { url = "https://files.pythonhosted.org/packages/bf/0f/93808b765192780d117814a6dfcc2e75de6dcc610009ad408b8814dca3ba/multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95", size = 133475 }, + { url = "https://files.pythonhosted.org/packages/d3/c8/529101d7176fe7dfe1d99604e48d69c5dfdcadb4f06561f465c8ef12b4df/multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925", size = 131049 }, + { url = "https://files.pythonhosted.org/packages/ca/0c/fc85b439014d5a58063e19c3a158a889deec399d47b5269a0f3b6a2e28bc/multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966", size = 120370 }, + { url = "https://files.pythonhosted.org/packages/db/46/d4416eb20176492d2258fbd47b4abe729ff3b6e9c829ea4236f93c865089/multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305", size = 125178 }, + { url = "https://files.pythonhosted.org/packages/5b/46/73697ad7ec521df7de5531a32780bbfd908ded0643cbe457f981a701457c/multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2", size = 119567 }, + { url = "https://files.pythonhosted.org/packages/cd/ed/51f060e2cb0e7635329fa6ff930aa5cffa17f4c7f5c6c3ddc3500708e2f2/multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2", size = 129822 }, + { url = "https://files.pythonhosted.org/packages/df/9e/ee7d1954b1331da3eddea0c4e08d9142da5f14b1321c7301f5014f49d492/multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6", size = 128656 }, + { url = "https://files.pythonhosted.org/packages/77/00/8538f11e3356b5d95fa4b024aa566cde7a38aa7a5f08f4912b32a037c5dc/multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3", size = 125360 }, + { url = "https://files.pythonhosted.org/packages/be/05/5d334c1f2462d43fec2363cd00b1c44c93a78c3925d952e9a71caf662e96/multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133", size = 26382 }, + { url = "https://files.pythonhosted.org/packages/a3/bf/f332a13486b1ed0496d624bcc7e8357bb8053823e8cd4b9a18edc1d97e73/multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1", size = 28529 }, + { url = "https://files.pythonhosted.org/packages/22/67/1c7c0f39fe069aa4e5d794f323be24bf4d33d62d2a348acdb7991f8f30db/multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008", size = 48771 }, + { url = "https://files.pythonhosted.org/packages/3c/25/c186ee7b212bdf0df2519eacfb1981a017bda34392c67542c274651daf23/multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f", size = 29533 }, + { url = "https://files.pythonhosted.org/packages/67/5e/04575fd837e0958e324ca035b339cea174554f6f641d3fb2b4f2e7ff44a2/multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28", size = 29595 }, + { url = "https://files.pythonhosted.org/packages/d3/b2/e56388f86663810c07cfe4a3c3d87227f3811eeb2d08450b9e5d19d78876/multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b", size = 130094 }, + { url = "https://files.pythonhosted.org/packages/6c/ee/30ae9b4186a644d284543d55d491fbd4239b015d36b23fea43b4c94f7052/multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c", size = 134876 }, + { url = "https://files.pythonhosted.org/packages/84/c7/70461c13ba8ce3c779503c70ec9d0345ae84de04521c1f45a04d5f48943d/multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3", size = 133500 }, + { url = "https://files.pythonhosted.org/packages/4a/9f/002af221253f10f99959561123fae676148dd730e2daa2cd053846a58507/multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44", size = 131099 }, + { url = "https://files.pythonhosted.org/packages/82/42/d1c7a7301d52af79d88548a97e297f9d99c961ad76bbe6f67442bb77f097/multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2", size = 120403 }, + { url = "https://files.pythonhosted.org/packages/68/f3/471985c2c7ac707547553e8f37cff5158030d36bdec4414cb825fbaa5327/multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3", size = 125348 }, + { url = "https://files.pythonhosted.org/packages/67/2c/e6df05c77e0e433c214ec1d21ddd203d9a4770a1f2866a8ca40a545869a0/multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa", size = 119673 }, + { url = "https://files.pythonhosted.org/packages/c5/cd/bc8608fff06239c9fb333f9db7743a1b2eafe98c2666c9a196e867a3a0a4/multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa", size = 129927 }, + { url = "https://files.pythonhosted.org/packages/44/8e/281b69b7bc84fc963a44dc6e0bbcc7150e517b91df368a27834299a526ac/multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4", size = 128711 }, + { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519 }, + { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426 }, + { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531 }, + { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, +] + +[[package]] +name = "mypy" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, + { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, + { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, + { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, + { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, + { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, + { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, + { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, + { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, + { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, + { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, + { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, + { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, + { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, + { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, + { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, + { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, + { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, + { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, + { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "postgrest" +version = "0.18.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecation" }, + { name = "httpx", extra = ["http2"] }, + { name = "pydantic" }, + { name = "strenum", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/f1/4e02f36b8b1b0fbac55607d0d650913dd3fc05c82cc8fbcb899e46c54e91/postgrest-0.18.0.tar.gz", hash = "sha256:29c1a94801a17eb9ad590189993fe5a7a6d8c1bfc11a3c9d0ce7ba146454ebb3", size = 14693 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/c5/3d476b885230325269befd6d985256e8a1398e7dbea2185965e7524e0bba/postgrest-0.18.0-py3-none-any.whl", hash = "sha256:200baad0d23fee986b3a0ffd3e07bfe0cdd40e09760f11e8e13a6c0c2376d5fa", size = 21771 }, +] + +[[package]] +name = "pre-commit" +version = "4.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, +] + +[[package]] +name = "propcache" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/08/1963dfb932b8d74d5b09098507b37e9b96c835ba89ab8aad35aa330f4ff3/propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", size = 80712 }, + { url = "https://files.pythonhosted.org/packages/e6/59/49072aba9bf8a8ed958e576182d46f038e595b17ff7408bc7e8807e721e1/propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", size = 46301 }, + { url = "https://files.pythonhosted.org/packages/33/a2/6b1978c2e0d80a678e2c483f45e5443c15fe5d32c483902e92a073314ef1/propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", size = 45581 }, + { url = "https://files.pythonhosted.org/packages/43/95/55acc9adff8f997c7572f23d41993042290dfb29e404cdadb07039a4386f/propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", size = 208659 }, + { url = "https://files.pythonhosted.org/packages/bd/2c/ef7371ff715e6cd19ea03fdd5637ecefbaa0752fee5b0f2fe8ea8407ee01/propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", size = 222613 }, + { url = "https://files.pythonhosted.org/packages/5e/1c/fef251f79fd4971a413fa4b1ae369ee07727b4cc2c71e2d90dfcde664fbb/propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", size = 221067 }, + { url = "https://files.pythonhosted.org/packages/8d/e7/22e76ae6fc5a1708bdce92bdb49de5ebe89a173db87e4ef597d6bbe9145a/propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", size = 208920 }, + { url = "https://files.pythonhosted.org/packages/04/3e/f10aa562781bcd8a1e0b37683a23bef32bdbe501d9cc7e76969becaac30d/propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", size = 200050 }, + { url = "https://files.pythonhosted.org/packages/d0/98/8ac69f638358c5f2a0043809c917802f96f86026e86726b65006830f3dc6/propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", size = 202346 }, + { url = "https://files.pythonhosted.org/packages/ee/78/4acfc5544a5075d8e660af4d4e468d60c418bba93203d1363848444511ad/propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", size = 199750 }, + { url = "https://files.pythonhosted.org/packages/a2/8f/90ada38448ca2e9cf25adc2fe05d08358bda1b9446f54a606ea38f41798b/propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", size = 201279 }, + { url = "https://files.pythonhosted.org/packages/08/31/0e299f650f73903da851f50f576ef09bfffc8e1519e6a2f1e5ed2d19c591/propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", size = 211035 }, + { url = "https://files.pythonhosted.org/packages/85/3e/e356cc6b09064bff1c06d0b2413593e7c925726f0139bc7acef8a21e87a8/propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", size = 215565 }, + { url = "https://files.pythonhosted.org/packages/8b/54/4ef7236cd657e53098bd05aa59cbc3cbf7018fba37b40eaed112c3921e51/propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", size = 207604 }, + { url = "https://files.pythonhosted.org/packages/1f/27/d01d7799c068443ee64002f0655d82fb067496897bf74b632e28ee6a32cf/propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", size = 40526 }, + { url = "https://files.pythonhosted.org/packages/bb/44/6c2add5eeafb7f31ff0d25fbc005d930bea040a1364cf0f5768750ddf4d1/propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", size = 44958 }, + { url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811 }, + { url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365 }, + { url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602 }, + { url = "https://files.pythonhosted.org/packages/2e/5e/4a3e96380805bf742712e39a4534689f4cddf5fa2d3a93f22e9fd8001b23/propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", size = 236161 }, + { url = "https://files.pythonhosted.org/packages/a5/85/90132481183d1436dff6e29f4fa81b891afb6cb89a7306f32ac500a25932/propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", size = 244938 }, + { url = "https://files.pythonhosted.org/packages/4a/89/c893533cb45c79c970834274e2d0f6d64383ec740be631b6a0a1d2b4ddc0/propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", size = 243576 }, + { url = "https://files.pythonhosted.org/packages/8c/56/98c2054c8526331a05f205bf45cbb2cda4e58e56df70e76d6a509e5d6ec6/propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", size = 236011 }, + { url = "https://files.pythonhosted.org/packages/2d/0c/8b8b9f8a6e1abd869c0fa79b907228e7abb966919047d294ef5df0d136cf/propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504", size = 224834 }, + { url = "https://files.pythonhosted.org/packages/18/bb/397d05a7298b7711b90e13108db697732325cafdcd8484c894885c1bf109/propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", size = 224946 }, + { url = "https://files.pythonhosted.org/packages/25/19/4fc08dac19297ac58135c03770b42377be211622fd0147f015f78d47cd31/propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", size = 217280 }, + { url = "https://files.pythonhosted.org/packages/7e/76/c79276a43df2096ce2aba07ce47576832b1174c0c480fe6b04bd70120e59/propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", size = 220088 }, + { url = "https://files.pythonhosted.org/packages/c3/9a/8a8cf428a91b1336b883f09c8b884e1734c87f724d74b917129a24fe2093/propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", size = 233008 }, + { url = "https://files.pythonhosted.org/packages/25/7b/768a8969abd447d5f0f3333df85c6a5d94982a1bc9a89c53c154bf7a8b11/propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", size = 237719 }, + { url = "https://files.pythonhosted.org/packages/ed/0d/e5d68ccc7976ef8b57d80613ac07bbaf0614d43f4750cf953f0168ef114f/propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", size = 227729 }, + { url = "https://files.pythonhosted.org/packages/05/64/17eb2796e2d1c3d0c431dc5f40078d7282f4645af0bb4da9097fbb628c6c/propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", size = 40473 }, + { url = "https://files.pythonhosted.org/packages/83/c5/e89fc428ccdc897ade08cd7605f174c69390147526627a7650fb883e0cd0/propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", size = 44921 }, + { url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800 }, + { url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443 }, + { url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676 }, + { url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191 }, + { url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791 }, + { url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434 }, + { url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150 }, + { url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568 }, + { url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874 }, + { url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857 }, + { url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604 }, + { url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430 }, + { url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814 }, + { url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922 }, + { url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177 }, + { url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446 }, + { url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120 }, + { url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127 }, + { url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419 }, + { url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611 }, + { url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005 }, + { url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270 }, + { url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877 }, + { url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848 }, + { url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987 }, + { url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451 }, + { url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879 }, + { url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288 }, + { url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257 }, + { url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075 }, + { url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654 }, + { url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705 }, + { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 }, +] + +[[package]] +name = "pydantic" +version = "2.9.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types" }, + { name = "pydantic-core" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, +] + +[package.optional-dependencies] +email = [ + { name = "email-validator" }, +] + +[[package]] +name = "pydantic-core" +version = "2.23.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, + { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, + { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, + { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, + { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, + { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, + { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, + { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, + { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, + { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, + { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, + { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, + { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, + { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, + { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, + { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, + { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, + { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, + { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, + { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, + { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, + { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, + { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, + { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, + { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, + { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, + { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, + { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, + { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, + { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, + { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, + { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, + { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, + { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, + { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, + { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, + { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, + { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, + { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, + { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, + { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, + { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, + { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, + { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, + { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, + { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, + { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, + { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, + { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, + { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, + { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, + { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, + { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, + { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, + { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +] + +[[package]] +name = "pydantic-settings" +version = "2.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "python-dotenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/d4/9dfbe238f45ad8b168f5c96ee49a3df0598ce18a0795a983b419949ce65b/pydantic_settings-2.6.1.tar.gz", hash = "sha256:e0f92546d8a9923cb8941689abf85d6601a8c19a23e97a34b2964a2e3f813ca0", size = 75646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/f9/ff95fd7d760af42f647ea87f9b8a383d891cdb5e5dbd4613edaeb094252a/pydantic_settings-2.6.1-py3-none-any.whl", hash = "sha256:7fb0637c786a558d3103436278a7c4f1cfd29ba8973238a50c5bb9a55387da87", size = 28595 }, +] + +[[package]] +name = "pytest" +version = "8.3.3" +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 = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, +] + +[[package]] +name = "pytest-sugar" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "packaging" }, + { name = "pytest" }, + { name = "termcolor" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/ac/5754f5edd6d508bc6493bc37d74b928f102a5fff82d9a80347e180998f08/pytest-sugar-1.0.0.tar.gz", hash = "sha256:6422e83258f5b0c04ce7c632176c7732cab5fdb909cb39cca5c9139f81276c0a", size = 14992 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/fb/889f1b69da2f13691de09a111c16c4766a433382d44aa0ecf221deded44a/pytest_sugar-1.0.0-py3-none-any.whl", hash = "sha256:70ebcd8fc5795dc457ff8b69d266a4e2e8a74ae0c3edc749381c64b5246c8dfd", size = 10171 }, +] + +[[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 } +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 }, +] + +[[package]] +name = "python-dotenv" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, +] + +[[package]] +name = "python-multipart" +version = "0.0.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/40/22/edea41c2d4a22e666c0c7db7acdcbf7bc8c1c1f7d3b3ca246ec982fec612/python_multipart-0.0.17.tar.gz", hash = "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538", size = 36452 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/fb/275137a799169392f1fa88fff2be92f16eee38e982720a8aaadefc4a36b2/python_multipart-0.0.17-py3-none-any.whl", hash = "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d", size = 24453 }, +] + +[[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 } +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, +] + +[[package]] +name = "realtime" +version = "2.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "python-dateutil" }, + { name = "typing-extensions" }, + { name = "websockets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/7d/07f006df098c5fc9e00488e5268bcd7af0ee30a65fd6dfdbcee17ffeaa3b/realtime-2.0.6.tar.gz", hash = "sha256:ced37686a77a546571029ecc74cfb31fff1404a5159d1198fa882af545843a6f", size = 17463 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/fc/47a6615db976d5417ad982a15983cb3750910e0672d2e7e2d620433cdb2f/realtime-2.0.6-py3-none-any.whl", hash = "sha256:9aab6009c11883197386a0a9dc8c2b6939e62dddda734cfb77594727ac9ae0ce", size = 20568 }, +] + +[[package]] +name = "six" +version = "1.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.36" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/50/65/9cbc9c4c3287bed2499e05033e207473504dc4df999ce49385fb1f8b058a/sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", size = 9574485 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/72/14ab694b8b3f0e35ef5beb74a8fea2811aa791ba1611c44dc90cdf46af17/SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", size = 2092604 }, + { url = "https://files.pythonhosted.org/packages/1e/59/333fcbca58b79f5b8b61853d6137530198823392151fa8fd9425f367519e/SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", size = 2083796 }, + { url = "https://files.pythonhosted.org/packages/6c/a0/ec3c188d2b0c1bc742262e76408d44104598d7247c23f5b06bb97ee21bfa/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", size = 3066165 }, + { url = "https://files.pythonhosted.org/packages/07/15/68ef91de5b8b7f80fb2d2b3b31ed42180c6227fe0a701aed9d01d34f98ec/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", size = 3074428 }, + { url = "https://files.pythonhosted.org/packages/e2/4c/9dfea5e63b87325eef6d9cdaac913459aa6a157a05a05ea6ff20004aee8e/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", size = 3030477 }, + { url = "https://files.pythonhosted.org/packages/16/a5/fcfde8e74ea5f683b24add22463bfc21e431d4a5531c8a5b55bc6fbea164/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", size = 3055942 }, + { url = "https://files.pythonhosted.org/packages/3c/ee/c22c415a771d791ae99146d72ffdb20e43625acd24835ea7fc157436d59f/SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", size = 2064960 }, + { url = "https://files.pythonhosted.org/packages/aa/af/ad9c25cadc79bd851bdb9d82b68af9bdb91ff05f56d0da2f8a654825974f/SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", size = 2089078 }, + { url = "https://files.pythonhosted.org/packages/00/4e/5a67963fd7cbc1beb8bd2152e907419f4c940ef04600b10151a751fe9e06/SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", size = 2093782 }, + { url = "https://files.pythonhosted.org/packages/b3/24/30e33b6389ebb5a17df2a4243b091bc709fb3dfc9a48c8d72f8e037c943d/SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", size = 2084180 }, + { url = "https://files.pythonhosted.org/packages/10/1e/70e9ed2143a27065246be40f78637ad5160ea0f5fd32f8cab819a31ff54d/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", size = 3202469 }, + { url = "https://files.pythonhosted.org/packages/b4/5f/95e0ed74093ac3c0db6acfa944d4d8ac6284ef5e1136b878a327ea1f975a/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", size = 3202464 }, + { url = "https://files.pythonhosted.org/packages/91/95/2cf9b85a6bc2ee660e40594dffe04e777e7b8617fd0c6d77a0f782ea96c9/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", size = 3139508 }, + { url = "https://files.pythonhosted.org/packages/92/ea/f0c01bc646456e4345c0fb5a3ddef457326285c2dc60435b0eb96b61bf31/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", size = 3159837 }, + { url = "https://files.pythonhosted.org/packages/a6/93/c8edbf153ee38fe529773240877bf1332ed95328aceef6254288f446994e/SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", size = 2064529 }, + { url = "https://files.pythonhosted.org/packages/b1/03/d12b7c1d36fd80150c1d52e121614cf9377dac99e5497af8d8f5b2a8db64/SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", size = 2089874 }, + { url = "https://files.pythonhosted.org/packages/b8/bf/005dc47f0e57556e14512d5542f3f183b94fde46e15ff1588ec58ca89555/SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", size = 2092378 }, + { url = "https://files.pythonhosted.org/packages/94/65/f109d5720779a08e6e324ec89a744f5f92c48bd8005edc814bf72fbb24e5/SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", size = 2082778 }, + { url = "https://files.pythonhosted.org/packages/60/f6/d9aa8c49c44f9b8c9b9dada1f12fa78df3d4c42aa2de437164b83ee1123c/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53", size = 3232191 }, + { url = "https://files.pythonhosted.org/packages/8a/ab/81d4514527c068670cb1d7ab62a81a185df53a7c379bd2a5636e83d09ede/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", size = 3243044 }, + { url = "https://files.pythonhosted.org/packages/35/b4/f87c014ecf5167dc669199cafdb20a7358ff4b1d49ce3622cc48571f811c/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", size = 3178511 }, + { url = "https://files.pythonhosted.org/packages/ea/09/badfc9293bc3ccba6ede05e5f2b44a760aa47d84da1fc5a326e963e3d4d9/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", size = 3205147 }, + { url = "https://files.pythonhosted.org/packages/c8/60/70e681de02a13c4b27979b7b78da3058c49bacc9858c89ba672e030f03f2/SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", size = 2062709 }, + { url = "https://files.pythonhosted.org/packages/b7/ed/f6cd9395e41bfe47dd253d74d2dfc3cab34980d4e20c8878cb1117306085/SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", size = 2088433 }, + { url = "https://files.pythonhosted.org/packages/78/5c/236398ae3678b3237726819b484f15f5c038a9549da01703a771f05a00d6/SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", size = 2087651 }, + { url = "https://files.pythonhosted.org/packages/a8/14/55c47420c0d23fb67a35af8be4719199b81c59f3084c28d131a7767b0b0b/SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", size = 2078132 }, + { url = "https://files.pythonhosted.org/packages/3d/97/1e843b36abff8c4a7aa2e37f9bea364f90d021754c2de94d792c2d91405b/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", size = 3164559 }, + { url = "https://files.pythonhosted.org/packages/7b/c5/07f18a897b997f6d6b234fab2bf31dccf66d5d16a79fe329aefc95cd7461/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", size = 3177897 }, + { url = "https://files.pythonhosted.org/packages/b3/cd/e16f3cbefd82b5c40b33732da634ec67a5f33b587744c7ab41699789d492/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", size = 3111289 }, + { url = "https://files.pythonhosted.org/packages/15/85/5b8a3b0bc29c9928aa62b5c91fcc8335f57c1de0a6343873b5f372e3672b/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", size = 3139491 }, + { url = "https://files.pythonhosted.org/packages/a1/95/81babb6089938680dfe2cd3f88cd3fd39cccd1543b7cb603b21ad881bff1/SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", size = 2060439 }, + { url = "https://files.pythonhosted.org/packages/c1/ce/5f7428df55660d6879d0522adc73a3364970b5ef33ec17fa125c5dbcac1d/SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", size = 2084574 }, + { url = "https://files.pythonhosted.org/packages/b8/49/21633706dd6feb14cd3f7935fc00b60870ea057686035e1a99ae6d9d9d53/SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", size = 1883787 }, +] + +[[package]] +name = "sqlmodel" +version = "0.0.22" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic" }, + { name = "sqlalchemy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/39/8641040ab0d5e1d8a1c2325ae89a01ae659fc96c61a43d158fb71c9a0bf0/sqlmodel-0.0.22.tar.gz", hash = "sha256:7d37c882a30c43464d143e35e9ecaf945d88035e20117bf5ec2834a23cbe505e", size = 116392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/b1/3af5104b716c420e40a6ea1b09886cae3a1b9f4538343875f637755cae5b/sqlmodel-0.0.22-py3-none-any.whl", hash = "sha256:a1ed13e28a1f4057cbf4ff6cdb4fc09e85702621d3259ba17b3c230bfb2f941b", size = 28276 }, +] + +[[package]] +name = "starlette" +version = "0.41.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3e/da/1fb4bdb72ae12b834becd7e1e7e47001d32f91ec0ce8d7bc1b618d9f0bd9/starlette-0.41.2.tar.gz", hash = "sha256:9834fd799d1a87fd346deb76158668cfa0b0d56f85caefe8268e2d97c3468b62", size = 2573867 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/43/f185bfd0ca1d213beb4293bed51d92254df23d8ceaf6c0e17146d508a776/starlette-0.41.2-py3-none-any.whl", hash = "sha256:fbc189474b4731cf30fcef52f18a8d070e3f3b46c6a04c97579e85e6ffca942d", size = 73259 }, +] + +[[package]] +name = "storage3" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx", extra = ["http2"] }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/e7/8107787c4aa24c435f44f0b0f3332004c82d84c90b6e449d9b3747100687/storage3-0.9.0.tar.gz", hash = "sha256:e16697f60894c94e1d9df0d2e4af783c1b3f7dd08c9013d61978825c624188c4", size = 9031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/2f/ee424eaa9939d1a6a3ae727b24da6c80ab4ef913ee1dc8c4392eebc73a3c/storage3-0.9.0-py3-none-any.whl", hash = "sha256:8b2fb91f0c61583a2f4eac74a8bae67e00d41ff38095c8a6cd3f2ce5e0ab76e7", size = 16175 }, +] + +[[package]] +name = "strenum" +version = "0.4.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/ad/430fb60d90e1d112a62ff57bdd1f286ec73a2a0331272febfddd21f330e1/StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff", size = 23384 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/69/297302c5f5f59c862faa31e6cb9a4cd74721cd1e052b38e464c5b402df8b/StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659", size = 8851 }, +] + +[[package]] +name = "supabase" +version = "2.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gotrue" }, + { name = "httpx" }, + { name = "postgrest" }, + { name = "realtime" }, + { name = "storage3" }, + { name = "supafunc" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7f/31/656c8c271b7da5104d2fcda0d7c53c95c6ba009f5d708f598784efb1573b/supabase-2.10.0.tar.gz", hash = "sha256:9ac095f8947bf60780e67c0edcbab53e2db3f6f3f022329397b093500bf2607c", size = 13909 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/8d/ec1dd5f1e17dd51e358809adfceafa0a78f32f171d33b9cbe38bb5eac8a3/supabase-2.10.0-py3-none-any.whl", hash = "sha256:183fb23c04528593f8f81c24ceb8178f3a56bff40fec7ed873b6c55ebc2e420a", size = 16626 }, +] + +[[package]] +name = "supafunc" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx", extra = ["http2"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/f5/50eae5b8428772fee09e737e9ea958e9d76c04814f72b58d181f8477e730/supafunc-0.7.0.tar.gz", hash = "sha256:5b1c415fba1395740b2b4eedd1d786384bd58b98f6333a11ba7889820a48b6a7", size = 4085 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/26/bc4cd6d19b6290025fe9068df1540a3aab9806daca8b1dd19c0902072a24/supafunc-0.7.0-py3-none-any.whl", hash = "sha256:4160260dc02bdd906be1e2ffd7cb3ae8b74ae437c892bb475352b6a99d9ff8eb", size = 6936 }, +] + +[[package]] +name = "tenacity" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, +] + +[[package]] +name = "termcolor" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/72/88311445fd44c455c7d553e61f95412cf89054308a1aa2434ab835075fc5/termcolor-2.5.0.tar.gz", hash = "sha256:998d8d27da6d48442e8e1f016119076b690d962507531df4890fcd2db2ef8a6f", size = 13057 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/be/df630c387a0a054815d60be6a97eb4e8f17385d5d6fe660e1c02750062b4/termcolor-2.5.0-py3-none-any.whl", hash = "sha256:37b17b5fc1e604945c2642c872a3764b5d547a48009871aea3edd3afa180afb8", size = 7755 }, +] + +[[package]] +name = "tomli" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uvicorn" +version = "0.32.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "h11" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/fc/1d785078eefd6945f3e5bab5c076e4230698046231eb0f3747bc5c8fa992/uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e", size = 77564 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/14/78bd0e95dd2444b6caacbca2b730671d4295ccb628ef58b81bee903629df/uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82", size = 63723 }, +] + +[[package]] +name = "virtualenv" +version = "20.27.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8c/b3/7b6a79c5c8cf6d90ea681310e169cf2db2884f4d583d16c6e1d5a75a4e04/virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", size = 6491145 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/92/78324ff89391e00c8f4cf6b8526c41c6ef36b4ea2d2c132250b1a6fc2b8d/virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4", size = 3117838 }, +] + +[[package]] +name = "websockets" +version = "13.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/73/9223dbc7be3dcaf2a7bbf756c351ec8da04b1fa573edaf545b95f6b0c7fd/websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878", size = 158549 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/94/d15dbfc6a5eb636dbc754303fba18208f2e88cf97e733e1d64fb9cb5c89e/websockets-13.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f48c749857f8fb598fb890a75f540e3221d0976ed0bf879cf3c7eef34151acee", size = 157815 }, + { url = "https://files.pythonhosted.org/packages/30/02/c04af33f4663945a26f5e8cf561eb140c35452b50af47a83c3fbcfe62ae1/websockets-13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c7e72ce6bda6fb9409cc1e8164dd41d7c91466fb599eb047cfda72fe758a34a7", size = 155466 }, + { url = "https://files.pythonhosted.org/packages/35/e8/719f08d12303ea643655e52d9e9851b2dadbb1991d4926d9ce8862efa2f5/websockets-13.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f779498eeec470295a2b1a5d97aa1bc9814ecd25e1eb637bd9d1c73a327387f6", size = 155716 }, + { url = "https://files.pythonhosted.org/packages/91/e1/14963ae0252a8925f7434065d25dcd4701d5e281a0b4b460a3b5963d2594/websockets-13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4676df3fe46956fbb0437d8800cd5f2b6d41143b6e7e842e60554398432cf29b", size = 164806 }, + { url = "https://files.pythonhosted.org/packages/ec/fa/ab28441bae5e682a0f7ddf3d03440c0c352f930da419301f4a717f675ef3/websockets-13.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a7affedeb43a70351bb811dadf49493c9cfd1ed94c9c70095fd177e9cc1541fa", size = 163810 }, + { url = "https://files.pythonhosted.org/packages/44/77/dea187bd9d16d4b91566a2832be31f99a40d0f5bfa55eeb638eb2c3bc33d/websockets-13.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1971e62d2caa443e57588e1d82d15f663b29ff9dfe7446d9964a4b6f12c1e700", size = 164125 }, + { url = "https://files.pythonhosted.org/packages/cf/d9/3af14544e83f1437eb684b399e6ba0fa769438e869bf5d83d74bc197fae8/websockets-13.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5f2e75431f8dc4a47f31565a6e1355fb4f2ecaa99d6b89737527ea917066e26c", size = 164532 }, + { url = "https://files.pythonhosted.org/packages/1c/8a/6d332eabe7d59dfefe4b8ba6f46c8c5fabb15b71c8a8bc3d2b65de19a7b6/websockets-13.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58cf7e75dbf7e566088b07e36ea2e3e2bd5676e22216e4cad108d4df4a7402a0", size = 163948 }, + { url = "https://files.pythonhosted.org/packages/1a/91/a0aeadbaf3017467a1ee03f8fb67accdae233fe2d5ad4b038c0a84e357b0/websockets-13.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90d6dec6be2c7d03378a574de87af9b1efea77d0c52a8301dd831ece938452f", size = 163898 }, + { url = "https://files.pythonhosted.org/packages/71/31/a90fb47c63e0ae605be914b0b969d7c6e6ffe2038cd744798e4b3fbce53b/websockets-13.1-cp310-cp310-win32.whl", hash = "sha256:730f42125ccb14602f455155084f978bd9e8e57e89b569b4d7f0f0c17a448ffe", size = 158706 }, + { url = "https://files.pythonhosted.org/packages/93/ca/9540a9ba80da04dc7f36d790c30cae4252589dbd52ccdc92e75b0be22437/websockets-13.1-cp310-cp310-win_amd64.whl", hash = "sha256:5993260f483d05a9737073be197371940c01b257cc45ae3f1d5d7adb371b266a", size = 159141 }, + { url = "https://files.pythonhosted.org/packages/b2/f0/cf0b8a30d86b49e267ac84addbebbc7a48a6e7bb7c19db80f62411452311/websockets-13.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:61fc0dfcda609cda0fc9fe7977694c0c59cf9d749fbb17f4e9483929e3c48a19", size = 157813 }, + { url = "https://files.pythonhosted.org/packages/bf/e7/22285852502e33071a8cf0ac814f8988480ec6db4754e067b8b9d0e92498/websockets-13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ceec59f59d092c5007e815def4ebb80c2de330e9588e101cf8bd94c143ec78a5", size = 155469 }, + { url = "https://files.pythonhosted.org/packages/68/d4/c8c7c1e5b40ee03c5cc235955b0fb1ec90e7e37685a5f69229ad4708dcde/websockets-13.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c1dca61c6db1166c48b95198c0b7d9c990b30c756fc2923cc66f68d17dc558fd", size = 155717 }, + { url = "https://files.pythonhosted.org/packages/c9/e4/c50999b9b848b1332b07c7fd8886179ac395cb766fda62725d1539e7bc6c/websockets-13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308e20f22c2c77f3f39caca508e765f8725020b84aa963474e18c59accbf4c02", size = 165379 }, + { url = "https://files.pythonhosted.org/packages/bc/49/4a4ad8c072f18fd79ab127650e47b160571aacfc30b110ee305ba25fffc9/websockets-13.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d516c325e6540e8a57b94abefc3459d7dab8ce52ac75c96cad5549e187e3a7", size = 164376 }, + { url = "https://files.pythonhosted.org/packages/af/9b/8c06d425a1d5a74fd764dd793edd02be18cf6fc3b1ccd1f29244ba132dc0/websockets-13.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c6e35319b46b99e168eb98472d6c7d8634ee37750d7693656dc766395df096", size = 164753 }, + { url = "https://files.pythonhosted.org/packages/d5/5b/0acb5815095ff800b579ffc38b13ab1b915b317915023748812d24e0c1ac/websockets-13.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5f9fee94ebafbc3117c30be1844ed01a3b177bb6e39088bc6b2fa1dc15572084", size = 165051 }, + { url = "https://files.pythonhosted.org/packages/30/93/c3891c20114eacb1af09dedfcc620c65c397f4fd80a7009cd12d9457f7f5/websockets-13.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7c1e90228c2f5cdde263253fa5db63e6653f1c00e7ec64108065a0b9713fa1b3", size = 164489 }, + { url = "https://files.pythonhosted.org/packages/28/09/af9e19885539759efa2e2cd29b8b3f9eecef7ecefea40d46612f12138b36/websockets-13.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6548f29b0e401eea2b967b2fdc1c7c7b5ebb3eeb470ed23a54cd45ef078a0db9", size = 164438 }, + { url = "https://files.pythonhosted.org/packages/b6/08/6f38b8e625b3d93de731f1d248cc1493327f16cb45b9645b3e791782cff0/websockets-13.1-cp311-cp311-win32.whl", hash = "sha256:c11d4d16e133f6df8916cc5b7e3e96ee4c44c936717d684a94f48f82edb7c92f", size = 158710 }, + { url = "https://files.pythonhosted.org/packages/fb/39/ec8832ecb9bb04a8d318149005ed8cee0ba4e0205835da99e0aa497a091f/websockets-13.1-cp311-cp311-win_amd64.whl", hash = "sha256:d04f13a1d75cb2b8382bdc16ae6fa58c97337253826dfe136195b7f89f661557", size = 159137 }, + { url = "https://files.pythonhosted.org/packages/df/46/c426282f543b3c0296cf964aa5a7bb17e984f58dde23460c3d39b3148fcf/websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc", size = 157821 }, + { url = "https://files.pythonhosted.org/packages/aa/85/22529867010baac258da7c45848f9415e6cf37fef00a43856627806ffd04/websockets-13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9b6f347deb3dcfbfde1c20baa21c2ac0751afaa73e64e5b693bb2b848efeaa49", size = 155480 }, + { url = "https://files.pythonhosted.org/packages/29/2c/bdb339bfbde0119a6e84af43ebf6275278698a2241c2719afc0d8b0bdbf2/websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd", size = 155715 }, + { url = "https://files.pythonhosted.org/packages/9f/d0/8612029ea04c5c22bf7af2fd3d63876c4eaeef9b97e86c11972a43aa0e6c/websockets-13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1b54689e38d1279a51d11e3467dd2f3a50f5f2e879012ce8f2d6943f00e83f0", size = 165647 }, + { url = "https://files.pythonhosted.org/packages/56/04/1681ed516fa19ca9083f26d3f3a302257e0911ba75009533ed60fbb7b8d1/websockets-13.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cf1781ef73c073e6b0f90af841aaf98501f975d306bbf6221683dd594ccc52b6", size = 164592 }, + { url = "https://files.pythonhosted.org/packages/38/6f/a96417a49c0ed132bb6087e8e39a37db851c70974f5c724a4b2a70066996/websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9", size = 165012 }, + { url = "https://files.pythonhosted.org/packages/40/8b/fccf294919a1b37d190e86042e1a907b8f66cff2b61e9befdbce03783e25/websockets-13.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3c78383585f47ccb0fcf186dcb8a43f5438bd7d8f47d69e0b56f71bf431a0a68", size = 165311 }, + { url = "https://files.pythonhosted.org/packages/c1/61/f8615cf7ce5fe538476ab6b4defff52beb7262ff8a73d5ef386322d9761d/websockets-13.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d6d300f8ec35c24025ceb9b9019ae9040c1ab2f01cddc2bcc0b518af31c75c14", size = 164692 }, + { url = "https://files.pythonhosted.org/packages/5c/f1/a29dd6046d3a722d26f182b783a7997d25298873a14028c4760347974ea3/websockets-13.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a9dcaf8b0cc72a392760bb8755922c03e17a5a54e08cca58e8b74f6902b433cf", size = 164686 }, + { url = "https://files.pythonhosted.org/packages/0f/99/ab1cdb282f7e595391226f03f9b498f52109d25a2ba03832e21614967dfa/websockets-13.1-cp312-cp312-win32.whl", hash = "sha256:2f85cf4f2a1ba8f602298a853cec8526c2ca42a9a4b947ec236eaedb8f2dc80c", size = 158712 }, + { url = "https://files.pythonhosted.org/packages/46/93/e19160db48b5581feac8468330aa11b7292880a94a37d7030478596cc14e/websockets-13.1-cp312-cp312-win_amd64.whl", hash = "sha256:38377f8b0cdeee97c552d20cf1865695fcd56aba155ad1b4ca8779a5b6ef4ac3", size = 159145 }, + { url = "https://files.pythonhosted.org/packages/51/20/2b99ca918e1cbd33c53db2cace5f0c0cd8296fc77558e1908799c712e1cd/websockets-13.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a9ab1e71d3d2e54a0aa646ab6d4eebfaa5f416fe78dfe4da2839525dc5d765c6", size = 157828 }, + { url = "https://files.pythonhosted.org/packages/b8/47/0932a71d3d9c0e9483174f60713c84cee58d62839a143f21a2bcdbd2d205/websockets-13.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b9d7439d7fab4dce00570bb906875734df13d9faa4b48e261c440a5fec6d9708", size = 155487 }, + { url = "https://files.pythonhosted.org/packages/a9/60/f1711eb59ac7a6c5e98e5637fef5302f45b6f76a2c9d64fd83bbb341377a/websockets-13.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:327b74e915cf13c5931334c61e1a41040e365d380f812513a255aa804b183418", size = 155721 }, + { url = "https://files.pythonhosted.org/packages/6a/e6/ba9a8db7f9d9b0e5f829cf626ff32677f39824968317223605a6b419d445/websockets-13.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:325b1ccdbf5e5725fdcb1b0e9ad4d2545056479d0eee392c291c1bf76206435a", size = 165609 }, + { url = "https://files.pythonhosted.org/packages/c1/22/4ec80f1b9c27a0aebd84ccd857252eda8418ab9681eb571b37ca4c5e1305/websockets-13.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:346bee67a65f189e0e33f520f253d5147ab76ae42493804319b5716e46dddf0f", size = 164556 }, + { url = "https://files.pythonhosted.org/packages/27/ac/35f423cb6bb15600438db80755609d27eda36d4c0b3c9d745ea12766c45e/websockets-13.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91a0fa841646320ec0d3accdff5b757b06e2e5c86ba32af2e0815c96c7a603c5", size = 164993 }, + { url = "https://files.pythonhosted.org/packages/31/4e/98db4fd267f8be9e52e86b6ee4e9aa7c42b83452ea0ea0672f176224b977/websockets-13.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18503d2c5f3943e93819238bf20df71982d193f73dcecd26c94514f417f6b135", size = 165360 }, + { url = "https://files.pythonhosted.org/packages/3f/15/3f0de7cda70ffc94b7e7024544072bc5b26e2c1eb36545291abb755d8cdb/websockets-13.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:a9cd1af7e18e5221d2878378fbc287a14cd527fdd5939ed56a18df8a31136bb2", size = 164745 }, + { url = "https://files.pythonhosted.org/packages/a1/6e/66b6b756aebbd680b934c8bdbb6dcb9ce45aad72cde5f8a7208dbb00dd36/websockets-13.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:70c5be9f416aa72aab7a2a76c90ae0a4fe2755c1816c153c1a2bcc3333ce4ce6", size = 164732 }, + { url = "https://files.pythonhosted.org/packages/35/c6/12e3aab52c11aeb289e3dbbc05929e7a9d90d7a9173958477d3ef4f8ce2d/websockets-13.1-cp313-cp313-win32.whl", hash = "sha256:624459daabeb310d3815b276c1adef475b3e6804abaf2d9d2c061c319f7f187d", size = 158709 }, + { url = "https://files.pythonhosted.org/packages/41/d8/63d6194aae711d7263df4498200c690a9c39fb437ede10f3e157a6343e0d/websockets-13.1-cp313-cp313-win_amd64.whl", hash = "sha256:c518e84bb59c2baae725accd355c8dc517b4a3ed8db88b4bc93c78dae2974bf2", size = 159144 }, + { url = "https://files.pythonhosted.org/packages/2d/75/6da22cb3ad5b8c606963f9a5f9f88656256fecc29d420b4b2bf9e0c7d56f/websockets-13.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:5dd6da9bec02735931fccec99d97c29f47cc61f644264eb995ad6c0c27667238", size = 155499 }, + { url = "https://files.pythonhosted.org/packages/c0/ba/22833d58629088fcb2ccccedfae725ac0bbcd713319629e97125b52ac681/websockets-13.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:2510c09d8e8df777177ee3d40cd35450dc169a81e747455cc4197e63f7e7bfe5", size = 155737 }, + { url = "https://files.pythonhosted.org/packages/95/54/61684fe22bdb831e9e1843d972adadf359cf04ab8613285282baea6a24bb/websockets-13.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1c3cf67185543730888b20682fb186fc8d0fa6f07ccc3ef4390831ab4b388d9", size = 157095 }, + { url = "https://files.pythonhosted.org/packages/fc/f5/6652fb82440813822022a9301a30afde85e5ff3fb2aebb77f34aabe2b4e8/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bcc03c8b72267e97b49149e4863d57c2d77f13fae12066622dc78fe322490fe6", size = 156701 }, + { url = "https://files.pythonhosted.org/packages/67/33/ae82a7b860fa8a08aba68818bdf7ff61f04598aa5ab96df4cd5a3e418ca4/websockets-13.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:004280a140f220c812e65f36944a9ca92d766b6cc4560be652a0a3883a79ed8a", size = 156654 }, + { url = "https://files.pythonhosted.org/packages/63/0b/a1b528d36934f833e20f6da1032b995bf093d55cb416b9f2266f229fb237/websockets-13.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:e2620453c075abeb0daa949a292e19f56de518988e079c36478bacf9546ced23", size = 159192 }, + { url = "https://files.pythonhosted.org/packages/56/27/96a5cd2626d11c8280656c6c71d8ab50fe006490ef9971ccd154e0c42cd2/websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f", size = 152134 }, +] + +[[package]] +name = "yarl" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna" }, + { name = "multidict" }, + { name = "propcache" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/9c/9c0a9bfa683fc1be7fdcd9687635151544d992cccd48892dc5e0a5885a29/yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", size = 178163 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/63/0e1e3626a323f366a8ff8eeb4d2835d403cb505393c2fce00c68c2be9d1a/yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", size = 140627 }, + { url = "https://files.pythonhosted.org/packages/ff/ef/80c92e43f5ca5dfe964f42080252b669097fdd37d40e8c174e5a10d67d2c/yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", size = 93563 }, + { url = "https://files.pythonhosted.org/packages/05/43/add866f8c7e99af126a3ff4a673165537617995a5ae90e86cb95f9a1d4ad/yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", size = 91400 }, + { url = "https://files.pythonhosted.org/packages/b9/44/464aba5761fb7ab448d8854520d98355217481746d2421231b8d07d2de8c/yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", size = 313746 }, + { url = "https://files.pythonhosted.org/packages/c1/0f/3a08d81f1e4ff88b07d62f3bb271603c0e2d063cea12239e500defa800d3/yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", size = 329234 }, + { url = "https://files.pythonhosted.org/packages/7d/0f/98f29b8637cf13d7589bb7a1fdc4357bcfc0cfc3f20bc65a6970b71a22ec/yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", size = 325776 }, + { url = "https://files.pythonhosted.org/packages/3c/8c/f383fc542a3d2a1837fb0543ce698653f1760cc18954c29e6d6d49713376/yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", size = 318659 }, + { url = "https://files.pythonhosted.org/packages/2b/35/742b4a03ca90e116f70a44b24a36d2138f1b1d776a532ddfece4d60cd93d/yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", size = 310172 }, + { url = "https://files.pythonhosted.org/packages/9b/fc/f1aba4194861f44673d9b432310cbee2e7c3ffa8ff9bdf165c7eaa9c6e38/yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", size = 318283 }, + { url = "https://files.pythonhosted.org/packages/27/0f/2b20100839064d1c75fb85fa6b5cbd68249d96a4b06a5cf25f9eaaf9b32a/yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", size = 317599 }, + { url = "https://files.pythonhosted.org/packages/7b/da/3f2d6643d8cf3003c72587f28a9d9c76829a5b45186cae8f978bac113fc5/yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", size = 323398 }, + { url = "https://files.pythonhosted.org/packages/9e/f8/881c97cc35603ec63b48875d47e36e1b984648826b36ce7affac16e08261/yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", size = 337601 }, + { url = "https://files.pythonhosted.org/packages/81/da/049b354e00b33019c32126f2a40ecbcc320859f619c4304c556cf23a5dc3/yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", size = 338975 }, + { url = "https://files.pythonhosted.org/packages/26/64/e36e808b249d64cfc33caca7e9ef2d7e636e4f9e8529e4fe5ed4813ac5b0/yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", size = 331078 }, + { url = "https://files.pythonhosted.org/packages/82/cb/6fe205b528cc889f8e13d6d180adbc8721a21a6aac67fc3158294575add3/yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", size = 83573 }, + { url = "https://files.pythonhosted.org/packages/55/96/4dcb7110ae4cd53768254fb50ace7bca00e110459e6eff1d16983c513219/yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", size = 89761 }, + { url = "https://files.pythonhosted.org/packages/ec/0f/ce6a2c8aab9946446fb27f1e28f0fd89ce84ae913ab18a92d18078a1c7ed/yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", size = 140727 }, + { url = "https://files.pythonhosted.org/packages/9d/df/204f7a502bdc3973cd9fc29e7dfad18ae48b3acafdaaf1ae07c0f41025aa/yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", size = 93560 }, + { url = "https://files.pythonhosted.org/packages/a2/e1/f4d522ae0560c91a4ea31113a50f00f85083be885e1092fc6e74eb43cb1d/yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75", size = 91497 }, + { url = "https://files.pythonhosted.org/packages/f1/82/783d97bf4a226f1a2e59b1966f2752244c2bf4dc89bc36f61d597b8e34e5/yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", size = 339446 }, + { url = "https://files.pythonhosted.org/packages/e5/ff/615600647048d81289c80907165de713fbc566d1e024789863a2f6563ba3/yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", size = 354616 }, + { url = "https://files.pythonhosted.org/packages/a5/04/bfb7adb452bd19dfe0c35354ffce8ebc3086e028e5f8270e409d17da5466/yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", size = 351801 }, + { url = "https://files.pythonhosted.org/packages/10/e0/efe21edacdc4a638ce911f8cabf1c77cac3f60e9819ba7d891b9ceb6e1d4/yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", size = 343381 }, + { url = "https://files.pythonhosted.org/packages/63/f9/7bc7e69857d6fc3920ecd173592f921d5701f4a0dd3f2ae293b386cfa3bf/yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", size = 337093 }, + { url = "https://files.pythonhosted.org/packages/93/52/99da61947466275ff17d7bc04b0ac31dfb7ec699bd8d8985dffc34c3a913/yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", size = 346619 }, + { url = "https://files.pythonhosted.org/packages/91/8a/8aaad86a35a16e485ba0e5de0d2ae55bf8dd0c9f1cccac12be4c91366b1d/yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", size = 344347 }, + { url = "https://files.pythonhosted.org/packages/af/b6/97f29f626b4a1768ffc4b9b489533612cfcb8905c90f745aade7b2eaf75e/yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", size = 350316 }, + { url = "https://files.pythonhosted.org/packages/d7/98/8e0e8b812479569bdc34d66dd3e2471176ca33be4ff5c272a01333c4b269/yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", size = 361336 }, + { url = "https://files.pythonhosted.org/packages/9e/d3/d1507efa0a85c25285f8eb51df9afa1ba1b6e446dda781d074d775b6a9af/yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", size = 365350 }, + { url = "https://files.pythonhosted.org/packages/22/ba/ee7f1830449c96bae6f33210b7d89e8aaf3079fbdaf78ac398e50a9da404/yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", size = 357689 }, + { url = "https://files.pythonhosted.org/packages/a0/85/321c563dc5afe1661108831b965c512d185c61785400f5606006507d2e18/yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", size = 83635 }, + { url = "https://files.pythonhosted.org/packages/bc/da/543a32c00860588ff1235315b68f858cea30769099c32cd22b7bb266411b/yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", size = 90218 }, + { url = "https://files.pythonhosted.org/packages/5d/af/e25615c7920396219b943b9ff8b34636ae3e1ad30777649371317d7f05f8/yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", size = 141839 }, + { url = "https://files.pythonhosted.org/packages/83/5e/363d9de3495c7c66592523f05d21576a811015579e0c87dd38c7b5788afd/yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", size = 94125 }, + { url = "https://files.pythonhosted.org/packages/e3/a2/b65447626227ebe36f18f63ac551790068bf42c69bb22dfa3ae986170728/yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", size = 92048 }, + { url = "https://files.pythonhosted.org/packages/a1/f5/2ef86458446f85cde10582054fd5113495ef8ce8477da35aaaf26d2970ef/yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", size = 331472 }, + { url = "https://files.pythonhosted.org/packages/f3/6b/1ba79758ba352cdf2ad4c20cab1b982dd369aa595bb0d7601fc89bf82bee/yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", size = 341260 }, + { url = "https://files.pythonhosted.org/packages/2d/41/4e07c2afca3f9ed3da5b0e38d43d0280d9b624a3d5c478c425e5ce17775c/yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", size = 340882 }, + { url = "https://files.pythonhosted.org/packages/c3/c0/cd8e94618983c1b811af082e1a7ad7764edb3a6af2bc6b468e0e686238ba/yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", size = 336648 }, + { url = "https://files.pythonhosted.org/packages/ac/fc/73ec4340d391ffbb8f34eb4c55429784ec9f5bd37973ce86d52d67135418/yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", size = 325019 }, + { url = "https://files.pythonhosted.org/packages/57/48/da3ebf418fc239d0a156b3bdec6b17a5446f8d2dea752299c6e47b143a85/yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", size = 342841 }, + { url = "https://files.pythonhosted.org/packages/5d/79/107272745a470a8167924e353a5312eb52b5a9bb58e22686adc46c94f7ec/yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", size = 341433 }, + { url = "https://files.pythonhosted.org/packages/30/9c/6459668b3b8dcc11cd061fc53e12737e740fb6b1575b49c84cbffb387b3a/yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", size = 344927 }, + { url = "https://files.pythonhosted.org/packages/c5/0b/93a17ed733aca8164fc3a01cb7d47b3f08854ce4f957cce67a6afdb388a0/yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", size = 355732 }, + { url = "https://files.pythonhosted.org/packages/9a/63/ead2ed6aec3c59397e135cadc66572330325a0c24cd353cd5c94f5e63463/yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", size = 362123 }, + { url = "https://files.pythonhosted.org/packages/89/bf/f6b75b4c2fcf0e7bb56edc0ed74e33f37fac45dc40e5a52a3be66b02587a/yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", size = 356355 }, + { url = "https://files.pythonhosted.org/packages/45/1f/50a0257cd07eef65c8c65ad6a21f5fb230012d659e021aeb6ac8a7897bf6/yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", size = 83279 }, + { url = "https://files.pythonhosted.org/packages/bc/82/fafb2c1268d63d54ec08b3a254fbe51f4ef098211501df646026717abee3/yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", size = 89590 }, + { url = "https://files.pythonhosted.org/packages/06/1e/5a93e3743c20eefbc68bd89334d9c9f04f3f2334380f7bbf5e950f29511b/yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", size = 139974 }, + { url = "https://files.pythonhosted.org/packages/a1/be/4e0f6919013c7c5eaea5c31811c551ccd599d2fc80aa3dd6962f1bbdcddd/yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", size = 93364 }, + { url = "https://files.pythonhosted.org/packages/73/f0/650f994bc491d0cb85df8bb45392780b90eab1e175f103a5edc61445ff67/yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", size = 91177 }, + { url = "https://files.pythonhosted.org/packages/f3/e8/9945ed555d14b43ede3ae8b1bd73e31068a694cad2b9d3cad0a28486c2eb/yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", size = 333086 }, + { url = "https://files.pythonhosted.org/packages/a6/c0/7d167e48e14d26639ca066825af8da7df1d2fcdba827e3fd6341aaf22a3b/yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", size = 343661 }, + { url = "https://files.pythonhosted.org/packages/fa/81/80a266517531d4e3553aecd141800dbf48d02e23ebd52909e63598a80134/yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", size = 345196 }, + { url = "https://files.pythonhosted.org/packages/b0/77/6adc482ba7f2dc6c0d9b3b492e7cd100edfac4cfc3849c7ffa26fd7beb1a/yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", size = 338743 }, + { url = "https://files.pythonhosted.org/packages/6d/cc/f0c4c0b92ff3ada517ffde2b127406c001504b225692216d969879ada89a/yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", size = 326719 }, + { url = "https://files.pythonhosted.org/packages/18/3b/7bfc80d3376b5fa162189993a87a5a6a58057f88315bd0ea00610055b57a/yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", size = 345826 }, + { url = "https://files.pythonhosted.org/packages/2e/66/cf0b0338107a5c370205c1a572432af08f36ca12ecce127f5b558398b4fd/yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", size = 340335 }, + { url = "https://files.pythonhosted.org/packages/2f/52/b084b0eec0fd4d2490e1d33ace3320fad704c5f1f3deaa709f929d2d87fc/yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", size = 345301 }, + { url = "https://files.pythonhosted.org/packages/ef/38/9e2036d948efd3bafcdb4976cb212166fded76615f0dfc6c1492c4ce4784/yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", size = 354205 }, + { url = "https://files.pythonhosted.org/packages/81/c1/13dfe1e70b86811733316221c696580725ceb1c46d4e4db852807e134310/yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", size = 360501 }, + { url = "https://files.pythonhosted.org/packages/91/87/756e05c74cd8bf9e71537df4a2cae7e8211a9ebe0d2350a3e26949e1e41c/yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", size = 359452 }, + { url = "https://files.pythonhosted.org/packages/06/b2/b2bb09c1e6d59e1c9b1b36a86caa473e22c3dbf26d1032c030e9bfb554dc/yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", size = 308904 }, + { url = "https://files.pythonhosted.org/packages/f3/27/f084d9a5668853c1f3b246620269b14ee871ef3c3cc4f3a1dd53645b68ec/yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", size = 314637 }, + { url = "https://files.pythonhosted.org/packages/52/ad/1fe7ff5f3e8869d4c5070f47b96bac2b4d15e67c100a8278d8e7876329fc/yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", size = 44352 }, +] diff --git a/pyproject.toml b/pyproject.toml index a7d1ded..47da6b0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,135 +3,9 @@ name = "fastapi_supabase_template" version = "0.4.1" description = "" authors = [ - {name = "Atticuszz", email = "1831768457@qq.com"}, + {name = "Atticus.J.Zeller", email = "atticus.zeller@pm.me"}, ] readme = "README.md" -requires-python = ">=3.10" -dependencies = [ - "python-dotenv>=1.0.1", - "uvicorn>=0.30.6", - "pydantic[email]>=2.8.2", - "pydantic-settings>=2.4.0", - "python-multipart>=0.0.9", - "supabase>=2.7.4", - "fastapi>=0.112.2", - "sqlmodel>=0.0.22", - "asyncpg>=0.30.0", - "alembic>=1.14.0", - "tenacity>=9.0.0", -] - -[dependency-groups] -dev = [ - "anyio>=4.4.0", - "coverage>=7.6.1", - "faker>=28.0.0", - "mypy>=1.13.0", - "pre-commit>=3.8.0", - "pytest>=8.3.2", - "pytest-dotenv>=0.5.2", - "typos>=1.27.0", - "git-cliff>=2.6.1", -] -docs = [ - "mkdocs-git-revision-date-localized-plugin>=1.2.9", - "mkdocs-glightbox>=0.4.0", - "mkdocs-material>=9.5.39", - "mkdocs-obsidian-bridge>=1.1.1", - "mkdocs-publisher>=1.4.2", - "pymdown-extensions>=10.11.1", -] - -## Test -[tool.mypy] -strict = true -exclude = ["venv", ".venv"] - -[tool.pytest.ini_options] -# Set additional command line options for pytest= -# -r= show extra test summary info -# X= show extra info on xfailed tests -# s= don't capture stdout (allow print statements) -# --strict-config= any warnings about configuration are treated as errors -# --strict-markers= treat unregistered markers as errors -addopts = "-rXs --strict-config --strict-markers" -xfail_strict = true # Treat tests that are marked as xfail but pass as test failures -filterwarnings = ["error"] # Treat all warnings as errors -pythonpath = "src" - -[tool.coverage.run] -branch = true - -[tool.coverage.report] -skip_covered = true -show_missing = true -precision = 2 -exclude_lines = [ - 'def __repr__', - 'pragma= no cover', - 'raise NotImplementedError', - 'if TYPE_CHECKING=', - 'if typing.TYPE_CHECKING=', - '@overload', - '@typing.overload', - '\(Protocol\)=$', - 'typing.assert_never', - 'assert_never', - 'if __name__ == "__main__":', -] - - -## Linter and formatter -[tool.ruff] -# cover and extend the default config in https=//docs.astral.sh/ruff/configuration/ -extend-exclude = [""] -target-version = "py310" - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "B", # flake8-bugbear - "C4", # flake8-comprehensions - "UP", # pyupgrade - "ARG001", # unused arguments in functions -] -ignore = [ - "E501", # line too long, handled by black - "B008", # do not perform function calls in argument defaults - "W191", # indentation contains tabs - "B904", # Allow raising exceptions without from e, for HTTPException - "COM819", # Trailing comma prohibited - "D100", # Missing docstring in public module(file) - "D104", # Missing docstring in public package - "D203", # 1 blank line required before class docstring - "E201", # Whitespace after '(' - "E202", # Whitespace before ')' - "E203", # Whitespace before '=' - "E221", # Multiple spaces before operator - "E241", # Multiple spaces after ',' - "E251", # Unexpected spaces around keyword / parameter equals - "W291", # Trailing whitespace - "W293", # Blank line contains whitespace -] - -isort = { combine-as-imports = true, split-on-trailing-comma = false } - -# Avoid trying to fix flake8-bugbear (`B`) violations. -unfixable = ["B"] - -[tool.ruff.format] -docstring-code-format = true -skip-magic-trailing-comma = true - -# Reference -# 1. https=//github.com/Kludex/python-template/blob/main/template/%7B%7B%20project_slug%20%7D%7D/pyproject.toml.jinja -# 2. https=//github.com/fastapi/full-stack-fastapi-template/blob/master/backend/pyproject.toml -# 3. https=//github.com/pydantic/logfire -# 4. https=//coverage.readthedocs.io/en/latest/index.html - ## VCS [tool.git-cliff.remote.github] diff --git a/scripts/bump.sh b/scripts/bump.sh index 6ec275b..2bc187e 100755 --- a/scripts/bump.sh +++ b/scripts/bump.sh @@ -1,8 +1,8 @@ #!/usr/bin/env bash # update CHANGELOG.md use GITHUB_REPO ENV as github token -git-cliff -o -v --github-repo "atticuszz/python-uv" +uvx git-cliff -o -v --github-repo "atticuszz/python-uv" # bump version and commit with tags -bump-my-version bump patch +# uvx bump-my-version bump patch # push remote -git push origin main --tags +# git push origin main --tags diff --git a/scripts/docs.sh b/scripts/docs.sh new file mode 100755 index 0000000..b76f2d0 --- /dev/null +++ b/scripts/docs.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +uvx --with mkdocs-material \ + --with mkdocs-git-revision-date-localized-plugin \ + --with mkdocs-glightbox \ + --with mkdocs-obsidian-bridge \ + --with mkdocs-publisher \ + --with pymdown-extensions \ + mkdocs serve diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh new file mode 100755 index 0000000..6da2e5d --- /dev/null +++ b/scripts/pre-commit.sh @@ -0,0 +1,3 @@ +#!/usr/bin/env bash + +uvx pre-commit run --all-file diff --git a/uv.lock b/uv.lock index 9c4bc40..dcd599d 100644 --- a/uv.lock +++ b/uv.lock @@ -1,1995 +1,7 @@ version = 1 -requires-python = ">=3.10" -resolution-markers = [ - "python_full_version < '3.13'", - "python_full_version >= '3.13'", -] - -[[package]] -name = "aiohappyeyeballs" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2d/f7/22bba300a16fd1cad99da1a23793fe43963ee326d012fdf852d0b4035955/aiohappyeyeballs-2.4.0.tar.gz", hash = "sha256:55a1714f084e63d49639800f95716da97a1f173d46a16dfcfda0016abb93b6b2", size = 16786 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/b6/58ea188899950d759a837f9a58b2aee1d1a380ea4d6211ce9b1823748851/aiohappyeyeballs-2.4.0-py3-none-any.whl", hash = "sha256:7ce92076e249169a13c2f49320d1967425eaf1f407522d707d59cac7628d62bd", size = 12155 }, -] - -[[package]] -name = "aiohttp" -version = "3.10.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohappyeyeballs" }, - { name = "aiosignal" }, - { name = "async-timeout", marker = "python_full_version < '3.11'" }, - { name = "attrs" }, - { name = "frozenlist" }, - { name = "multidict" }, - { name = "yarl" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ca/28/ca549838018140b92a19001a8628578b0f2a3b38c16826212cc6f706e6d4/aiohttp-3.10.5.tar.gz", hash = "sha256:f071854b47d39591ce9a17981c46790acb30518e2f83dfca8db2dfa091178691", size = 7524360 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/4a/b27dd9b88fe22dde88742b341fd10251746a6ffcfe1c0b8b15b4a8cbd7c1/aiohttp-3.10.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:18a01eba2574fb9edd5f6e5fb25f66e6ce061da5dab5db75e13fe1558142e0a3", size = 587010 }, - { url = "https://files.pythonhosted.org/packages/de/a9/0f7e2b71549c9d641086c423526ae7a10de3b88d03ba104a3df153574d0d/aiohttp-3.10.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:94fac7c6e77ccb1ca91e9eb4cb0ac0270b9fb9b289738654120ba8cebb1189c6", size = 397698 }, - { url = "https://files.pythonhosted.org/packages/3b/52/26baa486e811c25b0cd16a494038260795459055568713f841e78f016481/aiohttp-3.10.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2f1f1c75c395991ce9c94d3e4aa96e5c59c8356a15b1c9231e783865e2772699", size = 389052 }, - { url = "https://files.pythonhosted.org/packages/33/df/71ba374a3e925539cb2f6e6d4f5326e7b6b200fabbe1b3cc5e6368f07ce7/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f7acae3cf1a2a2361ec4c8e787eaaa86a94171d2417aae53c0cca6ca3118ff6", size = 1248615 }, - { url = "https://files.pythonhosted.org/packages/67/02/bb89c1eba08a27fc844933bee505d63d480caf8e2816c06961d2941cd128/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:94c4381ffba9cc508b37d2e536b418d5ea9cfdc2848b9a7fea6aebad4ec6aac1", size = 1282930 }, - { url = "https://files.pythonhosted.org/packages/db/36/07d8cfcc37f39c039f93a4210cc71dadacca003609946c63af23659ba656/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c31ad0c0c507894e3eaa843415841995bf8de4d6b2d24c6e33099f4bc9fc0d4f", size = 1317250 }, - { url = "https://files.pythonhosted.org/packages/9a/44/cabeac994bef8ba521b552ae996928afc6ee1975a411385a07409811b01f/aiohttp-3.10.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0912b8a8fadeb32ff67a3ed44249448c20148397c1ed905d5dac185b4ca547bb", size = 1243212 }, - { url = "https://files.pythonhosted.org/packages/5a/11/23f1e31f5885ac72be52fd205981951dd2e4c87c5b1487cf82fde5bbd46c/aiohttp-3.10.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d93400c18596b7dc4794d48a63fb361b01a0d8eb39f28800dc900c8fbdaca91", size = 1213401 }, - { url = "https://files.pythonhosted.org/packages/3f/e7/6e69a0b0d896fbaf1192d492db4c21688e6c0d327486da610b0e8195bcc9/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3c5e0d764a5c9aa5a62d99728c56d455310bcc288a79cab10157b3af426f", size = 1212450 }, - { url = "https://files.pythonhosted.org/packages/a9/7f/a42f51074c723ea848254946aec118f1e59914a639dc8ba20b0c9247c195/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:d742c36ed44f2798c8d3f4bc511f479b9ceef2b93f348671184139e7d708042c", size = 1211324 }, - { url = "https://files.pythonhosted.org/packages/d5/43/c2f9d2f588ccef8f028f0a0c999b5ceafecbda50b943313faee7e91f3e03/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:814375093edae5f1cb31e3407997cf3eacefb9010f96df10d64829362ae2df69", size = 1266838 }, - { url = "https://files.pythonhosted.org/packages/c1/a7/ff9f067ecb06896d859e4f2661667aee4bd9c616689599ff034b63cbd9d7/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:8224f98be68a84b19f48e0bdc14224b5a71339aff3a27df69989fa47d01296f3", size = 1285301 }, - { url = "https://files.pythonhosted.org/packages/9a/e3/dd56bb4c67d216046ce61d98dec0f3023043f1de48f561df1bf93dd47aea/aiohttp-3.10.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d9a487ef090aea982d748b1b0d74fe7c3950b109df967630a20584f9a99c0683", size = 1235806 }, - { url = "https://files.pythonhosted.org/packages/a7/64/90dcd42ac21927a49ba4140b2e4d50e1847379427ef6c43eb338ef9960e3/aiohttp-3.10.5-cp310-cp310-win32.whl", hash = "sha256:d9ef084e3dc690ad50137cc05831c52b6ca428096e6deb3c43e95827f531d5ef", size = 360162 }, - { url = "https://files.pythonhosted.org/packages/f3/45/145d8b4853fc92c0c8509277642767e7726a085e390ce04353dc68b0f5b5/aiohttp-3.10.5-cp310-cp310-win_amd64.whl", hash = "sha256:66bf9234e08fe561dccd62083bf67400bdbf1c67ba9efdc3dac03650e97c6088", size = 379173 }, - { url = "https://files.pythonhosted.org/packages/f1/90/54ccb1e4eadfb6c95deff695582453f6208584431d69bf572782e9ae542b/aiohttp-3.10.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8c6a4e5e40156d72a40241a25cc226051c0a8d816610097a8e8f517aeacd59a2", size = 586455 }, - { url = "https://files.pythonhosted.org/packages/c3/7a/95e88c02756e7e718f054e1bb3ec6ad5d0ee4a2ca2bb1768c5844b3de30a/aiohttp-3.10.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c634a3207a5445be65536d38c13791904fda0748b9eabf908d3fe86a52941cf", size = 397255 }, - { url = "https://files.pythonhosted.org/packages/07/4f/767387b39990e1ee9aba8ce642abcc286d84d06e068dc167dab983898f18/aiohttp-3.10.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4aff049b5e629ef9b3e9e617fa6e2dfeda1bf87e01bcfecaf3949af9e210105e", size = 388973 }, - { url = "https://files.pythonhosted.org/packages/61/46/0df41170a4d228c07b661b1ba9d87101d99a79339dc93b8b1183d8b20545/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1942244f00baaacaa8155eca94dbd9e8cc7017deb69b75ef67c78e89fdad3c77", size = 1326126 }, - { url = "https://files.pythonhosted.org/packages/af/20/da0d65e07ce49d79173fed41598f487a0a722e87cfbaa8bb7e078a7c1d39/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e04a1f2a65ad2f93aa20f9ff9f1b672bf912413e5547f60749fa2ef8a644e061", size = 1364538 }, - { url = "https://files.pythonhosted.org/packages/aa/20/b59728405114e57541ba9d5b96033e69d004e811ded299537f74237629ca/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f2bfc0032a00405d4af2ba27f3c429e851d04fad1e5ceee4080a1c570476697", size = 1399896 }, - { url = "https://files.pythonhosted.org/packages/2a/92/006690c31b830acbae09d2618e41308fe4c81c0679b3b33a3af859e0b7bf/aiohttp-3.10.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:424ae21498790e12eb759040bbb504e5e280cab64693d14775c54269fd1d2bb7", size = 1312914 }, - { url = "https://files.pythonhosted.org/packages/d4/71/1a253ca215b6c867adbd503f1e142117527ea8775e65962bc09b2fad1d2c/aiohttp-3.10.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:975218eee0e6d24eb336d0328c768ebc5d617609affaca5dbbd6dd1984f16ed0", size = 1271301 }, - { url = "https://files.pythonhosted.org/packages/0a/ab/5d1d9ff9ce6cce8fa54774d0364e64a0f3cd50e512ff09082ced8e5217a1/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4120d7fefa1e2d8fb6f650b11489710091788de554e2b6f8347c7a20ceb003f5", size = 1291652 }, - { url = "https://files.pythonhosted.org/packages/75/5f/f90510ea954b9ae6e7a53d2995b97a3e5c181110fdcf469bc9238445871d/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b90078989ef3fc45cf9221d3859acd1108af7560c52397ff4ace8ad7052a132e", size = 1286289 }, - { url = "https://files.pythonhosted.org/packages/be/9e/1f523414237798660921817c82b9225a363af436458caf584d2fa6a2eb4a/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ba5a8b74c2a8af7d862399cdedce1533642fa727def0b8c3e3e02fcb52dca1b1", size = 1341848 }, - { url = "https://files.pythonhosted.org/packages/f6/36/443472ddaa85d7d80321fda541d9535b23ecefe0bf5792cc3955ea635190/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:02594361128f780eecc2a29939d9dfc870e17b45178a867bf61a11b2a4367277", size = 1361619 }, - { url = "https://files.pythonhosted.org/packages/19/f6/3ecbac0bc4359c7d7ba9e85c6b10f57e20edaf1f97751ad2f892db231ad0/aiohttp-3.10.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4fc029e135859f533025bc82047334e24b0d489e75513144f25408ecaf058", size = 1320869 }, - { url = "https://files.pythonhosted.org/packages/34/7e/ed74ffb36e3a0cdec1b05d8fbaa29cb532371d5a20058b3a8052fc90fe7c/aiohttp-3.10.5-cp311-cp311-win32.whl", hash = "sha256:e1ca1ef5ba129718a8fc827b0867f6aa4e893c56eb00003b7367f8a733a9b072", size = 359271 }, - { url = "https://files.pythonhosted.org/packages/98/1b/718901f04bc8c886a742be9e83babb7b93facabf7c475cc95e2b3ab80b4d/aiohttp-3.10.5-cp311-cp311-win_amd64.whl", hash = "sha256:349ef8a73a7c5665cca65c88ab24abe75447e28aa3bc4c93ea5093474dfdf0ff", size = 379143 }, - { url = "https://files.pythonhosted.org/packages/d9/1c/74f9dad4a2fc4107e73456896283d915937f48177b99867b63381fadac6e/aiohttp-3.10.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:305be5ff2081fa1d283a76113b8df7a14c10d75602a38d9f012935df20731487", size = 583468 }, - { url = "https://files.pythonhosted.org/packages/12/29/68d090551f2b58ce76c2b436ced8dd2dfd32115d41299bf0b0c308a5483c/aiohttp-3.10.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3a1c32a19ee6bbde02f1cb189e13a71b321256cc1d431196a9f824050b160d5a", size = 394066 }, - { url = "https://files.pythonhosted.org/packages/8f/f7/971f88b4cdcaaa4622925ba7d86de47b48ec02a9040a143514b382f78da4/aiohttp-3.10.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:61645818edd40cc6f455b851277a21bf420ce347baa0b86eaa41d51ef58ba23d", size = 389098 }, - { url = "https://files.pythonhosted.org/packages/f1/5a/fe3742efdce551667b2ddf1158b27c5b8eb1edc13d5e14e996e52e301025/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c225286f2b13bab5987425558baa5cbdb2bc925b2998038fa028245ef421e75", size = 1332742 }, - { url = "https://files.pythonhosted.org/packages/1a/52/a25c0334a1845eb4967dff279151b67ca32a948145a5812ed660ed900868/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ba01ebc6175e1e6b7275c907a3a36be48a2d487549b656aa90c8a910d9f3178", size = 1372134 }, - { url = "https://files.pythonhosted.org/packages/96/3d/33c1d8efc2d8ec36bff9a8eca2df9fdf8a45269c6e24a88e74f2aa4f16bd/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8eaf44ccbc4e35762683078b72bf293f476561d8b68ec8a64f98cf32811c323e", size = 1414413 }, - { url = "https://files.pythonhosted.org/packages/64/74/0f1ddaa5f0caba1d946f0dd0c31f5744116e4a029beec454ec3726d3311f/aiohttp-3.10.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b1c43eb1ab7cbf411b8e387dc169acb31f0ca0d8c09ba63f9eac67829585b44f", size = 1328107 }, - { url = "https://files.pythonhosted.org/packages/0a/32/c10118f0ad50e4093227234f71fd0abec6982c29367f65f32ee74ed652c4/aiohttp-3.10.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de7a5299827253023c55ea549444e058c0eb496931fa05d693b95140a947cb73", size = 1280126 }, - { url = "https://files.pythonhosted.org/packages/c6/c9/77e3d648d97c03a42acfe843d03e97be3c5ef1b4d9de52e5bd2d28eed8e7/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4790f0e15f00058f7599dab2b206d3049d7ac464dc2e5eae0e93fa18aee9e7bf", size = 1292660 }, - { url = "https://files.pythonhosted.org/packages/7e/5d/99c71f8e5c8b64295be421b4c42d472766b263a1fe32e91b64bf77005bf2/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:44b324a6b8376a23e6ba25d368726ee3bc281e6ab306db80b5819999c737d820", size = 1300988 }, - { url = "https://files.pythonhosted.org/packages/8f/2c/76d2377dd947f52fbe8afb19b18a3b816d66c7966755c04030f93b1f7b2d/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0d277cfb304118079e7044aad0b76685d30ecb86f83a0711fc5fb257ffe832ca", size = 1339268 }, - { url = "https://files.pythonhosted.org/packages/fd/e6/3d9d935cc705d57ed524d82ec5d6b678a53ac1552720ae41282caa273584/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:54d9ddea424cd19d3ff6128601a4a4d23d54a421f9b4c0fff740505813739a91", size = 1366993 }, - { url = "https://files.pythonhosted.org/packages/fe/c2/f7eed4d602f3f224600d03ab2e1a7734999b0901b1c49b94dc5891340433/aiohttp-3.10.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4f1c9866ccf48a6df2b06823e6ae80573529f2af3a0992ec4fe75b1a510df8a6", size = 1329459 }, - { url = "https://files.pythonhosted.org/packages/ce/8f/27f205b76531fc592abe29e1ad265a16bf934a9f609509c02d765e6a8055/aiohttp-3.10.5-cp312-cp312-win32.whl", hash = "sha256:dc4826823121783dccc0871e3f405417ac116055bf184ac04c36f98b75aacd12", size = 356968 }, - { url = "https://files.pythonhosted.org/packages/39/8c/4f6c0b2b3629f6be6c81ab84d9d577590f74f01d4412bfc4067958eaa1e1/aiohttp-3.10.5-cp312-cp312-win_amd64.whl", hash = "sha256:22c0a23a3b3138a6bf76fc553789cb1a703836da86b0f306b6f0dc1617398abc", size = 377650 }, - { url = "https://files.pythonhosted.org/packages/7b/b9/03b4327897a5b5d29338fa9b514f1c2f66a3e4fc88a4e40fad478739314d/aiohttp-3.10.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:7f6b639c36734eaa80a6c152a238242bedcee9b953f23bb887e9102976343092", size = 576994 }, - { url = "https://files.pythonhosted.org/packages/67/1b/20c2e159cd07b8ed6dde71c2258233902fdf415b2fe6174bd2364ba63107/aiohttp-3.10.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f29930bc2921cef955ba39a3ff87d2c4398a0394ae217f41cb02d5c26c8b1b77", size = 390684 }, - { url = "https://files.pythonhosted.org/packages/4d/6b/ff83b34f157e370431d8081c5d1741963f4fb12f9aaddb2cacbf50305225/aiohttp-3.10.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f489a2c9e6455d87eabf907ac0b7d230a9786be43fbe884ad184ddf9e9c1e385", size = 386176 }, - { url = "https://files.pythonhosted.org/packages/4d/a1/6e92817eb657de287560962df4959b7ddd22859c4b23a0309e2d3de12538/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:123dd5b16b75b2962d0fff566effb7a065e33cd4538c1692fb31c3bda2bfb972", size = 1303310 }, - { url = "https://files.pythonhosted.org/packages/04/29/200518dc7a39c30ae6d5bc232d7207446536e93d3d9299b8e95db6e79c54/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b98e698dc34966e5976e10bbca6d26d6724e6bdea853c7c10162a3235aba6e16", size = 1340445 }, - { url = "https://files.pythonhosted.org/packages/8e/20/53f7bba841ba7b5bb5dea580fea01c65524879ba39cb917d08c845524717/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3b9162bab7e42f21243effc822652dc5bb5e8ff42a4eb62fe7782bcbcdfacf6", size = 1385121 }, - { url = "https://files.pythonhosted.org/packages/f1/b4/d99354ad614c48dd38fb1ee880a1a54bd9ab2c3bcad3013048d4a1797d3a/aiohttp-3.10.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1923a5c44061bffd5eebeef58cecf68096e35003907d8201a4d0d6f6e387ccaa", size = 1299669 }, - { url = "https://files.pythonhosted.org/packages/51/39/ca1de675f2a5729c71c327e52ac6344e63f036bd37281686ae5c3fb13bfb/aiohttp-3.10.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55f011da0a843c3d3df2c2cf4e537b8070a419f891c930245f05d329c4b0689", size = 1252638 }, - { url = "https://files.pythonhosted.org/packages/54/cf/a3ae7ff43138422d477348e309ef8275779701bf305ff6054831ef98b782/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:afe16a84498441d05e9189a15900640a2d2b5e76cf4efe8cbb088ab4f112ee57", size = 1266889 }, - { url = "https://files.pythonhosted.org/packages/6e/7a/c6027ad70d9fb23cf254a26144de2723821dade1a624446aa22cd0b6d012/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8112fb501b1e0567a1251a2fd0747baae60a4ab325a871e975b7bb67e59221f", size = 1266249 }, - { url = "https://files.pythonhosted.org/packages/64/fd/ed136d46bc2c7e3342fed24662b4827771d55ceb5a7687847aae977bfc17/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1e72589da4c90337837fdfe2026ae1952c0f4a6e793adbbfbdd40efed7c63599", size = 1311036 }, - { url = "https://files.pythonhosted.org/packages/76/9a/43eeb0166f1119256d6f43468f900db1aed7fbe32069d2a71c82f987db4d/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:4d46c7b4173415d8e583045fbc4daa48b40e31b19ce595b8d92cf639396c15d5", size = 1338756 }, - { url = "https://files.pythonhosted.org/packages/d5/bc/d01ff0810b3f5e26896f76d44225ed78b088ddd33079b85cd1a23514318b/aiohttp-3.10.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:33e6bc4bab477c772a541f76cd91e11ccb6d2efa2b8d7d7883591dfb523e5987", size = 1299976 }, - { url = "https://files.pythonhosted.org/packages/3e/c9/50a297c4f7ab57a949f4add2d3eafe5f3e68bb42f739e933f8b32a092bda/aiohttp-3.10.5-cp313-cp313-win32.whl", hash = "sha256:c58c6837a2c2a7cf3133983e64173aec11f9c2cd8e87ec2fdc16ce727bcf1a04", size = 355609 }, - { url = "https://files.pythonhosted.org/packages/65/28/aee9d04fb0b3b1f90622c338a08e54af5198e704a910e20947c473298fd0/aiohttp-3.10.5-cp313-cp313-win_amd64.whl", hash = "sha256:38172a70005252b6893088c0f5e8a47d173df7cc2b2bd88650957eb84fcf5022", size = 375697 }, -] - -[[package]] -name = "aiosignal" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "frozenlist" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 }, -] - -[[package]] -name = "alembic" -version = "1.14.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mako" }, - { name = "sqlalchemy" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/00/1e/8cb8900ba1b6360431e46fb7a89922916d3a1b017a8908a7c0499cc7e5f6/alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b", size = 1916172 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/06/8b505aea3d77021b18dcbd8133aa1418f1a1e37e432a465b14c46b2c0eaa/alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25", size = 233482 }, -] - -[[package]] -name = "annotated-types" -version = "0.7.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, -] - -[[package]] -name = "anyio" -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "idna" }, - { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e6/e3/c4c8d473d6780ef1853d630d581f70d655b4f8d7553c6997958c283039a2/anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94", size = 163930 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/a2/10639a79341f6c019dedc95bd48a4928eed9f1d1197f4c04f546fc7ae0ff/anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7", size = 86780 }, -] - -[[package]] -name = "async-timeout" -version = "4.0.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, -] - -[[package]] -name = "asyncpg" -version = "0.30.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "async-timeout", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143 }, - { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035 }, - { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384 }, - { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526 }, - { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390 }, - { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630 }, - { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760 }, - { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764 }, - { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506 }, - { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922 }, - { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565 }, - { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962 }, - { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791 }, - { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696 }, - { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358 }, - { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375 }, - { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162 }, - { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025 }, - { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243 }, - { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059 }, - { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596 }, - { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632 }, - { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186 }, - { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064 }, - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, -] - -[[package]] -name = "attrs" -version = "24.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, -] - -[[package]] -name = "babel" -version = "2.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, -] - -[[package]] -name = "beautifulsoup4" -version = "4.12.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "soupsieve" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, -] - -[[package]] -name = "certifi" -version = "2024.8.30" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, -] - -[[package]] -name = "cfgv" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f2/4f/e1808dc01273379acc506d18f1504eb2d299bd4131743b9fc54d7be4df1e/charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", size = 106620 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/69/8b/825cc84cf13a28bfbcba7c416ec22bf85a9584971be15b21dd8300c65b7f/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", size = 196363 }, - { url = "https://files.pythonhosted.org/packages/23/81/d7eef6a99e42c77f444fdd7bc894b0ceca6c3a95c51239e74a722039521c/charset_normalizer-3.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", size = 125639 }, - { url = "https://files.pythonhosted.org/packages/21/67/b4564d81f48042f520c948abac7079356e94b30cb8ffb22e747532cf469d/charset_normalizer-3.4.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", size = 120451 }, - { url = "https://files.pythonhosted.org/packages/c2/72/12a7f0943dd71fb5b4e7b55c41327ac0a1663046a868ee4d0d8e9c369b85/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", size = 140041 }, - { url = "https://files.pythonhosted.org/packages/67/56/fa28c2c3e31217c4c52158537a2cf5d98a6c1e89d31faf476c89391cd16b/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", size = 150333 }, - { url = "https://files.pythonhosted.org/packages/f9/d2/466a9be1f32d89eb1554cf84073a5ed9262047acee1ab39cbaefc19635d2/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", size = 142921 }, - { url = "https://files.pythonhosted.org/packages/f8/01/344ec40cf5d85c1da3c1f57566c59e0c9b56bcc5566c08804a95a6cc8257/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", size = 144785 }, - { url = "https://files.pythonhosted.org/packages/73/8b/2102692cb6d7e9f03b9a33a710e0164cadfce312872e3efc7cfe22ed26b4/charset_normalizer-3.4.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", size = 146631 }, - { url = "https://files.pythonhosted.org/packages/d8/96/cc2c1b5d994119ce9f088a9a0c3ebd489d360a2eb058e2c8049f27092847/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b", size = 140867 }, - { url = "https://files.pythonhosted.org/packages/c9/27/cde291783715b8ec30a61c810d0120411844bc4c23b50189b81188b273db/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", size = 149273 }, - { url = "https://files.pythonhosted.org/packages/3a/a4/8633b0fc1a2d1834d5393dafecce4a1cc56727bfd82b4dc18fc92f0d3cc3/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", size = 152437 }, - { url = "https://files.pythonhosted.org/packages/64/ea/69af161062166b5975ccbb0961fd2384853190c70786f288684490913bf5/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", size = 150087 }, - { url = "https://files.pythonhosted.org/packages/3b/fd/e60a9d9fd967f4ad5a92810138192f825d77b4fa2a557990fd575a47695b/charset_normalizer-3.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", size = 145142 }, - { url = "https://files.pythonhosted.org/packages/6d/02/8cb0988a1e49ac9ce2eed1e07b77ff118f2923e9ebd0ede41ba85f2dcb04/charset_normalizer-3.4.0-cp310-cp310-win32.whl", hash = "sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", size = 94701 }, - { url = "https://files.pythonhosted.org/packages/d6/20/f1d4670a8a723c46be695dff449d86d6092916f9e99c53051954ee33a1bc/charset_normalizer-3.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", size = 102191 }, - { url = "https://files.pythonhosted.org/packages/9c/61/73589dcc7a719582bf56aae309b6103d2762b526bffe189d635a7fcfd998/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", size = 193339 }, - { url = "https://files.pythonhosted.org/packages/77/d5/8c982d58144de49f59571f940e329ad6e8615e1e82ef84584c5eeb5e1d72/charset_normalizer-3.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", size = 124366 }, - { url = "https://files.pythonhosted.org/packages/bf/19/411a64f01ee971bed3231111b69eb56f9331a769072de479eae7de52296d/charset_normalizer-3.4.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", size = 118874 }, - { url = "https://files.pythonhosted.org/packages/4c/92/97509850f0d00e9f14a46bc751daabd0ad7765cff29cdfb66c68b6dad57f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", size = 138243 }, - { url = "https://files.pythonhosted.org/packages/e2/29/d227805bff72ed6d6cb1ce08eec707f7cfbd9868044893617eb331f16295/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", size = 148676 }, - { url = "https://files.pythonhosted.org/packages/13/bc/87c2c9f2c144bedfa62f894c3007cd4530ba4b5351acb10dc786428a50f0/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", size = 141289 }, - { url = "https://files.pythonhosted.org/packages/eb/5b/6f10bad0f6461fa272bfbbdf5d0023b5fb9bc6217c92bf068fa5a99820f5/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", size = 142585 }, - { url = "https://files.pythonhosted.org/packages/3b/a0/a68980ab8a1f45a36d9745d35049c1af57d27255eff8c907e3add84cf68f/charset_normalizer-3.4.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", size = 144408 }, - { url = "https://files.pythonhosted.org/packages/d7/a1/493919799446464ed0299c8eef3c3fad0daf1c3cd48bff9263c731b0d9e2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", size = 139076 }, - { url = "https://files.pythonhosted.org/packages/fb/9d/9c13753a5a6e0db4a0a6edb1cef7aee39859177b64e1a1e748a6e3ba62c2/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", size = 146874 }, - { url = "https://files.pythonhosted.org/packages/75/d2/0ab54463d3410709c09266dfb416d032a08f97fd7d60e94b8c6ef54ae14b/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365", size = 150871 }, - { url = "https://files.pythonhosted.org/packages/8d/c9/27e41d481557be53d51e60750b85aa40eaf52b841946b3cdeff363105737/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", size = 148546 }, - { url = "https://files.pythonhosted.org/packages/ee/44/4f62042ca8cdc0cabf87c0fc00ae27cd8b53ab68be3605ba6d071f742ad3/charset_normalizer-3.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", size = 143048 }, - { url = "https://files.pythonhosted.org/packages/01/f8/38842422988b795220eb8038745d27a675ce066e2ada79516c118f291f07/charset_normalizer-3.4.0-cp311-cp311-win32.whl", hash = "sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", size = 94389 }, - { url = "https://files.pythonhosted.org/packages/0b/6e/b13bd47fa9023b3699e94abf565b5a2f0b0be6e9ddac9812182596ee62e4/charset_normalizer-3.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", size = 101752 }, - { url = "https://files.pythonhosted.org/packages/d3/0b/4b7a70987abf9b8196845806198975b6aab4ce016632f817ad758a5aa056/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", size = 194445 }, - { url = "https://files.pythonhosted.org/packages/50/89/354cc56cf4dd2449715bc9a0f54f3aef3dc700d2d62d1fa5bbea53b13426/charset_normalizer-3.4.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf", size = 125275 }, - { url = "https://files.pythonhosted.org/packages/fa/44/b730e2a2580110ced837ac083d8ad222343c96bb6b66e9e4e706e4d0b6df/charset_normalizer-3.4.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", size = 119020 }, - { url = "https://files.pythonhosted.org/packages/9d/e4/9263b8240ed9472a2ae7ddc3e516e71ef46617fe40eaa51221ccd4ad9a27/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", size = 139128 }, - { url = "https://files.pythonhosted.org/packages/6b/e3/9f73e779315a54334240353eaea75854a9a690f3f580e4bd85d977cb2204/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03", size = 149277 }, - { url = "https://files.pythonhosted.org/packages/1a/cf/f1f50c2f295312edb8a548d3fa56a5c923b146cd3f24114d5adb7e7be558/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", size = 142174 }, - { url = "https://files.pythonhosted.org/packages/16/92/92a76dc2ff3a12e69ba94e7e05168d37d0345fa08c87e1fe24d0c2a42223/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", size = 143838 }, - { url = "https://files.pythonhosted.org/packages/a4/01/2117ff2b1dfc61695daf2babe4a874bca328489afa85952440b59819e9d7/charset_normalizer-3.4.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", size = 146149 }, - { url = "https://files.pythonhosted.org/packages/f6/9b/93a332b8d25b347f6839ca0a61b7f0287b0930216994e8bf67a75d050255/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", size = 140043 }, - { url = "https://files.pythonhosted.org/packages/ab/f6/7ac4a01adcdecbc7a7587767c776d53d369b8b971382b91211489535acf0/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", size = 148229 }, - { url = "https://files.pythonhosted.org/packages/9d/be/5708ad18161dee7dc6a0f7e6cf3a88ea6279c3e8484844c0590e50e803ef/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", size = 151556 }, - { url = "https://files.pythonhosted.org/packages/5a/bb/3d8bc22bacb9eb89785e83e6723f9888265f3a0de3b9ce724d66bd49884e/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", size = 149772 }, - { url = "https://files.pythonhosted.org/packages/f7/fa/d3fc622de05a86f30beea5fc4e9ac46aead4731e73fd9055496732bcc0a4/charset_normalizer-3.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", size = 144800 }, - { url = "https://files.pythonhosted.org/packages/9a/65/bdb9bc496d7d190d725e96816e20e2ae3a6fa42a5cac99c3c3d6ff884118/charset_normalizer-3.4.0-cp312-cp312-win32.whl", hash = "sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", size = 94836 }, - { url = "https://files.pythonhosted.org/packages/3e/67/7b72b69d25b89c0b3cea583ee372c43aa24df15f0e0f8d3982c57804984b/charset_normalizer-3.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", size = 102187 }, - { url = "https://files.pythonhosted.org/packages/f3/89/68a4c86f1a0002810a27f12e9a7b22feb198c59b2f05231349fbce5c06f4/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", size = 194617 }, - { url = "https://files.pythonhosted.org/packages/4f/cd/8947fe425e2ab0aa57aceb7807af13a0e4162cd21eee42ef5b053447edf5/charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed", size = 125310 }, - { url = "https://files.pythonhosted.org/packages/5b/f0/b5263e8668a4ee9becc2b451ed909e9c27058337fda5b8c49588183c267a/charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", size = 119126 }, - { url = "https://files.pythonhosted.org/packages/ff/6e/e445afe4f7fda27a533f3234b627b3e515a1b9429bc981c9a5e2aa5d97b6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", size = 139342 }, - { url = "https://files.pythonhosted.org/packages/a1/b2/4af9993b532d93270538ad4926c8e37dc29f2111c36f9c629840c57cd9b3/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", size = 149383 }, - { url = "https://files.pythonhosted.org/packages/fb/6f/4e78c3b97686b871db9be6f31d64e9264e889f8c9d7ab33c771f847f79b7/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", size = 142214 }, - { url = "https://files.pythonhosted.org/packages/2b/c9/1c8fe3ce05d30c87eff498592c89015b19fade13df42850aafae09e94f35/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", size = 144104 }, - { url = "https://files.pythonhosted.org/packages/ee/68/efad5dcb306bf37db7db338338e7bb8ebd8cf38ee5bbd5ceaaaa46f257e6/charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d", size = 146255 }, - { url = "https://files.pythonhosted.org/packages/0c/75/1ed813c3ffd200b1f3e71121c95da3f79e6d2a96120163443b3ad1057505/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", size = 140251 }, - { url = "https://files.pythonhosted.org/packages/7d/0d/6f32255c1979653b448d3c709583557a4d24ff97ac4f3a5be156b2e6a210/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", size = 148474 }, - { url = "https://files.pythonhosted.org/packages/ac/a0/c1b5298de4670d997101fef95b97ac440e8c8d8b4efa5a4d1ef44af82f0d/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", size = 151849 }, - { url = "https://files.pythonhosted.org/packages/04/4f/b3961ba0c664989ba63e30595a3ed0875d6790ff26671e2aae2fdc28a399/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", size = 149781 }, - { url = "https://files.pythonhosted.org/packages/d8/90/6af4cd042066a4adad58ae25648a12c09c879efa4849c705719ba1b23d8c/charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482", size = 144970 }, - { url = "https://files.pythonhosted.org/packages/cc/67/e5e7e0cbfefc4ca79025238b43cdf8a2037854195b37d6417f3d0895c4c2/charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67", size = 94973 }, - { url = "https://files.pythonhosted.org/packages/65/97/fc9bbc54ee13d33dc54a7fcf17b26368b18505500fc01e228c27b5222d80/charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", size = 102308 }, - { url = "https://files.pythonhosted.org/packages/bf/9b/08c0432272d77b04803958a4598a51e2a4b51c06640af8b8f0f908c18bf2/charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079", size = 49446 }, -] - -[[package]] -name = "click" -version = "8.1.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, -] - -[[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 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, -] - -[[package]] -name = "coverage" -version = "7.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f7/08/7e37f82e4d1aead42a7443ff06a1e406aabf7302c4f00a546e4b320b994c/coverage-7.6.1.tar.gz", hash = "sha256:953510dfb7b12ab69d20135a0662397f077c59b1e6379a768e97c59d852ee51d", size = 798791 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/61/eb7ce5ed62bacf21beca4937a90fe32545c91a3c8a42a30c6616d48fc70d/coverage-7.6.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b06079abebbc0e89e6163b8e8f0e16270124c154dc6e4a47b413dd538859af16", size = 206690 }, - { url = "https://files.pythonhosted.org/packages/7d/73/041928e434442bd3afde5584bdc3f932fb4562b1597629f537387cec6f3d/coverage-7.6.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf4b19715bccd7ee27b6b120e7e9dd56037b9c0681dcc1adc9ba9db3d417fa36", size = 207127 }, - { url = "https://files.pythonhosted.org/packages/c7/c8/6ca52b5147828e45ad0242388477fdb90df2c6cbb9a441701a12b3c71bc8/coverage-7.6.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61c0abb4c85b095a784ef23fdd4aede7a2628478e7baba7c5e3deba61070a02", size = 235654 }, - { url = "https://files.pythonhosted.org/packages/d5/da/9ac2b62557f4340270942011d6efeab9833648380109e897d48ab7c1035d/coverage-7.6.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fd21f6ae3f08b41004dfb433fa895d858f3f5979e7762d052b12aef444e29afc", size = 233598 }, - { url = "https://files.pythonhosted.org/packages/53/23/9e2c114d0178abc42b6d8d5281f651a8e6519abfa0ef460a00a91f80879d/coverage-7.6.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f59d57baca39b32db42b83b2a7ba6f47ad9c394ec2076b084c3f029b7afca23", size = 234732 }, - { url = "https://files.pythonhosted.org/packages/0f/7e/a0230756fb133343a52716e8b855045f13342b70e48e8ad41d8a0d60ab98/coverage-7.6.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a1ac0ae2b8bd743b88ed0502544847c3053d7171a3cff9228af618a068ed9c34", size = 233816 }, - { url = "https://files.pythonhosted.org/packages/28/7c/3753c8b40d232b1e5eeaed798c875537cf3cb183fb5041017c1fdb7ec14e/coverage-7.6.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e6a08c0be454c3b3beb105c0596ebdc2371fab6bb90c0c0297f4e58fd7e1012c", size = 232325 }, - { url = "https://files.pythonhosted.org/packages/57/e3/818a2b2af5b7573b4b82cf3e9f137ab158c90ea750a8f053716a32f20f06/coverage-7.6.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f5796e664fe802da4f57a168c85359a8fbf3eab5e55cd4e4569fbacecc903959", size = 233418 }, - { url = "https://files.pythonhosted.org/packages/c8/fb/4532b0b0cefb3f06d201648715e03b0feb822907edab3935112b61b885e2/coverage-7.6.1-cp310-cp310-win32.whl", hash = "sha256:7bb65125fcbef8d989fa1dd0e8a060999497629ca5b0efbca209588a73356232", size = 209343 }, - { url = "https://files.pythonhosted.org/packages/5a/25/af337cc7421eca1c187cc9c315f0a755d48e755d2853715bfe8c418a45fa/coverage-7.6.1-cp310-cp310-win_amd64.whl", hash = "sha256:3115a95daa9bdba70aea750db7b96b37259a81a709223c8448fa97727d546fe0", size = 210136 }, - { url = "https://files.pythonhosted.org/packages/ad/5f/67af7d60d7e8ce61a4e2ddcd1bd5fb787180c8d0ae0fbd073f903b3dd95d/coverage-7.6.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7dea0889685db8550f839fa202744652e87c60015029ce3f60e006f8c4462c93", size = 206796 }, - { url = "https://files.pythonhosted.org/packages/e1/0e/e52332389e057daa2e03be1fbfef25bb4d626b37d12ed42ae6281d0a274c/coverage-7.6.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed37bd3c3b063412f7620464a9ac1314d33100329f39799255fb8d3027da50d3", size = 207244 }, - { url = "https://files.pythonhosted.org/packages/aa/cd/766b45fb6e090f20f8927d9c7cb34237d41c73a939358bc881883fd3a40d/coverage-7.6.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d85f5e9a5f8b73e2350097c3756ef7e785f55bd71205defa0bfdaf96c31616ff", size = 239279 }, - { url = "https://files.pythonhosted.org/packages/70/6c/a9ccd6fe50ddaf13442a1e2dd519ca805cbe0f1fcd377fba6d8339b98ccb/coverage-7.6.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9bc572be474cafb617672c43fe989d6e48d3c83af02ce8de73fff1c6bb3c198d", size = 236859 }, - { url = "https://files.pythonhosted.org/packages/14/6f/8351b465febb4dbc1ca9929505202db909c5a635c6fdf33e089bbc3d7d85/coverage-7.6.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c0420b573964c760df9e9e86d1a9a622d0d27f417e1a949a8a66dd7bcee7bc6", size = 238549 }, - { url = "https://files.pythonhosted.org/packages/68/3c/289b81fa18ad72138e6d78c4c11a82b5378a312c0e467e2f6b495c260907/coverage-7.6.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1f4aa8219db826ce6be7099d559f8ec311549bfc4046f7f9fe9b5cea5c581c56", size = 237477 }, - { url = "https://files.pythonhosted.org/packages/ed/1c/aa1efa6459d822bd72c4abc0b9418cf268de3f60eeccd65dc4988553bd8d/coverage-7.6.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:fc5a77d0c516700ebad189b587de289a20a78324bc54baee03dd486f0855d234", size = 236134 }, - { url = "https://files.pythonhosted.org/packages/fb/c8/521c698f2d2796565fe9c789c2ee1ccdae610b3aa20b9b2ef980cc253640/coverage-7.6.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b48f312cca9621272ae49008c7f613337c53fadca647d6384cc129d2996d1133", size = 236910 }, - { url = "https://files.pythonhosted.org/packages/7d/30/033e663399ff17dca90d793ee8a2ea2890e7fdf085da58d82468b4220bf7/coverage-7.6.1-cp311-cp311-win32.whl", hash = "sha256:1125ca0e5fd475cbbba3bb67ae20bd2c23a98fac4e32412883f9bcbaa81c314c", size = 209348 }, - { url = "https://files.pythonhosted.org/packages/20/05/0d1ccbb52727ccdadaa3ff37e4d2dc1cd4d47f0c3df9eb58d9ec8508ca88/coverage-7.6.1-cp311-cp311-win_amd64.whl", hash = "sha256:8ae539519c4c040c5ffd0632784e21b2f03fc1340752af711f33e5be83a9d6c6", size = 210230 }, - { url = "https://files.pythonhosted.org/packages/7e/d4/300fc921dff243cd518c7db3a4c614b7e4b2431b0d1145c1e274fd99bd70/coverage-7.6.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:95cae0efeb032af8458fc27d191f85d1717b1d4e49f7cb226cf526ff28179778", size = 206983 }, - { url = "https://files.pythonhosted.org/packages/e1/ab/6bf00de5327ecb8db205f9ae596885417a31535eeda6e7b99463108782e1/coverage-7.6.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5621a9175cf9d0b0c84c2ef2b12e9f5f5071357c4d2ea6ca1cf01814f45d2391", size = 207221 }, - { url = "https://files.pythonhosted.org/packages/92/8f/2ead05e735022d1a7f3a0a683ac7f737de14850395a826192f0288703472/coverage-7.6.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:260933720fdcd75340e7dbe9060655aff3af1f0c5d20f46b57f262ab6c86a5e8", size = 240342 }, - { url = "https://files.pythonhosted.org/packages/0f/ef/94043e478201ffa85b8ae2d2c79b4081e5a1b73438aafafccf3e9bafb6b5/coverage-7.6.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07e2ca0ad381b91350c0ed49d52699b625aab2b44b65e1b4e02fa9df0e92ad2d", size = 237371 }, - { url = "https://files.pythonhosted.org/packages/1f/0f/c890339dd605f3ebc269543247bdd43b703cce6825b5ed42ff5f2d6122c7/coverage-7.6.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c44fee9975f04b33331cb8eb272827111efc8930cfd582e0320613263ca849ca", size = 239455 }, - { url = "https://files.pythonhosted.org/packages/d1/04/7fd7b39ec7372a04efb0f70c70e35857a99b6a9188b5205efb4c77d6a57a/coverage-7.6.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:877abb17e6339d96bf08e7a622d05095e72b71f8afd8a9fefc82cf30ed944163", size = 238924 }, - { url = "https://files.pythonhosted.org/packages/ed/bf/73ce346a9d32a09cf369f14d2a06651329c984e106f5992c89579d25b27e/coverage-7.6.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3e0cadcf6733c09154b461f1ca72d5416635e5e4ec4e536192180d34ec160f8a", size = 237252 }, - { url = "https://files.pythonhosted.org/packages/86/74/1dc7a20969725e917b1e07fe71a955eb34bc606b938316bcc799f228374b/coverage-7.6.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3c02d12f837d9683e5ab2f3d9844dc57655b92c74e286c262e0fc54213c216d", size = 238897 }, - { url = "https://files.pythonhosted.org/packages/b6/e9/d9cc3deceb361c491b81005c668578b0dfa51eed02cd081620e9a62f24ec/coverage-7.6.1-cp312-cp312-win32.whl", hash = "sha256:e05882b70b87a18d937ca6768ff33cc3f72847cbc4de4491c8e73880766718e5", size = 209606 }, - { url = "https://files.pythonhosted.org/packages/47/c8/5a2e41922ea6740f77d555c4d47544acd7dc3f251fe14199c09c0f5958d3/coverage-7.6.1-cp312-cp312-win_amd64.whl", hash = "sha256:b5d7b556859dd85f3a541db6a4e0167b86e7273e1cdc973e5b175166bb634fdb", size = 210373 }, - { url = "https://files.pythonhosted.org/packages/8c/f9/9aa4dfb751cb01c949c990d136a0f92027fbcc5781c6e921df1cb1563f20/coverage-7.6.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a4acd025ecc06185ba2b801f2de85546e0b8ac787cf9d3b06e7e2a69f925b106", size = 207007 }, - { url = "https://files.pythonhosted.org/packages/b9/67/e1413d5a8591622a46dd04ff80873b04c849268831ed5c304c16433e7e30/coverage-7.6.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a6d3adcf24b624a7b778533480e32434a39ad8fa30c315208f6d3e5542aeb6e9", size = 207269 }, - { url = "https://files.pythonhosted.org/packages/14/5b/9dec847b305e44a5634d0fb8498d135ab1d88330482b74065fcec0622224/coverage-7.6.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0c212c49b6c10e6951362f7c6df3329f04c2b1c28499563d4035d964ab8e08c", size = 239886 }, - { url = "https://files.pythonhosted.org/packages/7b/b7/35760a67c168e29f454928f51f970342d23cf75a2bb0323e0f07334c85f3/coverage-7.6.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e81d7a3e58882450ec4186ca59a3f20a5d4440f25b1cff6f0902ad890e6748a", size = 237037 }, - { url = "https://files.pythonhosted.org/packages/f7/95/d2fd31f1d638df806cae59d7daea5abf2b15b5234016a5ebb502c2f3f7ee/coverage-7.6.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78b260de9790fd81e69401c2dc8b17da47c8038176a79092a89cb2b7d945d060", size = 239038 }, - { url = "https://files.pythonhosted.org/packages/6e/bd/110689ff5752b67924efd5e2aedf5190cbbe245fc81b8dec1abaffba619d/coverage-7.6.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a78d169acd38300060b28d600344a803628c3fd585c912cacc9ea8790fe96862", size = 238690 }, - { url = "https://files.pythonhosted.org/packages/d3/a8/08d7b38e6ff8df52331c83130d0ab92d9c9a8b5462f9e99c9f051a4ae206/coverage-7.6.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2c09f4ce52cb99dd7505cd0fc8e0e37c77b87f46bc9c1eb03fe3bc9991085388", size = 236765 }, - { url = "https://files.pythonhosted.org/packages/d6/6a/9cf96839d3147d55ae713eb2d877f4d777e7dc5ba2bce227167d0118dfe8/coverage-7.6.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6878ef48d4227aace338d88c48738a4258213cd7b74fd9a3d4d7582bb1d8a155", size = 238611 }, - { url = "https://files.pythonhosted.org/packages/74/e4/7ff20d6a0b59eeaab40b3140a71e38cf52547ba21dbcf1d79c5a32bba61b/coverage-7.6.1-cp313-cp313-win32.whl", hash = "sha256:44df346d5215a8c0e360307d46ffaabe0f5d3502c8a1cefd700b34baf31d411a", size = 209671 }, - { url = "https://files.pythonhosted.org/packages/35/59/1812f08a85b57c9fdb6d0b383d779e47b6f643bc278ed682859512517e83/coverage-7.6.1-cp313-cp313-win_amd64.whl", hash = "sha256:8284cf8c0dd272a247bc154eb6c95548722dce90d098c17a883ed36e67cdb129", size = 210368 }, - { url = "https://files.pythonhosted.org/packages/9c/15/08913be1c59d7562a3e39fce20661a98c0a3f59d5754312899acc6cb8a2d/coverage-7.6.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3296782ca4eab572a1a4eca686d8bfb00226300dcefdf43faa25b5242ab8a3e", size = 207758 }, - { url = "https://files.pythonhosted.org/packages/c4/ae/b5d58dff26cade02ada6ca612a76447acd69dccdbb3a478e9e088eb3d4b9/coverage-7.6.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:502753043567491d3ff6d08629270127e0c31d4184c4c8d98f92c26f65019962", size = 208035 }, - { url = "https://files.pythonhosted.org/packages/b8/d7/62095e355ec0613b08dfb19206ce3033a0eedb6f4a67af5ed267a8800642/coverage-7.6.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6a89ecca80709d4076b95f89f308544ec8f7b4727e8a547913a35f16717856cb", size = 250839 }, - { url = "https://files.pythonhosted.org/packages/7c/1e/c2967cb7991b112ba3766df0d9c21de46b476d103e32bb401b1b2adf3380/coverage-7.6.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a318d68e92e80af8b00fa99609796fdbcdfef3629c77c6283566c6f02c6d6704", size = 246569 }, - { url = "https://files.pythonhosted.org/packages/8b/61/a7a6a55dd266007ed3b1df7a3386a0d760d014542d72f7c2c6938483b7bd/coverage-7.6.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13b0a73a0896988f053e4fbb7de6d93388e6dd292b0d87ee51d106f2c11b465b", size = 248927 }, - { url = "https://files.pythonhosted.org/packages/c8/fa/13a6f56d72b429f56ef612eb3bc5ce1b75b7ee12864b3bd12526ab794847/coverage-7.6.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4421712dbfc5562150f7554f13dde997a2e932a6b5f352edcce948a815efee6f", size = 248401 }, - { url = "https://files.pythonhosted.org/packages/75/06/0429c652aa0fb761fc60e8c6b291338c9173c6aa0f4e40e1902345b42830/coverage-7.6.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:166811d20dfea725e2e4baa71fffd6c968a958577848d2131f39b60043400223", size = 246301 }, - { url = "https://files.pythonhosted.org/packages/52/76/1766bb8b803a88f93c3a2d07e30ffa359467810e5cbc68e375ebe6906efb/coverage-7.6.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:225667980479a17db1048cb2bf8bfb39b8e5be8f164b8f6628b64f78a72cf9d3", size = 247598 }, - { url = "https://files.pythonhosted.org/packages/66/8b/f54f8db2ae17188be9566e8166ac6df105c1c611e25da755738025708d54/coverage-7.6.1-cp313-cp313t-win32.whl", hash = "sha256:170d444ab405852903b7d04ea9ae9b98f98ab6d7e63e1115e82620807519797f", size = 210307 }, - { url = "https://files.pythonhosted.org/packages/9f/b0/e0dca6da9170aefc07515cce067b97178cefafb512d00a87a1c717d2efd5/coverage-7.6.1-cp313-cp313t-win_amd64.whl", hash = "sha256:b9f222de8cded79c49bf184bdbc06630d4c58eec9459b939b4a690c82ed05657", size = 211453 }, - { url = "https://files.pythonhosted.org/packages/a5/2b/0354ed096bca64dc8e32a7cbcae28b34cb5ad0b1fe2125d6d99583313ac0/coverage-7.6.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:e9a6e0eb86070e8ccaedfbd9d38fec54864f3125ab95419970575b42af7541df", size = 198926 }, -] - -[[package]] -name = "deprecation" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "packaging" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5a/d3/8ae2869247df154b64c1884d7346d412fed0c49df84db635aab2d1c40e62/deprecation-2.1.0.tar.gz", hash = "sha256:72b3bde64e5d778694b0cf68178aed03d15e15477116add3fb773e581f9518ff", size = 173788 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/c3/253a89ee03fc9b9682f1541728eb66db7db22148cd94f89ab22528cd1e1b/deprecation-2.1.0-py2.py3-none-any.whl", hash = "sha256:a10811591210e1fb0e768a8c25517cabeabcba6f0bf96564f8ff45189f90b14a", size = 11178 }, -] - -[[package]] -name = "distlib" -version = "0.3.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c4/91/e2df406fb4efacdf46871c25cde65d3c6ee5e173b7e5a4547a47bae91920/distlib-0.3.8.tar.gz", hash = "sha256:1530ea13e350031b6312d8580ddb6b27a104275a31106523b8f123787f494f64", size = 609931 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/8e/41/9307e4f5f9976bc8b7fea0b66367734e8faf3ec84bc0d412d8cfabbb66cd/distlib-0.3.8-py2.py3-none-any.whl", hash = "sha256:034db59a0b96f8ca18035f36290806a9a6e6bd9d1ff91e45a7f172eb17e51784", size = 468850 }, -] - -[[package]] -name = "dnspython" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/37/7d/c871f55054e403fdfd6b8f65fd6d1c4e147ed100d3e9f9ba1fe695403939/dnspython-2.6.1.tar.gz", hash = "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc", size = 332727 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/87/a1/8c5287991ddb8d3e4662f71356d9656d91ab3a36618c3dd11b280df0d255/dnspython-2.6.1-py3-none-any.whl", hash = "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", size = 307696 }, -] - -[[package]] -name = "email-validator" -version = "2.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "dnspython" }, - { name = "idna" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/48/ce/13508a1ec3f8bb981ae4ca79ea40384becc868bfae97fd1c942bb3a001b1/email_validator-2.2.0.tar.gz", hash = "sha256:cb690f344c617a714f22e66ae771445a1ceb46821152df8e165c5f9a364582b7", size = 48967 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/ee/bf0adb559ad3c786f12bcbc9296b3f5675f529199bef03e2df281fa1fadb/email_validator-2.2.0-py3-none-any.whl", hash = "sha256:561977c2d73ce3611850a06fa56b414621e0c8faa9d66f2611407d87465da631", size = 33521 }, -] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, -] - -[[package]] -name = "faker" -version = "28.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "python-dateutil" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fe/d6/f1a81065124b23d1b56367570a4e00531005b4cca76a739b50ebf79a026d/faker-28.0.0.tar.gz", hash = "sha256:0d3c0399204aaf8205cc1750db443474ca0436f177126b2c27b798e8336cc74f", size = 1782120 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/92/09/74f194bc3f5fe1d88cd4a882d51669431f82b17327840bd7fdd7b516c97e/Faker-28.0.0-py3-none-any.whl", hash = "sha256:6a3a08be54c37e05f7943d7ba5211d252c1de737687a46ad6f29209d8d5db11f", size = 1820129 }, -] - -[[package]] -name = "fastapi" -version = "0.112.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "starlette" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/9c/11/4874d165e7ef97aa803a567a4be8f9c8b0bd7cced6d536d44033ef7d4bfa/fastapi-0.112.2.tar.gz", hash = "sha256:3d4729c038414d5193840706907a41839d839523da6ed0c2811f1168cac1798c", size = 291967 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/ae/6570ae1b67007735229f10f2e1174d6e33c056ee9c0c1754d432acbede94/fastapi-0.112.2-py3-none-any.whl", hash = "sha256:db84b470bd0e2b1075942231e90e3577e12a903c4dc8696f0d206a7904a7af1c", size = 93471 }, -] +requires-python = ">=3.12" [[package]] name = "fastapi-supabase-template" version = "0.4.1" source = { virtual = "." } -dependencies = [ - { name = "alembic" }, - { name = "asyncpg" }, - { name = "fastapi" }, - { name = "pydantic", extra = ["email"] }, - { name = "pydantic-settings" }, - { name = "python-dotenv" }, - { name = "python-multipart" }, - { name = "sqlmodel" }, - { name = "supabase" }, - { name = "tenacity" }, - { name = "uvicorn" }, -] - -[package.dev-dependencies] -dev = [ - { name = "anyio" }, - { name = "coverage" }, - { name = "faker" }, - { name = "git-cliff" }, - { name = "mypy" }, - { name = "pre-commit" }, - { name = "pytest" }, - { name = "pytest-dotenv" }, - { name = "typos" }, -] -docs = [ - { name = "mkdocs-git-revision-date-localized-plugin" }, - { name = "mkdocs-glightbox" }, - { name = "mkdocs-material" }, - { name = "mkdocs-obsidian-bridge" }, - { name = "mkdocs-publisher" }, - { name = "pymdown-extensions" }, -] - -[package.metadata] -requires-dist = [ - { name = "alembic", specifier = ">=1.14.0" }, - { name = "asyncpg", specifier = ">=0.30.0" }, - { name = "fastapi", specifier = ">=0.112.2" }, - { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, - { name = "pydantic-settings", specifier = ">=2.4.0" }, - { name = "python-dotenv", specifier = ">=1.0.1" }, - { name = "python-multipart", specifier = ">=0.0.9" }, - { name = "sqlmodel", specifier = ">=0.0.22" }, - { name = "supabase", specifier = ">=2.7.4" }, - { name = "tenacity", specifier = ">=9.0.0" }, - { name = "uvicorn", specifier = ">=0.30.6" }, -] - -[package.metadata.requires-dev] -dev = [ - { name = "anyio", specifier = ">=4.4.0" }, - { name = "coverage", specifier = ">=7.6.1" }, - { name = "faker", specifier = ">=28.0.0" }, - { name = "git-cliff", specifier = ">=2.6.1" }, - { name = "mypy", specifier = ">=1.13.0" }, - { name = "pre-commit", specifier = ">=3.8.0" }, - { name = "pytest", specifier = ">=8.3.2" }, - { name = "pytest-dotenv", specifier = ">=0.5.2" }, - { name = "typos", specifier = ">=1.27.0" }, -] -docs = [ - { name = "mkdocs-git-revision-date-localized-plugin", specifier = ">=1.2.9" }, - { name = "mkdocs-glightbox", specifier = ">=0.4.0" }, - { name = "mkdocs-material", specifier = ">=9.5.39" }, - { name = "mkdocs-obsidian-bridge", specifier = ">=1.1.1" }, - { name = "mkdocs-publisher", specifier = ">=1.4.2" }, - { name = "pymdown-extensions", specifier = ">=10.11.1" }, -] - -[[package]] -name = "filelock" -version = "3.15.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/08/dd/49e06f09b6645156550fb9aee9cc1e59aba7efbc972d665a1bd6ae0435d4/filelock-3.15.4.tar.gz", hash = "sha256:2207938cbc1844345cb01a5a95524dae30f0ce089eba5b00378295a17e3e90cb", size = 18007 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/f0/48285f0262fe47103a4a45972ed2f9b93e4c80b8fd609fa98da78b2a5706/filelock-3.15.4-py3-none-any.whl", hash = "sha256:6ca1fffae96225dab4c6eaf1c4f4f28cd2568d3ec2a44e15a08520504de468e7", size = 16159 }, -] - -[[package]] -name = "frozenlist" -version = "1.4.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cf/3d/2102257e7acad73efc4a0c306ad3953f68c504c16982bbdfee3ad75d8085/frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b", size = 37820 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7a/35/1328c7b0f780d34f8afc1d87ebdc2bb065a123b24766a0b475f0d67da637/frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac", size = 94315 }, - { url = "https://files.pythonhosted.org/packages/f4/d6/ca016b0adcf8327714ccef969740688808c86e0287bf3a639ff582f24e82/frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868", size = 53805 }, - { url = "https://files.pythonhosted.org/packages/ae/83/bcdaa437a9bd693ba658a0310f8cdccff26bd78e45fccf8e49897904a5cd/frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776", size = 52163 }, - { url = "https://files.pythonhosted.org/packages/d4/e9/759043ab7d169b74fe05ebfbfa9ee5c881c303ebc838e308346204309cd0/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a", size = 238595 }, - { url = "https://files.pythonhosted.org/packages/f8/ce/b9de7dc61e753dc318cf0de862181b484178210c5361eae6eaf06792264d/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad", size = 262428 }, - { url = "https://files.pythonhosted.org/packages/36/ce/dc6f29e0352fa34ebe45421960c8e7352ca63b31630a576e8ffb381e9c08/frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c", size = 258867 }, - { url = "https://files.pythonhosted.org/packages/51/47/159ac53faf8a11ae5ee8bb9db10327575557504e549cfd76f447b969aa91/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe", size = 229412 }, - { url = "https://files.pythonhosted.org/packages/ec/25/0c87df2e53c0c5d90f7517ca0ff7aca78d050a8ec4d32c4278e8c0e52e51/frozenlist-1.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9b2de4cf0cdd5bd2dee4c4f63a653c61d2408055ab77b151c1957f221cabf2a", size = 239539 }, - { url = "https://files.pythonhosted.org/packages/97/94/a1305fa4716726ae0abf3b1069c2d922fcfd442538cb850f1be543f58766/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98", size = 253379 }, - { url = "https://files.pythonhosted.org/packages/53/82/274e19f122e124aee6d113188615f63b0736b4242a875f482a81f91e07e2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75", size = 245901 }, - { url = "https://files.pythonhosted.org/packages/b8/28/899931015b8cffbe155392fe9ca663f981a17e1adc69589ee0e1e7cdc9a2/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5", size = 263797 }, - { url = "https://files.pythonhosted.org/packages/6e/4f/b8a5a2f10c4a58c52a52a40cf6cf1ffcdbf3a3b64f276f41dab989bf3ab5/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950", size = 264415 }, - { url = "https://files.pythonhosted.org/packages/b0/2c/7be3bdc59dbae444864dbd9cde82790314390ec54636baf6b9ce212627ad/frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc", size = 253964 }, - { url = "https://files.pythonhosted.org/packages/2e/ec/4fb5a88f6b9a352aed45ab824dd7ce4801b7bcd379adcb927c17a8f0a1a8/frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1", size = 44559 }, - { url = "https://files.pythonhosted.org/packages/61/15/2b5d644d81282f00b61e54f7b00a96f9c40224107282efe4cd9d2bf1433a/frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439", size = 50434 }, - { url = "https://files.pythonhosted.org/packages/01/bc/8d33f2d84b9368da83e69e42720cff01c5e199b5a868ba4486189a4d8fa9/frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0", size = 97060 }, - { url = "https://files.pythonhosted.org/packages/af/b2/904500d6a162b98a70e510e743e7ea992241b4f9add2c8063bf666ca21df/frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49", size = 55347 }, - { url = "https://files.pythonhosted.org/packages/5b/9c/f12b69997d3891ddc0d7895999a00b0c6a67f66f79498c0e30f27876435d/frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced", size = 53374 }, - { url = "https://files.pythonhosted.org/packages/ac/6e/e0322317b7c600ba21dec224498c0c5959b2bce3865277a7c0badae340a9/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0", size = 273288 }, - { url = "https://files.pythonhosted.org/packages/a7/76/180ee1b021568dad5b35b7678616c24519af130ed3fa1e0f1ed4014e0f93/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106", size = 284737 }, - { url = "https://files.pythonhosted.org/packages/05/08/40159d706a6ed983c8aca51922a93fc69f3c27909e82c537dd4054032674/frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068", size = 280267 }, - { url = "https://files.pythonhosted.org/packages/e0/18/9f09f84934c2b2aa37d539a322267939770362d5495f37783440ca9c1b74/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2", size = 258778 }, - { url = "https://files.pythonhosted.org/packages/b3/c9/0bc5ee7e1f5cc7358ab67da0b7dfe60fbd05c254cea5c6108e7d1ae28c63/frozenlist-1.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9c515e7914626b2a2e1e311794b4c35720a0be87af52b79ff8e1429fc25f19", size = 272276 }, - { url = "https://files.pythonhosted.org/packages/12/5d/147556b73a53ad4df6da8bbb50715a66ac75c491fdedac3eca8b0b915345/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82", size = 272424 }, - { url = "https://files.pythonhosted.org/packages/83/61/2087bbf24070b66090c0af922685f1d0596c24bb3f3b5223625bdeaf03ca/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec", size = 260881 }, - { url = "https://files.pythonhosted.org/packages/a8/be/a235bc937dd803258a370fe21b5aa2dd3e7bfe0287a186a4bec30c6cccd6/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a", size = 282327 }, - { url = "https://files.pythonhosted.org/packages/5d/e7/b2469e71f082948066b9382c7b908c22552cc705b960363c390d2e23f587/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74", size = 281502 }, - { url = "https://files.pythonhosted.org/packages/db/1b/6a5b970e55dffc1a7d0bb54f57b184b2a2a2ad0b7bca16a97ca26d73c5b5/frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2", size = 272292 }, - { url = "https://files.pythonhosted.org/packages/1a/05/ebad68130e6b6eb9b287dacad08ea357c33849c74550c015b355b75cc714/frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17", size = 44446 }, - { url = "https://files.pythonhosted.org/packages/b3/21/c5aaffac47fd305d69df46cfbf118768cdf049a92ee6b0b5cb029d449dcf/frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825", size = 50459 }, - { url = "https://files.pythonhosted.org/packages/b4/db/4cf37556a735bcdb2582f2c3fa286aefde2322f92d3141e087b8aeb27177/frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae", size = 93937 }, - { url = "https://files.pythonhosted.org/packages/46/03/69eb64642ca8c05f30aa5931d6c55e50b43d0cd13256fdd01510a1f85221/frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb", size = 53656 }, - { url = "https://files.pythonhosted.org/packages/3f/ab/c543c13824a615955f57e082c8a5ee122d2d5368e80084f2834e6f4feced/frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b", size = 51868 }, - { url = "https://files.pythonhosted.org/packages/a9/b8/438cfd92be2a124da8259b13409224d9b19ef8f5a5b2507174fc7e7ea18f/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86", size = 280652 }, - { url = "https://files.pythonhosted.org/packages/54/72/716a955521b97a25d48315c6c3653f981041ce7a17ff79f701298195bca3/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480", size = 286739 }, - { url = "https://files.pythonhosted.org/packages/65/d8/934c08103637567084568e4d5b4219c1016c60b4d29353b1a5b3587827d6/frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09", size = 289447 }, - { url = "https://files.pythonhosted.org/packages/70/bb/d3b98d83ec6ef88f9bd63d77104a305d68a146fd63a683569ea44c3085f6/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a", size = 265466 }, - { url = "https://files.pythonhosted.org/packages/0b/f2/b8158a0f06faefec33f4dff6345a575c18095a44e52d4f10c678c137d0e0/frozenlist-1.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9acbb16f06fe7f52f441bb6f413ebae6c37baa6ef9edd49cdd567216da8600cd", size = 281530 }, - { url = "https://files.pythonhosted.org/packages/ea/a2/20882c251e61be653764038ece62029bfb34bd5b842724fff32a5b7a2894/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6", size = 281295 }, - { url = "https://files.pythonhosted.org/packages/4c/f9/8894c05dc927af2a09663bdf31914d4fb5501653f240a5bbaf1e88cab1d3/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1", size = 268054 }, - { url = "https://files.pythonhosted.org/packages/37/ff/a613e58452b60166507d731812f3be253eb1229808e59980f0405d1eafbf/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b", size = 286904 }, - { url = "https://files.pythonhosted.org/packages/cc/6e/0091d785187f4c2020d5245796d04213f2261ad097e0c1cf35c44317d517/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e", size = 290754 }, - { url = "https://files.pythonhosted.org/packages/a5/c2/e42ad54bae8bcffee22d1e12a8ee6c7717f7d5b5019261a8c861854f4776/frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8", size = 282602 }, - { url = "https://files.pythonhosted.org/packages/b6/61/56bad8cb94f0357c4bc134acc30822e90e203b5cb8ff82179947de90c17f/frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89", size = 44063 }, - { url = "https://files.pythonhosted.org/packages/3e/dc/96647994a013bc72f3d453abab18340b7f5e222b7b7291e3697ca1fcfbd5/frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5", size = 50452 }, - { url = "https://files.pythonhosted.org/packages/83/10/466fe96dae1bff622021ee687f68e5524d6392b0a2f80d05001cd3a451ba/frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7", size = 11552 }, -] - -[[package]] -name = "ghp-import" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "python-dateutil" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034 }, -] - -[[package]] -name = "git-cliff" -version = "2.6.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a6/b2/266a376450ed2d2779e6881f73f3ecb6e7651eaf1641543f0d246d25d156/git_cliff-2.6.1.tar.gz", hash = "sha256:5a6ab41efb547c01d09d0354f4132aa3a46e2aab5e60c576bca1def6f6efec9f", size = 80951 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/49/35/a085eaaffc04ba73bea83479aae4f36bdaccb716c069f1edd0b9e5cb1b1a/git_cliff-2.6.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:c7bf47e3cccc5aaab360231428efc3e5fc868b16add6188947dbfd397e0b752f", size = 6475059 }, - { url = "https://files.pythonhosted.org/packages/e1/f8/08833e6e33b91ce0440718006c07176c54edeee873cf2ae8e3eb483bf395/git_cliff-2.6.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:6ba81968e13f2d91a3da062313c04818c5d9b8eb65a0fa799668d4217182fe1e", size = 6030702 }, - { url = "https://files.pythonhosted.org/packages/a0/fd/8d3eb58d609e89083ed838be27d5fb5f50de2e7f7e23fc98deff6f390780/git_cliff-2.6.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:903dddef02eea4a77a8d20242a9a78c09e3cf8132fd447eb40ee4f90d5705199", size = 6370975 }, - { url = "https://files.pythonhosted.org/packages/fd/9a/85c3b7696947ebf8377df105bed670d1dd494c12a13d5c7cb0d0f53cd03c/git_cliff-2.6.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be626d41b461b889c4e6a6944115bd1df37bd16428881680d12ffde57c460a2d", size = 6817707 }, - { url = "https://files.pythonhosted.org/packages/76/f6/c7e7ae1fcbde4bf09de65c24f3ec22af9403f73adabf2b5e5e559bfaefe0/git_cliff-2.6.1-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:56636d2c1a73ba687a528befbef96dcc79cdd94ec7c166d17362ce4e336a6538", size = 6419227 }, - { url = "https://files.pythonhosted.org/packages/e8/ff/32aed7902bd1e1a0748cf5775d88c614865d5f97dcac70d881a8a662fe5f/git_cliff-2.6.1-py3-none-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:401acf2f65d7fab41afacc72d7c225a8a58b127821b7e23ec7420e61407d1df2", size = 6670198 }, - { url = "https://files.pythonhosted.org/packages/14/d4/8ca20b1a28119aa4ff85553102334054056d3f4e754259c384c1406e9280/git_cliff-2.6.1-py3-none-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f18d6c485f7198fe4e430fc059488d033ea9ccca122427c7647617ae1d3f4d33", size = 7065947 }, - { url = "https://files.pythonhosted.org/packages/e8/09/35237627f7f731324c7bfc77cfef11c4bd85b1c23d30d796926f7fea4b4f/git_cliff-2.6.1-py3-none-win32.whl", hash = "sha256:f5b943b071bfdbdf1027ba0da529590305ec1be018d4236f0bacf5cf31e60b86", size = 6164541 }, - { url = "https://files.pythonhosted.org/packages/a5/00/432b89766f1b3172a569b70d7f873b2d7c41e43e293b86d3ac75f0126d7d/git_cliff-2.6.1-py3-none-win_amd64.whl", hash = "sha256:59fb3f42b51eb23cf32686f5bb72f4d82b63e28c09c41db8706c9cfee3e9fab6", size = 6878759 }, -] - -[[package]] -name = "gitdb" -version = "4.0.11" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "smmap" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/19/0d/bbb5b5ee188dec84647a4664f3e11b06ade2bde568dbd489d9d64adef8ed/gitdb-4.0.11.tar.gz", hash = "sha256:bf5421126136d6d0af55bc1e7c1af1c397a34f5b7bd79e776cd3e89785c2b04b", size = 394469 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fd/5b/8f0c4a5bb9fd491c277c21eff7ccae71b47d43c4446c9d0c6cff2fe8c2c4/gitdb-4.0.11-py3-none-any.whl", hash = "sha256:81a3407ddd2ee8df444cbacea00e2d038e40150acfa3001696fe0dcf1d3adfa4", size = 62721 }, -] - -[[package]] -name = "gitpython" -version = "3.1.43" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gitdb" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b6/a1/106fd9fa2dd989b6fb36e5893961f82992cf676381707253e0bf93eb1662/GitPython-3.1.43.tar.gz", hash = "sha256:35f314a9f878467f5453cc1fee295c3e18e52f1b99f10f6cf5b1682e968a9e7c", size = 214149 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/bd/cc3a402a6439c15c3d4294333e13042b915bbeab54edc457c723931fed3f/GitPython-3.1.43-py3-none-any.whl", hash = "sha256:eec7ec56b92aad751f9912a73404bc02ba212a23adb2c7098ee668417051a1ff", size = 207337 }, -] - -[[package]] -name = "gotrue" -version = "2.8.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx", extra = ["http2"] }, - { name = "pydantic" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e6/7f/407a0de3c4f57e2be6620be53c2398b550644763b4bddd19d19b29e8be1d/gotrue-2.8.1.tar.gz", hash = "sha256:644d0096c4c390f7e36d9cb05271a7091c01e7dc6d506eb117b8fe8fc48eb8d9", size = 41223 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/ee/4aad2b25941393e956ccda6aea8b2e144dbd780adb893e7f5b7147f0527e/gotrue-2.8.1-py3-none-any.whl", hash = "sha256:97dff077d71cca629f046c35ba34fae132b69c55fe271651766ddcf6d8132468", size = 48388 }, -] - -[[package]] -name = "greenlet" -version = "3.1.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2f/ff/df5fede753cc10f6a5be0931204ea30c35fa2f2ea7a35b25bdaf4fe40e46/greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467", size = 186022 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/25/90/5234a78dc0ef6496a6eb97b67a42a8e96742a56f7dc808cb954a85390448/greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563", size = 271235 }, - { url = "https://files.pythonhosted.org/packages/7c/16/cd631fa0ab7d06ef06387135b7549fdcc77d8d859ed770a0d28e47b20972/greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83", size = 637168 }, - { url = "https://files.pythonhosted.org/packages/2f/b1/aed39043a6fec33c284a2c9abd63ce191f4f1a07319340ffc04d2ed3256f/greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0", size = 648826 }, - { url = "https://files.pythonhosted.org/packages/76/25/40e0112f7f3ebe54e8e8ed91b2b9f970805143efef16d043dfc15e70f44b/greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120", size = 644443 }, - { url = "https://files.pythonhosted.org/packages/fb/2f/3850b867a9af519794784a7eeed1dd5bc68ffbcc5b28cef703711025fd0a/greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc", size = 643295 }, - { url = "https://files.pythonhosted.org/packages/cf/69/79e4d63b9387b48939096e25115b8af7cd8a90397a304f92436bcb21f5b2/greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617", size = 599544 }, - { url = "https://files.pythonhosted.org/packages/46/1d/44dbcb0e6c323bd6f71b8c2f4233766a5faf4b8948873225d34a0b7efa71/greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7", size = 1125456 }, - { url = "https://files.pythonhosted.org/packages/e0/1d/a305dce121838d0278cee39d5bb268c657f10a5363ae4b726848f833f1bb/greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6", size = 1149111 }, - { url = "https://files.pythonhosted.org/packages/96/28/d62835fb33fb5652f2e98d34c44ad1a0feacc8b1d3f1aecab035f51f267d/greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80", size = 298392 }, - { url = "https://files.pythonhosted.org/packages/28/62/1c2665558618553c42922ed47a4e6d6527e2fa3516a8256c2f431c5d0441/greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70", size = 272479 }, - { url = "https://files.pythonhosted.org/packages/76/9d/421e2d5f07285b6e4e3a676b016ca781f63cfe4a0cd8eaecf3fd6f7a71ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159", size = 640404 }, - { url = "https://files.pythonhosted.org/packages/e5/de/6e05f5c59262a584e502dd3d261bbdd2c97ab5416cc9c0b91ea38932a901/greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e", size = 652813 }, - { url = "https://files.pythonhosted.org/packages/49/93/d5f93c84241acdea15a8fd329362c2c71c79e1a507c3f142a5d67ea435ae/greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1", size = 648517 }, - { url = "https://files.pythonhosted.org/packages/15/85/72f77fc02d00470c86a5c982b8daafdf65d38aefbbe441cebff3bf7037fc/greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383", size = 647831 }, - { url = "https://files.pythonhosted.org/packages/f7/4b/1c9695aa24f808e156c8f4813f685d975ca73c000c2a5056c514c64980f6/greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a", size = 602413 }, - { url = "https://files.pythonhosted.org/packages/76/70/ad6e5b31ef330f03b12559d19fda2606a522d3849cde46b24f223d6d1619/greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511", size = 1129619 }, - { url = "https://files.pythonhosted.org/packages/f4/fb/201e1b932e584066e0f0658b538e73c459b34d44b4bd4034f682423bc801/greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395", size = 1155198 }, - { url = "https://files.pythonhosted.org/packages/12/da/b9ed5e310bb8b89661b80cbcd4db5a067903bbcd7fc854923f5ebb4144f0/greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39", size = 298930 }, - { url = "https://files.pythonhosted.org/packages/7d/ec/bad1ac26764d26aa1353216fcbfa4670050f66d445448aafa227f8b16e80/greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d", size = 274260 }, - { url = "https://files.pythonhosted.org/packages/66/d4/c8c04958870f482459ab5956c2942c4ec35cac7fe245527f1039837c17a9/greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79", size = 649064 }, - { url = "https://files.pythonhosted.org/packages/51/41/467b12a8c7c1303d20abcca145db2be4e6cd50a951fa30af48b6ec607581/greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa", size = 663420 }, - { url = "https://files.pythonhosted.org/packages/27/8f/2a93cd9b1e7107d5c7b3b7816eeadcac2ebcaf6d6513df9abaf0334777f6/greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441", size = 658035 }, - { url = "https://files.pythonhosted.org/packages/57/5c/7c6f50cb12be092e1dccb2599be5a942c3416dbcfb76efcf54b3f8be4d8d/greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36", size = 660105 }, - { url = "https://files.pythonhosted.org/packages/f1/66/033e58a50fd9ec9df00a8671c74f1f3a320564c6415a4ed82a1c651654ba/greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9", size = 613077 }, - { url = "https://files.pythonhosted.org/packages/19/c5/36384a06f748044d06bdd8776e231fadf92fc896bd12cb1c9f5a1bda9578/greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0", size = 1135975 }, - { url = "https://files.pythonhosted.org/packages/38/f9/c0a0eb61bdf808d23266ecf1d63309f0e1471f284300ce6dac0ae1231881/greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942", size = 1163955 }, - { url = "https://files.pythonhosted.org/packages/43/21/a5d9df1d21514883333fc86584c07c2b49ba7c602e670b174bd73cfc9c7f/greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01", size = 299655 }, - { url = "https://files.pythonhosted.org/packages/f3/57/0db4940cd7bb461365ca8d6fd53e68254c9dbbcc2b452e69d0d41f10a85e/greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1", size = 272990 }, - { url = "https://files.pythonhosted.org/packages/1c/ec/423d113c9f74e5e402e175b157203e9102feeb7088cee844d735b28ef963/greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff", size = 649175 }, - { url = "https://files.pythonhosted.org/packages/a9/46/ddbd2db9ff209186b7b7c621d1432e2f21714adc988703dbdd0e65155c77/greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a", size = 663425 }, - { url = "https://files.pythonhosted.org/packages/bc/f9/9c82d6b2b04aa37e38e74f0c429aece5eeb02bab6e3b98e7db89b23d94c6/greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e", size = 657736 }, - { url = "https://files.pythonhosted.org/packages/d9/42/b87bc2a81e3a62c3de2b0d550bf91a86939442b7ff85abb94eec3fc0e6aa/greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4", size = 660347 }, - { url = "https://files.pythonhosted.org/packages/37/fa/71599c3fd06336cdc3eac52e6871cfebab4d9d70674a9a9e7a482c318e99/greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e", size = 615583 }, - { url = "https://files.pythonhosted.org/packages/4e/96/e9ef85de031703ee7a4483489b40cf307f93c1824a02e903106f2ea315fe/greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1", size = 1133039 }, - { url = "https://files.pythonhosted.org/packages/87/76/b2b6362accd69f2d1889db61a18c94bc743e961e3cab344c2effaa4b4a25/greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c", size = 1160716 }, - { url = "https://files.pythonhosted.org/packages/1f/1b/54336d876186920e185066d8c3024ad55f21d7cc3683c856127ddb7b13ce/greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761", size = 299490 }, - { url = "https://files.pythonhosted.org/packages/5f/17/bea55bf36990e1638a2af5ba10c1640273ef20f627962cf97107f1e5d637/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011", size = 643731 }, - { url = "https://files.pythonhosted.org/packages/78/d2/aa3d2157f9ab742a08e0fd8f77d4699f37c22adfbfeb0c610a186b5f75e0/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13", size = 649304 }, - { url = "https://files.pythonhosted.org/packages/f1/8e/d0aeffe69e53ccff5a28fa86f07ad1d2d2d6537a9506229431a2a02e2f15/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475", size = 646537 }, - { url = "https://files.pythonhosted.org/packages/05/79/e15408220bbb989469c8871062c97c6c9136770657ba779711b90870d867/greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b", size = 642506 }, - { url = "https://files.pythonhosted.org/packages/18/87/470e01a940307796f1d25f8167b551a968540fbe0551c0ebb853cb527dd6/greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822", size = 602753 }, - { url = "https://files.pythonhosted.org/packages/e2/72/576815ba674eddc3c25028238f74d7b8068902b3968cbe456771b166455e/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01", size = 1122731 }, - { url = "https://files.pythonhosted.org/packages/ac/38/08cc303ddddc4b3d7c628c3039a61a3aae36c241ed01393d00c2fd663473/greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6", size = 1142112 }, -] - -[[package]] -name = "h11" -version = "0.14.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, -] - -[[package]] -name = "h2" -version = "4.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "hpack" }, - { name = "hyperframe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/32/fec683ddd10629ea4ea46d206752a95a2d8a48c22521edd70b142488efe1/h2-4.1.0.tar.gz", hash = "sha256:a83aca08fbe7aacb79fec788c9c0bac936343560ed9ec18b82a13a12c28d2abb", size = 2145593 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e5/db6d438da759efbb488c4f3fbdab7764492ff3c3f953132efa6b9f0e9e53/h2-4.1.0-py3-none-any.whl", hash = "sha256:03a46bcf682256c95b5fd9e9a99c1323584c3eec6440d379b9903d709476bc6d", size = 57488 }, -] - -[[package]] -name = "hpack" -version = "4.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3e/9b/fda93fb4d957db19b0f6b370e79d586b3e8528b20252c729c476a2c02954/hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095", size = 49117 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/34/e8b383f35b77c402d28563d2b8f83159319b509bc5f760b15d60b0abf165/hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", size = 32611 }, -] - -[[package]] -name = "httpcore" -version = "1.0.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "h11" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/17/b0/5e8b8674f8d203335a62fdfcfa0d11ebe09e23613c3391033cbba35f7926/httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61", size = 83234 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/78/d4/e5d7e4f2174f8a4d63c8897d79eb8fe2503f7ecc03282fee1fa2719c2704/httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5", size = 77926 }, -] - -[[package]] -name = "httpx" -version = "0.27.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, - { name = "certifi" }, - { name = "httpcore" }, - { name = "idna" }, - { name = "sniffio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, -] - -[package.optional-dependencies] -http2 = [ - { name = "h2" }, -] - -[[package]] -name = "hyperframe" -version = "6.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/2a/4747bff0a17f7281abe73e955d60d80aae537a5d203f417fa1c2e7578ebb/hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914", size = 25008 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/de/85a784bcc4a3779d1753a7ec2dee5de90e18c7bcf402e71b51fcf150b129/hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", size = 12389 }, -] - -[[package]] -name = "identify" -version = "2.6.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/32/f4/8e8f7db397a7ce20fbdeac5f25adaf567fc362472432938d25556008e03a/identify-2.6.0.tar.gz", hash = "sha256:cb171c685bdc31bcc4c1734698736a7d5b6c8bf2e0c15117f4d469c8640ae5cf", size = 99116 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/24/6c/a4f39abe7f19600b74528d0c717b52fff0b300bb0161081510d39c53cb00/identify-2.6.0-py2.py3-none-any.whl", hash = "sha256:e79ae4406387a9d300332b5fd366d8994f1525e8414984e1a59e058b2eda2dd0", size = 98962 }, -] - -[[package]] -name = "idna" -version = "3.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/e8/ac/e349c5e6d4543326c6883ee9491e3921e0d07b55fdf3cce184b40d63e72a/idna-3.8.tar.gz", hash = "sha256:d838c2c0ed6fced7693d5e8ab8e734d5f8fda53a039c0164afb0b82e771e3603", size = 189467 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/7e/d71db821f177828df9dea8c42ac46473366f191be53080e552e628aad991/idna-3.8-py3-none-any.whl", hash = "sha256:050b4e5baadcd44d760cedbd2b8e639f2ff89bbc7a5730fcc662954303377aac", size = 66894 }, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, -] - -[[package]] -name = "jinja2" -version = "3.1.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ed/55/39036716d19cab0747a5020fc7e907f362fbf48c984b14e62127f7e68e5d/jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", size = 240245 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/31/80/3a54838c3fb461f6fec263ebf3a3a41771bd05190238de3486aae8540c36/jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d", size = 133271 }, -] - -[[package]] -name = "mako" -version = "1.3.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fa/0b/29bc5a230948bf209d3ed3165006d257e547c02c3c2a96f6286320dfe8dc/mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d", size = 390206 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/48/22/bc14c6f02e6dccaafb3eba95764c8f096714260c2aa5f76f654fd16a23dd/Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a", size = 78557 }, -] - -[[package]] -name = "markdown" -version = "3.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/28/3af612670f82f4c056911fbbbb42760255801b3068c48de792d354ff4472/markdown-3.7.tar.gz", hash = "sha256:2ae2471477cfd02dbbf038d5d9bc226d40def84b4fe2986e49b59b6b472bbed2", size = 357086 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3f/08/83871f3c50fc983b88547c196d11cf8c3340e37c32d2e9d6152abe2c61f7/Markdown-3.7-py3-none-any.whl", hash = "sha256:7eb6df5690b81a1d7942992c97fad2938e956e79df20cbc6186e9c3a77b1c803", size = 106349 }, -] - -[[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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, - { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, - { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, - { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, -] - -[[package]] -name = "mergedeep" -version = "1.3.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354 }, -] - -[[package]] -name = "mkdocs" -version = "1.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "colorama", marker = "platform_system == 'Windows'" }, - { name = "ghp-import" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mergedeep" }, - { name = "mkdocs-get-deps" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "pyyaml" }, - { name = "pyyaml-env-tag" }, - { name = "watchdog" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451 }, -] - -[[package]] -name = "mkdocs-get-deps" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mergedeep" }, - { name = "platformdirs" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521 }, -] - -[[package]] -name = "mkdocs-git-revision-date-localized-plugin" -version = "1.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "babel" }, - { name = "gitpython" }, - { name = "mkdocs" }, - { name = "pytz" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/73/85/6dc9d4eca486ed5734a05f7fd5c612a8e60a35e65610dad6aa9c58118c3f/mkdocs_git_revision_date_localized_plugin-1.3.0.tar.gz", hash = "sha256:439e2f14582204050a664c258861c325064d97cdc848c541e48bb034a6c4d0cb", size = 384797 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/67/e5/ffeb92db53af8c3aa2d92e21a3cf6b5f83eee7e03b9cf9234ef6b30230d5/mkdocs_git_revision_date_localized_plugin-1.3.0-py3-none-any.whl", hash = "sha256:c99377ee119372d57a9e47cff4e68f04cce634a74831c06bc89b33e456e840a1", size = 22549 }, -] - -[[package]] -name = "mkdocs-glightbox" -version = "0.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/86/5a/0bc456397ba0acc684b5b1daa4ca232ed717938fd37198251d8bcc4053bf/mkdocs-glightbox-0.4.0.tar.gz", hash = "sha256:392b34207bf95991071a16d5f8916d1d2f2cd5d5bb59ae2997485ccd778c70d9", size = 32010 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/72/b0c2128bb569c732c11ae8e49a777089e77d83c05946062caa19b841e6fb/mkdocs_glightbox-0.4.0-py3-none-any.whl", hash = "sha256:e0107beee75d3eb7380ac06ea2d6eac94c999eaa49f8c3cbab0e7be2ac006ccf", size = 31154 }, -] - -[[package]] -name = "mkdocs-material" -version = "9.5.44" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "babel" }, - { name = "colorama" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "mkdocs" }, - { name = "mkdocs-material-extensions" }, - { name = "paginate" }, - { name = "pygments" }, - { name = "pymdown-extensions" }, - { name = "regex" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/f7/56/182d8121db9ab553cdf9bc58d5972b89833f60b63272f693c1f2b849b640/mkdocs_material-9.5.44.tar.gz", hash = "sha256:f3a6c968e524166b3f3ed1fb97d3ed3e0091183b0545cedf7156a2a6804c56c0", size = 3964306 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ed/eb/a801d00e0e210d82184aacce596906ec065422c78a7319244ba0771c4ded/mkdocs_material-9.5.44-py3-none-any.whl", hash = "sha256:47015f9c167d58a5ff5e682da37441fc4d66a1c79334bfc08d774763cacf69ca", size = 8674509 }, -] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, -] - -[[package]] -name = "mkdocs-obsidian-bridge" -version = "1.1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "mkdocs" }, - { name = "obsidian-media" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/3e/49/19e5dddea68b1383a60df206d38a852e275ddae92959721662a0c134411e/mkdocs_obsidian_bridge-1.1.1.tar.gz", hash = "sha256:9ee0b89c881982a908a18dfc3108d4a8e225c1fc22776052ce4ad2efd17b14f2", size = 49201 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/c5/45b9d09745196cf394ea5ce79e84e9c6f518c9a0687be7c47cf49fe56b20/mkdocs_obsidian_bridge-1.1.1-py3-none-any.whl", hash = "sha256:1c16e45a266e54ae969d5d4dc5457742c991aeafc529878a2598b5a13eb513eb", size = 9727 }, -] - -[[package]] -name = "mkdocs-publisher" -version = "1.4.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beautifulsoup4" }, - { name = "mkdocs" }, - { name = "mkdocs-material" }, - { name = "pymdown-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d3/20/b544c914fadc31b094aefffa3dcbd216542d74a44f7fdf9aa6c7ca97976a/mkdocs_publisher-1.4.3.tar.gz", hash = "sha256:93589b7cf622337f6d8d6f3b1b6a2d18d241c81577ac3633e1aebe69c6fcd04e", size = 44810 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/70/53/8cb97ff9bee2210585c61f43bd39877baca530f172044853e0c4a2bc3413/mkdocs_publisher-1.4.3-py3-none-any.whl", hash = "sha256:dc29352cd4c3384ff2f8ac154d2fd6dd2c54a8c9c541720254fbefcad0536a35", size = 92215 }, -] - -[[package]] -name = "multidict" -version = "6.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d6/be/504b89a5e9ca731cd47487e91c469064f8ae5af93b7259758dcfc2b9c848/multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a", size = 64002 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/29/68/259dee7fd14cf56a17c554125e534f6274c2860159692a414d0b402b9a6d/multidict-6.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3380252550e372e8511d49481bd836264c009adb826b23fefcc5dd3c69692f60", size = 48628 }, - { url = "https://files.pythonhosted.org/packages/50/79/53ba256069fe5386a4a9e80d4e12857ced9de295baf3e20c68cdda746e04/multidict-6.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:99f826cbf970077383d7de805c0681799491cb939c25450b9b5b3ced03ca99f1", size = 29327 }, - { url = "https://files.pythonhosted.org/packages/ff/10/71f1379b05b196dae749b5ac062e87273e3f11634f447ebac12a571d90ae/multidict-6.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a114d03b938376557927ab23f1e950827c3b893ccb94b62fd95d430fd0e5cf53", size = 29689 }, - { url = "https://files.pythonhosted.org/packages/71/45/70bac4f87438ded36ad4793793c0095de6572d433d98575a5752629ef549/multidict-6.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1c416351ee6271b2f49b56ad7f308072f6f44b37118d69c2cad94f3fa8a40d5", size = 126639 }, - { url = "https://files.pythonhosted.org/packages/80/cf/17f35b3b9509b4959303c05379c4bfb0d7dd05c3306039fc79cf035bbac0/multidict-6.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6b5d83030255983181005e6cfbac1617ce9746b219bc2aad52201ad121226581", size = 134315 }, - { url = "https://files.pythonhosted.org/packages/ef/1f/652d70ab5effb33c031510a3503d4d6efc5ec93153562f1ee0acdc895a57/multidict-6.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3e97b5e938051226dc025ec80980c285b053ffb1e25a3db2a3aa3bc046bf7f56", size = 129471 }, - { url = "https://files.pythonhosted.org/packages/a6/64/2dd6c4c681688c0165dea3975a6a4eab4944ea30f35000f8b8af1df3148c/multidict-6.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d618649d4e70ac6efcbba75be98b26ef5078faad23592f9b51ca492953012429", size = 124585 }, - { url = "https://files.pythonhosted.org/packages/87/56/e6ee5459894c7e554b57ba88f7257dc3c3d2d379cb15baaa1e265b8c6165/multidict-6.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10524ebd769727ac77ef2278390fb0068d83f3acb7773792a5080f2b0abf7748", size = 116957 }, - { url = "https://files.pythonhosted.org/packages/36/9e/616ce5e8d375c24b84f14fc263c7ef1d8d5e8ef529dbc0f1df8ce71bb5b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ff3827aef427c89a25cc96ded1759271a93603aba9fb977a6d264648ebf989db", size = 128609 }, - { url = "https://files.pythonhosted.org/packages/8c/4f/4783e48a38495d000f2124020dc96bacc806a4340345211b1ab6175a6cb4/multidict-6.1.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:06809f4f0f7ab7ea2cabf9caca7d79c22c0758b58a71f9d32943ae13c7ace056", size = 123016 }, - { url = "https://files.pythonhosted.org/packages/3e/b3/4950551ab8fc39862ba5e9907dc821f896aa829b4524b4deefd3e12945ab/multidict-6.1.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f179dee3b863ab1c59580ff60f9d99f632f34ccb38bf67a33ec6b3ecadd0fd76", size = 133542 }, - { url = "https://files.pythonhosted.org/packages/96/4d/f0ce6ac9914168a2a71df117935bb1f1781916acdecbb43285e225b484b8/multidict-6.1.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:aaed8b0562be4a0876ee3b6946f6869b7bcdb571a5d1496683505944e268b160", size = 130163 }, - { url = "https://files.pythonhosted.org/packages/be/72/17c9f67e7542a49dd252c5ae50248607dfb780bcc03035907dafefb067e3/multidict-6.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c8b88a2ccf5493b6c8da9076fb151ba106960a2df90c2633f342f120751a9e7", size = 126832 }, - { url = "https://files.pythonhosted.org/packages/71/9f/72d719e248cbd755c8736c6d14780533a1606ffb3fbb0fbd77da9f0372da/multidict-6.1.0-cp310-cp310-win32.whl", hash = "sha256:4a9cb68166a34117d6646c0023c7b759bf197bee5ad4272f420a0141d7eb03a0", size = 26402 }, - { url = "https://files.pythonhosted.org/packages/04/5a/d88cd5d00a184e1ddffc82aa2e6e915164a6d2641ed3606e766b5d2f275a/multidict-6.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:20b9b5fbe0b88d0bdef2012ef7dee867f874b72528cf1d08f1d59b0e3850129d", size = 28800 }, - { url = "https://files.pythonhosted.org/packages/93/13/df3505a46d0cd08428e4c8169a196131d1b0c4b515c3649829258843dde6/multidict-6.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3efe2c2cb5763f2f1b275ad2bf7a287d3f7ebbef35648a9726e3b69284a4f3d6", size = 48570 }, - { url = "https://files.pythonhosted.org/packages/f0/e1/a215908bfae1343cdb72f805366592bdd60487b4232d039c437fe8f5013d/multidict-6.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7053d3b0353a8b9de430a4f4b4268ac9a4fb3481af37dfe49825bf45ca24156", size = 29316 }, - { url = "https://files.pythonhosted.org/packages/70/0f/6dc70ddf5d442702ed74f298d69977f904960b82368532c88e854b79f72b/multidict-6.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:27e5fc84ccef8dfaabb09d82b7d179c7cf1a3fbc8a966f8274fcb4ab2eb4cadb", size = 29640 }, - { url = "https://files.pythonhosted.org/packages/d8/6d/9c87b73a13d1cdea30b321ef4b3824449866bd7f7127eceed066ccb9b9ff/multidict-6.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2b90b43e696f25c62656389d32236e049568b39320e2735d51f08fd362761b", size = 131067 }, - { url = "https://files.pythonhosted.org/packages/cc/1e/1b34154fef373371fd6c65125b3d42ff5f56c7ccc6bfff91b9b3c60ae9e0/multidict-6.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d83a047959d38a7ff552ff94be767b7fd79b831ad1cd9920662db05fec24fe72", size = 138507 }, - { url = "https://files.pythonhosted.org/packages/fb/e0/0bc6b2bac6e461822b5f575eae85da6aae76d0e2a79b6665d6206b8e2e48/multidict-6.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1a9dd711d0877a1ece3d2e4fea11a8e75741ca21954c919406b44e7cf971304", size = 133905 }, - { url = "https://files.pythonhosted.org/packages/ba/af/73d13b918071ff9b2205fcf773d316e0f8fefb4ec65354bbcf0b10908cc6/multidict-6.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec2abea24d98246b94913b76a125e855eb5c434f7c46546046372fe60f666351", size = 129004 }, - { url = "https://files.pythonhosted.org/packages/74/21/23960627b00ed39643302d81bcda44c9444ebcdc04ee5bedd0757513f259/multidict-6.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4867cafcbc6585e4b678876c489b9273b13e9fff9f6d6d66add5e15d11d926cb", size = 121308 }, - { url = "https://files.pythonhosted.org/packages/8b/5c/cf282263ffce4a596ed0bb2aa1a1dddfe1996d6a62d08842a8d4b33dca13/multidict-6.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5b48204e8d955c47c55b72779802b219a39acc3ee3d0116d5080c388970b76e3", size = 132608 }, - { url = "https://files.pythonhosted.org/packages/d7/3e/97e778c041c72063f42b290888daff008d3ab1427f5b09b714f5a8eff294/multidict-6.1.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:d8fff389528cad1618fb4b26b95550327495462cd745d879a8c7c2115248e399", size = 127029 }, - { url = "https://files.pythonhosted.org/packages/47/ac/3efb7bfe2f3aefcf8d103e9a7162572f01936155ab2f7ebcc7c255a23212/multidict-6.1.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a7a9541cd308eed5e30318430a9c74d2132e9a8cb46b901326272d780bf2d423", size = 137594 }, - { url = "https://files.pythonhosted.org/packages/42/9b/6c6e9e8dc4f915fc90a9b7798c44a30773dea2995fdcb619870e705afe2b/multidict-6.1.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:da1758c76f50c39a2efd5e9859ce7d776317eb1dd34317c8152ac9251fc574a3", size = 134556 }, - { url = "https://files.pythonhosted.org/packages/1d/10/8e881743b26aaf718379a14ac58572a240e8293a1c9d68e1418fb11c0f90/multidict-6.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:c943a53e9186688b45b323602298ab727d8865d8c9ee0b17f8d62d14b56f0753", size = 130993 }, - { url = "https://files.pythonhosted.org/packages/45/84/3eb91b4b557442802d058a7579e864b329968c8d0ea57d907e7023c677f2/multidict-6.1.0-cp311-cp311-win32.whl", hash = "sha256:90f8717cb649eea3504091e640a1b8568faad18bd4b9fcd692853a04475a4b80", size = 26405 }, - { url = "https://files.pythonhosted.org/packages/9f/0b/ad879847ecbf6d27e90a6eabb7eff6b62c129eefe617ea45eae7c1f0aead/multidict-6.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:82176036e65644a6cc5bd619f65f6f19781e8ec2e5330f51aa9ada7504cc1926", size = 28795 }, - { url = "https://files.pythonhosted.org/packages/fd/16/92057c74ba3b96d5e211b553895cd6dc7cc4d1e43d9ab8fafc727681ef71/multidict-6.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b04772ed465fa3cc947db808fa306d79b43e896beb677a56fb2347ca1a49c1fa", size = 48713 }, - { url = "https://files.pythonhosted.org/packages/94/3d/37d1b8893ae79716179540b89fc6a0ee56b4a65fcc0d63535c6f5d96f217/multidict-6.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6180c0ae073bddeb5a97a38c03f30c233e0a4d39cd86166251617d1bbd0af436", size = 29516 }, - { url = "https://files.pythonhosted.org/packages/a2/12/adb6b3200c363062f805275b4c1e656be2b3681aada66c80129932ff0bae/multidict-6.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:071120490b47aa997cca00666923a83f02c7fbb44f71cf7f136df753f7fa8761", size = 29557 }, - { url = "https://files.pythonhosted.org/packages/47/e9/604bb05e6e5bce1e6a5cf80a474e0f072e80d8ac105f1b994a53e0b28c42/multidict-6.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50b3a2710631848991d0bf7de077502e8994c804bb805aeb2925a981de58ec2e", size = 130170 }, - { url = "https://files.pythonhosted.org/packages/7e/13/9efa50801785eccbf7086b3c83b71a4fb501a4d43549c2f2f80b8787d69f/multidict-6.1.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b58c621844d55e71c1b7f7c498ce5aa6985d743a1a59034c57a905b3f153c1ef", size = 134836 }, - { url = "https://files.pythonhosted.org/packages/bf/0f/93808b765192780d117814a6dfcc2e75de6dcc610009ad408b8814dca3ba/multidict-6.1.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55b6d90641869892caa9ca42ff913f7ff1c5ece06474fbd32fb2cf6834726c95", size = 133475 }, - { url = "https://files.pythonhosted.org/packages/d3/c8/529101d7176fe7dfe1d99604e48d69c5dfdcadb4f06561f465c8ef12b4df/multidict-6.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b820514bfc0b98a30e3d85462084779900347e4d49267f747ff54060cc33925", size = 131049 }, - { url = "https://files.pythonhosted.org/packages/ca/0c/fc85b439014d5a58063e19c3a158a889deec399d47b5269a0f3b6a2e28bc/multidict-6.1.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:10a9b09aba0c5b48c53761b7c720aaaf7cf236d5fe394cd399c7ba662d5f9966", size = 120370 }, - { url = "https://files.pythonhosted.org/packages/db/46/d4416eb20176492d2258fbd47b4abe729ff3b6e9c829ea4236f93c865089/multidict-6.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e16bf3e5fc9f44632affb159d30a437bfe286ce9e02754759be5536b169b305", size = 125178 }, - { url = "https://files.pythonhosted.org/packages/5b/46/73697ad7ec521df7de5531a32780bbfd908ded0643cbe457f981a701457c/multidict-6.1.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:76f364861c3bfc98cbbcbd402d83454ed9e01a5224bb3a28bf70002a230f73e2", size = 119567 }, - { url = "https://files.pythonhosted.org/packages/cd/ed/51f060e2cb0e7635329fa6ff930aa5cffa17f4c7f5c6c3ddc3500708e2f2/multidict-6.1.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:820c661588bd01a0aa62a1283f20d2be4281b086f80dad9e955e690c75fb54a2", size = 129822 }, - { url = "https://files.pythonhosted.org/packages/df/9e/ee7d1954b1331da3eddea0c4e08d9142da5f14b1321c7301f5014f49d492/multidict-6.1.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:0e5f362e895bc5b9e67fe6e4ded2492d8124bdf817827f33c5b46c2fe3ffaca6", size = 128656 }, - { url = "https://files.pythonhosted.org/packages/77/00/8538f11e3356b5d95fa4b024aa566cde7a38aa7a5f08f4912b32a037c5dc/multidict-6.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3ec660d19bbc671e3a6443325f07263be452c453ac9e512f5eb935e7d4ac28b3", size = 125360 }, - { url = "https://files.pythonhosted.org/packages/be/05/5d334c1f2462d43fec2363cd00b1c44c93a78c3925d952e9a71caf662e96/multidict-6.1.0-cp312-cp312-win32.whl", hash = "sha256:58130ecf8f7b8112cdb841486404f1282b9c86ccb30d3519faf301b2e5659133", size = 26382 }, - { url = "https://files.pythonhosted.org/packages/a3/bf/f332a13486b1ed0496d624bcc7e8357bb8053823e8cd4b9a18edc1d97e73/multidict-6.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:188215fc0aafb8e03341995e7c4797860181562380f81ed0a87ff455b70bf1f1", size = 28529 }, - { url = "https://files.pythonhosted.org/packages/22/67/1c7c0f39fe069aa4e5d794f323be24bf4d33d62d2a348acdb7991f8f30db/multidict-6.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:d569388c381b24671589335a3be6e1d45546c2988c2ebe30fdcada8457a31008", size = 48771 }, - { url = "https://files.pythonhosted.org/packages/3c/25/c186ee7b212bdf0df2519eacfb1981a017bda34392c67542c274651daf23/multidict-6.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:052e10d2d37810b99cc170b785945421141bf7bb7d2f8799d431e7db229c385f", size = 29533 }, - { url = "https://files.pythonhosted.org/packages/67/5e/04575fd837e0958e324ca035b339cea174554f6f641d3fb2b4f2e7ff44a2/multidict-6.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f90c822a402cb865e396a504f9fc8173ef34212a342d92e362ca498cad308e28", size = 29595 }, - { url = "https://files.pythonhosted.org/packages/d3/b2/e56388f86663810c07cfe4a3c3d87227f3811eeb2d08450b9e5d19d78876/multidict-6.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b225d95519a5bf73860323e633a664b0d85ad3d5bede6d30d95b35d4dfe8805b", size = 130094 }, - { url = "https://files.pythonhosted.org/packages/6c/ee/30ae9b4186a644d284543d55d491fbd4239b015d36b23fea43b4c94f7052/multidict-6.1.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:23bfd518810af7de1116313ebd9092cb9aa629beb12f6ed631ad53356ed6b86c", size = 134876 }, - { url = "https://files.pythonhosted.org/packages/84/c7/70461c13ba8ce3c779503c70ec9d0345ae84de04521c1f45a04d5f48943d/multidict-6.1.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c09fcfdccdd0b57867577b719c69e347a436b86cd83747f179dbf0cc0d4c1f3", size = 133500 }, - { url = "https://files.pythonhosted.org/packages/4a/9f/002af221253f10f99959561123fae676148dd730e2daa2cd053846a58507/multidict-6.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf6bea52ec97e95560af5ae576bdac3aa3aae0b6758c6efa115236d9e07dae44", size = 131099 }, - { url = "https://files.pythonhosted.org/packages/82/42/d1c7a7301d52af79d88548a97e297f9d99c961ad76bbe6f67442bb77f097/multidict-6.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57feec87371dbb3520da6192213c7d6fc892d5589a93db548331954de8248fd2", size = 120403 }, - { url = "https://files.pythonhosted.org/packages/68/f3/471985c2c7ac707547553e8f37cff5158030d36bdec4414cb825fbaa5327/multidict-6.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0c3f390dc53279cbc8ba976e5f8035eab997829066756d811616b652b00a23a3", size = 125348 }, - { url = "https://files.pythonhosted.org/packages/67/2c/e6df05c77e0e433c214ec1d21ddd203d9a4770a1f2866a8ca40a545869a0/multidict-6.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:59bfeae4b25ec05b34f1956eaa1cb38032282cd4dfabc5056d0a1ec4d696d3aa", size = 119673 }, - { url = "https://files.pythonhosted.org/packages/c5/cd/bc8608fff06239c9fb333f9db7743a1b2eafe98c2666c9a196e867a3a0a4/multidict-6.1.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:b2f59caeaf7632cc633b5cf6fc449372b83bbdf0da4ae04d5be36118e46cc0aa", size = 129927 }, - { url = "https://files.pythonhosted.org/packages/44/8e/281b69b7bc84fc963a44dc6e0bbcc7150e517b91df368a27834299a526ac/multidict-6.1.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:37bb93b2178e02b7b618893990941900fd25b6b9ac0fa49931a40aecdf083fe4", size = 128711 }, - { url = "https://files.pythonhosted.org/packages/12/a4/63e7cd38ed29dd9f1881d5119f272c898ca92536cdb53ffe0843197f6c85/multidict-6.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4e9f48f58c2c523d5a06faea47866cd35b32655c46b443f163d08c6d0ddb17d6", size = 125519 }, - { url = "https://files.pythonhosted.org/packages/38/e0/4f5855037a72cd8a7a2f60a3952d9aa45feedb37ae7831642102604e8a37/multidict-6.1.0-cp313-cp313-win32.whl", hash = "sha256:3a37ffb35399029b45c6cc33640a92bef403c9fd388acce75cdc88f58bd19a81", size = 26426 }, - { url = "https://files.pythonhosted.org/packages/7e/a5/17ee3a4db1e310b7405f5d25834460073a8ccd86198ce044dfaf69eac073/multidict-6.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:e9aa71e15d9d9beaad2c6b9319edcdc0a49a43ef5c0a4c8265ca9ee7d6c67774", size = 28531 }, - { url = "https://files.pythonhosted.org/packages/99/b7/b9e70fde2c0f0c9af4cc5277782a89b66d35948ea3369ec9f598358c3ac5/multidict-6.1.0-py3-none-any.whl", hash = "sha256:48e171e52d1c4d33888e529b999e5900356b9ae588c2f09a52dcefb158b27506", size = 10051 }, -] - -[[package]] -name = "mypy" -version = "1.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mypy-extensions" }, - { name = "tomli", marker = "python_full_version < '3.11'" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, - { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, - { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, - { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, - { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, - { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, - { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, - { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, - { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, - { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, - { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, - { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, - { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, - { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, - { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, - { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, - { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, - { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, - { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, - { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, - { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, -] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, -] - -[[package]] -name = "nodeenv" -version = "1.9.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, -] - -[[package]] -name = "obsidian-media" -version = "2.0.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2a/fa/99965ada8a2c84195dcd26ca72efc2f4bf515059a075625bcc8269d2abb7/obsidian_media-2.0.0.tar.gz", hash = "sha256:32ba18569f60d2ea747f8fdb72f979bbd265b2ef1305c95ef82d5efe21c7fca5", size = 11348 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/11/f83635e9bb098cbda2ad035bd1f27f48f6cce27aa954a0e11fb735184b4d/obsidian_media-2.0.0-py3-none-any.whl", hash = "sha256:9c1370cf2f6c488ab18fdfd1be1b07ae475d30983c8481dc6ba7836e85f75970", size = 6019 }, -] - -[[package]] -name = "packaging" -version = "24.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/51/65/50db4dda066951078f0a96cf12f4b9ada6e4b811516bf0262c0f4f7064d4/packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002", size = 148788 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/08/aa/cc0199a5f0ad350994d660967a8efb233fe0416e4639146c089643407ce6/packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124", size = 53985 }, -] - -[[package]] -name = "paginate" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746 }, -] - -[[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 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, -] - -[[package]] -name = "platformdirs" -version = "4.2.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/52/0763d1d976d5c262df53ddda8d8d4719eedf9594d046f117c25a27261a19/platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3", size = 20916 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/13/2aa1f0e1364feb2c9ef45302f387ac0bd81484e9c9a4c5688a322fbdfd08/platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee", size = 18146 }, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, -] - -[[package]] -name = "postgrest" -version = "0.16.11" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "deprecation" }, - { name = "httpx", extra = ["http2"] }, - { name = "pydantic" }, - { name = "strenum" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/e8/ba0a844d777130e9403ce7a5d9518f75f7fa4a4d9c267b06fb5899f89268/postgrest-0.16.11.tar.gz", hash = "sha256:10af51b4c39e288ad7df2db92d6a61fb3c4683131b40561f473e3de116e83fa5", size = 15074 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/fb/c1/71ea002b5a9e777d8c80f58d10946fd13b04119c0f4f8604962c0cc450b6/postgrest-0.16.11-py3-none-any.whl", hash = "sha256:22fb6b817ace1f68aa648fd4ce0f56d2786c9260fa4ed2cb9046191231a682b8", size = 21860 }, -] - -[[package]] -name = "pre-commit" -version = "3.8.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "cfgv" }, - { name = "identify" }, - { name = "nodeenv" }, - { name = "pyyaml" }, - { name = "virtualenv" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/64/10/97ee2fa54dff1e9da9badbc5e35d0bbaef0776271ea5907eccf64140f72f/pre_commit-3.8.0.tar.gz", hash = "sha256:8bb6494d4a20423842e198980c9ecf9f96607a07ea29549e180eef9ae80fe7af", size = 177815 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/92/caae8c86e94681b42c246f0bca35c059a2f0529e5b92619f6aba4cf7e7b6/pre_commit-3.8.0-py2.py3-none-any.whl", hash = "sha256:9a90a53bf82fdd8778d58085faf8d83df56e40dfe18f45b19446e26bf1b3a63f", size = 204643 }, -] - -[[package]] -name = "pydantic" -version = "2.8.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "annotated-types" }, - { name = "pydantic-core" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/8c/99/d0a5dca411e0a017762258013ba9905cd6e7baa9a3fd1fe8b6529472902e/pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a", size = 739834 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1f/fa/b7f815b8c9ad021c07f88875b601222ef5e70619391ade4a49234d12d278/pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8", size = 423875 }, -] - -[package.optional-dependencies] -email = [ - { name = "email-validator" }, -] - -[[package]] -name = "pydantic-core" -version = "2.20.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/12/e3/0d5ad91211dba310f7ded335f4dad871172b9cc9ce204f5a56d76ccd6247/pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4", size = 388371 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/9d/f30f080f745682e762512f3eef1f6e392c7d74a102e6e96de8a013a5db84/pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3", size = 1837257 }, - { url = "https://files.pythonhosted.org/packages/f2/89/77e7aebdd4a235497ac1e07f0a99e9f40e47f6e0f6783fe30500df08fc42/pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6", size = 1776715 }, - { url = "https://files.pythonhosted.org/packages/18/50/5a4e9120b395108c2a0441a425356c0d26a655d7c617288bec1c28b854ac/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a", size = 1789023 }, - { url = "https://files.pythonhosted.org/packages/c7/e5/f19e13ba86b968d024b56aa53f40b24828652ac026e5addd0ae49eeada02/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3", size = 1775598 }, - { url = "https://files.pythonhosted.org/packages/c9/c7/f3c29bed28bd022c783baba5bf9946c4f694cb837a687e62f453c81eb5c6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1", size = 1977691 }, - { url = "https://files.pythonhosted.org/packages/41/3e/f62c2a05c554fff34570f6788617e9670c83ed7bc07d62a55cccd1bc0be6/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953", size = 2693214 }, - { url = "https://files.pythonhosted.org/packages/ae/49/8a6fe79d35e2f3bea566d8ea0e4e6f436d4f749d7838c8e8c4c5148ae706/pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98", size = 2061047 }, - { url = "https://files.pythonhosted.org/packages/51/c6/585355c7c8561e11197dbf6333c57dd32f9f62165d48589b57ced2373d97/pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a", size = 1895106 }, - { url = "https://files.pythonhosted.org/packages/ce/23/829f6b87de0775919e82f8addef8b487ace1c77bb4cb754b217f7b1301b6/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a", size = 1968506 }, - { url = "https://files.pythonhosted.org/packages/ca/2f/f8ca8f0c40b3ee0a4d8730a51851adb14c5eda986ec09f8d754b2fba784e/pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840", size = 2110217 }, - { url = "https://files.pythonhosted.org/packages/bb/a0/1876656c7b17eb69cc683452cce6bb890dd722222a71b3de57ddb512f561/pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250", size = 1709669 }, - { url = "https://files.pythonhosted.org/packages/be/4a/576524eefa9b301c088c4818dc50ff1c51a88fe29efd87ab75748ae15fd7/pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c", size = 1902386 }, - { url = "https://files.pythonhosted.org/packages/61/db/f6a724db226d990a329910727cfac43539ff6969edc217286dd05cda3ef6/pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312", size = 1834507 }, - { url = "https://files.pythonhosted.org/packages/9b/83/6f2bfe75209d557ae1c3550c1252684fc1827b8b12fbed84c3b4439e135d/pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88", size = 1773527 }, - { url = "https://files.pythonhosted.org/packages/93/ef/513ea76d7ca81f2354bb9c8d7839fc1157673e652613f7e1aff17d8ce05d/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc", size = 1787879 }, - { url = "https://files.pythonhosted.org/packages/31/0a/ac294caecf235f0cc651de6232f1642bb793af448d1cfc541b0dc1fd72b8/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43", size = 1774694 }, - { url = "https://files.pythonhosted.org/packages/46/a4/08f12b5512f095963550a7cb49ae010e3f8f3f22b45e508c2cb4d7744fce/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6", size = 1976369 }, - { url = "https://files.pythonhosted.org/packages/15/59/b2495be4410462aedb399071c71884042a2c6443319cbf62d00b4a7ed7a5/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121", size = 2691250 }, - { url = "https://files.pythonhosted.org/packages/3c/ae/fc99ce1ba791c9e9d1dee04ce80eef1dae5b25b27e3fc8e19f4e3f1348bf/pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1", size = 2061462 }, - { url = "https://files.pythonhosted.org/packages/44/bb/eb07cbe47cfd638603ce3cb8c220f1a054b821e666509e535f27ba07ca5f/pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b", size = 1893923 }, - { url = "https://files.pythonhosted.org/packages/ce/ef/5a52400553b8faa0e7f11fd7a2ba11e8d2feb50b540f9e7973c49b97eac0/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27", size = 1966779 }, - { url = "https://files.pythonhosted.org/packages/4c/5b/fb37fe341344d9651f5c5f579639cd97d50a457dc53901aa8f7e9f28beb9/pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b", size = 2109044 }, - { url = "https://files.pythonhosted.org/packages/70/1a/6f7278802dbc66716661618807ab0dfa4fc32b09d1235923bbbe8b3a5757/pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a", size = 1708265 }, - { url = "https://files.pythonhosted.org/packages/35/7f/58758c42c61b0bdd585158586fecea295523d49933cb33664ea888162daf/pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2", size = 1901750 }, - { url = "https://files.pythonhosted.org/packages/6f/47/ef0d60ae23c41aced42921728650460dc831a0adf604bfa66b76028cb4d0/pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231", size = 1839225 }, - { url = "https://files.pythonhosted.org/packages/6a/23/430f2878c9cd977a61bb39f71751d9310ec55cee36b3d5bf1752c6341fd0/pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9", size = 1768604 }, - { url = "https://files.pythonhosted.org/packages/9e/2b/ec4e7225dee79e0dc80ccc3c35ab33cc2c4bbb8a1a7ecf060e5e453651ec/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f", size = 1789767 }, - { url = "https://files.pythonhosted.org/packages/64/b0/38b24a1fa6d2f96af3148362e10737ec073768cd44d3ec21dca3be40a519/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52", size = 1772061 }, - { url = "https://files.pythonhosted.org/packages/5e/da/bb73274c42cb60decfa61e9eb0c9029da78b3b9af0a9de0309dbc8ff87b6/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237", size = 1974573 }, - { url = "https://files.pythonhosted.org/packages/c8/65/41693110fb3552556180460daffdb8bbeefb87fc026fd9aa4b849374015c/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe", size = 2625596 }, - { url = "https://files.pythonhosted.org/packages/09/b3/a5a54b47cccd1ab661ed5775235c5e06924753c2d4817737c5667bfa19a8/pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e", size = 2099064 }, - { url = "https://files.pythonhosted.org/packages/52/fa/443a7a6ea54beaba45ff3a59f3d3e6e3004b7460bcfb0be77bcf98719d3b/pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24", size = 1900345 }, - { url = "https://files.pythonhosted.org/packages/8e/e6/9aca9ffae60f9cdf0183069de3e271889b628d0fb175913fcb3db5618fb1/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1", size = 1968252 }, - { url = "https://files.pythonhosted.org/packages/46/5e/6c716810ea20a6419188992973a73c2fb4eb99cd382368d0637ddb6d3c99/pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd", size = 2119191 }, - { url = "https://files.pythonhosted.org/packages/06/fc/6123b00a9240fbb9ae0babad7a005d51103d9a5d39c957a986f5cdd0c271/pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688", size = 1717788 }, - { url = "https://files.pythonhosted.org/packages/d5/36/e61ad5a46607a469e2786f398cd671ebafcd9fb17f09a2359985c7228df5/pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d", size = 1898188 }, - { url = "https://files.pythonhosted.org/packages/49/75/40b0e98b658fdba02a693b3bacb4c875a28bba87796c7b13975976597d8c/pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686", size = 1838688 }, - { url = "https://files.pythonhosted.org/packages/75/02/d8ba2d4a266591a6a623c68b331b96523d4b62ab82a951794e3ed8907390/pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a", size = 1768409 }, - { url = "https://files.pythonhosted.org/packages/91/ae/25ecd9bc4ce4993e99a1a3c9ab111c082630c914260e129572fafed4ecc2/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b", size = 1789317 }, - { url = "https://files.pythonhosted.org/packages/7a/80/72057580681cdbe55699c367963d9c661b569a1d39338b4f6239faf36cdc/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19", size = 1771949 }, - { url = "https://files.pythonhosted.org/packages/a2/be/d9bbabc55b05019013180f141fcaf3b14dbe15ca7da550e95b60c321009a/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac", size = 1974392 }, - { url = "https://files.pythonhosted.org/packages/79/2d/7bcd938c6afb0f40293283f5f09988b61fb0a4f1d180abe7c23a2f665f8e/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703", size = 2625565 }, - { url = "https://files.pythonhosted.org/packages/ac/88/ca758e979457096008a4b16a064509028e3e092a1e85a5ed6c18ced8da88/pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c", size = 2098784 }, - { url = "https://files.pythonhosted.org/packages/eb/de/2fad6d63c3c42e472e985acb12ec45b7f56e42e6f4cd6dfbc5e87ee8678c/pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83", size = 1900198 }, - { url = "https://files.pythonhosted.org/packages/fe/50/077c7f35b6488dc369a6d22993af3a37901e198630f38ac43391ca730f5b/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203", size = 1968005 }, - { url = "https://files.pythonhosted.org/packages/5d/1f/f378631574ead46d636b9a04a80ff878b9365d4b361b1905ef1667d4182a/pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0", size = 2118920 }, - { url = "https://files.pythonhosted.org/packages/7a/ea/e4943f17df7a3031d709481fe4363d4624ae875a6409aec34c28c9e6cf59/pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e", size = 1717397 }, - { url = "https://files.pythonhosted.org/packages/13/63/b95781763e8d84207025071c0cec16d921c0163c7a9033ae4b9a0e020dc7/pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20", size = 1898013 }, - { url = "https://files.pythonhosted.org/packages/73/73/0c7265903f66cce39ed7ca939684fba344210cefc91ccc999cfd5b113fd3/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906", size = 1828190 }, - { url = "https://files.pythonhosted.org/packages/27/55/60b8b0e58b49ee3ed36a18562dd7c6bc06a551c390e387af5872a238f2ec/pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94", size = 1715252 }, - { url = "https://files.pythonhosted.org/packages/28/3d/d66314bad6bb777a36559195a007b31e916bd9e2c198f7bb8f4ccdceb4fa/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f", size = 1782641 }, - { url = "https://files.pythonhosted.org/packages/9e/f5/f178f4354d0d6c1431a8f9ede71f3c4269ac4dc55d314fdb7555814276dc/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482", size = 1928788 }, - { url = "https://files.pythonhosted.org/packages/9c/51/1f5e27bb194df79e30b593b608c66e881ed481241e2b9ed5bdf86d165480/pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6", size = 1886116 }, - { url = "https://files.pythonhosted.org/packages/ac/76/450d9258c58dc7c70b9e3aadf6bebe23ddd99e459c365e2adbde80e238da/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc", size = 1960125 }, - { url = "https://files.pythonhosted.org/packages/dd/9e/0309a7a4bea51771729515e413b3987be0789837de99087f7415e0db1f9b/pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99", size = 2100407 }, - { url = "https://files.pythonhosted.org/packages/af/93/06d44e08277b3b818b75bd5f25e879d7693e4b7dd3505fde89916fcc9ca2/pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6", size = 1914966 }, -] - -[[package]] -name = "pydantic-settings" -version = "2.4.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "python-dotenv" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/58/14/7bfb313ccee79f97dc235721b035174af94ef4472cfe455c259cd2971f2f/pydantic_settings-2.4.0.tar.gz", hash = "sha256:ed81c3a0f46392b4d7c0a565c05884e6e54b3456e6f0fe4d8814981172dc9a88", size = 63033 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/46/7f90f36c1bdcf24962d2b7b0e11aba3bbd65ea7904cb2553072882a4e6b7/pydantic_settings-2.4.0-py3-none-any.whl", hash = "sha256:bb6849dc067f1687574c12a639e231f3a6feeed0a12d710c1382045c5db1c315", size = 23996 }, -] - -[[package]] -name = "pygments" -version = "2.18.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/8e/62/8336eff65bcbc8e4cb5d05b55faf041285951b6e80f33e2bff2024788f31/pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", size = 4891905 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/3f/01c8b82017c199075f8f788d0d906b9ffbbc5a47dc9918a945e13d5a2bda/pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a", size = 1205513 }, -] - -[[package]] -name = "pymdown-extensions" -version = "10.12" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d8/0b/32f05854cfd432e9286bb41a870e0d1a926b72df5f5cdb6dec962b2e369e/pymdown_extensions-10.12.tar.gz", hash = "sha256:b0ee1e0b2bef1071a47891ab17003bfe5bf824a398e13f49f8ed653b699369a7", size = 840790 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/53/32/95a164ddf533bd676cbbe878e36e89b4ade3efde8dd61d0148c90cbbe57e/pymdown_extensions-10.12-py3-none-any.whl", hash = "sha256:49f81412242d3527b8b4967b990df395c89563043bc51a3d2d7d500e52123b77", size = 263448 }, -] - -[[package]] -name = "pytest" -version = "8.3.2" -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 = "tomli", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b4/8c/9862305bdcd6020bc7b45b1b5e7397a6caf1a33d3025b9a003b39075ffb2/pytest-8.3.2.tar.gz", hash = "sha256:c132345d12ce551242c87269de812483f5bcc87cdbb4722e48487ba194f9fdce", size = 1439314 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0f/f9/cf155cf32ca7d6fa3601bc4c5dd19086af4b320b706919d48a4c79081cf9/pytest-8.3.2-py3-none-any.whl", hash = "sha256:4ba08f9ae7dcf84ded419494d229b48d0903ea6407b030eaec46df5e6a73bba5", size = 341802 }, -] - -[[package]] -name = "pytest-dotenv" -version = "0.5.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pytest" }, - { name = "python-dotenv" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/cd/b0/cafee9c627c1bae228eb07c9977f679b3a7cb111b488307ab9594ba9e4da/pytest-dotenv-0.5.2.tar.gz", hash = "sha256:2dc6c3ac6d8764c71c6d2804e902d0ff810fa19692e95fe138aefc9b1aa73732", size = 3782 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/da/9da67c67b3d0963160e3d2cbc7c38b6fae342670cc8e6d5936644b2cf944/pytest_dotenv-0.5.2-py3-none-any.whl", hash = "sha256:40a2cece120a213898afaa5407673f6bd924b1fa7eafce6bda0e8abffe2f710f", size = 3993 }, -] - -[[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 } -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 }, -] - -[[package]] -name = "python-dotenv" -version = "1.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, -] - -[[package]] -name = "python-multipart" -version = "0.0.9" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5c/0f/9c55ac6c84c0336e22a26fa84ca6c51d58d7ac3a2d78b0dfa8748826c883/python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026", size = 31516 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/47/444768600d9e0ebc82f8e347775d24aef8f6348cf00e9fa0e81910814e6d/python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215", size = 22299 }, -] - -[[package]] -name = "pytz" -version = "2024.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/31/3c70bf7603cc2dca0f19bdc53b4537a797747a58875b552c8c413d963a3f/pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", size = 319692 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/11/c3/005fcca25ce078d2cc29fd559379817424e94885510568bc1bc53d7d5846/pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725", size = 508002 }, -] - -[[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 } -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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, - { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, - { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, - { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { 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 }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, -] - -[[package]] -name = "pyyaml-env-tag" -version = "0.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fb/8e/da1c6c58f751b70f8ceb1eb25bc25d524e8f14fe16edcce3f4e3ba08629c/pyyaml_env_tag-0.1.tar.gz", hash = "sha256:70092675bda14fdec33b31ba77e7543de9ddc88f2e5b99160396572d11525bdb", size = 5631 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5a/66/bbb1dd374f5c870f59c5bb1db0e18cbe7fa739415a24cbd95b2d1f5ae0c4/pyyaml_env_tag-0.1-py3-none-any.whl", hash = "sha256:af31106dec8a4d68c60207c1886031cbf839b68aa7abccdb19868200532c2069", size = 3911 }, -] - -[[package]] -name = "realtime" -version = "2.0.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "aiohttp" }, - { name = "python-dateutil" }, - { name = "typing-extensions" }, - { name = "websockets" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/a0/d0/7f98c9d26c3577d8ffcc853ad2f6332851da7a4fcb5bfd485173caeda636/realtime-2.0.2.tar.gz", hash = "sha256:519da9325b3b8102139d51785013d592f6b2403d81fa21d838a0b0234723ed7d", size = 17271 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a3/75/3307fae4fd06288b4211d5e8af960ed30718817a9f6f17e86560a0eca4b8/realtime-2.0.2-py3-none-any.whl", hash = "sha256:2634c915bc38807f2013f21e8bcc4d2f79870dfd81460ddb9393883d0489928a", size = 20222 }, -] - -[[package]] -name = "regex" -version = "2024.9.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f9/38/148df33b4dbca3bd069b963acab5e0fa1a9dbd6820f8c322d0dd6faeff96/regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd", size = 399403 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/63/12/497bd6599ce8a239ade68678132296aec5ee25ebea45fc8ba91aa60fceec/regex-2024.9.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1494fa8725c285a81d01dc8c06b55287a1ee5e0e382d8413adc0a9197aac6408", size = 482488 }, - { url = "https://files.pythonhosted.org/packages/c1/24/595ddb9bec2a9b151cdaf9565b0c9f3da9f0cb1dca6c158bc5175332ddf8/regex-2024.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0e12c481ad92d129c78f13a2a3662317e46ee7ef96c94fd332e1c29131875b7d", size = 287443 }, - { url = "https://files.pythonhosted.org/packages/69/a8/b2fb45d9715b1469383a0da7968f8cacc2f83e9fbbcd6b8713752dd980a6/regex-2024.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:16e13a7929791ac1216afde26f712802e3df7bf0360b32e4914dca3ab8baeea5", size = 284561 }, - { url = "https://files.pythonhosted.org/packages/88/87/1ce4a5357216b19b7055e7d3b0efc75a6e426133bf1e7d094321df514257/regex-2024.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:46989629904bad940bbec2106528140a218b4a36bb3042d8406980be1941429c", size = 783177 }, - { url = "https://files.pythonhosted.org/packages/3c/65/b9f002ab32f7b68e7d1dcabb67926f3f47325b8dbc22cc50b6a043e1d07c/regex-2024.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a906ed5e47a0ce5f04b2c981af1c9acf9e8696066900bf03b9d7879a6f679fc8", size = 823193 }, - { url = "https://files.pythonhosted.org/packages/22/91/8339dd3abce101204d246e31bc26cdd7ec07c9f91598472459a3a902aa41/regex-2024.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e9a091b0550b3b0207784a7d6d0f1a00d1d1c8a11699c1a4d93db3fbefc3ad35", size = 809950 }, - { url = "https://files.pythonhosted.org/packages/cb/19/556638aa11c2ec9968a1da998f07f27ec0abb9bf3c647d7c7985ca0b8eea/regex-2024.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ddcd9a179c0a6fa8add279a4444015acddcd7f232a49071ae57fa6e278f1f71", size = 782661 }, - { url = "https://files.pythonhosted.org/packages/d1/e9/7a5bc4c6ef8d9cd2bdd83a667888fc35320da96a4cc4da5fa084330f53db/regex-2024.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6b41e1adc61fa347662b09398e31ad446afadff932a24807d3ceb955ed865cc8", size = 772348 }, - { url = "https://files.pythonhosted.org/packages/f1/0b/29f2105bfac3ed08e704914c38e93b07c784a6655f8a015297ee7173e95b/regex-2024.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ced479f601cd2f8ca1fd7b23925a7e0ad512a56d6e9476f79b8f381d9d37090a", size = 697460 }, - { url = "https://files.pythonhosted.org/packages/71/3a/52ff61054d15a4722605f5872ad03962b319a04c1ebaebe570b8b9b7dde1/regex-2024.9.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:635a1d96665f84b292e401c3d62775851aedc31d4f8784117b3c68c4fcd4118d", size = 769151 }, - { url = "https://files.pythonhosted.org/packages/97/07/37e460ab5ca84be8e1e197c3b526c5c86993dcc9e13cbc805c35fc2463c1/regex-2024.9.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c0256beda696edcf7d97ef16b2a33a8e5a875affd6fa6567b54f7c577b30a137", size = 777478 }, - { url = "https://files.pythonhosted.org/packages/65/7b/953075723dd5ab00780043ac2f9de667306ff9e2a85332975e9f19279174/regex-2024.9.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:3ce4f1185db3fbde8ed8aa223fc9620f276c58de8b0d4f8cc86fd1360829edb6", size = 845373 }, - { url = "https://files.pythonhosted.org/packages/40/b8/3e9484c6230b8b6e8f816ab7c9a080e631124991a4ae2c27a81631777db0/regex-2024.9.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:09d77559e80dcc9d24570da3745ab859a9cf91953062e4ab126ba9d5993688ca", size = 845369 }, - { url = "https://files.pythonhosted.org/packages/b7/99/38434984d912edbd2e1969d116257e869578f67461bd7462b894c45ed874/regex-2024.9.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7a22ccefd4db3f12b526eccb129390942fe874a3a9fdbdd24cf55773a1faab1a", size = 773935 }, - { url = "https://files.pythonhosted.org/packages/ab/67/43174d2b46fa947b7b9dfe56b6c8a8a76d44223f35b1d64645a732fd1d6f/regex-2024.9.11-cp310-cp310-win32.whl", hash = "sha256:f745ec09bc1b0bd15cfc73df6fa4f726dcc26bb16c23a03f9e3367d357eeedd0", size = 261624 }, - { url = "https://files.pythonhosted.org/packages/c4/2a/4f9c47d9395b6aff24874c761d8d620c0232f97c43ef3cf668c8b355e7a7/regex-2024.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:01c2acb51f8a7d6494c8c5eafe3d8e06d76563d8a8a4643b37e9b2dd8a2ff623", size = 274020 }, - { url = "https://files.pythonhosted.org/packages/86/a1/d526b7b6095a0019aa360948c143aacfeb029919c898701ce7763bbe4c15/regex-2024.9.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2cce2449e5927a0bf084d346da6cd5eb016b2beca10d0013ab50e3c226ffc0df", size = 482483 }, - { url = "https://files.pythonhosted.org/packages/32/d9/bfdd153179867c275719e381e1e8e84a97bd186740456a0dcb3e7125c205/regex-2024.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3b37fa423beefa44919e009745ccbf353d8c981516e807995b2bd11c2c77d268", size = 287442 }, - { url = "https://files.pythonhosted.org/packages/33/c4/60f3370735135e3a8d673ddcdb2507a8560d0e759e1398d366e43d000253/regex-2024.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:64ce2799bd75039b480cc0360907c4fb2f50022f030bf9e7a8705b636e408fad", size = 284561 }, - { url = "https://files.pythonhosted.org/packages/b1/51/91a5ebdff17f9ec4973cb0aa9d37635efec1c6868654bbc25d1543aca4ec/regex-2024.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4cc92bb6db56ab0c1cbd17294e14f5e9224f0cc6521167ef388332604e92679", size = 791779 }, - { url = "https://files.pythonhosted.org/packages/07/4a/022c5e6f0891a90cd7eb3d664d6c58ce2aba48bff107b00013f3d6167069/regex-2024.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d05ac6fa06959c4172eccd99a222e1fbf17b5670c4d596cb1e5cde99600674c4", size = 832605 }, - { url = "https://files.pythonhosted.org/packages/ac/1c/3793990c8c83ca04e018151ddda83b83ecc41d89964f0f17749f027fc44d/regex-2024.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:040562757795eeea356394a7fb13076ad4f99d3c62ab0f8bdfb21f99a1f85664", size = 818556 }, - { url = "https://files.pythonhosted.org/packages/e9/5c/8b385afbfacb853730682c57be56225f9fe275c5bf02ac1fc88edbff316d/regex-2024.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6113c008a7780792efc80f9dfe10ba0cd043cbf8dc9a76ef757850f51b4edc50", size = 792808 }, - { url = "https://files.pythonhosted.org/packages/9b/8b/a4723a838b53c771e9240951adde6af58c829fb6a6a28f554e8131f53839/regex-2024.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e5fb5f77c8745a60105403a774fe2c1759b71d3e7b4ca237a5e67ad066c7199", size = 781115 }, - { url = "https://files.pythonhosted.org/packages/83/5f/031a04b6017033d65b261259c09043c06f4ef2d4eac841d0649d76d69541/regex-2024.9.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:54d9ff35d4515debf14bc27f1e3b38bfc453eff3220f5bce159642fa762fe5d4", size = 778155 }, - { url = "https://files.pythonhosted.org/packages/fd/cd/4660756070b03ce4a66663a43f6c6e7ebc2266cc6b4c586c167917185eb4/regex-2024.9.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:df5cbb1fbc74a8305b6065d4ade43b993be03dbe0f8b30032cced0d7740994bd", size = 784614 }, - { url = "https://files.pythonhosted.org/packages/93/8d/65b9bea7df120a7be8337c415b6d256ba786cbc9107cebba3bf8ff09da99/regex-2024.9.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:7fb89ee5d106e4a7a51bce305ac4efb981536301895f7bdcf93ec92ae0d91c7f", size = 853744 }, - { url = "https://files.pythonhosted.org/packages/96/a7/fba1eae75eb53a704475baf11bd44b3e6ccb95b316955027eb7748f24ef8/regex-2024.9.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a738b937d512b30bf75995c0159c0ddf9eec0775c9d72ac0202076c72f24aa96", size = 855890 }, - { url = "https://files.pythonhosted.org/packages/45/14/d864b2db80a1a3358534392373e8a281d95b28c29c87d8548aed58813910/regex-2024.9.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e28f9faeb14b6f23ac55bfbbfd3643f5c7c18ede093977f1df249f73fd22c7b1", size = 781887 }, - { url = "https://files.pythonhosted.org/packages/4d/a9/bfb29b3de3eb11dc9b412603437023b8e6c02fb4e11311863d9bf62c403a/regex-2024.9.11-cp311-cp311-win32.whl", hash = "sha256:18e707ce6c92d7282dfce370cd205098384b8ee21544e7cb29b8aab955b66fa9", size = 261644 }, - { url = "https://files.pythonhosted.org/packages/c7/ab/1ad2511cf6a208fde57fafe49829cab8ca018128ab0d0b48973d8218634a/regex-2024.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:313ea15e5ff2a8cbbad96ccef6be638393041b0a7863183c2d31e0c6116688cf", size = 274033 }, - { url = "https://files.pythonhosted.org/packages/6e/92/407531450762bed778eedbde04407f68cbd75d13cee96c6f8d6903d9c6c1/regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7", size = 483590 }, - { url = "https://files.pythonhosted.org/packages/8e/a2/048acbc5ae1f615adc6cba36cc45734e679b5f1e4e58c3c77f0ed611d4e2/regex-2024.9.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:49b0e06786ea663f933f3710a51e9385ce0cba0ea56b67107fd841a55d56a231", size = 288175 }, - { url = "https://files.pythonhosted.org/packages/8a/ea/909d8620329ab710dfaf7b4adee41242ab7c9b95ea8d838e9bfe76244259/regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d", size = 284749 }, - { url = "https://files.pythonhosted.org/packages/ca/fa/521eb683b916389b4975337873e66954e0f6d8f91bd5774164a57b503185/regex-2024.9.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ee439691d8c23e76f9802c42a95cfeebf9d47cf4ffd06f18489122dbb0a7ad64", size = 795181 }, - { url = "https://files.pythonhosted.org/packages/28/db/63047feddc3280cc242f9c74f7aeddc6ee662b1835f00046f57d5630c827/regex-2024.9.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a8f877c89719d759e52783f7fe6e1c67121076b87b40542966c02de5503ace42", size = 835842 }, - { url = "https://files.pythonhosted.org/packages/e3/94/86adc259ff8ec26edf35fcca7e334566c1805c7493b192cb09679f9c3dee/regex-2024.9.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:23b30c62d0f16827f2ae9f2bb87619bc4fba2044911e2e6c2eb1af0161cdb766", size = 823533 }, - { url = "https://files.pythonhosted.org/packages/29/52/84662b6636061277cb857f658518aa7db6672bc6d1a3f503ccd5aefc581e/regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a", size = 797037 }, - { url = "https://files.pythonhosted.org/packages/c3/2a/cd4675dd987e4a7505f0364a958bc41f3b84942de9efaad0ef9a2646681c/regex-2024.9.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8dee5b4810a89447151999428fe096977346cf2f29f4d5e29609d2e19e0199c9", size = 784106 }, - { url = "https://files.pythonhosted.org/packages/6f/75/3ea7ec29de0bbf42f21f812f48781d41e627d57a634f3f23947c9a46e303/regex-2024.9.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98eeee2f2e63edae2181c886d7911ce502e1292794f4c5ee71e60e23e8d26b5d", size = 782468 }, - { url = "https://files.pythonhosted.org/packages/d3/67/15519d69b52c252b270e679cb578e22e0c02b8dd4e361f2b04efcc7f2335/regex-2024.9.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:57fdd2e0b2694ce6fc2e5ccf189789c3e2962916fb38779d3e3521ff8fe7a822", size = 790324 }, - { url = "https://files.pythonhosted.org/packages/9c/71/eff77d3fe7ba08ab0672920059ec30d63fa7e41aa0fb61c562726e9bd721/regex-2024.9.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d552c78411f60b1fdaafd117a1fca2f02e562e309223b9d44b7de8be451ec5e0", size = 860214 }, - { url = "https://files.pythonhosted.org/packages/81/11/e1bdf84a72372e56f1ea4b833dd583b822a23138a616ace7ab57a0e11556/regex-2024.9.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a0b2b80321c2ed3fcf0385ec9e51a12253c50f146fddb2abbb10f033fe3d049a", size = 859420 }, - { url = "https://files.pythonhosted.org/packages/ea/75/9753e9dcebfa7c3645563ef5c8a58f3a47e799c872165f37c55737dadd3e/regex-2024.9.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:18406efb2f5a0e57e3a5881cd9354c1512d3bb4f5c45d96d110a66114d84d23a", size = 787333 }, - { url = "https://files.pythonhosted.org/packages/bc/4e/ba1cbca93141f7416624b3ae63573e785d4bc1834c8be44a8f0747919eca/regex-2024.9.11-cp312-cp312-win32.whl", hash = "sha256:e464b467f1588e2c42d26814231edecbcfe77f5ac414d92cbf4e7b55b2c2a776", size = 262058 }, - { url = "https://files.pythonhosted.org/packages/6e/16/efc5f194778bf43e5888209e5cec4b258005d37c613b67ae137df3b89c53/regex-2024.9.11-cp312-cp312-win_amd64.whl", hash = "sha256:9e8719792ca63c6b8340380352c24dcb8cd7ec49dae36e963742a275dfae6009", size = 273526 }, - { url = "https://files.pythonhosted.org/packages/93/0a/d1c6b9af1ff1e36832fe38d74d5c5bab913f2bdcbbd6bc0e7f3ce8b2f577/regex-2024.9.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c157bb447303070f256e084668b702073db99bbb61d44f85d811025fcf38f784", size = 483376 }, - { url = "https://files.pythonhosted.org/packages/a4/42/5910a050c105d7f750a72dcb49c30220c3ae4e2654e54aaaa0e9bc0584cb/regex-2024.9.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4db21ece84dfeefc5d8a3863f101995de646c6cb0536952c321a2650aa202c36", size = 288112 }, - { url = "https://files.pythonhosted.org/packages/8d/56/0c262aff0e9224fa7ffce47b5458d373f4d3e3ff84e99b5ff0cb15e0b5b2/regex-2024.9.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:220e92a30b426daf23bb67a7962900ed4613589bab80382be09b48896d211e92", size = 284608 }, - { url = "https://files.pythonhosted.org/packages/b9/54/9fe8f9aec5007bbbbce28ba3d2e3eaca425f95387b7d1e84f0d137d25237/regex-2024.9.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb1ae19e64c14c7ec1995f40bd932448713d3c73509e82d8cd7744dc00e29e86", size = 795337 }, - { url = "https://files.pythonhosted.org/packages/b2/e7/6b2f642c3cded271c4f16cc4daa7231be544d30fe2b168e0223724b49a61/regex-2024.9.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f47cd43a5bfa48f86925fe26fbdd0a488ff15b62468abb5d2a1e092a4fb10e85", size = 835848 }, - { url = "https://files.pythonhosted.org/packages/cd/9e/187363bdf5d8c0e4662117b92aa32bf52f8f09620ae93abc7537d96d3311/regex-2024.9.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9d4a76b96f398697fe01117093613166e6aa8195d63f1b4ec3f21ab637632963", size = 823503 }, - { url = "https://files.pythonhosted.org/packages/f8/10/601303b8ee93589f879664b0cfd3127949ff32b17f9b6c490fb201106c4d/regex-2024.9.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ea51dcc0835eea2ea31d66456210a4e01a076d820e9039b04ae8d17ac11dee6", size = 797049 }, - { url = "https://files.pythonhosted.org/packages/ef/1c/ea200f61ce9f341763f2717ab4daebe4422d83e9fd4ac5e33435fd3a148d/regex-2024.9.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b7aaa315101c6567a9a45d2839322c51c8d6e81f67683d529512f5bcfb99c802", size = 784144 }, - { url = "https://files.pythonhosted.org/packages/d8/5c/d2429be49ef3292def7688401d3deb11702c13dcaecdc71d2b407421275b/regex-2024.9.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c57d08ad67aba97af57a7263c2d9006d5c404d721c5f7542f077f109ec2a4a29", size = 782483 }, - { url = "https://files.pythonhosted.org/packages/12/d9/cbc30f2ff7164f3b26a7760f87c54bf8b2faed286f60efd80350a51c5b99/regex-2024.9.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:f8404bf61298bb6f8224bb9176c1424548ee1181130818fcd2cbffddc768bed8", size = 790320 }, - { url = "https://files.pythonhosted.org/packages/19/1d/43ed03a236313639da5a45e61bc553c8d41e925bcf29b0f8ecff0c2c3f25/regex-2024.9.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dd4490a33eb909ef5078ab20f5f000087afa2a4daa27b4c072ccb3cb3050ad84", size = 860435 }, - { url = "https://files.pythonhosted.org/packages/34/4f/5d04da61c7c56e785058a46349f7285ae3ebc0726c6ea7c5c70600a52233/regex-2024.9.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:eee9130eaad130649fd73e5cd92f60e55708952260ede70da64de420cdcad554", size = 859571 }, - { url = "https://files.pythonhosted.org/packages/12/7f/8398c8155a3c70703a8e91c29532558186558e1aea44144b382faa2a6f7a/regex-2024.9.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6a2644a93da36c784e546de579ec1806bfd2763ef47babc1b03d765fe560c9f8", size = 787398 }, - { url = "https://files.pythonhosted.org/packages/58/3a/f5903977647a9a7e46d5535e9e96c194304aeeca7501240509bde2f9e17f/regex-2024.9.11-cp313-cp313-win32.whl", hash = "sha256:e997fd30430c57138adc06bba4c7c2968fb13d101e57dd5bb9355bf8ce3fa7e8", size = 262035 }, - { url = "https://files.pythonhosted.org/packages/ff/80/51ba3a4b7482f6011095b3a036e07374f64de180b7d870b704ed22509002/regex-2024.9.11-cp313-cp313-win_amd64.whl", hash = "sha256:042c55879cfeb21a8adacc84ea347721d3d83a159da6acdf1116859e2427c43f", size = 273510 }, -] - -[[package]] -name = "requests" -version = "2.32.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, -] - -[[package]] -name = "six" -version = "1.16.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, -] - -[[package]] -name = "smmap" -version = "5.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/88/04/b5bf6d21dc4041000ccba7eb17dd3055feb237e7ffc2c20d3fae3af62baa/smmap-5.0.1.tar.gz", hash = "sha256:dceeb6c0028fdb6734471eb07c0cd2aae706ccaecab45965ee83f11c8d3b1f62", size = 22291 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/a5/10f97f73544edcdef54409f1d839f6049a0d79df68adbc1ceb24d1aaca42/smmap-5.0.1-py3-none-any.whl", hash = "sha256:e6d8668fa5f93e706934a62d7b4db19c8d9eb8cf2adbb75ef1b675aa332b69da", size = 24282 }, -] - -[[package]] -name = "sniffio" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, -] - -[[package]] -name = "soupsieve" -version = "2.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, -] - -[[package]] -name = "sqlalchemy" -version = "2.0.36" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/50/65/9cbc9c4c3287bed2499e05033e207473504dc4df999ce49385fb1f8b058a/sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", size = 9574485 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/72/14ab694b8b3f0e35ef5beb74a8fea2811aa791ba1611c44dc90cdf46af17/SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", size = 2092604 }, - { url = "https://files.pythonhosted.org/packages/1e/59/333fcbca58b79f5b8b61853d6137530198823392151fa8fd9425f367519e/SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", size = 2083796 }, - { url = "https://files.pythonhosted.org/packages/6c/a0/ec3c188d2b0c1bc742262e76408d44104598d7247c23f5b06bb97ee21bfa/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", size = 3066165 }, - { url = "https://files.pythonhosted.org/packages/07/15/68ef91de5b8b7f80fb2d2b3b31ed42180c6227fe0a701aed9d01d34f98ec/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", size = 3074428 }, - { url = "https://files.pythonhosted.org/packages/e2/4c/9dfea5e63b87325eef6d9cdaac913459aa6a157a05a05ea6ff20004aee8e/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", size = 3030477 }, - { url = "https://files.pythonhosted.org/packages/16/a5/fcfde8e74ea5f683b24add22463bfc21e431d4a5531c8a5b55bc6fbea164/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", size = 3055942 }, - { url = "https://files.pythonhosted.org/packages/3c/ee/c22c415a771d791ae99146d72ffdb20e43625acd24835ea7fc157436d59f/SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", size = 2064960 }, - { url = "https://files.pythonhosted.org/packages/aa/af/ad9c25cadc79bd851bdb9d82b68af9bdb91ff05f56d0da2f8a654825974f/SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", size = 2089078 }, - { url = "https://files.pythonhosted.org/packages/00/4e/5a67963fd7cbc1beb8bd2152e907419f4c940ef04600b10151a751fe9e06/SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", size = 2093782 }, - { url = "https://files.pythonhosted.org/packages/b3/24/30e33b6389ebb5a17df2a4243b091bc709fb3dfc9a48c8d72f8e037c943d/SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", size = 2084180 }, - { url = "https://files.pythonhosted.org/packages/10/1e/70e9ed2143a27065246be40f78637ad5160ea0f5fd32f8cab819a31ff54d/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", size = 3202469 }, - { url = "https://files.pythonhosted.org/packages/b4/5f/95e0ed74093ac3c0db6acfa944d4d8ac6284ef5e1136b878a327ea1f975a/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", size = 3202464 }, - { url = "https://files.pythonhosted.org/packages/91/95/2cf9b85a6bc2ee660e40594dffe04e777e7b8617fd0c6d77a0f782ea96c9/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", size = 3139508 }, - { url = "https://files.pythonhosted.org/packages/92/ea/f0c01bc646456e4345c0fb5a3ddef457326285c2dc60435b0eb96b61bf31/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", size = 3159837 }, - { url = "https://files.pythonhosted.org/packages/a6/93/c8edbf153ee38fe529773240877bf1332ed95328aceef6254288f446994e/SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", size = 2064529 }, - { url = "https://files.pythonhosted.org/packages/b1/03/d12b7c1d36fd80150c1d52e121614cf9377dac99e5497af8d8f5b2a8db64/SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", size = 2089874 }, - { url = "https://files.pythonhosted.org/packages/b8/bf/005dc47f0e57556e14512d5542f3f183b94fde46e15ff1588ec58ca89555/SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", size = 2092378 }, - { url = "https://files.pythonhosted.org/packages/94/65/f109d5720779a08e6e324ec89a744f5f92c48bd8005edc814bf72fbb24e5/SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", size = 2082778 }, - { url = "https://files.pythonhosted.org/packages/60/f6/d9aa8c49c44f9b8c9b9dada1f12fa78df3d4c42aa2de437164b83ee1123c/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53", size = 3232191 }, - { url = "https://files.pythonhosted.org/packages/8a/ab/81d4514527c068670cb1d7ab62a81a185df53a7c379bd2a5636e83d09ede/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", size = 3243044 }, - { url = "https://files.pythonhosted.org/packages/35/b4/f87c014ecf5167dc669199cafdb20a7358ff4b1d49ce3622cc48571f811c/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", size = 3178511 }, - { url = "https://files.pythonhosted.org/packages/ea/09/badfc9293bc3ccba6ede05e5f2b44a760aa47d84da1fc5a326e963e3d4d9/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", size = 3205147 }, - { url = "https://files.pythonhosted.org/packages/c8/60/70e681de02a13c4b27979b7b78da3058c49bacc9858c89ba672e030f03f2/SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", size = 2062709 }, - { url = "https://files.pythonhosted.org/packages/b7/ed/f6cd9395e41bfe47dd253d74d2dfc3cab34980d4e20c8878cb1117306085/SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", size = 2088433 }, - { url = "https://files.pythonhosted.org/packages/78/5c/236398ae3678b3237726819b484f15f5c038a9549da01703a771f05a00d6/SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", size = 2087651 }, - { url = "https://files.pythonhosted.org/packages/a8/14/55c47420c0d23fb67a35af8be4719199b81c59f3084c28d131a7767b0b0b/SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", size = 2078132 }, - { url = "https://files.pythonhosted.org/packages/3d/97/1e843b36abff8c4a7aa2e37f9bea364f90d021754c2de94d792c2d91405b/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", size = 3164559 }, - { url = "https://files.pythonhosted.org/packages/7b/c5/07f18a897b997f6d6b234fab2bf31dccf66d5d16a79fe329aefc95cd7461/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", size = 3177897 }, - { url = "https://files.pythonhosted.org/packages/b3/cd/e16f3cbefd82b5c40b33732da634ec67a5f33b587744c7ab41699789d492/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", size = 3111289 }, - { url = "https://files.pythonhosted.org/packages/15/85/5b8a3b0bc29c9928aa62b5c91fcc8335f57c1de0a6343873b5f372e3672b/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", size = 3139491 }, - { url = "https://files.pythonhosted.org/packages/a1/95/81babb6089938680dfe2cd3f88cd3fd39cccd1543b7cb603b21ad881bff1/SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", size = 2060439 }, - { url = "https://files.pythonhosted.org/packages/c1/ce/5f7428df55660d6879d0522adc73a3364970b5ef33ec17fa125c5dbcac1d/SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", size = 2084574 }, - { url = "https://files.pythonhosted.org/packages/b8/49/21633706dd6feb14cd3f7935fc00b60870ea057686035e1a99ae6d9d9d53/SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", size = 1883787 }, -] - -[[package]] -name = "sqlmodel" -version = "0.0.22" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pydantic" }, - { name = "sqlalchemy" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b5/39/8641040ab0d5e1d8a1c2325ae89a01ae659fc96c61a43d158fb71c9a0bf0/sqlmodel-0.0.22.tar.gz", hash = "sha256:7d37c882a30c43464d143e35e9ecaf945d88035e20117bf5ec2834a23cbe505e", size = 116392 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/b1/3af5104b716c420e40a6ea1b09886cae3a1b9f4538343875f637755cae5b/sqlmodel-0.0.22-py3-none-any.whl", hash = "sha256:a1ed13e28a1f4057cbf4ff6cdb4fc09e85702621d3259ba17b3c230bfb2f941b", size = 28276 }, -] - -[[package]] -name = "starlette" -version = "0.38.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "anyio" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/43/e2/d49a94ecb665b3a1c34b40c78165a737abc384fcabc843ccb14a3bd3dc37/starlette-0.38.2.tar.gz", hash = "sha256:c7c0441065252160993a1a37cf2a73bb64d271b17303e0b0c1eb7191cfb12d75", size = 2844770 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c1/60/d976da9998e4f4a99e297cda09d61ce305919ea94cbeeb476dba4fece098/starlette-0.38.2-py3-none-any.whl", hash = "sha256:4ec6a59df6bbafdab5f567754481657f7ed90dc9d69b0c9ff017907dd54faeff", size = 72020 }, -] - -[[package]] -name = "storage3" -version = "0.7.7" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx", extra = ["http2"] }, - { name = "python-dateutil" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/23/7e/c644337cc0147e1784c34258a518823d505c008282c82305edcbb7ccc600/storage3-0.7.7.tar.gz", hash = "sha256:9fba680cf761d139ad764f43f0e91c245d1ce1af2cc3afe716652f835f48f83e", size = 9282 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/fa/92bd5459ca82d3c24def4f2a72f07f401c4e95de4d44840e2671bed3f052/storage3-0.7.7-py3-none-any.whl", hash = "sha256:ed80a2546cd0b5c22e2c30ea71096db6c99268daf2958c603488e7d72efb8426", size = 16057 }, -] - -[[package]] -name = "strenum" -version = "0.4.15" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/85/ad/430fb60d90e1d112a62ff57bdd1f286ec73a2a0331272febfddd21f330e1/StrEnum-0.4.15.tar.gz", hash = "sha256:878fb5ab705442070e4dd1929bb5e2249511c0bcf2b0eeacf3bcd80875c82eff", size = 23384 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/81/69/297302c5f5f59c862faa31e6cb9a4cd74721cd1e052b38e464c5b402df8b/StrEnum-0.4.15-py3-none-any.whl", hash = "sha256:a30cda4af7cc6b5bf52c8055bc4bf4b2b6b14a93b574626da33df53cf7740659", size = 8851 }, -] - -[[package]] -name = "supabase" -version = "2.7.4" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "gotrue" }, - { name = "httpx" }, - { name = "postgrest" }, - { name = "realtime" }, - { name = "storage3" }, - { name = "supafunc" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/15/5e/5e07134a59fb8ecdf5282ef5fe00d55ab601c31185f867f2ce5adb9009d6/supabase-2.7.4.tar.gz", hash = "sha256:5a979c7711b3c5ce688514fa0afc015780522569494e1a9a9d25d03b7c3d654b", size = 13259 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/af/c9/b7b81e5e5119735717edc8667043cb1c58be5849453d1a6accedb3a6c972/supabase-2.7.4-py3-none-any.whl", hash = "sha256:01815fbc30cac753933d4a44a2529fd13cb7634b56c705c65b12a02c8e75982b", size = 15716 }, -] - -[[package]] -name = "supafunc" -version = "0.5.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "httpx", extra = ["http2"] }, -] -sdist = { url = "https://files.pythonhosted.org/packages/6f/f6/06eefb1975e871b36abc8aebd6e370d441344ac4323d85cad6790709f75a/supafunc-0.5.1.tar.gz", hash = "sha256:1ae9dce6bd935939c561650e86abb676af9665ecf5d4ffc1c7ec3c4932c84334", size = 4087 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/93/ea/da0b3bd36ac21e91a7f3d43c3cc7884b79d96766cb07d1e55a83df0baadd/supafunc-0.5.1-py3-none-any.whl", hash = "sha256:b05e99a2b41270211a3f90ec843c04c5f27a5618f2d2d2eb8e07f41eb962a910", size = 6404 }, -] - -[[package]] -name = "tenacity" -version = "9.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cd/94/91fccdb4b8110642462e653d5dcb27e7b674742ad68efd146367da7bdb10/tenacity-9.0.0.tar.gz", hash = "sha256:807f37ca97d62aa361264d497b0e31e92b8027044942bfa756160d908320d73b", size = 47421 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b6/cb/b86984bed139586d01532a587464b5805f12e397594f19f931c4c2fbfa61/tenacity-9.0.0-py3-none-any.whl", hash = "sha256:93de0c98785b27fcf659856aa9f54bfbd399e29969b0621bc7f762bd441b4539", size = 28169 }, -] - -[[package]] -name = "tomli" -version = "2.0.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f", size = 15164 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", size = 12757 }, -] - -[[package]] -name = "typing-extensions" -version = "4.12.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, -] - -[[package]] -name = "typos" -version = "1.27.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7e/14/9339fffca6831ddb5c003cbfa22841aff2f0f21ae78821960b58e8f46564/typos-1.27.0.tar.gz", hash = "sha256:1ace06f2f107a939d3ddd2cc3517250b08d8ae95297c3722f48f39b899f3c1af", size = 1121281 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/61/a9/534ccebf318b3fa6e46ad6cde12219cc424f548daa79aed963c326e25ce6/typos-1.27.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:4902c9e03c514d8515387301a6509632f45a88db6d86940ee5aee57945d20eb6", size = 3004813 }, - { url = "https://files.pythonhosted.org/packages/51/04/97ae0f5f2f48c802acb58383af71d9543e16e4fb614644d33fd9d7a56739/typos-1.27.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:410b2b23021bb11be49ba7d49ef76be56d400ee04b0aef8a40185dd1f15de366", size = 2907982 }, - { url = "https://files.pythonhosted.org/packages/20/8e/dacd4e4ca5aded54b20ac54eb041997ce815e1cd6abdb2ccc8a1cf360794/typos-1.27.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:98b444ebbe052ec04ef79c351efa8373e5913960ef05c6be910d9c75303f5def", size = 4309079 }, - { url = "https://files.pythonhosted.org/packages/49/ac/ea163be3ee8d33299e9875ac42c38e1a25a5e8975344d77f14b972249f00/typos-1.27.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b2480fdab0e6e01270cf3d0840d6356cacfe2822894cdaf5c6dc9e1f0be5a6e", size = 3379525 }, - { url = "https://files.pythonhosted.org/packages/0b/ab/a258e3c916caf1f5e4945c260cb811b391d66d8f63f183bca4560df90914/typos-1.27.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:64f59c0e9c51d279aafd9fdfc8a392eab4ab56ba0786e3e578755c99592433f4", size = 4093616 }, - { url = "https://files.pythonhosted.org/packages/c2/4b/ad5af38a987cf92079dd967864ce9a88d4149eea08514968380fddcbb4c3/typos-1.27.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:07f2ea4f5ef7079c71116f4427074c330c17531b7ee75ca6693f3bd7fbbae4b0", size = 3911242 }, - { url = "https://files.pythonhosted.org/packages/f0/5f/d4ab810a9168d5d0cf0ea4842f3fc3537d325dcfd12ffc417a69552502e0/typos-1.27.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:984568803b5d87f63d8e1bb26cc16a17e4d942ca0732e01c36ac4311f0809b0f", size = 4096152 }, - { url = "https://files.pythonhosted.org/packages/18/71/0b8f06c7a29edfb7a7e58b4752fa3ae6c7de2ffb9471b1224dafed3347b7/typos-1.27.0-py3-none-win32.whl", hash = "sha256:d93da7e3b1c332378acbaab5b326fbf42b5075860044e11d14f51b310f0e3f03", size = 2431750 }, - { url = "https://files.pythonhosted.org/packages/de/6a/56fe95c40b4d966755d49fabb022ac1fadcbff5469e81a51226d51789c72/typos-1.27.0-py3-none-win_amd64.whl", hash = "sha256:97f799d8428d2f6f2889655a322e582117c6108df4b7de5fb4902d40e3e60850", size = 2562380 }, -] - -[[package]] -name = "urllib3" -version = "2.2.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ed/63/22ba4ebfe7430b76388e7cd448d5478814d3032121827c12a2cc287e2260/urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9", size = 300677 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ce/d9/5f4c13cecde62396b0d3fe530a50ccea91e7dfc1ccf0e09c228841bb5ba8/urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", size = 126338 }, -] - -[[package]] -name = "uvicorn" -version = "0.30.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "h11" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/5a/01/5e637e7aa9dd031be5376b9fb749ec20b86f5a5b6a49b87fabd374d5fa9f/uvicorn-0.30.6.tar.gz", hash = "sha256:4b15decdda1e72be08209e860a1e10e92439ad5b97cf44cc945fcbee66fc5788", size = 42825 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f5/8e/cdc7d6263db313030e4c257dd5ba3909ebc4e4fb53ad62d5f09b1a2f5458/uvicorn-0.30.6-py3-none-any.whl", hash = "sha256:65fd46fe3fda5bdc1b03b94eb634923ff18cd35b2f084813ea79d1f103f711b5", size = 62835 }, -] - -[[package]] -name = "virtualenv" -version = "20.26.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "distlib" }, - { name = "filelock" }, - { name = "platformdirs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/68/60/db9f95e6ad456f1872486769c55628c7901fb4de5a72c2f7bdd912abf0c1/virtualenv-20.26.3.tar.gz", hash = "sha256:4c43a2a236279d9ea36a0d76f98d84bd6ca94ac4e0f4a3b9d46d05e10fea542a", size = 9057588 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/07/4d/410156100224c5e2f0011d435e477b57aed9576fc7fe137abcf14ec16e11/virtualenv-20.26.3-py3-none-any.whl", hash = "sha256:8cc4a31139e796e9a7de2cd5cf2489de1217193116a8fd42328f1bd65f434589", size = 5684792 }, -] - -[[package]] -name = "watchdog" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, - { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, - { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, - { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, - { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, - { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, - { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, - { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, - { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, - { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, - { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, -] - -[[package]] -name = "websockets" -version = "12.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/2e/62/7a7874b7285413c954a4cca3c11fd851f11b2fe5b4ae2d9bee4f6d9bdb10/websockets-12.0.tar.gz", hash = "sha256:81df9cbcbb6c260de1e007e58c011bfebe2dafc8435107b0537f393dd38c8b1b", size = 104994 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b1/b9/360b86ded0920a93bff0db4e4b0aa31370b0208ca240b2e98d62aad8d082/websockets-12.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d554236b2a2006e0ce16315c16eaa0d628dab009c33b63ea03f41c6107958374", size = 124025 }, - { url = "https://files.pythonhosted.org/packages/bb/d3/1eca0d8fb6f0665c96f0dc7c0d0ec8aa1a425e8c003e0c18e1451f65d177/websockets-12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2d225bb6886591b1746b17c0573e29804619c8f755b5598d875bb4235ea639be", size = 121261 }, - { url = "https://files.pythonhosted.org/packages/4e/e1/f6c3ecf7f1bfd9209e13949db027d7fdea2faf090c69b5f2d17d1d796d96/websockets-12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:eb809e816916a3b210bed3c82fb88eaf16e8afcf9c115ebb2bacede1797d2547", size = 121328 }, - { url = "https://files.pythonhosted.org/packages/74/4d/f88eeceb23cb587c4aeca779e3f356cf54817af2368cb7f2bd41f93c8360/websockets-12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c588f6abc13f78a67044c6b1273a99e1cf31038ad51815b3b016ce699f0d75c2", size = 130925 }, - { url = "https://files.pythonhosted.org/packages/16/17/f63d9ee6ffd9afbeea021d5950d6e8db84cd4aead306c6c2ca523805699e/websockets-12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5aa9348186d79a5f232115ed3fa9020eab66d6c3437d72f9d2c8ac0c6858c558", size = 129930 }, - { url = "https://files.pythonhosted.org/packages/9a/12/c7a7504f5bf74d6ee0533f6fc7d30d8f4b79420ab179d1df2484b07602eb/websockets-12.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6350b14a40c95ddd53e775dbdbbbc59b124a5c8ecd6fbb09c2e52029f7a9f480", size = 130245 }, - { url = "https://files.pythonhosted.org/packages/e4/6a/3600c7771eb31116d2e77383d7345618b37bb93709d041e328c08e2a8eb3/websockets-12.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:70ec754cc2a769bcd218ed8d7209055667b30860ffecb8633a834dde27d6307c", size = 134966 }, - { url = "https://files.pythonhosted.org/packages/22/26/df77c4b7538caebb78c9b97f43169ef742a4f445e032a5ea1aaef88f8f46/websockets-12.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6e96f5ed1b83a8ddb07909b45bd94833b0710f738115751cdaa9da1fb0cb66e8", size = 134196 }, - { url = "https://files.pythonhosted.org/packages/e5/18/18ce9a4a08203c8d0d3d561e3ea4f453daf32f099601fc831e60c8a9b0f2/websockets-12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4d87be612cbef86f994178d5186add3d94e9f31cc3cb499a0482b866ec477603", size = 134822 }, - { url = "https://files.pythonhosted.org/packages/45/51/1f823a341fc20a880e67ae62f6c38c4880a24a4b60fbe544a38f516f39a1/websockets-12.0-cp310-cp310-win32.whl", hash = "sha256:befe90632d66caaf72e8b2ed4d7f02b348913813c8b0a32fae1cc5fe3730902f", size = 124454 }, - { url = "https://files.pythonhosted.org/packages/41/b0/5ec054cfcf23adfc88d39359b85e81d043af8a141e3ac8ce40f45a5ce5f4/websockets-12.0-cp310-cp310-win_amd64.whl", hash = "sha256:363f57ca8bc8576195d0540c648aa58ac18cf85b76ad5202b9f976918f4219cf", size = 124974 }, - { url = "https://files.pythonhosted.org/packages/02/73/9c1e168a2e7fdf26841dc98f5f5502e91dea47428da7690a08101f616169/websockets-12.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:5d873c7de42dea355d73f170be0f23788cf3fa9f7bed718fd2830eefedce01b4", size = 124047 }, - { url = "https://files.pythonhosted.org/packages/e4/2d/9a683359ad2ed11b2303a7a94800db19c61d33fa3bde271df09e99936022/websockets-12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3f61726cae9f65b872502ff3c1496abc93ffbe31b278455c418492016e2afc8f", size = 121282 }, - { url = "https://files.pythonhosted.org/packages/95/aa/75fa3b893142d6d98a48cb461169bd268141f2da8bfca97392d6462a02eb/websockets-12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ed2fcf7a07334c77fc8a230755c2209223a7cc44fc27597729b8ef5425aa61a3", size = 121325 }, - { url = "https://files.pythonhosted.org/packages/6e/a4/51a25e591d645df71ee0dc3a2c880b28e5514c00ce752f98a40a87abcd1e/websockets-12.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e332c210b14b57904869ca9f9bf4ca32f5427a03eeb625da9b616c85a3a506c", size = 131502 }, - { url = "https://files.pythonhosted.org/packages/cd/ea/0ceeea4f5b87398fe2d9f5bcecfa00a1bcd542e2bfcac2f2e5dd612c4e9e/websockets-12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5693ef74233122f8ebab026817b1b37fe25c411ecfca084b29bc7d6efc548f45", size = 130491 }, - { url = "https://files.pythonhosted.org/packages/e3/05/f52a60b66d9faf07a4f7d71dc056bffafe36a7e98c4eb5b78f04fe6e4e85/websockets-12.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e9e7db18b4539a29cc5ad8c8b252738a30e2b13f033c2d6e9d0549b45841c04", size = 130872 }, - { url = "https://files.pythonhosted.org/packages/ac/4e/c7361b2d7b964c40fea924d64881145164961fcd6c90b88b7e3ab2c4f431/websockets-12.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6e2df67b8014767d0f785baa98393725739287684b9f8d8a1001eb2839031447", size = 136318 }, - { url = "https://files.pythonhosted.org/packages/0a/31/337bf35ae5faeaf364c9cddec66681cdf51dc4414ee7a20f92a18e57880f/websockets-12.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:bea88d71630c5900690fcb03161ab18f8f244805c59e2e0dc4ffadae0a7ee0ca", size = 135594 }, - { url = "https://files.pythonhosted.org/packages/95/aa/1ac767825c96f9d7e43c4c95683757d4ef28cf11fa47a69aca42428d3e3a/websockets-12.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dff6cdf35e31d1315790149fee351f9e52978130cef6c87c4b6c9b3baf78bc53", size = 136191 }, - { url = "https://files.pythonhosted.org/packages/28/4b/344ec5cfeb6bc417da097f8253607c3aed11d9a305fb58346f506bf556d8/websockets-12.0-cp311-cp311-win32.whl", hash = "sha256:3e3aa8c468af01d70332a382350ee95f6986db479ce7af14d5e81ec52aa2b402", size = 124453 }, - { url = "https://files.pythonhosted.org/packages/d1/40/6b169cd1957476374f51f4486a3e85003149e62a14e6b78a958c2222337a/websockets-12.0-cp311-cp311-win_amd64.whl", hash = "sha256:25eb766c8ad27da0f79420b2af4b85d29914ba0edf69f547cc4f06ca6f1d403b", size = 124971 }, - { url = "https://files.pythonhosted.org/packages/a9/6d/23cc898647c8a614a0d9ca703695dd04322fb5135096a20c2684b7c852b6/websockets-12.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0e6e2711d5a8e6e482cacb927a49a3d432345dfe7dea8ace7b5790df5932e4df", size = 124061 }, - { url = "https://files.pythonhosted.org/packages/39/34/364f30fdf1a375e4002a26ee3061138d1571dfda6421126127d379d13930/websockets-12.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:dbcf72a37f0b3316e993e13ecf32f10c0e1259c28ffd0a85cee26e8549595fbc", size = 121296 }, - { url = "https://files.pythonhosted.org/packages/2e/00/96ae1c9dcb3bc316ef683f2febd8c97dde9f254dc36c3afc65c7645f734c/websockets-12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:12743ab88ab2af1d17dd4acb4645677cb7063ef4db93abffbf164218a5d54c6b", size = 121326 }, - { url = "https://files.pythonhosted.org/packages/af/f1/bba1e64430685dd456c1a1fd6b0c791ae33104967b928aefeff261761e8d/websockets-12.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b645f491f3c48d3f8a00d1fce07445fab7347fec54a3e65f0725d730d5b99cb", size = 131807 }, - { url = "https://files.pythonhosted.org/packages/62/3b/98ee269712f37d892b93852ce07b3e6d7653160ca4c0d4f8c8663f8021f8/websockets-12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9893d1aa45a7f8b3bc4510f6ccf8db8c3b62120917af15e3de247f0780294b92", size = 130751 }, - { url = "https://files.pythonhosted.org/packages/f1/00/d6f01ca2b191f8b0808e4132ccd2e7691f0453cbd7d0f72330eb97453c3a/websockets-12.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1f38a7b376117ef7aff996e737583172bdf535932c9ca021746573bce40165ed", size = 131176 }, - { url = "https://files.pythonhosted.org/packages/af/9c/703ff3cd8109dcdee6152bae055d852ebaa7750117760ded697ab836cbcf/websockets-12.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f764ba54e33daf20e167915edc443b6f88956f37fb606449b4a5b10ba42235a5", size = 136246 }, - { url = "https://files.pythonhosted.org/packages/0b/a5/1a38fb85a456b9dc874ec984f3ff34f6550eafd17a3da28753cd3c1628e8/websockets-12.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1e4b3f8ea6a9cfa8be8484c9221ec0257508e3a1ec43c36acdefb2a9c3b00aa2", size = 135466 }, - { url = "https://files.pythonhosted.org/packages/3c/98/1261f289dff7e65a38d59d2f591de6ed0a2580b729aebddec033c4d10881/websockets-12.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9fdf06fd06c32205a07e47328ab49c40fc1407cdec801d698a7c41167ea45113", size = 136083 }, - { url = "https://files.pythonhosted.org/packages/a9/1c/f68769fba63ccb9c13fe0a25b616bd5aebeef1c7ddebc2ccc32462fb784d/websockets-12.0-cp312-cp312-win32.whl", hash = "sha256:baa386875b70cbd81798fa9f71be689c1bf484f65fd6fb08d051a0ee4e79924d", size = 124460 }, - { url = "https://files.pythonhosted.org/packages/20/52/8915f51f9aaef4e4361c89dd6cf69f72a0159f14e0d25026c81b6ad22525/websockets-12.0-cp312-cp312-win_amd64.whl", hash = "sha256:ae0a5da8f35a5be197f328d4727dbcfafa53d1824fac3d96cdd3a642fe09394f", size = 124985 }, - { url = "https://files.pythonhosted.org/packages/43/8b/554a8a8bb6da9dd1ce04c44125e2192af7b7beebf6e3dbfa5d0e285cc20f/websockets-12.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:248d8e2446e13c1d4326e0a6a4e9629cb13a11195051a73acf414812700badbd", size = 121110 }, - { url = "https://files.pythonhosted.org/packages/b0/8e/58b8812940d746ad74d395fb069497255cb5ef50748dfab1e8b386b1f339/websockets-12.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f44069528d45a933997a6fef143030d8ca8042f0dfaad753e2906398290e2870", size = 123216 }, - { url = "https://files.pythonhosted.org/packages/81/ee/272cb67ace1786ce6d9f39d47b3c55b335e8b75dd1972a7967aad39178b6/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c4e37d36f0d19f0a4413d3e18c0d03d0c268ada2061868c1e6f5ab1a6d575077", size = 122821 }, - { url = "https://files.pythonhosted.org/packages/a8/03/387fc902b397729df166763e336f4e5cec09fe7b9d60f442542c94a21be1/websockets-12.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d829f975fc2e527a3ef2f9c8f25e553eb7bc779c6665e8e1d52aa22800bb38b", size = 122768 }, - { url = "https://files.pythonhosted.org/packages/50/f0/5939fbc9bc1979d79a774ce5b7c4b33c0cefe99af22fb70f7462d0919640/websockets-12.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2c71bd45a777433dd9113847af751aae36e448bc6b8c361a566cb043eda6ec30", size = 125009 }, - { url = "https://files.pythonhosted.org/packages/79/4d/9cc401e7b07e80532ebc8c8e993f42541534da9e9249c59ee0139dcb0352/websockets-12.0-py3-none-any.whl", hash = "sha256:dc284bbc8d7c78a6c69e0c7325ab46ee5e40bb4d50e494d8131a07ef47500e9e", size = 118370 }, -] - -[[package]] -name = "yarl" -version = "1.11.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "idna" }, - { name = "multidict" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e4/3d/4924f9ed49698bac5f112bc9b40aa007bbdcd702462c1df3d2e1383fb158/yarl-1.11.1.tar.gz", hash = "sha256:1bb2d9e212fb7449b8fb73bc461b51eaa17cc8430b4a87d87be7b25052d92f53", size = 162095 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/da/a3/4e67b1463c12ba178aace33b62468377473c77b33a95bcb12b67b2b93817/yarl-1.11.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:400cd42185f92de559d29eeb529e71d80dfbd2f45c36844914a4a34297ca6f00", size = 188473 }, - { url = "https://files.pythonhosted.org/packages/f3/86/c0c76e69a390fb43533783582714e8a58003f443b81cac1605ce71cade00/yarl-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8258c86f47e080a258993eed877d579c71da7bda26af86ce6c2d2d072c11320d", size = 114362 }, - { url = "https://files.pythonhosted.org/packages/07/ef/e6bee78c1bf432de839148fe9fdc1cf5e7fbd6402d8b0b7d7a1522fb9733/yarl-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2164cd9725092761fed26f299e3f276bb4b537ca58e6ff6b252eae9631b5c96e", size = 112537 }, - { url = "https://files.pythonhosted.org/packages/37/f4/3406e76ed71e4d3023dbae4514513a387e2e753cb8a4cadd6ff9ba08a046/yarl-1.11.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08ea567c16f140af8ddc7cb58e27e9138a1386e3e6e53982abaa6f2377b38cc", size = 442573 }, - { url = "https://files.pythonhosted.org/packages/37/15/98b4951271a693142e551fea24bca1e96be71b5256b3091dbe8433532a45/yarl-1.11.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:768ecc550096b028754ea28bf90fde071c379c62c43afa574edc6f33ee5daaec", size = 468046 }, - { url = "https://files.pythonhosted.org/packages/88/1a/f10b88c4d8200708cbc799aad978a37a0ab15a4a72511c60bed11ee585c4/yarl-1.11.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2909fa3a7d249ef64eeb2faa04b7957e34fefb6ec9966506312349ed8a7e77bf", size = 462124 }, - { url = "https://files.pythonhosted.org/packages/02/a3/97b527b5c4551c3b17fd095fe019435664330060b3879c8c1ae80985d4bc/yarl-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:01a8697ec24f17c349c4f655763c4db70eebc56a5f82995e5e26e837c6eb0e49", size = 446807 }, - { url = "https://files.pythonhosted.org/packages/40/06/da47aae54f1bb8ac0668d68bbdde40ba761643f253b2c16fdb4362af8ca3/yarl-1.11.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e286580b6511aac7c3268a78cdb861ec739d3e5a2a53b4809faef6b49778eaff", size = 431778 }, - { url = "https://files.pythonhosted.org/packages/ba/a1/54992cd68f61c11d975184f4c8a4c7f43a838e7c6ce183030a3fc0a257a6/yarl-1.11.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4179522dc0305c3fc9782549175c8e8849252fefeb077c92a73889ccbcd508ad", size = 443702 }, - { url = "https://files.pythonhosted.org/packages/5c/8b/adf290dc272a1a30a0e9dc04e2e62486be80f371bd9da2e9899f8e6181f3/yarl-1.11.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:27fcb271a41b746bd0e2a92182df507e1c204759f460ff784ca614e12dd85145", size = 448289 }, - { url = "https://files.pythonhosted.org/packages/fc/98/e6ad935fa009890b9ef2769266dc9dceaeee5a7f9a57bc7daf50b5b6c305/yarl-1.11.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f61db3b7e870914dbd9434b560075e0366771eecbe6d2b5561f5bc7485f39efd", size = 471660 }, - { url = "https://files.pythonhosted.org/packages/91/5d/1ad82849ce3c02661395f5097878c58ecabc4dac5d2d98e4f85949386448/yarl-1.11.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:c92261eb2ad367629dc437536463dc934030c9e7caca861cc51990fe6c565f26", size = 469830 }, - { url = "https://files.pythonhosted.org/packages/e0/70/376046a7f69cfec814b97fb8bf1af6f16dcbe37fd0ef89a9f87b04156923/yarl-1.11.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d95b52fbef190ca87d8c42f49e314eace4fc52070f3dfa5f87a6594b0c1c6e46", size = 457671 }, - { url = "https://files.pythonhosted.org/packages/33/49/825f84f9a5d26d26fbf82531cee3923f356e2d8efc1819b85ada508fa91f/yarl-1.11.1-cp310-cp310-win32.whl", hash = "sha256:489fa8bde4f1244ad6c5f6d11bb33e09cf0d1d0367edb197619c3e3fc06f3d91", size = 101184 }, - { url = "https://files.pythonhosted.org/packages/b0/29/2a08a45b9f2eddd1b840813698ee655256f43b507c12f7f86df947cf5f8f/yarl-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:476e20c433b356e16e9a141449f25161e6b69984fb4cdbd7cd4bd54c17844998", size = 110175 }, - { url = "https://files.pythonhosted.org/packages/af/f1/f3e6be722461cab1e7c6aea657685897956d6e4743940d685d167914e31c/yarl-1.11.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:946eedc12895873891aaceb39bceb484b4977f70373e0122da483f6c38faaa68", size = 188410 }, - { url = "https://files.pythonhosted.org/packages/4b/c1/21cc66b263fdc2ec10b6459aed5b239f07eed91a77438d88f0e1bd70e202/yarl-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:21a7c12321436b066c11ec19c7e3cb9aec18884fe0d5b25d03d756a9e654edfe", size = 114293 }, - { url = "https://files.pythonhosted.org/packages/31/7a/0ecab63a166a22357772f4a2852c859e2d5a7b02a5c58803458dd516e6b4/yarl-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c35f493b867912f6fda721a59cc7c4766d382040bdf1ddaeeaa7fa4d072f4675", size = 112548 }, - { url = "https://files.pythonhosted.org/packages/57/5d/78152026864475e841fdae816499345364c8e364b45ea6accd0814a295f0/yarl-1.11.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25861303e0be76b60fddc1250ec5986c42f0a5c0c50ff57cc30b1be199c00e63", size = 485002 }, - { url = "https://files.pythonhosted.org/packages/d3/70/2e880d74aeb4908d45c6403e46bbd4aa866ae31ddb432318d9b8042fe0f6/yarl-1.11.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e4b53f73077e839b3f89c992223f15b1d2ab314bdbdf502afdc7bb18e95eae27", size = 504850 }, - { url = "https://files.pythonhosted.org/packages/06/58/5676a47b6d2751853f89d1d68b6a54d725366da6a58482f2410fa7eb38af/yarl-1.11.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:327c724b01b8641a1bf1ab3b232fb638706e50f76c0b5bf16051ab65c868fac5", size = 499291 }, - { url = "https://files.pythonhosted.org/packages/4d/e5/b56d535703a63a8d86ac82059e630e5ba9c0d5626d9c5ac6af53eed815c2/yarl-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4307d9a3417eea87715c9736d050c83e8c1904e9b7aada6ce61b46361b733d92", size = 487818 }, - { url = "https://files.pythonhosted.org/packages/f3/b4/6b95e1e0983593f4145518980b07126a27e2a4938cb6afb8b592ce6fc2c9/yarl-1.11.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:48a28bed68ab8fb7e380775f0029a079f08a17799cb3387a65d14ace16c12e2b", size = 470447 }, - { url = "https://files.pythonhosted.org/packages/a8/e5/5d349b7b04ed4247d4f717f271fce601a79d10e2ac81166c13f97c4973a9/yarl-1.11.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:067b961853c8e62725ff2893226fef3d0da060656a9827f3f520fb1d19b2b68a", size = 484544 }, - { url = "https://files.pythonhosted.org/packages/fa/dc/ce90e9d85ef2233e81148a9658e4ea8372c6de070ce96c5c8bd3ff365144/yarl-1.11.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8215f6f21394d1f46e222abeb06316e77ef328d628f593502d8fc2a9117bde83", size = 482409 }, - { url = "https://files.pythonhosted.org/packages/4c/a1/17c0a03615b0cd213aee2e318a0fbd3d07259c37976d85af9eec6184c589/yarl-1.11.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:498442e3af2a860a663baa14fbf23fb04b0dd758039c0e7c8f91cb9279799bff", size = 512970 }, - { url = "https://files.pythonhosted.org/packages/6c/ed/1e317799d54c79a3e4846db597510f5c84fb7643bb8703a3848136d40809/yarl-1.11.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:69721b8effdb588cb055cc22f7c5105ca6fdaa5aeb3ea09021d517882c4a904c", size = 515203 }, - { url = "https://files.pythonhosted.org/packages/7a/37/9a4e2d73953956fa686fa0f0c4a0881245f39423fa75875d981b4f680611/yarl-1.11.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1e969fa4c1e0b1a391f3fcbcb9ec31e84440253325b534519be0d28f4b6b533e", size = 497323 }, - { url = "https://files.pythonhosted.org/packages/a3/c3/a25ae9c85c0e50a8722aecc486ac5ba53b28d1384548df99b2145cb69862/yarl-1.11.1-cp311-cp311-win32.whl", hash = "sha256:7d51324a04fc4b0e097ff8a153e9276c2593106a811704025bbc1d6916f45ca6", size = 101226 }, - { url = "https://files.pythonhosted.org/packages/90/6d/c62ba0ae0232a0b0012706a7735a16b44a03216fedfb6ea0bcda79d1e12c/yarl-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:15061ce6584ece023457fb8b7a7a69ec40bf7114d781a8c4f5dcd68e28b5c53b", size = 110471 }, - { url = "https://files.pythonhosted.org/packages/3b/05/379002019a0c9d5dc0c4cc6f71e324ea43461ae6f58e94ee87e07b8ffa90/yarl-1.11.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a4264515f9117be204935cd230fb2a052dd3792789cc94c101c535d349b3dab0", size = 189044 }, - { url = "https://files.pythonhosted.org/packages/23/d5/e62cfba5ceaaf92ee4f9af6f9c9ab2f2b47d8ad48687fa69570a93b0872c/yarl-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f41fa79114a1d2eddb5eea7b912d6160508f57440bd302ce96eaa384914cd265", size = 114867 }, - { url = "https://files.pythonhosted.org/packages/b1/10/6abc0bd7e7fe7c6b9b9e9ce0ff558912c9ecae65a798f5442020ef9e4177/yarl-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:02da8759b47d964f9173c8675710720b468aa1c1693be0c9c64abb9d8d9a4867", size = 112737 }, - { url = "https://files.pythonhosted.org/packages/37/a5/ad026afde5efe1849f4f55bd9f9a2cb5b006511b324db430ae5336104fb3/yarl-1.11.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9361628f28f48dcf8b2f528420d4d68102f593f9c2e592bfc842f5fb337e44fd", size = 482887 }, - { url = "https://files.pythonhosted.org/packages/f8/82/b8bee972617b800319b4364cfcd69bfaf7326db052e91a56e63986cc3e05/yarl-1.11.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b91044952da03b6f95fdba398d7993dd983b64d3c31c358a4c89e3c19b6f7aef", size = 498635 }, - { url = "https://files.pythonhosted.org/packages/af/ad/ac688503b134e02e8505415f0b8e94dc8e92a97e82abdd9736658389b5ae/yarl-1.11.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:74db2ef03b442276d25951749a803ddb6e270d02dda1d1c556f6ae595a0d76a8", size = 496198 }, - { url = "https://files.pythonhosted.org/packages/ce/f2/b6cae0ad1afed6e95f82ab2cb9eb5b63e41f1463ece2a80c39d80cf6167a/yarl-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e975a2211952a8a083d1b9d9ba26472981ae338e720b419eb50535de3c02870", size = 489068 }, - { url = "https://files.pythonhosted.org/packages/c8/f4/355e69b5563154b40550233ffba8f6099eac0c99788600191967763046cf/yarl-1.11.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8aef97ba1dd2138112890ef848e17d8526fe80b21f743b4ee65947ea184f07a2", size = 468286 }, - { url = "https://files.pythonhosted.org/packages/26/3d/3c37f3f150faf87b086f7915724f2fcb9ff2f7c9d3f6c0f42b7722bd9b77/yarl-1.11.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7915ea49b0c113641dc4d9338efa9bd66b6a9a485ffe75b9907e8573ca94b84", size = 484568 }, - { url = "https://files.pythonhosted.org/packages/94/ee/d591abbaea3b14e0f68bdec5cbcb75f27107190c51889d518bafe5d8f120/yarl-1.11.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:504cf0d4c5e4579a51261d6091267f9fd997ef58558c4ffa7a3e1460bd2336fa", size = 484947 }, - { url = "https://files.pythonhosted.org/packages/57/70/ad1c65a13315f03ff0c63fd6359dd40d8198e2a42e61bf86507602a0364f/yarl-1.11.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:3de5292f9f0ee285e6bd168b2a77b2a00d74cbcfa420ed078456d3023d2f6dff", size = 505610 }, - { url = "https://files.pythonhosted.org/packages/4c/8c/6086dec0f8d7df16d136b38f373c49cf3d2fb94464e5a10bf788b36f3f54/yarl-1.11.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a34e1e30f1774fa35d37202bbeae62423e9a79d78d0874e5556a593479fdf239", size = 515951 }, - { url = "https://files.pythonhosted.org/packages/49/79/e0479e9a3bbb7bdcb82779d89711b97cea30902a4bfe28d681463b7071ce/yarl-1.11.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:66b63c504d2ca43bf7221a1f72fbe981ff56ecb39004c70a94485d13e37ebf45", size = 501273 }, - { url = "https://files.pythonhosted.org/packages/8e/85/eab962453e81073276b22f3d1503dffe6bfc3eb9cd0f31899970de05d490/yarl-1.11.1-cp312-cp312-win32.whl", hash = "sha256:a28b70c9e2213de425d9cba5ab2e7f7a1c8ca23a99c4b5159bf77b9c31251447", size = 101139 }, - { url = "https://files.pythonhosted.org/packages/5d/de/618b3e5cab10af8a2ed3eb625dac61c1d16eb155d1f56f9fdb3500786c12/yarl-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:17b5a386d0d36fb828e2fb3ef08c8829c1ebf977eef88e5367d1c8c94b454639", size = 110504 }, - { url = "https://files.pythonhosted.org/packages/07/b7/948e4f427817e0178f3737adf6712fea83f76921e11e2092f403a8a9dc4a/yarl-1.11.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:1fa2e7a406fbd45b61b4433e3aa254a2c3e14c4b3186f6e952d08a730807fa0c", size = 185061 }, - { url = "https://files.pythonhosted.org/packages/f3/67/8d91ad79a3b907b4fef27fafa912350554443ba53364fff3c347b41105cb/yarl-1.11.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:750f656832d7d3cb0c76be137ee79405cc17e792f31e0a01eee390e383b2936e", size = 113056 }, - { url = "https://files.pythonhosted.org/packages/a1/77/6b2348a753702fa87f435cc33dcec21981aaca8ef98a46566a7b29940b4a/yarl-1.11.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0b8486f322d8f6a38539136a22c55f94d269addb24db5cb6f61adc61eabc9d93", size = 110958 }, - { url = "https://files.pythonhosted.org/packages/8e/3e/6eadf32656741549041f549a392f3b15245d3a0a0b12a9bc22bd6b69621f/yarl-1.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3fce4da3703ee6048ad4138fe74619c50874afe98b1ad87b2698ef95bf92c96d", size = 470326 }, - { url = "https://files.pythonhosted.org/packages/3d/a4/1b641a8c7899eeaceec45ff105a2e7206ec0eb0fb9d86403963cc8521c5e/yarl-1.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8ed653638ef669e0efc6fe2acb792275cb419bf9cb5c5049399f3556995f23c7", size = 484778 }, - { url = "https://files.pythonhosted.org/packages/8a/f5/80c142f34779a5c26002b2bf1f73b9a9229aa9e019ee6f9fd9d3e9704e78/yarl-1.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:18ac56c9dd70941ecad42b5a906820824ca72ff84ad6fa18db33c2537ae2e089", size = 485568 }, - { url = "https://files.pythonhosted.org/packages/f8/f2/6b40ffea2d5d3a11f514ab23c30d14f52600c36a3210786f5974b6701bb8/yarl-1.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:688654f8507464745ab563b041d1fb7dab5d9912ca6b06e61d1c4708366832f5", size = 477801 }, - { url = "https://files.pythonhosted.org/packages/4c/1a/e60c116f3241e4842ed43c104eb2751abe02f6bac0301cdae69e4fda9c3a/yarl-1.11.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4973eac1e2ff63cf187073cd4e1f1148dcd119314ab79b88e1b3fad74a18c9d5", size = 455361 }, - { url = "https://files.pythonhosted.org/packages/b9/98/fe0aeee425a4bc5cd3ed86e867661d2bfa782544fa07a8e3dcd97d51ae3d/yarl-1.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:964a428132227edff96d6f3cf261573cb0f1a60c9a764ce28cda9525f18f7786", size = 473893 }, - { url = "https://files.pythonhosted.org/packages/6b/9b/677455d146bd3cecd350673f0e4bb28854af66726493ace3b640e9c5552b/yarl-1.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6d23754b9939cbab02c63434776df1170e43b09c6a517585c7ce2b3d449b7318", size = 476407 }, - { url = "https://files.pythonhosted.org/packages/33/ca/ce85766247a9a9b56654428fb78a3e14ea6947a580a9c4e891b3aa7da322/yarl-1.11.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c2dc4250fe94d8cd864d66018f8344d4af50e3758e9d725e94fecfa27588ff82", size = 490848 }, - { url = "https://files.pythonhosted.org/packages/6d/d6/717f0f19bcf2c4705ad95550b4b6319a0d8d1d4f137ea5e223207f00df50/yarl-1.11.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09696438cb43ea6f9492ef237761b043f9179f455f405279e609f2bc9100212a", size = 501084 }, - { url = "https://files.pythonhosted.org/packages/14/b5/b93c70d9a462b802c8df65c64b85f49d86b4ba70c393fbad95cf7ec053cb/yarl-1.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:999bfee0a5b7385a0af5ffb606393509cfde70ecca4f01c36985be6d33e336da", size = 491776 }, - { url = "https://files.pythonhosted.org/packages/03/0f/5a52eaa402a6a93265ba82f42c6f6085ccbe483e1b058ad34207e75812b1/yarl-1.11.1-cp313-cp313-win32.whl", hash = "sha256:ce928c9c6409c79e10f39604a7e214b3cb69552952fbda8d836c052832e6a979", size = 485250 }, - { url = "https://files.pythonhosted.org/packages/dd/97/946d26a5d82706a6769399cabd472c59f9a3227ce1432afb4739b9c29572/yarl-1.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:501c503eed2bb306638ccb60c174f856cc3246c861829ff40eaa80e2f0330367", size = 492590 }, - { url = "https://files.pythonhosted.org/packages/5b/b3/841f7d706137bdc8b741c6826106b6f703155076d58f1830f244da857451/yarl-1.11.1-py3-none-any.whl", hash = "sha256:72bf26f66456baa0584eff63e44545c9f0eaed9b73cb6601b647c91f14c11f38", size = 38648 }, -] From cd255626f68c45f9960231d60ec382fdc4cfcba6 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 15:30:01 +0800 Subject: [PATCH 30/65] fix: super client options --- backend/app/core/auth.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/backend/app/core/auth.py b/backend/app/core/auth.py index ab1d440..4af1108 100644 --- a/backend/app/core/auth.py +++ b/backend/app/core/auth.py @@ -3,11 +3,11 @@ from fastapi import Depends, HTTPException from fastapi.security import OAuth2PasswordBearer +from supabase import AsyncClientOptions +from supabase._async.client import AsyncClient, create_client from app.core.config import settings from app.schemas.auth import UserIn -from supabase._async.client import AsyncClient, create_client -from supabase.lib.client_options import ClientOptions async def get_super_client() -> AsyncClient: @@ -15,7 +15,7 @@ async def get_super_client() -> AsyncClient: super_client = await create_client( settings.SUPABASE_URL, settings.SUPABASE_KEY, - options=ClientOptions(postgrest_client_timeout=10, storage_client_timeout=10), + options=AsyncClientOptions(postgrest_client_timeout=10, storage_client_timeout=10), ) if not super_client: raise HTTPException(status_code=500, detail="Super client not initialized") From 92dd75d4ea5e6358d0c7891841c7a6d4a1a098c9 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 16:12:42 +0800 Subject: [PATCH 31/65] feat: add pre-start.py to init first user --- .env | 2 +- backend/app/core/auth.py | 4 +++- backend/app/core/db.py | 23 ++++++++++++----------- backend/app/models/__init__.py | 4 +++- backend/app/models/item.py | 6 ++++-- backend/app/models/user.py | 8 +++----- backend/app/utils/pre_start.py | 25 +++++++++++++++++++++++++ backend/app/utils/test_pre_start.py | 6 +++--- backend/scripts/pre-start.sh | 13 +++++++++++++ backend/scripts/test.sh | 2 +- 10 files changed, 68 insertions(+), 25 deletions(-) create mode 100644 backend/app/utils/pre_start.py create mode 100755 backend/scripts/pre-start.sh diff --git a/.env b/.env index 0e4dca2..4e6e028 100644 --- a/.env +++ b/.env @@ -13,7 +13,7 @@ PROJECT_NAME="FastAPI Supabase Template" BACKEND_CORS_ORIGINS="http://localhost" SECRET_KEY=local_dev FIRST_SUPERUSER=admin@example.com -FIRST_SUPERUSER_PASSWORD=admin +FIRST_SUPERUSER_PASSWORD=admin12345 # run `supabase status` # API URL diff --git a/backend/app/core/auth.py b/backend/app/core/auth.py index 4af1108..b819b52 100644 --- a/backend/app/core/auth.py +++ b/backend/app/core/auth.py @@ -15,7 +15,9 @@ async def get_super_client() -> AsyncClient: super_client = await create_client( settings.SUPABASE_URL, settings.SUPABASE_KEY, - options=AsyncClientOptions(postgrest_client_timeout=10, storage_client_timeout=10), + options=AsyncClientOptions( + postgrest_client_timeout=10, storage_client_timeout=10 + ), ) if not super_client: raise HTTPException(status_code=500, detail="Super client not initialized") diff --git a/backend/app/core/db.py b/backend/app/core/db.py index 99b49f2..2061407 100644 --- a/backend/app/core/db.py +++ b/backend/app/core/db.py @@ -1,8 +1,7 @@ -from collections.abc import Generator -from typing import AsyncGenerator +from collections.abc import AsyncGenerator from sqlalchemy.ext.asyncio import create_async_engine -from sqlmodel import Session, select +from sqlmodel import select from sqlmodel.ext.asyncio.session import AsyncSession from app.core.auth import get_super_client @@ -13,7 +12,9 @@ # otherwise, SQLModel might fail to initialize relationships properly # for more details: https://github.com/fastapi/full-stack-fastapi-template/issues/28 -engine = create_async_engine(str(settings.SQLALCHEMY_DATABASE_URI), echo=True, future=True) +engine = create_async_engine( + str(settings.SQLALCHEMY_DATABASE_URI), echo=True, future=True +) async def get_db() -> AsyncGenerator[AsyncSession, None]: @@ -21,7 +22,7 @@ async def get_db() -> AsyncGenerator[AsyncSession, None]: yield session -async def init_db(session: Session) -> None: +async def init_db(session: AsyncSession) -> None: # Tables should be created with Alembic migrations # But if you don't want to use migrations, create # the tables un-commenting the next lines @@ -29,10 +30,10 @@ async def init_db(session: Session) -> None: # # This works because the models are already imported and registered from app.models # SQLModel.metadata.create_all(engine) - user = session.exec( + result = await session.exec( select(User).where(User.email == settings.FIRST_SUPERUSER) - ).first() - + ) + user = result.first() if not user: super_client = await get_super_client() response = await super_client.auth.sign_up( @@ -41,6 +42,6 @@ async def init_db(session: Session) -> None: "password": settings.FIRST_SUPERUSER_PASSWORD, } ) - assert response.user.email == settings.FIRST_SUPERUSER - assert response.user.id is not None - assert response.session.access_token is not None + assert response.user.email == settings.FIRST_SUPERUSER + assert response.user.id is not None + assert response.session.access_token is not None diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index 10a1377..c8b677d 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -1,6 +1,8 @@ +from sqlmodel import SQLModel + from .item import Item from .user import User -from sqlmodel import SQLModel + __all__ = ["User", "Item", "Message"] diff --git a/backend/app/models/item.py b/backend/app/models/item.py index aad2678..e503370 100644 --- a/backend/app/models/item.py +++ b/backend/app/models/item.py @@ -1,4 +1,5 @@ import uuid +from datetime import datetime, timezone from sqlmodel import Field, SQLModel @@ -22,10 +23,11 @@ class ItemUpdate(ItemBase): # Database model, database table inferred from class name class Item(ItemBase, table=True): id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) - title: str = Field(max_length=255) owner_id: uuid.UUID = Field( - foreign_key="user.id", nullable=False, ondelete="CASCADE" + foreign_key="auth.users.id", nullable=False, ondelete="CASCADE" ) + created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) + updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) # Properties to return via API, id is always required diff --git a/backend/app/models/user.py b/backend/app/models/user.py index a46259e..071e411 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -1,13 +1,11 @@ import uuid from pydantic import EmailStr -from sqlmodel import Field, Relationship, SQLModel - -from app.models import Item +from sqlmodel import Field, SQLModel class User(SQLModel, table=True): - # __table_args__ = {'extend_existing': True, 'autoload': True} + __tablename__ = "users" + __table_args__ = {"schema": "auth", "extend_existing": True} id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) email: EmailStr = Field(max_length=255) - items: list["Item"] = Relationship(back_populates="owner", cascade_delete=True) diff --git a/backend/app/utils/pre_start.py b/backend/app/utils/pre_start.py new file mode 100644 index 0000000..99da629 --- /dev/null +++ b/backend/app/utils/pre_start.py @@ -0,0 +1,25 @@ +import asyncio +import logging + +from sqlalchemy.ext.asyncio import AsyncEngine +from sqlmodel.ext.asyncio.session import AsyncSession + +from app.core.db import engine, init_db + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +async def init(db_ngine: AsyncEngine) -> None: + async with AsyncSession(db_ngine) as session: + await init_db(session) + + +def main() -> None: + logger.info("Creating initial data") + asyncio.run(init(engine)) + logger.info("Initial data created") + + +if __name__ == "__main__": + main() diff --git a/backend/app/utils/test_pre_start.py b/backend/app/utils/test_pre_start.py index 2684669..3b201f0 100644 --- a/backend/app/utils/test_pre_start.py +++ b/backend/app/utils/test_pre_start.py @@ -30,11 +30,11 @@ async def init(db_engine: AsyncEngine) -> None: raise e -async def main() -> None: +def main() -> None: logger.info("Initializing service") - await init(engine) + asyncio.run(init(engine)) logger.info("Service finished initializing") if __name__ == "__main__": - asyncio.run(main()) + main() diff --git a/backend/scripts/pre-start.sh b/backend/scripts/pre-start.sh new file mode 100755 index 0000000..f92788c --- /dev/null +++ b/backend/scripts/pre-start.sh @@ -0,0 +1,13 @@ +#! /usr/bin/env bash + +set -e +set -x + +# Let the DB start +python -m app.utils.pre_start + +# # Run migrations +# alembic upgrade head + +# # Create initial data in DB +# python app/initial_data.py diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh index 97c2033..df23f70 100755 --- a/backend/scripts/test.sh +++ b/backend/scripts/test.sh @@ -3,6 +3,6 @@ set -e set -x -coverage run --source=src -m pytest +coverage run --source=app -m pytest coverage report --show-missing coverage html --title "${@-coverage}" From e0fbf96e5150271012447f8fb7498c1e136b938e Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 16:21:05 +0800 Subject: [PATCH 32/65] chore: move tests to backend/ --- backend/app/tests/conftest.py | 97 ------------------- backend/app/tests/pre_start/test_db.py | 16 --- backend/pyproject.toml | 2 +- backend/{app => }/tests/.env | 0 backend/{app => }/tests/__init__.py | 0 backend/{app => }/tests/api/__init__.py | 0 .../{app => }/tests/api/api_v1/__init__.py | 0 .../{app => }/tests/api/api_v1/test_items.py | 0 backend/tests/conftest.py | 48 +++++++++ backend/{app => }/tests/crud/__init__.py | 0 backend/{app => }/tests/crud/test_item.py | 0 backend/tests/pre_start/test_db.py | 16 +++ .../{app => }/tests/pre_start/test_main.py | 0 backend/{app => }/tests/utils.py | 0 14 files changed, 65 insertions(+), 114 deletions(-) delete mode 100644 backend/app/tests/conftest.py delete mode 100644 backend/app/tests/pre_start/test_db.py rename backend/{app => }/tests/.env (100%) rename backend/{app => }/tests/__init__.py (100%) rename backend/{app => }/tests/api/__init__.py (100%) rename backend/{app => }/tests/api/api_v1/__init__.py (100%) rename backend/{app => }/tests/api/api_v1/test_items.py (100%) create mode 100644 backend/tests/conftest.py rename backend/{app => }/tests/crud/__init__.py (100%) rename backend/{app => }/tests/crud/test_item.py (100%) create mode 100644 backend/tests/pre_start/test_db.py rename backend/{app => }/tests/pre_start/test_main.py (100%) rename backend/{app => }/tests/utils.py (100%) diff --git a/backend/app/tests/conftest.py b/backend/app/tests/conftest.py deleted file mode 100644 index ab9e7c9..0000000 --- a/backend/app/tests/conftest.py +++ /dev/null @@ -1,97 +0,0 @@ -import logging -import os -from collections.abc import AsyncGenerator, Generator -from logging.handlers import RotatingFileHandler -from pathlib import Path - -import pytest -from faker import Faker -from fastapi.testclient import TestClient -from sqlmodel import Session - -from app.main import app -from app.schemas import Token -from supabase._async.client import create_client - -LOG_FILE = Path(__file__).parent / "scripts.log" - - -def setup_logging(level: int = logging.INFO) -> None: - logger = logging.getLogger() - logger.setLevel(level) - - file_handler = RotatingFileHandler( - LOG_FILE, maxBytes=1024 * 1024 * 5, backupCount=5 - ) - file_handler.setLevel(level) - file_formatter = logging.Formatter( - "%(asctime)s - %(name)s - %(levelname)s - %(message)s" - ) - file_handler.setFormatter(file_formatter) - - console_handler = logging.StreamHandler() - console_handler.setLevel(level) - console_formatter = logging.Formatter("%(name)s - %(levelname)s - %(message)s") - console_handler.setFormatter(console_formatter) - - logger.addHandler(file_handler) - logger.addHandler(console_handler) - - -setup_logging() - - -@pytest.fixture(scope="module") -def anyio_backend() -> str: - return "asyncio" - - -@pytest.fixture(scope="session", autouse=True) -def db() -> Generator[Session, None, None]: - with Session(engine) as session: - yield session - - -@pytest.fixture(scope="module") -def client() -> Generator[TestClient, None, None]: - with TestClient(app) as c: - yield c - - -@pytest.fixture(scope="module") -async def token() -> AsyncGenerator[Token, None]: - url = os.environ.get("SUPABASE_TEST_URL") - assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" - key = os.environ.get("SUPABASE_TEST_KEY") - assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" - db_client = await create_client(url, key) - fake_email = Faker().email() - fake_password = Faker().password() - response = await db_client.auth.sign_up( - {"email": fake_email, "password": fake_password} - ) - assert response.user - assert response.user.email == fake_email - assert response.user.id is not None - - yield Token(access_token=response.session.access_token) - - -# @pytest.fixture(scope="module") -# async def db() -> AsyncGenerator[AsyncClient, None]: -# url = os.environ.get("SUPABASE_TEST_URL") -# assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" -# key = os.environ.get("SUPABASE_TEST_KEY") -# assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" -# db_client = await create_client(url, key) -# # await db_client.auth.sign_in_with_password( -# # {"email": "zhouge1831@gmail.com", "password": "Zz030327#"} -# # ) -# # get_session = await db_client.auth.get_session() -# # assert get_session.user is not None -# # logging.info("db_client.get_session", get_session.user.model_dump()) -# try: -# yield db_client -# finally: -# if db_client: -# await db_client.auth.sign_out() diff --git a/backend/app/tests/pre_start/test_db.py b/backend/app/tests/pre_start/test_db.py deleted file mode 100644 index b1be969..0000000 --- a/backend/app/tests/pre_start/test_db.py +++ /dev/null @@ -1,16 +0,0 @@ -import logging - -import pytest -from sqlmodel import Session - -from src.app.api.deps import engine -from src.app.core.db import init_db - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) - - -@pytest.mark.anyio -async def test_init_db() -> None: - with Session(engine) as session: - await init_db(session) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 1222f8d..55856ff 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -41,7 +41,7 @@ exclude = ["venv", ".venv"] addopts = "-rXs --strict-config --strict-markers" xfail_strict = true # Treat tests that are marked as xfail but pass as test failures filterwarnings = ["error"] # Treat all warnings as errors -pythonpath = "backend" +pythonpath = "app" [tool.coverage.run] branch = true diff --git a/backend/app/tests/.env b/backend/tests/.env similarity index 100% rename from backend/app/tests/.env rename to backend/tests/.env diff --git a/backend/app/tests/__init__.py b/backend/tests/__init__.py similarity index 100% rename from backend/app/tests/__init__.py rename to backend/tests/__init__.py diff --git a/backend/app/tests/api/__init__.py b/backend/tests/api/__init__.py similarity index 100% rename from backend/app/tests/api/__init__.py rename to backend/tests/api/__init__.py diff --git a/backend/app/tests/api/api_v1/__init__.py b/backend/tests/api/api_v1/__init__.py similarity index 100% rename from backend/app/tests/api/api_v1/__init__.py rename to backend/tests/api/api_v1/__init__.py diff --git a/backend/app/tests/api/api_v1/test_items.py b/backend/tests/api/api_v1/test_items.py similarity index 100% rename from backend/app/tests/api/api_v1/test_items.py rename to backend/tests/api/api_v1/test_items.py diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py new file mode 100644 index 0000000..950fe86 --- /dev/null +++ b/backend/tests/conftest.py @@ -0,0 +1,48 @@ +import os +from collections.abc import AsyncGenerator, Generator + +import pytest +from faker import Faker +from fastapi.testclient import TestClient +from sqlmodel.ext.asyncio.session import AsyncSession +from supabase._async.client import create_client + +from app.core.db import engine +from app.main import app +from app.schemas import Token + + +@pytest.fixture(scope="module") +def anyio_backend() -> str: + return "asyncio" + + +@pytest.fixture(scope="module") +async def db() -> AsyncGenerator[AsyncSession, None]: + async with AsyncSession(engine) as session: + yield session + + +@pytest.fixture(scope="module") +def client() -> Generator[TestClient, None, None]: + with TestClient(app) as c: + yield c + + +@pytest.fixture(scope="module") +async def token() -> AsyncGenerator[Token, None]: + url = os.environ.get("SUPABASE_TEST_URL") + assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" + key = os.environ.get("SUPABASE_TEST_KEY") + assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" + db_client = await create_client(url, key) + fake_email = Faker().email() + fake_password = Faker().password() + response = await db_client.auth.sign_up( + {"email": fake_email, "password": fake_password} + ) + assert response.user + assert response.user.email == fake_email + assert response.user.id is not None + + yield Token(access_token=response.session.access_token) diff --git a/backend/app/tests/crud/__init__.py b/backend/tests/crud/__init__.py similarity index 100% rename from backend/app/tests/crud/__init__.py rename to backend/tests/crud/__init__.py diff --git a/backend/app/tests/crud/test_item.py b/backend/tests/crud/test_item.py similarity index 100% rename from backend/app/tests/crud/test_item.py rename to backend/tests/crud/test_item.py diff --git a/backend/tests/pre_start/test_db.py b/backend/tests/pre_start/test_db.py new file mode 100644 index 0000000..ec1ed81 --- /dev/null +++ b/backend/tests/pre_start/test_db.py @@ -0,0 +1,16 @@ +import logging + +import pytest + +from app.core.db import engine +from app.utils.pre_start import init as init_db +from app.utils.test_pre_start import init as connect_db + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + + +@pytest.mark.anyio +async def test_init_db() -> None: + await connect_db(engine) + await init_db(engine) \ No newline at end of file diff --git a/backend/app/tests/pre_start/test_main.py b/backend/tests/pre_start/test_main.py similarity index 100% rename from backend/app/tests/pre_start/test_main.py rename to backend/tests/pre_start/test_main.py diff --git a/backend/app/tests/utils.py b/backend/tests/utils.py similarity index 100% rename from backend/app/tests/utils.py rename to backend/tests/utils.py From 53300afa5b87cee12b05d8ffa19d528e2cda1a72 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 16:27:51 +0800 Subject: [PATCH 33/65] chore: move supabase to root --- {backend/supabase => supabase}/.gitignore | 0 {backend/supabase => supabase}/config.toml | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {backend/supabase => supabase}/.gitignore (100%) rename {backend/supabase => supabase}/config.toml (100%) diff --git a/backend/supabase/.gitignore b/supabase/.gitignore similarity index 100% rename from backend/supabase/.gitignore rename to supabase/.gitignore diff --git a/backend/supabase/config.toml b/supabase/config.toml similarity index 100% rename from backend/supabase/config.toml rename to supabase/config.toml From 7e027c4e1066f0c2188c74e102c7ef667094586e Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 16:58:33 +0800 Subject: [PATCH 34/65] feat: add timestamp_log --- backend/app/core/events.py | 19 ------------------- backend/app/main.py | 21 ++++++++++++++------- 2 files changed, 14 insertions(+), 26 deletions(-) delete mode 100644 backend/app/core/events.py diff --git a/backend/app/core/events.py b/backend/app/core/events.py deleted file mode 100644 index 4f2c1d6..0000000 --- a/backend/app/core/events.py +++ /dev/null @@ -1,19 +0,0 @@ -""" -life span events -""" - -import logging -from collections.abc import AsyncGenerator -from contextlib import asynccontextmanager - -from fastapi import FastAPI - - -@asynccontextmanager -async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 - """life span events""" - try: - logging.info("lifespan start") - yield - finally: - logging.info("lifespan shutdown") diff --git a/backend/app/main.py b/backend/app/main.py index 4a79bf9..cc6d197 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -13,6 +13,7 @@ logger = logging.getLogger("uvicorn") + @asynccontextmanager async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 """life span events""" @@ -44,16 +45,22 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 # Include the routers app.include_router(api_router, prefix=settings.API_V1_STR) + # Logger def timestamp_log_config(uvicorn_log_config: dict[str, Any]) -> dict[str, Any]: """https://github.com/fastapi/fastapi/discussions/7457#discussioncomment-5565969""" - datefmt = '%d-%m-%Y %H:%M:%S' - formatters = uvicorn_log_config['formatters'] - formatters['default']['fmt'] = '%(levelprefix)s [%(asctime)s] %(message)s' - formatters['access']['fmt'] = '%(levelprefix)s [%(asctime)s] %(client_addr)s - "%(request_line)s" %(status_code)s' - formatters['access']['datefmt'] = datefmt - formatters['default']['datefmt'] = datefmt + datefmt = "%d-%m-%Y %H:%M:%S" + formatters = uvicorn_log_config["formatters"] + formatters["default"]["fmt"] = "%(levelprefix)s [%(asctime)s] %(message)s" + formatters["access"]["fmt"] = ( + '%(levelprefix)s [%(asctime)s] %(client_addr)s - "%(request_line)s" %(status_code)s' + ) + formatters["access"]["datefmt"] = datefmt + formatters["default"]["datefmt"] = datefmt return uvicorn_log_config + if __name__ == "__main__": - uvicorn.run(app, host="0.0.0.0", port=8000,log_config=timestamp_log_config(LOGGING_CONFIG)) + uvicorn.run( + app, host="0.0.0.0", port=8000, log_config=timestamp_log_config(LOGGING_CONFIG) + ) From 666119bf706cf2675493ff1cd4d53ee75fa59bc3 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 17:00:00 +0800 Subject: [PATCH 35/65] chore: remove pre_start.py as init_data.py --- backend/app/utils/{pre_start.py => init_data.py} | 0 backend/tests/pre_start/test_db.py | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) rename backend/app/utils/{pre_start.py => init_data.py} (100%) diff --git a/backend/app/utils/pre_start.py b/backend/app/utils/init_data.py similarity index 100% rename from backend/app/utils/pre_start.py rename to backend/app/utils/init_data.py diff --git a/backend/tests/pre_start/test_db.py b/backend/tests/pre_start/test_db.py index ec1ed81..1a9d849 100644 --- a/backend/tests/pre_start/test_db.py +++ b/backend/tests/pre_start/test_db.py @@ -3,7 +3,7 @@ import pytest from app.core.db import engine -from app.utils.pre_start import init as init_db +from app.utils.init_data import init as init_db from app.utils.test_pre_start import init as connect_db logging.basicConfig(level=logging.INFO) @@ -13,4 +13,4 @@ @pytest.mark.anyio async def test_init_db() -> None: await connect_db(engine) - await init_db(engine) \ No newline at end of file + await init_db(engine) From 11f40420349f5a2ae3f01c6f8c6e46b752fda492 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 17:00:42 +0800 Subject: [PATCH 36/65] fix: format path --- backend/scripts/format.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/scripts/format.sh b/backend/scripts/format.sh index b1eb52e..8d214af 100755 --- a/backend/scripts/format.sh +++ b/backend/scripts/format.sh @@ -1,5 +1,5 @@ #!/bin/sh -e set -x -ruff check app scripts app/tests --fix -ruff format app scripts app/tests +ruff check app scripts tests --fix +ruff format app scripts tests From 04cc4d4768419e88863913445e5ad791fe6c9641 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 17:01:29 +0800 Subject: [PATCH 37/65] chore(deps): add psycopg2 --- backend/pyproject.toml | 11 +++++--- backend/uv.lock | 60 ++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index 55856ff..fc5915f 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "app" -dynamic = ["version"] +version = "0.4.1" requires-python = ">=3.10" dependencies = [ "uvicorn>=0.30.6", @@ -13,6 +13,7 @@ dependencies = [ "asyncpg>=0.30.0", "alembic>=1.14.0", "tenacity>=9.0.0", + "psycopg2-binary>=2.9.10", ] [dependency-groups] @@ -26,10 +27,14 @@ dev = [ "pytest>=8.3.2", ] +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + ## Test [tool.mypy] strict = true -exclude = ["venv", ".venv"] +exclude = ["venv", ".venv", "alembic"] [tool.pytest.ini_options] # Set additional command line options for pytest= @@ -68,7 +73,7 @@ exclude_lines = [ ## Linter and formatter [tool.ruff] # cover and extend the default config in https=//docs.astral.sh/ruff/configuration/ -extend-exclude = [""] +extend-exclude = ["alembic"] target-version = "py310" [tool.ruff.lint] diff --git a/backend/uv.lock b/backend/uv.lock index 6d35a70..3996156 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -143,12 +143,13 @@ wheels = [ [[package]] name = "app" -version = "0.0.0" -source = { virtual = "." } +version = "0.4.1" +source = { editable = "." } dependencies = [ { name = "alembic" }, { name = "asyncpg" }, { name = "fastapi" }, + { name = "psycopg2-binary" }, { name = "pydantic", extra = ["email"] }, { name = "pydantic-settings" }, { name = "python-multipart" }, @@ -174,6 +175,7 @@ requires-dist = [ { name = "alembic", specifier = ">=1.14.0" }, { name = "asyncpg", specifier = ">=0.30.0" }, { name = "fastapi", specifier = ">=0.112.2" }, + { name = "psycopg2-binary", specifier = ">=2.9.10" }, { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, { name = "pydantic-settings", specifier = ">=2.4.0" }, { name = "python-multipart", specifier = ">=0.0.9" }, @@ -1000,6 +1002,60 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 }, ] +[[package]] +name = "psycopg2-binary" +version = "2.9.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cb/0e/bdc8274dc0585090b4e3432267d7be4dfbfd8971c0fa59167c711105a6bf/psycopg2-binary-2.9.10.tar.gz", hash = "sha256:4b3df0e6990aa98acda57d983942eff13d824135fe2250e6522edaa782a06de2", size = 385764 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/81/331257dbf2801cdb82105306042f7a1637cc752f65f2bb688188e0de5f0b/psycopg2_binary-2.9.10-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:0ea8e3d0ae83564f2fc554955d327fa081d065c8ca5cc6d2abb643e2c9c1200f", size = 3043397 }, + { url = "https://files.pythonhosted.org/packages/e7/9a/7f4f2f031010bbfe6a02b4a15c01e12eb6b9b7b358ab33229f28baadbfc1/psycopg2_binary-2.9.10-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:3e9c76f0ac6f92ecfc79516a8034a544926430f7b080ec5a0537bca389ee0906", size = 3274806 }, + { url = "https://files.pythonhosted.org/packages/e5/57/8ddd4b374fa811a0b0a0f49b6abad1cde9cb34df73ea3348cc283fcd70b4/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ad26b467a405c798aaa1458ba09d7e2b6e5f96b1ce0ac15d82fd9f95dc38a92", size = 2851361 }, + { url = "https://files.pythonhosted.org/packages/f9/66/d1e52c20d283f1f3a8e7e5c1e06851d432f123ef57b13043b4f9b21ffa1f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:270934a475a0e4b6925b5f804e3809dd5f90f8613621d062848dd82f9cd62007", size = 3080836 }, + { url = "https://files.pythonhosted.org/packages/a0/cb/592d44a9546aba78f8a1249021fe7c59d3afb8a0ba51434d6610cc3462b6/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:48b338f08d93e7be4ab2b5f1dbe69dc5e9ef07170fe1f86514422076d9c010d0", size = 3264552 }, + { url = "https://files.pythonhosted.org/packages/64/33/c8548560b94b7617f203d7236d6cdf36fe1a5a3645600ada6efd79da946f/psycopg2_binary-2.9.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f4152f8f76d2023aac16285576a9ecd2b11a9895373a1f10fd9db54b3ff06b4", size = 3019789 }, + { url = "https://files.pythonhosted.org/packages/b0/0e/c2da0db5bea88a3be52307f88b75eec72c4de62814cbe9ee600c29c06334/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:32581b3020c72d7a421009ee1c6bf4a131ef5f0a968fab2e2de0c9d2bb4577f1", size = 2871776 }, + { url = "https://files.pythonhosted.org/packages/15/d7/774afa1eadb787ddf41aab52d4c62785563e29949613c958955031408ae6/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:2ce3e21dc3437b1d960521eca599d57408a695a0d3c26797ea0f72e834c7ffe5", size = 2820959 }, + { url = "https://files.pythonhosted.org/packages/5e/ed/440dc3f5991a8c6172a1cde44850ead0e483a375277a1aef7cfcec00af07/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e984839e75e0b60cfe75e351db53d6db750b00de45644c5d1f7ee5d1f34a1ce5", size = 2919329 }, + { url = "https://files.pythonhosted.org/packages/03/be/2cc8f4282898306732d2ae7b7378ae14e8df3c1231b53579efa056aae887/psycopg2_binary-2.9.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3c4745a90b78e51d9ba06e2088a2fe0c693ae19cc8cb051ccda44e8df8a6eb53", size = 2957659 }, + { url = "https://files.pythonhosted.org/packages/d0/12/fb8e4f485d98c570e00dad5800e9a2349cfe0f71a767c856857160d343a5/psycopg2_binary-2.9.10-cp310-cp310-win32.whl", hash = "sha256:e5720a5d25e3b99cd0dc5c8a440570469ff82659bb09431c1439b92caf184d3b", size = 1024605 }, + { url = "https://files.pythonhosted.org/packages/22/4f/217cd2471ecf45d82905dd09085e049af8de6cfdc008b6663c3226dc1c98/psycopg2_binary-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:3c18f74eb4386bf35e92ab2354a12c17e5eb4d9798e4c0ad3a00783eae7cd9f1", size = 1163817 }, + { url = "https://files.pythonhosted.org/packages/9c/8f/9feb01291d0d7a0a4c6a6bab24094135c2b59c6a81943752f632c75896d6/psycopg2_binary-2.9.10-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:04392983d0bb89a8717772a193cfaac58871321e3ec69514e1c4e0d4957b5aff", size = 3043397 }, + { url = "https://files.pythonhosted.org/packages/15/30/346e4683532011561cd9c8dfeac6a8153dd96452fee0b12666058ab7893c/psycopg2_binary-2.9.10-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:1a6784f0ce3fec4edc64e985865c17778514325074adf5ad8f80636cd029ef7c", size = 3274806 }, + { url = "https://files.pythonhosted.org/packages/66/6e/4efebe76f76aee7ec99166b6c023ff8abdc4e183f7b70913d7c047701b79/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5f86c56eeb91dc3135b3fd8a95dc7ae14c538a2f3ad77a19645cf55bab1799c", size = 2851370 }, + { url = "https://files.pythonhosted.org/packages/7f/fd/ff83313f86b50f7ca089b161b8e0a22bb3c319974096093cd50680433fdb/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b3d2491d4d78b6b14f76881905c7a8a8abcf974aad4a8a0b065273a0ed7a2cb", size = 3080780 }, + { url = "https://files.pythonhosted.org/packages/e6/c4/bfadd202dcda8333a7ccafdc51c541dbdfce7c2c7cda89fa2374455d795f/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2286791ececda3a723d1910441c793be44625d86d1a4e79942751197f4d30341", size = 3264583 }, + { url = "https://files.pythonhosted.org/packages/5d/f1/09f45ac25e704ac954862581f9f9ae21303cc5ded3d0b775532b407f0e90/psycopg2_binary-2.9.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:512d29bb12608891e349af6a0cccedce51677725a921c07dba6342beaf576f9a", size = 3019831 }, + { url = "https://files.pythonhosted.org/packages/9e/2e/9beaea078095cc558f215e38f647c7114987d9febfc25cb2beed7c3582a5/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5a507320c58903967ef7384355a4da7ff3f28132d679aeb23572753cbf2ec10b", size = 2871822 }, + { url = "https://files.pythonhosted.org/packages/01/9e/ef93c5d93f3dc9fc92786ffab39e323b9aed066ba59fdc34cf85e2722271/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6d4fa1079cab9018f4d0bd2db307beaa612b0d13ba73b5c6304b9fe2fb441ff7", size = 2820975 }, + { url = "https://files.pythonhosted.org/packages/a5/f0/049e9631e3268fe4c5a387f6fc27e267ebe199acf1bc1bc9cbde4bd6916c/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:851485a42dbb0bdc1edcdabdb8557c09c9655dfa2ca0460ff210522e073e319e", size = 2919320 }, + { url = "https://files.pythonhosted.org/packages/dc/9a/bcb8773b88e45fb5a5ea8339e2104d82c863a3b8558fbb2aadfe66df86b3/psycopg2_binary-2.9.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:35958ec9e46432d9076286dda67942ed6d968b9c3a6a2fd62b48939d1d78bf68", size = 2957617 }, + { url = "https://files.pythonhosted.org/packages/e2/6b/144336a9bf08a67d217b3af3246abb1d027095dab726f0687f01f43e8c03/psycopg2_binary-2.9.10-cp311-cp311-win32.whl", hash = "sha256:ecced182e935529727401b24d76634a357c71c9275b356efafd8a2a91ec07392", size = 1024618 }, + { url = "https://files.pythonhosted.org/packages/61/69/3b3d7bd583c6d3cbe5100802efa5beacaacc86e37b653fc708bf3d6853b8/psycopg2_binary-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:ee0e8c683a7ff25d23b55b11161c2663d4b099770f6085ff0a20d4505778d6b4", size = 1163816 }, + { url = "https://files.pythonhosted.org/packages/49/7d/465cc9795cf76f6d329efdafca74693714556ea3891813701ac1fee87545/psycopg2_binary-2.9.10-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:880845dfe1f85d9d5f7c412efea7a08946a46894537e4e5d091732eb1d34d9a0", size = 3044771 }, + { url = "https://files.pythonhosted.org/packages/8b/31/6d225b7b641a1a2148e3ed65e1aa74fc86ba3fee850545e27be9e1de893d/psycopg2_binary-2.9.10-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9440fa522a79356aaa482aa4ba500b65f28e5d0e63b801abf6aa152a29bd842a", size = 3275336 }, + { url = "https://files.pythonhosted.org/packages/30/b7/a68c2b4bff1cbb1728e3ec864b2d92327c77ad52edcd27922535a8366f68/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e3923c1d9870c49a2d44f795df0c889a22380d36ef92440ff618ec315757e539", size = 2851637 }, + { url = "https://files.pythonhosted.org/packages/0b/b1/cfedc0e0e6f9ad61f8657fd173b2f831ce261c02a08c0b09c652b127d813/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b2c956c028ea5de47ff3a8d6b3cc3330ab45cf0b7c3da35a2d6ff8420896526", size = 3082097 }, + { url = "https://files.pythonhosted.org/packages/18/ed/0a8e4153c9b769f59c02fb5e7914f20f0b2483a19dae7bf2db54b743d0d0/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f758ed67cab30b9a8d2833609513ce4d3bd027641673d4ebc9c067e4d208eec1", size = 3264776 }, + { url = "https://files.pythonhosted.org/packages/10/db/d09da68c6a0cdab41566b74e0a6068a425f077169bed0946559b7348ebe9/psycopg2_binary-2.9.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8cd9b4f2cfab88ed4a9106192de509464b75a906462fb846b936eabe45c2063e", size = 3020968 }, + { url = "https://files.pythonhosted.org/packages/94/28/4d6f8c255f0dfffb410db2b3f9ac5218d959a66c715c34cac31081e19b95/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6dc08420625b5a20b53551c50deae6e231e6371194fa0651dbe0fb206452ae1f", size = 2872334 }, + { url = "https://files.pythonhosted.org/packages/05/f7/20d7bf796593c4fea95e12119d6cc384ff1f6141a24fbb7df5a668d29d29/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d7cd730dfa7c36dbe8724426bf5612798734bff2d3c3857f36f2733f5bfc7c00", size = 2822722 }, + { url = "https://files.pythonhosted.org/packages/4d/e4/0c407ae919ef626dbdb32835a03b6737013c3cc7240169843965cada2bdf/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:155e69561d54d02b3c3209545fb08938e27889ff5a10c19de8d23eb5a41be8a5", size = 2920132 }, + { url = "https://files.pythonhosted.org/packages/2d/70/aa69c9f69cf09a01da224909ff6ce8b68faeef476f00f7ec377e8f03be70/psycopg2_binary-2.9.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c3cc28a6fd5a4a26224007712e79b81dbaee2ffb90ff406256158ec4d7b52b47", size = 2959312 }, + { url = "https://files.pythonhosted.org/packages/d3/bd/213e59854fafe87ba47814bf413ace0dcee33a89c8c8c814faca6bc7cf3c/psycopg2_binary-2.9.10-cp312-cp312-win32.whl", hash = "sha256:ec8a77f521a17506a24a5f626cb2aee7850f9b69a0afe704586f63a464f3cd64", size = 1025191 }, + { url = "https://files.pythonhosted.org/packages/92/29/06261ea000e2dc1e22907dbbc483a1093665509ea586b29b8986a0e56733/psycopg2_binary-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:18c5ee682b9c6dd3696dad6e54cc7ff3a1a9020df6a5c0f861ef8bfd338c3ca0", size = 1164031 }, + { url = "https://files.pythonhosted.org/packages/3e/30/d41d3ba765609c0763505d565c4d12d8f3c79793f0d0f044ff5a28bf395b/psycopg2_binary-2.9.10-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:26540d4a9a4e2b096f1ff9cce51253d0504dca5a85872c7f7be23be5a53eb18d", size = 3044699 }, + { url = "https://files.pythonhosted.org/packages/35/44/257ddadec7ef04536ba71af6bc6a75ec05c5343004a7ec93006bee66c0bc/psycopg2_binary-2.9.10-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e217ce4d37667df0bc1c397fdcd8de5e81018ef305aed9415c3b093faaeb10fb", size = 3275245 }, + { url = "https://files.pythonhosted.org/packages/1b/11/48ea1cd11de67f9efd7262085588790a95d9dfcd9b8a687d46caf7305c1a/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:245159e7ab20a71d989da00f280ca57da7641fa2cdcf71749c193cea540a74f7", size = 2851631 }, + { url = "https://files.pythonhosted.org/packages/62/e0/62ce5ee650e6c86719d621a761fe4bc846ab9eff8c1f12b1ed5741bf1c9b/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c4ded1a24b20021ebe677b7b08ad10bf09aac197d6943bfe6fec70ac4e4690d", size = 3082140 }, + { url = "https://files.pythonhosted.org/packages/27/ce/63f946c098611f7be234c0dd7cb1ad68b0b5744d34f68062bb3c5aa510c8/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3abb691ff9e57d4a93355f60d4f4c1dd2d68326c968e7db17ea96df3c023ef73", size = 3264762 }, + { url = "https://files.pythonhosted.org/packages/43/25/c603cd81402e69edf7daa59b1602bd41eb9859e2824b8c0855d748366ac9/psycopg2_binary-2.9.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8608c078134f0b3cbd9f89b34bd60a943b23fd33cc5f065e8d5f840061bd0673", size = 3020967 }, + { url = "https://files.pythonhosted.org/packages/5f/d6/8708d8c6fca531057fa170cdde8df870e8b6a9b136e82b361c65e42b841e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:230eeae2d71594103cd5b93fd29d1ace6420d0b86f4778739cb1a5a32f607d1f", size = 2872326 }, + { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, + { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, + { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, +] + [[package]] name = "pydantic" version = "2.9.2" From e802a05754921571dcf7f73e5ed9e011aa92bce4 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 10 Nov 2024 17:45:56 +0800 Subject: [PATCH 38/65] feat: alembic integration --- backend/alembic.ini | 115 ++++++++++++++++++ backend/app/alembic/env.py | 91 ++++++++++++++ backend/app/alembic/script.py.mako | 26 ++++ .../versions/ee4193e1c052_add_item_table.py | 46 +++++++ backend/app/models/__init__.py | 9 +- backend/app/models/user.py | 4 +- backend/scripts/pre-start.sh | 15 ++- 7 files changed, 292 insertions(+), 14 deletions(-) create mode 100644 backend/alembic.ini create mode 100644 backend/app/alembic/env.py create mode 100644 backend/app/alembic/script.py.mako create mode 100644 backend/app/alembic/versions/ee4193e1c052_add_item_table.py diff --git a/backend/alembic.ini b/backend/alembic.ini new file mode 100644 index 0000000..66d43a6 --- /dev/null +++ b/backend/alembic.ini @@ -0,0 +1,115 @@ +# A generic, single database configuration. + +[alembic] +# path to migration scripts +# Use forward slashes (/) also on windows to provide an os agnostic path +script_location = app/alembic + +# template used to generate migration file names; The default value is %%(rev)s_%%(slug)s +# Uncomment the line below if you want the files to be prepended with date and time +# see https://alembic.sqlalchemy.org/en/latest/tutorial.html#editing-the-ini-file +# for all available tokens +# file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s + +# sys.path path, will be prepended to sys.path if present. +# defaults to the current working directory. +prepend_sys_path = . + +# timezone to use when rendering the date within the migration file +# as well as the filename. +# If specified, requires the python>=3.9 or backports.zoneinfo library. +# Any required deps can installed by adding `alembic[tz]` to the pip requirements +# string value is passed to ZoneInfo() +# leave blank for localtime +# timezone = + +# max length of characters to apply to the "slug" field +# truncate_slug_length = 40 + +# set to 'true' to run the environment during +# the 'revision' command, regardless of autogenerate +# revision_environment = false + +# set to 'true' to allow .pyc and .pyo files without +# a source .py file to be detected as revisions in the +# versions/ directory +# sourceless = false + +# version location specification; This defaults +# to alembic/versions. When using multiple version +# directories, initial revisions must be specified with --version-path. +# The path separator used here should be the separator specified by "version_path_separator" below. +# version_locations = %(here)s/bar:%(here)s/bat:alembic/versions + +# version path separator; As mentioned above, this is the character used to split +# version_locations. The default within new alembic.ini files is "os", which uses os.pathsep. +# If this key is omitted entirely, it falls back to the legacy behavior of splitting on spaces and/or commas. +# Valid values for version_path_separator are: +# +# version_path_separator = : +# version_path_separator = ; +# version_path_separator = space +# version_path_separator = newline +version_path_separator = os # Use os.pathsep. Default configuration used for new projects. + +# set to 'true' to search source files recursively +# in each "version_locations" directory +# new in Alembic version 1.10 +# recursive_version_locations = false + +# the output encoding used when revision files +# are written from script.py.mako +# output_encoding = utf-8 + + +[post_write_hooks] +# post_write_hooks defines scripts or Python functions that are run +# on newly generated revision scripts. See the documentation for further +# detail and examples + +# format using "black" - use the console_scripts runner, against the "black" entrypoint +# hooks = black +# black.type = console_scripts +# black.entrypoint = black +# black.options = -l 79 REVISION_SCRIPT_FILENAME + +# lint with attempts to fix using "ruff" - use the exec runner, execute a binary +# hooks = ruff +# ruff.type = exec +# ruff.executable = %(here)s/.venv/bin/ruff +# ruff.options = --fix REVISION_SCRIPT_FILENAME + +# Logging configuration +[loggers] +keys = root,sqlalchemy,alembic + +[handlers] +keys = console + +[formatters] +keys = generic + +[logger_root] +level = WARNING +handlers = console +qualname = + +[logger_sqlalchemy] +level = WARNING +handlers = +qualname = sqlalchemy.engine + +[logger_alembic] +level = INFO +handlers = +qualname = alembic + +[handler_console] +class = StreamHandler +args = (sys.stderr,) +level = NOTSET +formatter = generic + +[formatter_generic] +format = %(levelname)-5.5s [%(name)s] %(message)s +datefmt = %H:%M:%S diff --git a/backend/app/alembic/env.py b/backend/app/alembic/env.py new file mode 100644 index 0000000..db878cb --- /dev/null +++ b/backend/app/alembic/env.py @@ -0,0 +1,91 @@ +from logging.config import fileConfig + +from alembic import context +from sqlalchemy import engine_from_config, pool +from sqlmodel import SQLModel + +from app.core.config import settings +from app.models import * # noqa: F403 + +# this is the Alembic Config object, which provides +# access to the values within the .ini file in use. +config = context.config + +# Interpret the config file for Python logging. +# This line sets up loggers basically. +if config.config_file_name is not None: + fileConfig(config.config_file_name) + +# add your model's MetaData object here +# for 'autogenerate' support + + +target_metadata = SQLModel.metadata + +# other values from the config, defined by the needs of env.py, +# can be acquired: +# my_important_option = config.get_main_option("my_important_option") +# ... etc. + + +def get_url() -> str: + url = str(settings.SQLALCHEMY_DATABASE_URI) + return url.replace("postgresql+asyncpg://", "postgresql://") + + +def run_migrations_offline() -> None: + """Run migrations in 'offline' mode. + + This configures the context with just a URL + and not an Engine, though an Engine is acceptable + here as well. By skipping the Engine creation + we don't even need a DBAPI to be available. + + Calls to context.execute() here emit the given string to the + script output. + + """ + url = get_url() + context.configure( + url=url, + target_metadata=target_metadata, + literal_binds=True, + compare_type=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +def run_migrations_online() -> None: + """Run migrations in 'online' mode. + + In this scenario we need to create an Engine + and associate a connection with the context. + + """ + configuration = config.get_section(config.config_ini_section) + if configuration is None: + raise FileNotFoundError("alembic config is None!") + configuration["sqlalchemy.url"] = get_url() + connectable = engine_from_config( + configuration, prefix="sqlalchemy.", poolclass=pool.NullPool + ) + + with connectable.connect() as connection: + context.configure( + connection=connection, + target_metadata=target_metadata, + compare_type=True, + dialect_opts={"paramstyle": "named"}, + ) + + with context.begin_transaction(): + context.run_migrations() + + +if context.is_offline_mode(): + run_migrations_offline() +else: + run_migrations_online() diff --git a/backend/app/alembic/script.py.mako b/backend/app/alembic/script.py.mako new file mode 100644 index 0000000..fbc4b07 --- /dev/null +++ b/backend/app/alembic/script.py.mako @@ -0,0 +1,26 @@ +"""${message} + +Revision ID: ${up_revision} +Revises: ${down_revision | comma,n} +Create Date: ${create_date} + +""" +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa +${imports if imports else ""} + +# revision identifiers, used by Alembic. +revision: str = ${repr(up_revision)} +down_revision: Union[str, None] = ${repr(down_revision)} +branch_labels: Union[str, Sequence[str], None] = ${repr(branch_labels)} +depends_on: Union[str, Sequence[str], None] = ${repr(depends_on)} + + +def upgrade() -> None: + ${upgrades if upgrades else "pass"} + + +def downgrade() -> None: + ${downgrades if downgrades else "pass"} diff --git a/backend/app/alembic/versions/ee4193e1c052_add_item_table.py b/backend/app/alembic/versions/ee4193e1c052_add_item_table.py new file mode 100644 index 0000000..f90952d --- /dev/null +++ b/backend/app/alembic/versions/ee4193e1c052_add_item_table.py @@ -0,0 +1,46 @@ +"""add_item_table + +Revision ID: ee4193e1c052 +Revises: +Create Date: 2024-11-10 17:28:34.531937 + +""" +from typing import Sequence, Union +import sqlmodel +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = 'ee4193e1c052' +down_revision: Union[str, None] = None +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + # op.create_table('users', + # sa.Column('id', sa.Uuid(), nullable=False), + # sa.Column('email', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + # sa.PrimaryKeyConstraint('id'), + # schema='auth' + # ) + op.create_table('item', + sa.Column('title', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=False), + sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), + sa.Column('id', sa.Uuid(), nullable=False), + sa.Column('owner_id', sa.Uuid(), nullable=False), + sa.Column('created_at', sa.DateTime(), nullable=False), + sa.Column('updated_at', sa.DateTime(), nullable=False), + sa.ForeignKeyConstraint(['owner_id'], ['auth.users.id'], ondelete='CASCADE'), + sa.PrimaryKeyConstraint('id') + ) + # ### end Alembic commands ### + + +def downgrade() -> None: + # ### commands auto generated by Alembic - please adjust! ### + op.drop_table('item') + # op.drop_table('users', schema='auth') + # ### end Alembic commands ### diff --git a/backend/app/models/__init__.py b/backend/app/models/__init__.py index c8b677d..207d7ca 100644 --- a/backend/app/models/__init__.py +++ b/backend/app/models/__init__.py @@ -1,11 +1,4 @@ -from sqlmodel import SQLModel - from .item import Item from .user import User -__all__ = ["User", "Item", "Message"] - - -# Generic message -class Message(SQLModel): - message: str +__all__ = ["User", "Item"] diff --git a/backend/app/models/user.py b/backend/app/models/user.py index 071e411..7ca877b 100644 --- a/backend/app/models/user.py +++ b/backend/app/models/user.py @@ -5,7 +5,9 @@ class User(SQLModel, table=True): + """NOTE: do not migrate with alembic with it""" + __tablename__ = "users" - __table_args__ = {"schema": "auth", "extend_existing": True} + __table_args__ = {"schema": "auth", "keep_existing": True} id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) email: EmailStr = Field(max_length=255) diff --git a/backend/scripts/pre-start.sh b/backend/scripts/pre-start.sh index f92788c..235bcb9 100755 --- a/backend/scripts/pre-start.sh +++ b/backend/scripts/pre-start.sh @@ -4,10 +4,15 @@ set -e set -x # Let the DB start -python -m app.utils.pre_start +python -m app.utils.test_pre_start -# # Run migrations -# alembic upgrade head +# before migrations +# alembic init +# mkdir -p app/alembic/versions +# alembic revision --autogenerate -m "initial commit" -# # Create initial data in DB -# python app/initial_data.py +# Run migrations +alembic upgrade head + +# Create initial data in DB +python -m app.utils.init_data From 375d5976a86215db17955d1328452f9fef6dd113 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Mon, 11 Nov 2024 19:35:39 +0800 Subject: [PATCH 39/65] chore(deps): update anyio --- backend/pyproject.toml | 2 +- backend/uv.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/pyproject.toml b/backend/pyproject.toml index fc5915f..c9be36d 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ [dependency-groups] dev = [ - "anyio>=4.4.0", + "anyio>=4.6.2.post1", "coverage>=7.6.1", "faker>=28.0.0", "mypy>=1.13.0", diff --git a/backend/uv.lock b/backend/uv.lock index 3996156..15b09fe 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -187,7 +187,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "anyio", specifier = ">=4.4.0" }, + { name = "anyio", specifier = ">=4.6.2.post1" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "faker", specifier = ">=28.0.0" }, { name = "mypy", specifier = ">=1.13.0" }, From 43e204bda073576fe0b50566f1aad9db590901da Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Mon, 11 Nov 2024 19:37:04 +0800 Subject: [PATCH 40/65] feat: curd items --- backend/app/crud/base.py | 118 ++++++++++--------- backend/app/crud/crud_item.py | 38 +++--- backend/app/models/base.py | 10 ++ backend/app/models/item.py | 12 +- backend/app/schemas/__init__.py | 4 +- backend/app/schemas/base.py | 48 -------- backend/app/schemas/item.py | 30 ----- backend/app/schemas/msg.py | 5 - backend/tests/crud/test_item.py | 202 +++++++++++++++++++++++++------- 9 files changed, 264 insertions(+), 203 deletions(-) create mode 100644 backend/app/models/base.py delete mode 100644 backend/app/schemas/base.py delete mode 100644 backend/app/schemas/item.py delete mode 100644 backend/app/schemas/msg.py diff --git a/backend/app/crud/base.py b/backend/app/crud/base.py index 8670ed7..fcc39f6 100644 --- a/backend/app/crud/base.py +++ b/backend/app/crud/base.py @@ -1,68 +1,78 @@ +import uuid +from collections.abc import Sequence from typing import Generic, TypeVar -from app.schemas.auth import UserIn -from app.schemas.base import CreateBase, ResponseBase, UpdateBase -from supabase._async.client import AsyncClient +from sqlmodel import SQLModel, select +from sqlmodel.ext.asyncio.session import AsyncSession -ModelType = TypeVar("ModelType", bound=ResponseBase) -CreateSchemaType = TypeVar("CreateSchemaType", bound=CreateBase) -UpdateSchemaType = TypeVar("UpdateSchemaType", bound=UpdateBase) +from app.models.base import InDBBase + +ModelType = TypeVar("ModelType", bound=InDBBase) +CreateSchemaType = TypeVar("CreateSchemaType", bound=SQLModel) +UpdateSchemaType = TypeVar("UpdateSchemaType", bound=SQLModel) class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]): def __init__(self, model: type[ModelType]): + """ + CRUD object with default methods to Create, Read, Update, Delete (CRUD). + + **Parameters** + + * `model`: A SQLModel model class + """ self.model = model - async def get(self, db: AsyncClient, *, id: str) -> ModelType | None: - """get by table_name by id""" - data, count = ( - await db.table(self.model.table_name).select("*").eq("id", id).execute() - ) - _, got = data - return self.model(**got[0]) if got else None + async def get(self, session: AsyncSession, *, id: uuid.UUID) -> ModelType | None: + """Get a single record by id""" + statement = select(self.model).where(self.model.id == id) + result = await session.exec(statement) + return result.one_or_none() - async def get_all(self, db: AsyncClient) -> list[ModelType]: - """get all by table_name""" - data, count = await db.table(self.model.table_name).select("*").execute() - _, got = data - return [self.model(**item) for item in got] + async def get_multi( + self, session: AsyncSession, *, skip: int = 0, limit: int = 100 + ) -> Sequence[ModelType]: + """Get multiple records with pagination""" + statement = select(self.model).offset(skip).limit(limit) + result = await session.exec(statement) + return result.all() - async def get_multi_by_owner( - self, db: AsyncClient, *, user: UserIn - ) -> list[ModelType]: - """get by owner,use it if rls failed to use""" - data, count = ( - await db.table(self.model.table_name) - .select("*") - .eq("user_id", user.id) - .execute() - ) - _, got = data - return [self.model(**item) for item in got] + async def create( + self, session: AsyncSession, *, owner_id: uuid.UUID, obj_in: CreateSchemaType + ) -> ModelType: + """Create new record""" + db_obj = self.model(**dict(owner_id=owner_id, **obj_in.model_dump())) + session.add(db_obj) + await session.commit() + await session.refresh(db_obj) + return db_obj + + async def update( + self, session: AsyncSession, *, id: uuid.UUID, obj_in: UpdateSchemaType + ) -> ModelType | None: + """Update existing record""" + db_obj = await self.get(session, id=id) + if db_obj: + update_data = obj_in.model_dump(exclude_unset=True) + db_obj.sqlmodel_update(update_data) - async def create(self, db: AsyncClient, *, obj_in: CreateSchemaType) -> ModelType: - """create by CreateSchemaType""" - data, count = ( - await db.table(self.model.table_name).insert(obj_in.model_dump()).execute() - ) - _, created = data - return self.model(**created[0]) + session.add(db_obj) + await session.commit() + await session.refresh(db_obj) + return db_obj - async def update(self, db: AsyncClient, *, obj_in: UpdateSchemaType) -> ModelType: - """update by UpdateSchemaType""" - data, count = ( - await db.table(self.model.table_name) - .update(obj_in.model_dump()) - .eq("id", obj_in.id) - .execute() - ) - _, updated = data - return self.model(**updated[0]) + async def remove(self, session: AsyncSession, *, id: uuid.UUID) -> ModelType | None: + """Remove a record""" + obj = await self.get(session, id=id) + if obj: + await session.delete(obj) + await session.commit() + return obj - async def delete(self, db: AsyncClient, *, id: str) -> ModelType: - """remove by UpdateSchemaType""" - data, count = ( - await db.table(self.model.table_name).delete().eq("id", id).execute() - ) - _, deleted = data - return self.model(**deleted[0]) + async def get_multi_by_owner( + self, session: AsyncSession, *, owner_id: uuid.UUID + ) -> Sequence[ModelType]: + """Get multiple records by owner""" + statement = select(self.model).where(self.model.owner_id == owner_id) + result = await session.exec(statement) + return result.all() diff --git a/backend/app/crud/crud_item.py b/backend/app/crud/crud_item.py index e46f0eb..1ba2b31 100644 --- a/backend/app/crud/crud_item.py +++ b/backend/app/crud/crud_item.py @@ -1,28 +1,36 @@ -from supabase._async.client import AsyncClient +import uuid +from collections.abc import Sequence + +from sqlmodel.ext.asyncio.session import AsyncSession from app.crud.base import CRUDBase -from app.schemas import Item, ItemCreate, ItemUpdate -from app.schemas.auth import UserIn +from app.models.item import Item, ItemCreate, ItemUpdate class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]): - async def create(self, db: AsyncClient, *, obj_in: ItemCreate) -> Item: - return await super().create(db, obj_in=obj_in) + async def create( + self, session: AsyncSession, *, owner_id: uuid.UUID, obj_in: ItemCreate + ) -> Item: + return await super().create(session, owner_id=owner_id, obj_in=obj_in) - async def get(self, db: AsyncClient, *, id: str) -> Item | None: - return await super().get(db, id=id) + async def get(self, session: AsyncSession, *, id: uuid.UUID) -> Item | None: + return await super().get(session, id=id) - async def get_all(self, db: AsyncClient) -> list[Item]: - return await super().get_all(db) + async def get_all(self, session: AsyncSession) -> Sequence[Item]: + return await super().get_multi(session) - async def get_multi_by_owner(self, db: AsyncClient, *, user: UserIn) -> list[Item]: - return await super().get_multi_by_owner(db, user=user) + async def get_multi_by_owner( + self, session: AsyncSession, *, owner_id: uuid.UUID + ) -> Sequence[Item]: + return await super().get_multi_by_owner(session, owner_id=owner_id) - async def update(self, db: AsyncClient, *, obj_in: ItemUpdate) -> Item: - return await super().update(db, obj_in=obj_in) + async def update( + self, session: AsyncSession, *, id: uuid.UUID, obj_in: ItemUpdate + ) -> Item | None: + return await super().update(session, id=id, obj_in=obj_in) - async def delete(self, db: AsyncClient, *, id: str) -> Item: - return await super().delete(db, id=id) + async def remove(self, session: AsyncSession, *, id: uuid.UUID) -> Item | None: + return await super().remove(session, id=id) item = CRUDItem(Item) diff --git a/backend/app/models/base.py b/backend/app/models/base.py new file mode 100644 index 0000000..4711257 --- /dev/null +++ b/backend/app/models/base.py @@ -0,0 +1,10 @@ +import uuid + +from sqlmodel import Field, SQLModel + + +class InDBBase(SQLModel): + id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) + owner_id: uuid.UUID = Field( + foreign_key="auth.users.id", nullable=False, ondelete="CASCADE" + ) diff --git a/backend/app/models/item.py b/backend/app/models/item.py index e503370..ae1f00c 100644 --- a/backend/app/models/item.py +++ b/backend/app/models/item.py @@ -1,8 +1,9 @@ import uuid -from datetime import datetime, timezone from sqlmodel import Field, SQLModel +from app.models.base import InDBBase + # Shared properties class ItemBase(SQLModel): @@ -21,13 +22,8 @@ class ItemUpdate(ItemBase): # Database model, database table inferred from class name -class Item(ItemBase, table=True): - id: uuid.UUID = Field(default_factory=uuid.uuid4, primary_key=True) - owner_id: uuid.UUID = Field( - foreign_key="auth.users.id", nullable=False, ondelete="CASCADE" - ) - created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) - updated_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc)) +class Item(InDBBase, ItemBase, table=True): + pass # Properties to return via API, id is always required diff --git a/backend/app/schemas/__init__.py b/backend/app/schemas/__init__.py index a4d5f94..b2fcc2c 100644 --- a/backend/app/schemas/__init__.py +++ b/backend/app/schemas/__init__.py @@ -1,5 +1,3 @@ from .auth import Token -from .item import Item, ItemCreate, ItemInDB, ItemUpdate -from .msg import Massage -__all__ = ["Token", "Item", "ItemCreate", "ItemInDB", "ItemUpdate", "Massage"] +__all__ = ["Token"] diff --git a/backend/app/schemas/base.py b/backend/app/schemas/base.py deleted file mode 100644 index e547cdb..0000000 --- a/backend/app/schemas/base.py +++ /dev/null @@ -1,48 +0,0 @@ -from typing import ClassVar - -from pydantic import BaseModel, ConfigDict - -# request - - -# Shared properties -# class CRUDBaseModel(BaseModel): -# # where the data -# table_name: str - - -# Properties to receive on item creation -# in -class CreateBase(BaseModel): - # inherent to add more properties for creating - pass - - -# Properties to receive on item update -# in - - -class UpdateBase(BaseModel): - # inherent to add more properties for updating - id: str - - -# response - - -# Properties shared by models stored in DB -class InDBBase(BaseModel): - id: str - user_id: str - created_at: str - - -# Properties to return to client -# curd model -# out -class ResponseBase(InDBBase): - # inherent to add more properties for responding - table_name: ClassVar[str] = "ResponseBase".lower() - Config: ClassVar[ConfigDict] = ConfigDict( - extra="ignore", arbitrary_types_allowed=True - ) diff --git a/backend/app/schemas/item.py b/backend/app/schemas/item.py deleted file mode 100644 index c6675df..0000000 --- a/backend/app/schemas/item.py +++ /dev/null @@ -1,30 +0,0 @@ -from typing import ClassVar - -from app.schemas.base import CreateBase, InDBBase, ResponseBase, UpdateBase - - -# request -# Properties to receive on item creation -# in -class ItemCreate(CreateBase): - test_data: str - - -# Properties to receive on item update -# in -class ItemUpdate(UpdateBase): - test_data: str - - -# Properties to return to client -# curd model -# out -class Item(ResponseBase): - test_data: str - - table_name: ClassVar[str] = "test_table" - - -# Properties properties stored in DB -class ItemInDB(InDBBase): - test_data: str diff --git a/backend/app/schemas/msg.py b/backend/app/schemas/msg.py deleted file mode 100644 index 6e3aea6..0000000 --- a/backend/app/schemas/msg.py +++ /dev/null @@ -1,5 +0,0 @@ -from pydantic import BaseModel - - -class Massage(BaseModel): - msg: str diff --git a/backend/tests/crud/test_item.py b/backend/tests/crud/test_item.py index 45173d3..d94863f 100644 --- a/backend/tests/crud/test_item.py +++ b/backend/tests/crud/test_item.py @@ -1,50 +1,172 @@ -# import pytest -# from app import crud -# from app.schemas.item import Item, ItemCreate, ItemUpdate -# from faker import Faker -# from supabase._async.client import AsyncClient +import uuid +from collections.abc import AsyncGenerator +import pytest +from faker import Faker +from sqlmodel import select +from sqlmodel.ext.asyncio.session import AsyncSession -# @pytest.mark.anyio -# async def test_create_item(db: AsyncClient) -> None: -# test_data = Faker().text() -# item_in = ItemCreate(test_data=test_data) -# item: Item = await crud.item.create(db=db, obj_in=item_in) -# assert item.test_data == test_data +from app import crud +from app.core.auth import get_super_client +from app.models import User as UserInDB +from app.models.item import Item, ItemCreate, ItemUpdate +fake = Faker() -# @pytest.mark.anyio -# async def test_get_item(db: AsyncClient) -> None: -# test_data = Faker().text() -# item_in = ItemCreate(table_name="test_table", test_data=test_data) -# item: Item = await crud.item.create(db=db, obj_in=item_in) -# stored_item = await crud.item.get(db, id=item.id) -# assert stored_item -# assert item.id == stored_item.id -# assert item.test_data == stored_item.test_data + +@pytest.fixture(scope="module") +async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: + """Fixture to create a test user""" + super_client = await get_super_client() + try: + response = await super_client.auth.sign_up( + {"email": fake.email(), "password": "testpassword123"} + ) + yield uuid.UUID(response.user.id) + finally: + result = await db.exec( + select(UserInDB).where(str(UserInDB.id) == response.user.id) + ) + user = result.first() + if user: + await db.delete(user) + await db.commit() + + +@pytest.fixture +async def test_item( + db: AsyncSession, test_user_id: uuid.UUID +) -> AsyncGenerator[Item, None]: + """Fixture to create a test item and clean it up after the test""" + item_in = ItemCreate( + title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) + ) + item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + yield item + # Cleanup + await crud.item.remove(db, id=item.id) + + +@pytest.mark.anyio +async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: + """Test creating a new item""" + title = fake.sentence(nb_words=3) + description = fake.text(max_nb_chars=200) + item_in = ItemCreate(title=title, description=description) + + item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + + assert item.id is not None + assert item.title == title + assert item.description == description + assert item.owner_id == test_user_id + + # Cleanup + await crud.item.remove(db, id=item.id) + + +@pytest.mark.anyio +async def test_get_item(db: AsyncSession, test_item: Item) -> None: + """Test retrieving a single item""" + stored_item = await crud.item.get(db, id=test_item.id) + + assert stored_item is not None + assert stored_item.id == test_item.id + assert stored_item.title == test_item.title + assert stored_item.description == test_item.description + assert stored_item.owner_id == test_item.owner_id + + +@pytest.mark.anyio +async def test_get_nonexistent_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: + """Test retrieving a non-existent item""" + nonexistent_item = await crud.item.get(db, id=test_user_id) + assert nonexistent_item is None + + +@pytest.mark.anyio +async def test_update_item(db: AsyncSession, test_item: Item) -> None: + """Test updating an item""" + new_title = fake.sentence(nb_words=3) + new_description = fake.text(max_nb_chars=200) + update_data = ItemUpdate(title=new_title, description=new_description) + + updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) + + assert updated_item is not None + assert updated_item.id == test_item.id + assert updated_item.title == new_title + assert updated_item.description == new_description + assert updated_item.owner_id == test_item.owner_id + + +@pytest.mark.anyio +async def test_update_nonexistent_item( + db: AsyncSession, test_user_id: uuid.UUID +) -> None: + """Test updating a non-existent item""" + update_data = ItemUpdate(title=fake.sentence(nb_words=3)) + updated_item = await crud.item.update(db, id=test_user_id, obj_in=update_data) + assert updated_item is None + + +@pytest.mark.anyio +async def test_delete_item(db: AsyncSession, test_item: Item) -> None: + """Test deleting an item""" + deleted_item = await crud.item.remove(db, id=test_item.id) + assert deleted_item is not None + assert deleted_item.id == test_item.id + + # Verify item is deleted + item = await crud.item.get(db, id=test_item.id) + assert item is None # @pytest.mark.anyio -# async def test_update_item(db: AsyncClient) -> None: -# test_data = Faker().text() -# item_in = ItemCreate(table_name="test_table", test_data=test_data) -# item: Item = await crud.item.create(db=db, obj_in=item_in) -# test_data2 = Faker().text() -# item_update = ItemUpdate(table_name="test_table", id=item.id, test_data=test_data2) -# item2 = await crud.item.update(db=db, obj_in=item_update) -# assert item.id == item2.id -# assert item.test_data != item2.test_data -# assert item2.test_data == test_data2 +# async def test_get_multi_by_owner(db: AsyncSession, test_user_id: uuid.UUID) -> None: +# """Test retrieving multiple items by owner""" +# # Create multiple items for the same owner +# items_data = [ +# ItemCreate(title=fake.sentence(nb_words=3), description=fake.text()) +# for _ in range(3) +# ] +# created_items = [] +# for item_data in items_data: +# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_data) +# created_items.append(item) + +# # Retrieve items by owner +# items = await crud.item.get_multi_by_owner(db, owner_id=test_user_id) + +# assert len(items) == len(created_items) +# assert all(item.owner_id == test_user_id for item in items) + +# # Cleanup +# for item in created_items: +# await crud.item.remove(db, id=item.id) # @pytest.mark.anyio -# async def test_delete_item(db: AsyncClient) -> None: -# test_data = Faker().text() -# item_in = ItemCreate(table_name="test_table", test_data=test_data) -# item: Item = await crud.item.create(db=db, obj_in=item_in) -# item2 = await crud.item.delete(db=db, id=item.id) -# item3 = await crud.item.get(db, id=item.id) -# assert item3 is None -# assert item.id == item2.id -# assert item.test_data == item2.test_data -# assert item2.test_data == test_data +# async def test_get_all_items(db: AsyncSession, test_user_id: uuid.UUID) -> None: +# """Test retrieving all items with pagination""" +# # Create multiple items +# items_data = [ +# ItemCreate(title=fake.sentence(nb_words=3), description=fake.text()) +# for _ in range(5) +# ] +# created_items = [] +# for item_data in items_data: +# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_data) +# created_items.append(item) + +# # Test pagination +# items_page_1 = await crud.item.get_multi(db, skip=0, limit=3) +# items_page_2 = await crud.item.get_multi(db, skip=3, limit=3) + +# assert len(items_page_1) == 3 +# assert len(items_page_2) == 2 + +# # Cleanup +# for item in created_items: +# await crud.item.remove(db, id=item.id) +# await db.commit() From fc27eecb57f9ba89d17bba2cf1fbfedd7dd996ac Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Mon, 11 Nov 2024 19:37:33 +0800 Subject: [PATCH 41/65] chore(db): update migration --- ...item_table.py => 2c0516590c18_initial_commit.py} | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename backend/app/alembic/versions/{ee4193e1c052_add_item_table.py => 2c0516590c18_initial_commit.py} (84%) diff --git a/backend/app/alembic/versions/ee4193e1c052_add_item_table.py b/backend/app/alembic/versions/2c0516590c18_initial_commit.py similarity index 84% rename from backend/app/alembic/versions/ee4193e1c052_add_item_table.py rename to backend/app/alembic/versions/2c0516590c18_initial_commit.py index f90952d..4ec9c34 100644 --- a/backend/app/alembic/versions/ee4193e1c052_add_item_table.py +++ b/backend/app/alembic/versions/2c0516590c18_initial_commit.py @@ -1,18 +1,19 @@ -"""add_item_table +"""initial commit -Revision ID: ee4193e1c052 +Revision ID: 2c0516590c18 Revises: -Create Date: 2024-11-10 17:28:34.531937 +Create Date: 2024-11-11 13:59:36.474238 """ from typing import Sequence, Union -import sqlmodel + from alembic import op +import sqlmodel import sqlalchemy as sa # revision identifiers, used by Alembic. -revision: str = 'ee4193e1c052' +revision: str = '2c0516590c18' down_revision: Union[str, None] = None branch_labels: Union[str, Sequence[str], None] = None depends_on: Union[str, Sequence[str], None] = None @@ -31,8 +32,6 @@ def upgrade() -> None: sa.Column('description', sqlmodel.sql.sqltypes.AutoString(length=255), nullable=True), sa.Column('id', sa.Uuid(), nullable=False), sa.Column('owner_id', sa.Uuid(), nullable=False), - sa.Column('created_at', sa.DateTime(), nullable=False), - sa.Column('updated_at', sa.DateTime(), nullable=False), sa.ForeignKeyConstraint(['owner_id'], ['auth.users.id'], ondelete='CASCADE'), sa.PrimaryKeyConstraint('id') ) From 994f8e815d5a99f63a75f0e0a80bc0b3b6c25b0a Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 19 Jan 2025 17:13:42 +0800 Subject: [PATCH 42/65] chore(deps): update deps and add Dockerile --- .dockerignore | 75 --- .pre-commit-config.yaml | 25 +- Dockerfile | 35 -- backend/.dockerignore | 185 ++++++ backend/Dockerfile | 47 ++ backend/pyproject.toml | 2 +- backend/uv.lock | 1243 ++++++++++++++++++++++++--------------- compose.yml | 0 8 files changed, 1021 insertions(+), 591 deletions(-) delete mode 100644 .dockerignore delete mode 100644 Dockerfile create mode 100644 backend/.dockerignore create mode 100644 backend/Dockerfile create mode 100644 compose.yml diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index fbe784e..0000000 --- a/.dockerignore +++ /dev/null @@ -1,75 +0,0 @@ -__pycache__/ -*.py[cod] -*$py.class -*.so -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST -*.manifest -*.spec -pip-log.txt -pip-delete-this-directory.txt -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ -*.mo -*.pot -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal -instance/ -.webassets-cache -.scrapy -docs/_build/ -.pybuilder/ -target/ -.ipynb_checkpoints -profile_default/ -ipython_config.py -.pdm.toml -__pypackages__/ -celerybeat-schedule -celerybeat.pid -*.sage.py -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ -.spyderproject -.spyproject -.ropeproject -/site -.mypy_cache/ -.dmypy.json -dmypy.json -.pyre/ -.pytype/ -cython_debug/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a583aa..3cbcd68 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -2,10 +2,9 @@ # `pre-commit install` to set up the git hook scripts # `pre-commit autoupdate` to update repos # `pre-commit run --all-files` run hooks for all file -exclude: (^|/)\..* # exclude hidden files or folder repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v5.0.0 hooks: - id: check-toml - id: check-yaml @@ -28,20 +27,22 @@ repos: args: [--write-changes] # lint and format - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.8 + rev: v0.9.2 hooks: + # Run the linter. - id: ruff args: [ --fix ] + # Run the formatter. - id: ruff-format - # - repo: https://github.com/hadolint/hadolint - # rev: v2.12.0 - # hooks: - # - id: hadolint - # name: Lint Dockerfiles - # description: Runs hadolint to lint Dockerfiles - # language: system - # types: ["dockerfile"] - # entry: hadolint + - repo: https://github.com/hadolint/hadolint + rev: v2.13.1-beta + hooks: + - id: hadolint + name: Lint Dockerfiles + description: Runs hadolint to lint Dockerfiles + language: system + types: ["dockerfile"] + entry: hadolint ci: # Settings for the https://pre-commit.ci/ continuous integration service autofix_prs: True diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 40f4c03..0000000 --- a/Dockerfile +++ /dev/null @@ -1,35 +0,0 @@ -# 第一阶段:使用 Poetry 安装依赖 -FROM python:3.11-rc-slim as builder - -WORKDIR /app - -RUN pip install poetry - -COPY poetry.lock pyproject.toml /app/ -# TODO: login docker register plugin -# 安装依赖,忽略项目本身 -RUN poetry config virtualenvs.create false \ - && poetry install --no-dev --no-root - -# 第二阶段:构建最终镜像 -FROM python:3.11-rc-slim - -ENV PYTHONPATH=/app/src -WORKDIR /app - -# 从 builder 阶段复制安装好的依赖 -COPY --from=builder /usr/local/lib/python3.11/site-packages /usr/local/lib/python3.11/site-packages -COPY --from=builder /usr/local/bin /usr/local/bin - -# 复制整个项目到容器中 -COPY . /app - -# 设置环境变量 -ENV PORT=5000 - - -# 暴露端口 -EXPOSE 5000 - -# 运行 FastAPI 应用 -CMD ["uvicorn", "src.app.main:app", "--host", "0.0.0.0", "--port", "5000"] diff --git a/backend/.dockerignore b/backend/.dockerignore new file mode 100644 index 0000000..9f2e657 --- /dev/null +++ b/backend/.dockerignore @@ -0,0 +1,185 @@ +# Byte-compiled / optimized / DLL files +**/__pycache__/ +**/*.py[cod] +**/*$py.class + +# C extensions +**/*.so + +# Distribution / packaging +**/.Python +**/build/ +**/develop-eggs/ +**/dist/ +**/downloads/ +**/eggs/ +**/.eggs/ +**/lib/ +**/lib64/ +**/parts/ +**/sdist/ +**/var/ +**/wheels/ +**/share/python-wheels/ +**/*.egg-info/ +**/.installed.cfg +**/*.egg +**/MANIFEST + +# Docker +**/compose.yml +**/docker-compose.yml +**/*Dockerfile +.dockerignore + +# Git +.git +.github +**/.gitignore + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +**/*.manifest +**/*.spec + +# Installer logs +**/pip-log.txt +**/pip-delete-this-directory.txt + +# Unit test / coverage reports +**/htmlcov/ +**/.tox/ +**/.nox/ +**/.coverage +**/.coverage.* +**/.*cache +**/nosetests.xml +**/coverage.xml +**/*.cover +**/*.py,cover +**/.hypothesis/ +**/.pytest_cache/ +**/cover/ + +# Translations +**/*.mo +**/*.pot + +# Django stuff: +**/*.log +**/local_settings.py +**/db.sqlite3 +**/db.sqlite3-journal + +# Flask stuff: +**/instance/ +**/.webassets-cache + +# Scrapy stuff: +**/.scrapy + +# Sphinx documentation +**/docs/_build/ + +# PyBuilder +**/.pybuilder/ +**/target/ + +# Jupyter Notebook +**/.ipynb_checkpoints + +# IPython +**/profile_default/ +**/ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +**/__pypackages__/ + +# Celery stuff +**/celerybeat-schedule +**/celerybeat.pid + +# SageMath parsed files +**/*.sage.py + +# Environments +**/.env +**/.venv +**/env/ +**/venv/ +**/ENV/ +**/env.bak/ +**/venv.bak/ + +# Spyder project settings +**/.spyderproject +**/.spyproject + +# Rope project settings +**/.ropeproject + +# mkdocs documentation +**/site + +# mypy +**/.mypy_cache/ +**/.dmypy.json +**/dmypy.json + +# Pyre type checker +**/.pyre/ + +# pytype static type analyzer +**/.pytype/ + +# Cython debug symbols +**/cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.idea/ + +# VS Code +.vscode +.devcontainer + +# Custom +.pre-commit-config.yaml +assets +docs +CHANGELOG.md +mkdocs.yml +tests diff --git a/backend/Dockerfile b/backend/Dockerfile new file mode 100644 index 0000000..fc9218e --- /dev/null +++ b/backend/Dockerfile @@ -0,0 +1,47 @@ +# Ref: https://github.com/fastapi/full-stack-fastapi-template/blob/master/backend/Dockerfile +FROM python:3.12-slim-bookworm + +# Print logs immediately +# Ref: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUNBUFFERED +ENV PYTHONUNBUFFERED=1 + +# Change the working directory to the `app` directory +WORKDIR /app + +# Install uv +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#installing-uv +COPY --from=ghcr.io/astral-sh/uv:0.5.18 /uv /uvx /bin/ + +# Place executables in the environment at the front of the path +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#using-the-environment +ENV PATH="/app/.venv/bin:$PATH" + +# Compile bytecode to speed up the startup time +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#compiling-bytecode +ENV UV_COMPILE_BYTECODE=1 + +# uv Cache +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#caching +ENV UV_LINK_MODE=copy + +# Install dependencies +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers +RUN --mount=type=cache,target=/root/.cache/uv \ + --mount=type=bind,source=uv.lock,target=uv.lock \ + --mount=type=bind,source=pyproject.toml,target=pyproject.toml \ + uv sync --frozen --no-install-project + +# Copy the project into the image +COPY . . + +# Sync the project +# Ref: https://docs.astral.sh/uv/guides/integration/docker/#intermediate-layers +RUN --mount=type=cache,target=/root/.cache/uv \ + uv sync + +# Set the default command +# Ref: https://fastapi.tiangolo.com/deployment/docker/ +CMD ["fastapi", "run", "app/main.py", "--port", "80"] + +# If running behind a proxy like Nginx or Traefik add --proxy-headers +# CMD ["fastapi", "run", "app/main.py", "--port", "80", "--proxy-headers"] diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c9be36d..c560446 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -8,7 +8,7 @@ dependencies = [ "pydantic-settings>=2.4.0", "python-multipart>=0.0.9", "supabase>=2.7.4", - "fastapi>=0.112.2", + "fastapi[standard]>=0.112.2", "sqlmodel>=0.0.22", "asyncpg>=0.30.0", "alembic>=1.14.0", diff --git a/backend/uv.lock b/backend/uv.lock index 15b09fe..1cb24ef 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -1,22 +1,18 @@ version = 1 requires-python = ">=3.10" -resolution-markers = [ - "python_full_version < '3.13'", - "python_full_version >= '3.13'", -] [[package]] name = "aiohappyeyeballs" -version = "2.4.3" +version = "2.4.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/69/2f6d5a019bd02e920a3417689a89887b39ad1e350b562f9955693d900c40/aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", size = 21809 } +sdist = { url = "https://files.pythonhosted.org/packages/7f/55/e4373e888fdacb15563ef6fa9fa8c8252476ea071e96fb46defac9f18bf2/aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", size = 21977 } wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/d8/120cd0fe3e8530df0539e71ba9683eade12cae103dd7543e50d15f737917/aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572", size = 14742 }, + { url = "https://files.pythonhosted.org/packages/b9/74/fbb6559de3607b3300b9be3cc64e97548d55678e44623db17820dbd20002/aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8", size = 14756 }, ] [[package]] name = "aiohttp" -version = "3.10.10" +version = "3.11.11" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohappyeyeballs" }, @@ -25,82 +21,83 @@ dependencies = [ { name = "attrs" }, { name = "frozenlist" }, { name = "multidict" }, + { name = "propcache" }, { name = "yarl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/17/7e/16e57e6cf20eb62481a2f9ce8674328407187950ccc602ad07c685279141/aiohttp-3.10.10.tar.gz", hash = "sha256:0631dd7c9f0822cc61c88586ca76d5b5ada26538097d0f1df510b082bad3411a", size = 7542993 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3d/dd/3d40c0e67e79c5c42671e3e268742f1ff96c6573ca43823563d01abd9475/aiohttp-3.10.10-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:be7443669ae9c016b71f402e43208e13ddf00912f47f623ee5994e12fc7d4b3f", size = 586969 }, - { url = "https://files.pythonhosted.org/packages/75/64/8de41b5555e5b43ef6d4ed1261891d33fe45ecc6cb62875bfafb90b9ab93/aiohttp-3.10.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7b06b7843929e41a94ea09eb1ce3927865387e3e23ebe108e0d0d09b08d25be9", size = 399367 }, - { url = "https://files.pythonhosted.org/packages/96/36/27bd62ea7ce43906d1443a73691823fc82ffb8fa03276b0e2f7e1037c286/aiohttp-3.10.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:333cf6cf8e65f6a1e06e9eb3e643a0c515bb850d470902274239fea02033e9a8", size = 390720 }, - { url = "https://files.pythonhosted.org/packages/e8/4d/d516b050d811ce0dd26325c383013c104ffa8b58bd361b82e52833f68e78/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:274cfa632350225ce3fdeb318c23b4a10ec25c0e2c880eff951a3842cf358ac1", size = 1228820 }, - { url = "https://files.pythonhosted.org/packages/53/94/964d9327a3e336d89aad52260836e4ec87fdfa1207176550fdf384eaffe7/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9e5e4a85bdb56d224f412d9c98ae4cbd032cc4f3161818f692cd81766eee65a", size = 1264616 }, - { url = "https://files.pythonhosted.org/packages/0c/20/70ce17764b685ca8f5bf4d568881b4e1f1f4ea5e8170f512fdb1a33859d2/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b606353da03edcc71130b52388d25f9a30a126e04caef1fd637e31683033abd", size = 1298402 }, - { url = "https://files.pythonhosted.org/packages/d1/d1/5248225ccc687f498d06c3bca5af2647a361c3687a85eb3aedcc247ee1aa/aiohttp-3.10.10-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab5a5a0c7a7991d90446a198689c0535be89bbd6b410a1f9a66688f0880ec026", size = 1222205 }, - { url = "https://files.pythonhosted.org/packages/f2/a3/9296b27cc5d4feadf970a14d0694902a49a985f3fae71b8322a5f77b0baa/aiohttp-3.10.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:578a4b875af3e0daaf1ac6fa983d93e0bbfec3ead753b6d6f33d467100cdc67b", size = 1193804 }, - { url = "https://files.pythonhosted.org/packages/d9/07/f3760160feb12ac51a6168a6da251a4a8f2a70733d49e6ceb9b3e6ee2f03/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8105fd8a890df77b76dd3054cddf01a879fc13e8af576805d667e0fa0224c35d", size = 1193544 }, - { url = "https://files.pythonhosted.org/packages/7e/4c/93a70f9a4ba1c30183a6dd68bfa79cddbf9a674f162f9c62e823a74a5515/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3bcd391d083f636c06a68715e69467963d1f9600f85ef556ea82e9ef25f043f7", size = 1193047 }, - { url = "https://files.pythonhosted.org/packages/ff/a3/36a1e23ff00c7a0cd696c5a28db05db25dc42bfc78c508bd78623ff62a4a/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:fbc6264158392bad9df19537e872d476f7c57adf718944cc1e4495cbabf38e2a", size = 1247201 }, - { url = "https://files.pythonhosted.org/packages/55/ae/95399848557b98bb2c402d640b2276ce3a542b94dba202de5a5a1fe29abe/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:e48d5021a84d341bcaf95c8460b152cfbad770d28e5fe14a768988c461b821bc", size = 1264102 }, - { url = "https://files.pythonhosted.org/packages/38/f5/02e5c72c1b60d7cceb30b982679a26167e84ac029fd35a93dd4da52c50a3/aiohttp-3.10.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2609e9ab08474702cc67b7702dbb8a80e392c54613ebe80db7e8dbdb79837c68", size = 1215760 }, - { url = "https://files.pythonhosted.org/packages/30/17/1463840bad10d02d0439068f37ce5af0b383884b0d5838f46fb027e233bf/aiohttp-3.10.10-cp310-cp310-win32.whl", hash = "sha256:84afcdea18eda514c25bc68b9af2a2b1adea7c08899175a51fe7c4fb6d551257", size = 362678 }, - { url = "https://files.pythonhosted.org/packages/dd/01/a0ef707d93e867a43abbffee3a2cdf30559910750b9176b891628c7ad074/aiohttp-3.10.10-cp310-cp310-win_amd64.whl", hash = "sha256:9c72109213eb9d3874f7ac8c0c5fa90e072d678e117d9061c06e30c85b4cf0e6", size = 381097 }, - { url = "https://files.pythonhosted.org/packages/72/31/3c351d17596194e5a38ef169a4da76458952b2497b4b54645b9d483cbbb0/aiohttp-3.10.10-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c30a0eafc89d28e7f959281b58198a9fa5e99405f716c0289b7892ca345fe45f", size = 586501 }, - { url = "https://files.pythonhosted.org/packages/a4/a8/a559d09eb08478cdead6b7ce05b0c4a133ba27fcdfa91e05d2e62867300d/aiohttp-3.10.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:258c5dd01afc10015866114e210fb7365f0d02d9d059c3c3415382ab633fcbcb", size = 398993 }, - { url = "https://files.pythonhosted.org/packages/c5/47/7736d4174613feef61d25332c3bd1a4f8ff5591fbd7331988238a7299485/aiohttp-3.10.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:15ecd889a709b0080f02721255b3f80bb261c2293d3c748151274dfea93ac871", size = 390647 }, - { url = "https://files.pythonhosted.org/packages/27/21/e9ba192a04b7160f5a8952c98a1de7cf8072ad150fa3abd454ead1ab1d7f/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3935f82f6f4a3820270842e90456ebad3af15810cf65932bd24da4463bc0a4c", size = 1306481 }, - { url = "https://files.pythonhosted.org/packages/cf/50/f364c01c8d0def1dc34747b2470969e216f5a37c7ece00fe558810f37013/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:413251f6fcf552a33c981c4709a6bba37b12710982fec8e558ae944bfb2abd38", size = 1344652 }, - { url = "https://files.pythonhosted.org/packages/1d/c2/74f608e984e9b585649e2e83883facad6fa3fc1d021de87b20cc67e8e5ae/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1720b4f14c78a3089562b8875b53e36b51c97c51adc53325a69b79b4b48ebcb", size = 1378498 }, - { url = "https://files.pythonhosted.org/packages/9f/a7/05a48c7c0a7a80a5591b1203bf1b64ca2ed6a2050af918d09c05852dc42b/aiohttp-3.10.10-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:679abe5d3858b33c2cf74faec299fda60ea9de62916e8b67e625d65bf069a3b7", size = 1292718 }, - { url = "https://files.pythonhosted.org/packages/7d/78/a925655018747e9790350180330032e27d6e0d7ed30bde545fae42f8c49c/aiohttp-3.10.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:79019094f87c9fb44f8d769e41dbb664d6e8fcfd62f665ccce36762deaa0e911", size = 1251776 }, - { url = "https://files.pythonhosted.org/packages/47/9d/85c6b69f702351d1236594745a4fdc042fc43f494c247a98dac17e004026/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fe2fb38c2ed905a2582948e2de560675e9dfbee94c6d5ccdb1301c6d0a5bf092", size = 1271716 }, - { url = "https://files.pythonhosted.org/packages/7f/a7/55fc805ff9b14af818903882ece08e2235b12b73b867b521b92994c52b14/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a3f00003de6eba42d6e94fabb4125600d6e484846dbf90ea8e48a800430cc142", size = 1266263 }, - { url = "https://files.pythonhosted.org/packages/1f/ec/d2be2ca7b063e4f91519d550dbc9c1cb43040174a322470deed90b3d3333/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:1bbb122c557a16fafc10354b9d99ebf2f2808a660d78202f10ba9d50786384b9", size = 1321617 }, - { url = "https://files.pythonhosted.org/packages/c9/a3/b29f7920e1cd0a9a68a45dd3eb16140074d2efb1518d2e1f3e140357dc37/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:30ca7c3b94708a9d7ae76ff281b2f47d8eaf2579cd05971b5dc681db8caac6e1", size = 1339227 }, - { url = "https://files.pythonhosted.org/packages/8a/81/34b67235c47e232d807b4bbc42ba9b927c7ce9476872372fddcfd1e41b3d/aiohttp-3.10.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:df9270660711670e68803107d55c2b5949c2e0f2e4896da176e1ecfc068b974a", size = 1299068 }, - { url = "https://files.pythonhosted.org/packages/04/1f/26a7fe11b6ad3184f214733428353c89ae9fe3e4f605a657f5245c5e720c/aiohttp-3.10.10-cp311-cp311-win32.whl", hash = "sha256:aafc8ee9b742ce75044ae9a4d3e60e3d918d15a4c2e08a6c3c3e38fa59b92d94", size = 362223 }, - { url = "https://files.pythonhosted.org/packages/10/91/85dcd93f64011434359ce2666bece981f08d31bc49df33261e625b28595d/aiohttp-3.10.10-cp311-cp311-win_amd64.whl", hash = "sha256:362f641f9071e5f3ee6f8e7d37d5ed0d95aae656adf4ef578313ee585b585959", size = 381576 }, - { url = "https://files.pythonhosted.org/packages/ae/99/4c5aefe5ad06a1baf206aed6598c7cdcbc7c044c46801cd0d1ecb758cae3/aiohttp-3.10.10-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9294bbb581f92770e6ed5c19559e1e99255e4ca604a22c5c6397b2f9dd3ee42c", size = 583536 }, - { url = "https://files.pythonhosted.org/packages/a9/36/8b3bc49b49cb6d2da40ee61ff15dbcc44fd345a3e6ab5bb20844df929821/aiohttp-3.10.10-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:a8fa23fe62c436ccf23ff930149c047f060c7126eae3ccea005f0483f27b2e28", size = 395693 }, - { url = "https://files.pythonhosted.org/packages/e1/77/0aa8660dcf11fa65d61712dbb458c4989de220a844bd69778dff25f2d50b/aiohttp-3.10.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5c6a5b8c7926ba5d8545c7dd22961a107526562da31a7a32fa2456baf040939f", size = 390898 }, - { url = "https://files.pythonhosted.org/packages/38/d2/b833d95deb48c75db85bf6646de0a697e7fb5d87bd27cbade4f9746b48b1/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:007ec22fbc573e5eb2fb7dec4198ef8f6bf2fe4ce20020798b2eb5d0abda6138", size = 1312060 }, - { url = "https://files.pythonhosted.org/packages/aa/5f/29fd5113165a0893de8efedf9b4737e0ba92dfcd791415a528f947d10299/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9627cc1a10c8c409b5822a92d57a77f383b554463d1884008e051c32ab1b3742", size = 1350553 }, - { url = "https://files.pythonhosted.org/packages/ad/cc/f835f74b7d344428469200105236d44606cfa448be1e7c95ca52880d9bac/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:50edbcad60d8f0e3eccc68da67f37268b5144ecc34d59f27a02f9611c1d4eec7", size = 1392646 }, - { url = "https://files.pythonhosted.org/packages/bf/fe/1332409d845ca601893bbf2d76935e0b93d41686e5f333841c7d7a4a770d/aiohttp-3.10.10-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a45d85cf20b5e0d0aa5a8dca27cce8eddef3292bc29d72dcad1641f4ed50aa16", size = 1306310 }, - { url = "https://files.pythonhosted.org/packages/e4/a1/25a7633a5a513278a9892e333501e2e69c83e50be4b57a62285fb7a008c3/aiohttp-3.10.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b00807e2605f16e1e198f33a53ce3c4523114059b0c09c337209ae55e3823a8", size = 1260255 }, - { url = "https://files.pythonhosted.org/packages/f2/39/30eafe89e0e2a06c25e4762844c8214c0c0cd0fd9ffc3471694a7986f421/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f2d4324a98062be0525d16f768a03e0bbb3b9fe301ceee99611dc9a7953124e6", size = 1271141 }, - { url = "https://files.pythonhosted.org/packages/5b/fc/33125df728b48391ef1fcb512dfb02072158cc10d041414fb79803463020/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:438cd072f75bb6612f2aca29f8bd7cdf6e35e8f160bc312e49fbecab77c99e3a", size = 1280244 }, - { url = "https://files.pythonhosted.org/packages/3b/61/e42bf2c2934b5caa4e2ec0b5e5fd86989adb022b5ee60c2572a9d77cf6fe/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:baa42524a82f75303f714108fea528ccacf0386af429b69fff141ffef1c534f9", size = 1316805 }, - { url = "https://files.pythonhosted.org/packages/18/32/f52a5e2ae9ad3bba10e026a63a7a23abfa37c7d97aeeb9004eaa98df3ce3/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a7d8d14fe962153fc681f6366bdec33d4356f98a3e3567782aac1b6e0e40109a", size = 1343930 }, - { url = "https://files.pythonhosted.org/packages/05/be/6a403b464dcab3631fe8e27b0f1d906d9e45c5e92aca97ee007e5a895560/aiohttp-3.10.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c1277cd707c465cd09572a774559a3cc7c7a28802eb3a2a9472588f062097205", size = 1306186 }, - { url = "https://files.pythonhosted.org/packages/8e/fd/bb50fe781068a736a02bf5c7ad5f3ab53e39f1d1e63110da6d30f7605edc/aiohttp-3.10.10-cp312-cp312-win32.whl", hash = "sha256:59bb3c54aa420521dc4ce3cc2c3fe2ad82adf7b09403fa1f48ae45c0cbde6628", size = 359289 }, - { url = "https://files.pythonhosted.org/packages/70/9e/5add7e240f77ef67c275c82cc1d08afbca57b77593118c1f6e920ae8ad3f/aiohttp-3.10.10-cp312-cp312-win_amd64.whl", hash = "sha256:0e1b370d8007c4ae31ee6db7f9a2fe801a42b146cec80a86766e7ad5c4a259cf", size = 379313 }, - { url = "https://files.pythonhosted.org/packages/b1/eb/618b1b76c7fe8082a71c9d62e3fe84c5b9af6703078caa9ec57850a12080/aiohttp-3.10.10-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ad7593bb24b2ab09e65e8a1d385606f0f47c65b5a2ae6c551db67d6653e78c28", size = 576114 }, - { url = "https://files.pythonhosted.org/packages/aa/37/3126995d7869f8b30d05381b81a2d4fb4ec6ad313db788e009bc6d39c211/aiohttp-3.10.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1eb89d3d29adaf533588f209768a9c02e44e4baf832b08118749c5fad191781d", size = 391901 }, - { url = "https://files.pythonhosted.org/packages/3e/f2/8fdfc845be1f811c31ceb797968523813f8e1263ee3e9120d61253f6848f/aiohttp-3.10.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3fe407bf93533a6fa82dece0e74dbcaaf5d684e5a51862887f9eaebe6372cd79", size = 387418 }, - { url = "https://files.pythonhosted.org/packages/60/d5/33d2061d36bf07e80286e04b7e0a4de37ce04b5ebfed72dba67659a05250/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50aed5155f819873d23520919e16703fc8925e509abbb1a1491b0087d1cd969e", size = 1287073 }, - { url = "https://files.pythonhosted.org/packages/00/52/affb55be16a4747740bd630b4c002dac6c5eac42f9bb64202fc3cf3f1930/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4f05e9727ce409358baa615dbeb9b969db94324a79b5a5cea45d39bdb01d82e6", size = 1323612 }, - { url = "https://files.pythonhosted.org/packages/94/f2/cddb69b975387daa2182a8442566971d6410b8a0179bb4540d81c97b1611/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3dffb610a30d643983aeb185ce134f97f290f8935f0abccdd32c77bed9388b42", size = 1368406 }, - { url = "https://files.pythonhosted.org/packages/c1/e4/afba7327da4d932da8c6e29aecaf855f9d52dace53ac15bfc8030a246f1b/aiohttp-3.10.10-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa6658732517ddabe22c9036479eabce6036655ba87a0224c612e1ae6af2087e", size = 1282761 }, - { url = "https://files.pythonhosted.org/packages/9f/6b/364856faa0c9031ea76e24ef0f7fef79cddd9fa8e7dba9a1771c6acc56b5/aiohttp-3.10.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:741a46d58677d8c733175d7e5aa618d277cd9d880301a380fd296975a9cdd7bc", size = 1236518 }, - { url = "https://files.pythonhosted.org/packages/46/af/c382846f8356fe64a7b5908bb9b477457aa23b71be7ed551013b7b7d4d87/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e00e3505cd80440f6c98c6d69269dcc2a119f86ad0a9fd70bccc59504bebd68a", size = 1250344 }, - { url = "https://files.pythonhosted.org/packages/87/53/294f87fc086fd0772d0ab82497beb9df67f0f27a8b3dd5742a2656db2bc6/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ffe595f10566f8276b76dc3a11ae4bb7eba1aac8ddd75811736a15b0d5311414", size = 1248956 }, - { url = "https://files.pythonhosted.org/packages/86/30/7d746717fe11bdfefb88bb6c09c5fc985d85c4632da8bb6018e273899254/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:bdfcf6443637c148c4e1a20c48c566aa694fa5e288d34b20fcdc58507882fed3", size = 1293379 }, - { url = "https://files.pythonhosted.org/packages/48/b9/45d670a834458db67a24258e9139ba61fa3bd7d69b98ecf3650c22806f8f/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d183cf9c797a5291e8301790ed6d053480ed94070637bfaad914dd38b0981f67", size = 1320108 }, - { url = "https://files.pythonhosted.org/packages/72/8c/804bb2e837a175635d2000a0659eafc15b2e9d92d3d81c8f69e141ecd0b0/aiohttp-3.10.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:77abf6665ae54000b98b3c742bc6ea1d1fb31c394bcabf8b5d2c1ac3ebfe7f3b", size = 1281546 }, - { url = "https://files.pythonhosted.org/packages/89/c0/862e6a9de3d6eeb126cd9d9ea388243b70df9b871ce1a42b193b7a4a77fc/aiohttp-3.10.10-cp313-cp313-win32.whl", hash = "sha256:4470c73c12cd9109db8277287d11f9dd98f77fc54155fc71a7738a83ffcc8ea8", size = 357516 }, - { url = "https://files.pythonhosted.org/packages/ae/63/3e1aee3e554263f3f1011cca50d78a4894ae16ce99bf78101ac3a2f0ef74/aiohttp-3.10.10-cp313-cp313-win_amd64.whl", hash = "sha256:486f7aabfa292719a2753c016cc3a8f8172965cabb3ea2e7f7436c7f5a22a151", size = 376785 }, +sdist = { url = "https://files.pythonhosted.org/packages/fe/ed/f26db39d29cd3cb2f5a3374304c713fe5ab5a0e4c8ee25a0c45cc6adf844/aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e", size = 7669618 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/75/7d/ff2e314b8f9e0b1df833e2d4778eaf23eae6b8cc8f922495d110ddcbf9e1/aiohttp-3.11.11-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a60804bff28662cbcf340a4d61598891f12eea3a66af48ecfdc975ceec21e3c8", size = 708550 }, + { url = "https://files.pythonhosted.org/packages/09/b8/aeb4975d5bba233d6f246941f5957a5ad4e3def8b0855a72742e391925f2/aiohttp-3.11.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4b4fa1cb5f270fb3eab079536b764ad740bb749ce69a94d4ec30ceee1b5940d5", size = 468430 }, + { url = "https://files.pythonhosted.org/packages/9c/5b/5b620279b3df46e597008b09fa1e10027a39467387c2332657288e25811a/aiohttp-3.11.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:731468f555656767cda219ab42e033355fe48c85fbe3ba83a349631541715ba2", size = 455593 }, + { url = "https://files.pythonhosted.org/packages/d8/75/0cdf014b816867d86c0bc26f3d3e3f194198dbf33037890beed629cd4f8f/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb23d8bb86282b342481cad4370ea0853a39e4a32a0042bb52ca6bdde132df43", size = 1584635 }, + { url = "https://files.pythonhosted.org/packages/df/2f/95b8f4e4dfeb57c1d9ad9fa911ede35a0249d75aa339edd2c2270dc539da/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f047569d655f81cb70ea5be942ee5d4421b6219c3f05d131f64088c73bb0917f", size = 1632363 }, + { url = "https://files.pythonhosted.org/packages/39/cb/70cf69ea7c50f5b0021a84f4c59c3622b2b3b81695f48a2f0e42ef7eba6e/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd7659baae9ccf94ae5fe8bfaa2c7bc2e94d24611528395ce88d009107e00c6d", size = 1668315 }, + { url = "https://files.pythonhosted.org/packages/2f/cc/3a3fc7a290eabc59839a7e15289cd48f33dd9337d06e301064e1e7fb26c5/aiohttp-3.11.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af01e42ad87ae24932138f154105e88da13ce7d202a6de93fafdafb2883a00ef", size = 1589546 }, + { url = "https://files.pythonhosted.org/packages/15/b4/0f7b0ed41ac6000e283e7332f0f608d734b675a8509763ca78e93714cfb0/aiohttp-3.11.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5854be2f3e5a729800bac57a8d76af464e160f19676ab6aea74bde18ad19d438", size = 1544581 }, + { url = "https://files.pythonhosted.org/packages/58/b9/4d06470fd85c687b6b0e31935ef73dde6e31767c9576d617309a2206556f/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6526e5fb4e14f4bbf30411216780c9967c20c5a55f2f51d3abd6de68320cc2f3", size = 1529256 }, + { url = "https://files.pythonhosted.org/packages/61/a2/6958b1b880fc017fd35f5dfb2c26a9a50c755b75fd9ae001dc2236a4fb79/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:85992ee30a31835fc482468637b3e5bd085fa8fe9392ba0bdcbdc1ef5e9e3c55", size = 1536592 }, + { url = "https://files.pythonhosted.org/packages/0f/dd/b974012a9551fd654f5bb95a6dd3f03d6e6472a17e1a8216dd42e9638d6c/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:88a12ad8ccf325a8a5ed80e6d7c3bdc247d66175afedbe104ee2aaca72960d8e", size = 1607446 }, + { url = "https://files.pythonhosted.org/packages/e0/d3/6c98fd87e638e51f074a3f2061e81fcb92123bcaf1439ac1b4a896446e40/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:0a6d3fbf2232e3a08c41eca81ae4f1dff3d8f1a30bae415ebe0af2d2458b8a33", size = 1628809 }, + { url = "https://files.pythonhosted.org/packages/a8/2e/86e6f85cbca02be042c268c3d93e7f35977a0e127de56e319bdd1569eaa8/aiohttp-3.11.11-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84a585799c58b795573c7fa9b84c455adf3e1d72f19a2bf498b54a95ae0d194c", size = 1564291 }, + { url = "https://files.pythonhosted.org/packages/0b/8d/1f4ef3503b767717f65e1f5178b0173ab03cba1a19997ebf7b052161189f/aiohttp-3.11.11-cp310-cp310-win32.whl", hash = "sha256:bfde76a8f430cf5c5584553adf9926534352251d379dcb266ad2b93c54a29745", size = 416601 }, + { url = "https://files.pythonhosted.org/packages/ad/86/81cb83691b5ace3d9aa148dc42bacc3450d749fc88c5ec1973573c1c1779/aiohttp-3.11.11-cp310-cp310-win_amd64.whl", hash = "sha256:0fd82b8e9c383af11d2b26f27a478640b6b83d669440c0a71481f7c865a51da9", size = 442007 }, + { url = "https://files.pythonhosted.org/packages/34/ae/e8806a9f054e15f1d18b04db75c23ec38ec954a10c0a68d3bd275d7e8be3/aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76", size = 708624 }, + { url = "https://files.pythonhosted.org/packages/c7/e0/313ef1a333fb4d58d0c55a6acb3cd772f5d7756604b455181049e222c020/aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538", size = 468507 }, + { url = "https://files.pythonhosted.org/packages/a9/60/03455476bf1f467e5b4a32a465c450548b2ce724eec39d69f737191f936a/aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/be/f9/469588603bd75bf02c8ffb8c8a0d4b217eed446b49d4a767684685aa33fd/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9", size = 1685694 }, + { url = "https://files.pythonhosted.org/packages/88/b9/1b7fa43faf6c8616fa94c568dc1309ffee2b6b68b04ac268e5d64b738688/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03", size = 1743660 }, + { url = "https://files.pythonhosted.org/packages/2a/8b/0248d19dbb16b67222e75f6aecedd014656225733157e5afaf6a6a07e2e8/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287", size = 1785421 }, + { url = "https://files.pythonhosted.org/packages/c4/11/f478e071815a46ca0a5ae974651ff0c7a35898c55063305a896e58aa1247/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e", size = 1675145 }, + { url = "https://files.pythonhosted.org/packages/26/5d/284d182fecbb5075ae10153ff7374f57314c93a8681666600e3a9e09c505/aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665", size = 1619804 }, + { url = "https://files.pythonhosted.org/packages/1b/78/980064c2ad685c64ce0e8aeeb7ef1e53f43c5b005edcd7d32e60809c4992/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b", size = 1654007 }, + { url = "https://files.pythonhosted.org/packages/21/8d/9e658d63b1438ad42b96f94da227f2e2c1d5c6001c9e8ffcc0bfb22e9105/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34", size = 1650022 }, + { url = "https://files.pythonhosted.org/packages/85/fd/a032bf7f2755c2df4f87f9effa34ccc1ef5cea465377dbaeef93bb56bbd6/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d", size = 1732899 }, + { url = "https://files.pythonhosted.org/packages/c5/0c/c2b85fde167dd440c7ba50af2aac20b5a5666392b174df54c00f888c5a75/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2", size = 1755142 }, + { url = "https://files.pythonhosted.org/packages/bc/78/91ae1a3b3b3bed8b893c5d69c07023e151b1c95d79544ad04cf68f596c2f/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773", size = 1692736 }, + { url = "https://files.pythonhosted.org/packages/77/89/a7ef9c4b4cdb546fcc650ca7f7395aaffbd267f0e1f648a436bec33c9b95/aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62", size = 416418 }, + { url = "https://files.pythonhosted.org/packages/fc/db/2192489a8a51b52e06627506f8ac8df69ee221de88ab9bdea77aa793aa6a/aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac", size = 442509 }, + { url = "https://files.pythonhosted.org/packages/69/cf/4bda538c502f9738d6b95ada11603c05ec260807246e15e869fc3ec5de97/aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886", size = 704666 }, + { url = "https://files.pythonhosted.org/packages/46/7b/87fcef2cad2fad420ca77bef981e815df6904047d0a1bd6aeded1b0d1d66/aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2", size = 464057 }, + { url = "https://files.pythonhosted.org/packages/5a/a6/789e1f17a1b6f4a38939fbc39d29e1d960d5f89f73d0629a939410171bc0/aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c", size = 455996 }, + { url = "https://files.pythonhosted.org/packages/b7/dd/485061fbfef33165ce7320db36e530cd7116ee1098e9c3774d15a732b3fd/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a", size = 1682367 }, + { url = "https://files.pythonhosted.org/packages/e9/d7/9ec5b3ea9ae215c311d88b2093e8da17e67b8856673e4166c994e117ee3e/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231", size = 1736989 }, + { url = "https://files.pythonhosted.org/packages/d6/fb/ea94927f7bfe1d86178c9d3e0a8c54f651a0a655214cce930b3c679b8f64/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e", size = 1793265 }, + { url = "https://files.pythonhosted.org/packages/40/7f/6de218084f9b653026bd7063cd8045123a7ba90c25176465f266976d8c82/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8", size = 1691841 }, + { url = "https://files.pythonhosted.org/packages/77/e2/992f43d87831cbddb6b09c57ab55499332f60ad6fdbf438ff4419c2925fc/aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8", size = 1619317 }, + { url = "https://files.pythonhosted.org/packages/96/74/879b23cdd816db4133325a201287c95bef4ce669acde37f8f1b8669e1755/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c", size = 1641416 }, + { url = "https://files.pythonhosted.org/packages/30/98/b123f6b15d87c54e58fd7ae3558ff594f898d7f30a90899718f3215ad328/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab", size = 1646514 }, + { url = "https://files.pythonhosted.org/packages/d7/38/257fda3dc99d6978ab943141d5165ec74fd4b4164baa15e9c66fa21da86b/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da", size = 1702095 }, + { url = "https://files.pythonhosted.org/packages/0c/f4/ddab089053f9fb96654df5505c0a69bde093214b3c3454f6bfdb1845f558/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853", size = 1734611 }, + { url = "https://files.pythonhosted.org/packages/c3/d6/f30b2bc520c38c8aa4657ed953186e535ae84abe55c08d0f70acd72ff577/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e", size = 1694576 }, + { url = "https://files.pythonhosted.org/packages/bc/97/b0a88c3f4c6d0020b34045ee6d954058abc870814f6e310c4c9b74254116/aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600", size = 411363 }, + { url = "https://files.pythonhosted.org/packages/7f/23/cc36d9c398980acaeeb443100f0216f50a7cfe20c67a9fd0a2f1a5a846de/aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", size = 437666 }, + { url = "https://files.pythonhosted.org/packages/49/d1/d8af164f400bad432b63e1ac857d74a09311a8334b0481f2f64b158b50eb/aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9", size = 697982 }, + { url = "https://files.pythonhosted.org/packages/92/d1/faad3bf9fa4bfd26b95c69fc2e98937d52b1ff44f7e28131855a98d23a17/aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194", size = 460662 }, + { url = "https://files.pythonhosted.org/packages/db/61/0d71cc66d63909dabc4590f74eba71f91873a77ea52424401c2498d47536/aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f", size = 452950 }, + { url = "https://files.pythonhosted.org/packages/07/db/6d04bc7fd92784900704e16b745484ef45b77bd04e25f58f6febaadf7983/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104", size = 1665178 }, + { url = "https://files.pythonhosted.org/packages/54/5c/e95ade9ae29f375411884d9fd98e50535bf9fe316c9feb0f30cd2ac8f508/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff", size = 1717939 }, + { url = "https://files.pythonhosted.org/packages/6f/1c/1e7d5c5daea9e409ed70f7986001b8c9e3a49a50b28404498d30860edab6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3", size = 1775125 }, + { url = "https://files.pythonhosted.org/packages/5d/66/890987e44f7d2f33a130e37e01a164168e6aff06fce15217b6eaf14df4f6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1", size = 1677176 }, + { url = "https://files.pythonhosted.org/packages/8f/dc/e2ba57d7a52df6cdf1072fd5fa9c6301a68e1cd67415f189805d3eeb031d/aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4", size = 1603192 }, + { url = "https://files.pythonhosted.org/packages/6c/9e/8d08a57de79ca3a358da449405555e668f2c8871a7777ecd2f0e3912c272/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d", size = 1618296 }, + { url = "https://files.pythonhosted.org/packages/56/51/89822e3ec72db352c32e7fc1c690370e24e231837d9abd056490f3a49886/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87", size = 1616524 }, + { url = "https://files.pythonhosted.org/packages/2c/fa/e2e6d9398f462ffaa095e84717c1732916a57f1814502929ed67dd7568ef/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2", size = 1685471 }, + { url = "https://files.pythonhosted.org/packages/ae/5f/6bb976e619ca28a052e2c0ca7b0251ccd893f93d7c24a96abea38e332bf6/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12", size = 1715312 }, + { url = "https://files.pythonhosted.org/packages/79/c1/756a7e65aa087c7fac724d6c4c038f2faaa2a42fe56dbc1dd62a33ca7213/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5", size = 1672783 }, + { url = "https://files.pythonhosted.org/packages/73/ba/a6190ebb02176c7f75e6308da31f5d49f6477b651a3dcfaaaca865a298e2/aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d", size = 410229 }, + { url = "https://files.pythonhosted.org/packages/b8/62/c9fa5bafe03186a0e4699150a7fed9b1e73240996d0d2f0e5f70f3fdf471/aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99", size = 436081 }, ] [[package]] name = "aiosignal" -version = "1.3.1" +version = "1.3.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "frozenlist" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422 } +sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424 } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 }, + { url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 }, ] [[package]] @@ -128,17 +125,17 @@ wheels = [ [[package]] name = "anyio" -version = "4.6.2.post1" +version = "4.8.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "idna" }, { name = "sniffio" }, - { name = "typing-extensions", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 }, + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, ] [[package]] @@ -148,7 +145,7 @@ source = { editable = "." } dependencies = [ { name = "alembic" }, { name = "asyncpg" }, - { name = "fastapi" }, + { name = "fastapi", extra = ["standard"] }, { name = "psycopg2-binary" }, { name = "pydantic", extra = ["email"] }, { name = "pydantic-settings" }, @@ -174,7 +171,7 @@ dev = [ requires-dist = [ { name = "alembic", specifier = ">=1.14.0" }, { name = "asyncpg", specifier = ">=0.30.0" }, - { name = "fastapi", specifier = ">=0.112.2" }, + { name = "fastapi", extras = ["standard"], specifier = ">=0.112.2" }, { name = "psycopg2-binary", specifier = ">=2.9.10" }, { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, { name = "pydantic-settings", specifier = ">=2.4.0" }, @@ -198,11 +195,11 @@ dev = [ [[package]] name = "async-timeout" -version = "4.0.3" +version = "5.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/87/d6/21b30a550dafea84b1b8eee21b5e23fa16d010ae006011221f33dcd8d7f8/async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f", size = 8345 } +sdist = { url = "https://files.pythonhosted.org/packages/a5/ae/136395dfbfe00dfc94da3f3e136d0b13f394cba8f4841120e34226265780/async_timeout-5.0.1.tar.gz", hash = "sha256:d9321a7a3d5a6a5e187e824d2fa0793ce379a202935782d555d6e9d2735677d3", size = 9274 } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/fa/e01228c2938de91d47b307831c62ab9e4001e747789d0b05baf779a6488c/async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028", size = 5721 }, + { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233 }, ] [[package]] @@ -250,20 +247,20 @@ wheels = [ [[package]] name = "attrs" -version = "24.2.0" +version = "24.3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 } +sdist = { url = "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", size = 805984 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 }, + { url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 }, ] [[package]] name = "certifi" -version = "2024.8.30" +version = "2024.12.14" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } wheels = [ - { url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 }, + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, ] [[package]] @@ -277,14 +274,14 @@ wheels = [ [[package]] name = "click" -version = "8.1.7" +version = "8.1.8" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "colorama", marker = "platform_system == 'Windows'" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } wheels = [ - { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, ] [[package]] @@ -298,61 +295,61 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713 }, - { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149 }, - { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584 }, - { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486 }, - { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649 }, - { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744 }, - { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204 }, - { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335 }, - { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435 }, - { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819 }, - { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263 }, - { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205 }, - { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612 }, - { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479 }, - { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405 }, - { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038 }, - { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812 }, - { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400 }, - { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243 }, - { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013 }, - { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251 }, - { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268 }, - { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298 }, - { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367 }, - { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853 }, - { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160 }, - { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824 }, - { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639 }, - { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428 }, - { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039 }, - { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298 }, - { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813 }, - { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959 }, - { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950 }, - { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610 }, - { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697 }, - { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541 }, - { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707 }, - { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439 }, - { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784 }, - { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058 }, - { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772 }, - { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490 }, - { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848 }, - { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340 }, - { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229 }, - { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510 }, - { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353 }, - { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502 }, - { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954 }, +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, ] [[package]] @@ -409,29 +406,58 @@ wheels = [ [[package]] name = "faker" -version = "30.8.2" +version = "33.3.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c1/df/7574c0d13f0bbab725e52bec4b00783aaa14163fe9093dde11a928a4c638/faker-30.8.2.tar.gz", hash = "sha256:aa31b52cdae3673d6a78b4857c7bcdc0e98f201a5cb77d7827fa9e6b5876da94", size = 1808329 } +sdist = { url = "https://files.pythonhosted.org/packages/9c/50/48ab6ba3f07ee7d0eac367695aeb8bc9eb9c3debc0445a67cd07e2d62b44/faker-33.3.1.tar.gz", hash = "sha256:49dde3b06a5602177bc2ad013149b6f60a290b7154539180d37b6f876ae79b20", size = 1854895 } wheels = [ - { url = "https://files.pythonhosted.org/packages/64/82/f7d0c0a4ab512fd1572a315eec903d50a578c75d5aa894cf3f5cc04025e5/Faker-30.8.2-py3-none-any.whl", hash = "sha256:4a82b2908cd19f3bba1a4da2060cc4eb18a40410ccdf9350d071d79dc92fe3ce", size = 1846458 }, + { url = "https://files.pythonhosted.org/packages/c2/01/6acc8b4dba4154cd93b444382a9ad3c099557aac577bdc7d66373e0a0c68/Faker-33.3.1-py3-none-any.whl", hash = "sha256:ac4cf2f967ce02c898efa50651c43180bd658a7707cfd676fcc5410ad1482c03", size = 1894842 }, ] [[package]] name = "fastapi" -version = "0.115.4" +version = "0.115.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/db/5781f19bd30745885e0737ff3fdd4e63e7bc691710f9da691128bb0dc73b/fastapi-0.115.4.tar.gz", hash = "sha256:db653475586b091cb8b2fec2ac54a680ac6a158e07406e1abae31679e8826349", size = 300737 } +sdist = { url = "https://files.pythonhosted.org/packages/93/72/d83b98cd106541e8f5e5bfab8ef2974ab45a62e8a6c5b5e6940f26d2ed4b/fastapi-0.115.6.tar.gz", hash = "sha256:9ec46f7addc14ea472958a96aae5b5de65f39721a46aaf5705c480d9a8b76654", size = 301336 } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/f6/af0d1f58f86002be0cf1e2665cdd6f7a4a71cdc8a7a9438cdc9e3b5375fe/fastapi-0.115.4-py3-none-any.whl", hash = "sha256:0b504a063ffb3cf96a5e27dc1bc32c80ca743a2528574f9cdc77daa2d31b4742", size = 94732 }, + { url = "https://files.pythonhosted.org/packages/52/b3/7e4df40e585df024fac2f80d1a2d579c854ac37109675db2b0cc22c0bb9e/fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305", size = 94843 }, +] + +[package.optional-dependencies] +standard = [ + { name = "email-validator" }, + { name = "fastapi-cli", extra = ["standard"] }, + { name = "httpx" }, + { name = "jinja2" }, + { name = "python-multipart" }, + { name = "uvicorn", extra = ["standard"] }, +] + +[[package]] +name = "fastapi-cli" +version = "0.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "rich-toolkit" }, + { name = "typer" }, + { name = "uvicorn", extra = ["standard"] }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/73/82a5831fbbf8ed75905bacf5b2d9d3dfd6f04d6968b29fe6f72a5ae9ceb1/fastapi_cli-0.0.7.tar.gz", hash = "sha256:02b3b65956f526412515907a0793c9094abd4bfb5457b389f645b0ea6ba3605e", size = 16753 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/e6/5daefc851b514ce2287d8f5d358ae4341089185f78f3217a69d0ce3a390c/fastapi_cli-0.0.7-py3-none-any.whl", hash = "sha256:d549368ff584b2804336c61f192d86ddea080c11255f375959627911944804f4", size = 10705 }, +] + +[package.optional-dependencies] +standard = [ + { name = "uvicorn", extra = ["standard"] }, ] [[package]] @@ -514,15 +540,15 @@ wheels = [ [[package]] name = "gotrue" -version = "2.10.0" +version = "2.11.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", extra = ["http2"] }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9a/4e/52c5e1a360fd0e67e0cc4512cb663613473b198974de6ae9e0aaeabff471/gotrue-2.10.0.tar.gz", hash = "sha256:4edf4c251da3535f2b044e23deba221e848ca1210c17d0c7a9b19f79a1e3f3c0", size = 41364 } +sdist = { url = "https://files.pythonhosted.org/packages/37/7e/36a105bfa50b6420ed05d56d5cb5838777e283af8c90e6db3645599740e3/gotrue-2.11.1.tar.gz", hash = "sha256:5594ceee60bd873e5f4fdd028b08dece3906f6013b6ed08e7786b71c0092fed0", size = 41813 } wheels = [ - { url = "https://files.pythonhosted.org/packages/03/06/dd3dfbb7722d0d8dfdce6b7c76695dfb4ea968dae4e46655f0d5310e27e1/gotrue-2.10.0-py3-none-any.whl", hash = "sha256:768e58207488e5184ffbdc4351b7280d913daf97962f4e9f2cca05c80004b042", size = 48596 }, + { url = "https://files.pythonhosted.org/packages/84/71/41b1da628837d4c03ad686388b3554bd29b65d126b65676e593b9eea5e43/gotrue-2.11.1-py3-none-any.whl", hash = "sha256:1b2d915bdc65fd0ad608532759ce9c72fa2e910145c1e6901f2188519e7bcd2d", size = 49058 }, ] [[package]] @@ -609,31 +635,66 @@ wheels = [ [[package]] name = "httpcore" -version = "1.0.6" +version = "1.0.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b6/44/ed0fa6a17845fb033bd885c03e842f08c1b9406c86a2e60ac1ae1b9206a6/httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f", size = 85180 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, +] + +[[package]] +name = "httptools" +version = "0.6.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/9a/ce5e1f7e131522e6d3426e8e7a490b3a01f39a6696602e1c4f33f9e94277/httptools-0.6.4.tar.gz", hash = "sha256:4e93eee4add6493b59a5c514da98c939b244fce4a0d8879cd3f466562f4b7d5c", size = 240639 } wheels = [ - { url = "https://files.pythonhosted.org/packages/06/89/b161908e2f51be56568184aeb4a880fd287178d176fd1c860d2217f41106/httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f", size = 78011 }, + { url = "https://files.pythonhosted.org/packages/3b/6f/972f8eb0ea7d98a1c6be436e2142d51ad2a64ee18e02b0e7ff1f62171ab1/httptools-0.6.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3c73ce323711a6ffb0d247dcd5a550b8babf0f757e86a52558fe5b86d6fefcc0", size = 198780 }, + { url = "https://files.pythonhosted.org/packages/6a/b0/17c672b4bc5c7ba7f201eada4e96c71d0a59fbc185e60e42580093a86f21/httptools-0.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:345c288418f0944a6fe67be8e6afa9262b18c7626c3ef3c28adc5eabc06a68da", size = 103297 }, + { url = "https://files.pythonhosted.org/packages/92/5e/b4a826fe91971a0b68e8c2bd4e7db3e7519882f5a8ccdb1194be2b3ab98f/httptools-0.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:deee0e3343f98ee8047e9f4c5bc7cedbf69f5734454a94c38ee829fb2d5fa3c1", size = 443130 }, + { url = "https://files.pythonhosted.org/packages/b0/51/ce61e531e40289a681a463e1258fa1e05e0be54540e40d91d065a264cd8f/httptools-0.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca80b7485c76f768a3bc83ea58373f8db7b015551117375e4918e2aa77ea9b50", size = 442148 }, + { url = "https://files.pythonhosted.org/packages/ea/9e/270b7d767849b0c96f275c695d27ca76c30671f8eb8cc1bab6ced5c5e1d0/httptools-0.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:90d96a385fa941283ebd231464045187a31ad932ebfa541be8edf5b3c2328959", size = 415949 }, + { url = "https://files.pythonhosted.org/packages/81/86/ced96e3179c48c6f656354e106934e65c8963d48b69be78f355797f0e1b3/httptools-0.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:59e724f8b332319e2875efd360e61ac07f33b492889284a3e05e6d13746876f4", size = 417591 }, + { url = "https://files.pythonhosted.org/packages/75/73/187a3f620ed3175364ddb56847d7a608a6fc42d551e133197098c0143eca/httptools-0.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:c26f313951f6e26147833fc923f78f95604bbec812a43e5ee37f26dc9e5a686c", size = 88344 }, + { url = "https://files.pythonhosted.org/packages/7b/26/bb526d4d14c2774fe07113ca1db7255737ffbb119315839af2065abfdac3/httptools-0.6.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f47f8ed67cc0ff862b84a1189831d1d33c963fb3ce1ee0c65d3b0cbe7b711069", size = 199029 }, + { url = "https://files.pythonhosted.org/packages/a6/17/3e0d3e9b901c732987a45f4f94d4e2c62b89a041d93db89eafb262afd8d5/httptools-0.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0614154d5454c21b6410fdf5262b4a3ddb0f53f1e1721cfd59d55f32138c578a", size = 103492 }, + { url = "https://files.pythonhosted.org/packages/b7/24/0fe235d7b69c42423c7698d086d4db96475f9b50b6ad26a718ef27a0bce6/httptools-0.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8787367fbdfccae38e35abf7641dafc5310310a5987b689f4c32cc8cc3ee975", size = 462891 }, + { url = "https://files.pythonhosted.org/packages/b1/2f/205d1f2a190b72da6ffb5f41a3736c26d6fa7871101212b15e9b5cd8f61d/httptools-0.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40b0f7fe4fd38e6a507bdb751db0379df1e99120c65fbdc8ee6c1d044897a636", size = 459788 }, + { url = "https://files.pythonhosted.org/packages/6e/4c/d09ce0eff09057a206a74575ae8f1e1e2f0364d20e2442224f9e6612c8b9/httptools-0.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:40a5ec98d3f49904b9fe36827dcf1aadfef3b89e2bd05b0e35e94f97c2b14721", size = 433214 }, + { url = "https://files.pythonhosted.org/packages/3e/d2/84c9e23edbccc4a4c6f96a1b8d99dfd2350289e94f00e9ccc7aadde26fb5/httptools-0.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:dacdd3d10ea1b4ca9df97a0a303cbacafc04b5cd375fa98732678151643d4988", size = 434120 }, + { url = "https://files.pythonhosted.org/packages/d0/46/4d8e7ba9581416de1c425b8264e2cadd201eb709ec1584c381f3e98f51c1/httptools-0.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:288cd628406cc53f9a541cfaf06041b4c71d751856bab45e3702191f931ccd17", size = 88565 }, + { url = "https://files.pythonhosted.org/packages/bb/0e/d0b71465c66b9185f90a091ab36389a7352985fe857e352801c39d6127c8/httptools-0.6.4-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:df017d6c780287d5c80601dafa31f17bddb170232d85c066604d8558683711a2", size = 200683 }, + { url = "https://files.pythonhosted.org/packages/e2/b8/412a9bb28d0a8988de3296e01efa0bd62068b33856cdda47fe1b5e890954/httptools-0.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:85071a1e8c2d051b507161f6c3e26155b5c790e4e28d7f236422dbacc2a9cc44", size = 104337 }, + { url = "https://files.pythonhosted.org/packages/9b/01/6fb20be3196ffdc8eeec4e653bc2a275eca7f36634c86302242c4fbb2760/httptools-0.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69422b7f458c5af875922cdb5bd586cc1f1033295aa9ff63ee196a87519ac8e1", size = 508796 }, + { url = "https://files.pythonhosted.org/packages/f7/d8/b644c44acc1368938317d76ac991c9bba1166311880bcc0ac297cb9d6bd7/httptools-0.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16e603a3bff50db08cd578d54f07032ca1631450ceb972c2f834c2b860c28ea2", size = 510837 }, + { url = "https://files.pythonhosted.org/packages/52/d8/254d16a31d543073a0e57f1c329ca7378d8924e7e292eda72d0064987486/httptools-0.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec4f178901fa1834d4a060320d2f3abc5c9e39766953d038f1458cb885f47e81", size = 485289 }, + { url = "https://files.pythonhosted.org/packages/5f/3c/4aee161b4b7a971660b8be71a92c24d6c64372c1ab3ae7f366b3680df20f/httptools-0.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f9eb89ecf8b290f2e293325c646a211ff1c2493222798bb80a530c5e7502494f", size = 489779 }, + { url = "https://files.pythonhosted.org/packages/12/b7/5cae71a8868e555f3f67a50ee7f673ce36eac970f029c0c5e9d584352961/httptools-0.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:db78cb9ca56b59b016e64b6031eda5653be0589dba2b1b43453f6e8b405a0970", size = 88634 }, + { url = "https://files.pythonhosted.org/packages/94/a3/9fe9ad23fd35f7de6b91eeb60848986058bd8b5a5c1e256f5860a160cc3e/httptools-0.6.4-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ade273d7e767d5fae13fa637f4d53b6e961fb7fd93c7797562663f0171c26660", size = 197214 }, + { url = "https://files.pythonhosted.org/packages/ea/d9/82d5e68bab783b632023f2fa31db20bebb4e89dfc4d2293945fd68484ee4/httptools-0.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:856f4bc0478ae143bad54a4242fccb1f3f86a6e1be5548fecfd4102061b3a083", size = 102431 }, + { url = "https://files.pythonhosted.org/packages/96/c1/cb499655cbdbfb57b577734fde02f6fa0bbc3fe9fb4d87b742b512908dff/httptools-0.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:322d20ea9cdd1fa98bd6a74b77e2ec5b818abdc3d36695ab402a0de8ef2865a3", size = 473121 }, + { url = "https://files.pythonhosted.org/packages/af/71/ee32fd358f8a3bb199b03261f10921716990808a675d8160b5383487a317/httptools-0.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4d87b29bd4486c0093fc64dea80231f7c7f7eb4dc70ae394d70a495ab8436071", size = 473805 }, + { url = "https://files.pythonhosted.org/packages/8a/0a/0d4df132bfca1507114198b766f1737d57580c9ad1cf93c1ff673e3387be/httptools-0.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:342dd6946aa6bda4b8f18c734576106b8a31f2fe31492881a9a160ec84ff4bd5", size = 448858 }, + { url = "https://files.pythonhosted.org/packages/1e/6a/787004fdef2cabea27bad1073bf6a33f2437b4dbd3b6fb4a9d71172b1c7c/httptools-0.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b36913ba52008249223042dca46e69967985fb4051951f94357ea681e1f5dc0", size = 452042 }, + { url = "https://files.pythonhosted.org/packages/4d/dc/7decab5c404d1d2cdc1bb330b1bf70e83d6af0396fd4fc76fc60c0d522bf/httptools-0.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:28908df1b9bb8187393d5b5db91435ccc9c8e891657f9cbb42a2541b44c82fc8", size = 87682 }, ] [[package]] name = "httpx" -version = "0.27.2" +version = "0.28.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, { name = "certifi" }, { name = "httpcore" }, { name = "idna" }, - { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/78/82/08f8c936781f67d9e6b9eeb8a0c8b4e406136ea4c3d1f89a5db71d42e0e6/httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2", size = 144189 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/95/9377bcb415797e44274b51d46e3249eba641711cf3348050f76ee7b15ffc/httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0", size = 76395 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, ] [package.optional-dependencies] @@ -652,11 +713,11 @@ wheels = [ [[package]] name = "identify" -version = "2.6.2" +version = "2.6.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/02/79/7a520fc5011e02ca3f3285b5f6820eaf80443eb73e3733f73c02fb42ba0b/identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd", size = 99113 } +sdist = { url = "https://files.pythonhosted.org/packages/cf/92/69934b9ef3c31ca2470980423fda3d00f0460ddefdf30a67adf7f17e2e00/identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc", size = 99213 } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/86/c4395700f3c5475424fb5c41e20c16be28d10c904aee4d005ba3217fc8e7/identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3", size = 98982 }, + { url = "https://files.pythonhosted.org/packages/ec/fa/dce098f4cdf7621aa8f7b4f919ce545891f489482f0bfa5102f3eca8608b/identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566", size = 99078 }, ] [[package]] @@ -677,16 +738,40 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, ] +[[package]] +name = "jinja2" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, +] + [[package]] name = "mako" -version = "1.3.6" +version = "1.3.8" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "markupsafe" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fa/0b/29bc5a230948bf209d3ed3165006d257e547c02c3c2a96f6286320dfe8dc/mako-1.3.6.tar.gz", hash = "sha256:9ec3a1583713479fae654f83ed9fa8c9a4c16b7bb0daba0e6bbebff50c0d983d", size = 390206 } +sdist = { url = "https://files.pythonhosted.org/packages/5f/d9/8518279534ed7dace1795d5a47e49d5299dd0994eed1053996402a8902f9/mako-1.3.8.tar.gz", hash = "sha256:577b97e414580d3e088d47c2dbbe9594aa7a5146ed2875d4dfa9075af2dd3cc8", size = 392069 } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/22/bc14c6f02e6dccaafb3eba95764c8f096714260c2aa5f76f654fd16a23dd/Mako-1.3.6-py3-none-any.whl", hash = "sha256:a91198468092a2f1a0de86ca92690fb0cfc43ca90ee17e15d93662b4c04b241a", size = 78557 }, + { url = "https://files.pythonhosted.org/packages/1e/bf/7a6a36ce2e4cafdfb202752be68850e22607fccd692847c45c1ae3c17ba6/Mako-1.3.8-py3-none-any.whl", hash = "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627", size = 78569 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, ] [[package]] @@ -747,6 +832,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, ] +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + [[package]] name = "multidict" version = "6.1.0" @@ -821,36 +915,40 @@ wheels = [ [[package]] name = "mypy" -version = "1.13.0" +version = "1.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mypy-extensions" }, { name = "tomli", marker = "python_full_version < '3.11'" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/8c/206de95a27722b5b5a8c85ba3100467bd86299d92a4f71c6b9aa448bfa2f/mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a", size = 11020731 }, - { url = "https://files.pythonhosted.org/packages/ab/bb/b31695a29eea76b1569fd28b4ab141a1adc9842edde080d1e8e1776862c7/mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80", size = 10184276 }, - { url = "https://files.pythonhosted.org/packages/a5/2d/4a23849729bb27934a0e079c9c1aad912167d875c7b070382a408d459651/mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7", size = 12587706 }, - { url = "https://files.pythonhosted.org/packages/5c/c3/d318e38ada50255e22e23353a469c791379825240e71b0ad03e76ca07ae6/mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f", size = 13105586 }, - { url = "https://files.pythonhosted.org/packages/4a/25/3918bc64952370c3dbdbd8c82c363804678127815febd2925b7273d9482c/mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372", size = 9632318 }, - { url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 }, - { url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 }, - { url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 }, - { url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 }, - { url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 }, - { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, - { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, - { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, - { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, - { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, - { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, - { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, - { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, - { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, - { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, - { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002 }, + { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400 }, + { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172 }, + { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732 }, + { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197 }, + { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836 }, + { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432 }, + { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515 }, + { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791 }, + { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203 }, + { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900 }, + { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869 }, + { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, + { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, + { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, + { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, + { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, + { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, + { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, + { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, + { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, + { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, + { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, + { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, + { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, ] [[package]] @@ -900,7 +998,7 @@ wheels = [ [[package]] name = "postgrest" -version = "0.18.0" +version = "0.19.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "deprecation" }, @@ -908,9 +1006,9 @@ dependencies = [ { name = "pydantic" }, { name = "strenum", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/f1/4e02f36b8b1b0fbac55607d0d650913dd3fc05c82cc8fbcb899e46c54e91/postgrest-0.18.0.tar.gz", hash = "sha256:29c1a94801a17eb9ad590189993fe5a7a6d8c1bfc11a3c9d0ce7ba146454ebb3", size = 14693 } +sdist = { url = "https://files.pythonhosted.org/packages/2c/0c/7b98d366e86a79b13237efb891321c867bb3d2ac6538af0da7c9eb8556b1/postgrest-0.19.1.tar.gz", hash = "sha256:d8fa88953cced4f45efa0f412056c364f64ece8a35b5b35f458a7e58c133fbca", size = 15034 } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/c5/3d476b885230325269befd6d985256e8a1398e7dbea2185965e7524e0bba/postgrest-0.18.0-py3-none-any.whl", hash = "sha256:200baad0d23fee986b3a0ffd3e07bfe0cdd40e09760f11e8e13a6c0c2376d5fa", size = 21771 }, + { url = "https://files.pythonhosted.org/packages/56/d2/480b92b0fb237fa00d10aa3c10d6a443a0a2b517ef1f1a492737829f1c02/postgrest-0.19.1-py3-none-any.whl", hash = "sha256:a8e7be4e1abc69fd8eee5a49d7dc3a76dfbffbd778beed0b2bd7accb3f4f3a2a", size = 22115 }, ] [[package]] @@ -931,75 +1029,75 @@ wheels = [ [[package]] name = "propcache" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3a/08/1963dfb932b8d74d5b09098507b37e9b96c835ba89ab8aad35aa330f4ff3/propcache-0.2.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:c5869b8fd70b81835a6f187c5fdbe67917a04d7e52b6e7cc4e5fe39d55c39d58", size = 80712 }, - { url = "https://files.pythonhosted.org/packages/e6/59/49072aba9bf8a8ed958e576182d46f038e595b17ff7408bc7e8807e721e1/propcache-0.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:952e0d9d07609d9c5be361f33b0d6d650cd2bae393aabb11d9b719364521984b", size = 46301 }, - { url = "https://files.pythonhosted.org/packages/33/a2/6b1978c2e0d80a678e2c483f45e5443c15fe5d32c483902e92a073314ef1/propcache-0.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:33ac8f098df0585c0b53009f039dfd913b38c1d2edafed0cedcc0c32a05aa110", size = 45581 }, - { url = "https://files.pythonhosted.org/packages/43/95/55acc9adff8f997c7572f23d41993042290dfb29e404cdadb07039a4386f/propcache-0.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e48e8875e6c13909c800fa344cd54cc4b2b0db1d5f911f840458a500fde2c2", size = 208659 }, - { url = "https://files.pythonhosted.org/packages/bd/2c/ef7371ff715e6cd19ea03fdd5637ecefbaa0752fee5b0f2fe8ea8407ee01/propcache-0.2.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:388f3217649d6d59292b722d940d4d2e1e6a7003259eb835724092a1cca0203a", size = 222613 }, - { url = "https://files.pythonhosted.org/packages/5e/1c/fef251f79fd4971a413fa4b1ae369ee07727b4cc2c71e2d90dfcde664fbb/propcache-0.2.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f571aea50ba5623c308aa146eb650eebf7dbe0fd8c5d946e28343cb3b5aad577", size = 221067 }, - { url = "https://files.pythonhosted.org/packages/8d/e7/22e76ae6fc5a1708bdce92bdb49de5ebe89a173db87e4ef597d6bbe9145a/propcache-0.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3dfafb44f7bb35c0c06eda6b2ab4bfd58f02729e7c4045e179f9a861b07c9850", size = 208920 }, - { url = "https://files.pythonhosted.org/packages/04/3e/f10aa562781bcd8a1e0b37683a23bef32bdbe501d9cc7e76969becaac30d/propcache-0.2.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3ebe9a75be7ab0b7da2464a77bb27febcb4fab46a34f9288f39d74833db7f61", size = 200050 }, - { url = "https://files.pythonhosted.org/packages/d0/98/8ac69f638358c5f2a0043809c917802f96f86026e86726b65006830f3dc6/propcache-0.2.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d2f0d0f976985f85dfb5f3d685697ef769faa6b71993b46b295cdbbd6be8cc37", size = 202346 }, - { url = "https://files.pythonhosted.org/packages/ee/78/4acfc5544a5075d8e660af4d4e468d60c418bba93203d1363848444511ad/propcache-0.2.0-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a3dc1a4b165283bd865e8f8cb5f0c64c05001e0718ed06250d8cac9bec115b48", size = 199750 }, - { url = "https://files.pythonhosted.org/packages/a2/8f/90ada38448ca2e9cf25adc2fe05d08358bda1b9446f54a606ea38f41798b/propcache-0.2.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:9e0f07b42d2a50c7dd2d8675d50f7343d998c64008f1da5fef888396b7f84630", size = 201279 }, - { url = "https://files.pythonhosted.org/packages/08/31/0e299f650f73903da851f50f576ef09bfffc8e1519e6a2f1e5ed2d19c591/propcache-0.2.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e63e3e1e0271f374ed489ff5ee73d4b6e7c60710e1f76af5f0e1a6117cd26394", size = 211035 }, - { url = "https://files.pythonhosted.org/packages/85/3e/e356cc6b09064bff1c06d0b2413593e7c925726f0139bc7acef8a21e87a8/propcache-0.2.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:56bb5c98f058a41bb58eead194b4db8c05b088c93d94d5161728515bd52b052b", size = 215565 }, - { url = "https://files.pythonhosted.org/packages/8b/54/4ef7236cd657e53098bd05aa59cbc3cbf7018fba37b40eaed112c3921e51/propcache-0.2.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7665f04d0c7f26ff8bb534e1c65068409bf4687aa2534faf7104d7182debb336", size = 207604 }, - { url = "https://files.pythonhosted.org/packages/1f/27/d01d7799c068443ee64002f0655d82fb067496897bf74b632e28ee6a32cf/propcache-0.2.0-cp310-cp310-win32.whl", hash = "sha256:7cf18abf9764746b9c8704774d8b06714bcb0a63641518a3a89c7f85cc02c2ad", size = 40526 }, - { url = "https://files.pythonhosted.org/packages/bb/44/6c2add5eeafb7f31ff0d25fbc005d930bea040a1364cf0f5768750ddf4d1/propcache-0.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:cfac69017ef97db2438efb854edf24f5a29fd09a536ff3a992b75990720cdc99", size = 44958 }, - { url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811 }, - { url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365 }, - { url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602 }, - { url = "https://files.pythonhosted.org/packages/2e/5e/4a3e96380805bf742712e39a4534689f4cddf5fa2d3a93f22e9fd8001b23/propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", size = 236161 }, - { url = "https://files.pythonhosted.org/packages/a5/85/90132481183d1436dff6e29f4fa81b891afb6cb89a7306f32ac500a25932/propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", size = 244938 }, - { url = "https://files.pythonhosted.org/packages/4a/89/c893533cb45c79c970834274e2d0f6d64383ec740be631b6a0a1d2b4ddc0/propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", size = 243576 }, - { url = "https://files.pythonhosted.org/packages/8c/56/98c2054c8526331a05f205bf45cbb2cda4e58e56df70e76d6a509e5d6ec6/propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", size = 236011 }, - { url = "https://files.pythonhosted.org/packages/2d/0c/8b8b9f8a6e1abd869c0fa79b907228e7abb966919047d294ef5df0d136cf/propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504", size = 224834 }, - { url = "https://files.pythonhosted.org/packages/18/bb/397d05a7298b7711b90e13108db697732325cafdcd8484c894885c1bf109/propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", size = 224946 }, - { url = "https://files.pythonhosted.org/packages/25/19/4fc08dac19297ac58135c03770b42377be211622fd0147f015f78d47cd31/propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", size = 217280 }, - { url = "https://files.pythonhosted.org/packages/7e/76/c79276a43df2096ce2aba07ce47576832b1174c0c480fe6b04bd70120e59/propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", size = 220088 }, - { url = "https://files.pythonhosted.org/packages/c3/9a/8a8cf428a91b1336b883f09c8b884e1734c87f724d74b917129a24fe2093/propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", size = 233008 }, - { url = "https://files.pythonhosted.org/packages/25/7b/768a8969abd447d5f0f3333df85c6a5d94982a1bc9a89c53c154bf7a8b11/propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", size = 237719 }, - { url = "https://files.pythonhosted.org/packages/ed/0d/e5d68ccc7976ef8b57d80613ac07bbaf0614d43f4750cf953f0168ef114f/propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", size = 227729 }, - { url = "https://files.pythonhosted.org/packages/05/64/17eb2796e2d1c3d0c431dc5f40078d7282f4645af0bb4da9097fbb628c6c/propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", size = 40473 }, - { url = "https://files.pythonhosted.org/packages/83/c5/e89fc428ccdc897ade08cd7605f174c69390147526627a7650fb883e0cd0/propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", size = 44921 }, - { url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800 }, - { url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443 }, - { url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676 }, - { url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191 }, - { url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791 }, - { url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434 }, - { url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150 }, - { url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568 }, - { url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874 }, - { url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857 }, - { url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604 }, - { url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430 }, - { url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814 }, - { url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922 }, - { url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177 }, - { url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446 }, - { url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120 }, - { url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127 }, - { url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419 }, - { url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611 }, - { url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005 }, - { url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270 }, - { url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877 }, - { url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848 }, - { url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987 }, - { url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451 }, - { url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879 }, - { url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288 }, - { url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257 }, - { url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075 }, - { url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654 }, - { url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705 }, - { url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 }, +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/c8/2a13f78d82211490855b2fb303b6721348d0787fdd9a12ac46d99d3acde1/propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", size = 41735 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/a5/0ea64c9426959ef145a938e38c832fc551843481d356713ececa9a8a64e8/propcache-0.2.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6b3f39a85d671436ee3d12c017f8fdea38509e4f25b28eb25877293c98c243f6", size = 79296 }, + { url = "https://files.pythonhosted.org/packages/76/5a/916db1aba735f55e5eca4733eea4d1973845cf77dfe67c2381a2ca3ce52d/propcache-0.2.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d51fbe4285d5db5d92a929e3e21536ea3dd43732c5b177c7ef03f918dff9f2", size = 45622 }, + { url = "https://files.pythonhosted.org/packages/2d/62/685d3cf268b8401ec12b250b925b21d152b9d193b7bffa5fdc4815c392c2/propcache-0.2.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6445804cf4ec763dc70de65a3b0d9954e868609e83850a47ca4f0cb64bd79fea", size = 45133 }, + { url = "https://files.pythonhosted.org/packages/4d/3d/31c9c29ee7192defc05aa4d01624fd85a41cf98e5922aaed206017329944/propcache-0.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9479aa06a793c5aeba49ce5c5692ffb51fcd9a7016e017d555d5e2b0045d212", size = 204809 }, + { url = "https://files.pythonhosted.org/packages/10/a1/e4050776f4797fc86140ac9a480d5dc069fbfa9d499fe5c5d2fa1ae71f07/propcache-0.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9631c5e8b5b3a0fda99cb0d29c18133bca1e18aea9effe55adb3da1adef80d3", size = 219109 }, + { url = "https://files.pythonhosted.org/packages/c9/c0/e7ae0df76343d5e107d81e59acc085cea5fd36a48aa53ef09add7503e888/propcache-0.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3156628250f46a0895f1f36e1d4fbe062a1af8718ec3ebeb746f1d23f0c5dc4d", size = 217368 }, + { url = "https://files.pythonhosted.org/packages/fc/e1/e0a2ed6394b5772508868a977d3238f4afb2eebaf9976f0b44a8d347ad63/propcache-0.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b6fb63ae352e13748289f04f37868099e69dba4c2b3e271c46061e82c745634", size = 205124 }, + { url = "https://files.pythonhosted.org/packages/50/c1/e388c232d15ca10f233c778bbdc1034ba53ede14c207a72008de45b2db2e/propcache-0.2.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:887d9b0a65404929641a9fabb6452b07fe4572b269d901d622d8a34a4e9043b2", size = 195463 }, + { url = "https://files.pythonhosted.org/packages/0a/fd/71b349b9def426cc73813dbd0f33e266de77305e337c8c12bfb0a2a82bfb/propcache-0.2.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a96dc1fa45bd8c407a0af03b2d5218392729e1822b0c32e62c5bf7eeb5fb3958", size = 198358 }, + { url = "https://files.pythonhosted.org/packages/02/f2/d7c497cd148ebfc5b0ae32808e6c1af5922215fe38c7a06e4e722fe937c8/propcache-0.2.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:a7e65eb5c003a303b94aa2c3852ef130230ec79e349632d030e9571b87c4698c", size = 195560 }, + { url = "https://files.pythonhosted.org/packages/bb/57/f37041bbe5e0dfed80a3f6be2612a3a75b9cfe2652abf2c99bef3455bbad/propcache-0.2.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:999779addc413181912e984b942fbcc951be1f5b3663cd80b2687758f434c583", size = 196895 }, + { url = "https://files.pythonhosted.org/packages/83/36/ae3cc3e4f310bff2f064e3d2ed5558935cc7778d6f827dce74dcfa125304/propcache-0.2.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:19a0f89a7bb9d8048d9c4370c9c543c396e894c76be5525f5e1ad287f1750ddf", size = 207124 }, + { url = "https://files.pythonhosted.org/packages/8c/c4/811b9f311f10ce9d31a32ff14ce58500458443627e4df4ae9c264defba7f/propcache-0.2.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:1ac2f5fe02fa75f56e1ad473f1175e11f475606ec9bd0be2e78e4734ad575034", size = 210442 }, + { url = "https://files.pythonhosted.org/packages/18/dd/a1670d483a61ecac0d7fc4305d91caaac7a8fc1b200ea3965a01cf03bced/propcache-0.2.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:574faa3b79e8ebac7cb1d7930f51184ba1ccf69adfdec53a12f319a06030a68b", size = 203219 }, + { url = "https://files.pythonhosted.org/packages/f9/2d/30ced5afde41b099b2dc0c6573b66b45d16d73090e85655f1a30c5a24e07/propcache-0.2.1-cp310-cp310-win32.whl", hash = "sha256:03ff9d3f665769b2a85e6157ac8b439644f2d7fd17615a82fa55739bc97863f4", size = 40313 }, + { url = "https://files.pythonhosted.org/packages/23/84/bd9b207ac80da237af77aa6e153b08ffa83264b1c7882495984fcbfcf85c/propcache-0.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:2d3af2e79991102678f53e0dbf4c35de99b6b8b58f29a27ca0325816364caaba", size = 44428 }, + { url = "https://files.pythonhosted.org/packages/bc/0f/2913b6791ebefb2b25b4efd4bb2299c985e09786b9f5b19184a88e5778dd/propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", size = 79297 }, + { url = "https://files.pythonhosted.org/packages/cf/73/af2053aeccd40b05d6e19058419ac77674daecdd32478088b79375b9ab54/propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", size = 45611 }, + { url = "https://files.pythonhosted.org/packages/3c/09/8386115ba7775ea3b9537730e8cf718d83bbf95bffe30757ccf37ec4e5da/propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", size = 45146 }, + { url = "https://files.pythonhosted.org/packages/03/7a/793aa12f0537b2e520bf09f4c6833706b63170a211ad042ca71cbf79d9cb/propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", size = 232136 }, + { url = "https://files.pythonhosted.org/packages/f1/38/b921b3168d72111769f648314100558c2ea1d52eb3d1ba7ea5c4aa6f9848/propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", size = 239706 }, + { url = "https://files.pythonhosted.org/packages/14/29/4636f500c69b5edea7786db3c34eb6166f3384b905665ce312a6e42c720c/propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", size = 238531 }, + { url = "https://files.pythonhosted.org/packages/85/14/01fe53580a8e1734ebb704a3482b7829a0ef4ea68d356141cf0994d9659b/propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", size = 231063 }, + { url = "https://files.pythonhosted.org/packages/33/5c/1d961299f3c3b8438301ccfbff0143b69afcc30c05fa28673cface692305/propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", size = 220134 }, + { url = "https://files.pythonhosted.org/packages/00/d0/ed735e76db279ba67a7d3b45ba4c654e7b02bc2f8050671ec365d8665e21/propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", size = 220009 }, + { url = "https://files.pythonhosted.org/packages/75/90/ee8fab7304ad6533872fee982cfff5a53b63d095d78140827d93de22e2d4/propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", size = 212199 }, + { url = "https://files.pythonhosted.org/packages/eb/ec/977ffaf1664f82e90737275873461695d4c9407d52abc2f3c3e24716da13/propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", size = 214827 }, + { url = "https://files.pythonhosted.org/packages/57/48/031fb87ab6081764054821a71b71942161619549396224cbb242922525e8/propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", size = 228009 }, + { url = "https://files.pythonhosted.org/packages/1a/06/ef1390f2524850838f2390421b23a8b298f6ce3396a7cc6d39dedd4047b0/propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", size = 231638 }, + { url = "https://files.pythonhosted.org/packages/38/2a/101e6386d5a93358395da1d41642b79c1ee0f3b12e31727932b069282b1d/propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", size = 222788 }, + { url = "https://files.pythonhosted.org/packages/db/81/786f687951d0979007e05ad9346cd357e50e3d0b0f1a1d6074df334b1bbb/propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", size = 40170 }, + { url = "https://files.pythonhosted.org/packages/cf/59/7cc7037b295d5772eceb426358bb1b86e6cab4616d971bd74275395d100d/propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", size = 44404 }, + { url = "https://files.pythonhosted.org/packages/4c/28/1d205fe49be8b1b4df4c50024e62480a442b1a7b818e734308bb0d17e7fb/propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", size = 79588 }, + { url = "https://files.pythonhosted.org/packages/21/ee/fc4d893f8d81cd4971affef2a6cb542b36617cd1d8ce56b406112cb80bf7/propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", size = 45825 }, + { url = "https://files.pythonhosted.org/packages/4a/de/bbe712f94d088da1d237c35d735f675e494a816fd6f54e9db2f61ef4d03f/propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", size = 45357 }, + { url = "https://files.pythonhosted.org/packages/7f/14/7ae06a6cf2a2f1cb382586d5a99efe66b0b3d0c6f9ac2f759e6f7af9d7cf/propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", size = 241869 }, + { url = "https://files.pythonhosted.org/packages/cc/59/227a78be960b54a41124e639e2c39e8807ac0c751c735a900e21315f8c2b/propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", size = 247884 }, + { url = "https://files.pythonhosted.org/packages/84/58/f62b4ffaedf88dc1b17f04d57d8536601e4e030feb26617228ef930c3279/propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", size = 248486 }, + { url = "https://files.pythonhosted.org/packages/1c/07/ebe102777a830bca91bbb93e3479cd34c2ca5d0361b83be9dbd93104865e/propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", size = 243649 }, + { url = "https://files.pythonhosted.org/packages/ed/bc/4f7aba7f08f520376c4bb6a20b9a981a581b7f2e385fa0ec9f789bb2d362/propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", size = 229103 }, + { url = "https://files.pythonhosted.org/packages/fe/d5/04ac9cd4e51a57a96f78795e03c5a0ddb8f23ec098b86f92de028d7f2a6b/propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", size = 226607 }, + { url = "https://files.pythonhosted.org/packages/e3/f0/24060d959ea41d7a7cc7fdbf68b31852331aabda914a0c63bdb0e22e96d6/propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", size = 221153 }, + { url = "https://files.pythonhosted.org/packages/77/a7/3ac76045a077b3e4de4859a0753010765e45749bdf53bd02bc4d372da1a0/propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", size = 222151 }, + { url = "https://files.pythonhosted.org/packages/e7/af/5e29da6f80cebab3f5a4dcd2a3240e7f56f2c4abf51cbfcc99be34e17f0b/propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", size = 233812 }, + { url = "https://files.pythonhosted.org/packages/8c/89/ebe3ad52642cc5509eaa453e9f4b94b374d81bae3265c59d5c2d98efa1b4/propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", size = 238829 }, + { url = "https://files.pythonhosted.org/packages/e9/2f/6b32f273fa02e978b7577159eae7471b3cfb88b48563b1c2578b2d7ca0bb/propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", size = 230704 }, + { url = "https://files.pythonhosted.org/packages/5c/2e/f40ae6ff5624a5f77edd7b8359b208b5455ea113f68309e2b00a2e1426b6/propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", size = 40050 }, + { url = "https://files.pythonhosted.org/packages/3b/77/a92c3ef994e47180862b9d7d11e37624fb1c00a16d61faf55115d970628b/propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", size = 44117 }, + { url = "https://files.pythonhosted.org/packages/0f/2a/329e0547cf2def8857157f9477669043e75524cc3e6251cef332b3ff256f/propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", size = 77002 }, + { url = "https://files.pythonhosted.org/packages/12/2d/c4df5415e2382f840dc2ecbca0eeb2293024bc28e57a80392f2012b4708c/propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", size = 44639 }, + { url = "https://files.pythonhosted.org/packages/d0/5a/21aaa4ea2f326edaa4e240959ac8b8386ea31dedfdaa636a3544d9e7a408/propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", size = 44049 }, + { url = "https://files.pythonhosted.org/packages/4e/3e/021b6cd86c0acc90d74784ccbb66808b0bd36067a1bf3e2deb0f3845f618/propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", size = 224819 }, + { url = "https://files.pythonhosted.org/packages/3c/57/c2fdeed1b3b8918b1770a133ba5c43ad3d78e18285b0c06364861ef5cc38/propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", size = 229625 }, + { url = "https://files.pythonhosted.org/packages/9d/81/70d4ff57bf2877b5780b466471bebf5892f851a7e2ca0ae7ffd728220281/propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", size = 232934 }, + { url = "https://files.pythonhosted.org/packages/3c/b9/bb51ea95d73b3fb4100cb95adbd4e1acaf2cbb1fd1083f5468eeb4a099a8/propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", size = 227361 }, + { url = "https://files.pythonhosted.org/packages/f1/20/3c6d696cd6fd70b29445960cc803b1851a1131e7a2e4ee261ee48e002bcd/propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", size = 213904 }, + { url = "https://files.pythonhosted.org/packages/a1/cb/1593bfc5ac6d40c010fa823f128056d6bc25b667f5393781e37d62f12005/propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", size = 212632 }, + { url = "https://files.pythonhosted.org/packages/6d/5c/e95617e222be14a34c709442a0ec179f3207f8a2b900273720501a70ec5e/propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", size = 207897 }, + { url = "https://files.pythonhosted.org/packages/8e/3b/56c5ab3dc00f6375fbcdeefdede5adf9bee94f1fab04adc8db118f0f9e25/propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", size = 208118 }, + { url = "https://files.pythonhosted.org/packages/86/25/d7ef738323fbc6ebcbce33eb2a19c5e07a89a3df2fded206065bd5e868a9/propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", size = 217851 }, + { url = "https://files.pythonhosted.org/packages/b3/77/763e6cef1852cf1ba740590364ec50309b89d1c818e3256d3929eb92fabf/propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", size = 222630 }, + { url = "https://files.pythonhosted.org/packages/4f/e9/0f86be33602089c701696fbed8d8c4c07b6ee9605c5b7536fd27ed540c5b/propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", size = 216269 }, + { url = "https://files.pythonhosted.org/packages/cc/02/5ac83217d522394b6a2e81a2e888167e7ca629ef6569a3f09852d6dcb01a/propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", size = 39472 }, + { url = "https://files.pythonhosted.org/packages/f4/33/d6f5420252a36034bc8a3a01171bc55b4bff5df50d1c63d9caa50693662f/propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", size = 43363 }, + { url = "https://files.pythonhosted.org/packages/41/b6/c5319caea262f4821995dca2107483b94a3345d4607ad797c76cb9c36bcc/propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", size = 11818 }, ] [[package]] @@ -1054,20 +1152,21 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ce/ac/5b1ea50fc08a9df82de7e1771537557f07c2632231bbab652c7e22597908/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bb89f0a835bcfc1d42ccd5f41f04870c1b936d8507c6df12b7737febc40f0909", size = 2822712 }, { url = "https://files.pythonhosted.org/packages/c4/fc/504d4503b2abc4570fac3ca56eb8fed5e437bf9c9ef13f36b6621db8ef00/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f0c2d907a1e102526dd2986df638343388b94c33860ff3bbe1384130828714b1", size = 2920155 }, { url = "https://files.pythonhosted.org/packages/b2/d1/323581e9273ad2c0dbd1902f3fb50c441da86e894b6e25a73c3fda32c57e/psycopg2_binary-2.9.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8157bed2f51db683f31306aa497311b560f2265998122abe1dce6428bd86567", size = 2959356 }, + { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, ] [[package]] name = "pydantic" -version = "2.9.2" +version = "2.10.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a9/b7/d9e3f12af310e1120c21603644a1cd86f59060e040ec5c3a80b8f05fae30/pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f", size = 769917 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/ca334c2ef6f2e046b1144fe4bb2a5da8a4c574e7f2ebf7e16b34a6a2fa92/pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", size = 761287 } wheels = [ - { url = "https://files.pythonhosted.org/packages/df/e4/ba44652d562cbf0bf320e0f3810206149c8a4e99cdbf66da82e97ab53a15/pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12", size = 434928 }, + { url = "https://files.pythonhosted.org/packages/58/26/82663c79010b28eddf29dcdd0ea723439535fa917fce5905885c0e9ba562/pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53", size = 431426 }, ] [package.optional-dependencies] @@ -1077,87 +1176,104 @@ email = [ [[package]] name = "pydantic-core" -version = "2.23.4" +version = "2.27.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e2/aa/6b6a9b9f8537b872f552ddd46dd3da230367754b6f707b8e1e963f515ea3/pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863", size = 402156 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5c/8b/d3ae387f66277bd8104096d6ec0a145f4baa2966ebb2cad746c0920c9526/pydantic_core-2.23.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:b10bd51f823d891193d4717448fab065733958bdb6a6b351967bd349d48d5c9b", size = 1867835 }, - { url = "https://files.pythonhosted.org/packages/46/76/f68272e4c3a7df8777798282c5e47d508274917f29992d84e1898f8908c7/pydantic_core-2.23.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4fc714bdbfb534f94034efaa6eadd74e5b93c8fa6315565a222f7b6f42ca1166", size = 1776689 }, - { url = "https://files.pythonhosted.org/packages/cc/69/5f945b4416f42ea3f3bc9d2aaec66c76084a6ff4ff27555bf9415ab43189/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63e46b3169866bd62849936de036f901a9356e36376079b05efa83caeaa02ceb", size = 1800748 }, - { url = "https://files.pythonhosted.org/packages/50/ab/891a7b0054bcc297fb02d44d05c50e68154e31788f2d9d41d0b72c89fdf7/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ed1a53de42fbe34853ba90513cea21673481cd81ed1be739f7f2efb931b24916", size = 1806469 }, - { url = "https://files.pythonhosted.org/packages/31/7c/6e3fa122075d78f277a8431c4c608f061881b76c2b7faca01d317ee39b5d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cfdd16ab5e59fc31b5e906d1a3f666571abc367598e3e02c83403acabc092e07", size = 2002246 }, - { url = "https://files.pythonhosted.org/packages/ad/6f/22d5692b7ab63fc4acbc74de6ff61d185804a83160adba5e6cc6068e1128/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255a8ef062cbf6674450e668482456abac99a5583bbafb73f9ad469540a3a232", size = 2659404 }, - { url = "https://files.pythonhosted.org/packages/11/ac/1e647dc1121c028b691028fa61a4e7477e6aeb5132628fde41dd34c1671f/pydantic_core-2.23.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4a7cd62e831afe623fbb7aabbb4fe583212115b3ef38a9f6b71869ba644624a2", size = 2053940 }, - { url = "https://files.pythonhosted.org/packages/91/75/984740c17f12c3ce18b5a2fcc4bdceb785cce7df1511a4ce89bca17c7e2d/pydantic_core-2.23.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f09e2ff1f17c2b51f2bc76d1cc33da96298f0a036a137f5440ab3ec5360b624f", size = 1921437 }, - { url = "https://files.pythonhosted.org/packages/a0/74/13c5f606b64d93f0721e7768cd3e8b2102164866c207b8cd6f90bb15d24f/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e38e63e6f3d1cec5a27e0afe90a085af8b6806ee208b33030e65b6516353f1a3", size = 1966129 }, - { url = "https://files.pythonhosted.org/packages/18/03/9c4aa5919457c7b57a016c1ab513b1a926ed9b2bb7915bf8e506bf65c34b/pydantic_core-2.23.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0dbd8dbed2085ed23b5c04afa29d8fd2771674223135dc9bc937f3c09284d071", size = 2110908 }, - { url = "https://files.pythonhosted.org/packages/92/2c/053d33f029c5dc65e5cf44ff03ceeefb7cce908f8f3cca9265e7f9b540c8/pydantic_core-2.23.4-cp310-none-win32.whl", hash = "sha256:6531b7ca5f951d663c339002e91aaebda765ec7d61b7d1e3991051906ddde119", size = 1735278 }, - { url = "https://files.pythonhosted.org/packages/de/81/7dfe464eca78d76d31dd661b04b5f2036ec72ea8848dd87ab7375e185c23/pydantic_core-2.23.4-cp310-none-win_amd64.whl", hash = "sha256:7c9129eb40958b3d4500fa2467e6a83356b3b61bfff1b414c7361d9220f9ae8f", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/5d/30/890a583cd3f2be27ecf32b479d5d615710bb926d92da03e3f7838ff3e58b/pydantic_core-2.23.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:77733e3892bb0a7fa797826361ce8a9184d25c8dffaec60b7ffe928153680ba8", size = 1865160 }, - { url = "https://files.pythonhosted.org/packages/1d/9a/b634442e1253bc6889c87afe8bb59447f106ee042140bd57680b3b113ec7/pydantic_core-2.23.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b84d168f6c48fabd1f2027a3d1bdfe62f92cade1fb273a5d68e621da0e44e6d", size = 1776777 }, - { url = "https://files.pythonhosted.org/packages/75/9a/7816295124a6b08c24c96f9ce73085032d8bcbaf7e5a781cd41aa910c891/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:df49e7a0861a8c36d089c1ed57d308623d60416dab2647a4a17fe050ba85de0e", size = 1799244 }, - { url = "https://files.pythonhosted.org/packages/a9/8f/89c1405176903e567c5f99ec53387449e62f1121894aa9fc2c4fdc51a59b/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff02b6d461a6de369f07ec15e465a88895f3223eb75073ffea56b84d9331f607", size = 1805307 }, - { url = "https://files.pythonhosted.org/packages/d5/a5/1a194447d0da1ef492e3470680c66048fef56fc1f1a25cafbea4bc1d1c48/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:996a38a83508c54c78a5f41456b0103c30508fed9abcad0a59b876d7398f25fd", size = 2000663 }, - { url = "https://files.pythonhosted.org/packages/13/a5/1df8541651de4455e7d587cf556201b4f7997191e110bca3b589218745a5/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d97683ddee4723ae8c95d1eddac7c192e8c552da0c73a925a89fa8649bf13eea", size = 2655941 }, - { url = "https://files.pythonhosted.org/packages/44/31/a3899b5ce02c4316865e390107f145089876dff7e1dfc770a231d836aed8/pydantic_core-2.23.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:216f9b2d7713eb98cb83c80b9c794de1f6b7e3145eef40400c62e86cee5f4e1e", size = 2052105 }, - { url = "https://files.pythonhosted.org/packages/1b/aa/98e190f8745d5ec831f6d5449344c48c0627ac5fed4e5340a44b74878f8e/pydantic_core-2.23.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6f783e0ec4803c787bcea93e13e9932edab72068f68ecffdf86a99fd5918878b", size = 1919967 }, - { url = "https://files.pythonhosted.org/packages/ae/35/b6e00b6abb2acfee3e8f85558c02a0822e9a8b2f2d812ea8b9079b118ba0/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d0776dea117cf5272382634bd2a5c1b6eb16767c223c6a5317cd3e2a757c61a0", size = 1964291 }, - { url = "https://files.pythonhosted.org/packages/13/46/7bee6d32b69191cd649bbbd2361af79c472d72cb29bb2024f0b6e350ba06/pydantic_core-2.23.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d5f7a395a8cf1621939692dba2a6b6a830efa6b3cee787d82c7de1ad2930de64", size = 2109666 }, - { url = "https://files.pythonhosted.org/packages/39/ef/7b34f1b122a81b68ed0a7d0e564da9ccdc9a2924c8d6c6b5b11fa3a56970/pydantic_core-2.23.4-cp311-none-win32.whl", hash = "sha256:74b9127ffea03643e998e0c5ad9bd3811d3dac8c676e47db17b0ee7c3c3bf35f", size = 1732940 }, - { url = "https://files.pythonhosted.org/packages/2f/76/37b7e76c645843ff46c1d73e046207311ef298d3f7b2f7d8f6ac60113071/pydantic_core-2.23.4-cp311-none-win_amd64.whl", hash = "sha256:98d134c954828488b153d88ba1f34e14259284f256180ce659e8d83e9c05eaa3", size = 1916804 }, - { url = "https://files.pythonhosted.org/packages/74/7b/8e315f80666194b354966ec84b7d567da77ad927ed6323db4006cf915f3f/pydantic_core-2.23.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:f3e0da4ebaef65158d4dfd7d3678aad692f7666877df0002b8a522cdf088f231", size = 1856459 }, - { url = "https://files.pythonhosted.org/packages/14/de/866bdce10ed808323d437612aca1ec9971b981e1c52e5e42ad9b8e17a6f6/pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee", size = 1770007 }, - { url = "https://files.pythonhosted.org/packages/dc/69/8edd5c3cd48bb833a3f7ef9b81d7666ccddd3c9a635225214e044b6e8281/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:723314c1d51722ab28bfcd5240d858512ffd3116449c557a1336cbe3919beb87", size = 1790245 }, - { url = "https://files.pythonhosted.org/packages/80/33/9c24334e3af796ce80d2274940aae38dd4e5676298b4398eff103a79e02d/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bb2802e667b7051a1bebbfe93684841cc9351004e2badbd6411bf357ab8d5ac8", size = 1801260 }, - { url = "https://files.pythonhosted.org/packages/a5/6f/e9567fd90104b79b101ca9d120219644d3314962caa7948dd8b965e9f83e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d18ca8148bebe1b0a382a27a8ee60350091a6ddaf475fa05ef50dc35b5df6327", size = 1996872 }, - { url = "https://files.pythonhosted.org/packages/2d/ad/b5f0fe9e6cfee915dd144edbd10b6e9c9c9c9d7a56b69256d124b8ac682e/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33e3d65a85a2a4a0dc3b092b938a4062b1a05f3a9abde65ea93b233bca0e03f2", size = 2661617 }, - { url = "https://files.pythonhosted.org/packages/06/c8/7d4b708f8d05a5cbfda3243aad468052c6e99de7d0937c9146c24d9f12e9/pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36", size = 2071831 }, - { url = "https://files.pythonhosted.org/packages/89/4d/3079d00c47f22c9a9a8220db088b309ad6e600a73d7a69473e3a8e5e3ea3/pydantic_core-2.23.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:68665f4c17edcceecc112dfed5dbe6f92261fb9d6054b47d01bf6371a6196126", size = 1917453 }, - { url = "https://files.pythonhosted.org/packages/e9/88/9df5b7ce880a4703fcc2d76c8c2d8eb9f861f79d0c56f4b8f5f2607ccec8/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:20152074317d9bed6b7a95ade3b7d6054845d70584216160860425f4fbd5ee9e", size = 1968793 }, - { url = "https://files.pythonhosted.org/packages/e3/b9/41f7efe80f6ce2ed3ee3c2dcfe10ab7adc1172f778cc9659509a79518c43/pydantic_core-2.23.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:9261d3ce84fa1d38ed649c3638feefeae23d32ba9182963e465d58d62203bd24", size = 2116872 }, - { url = "https://files.pythonhosted.org/packages/63/08/b59b7a92e03dd25554b0436554bf23e7c29abae7cce4b1c459cd92746811/pydantic_core-2.23.4-cp312-none-win32.whl", hash = "sha256:4ba762ed58e8d68657fc1281e9bb72e1c3e79cc5d464be146e260c541ec12d84", size = 1738535 }, - { url = "https://files.pythonhosted.org/packages/88/8d/479293e4d39ab409747926eec4329de5b7129beaedc3786eca070605d07f/pydantic_core-2.23.4-cp312-none-win_amd64.whl", hash = "sha256:97df63000f4fea395b2824da80e169731088656d1818a11b95f3b173747b6cd9", size = 1917992 }, - { url = "https://files.pythonhosted.org/packages/ad/ef/16ee2df472bf0e419b6bc68c05bf0145c49247a1095e85cee1463c6a44a1/pydantic_core-2.23.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7530e201d10d7d14abce4fb54cfe5b94a0aefc87da539d0346a484ead376c3cc", size = 1856143 }, - { url = "https://files.pythonhosted.org/packages/da/fa/bc3dbb83605669a34a93308e297ab22be82dfb9dcf88c6cf4b4f264e0a42/pydantic_core-2.23.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:df933278128ea1cd77772673c73954e53a1c95a4fdf41eef97c2b779271bd0bd", size = 1770063 }, - { url = "https://files.pythonhosted.org/packages/4e/48/e813f3bbd257a712303ebdf55c8dc46f9589ec74b384c9f652597df3288d/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cb3da3fd1b6a5d0279a01877713dbda118a2a4fc6f0d821a57da2e464793f05", size = 1790013 }, - { url = "https://files.pythonhosted.org/packages/b4/e0/56eda3a37929a1d297fcab1966db8c339023bcca0b64c5a84896db3fcc5c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:42c6dcb030aefb668a2b7009c85b27f90e51e6a3b4d5c9bc4c57631292015b0d", size = 1801077 }, - { url = "https://files.pythonhosted.org/packages/04/be/5e49376769bfbf82486da6c5c1683b891809365c20d7c7e52792ce4c71f3/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:696dd8d674d6ce621ab9d45b205df149399e4bb9aa34102c970b721554828510", size = 1996782 }, - { url = "https://files.pythonhosted.org/packages/bc/24/e3ee6c04f1d58cc15f37bcc62f32c7478ff55142b7b3e6d42ea374ea427c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2971bb5ffe72cc0f555c13e19b23c85b654dd2a8f7ab493c262071377bfce9f6", size = 2661375 }, - { url = "https://files.pythonhosted.org/packages/c1/f8/11a9006de4e89d016b8de74ebb1db727dc100608bb1e6bbe9d56a3cbbcce/pydantic_core-2.23.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8394d940e5d400d04cad4f75c0598665cbb81aecefaca82ca85bd28264af7f9b", size = 2071635 }, - { url = "https://files.pythonhosted.org/packages/7c/45/bdce5779b59f468bdf262a5bc9eecbae87f271c51aef628d8c073b4b4b4c/pydantic_core-2.23.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0dff76e0602ca7d4cdaacc1ac4c005e0ce0dcfe095d5b5259163a80d3a10d327", size = 1916994 }, - { url = "https://files.pythonhosted.org/packages/d8/fa/c648308fe711ee1f88192cad6026ab4f925396d1293e8356de7e55be89b5/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7d32706badfe136888bdea71c0def994644e09fff0bfe47441deaed8e96fdbc6", size = 1968877 }, - { url = "https://files.pythonhosted.org/packages/16/16/b805c74b35607d24d37103007f899abc4880923b04929547ae68d478b7f4/pydantic_core-2.23.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ed541d70698978a20eb63d8c5d72f2cc6d7079d9d90f6b50bad07826f1320f5f", size = 2116814 }, - { url = "https://files.pythonhosted.org/packages/d1/58/5305e723d9fcdf1c5a655e6a4cc2a07128bf644ff4b1d98daf7a9dbf57da/pydantic_core-2.23.4-cp313-none-win32.whl", hash = "sha256:3d5639516376dce1940ea36edf408c554475369f5da2abd45d44621cb616f769", size = 1738360 }, - { url = "https://files.pythonhosted.org/packages/a5/ae/e14b0ff8b3f48e02394d8acd911376b7b66e164535687ef7dc24ea03072f/pydantic_core-2.23.4-cp313-none-win_amd64.whl", hash = "sha256:5a1504ad17ba4210df3a045132a7baeeba5a200e930f57512ee02909fc5c4cb5", size = 1919411 }, - { url = "https://files.pythonhosted.org/packages/13/a9/5d582eb3204464284611f636b55c0a7410d748ff338756323cb1ce721b96/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f455ee30a9d61d3e1a15abd5068827773d6e4dc513e795f380cdd59932c782d5", size = 1857135 }, - { url = "https://files.pythonhosted.org/packages/2c/57/faf36290933fe16717f97829eabfb1868182ac495f99cf0eda9f59687c9d/pydantic_core-2.23.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1e90d2e3bd2c3863d48525d297cd143fe541be8bbf6f579504b9712cb6b643ec", size = 1740583 }, - { url = "https://files.pythonhosted.org/packages/91/7c/d99e3513dc191c4fec363aef1bf4c8af9125d8fa53af7cb97e8babef4e40/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e203fdf807ac7e12ab59ca2bfcabb38c7cf0b33c41efeb00f8e5da1d86af480", size = 1793637 }, - { url = "https://files.pythonhosted.org/packages/29/18/812222b6d18c2d13eebbb0f7cdc170a408d9ced65794fdb86147c77e1982/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e08277a400de01bc72436a0ccd02bdf596631411f592ad985dcee21445bd0068", size = 1941963 }, - { url = "https://files.pythonhosted.org/packages/0f/36/c1f3642ac3f05e6bb4aec3ffc399fa3f84895d259cf5f0ce3054b7735c29/pydantic_core-2.23.4-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f220b0eea5965dec25480b6333c788fb72ce5f9129e8759ef876a1d805d00801", size = 1915332 }, - { url = "https://files.pythonhosted.org/packages/f7/ca/9c0854829311fb446020ebb540ee22509731abad886d2859c855dd29b904/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:d06b0c8da4f16d1d1e352134427cb194a0a6e19ad5db9161bf32b2113409e728", size = 1957926 }, - { url = "https://files.pythonhosted.org/packages/c0/1c/7836b67c42d0cd4441fcd9fafbf6a027ad4b79b6559f80cf11f89fd83648/pydantic_core-2.23.4-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:ba1a0996f6c2773bd83e63f18914c1de3c9dd26d55f4ac302a7efe93fb8e7433", size = 2100342 }, - { url = "https://files.pythonhosted.org/packages/a9/f9/b6bcaf874f410564a78908739c80861a171788ef4d4f76f5009656672dfe/pydantic_core-2.23.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:9a5bce9d23aac8f0cf0836ecfc033896aa8443b501c58d0602dbfd5bd5b37753", size = 1920344 }, +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/bc/fed5f74b5d802cf9a03e83f60f18864e90e3aed7223adaca5ffb7a8d8d64/pydantic_core-2.27.2-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:2d367ca20b2f14095a8f4fa1210f5a7b78b8a20009ecced6b12818f455b1e9fa", size = 1895938 }, + { url = "https://files.pythonhosted.org/packages/71/2a/185aff24ce844e39abb8dd680f4e959f0006944f4a8a0ea372d9f9ae2e53/pydantic_core-2.27.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:491a2b73db93fab69731eaee494f320faa4e093dbed776be1a829c2eb222c34c", size = 1815684 }, + { url = "https://files.pythonhosted.org/packages/c3/43/fafabd3d94d159d4f1ed62e383e264f146a17dd4d48453319fd782e7979e/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7969e133a6f183be60e9f6f56bfae753585680f3b7307a8e555a948d443cc05a", size = 1829169 }, + { url = "https://files.pythonhosted.org/packages/a2/d1/f2dfe1a2a637ce6800b799aa086d079998959f6f1215eb4497966efd2274/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3de9961f2a346257caf0aa508a4da705467f53778e9ef6fe744c038119737ef5", size = 1867227 }, + { url = "https://files.pythonhosted.org/packages/7d/39/e06fcbcc1c785daa3160ccf6c1c38fea31f5754b756e34b65f74e99780b5/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e2bb4d3e5873c37bb3dd58714d4cd0b0e6238cebc4177ac8fe878f8b3aa8e74c", size = 2037695 }, + { url = "https://files.pythonhosted.org/packages/7a/67/61291ee98e07f0650eb756d44998214231f50751ba7e13f4f325d95249ab/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:280d219beebb0752699480fe8f1dc61ab6615c2046d76b7ab7ee38858de0a4e7", size = 2741662 }, + { url = "https://files.pythonhosted.org/packages/32/90/3b15e31b88ca39e9e626630b4c4a1f5a0dfd09076366f4219429e6786076/pydantic_core-2.27.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47956ae78b6422cbd46f772f1746799cbb862de838fd8d1fbd34a82e05b0983a", size = 1993370 }, + { url = "https://files.pythonhosted.org/packages/ff/83/c06d333ee3a67e2e13e07794995c1535565132940715931c1c43bfc85b11/pydantic_core-2.27.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:14d4a5c49d2f009d62a2a7140d3064f686d17a5d1a268bc641954ba181880236", size = 1996813 }, + { url = "https://files.pythonhosted.org/packages/7c/f7/89be1c8deb6e22618a74f0ca0d933fdcb8baa254753b26b25ad3acff8f74/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:337b443af21d488716f8d0b6164de833e788aa6bd7e3a39c005febc1284f4962", size = 2005287 }, + { url = "https://files.pythonhosted.org/packages/b7/7d/8eb3e23206c00ef7feee17b83a4ffa0a623eb1a9d382e56e4aa46fd15ff2/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_armv7l.whl", hash = "sha256:03d0f86ea3184a12f41a2d23f7ccb79cdb5a18e06993f8a45baa8dfec746f0e9", size = 2128414 }, + { url = "https://files.pythonhosted.org/packages/4e/99/fe80f3ff8dd71a3ea15763878d464476e6cb0a2db95ff1c5c554133b6b83/pydantic_core-2.27.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7041c36f5680c6e0f08d922aed302e98b3745d97fe1589db0a3eebf6624523af", size = 2155301 }, + { url = "https://files.pythonhosted.org/packages/2b/a3/e50460b9a5789ca1451b70d4f52546fa9e2b420ba3bfa6100105c0559238/pydantic_core-2.27.2-cp310-cp310-win32.whl", hash = "sha256:50a68f3e3819077be2c98110c1f9dcb3817e93f267ba80a2c05bb4f8799e2ff4", size = 1816685 }, + { url = "https://files.pythonhosted.org/packages/57/4c/a8838731cb0f2c2a39d3535376466de6049034d7b239c0202a64aaa05533/pydantic_core-2.27.2-cp310-cp310-win_amd64.whl", hash = "sha256:e0fd26b16394ead34a424eecf8a31a1f5137094cabe84a1bcb10fa6ba39d3d31", size = 1982876 }, + { url = "https://files.pythonhosted.org/packages/c2/89/f3450af9d09d44eea1f2c369f49e8f181d742f28220f88cc4dfaae91ea6e/pydantic_core-2.27.2-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:8e10c99ef58cfdf2a66fc15d66b16c4a04f62bca39db589ae8cba08bc55331bc", size = 1893421 }, + { url = "https://files.pythonhosted.org/packages/9e/e3/71fe85af2021f3f386da42d291412e5baf6ce7716bd7101ea49c810eda90/pydantic_core-2.27.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:26f32e0adf166a84d0cb63be85c562ca8a6fa8de28e5f0d92250c6b7e9e2aff7", size = 1814998 }, + { url = "https://files.pythonhosted.org/packages/a6/3c/724039e0d848fd69dbf5806894e26479577316c6f0f112bacaf67aa889ac/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c19d1ea0673cd13cc2f872f6c9ab42acc4e4f492a7ca9d3795ce2b112dd7e15", size = 1826167 }, + { url = "https://files.pythonhosted.org/packages/2b/5b/1b29e8c1fb5f3199a9a57c1452004ff39f494bbe9bdbe9a81e18172e40d3/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e68c4446fe0810e959cdff46ab0a41ce2f2c86d227d96dc3847af0ba7def306", size = 1865071 }, + { url = "https://files.pythonhosted.org/packages/89/6c/3985203863d76bb7d7266e36970d7e3b6385148c18a68cc8915fd8c84d57/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d9640b0059ff4f14d1f37321b94061c6db164fbe49b334b31643e0528d100d99", size = 2036244 }, + { url = "https://files.pythonhosted.org/packages/0e/41/f15316858a246b5d723f7d7f599f79e37493b2e84bfc789e58d88c209f8a/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:40d02e7d45c9f8af700f3452f329ead92da4c5f4317ca9b896de7ce7199ea459", size = 2737470 }, + { url = "https://files.pythonhosted.org/packages/a8/7c/b860618c25678bbd6d1d99dbdfdf0510ccb50790099b963ff78a124b754f/pydantic_core-2.27.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c1fd185014191700554795c99b347d64f2bb637966c4cfc16998a0ca700d048", size = 1992291 }, + { url = "https://files.pythonhosted.org/packages/bf/73/42c3742a391eccbeab39f15213ecda3104ae8682ba3c0c28069fbcb8c10d/pydantic_core-2.27.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d81d2068e1c1228a565af076598f9e7451712700b673de8f502f0334f281387d", size = 1994613 }, + { url = "https://files.pythonhosted.org/packages/94/7a/941e89096d1175d56f59340f3a8ebaf20762fef222c298ea96d36a6328c5/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1a4207639fb02ec2dbb76227d7c751a20b1a6b4bc52850568e52260cae64ca3b", size = 2002355 }, + { url = "https://files.pythonhosted.org/packages/6e/95/2359937a73d49e336a5a19848713555605d4d8d6940c3ec6c6c0ca4dcf25/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:3de3ce3c9ddc8bbd88f6e0e304dea0e66d843ec9de1b0042b0911c1663ffd474", size = 2126661 }, + { url = "https://files.pythonhosted.org/packages/2b/4c/ca02b7bdb6012a1adef21a50625b14f43ed4d11f1fc237f9d7490aa5078c/pydantic_core-2.27.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:30c5f68ded0c36466acede341551106821043e9afaad516adfb6e8fa80a4e6a6", size = 2153261 }, + { url = "https://files.pythonhosted.org/packages/72/9d/a241db83f973049a1092a079272ffe2e3e82e98561ef6214ab53fe53b1c7/pydantic_core-2.27.2-cp311-cp311-win32.whl", hash = "sha256:c70c26d2c99f78b125a3459f8afe1aed4d9687c24fd677c6a4436bc042e50d6c", size = 1812361 }, + { url = "https://files.pythonhosted.org/packages/e8/ef/013f07248041b74abd48a385e2110aa3a9bbfef0fbd97d4e6d07d2f5b89a/pydantic_core-2.27.2-cp311-cp311-win_amd64.whl", hash = "sha256:08e125dbdc505fa69ca7d9c499639ab6407cfa909214d500897d02afb816e7cc", size = 1982484 }, + { url = "https://files.pythonhosted.org/packages/10/1c/16b3a3e3398fd29dca77cea0a1d998d6bde3902fa2706985191e2313cc76/pydantic_core-2.27.2-cp311-cp311-win_arm64.whl", hash = "sha256:26f0d68d4b235a2bae0c3fc585c585b4ecc51382db0e3ba402a22cbc440915e4", size = 1867102 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, + { url = "https://files.pythonhosted.org/packages/46/72/af70981a341500419e67d5cb45abe552a7c74b66326ac8877588488da1ac/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:2bf14caea37e91198329b828eae1618c068dfb8ef17bb33287a7ad4b61ac314e", size = 1891159 }, + { url = "https://files.pythonhosted.org/packages/ad/3d/c5913cccdef93e0a6a95c2d057d2c2cba347815c845cda79ddd3c0f5e17d/pydantic_core-2.27.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:b0cb791f5b45307caae8810c2023a184c74605ec3bcbb67d13846c28ff731ff8", size = 1768331 }, + { url = "https://files.pythonhosted.org/packages/f6/f0/a3ae8fbee269e4934f14e2e0e00928f9346c5943174f2811193113e58252/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:688d3fd9fcb71f41c4c015c023d12a79d1c4c0732ec9eb35d96e3388a120dcf3", size = 1822467 }, + { url = "https://files.pythonhosted.org/packages/d7/7a/7bbf241a04e9f9ea24cd5874354a83526d639b02674648af3f350554276c/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d591580c34f4d731592f0e9fe40f9cc1b430d297eecc70b962e93c5c668f15f", size = 1979797 }, + { url = "https://files.pythonhosted.org/packages/4f/5f/4784c6107731f89e0005a92ecb8a2efeafdb55eb992b8e9d0a2be5199335/pydantic_core-2.27.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:82f986faf4e644ffc189a7f1aafc86e46ef70372bb153e7001e8afccc6e54133", size = 1987839 }, + { url = "https://files.pythonhosted.org/packages/6d/a7/61246562b651dff00de86a5f01b6e4befb518df314c54dec187a78d81c84/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:bec317a27290e2537f922639cafd54990551725fc844249e64c523301d0822fc", size = 1998861 }, + { url = "https://files.pythonhosted.org/packages/86/aa/837821ecf0c022bbb74ca132e117c358321e72e7f9702d1b6a03758545e2/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:0296abcb83a797db256b773f45773da397da75a08f5fcaef41f2044adec05f50", size = 2116582 }, + { url = "https://files.pythonhosted.org/packages/81/b0/5e74656e95623cbaa0a6278d16cf15e10a51f6002e3ec126541e95c29ea3/pydantic_core-2.27.2-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:0d75070718e369e452075a6017fbf187f788e17ed67a3abd47fa934d001863d9", size = 2151985 }, + { url = "https://files.pythonhosted.org/packages/63/37/3e32eeb2a451fddaa3898e2163746b0cffbbdbb4740d38372db0490d67f3/pydantic_core-2.27.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:7e17b560be3c98a8e3aa66ce828bdebb9e9ac6ad5466fba92eb74c4c95cb1151", size = 2004715 }, ] [[package]] name = "pydantic-settings" -version = "2.6.1" +version = "2.7.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b5/d4/9dfbe238f45ad8b168f5c96ee49a3df0598ce18a0795a983b419949ce65b/pydantic_settings-2.6.1.tar.gz", hash = "sha256:e0f92546d8a9923cb8941689abf85d6601a8c19a23e97a34b2964a2e3f813ca0", size = 75646 } +sdist = { url = "https://files.pythonhosted.org/packages/73/7b/c58a586cd7d9ac66d2ee4ba60ca2d241fa837c02bca9bea80a9a8c3d22a9/pydantic_settings-2.7.1.tar.gz", hash = "sha256:10c9caad35e64bfb3c2fbf70a078c0e25cc92499782e5200747f942a065dec93", size = 79920 } wheels = [ - { url = "https://files.pythonhosted.org/packages/5e/f9/ff95fd7d760af42f647ea87f9b8a383d891cdb5e5dbd4613edaeb094252a/pydantic_settings-2.6.1-py3-none-any.whl", hash = "sha256:7fb0637c786a558d3103436278a7c4f1cfd29ba8973238a50c5bb9a55387da87", size = 28595 }, + { url = "https://files.pythonhosted.org/packages/b4/46/93416fdae86d40879714f72956ac14df9c7b76f7d41a4d68aa9f71a0028b/pydantic_settings-2.7.1-py3-none-any.whl", hash = "sha256:590be9e6e24d06db33a4262829edef682500ef008565a969c73d39d5f8bfb3fd", size = 29718 }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, ] [[package]] name = "pytest" -version = "8.3.3" +version = "8.3.4" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -1167,9 +1283,9 @@ dependencies = [ { name = "pluggy" }, { name = "tomli", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } wheels = [ - { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, ] [[package]] @@ -1209,11 +1325,11 @@ wheels = [ [[package]] name = "python-multipart" -version = "0.0.17" +version = "0.0.20" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/40/22/edea41c2d4a22e666c0c7db7acdcbf7bc8c1c1f7d3b3ca246ec982fec612/python_multipart-0.0.17.tar.gz", hash = "sha256:41330d831cae6e2f22902704ead2826ea038d0419530eadff3ea80175aec5538", size = 36452 } +sdist = { url = "https://files.pythonhosted.org/packages/f3/87/f44d7c9f274c7ee665a29b885ec97089ec5dc034c7f3fafa03da9e39a09e/python_multipart-0.0.20.tar.gz", hash = "sha256:8dd0cab45b8e23064ae09147625994d090fa46f5b0d1e13af944c331a7fa9d13", size = 37158 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/fb/275137a799169392f1fa88fff2be92f16eee38e982720a8aaadefc4a36b2/python_multipart-0.0.17-py3-none-any.whl", hash = "sha256:15dc4f487e0a9476cc1201261188ee0940165cffc94429b6fc565c4d3045cb5d", size = 24453 }, + { url = "https://files.pythonhosted.org/packages/45/58/38b5afbc1a800eeea951b9285d3912613f2603bdf897a4ab0f4bd7f405fc/python_multipart-0.0.20-py3-none-any.whl", hash = "sha256:8a62d3a8335e06589fe01f2a3e178cdcc632f3fbe0d492ad9ee0ec35aab1f104", size = 24546 }, ] [[package]] @@ -1262,7 +1378,7 @@ wheels = [ [[package]] name = "realtime" -version = "2.0.6" +version = "2.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1270,18 +1386,55 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fe/7d/07f006df098c5fc9e00488e5268bcd7af0ee30a65fd6dfdbcee17ffeaa3b/realtime-2.0.6.tar.gz", hash = "sha256:ced37686a77a546571029ecc74cfb31fff1404a5159d1198fa882af545843a6f", size = 17463 } +sdist = { url = "https://files.pythonhosted.org/packages/97/c7/f7c93b658d486c393c33211e44ef56aba625df570ee93e97bda073483177/realtime-2.1.0.tar.gz", hash = "sha256:ca3ae6be47667a3cf3a307fec982ec1bf60313c38a8e29f016ab0380b76d7adb", size = 18207 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/d5/77d42647c73e328a705881d5466f2df3d8f6d63e60be212538779a9c2473/realtime-2.1.0-py3-none-any.whl", hash = "sha256:e2d4f28bb2a08c1cf80e40fbf31e6116544ad29d67dd4093093e511ad738708c", size = 21438 }, +] + +[[package]] +name = "rich" +version = "13.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 }, +] + +[[package]] +name = "rich-toolkit" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/8a/71cfbf6bf6257ea785d1f030c22468f763eea1b3e5417620f2ba9abd6dca/rich_toolkit-0.13.2.tar.gz", hash = "sha256:fea92557530de7c28f121cbed572ad93d9e0ddc60c3ca643f1b831f2f56b95d3", size = 72288 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/1b/1c2f43af46456050b27810a7a013af8a7e12bc545a0cdc00eb0df55eb769/rich_toolkit-0.13.2-py3-none-any.whl", hash = "sha256:f3f6c583e5283298a2f7dbd3c65aca18b7f818ad96174113ab5bec0b0e35ed61", size = 13566 }, +] + +[[package]] +name = "shellingham" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/fc/47a6615db976d5417ad982a15983cb3750910e0672d2e7e2d620433cdb2f/realtime-2.0.6-py3-none-any.whl", hash = "sha256:9aab6009c11883197386a0a9dc8c2b6939e62dddda734cfb77594727ac9ae0ce", size = 20568 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, ] [[package]] name = "six" -version = "1.16.0" +version = "1.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 }, + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, ] [[package]] @@ -1295,47 +1448,47 @@ wheels = [ [[package]] name = "sqlalchemy" -version = "2.0.36" +version = "2.0.37" source = { registry = "https://pypi.org/simple" } dependencies = [ - { name = "greenlet", marker = "(python_full_version < '3.13' and platform_machine == 'AMD64') or (python_full_version < '3.13' and platform_machine == 'WIN32') or (python_full_version < '3.13' and platform_machine == 'aarch64') or (python_full_version < '3.13' and platform_machine == 'amd64') or (python_full_version < '3.13' and platform_machine == 'ppc64le') or (python_full_version < '3.13' and platform_machine == 'win32') or (python_full_version < '3.13' and platform_machine == 'x86_64')" }, + { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/50/65/9cbc9c4c3287bed2499e05033e207473504dc4df999ce49385fb1f8b058a/sqlalchemy-2.0.36.tar.gz", hash = "sha256:7f2767680b6d2398aea7082e45a774b2b0767b5c8d8ffb9c8b683088ea9b29c5", size = 9574485 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/db/72/14ab694b8b3f0e35ef5beb74a8fea2811aa791ba1611c44dc90cdf46af17/SQLAlchemy-2.0.36-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:59b8f3adb3971929a3e660337f5dacc5942c2cdb760afcabb2614ffbda9f9f72", size = 2092604 }, - { url = "https://files.pythonhosted.org/packages/1e/59/333fcbca58b79f5b8b61853d6137530198823392151fa8fd9425f367519e/SQLAlchemy-2.0.36-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:37350015056a553e442ff672c2d20e6f4b6d0b2495691fa239d8aa18bb3bc908", size = 2083796 }, - { url = "https://files.pythonhosted.org/packages/6c/a0/ec3c188d2b0c1bc742262e76408d44104598d7247c23f5b06bb97ee21bfa/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8318f4776c85abc3f40ab185e388bee7a6ea99e7fa3a30686580b209eaa35c08", size = 3066165 }, - { url = "https://files.pythonhosted.org/packages/07/15/68ef91de5b8b7f80fb2d2b3b31ed42180c6227fe0a701aed9d01d34f98ec/SQLAlchemy-2.0.36-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c245b1fbade9c35e5bd3b64270ab49ce990369018289ecfde3f9c318411aaa07", size = 3074428 }, - { url = "https://files.pythonhosted.org/packages/e2/4c/9dfea5e63b87325eef6d9cdaac913459aa6a157a05a05ea6ff20004aee8e/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:69f93723edbca7342624d09f6704e7126b152eaed3cdbb634cb657a54332a3c5", size = 3030477 }, - { url = "https://files.pythonhosted.org/packages/16/a5/fcfde8e74ea5f683b24add22463bfc21e431d4a5531c8a5b55bc6fbea164/SQLAlchemy-2.0.36-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f9511d8dd4a6e9271d07d150fb2f81874a3c8c95e11ff9af3a2dfc35fe42ee44", size = 3055942 }, - { url = "https://files.pythonhosted.org/packages/3c/ee/c22c415a771d791ae99146d72ffdb20e43625acd24835ea7fc157436d59f/SQLAlchemy-2.0.36-cp310-cp310-win32.whl", hash = "sha256:c3f3631693003d8e585d4200730616b78fafd5a01ef8b698f6967da5c605b3fa", size = 2064960 }, - { url = "https://files.pythonhosted.org/packages/aa/af/ad9c25cadc79bd851bdb9d82b68af9bdb91ff05f56d0da2f8a654825974f/SQLAlchemy-2.0.36-cp310-cp310-win_amd64.whl", hash = "sha256:a86bfab2ef46d63300c0f06936bd6e6c0105faa11d509083ba8f2f9d237fb5b5", size = 2089078 }, - { url = "https://files.pythonhosted.org/packages/00/4e/5a67963fd7cbc1beb8bd2152e907419f4c940ef04600b10151a751fe9e06/SQLAlchemy-2.0.36-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fd3a55deef00f689ce931d4d1b23fa9f04c880a48ee97af488fd215cf24e2a6c", size = 2093782 }, - { url = "https://files.pythonhosted.org/packages/b3/24/30e33b6389ebb5a17df2a4243b091bc709fb3dfc9a48c8d72f8e037c943d/SQLAlchemy-2.0.36-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f5e9cd989b45b73bd359f693b935364f7e1f79486e29015813c338450aa5a71", size = 2084180 }, - { url = "https://files.pythonhosted.org/packages/10/1e/70e9ed2143a27065246be40f78637ad5160ea0f5fd32f8cab819a31ff54d/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0ddd9db6e59c44875211bc4c7953a9f6638b937b0a88ae6d09eb46cced54eff", size = 3202469 }, - { url = "https://files.pythonhosted.org/packages/b4/5f/95e0ed74093ac3c0db6acfa944d4d8ac6284ef5e1136b878a327ea1f975a/SQLAlchemy-2.0.36-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2519f3a5d0517fc159afab1015e54bb81b4406c278749779be57a569d8d1bb0d", size = 3202464 }, - { url = "https://files.pythonhosted.org/packages/91/95/2cf9b85a6bc2ee660e40594dffe04e777e7b8617fd0c6d77a0f782ea96c9/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:59b1ee96617135f6e1d6f275bbe988f419c5178016f3d41d3c0abb0c819f75bb", size = 3139508 }, - { url = "https://files.pythonhosted.org/packages/92/ea/f0c01bc646456e4345c0fb5a3ddef457326285c2dc60435b0eb96b61bf31/SQLAlchemy-2.0.36-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:39769a115f730d683b0eb7b694db9789267bcd027326cccc3125e862eb03bfd8", size = 3159837 }, - { url = "https://files.pythonhosted.org/packages/a6/93/c8edbf153ee38fe529773240877bf1332ed95328aceef6254288f446994e/SQLAlchemy-2.0.36-cp311-cp311-win32.whl", hash = "sha256:66bffbad8d6271bb1cc2f9a4ea4f86f80fe5e2e3e501a5ae2a3dc6a76e604e6f", size = 2064529 }, - { url = "https://files.pythonhosted.org/packages/b1/03/d12b7c1d36fd80150c1d52e121614cf9377dac99e5497af8d8f5b2a8db64/SQLAlchemy-2.0.36-cp311-cp311-win_amd64.whl", hash = "sha256:23623166bfefe1487d81b698c423f8678e80df8b54614c2bf4b4cfcd7c711959", size = 2089874 }, - { url = "https://files.pythonhosted.org/packages/b8/bf/005dc47f0e57556e14512d5542f3f183b94fde46e15ff1588ec58ca89555/SQLAlchemy-2.0.36-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7b64e6ec3f02c35647be6b4851008b26cff592a95ecb13b6788a54ef80bbdd4", size = 2092378 }, - { url = "https://files.pythonhosted.org/packages/94/65/f109d5720779a08e6e324ec89a744f5f92c48bd8005edc814bf72fbb24e5/SQLAlchemy-2.0.36-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46331b00096a6db1fdc052d55b101dbbfc99155a548e20a0e4a8e5e4d1362855", size = 2082778 }, - { url = "https://files.pythonhosted.org/packages/60/f6/d9aa8c49c44f9b8c9b9dada1f12fa78df3d4c42aa2de437164b83ee1123c/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdf3386a801ea5aba17c6410dd1dc8d39cf454ca2565541b5ac42a84e1e28f53", size = 3232191 }, - { url = "https://files.pythonhosted.org/packages/8a/ab/81d4514527c068670cb1d7ab62a81a185df53a7c379bd2a5636e83d09ede/SQLAlchemy-2.0.36-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac9dfa18ff2a67b09b372d5db8743c27966abf0e5344c555d86cc7199f7ad83a", size = 3243044 }, - { url = "https://files.pythonhosted.org/packages/35/b4/f87c014ecf5167dc669199cafdb20a7358ff4b1d49ce3622cc48571f811c/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:90812a8933df713fdf748b355527e3af257a11e415b613dd794512461eb8a686", size = 3178511 }, - { url = "https://files.pythonhosted.org/packages/ea/09/badfc9293bc3ccba6ede05e5f2b44a760aa47d84da1fc5a326e963e3d4d9/SQLAlchemy-2.0.36-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1bc330d9d29c7f06f003ab10e1eaced295e87940405afe1b110f2eb93a233588", size = 3205147 }, - { url = "https://files.pythonhosted.org/packages/c8/60/70e681de02a13c4b27979b7b78da3058c49bacc9858c89ba672e030f03f2/SQLAlchemy-2.0.36-cp312-cp312-win32.whl", hash = "sha256:79d2e78abc26d871875b419e1fd3c0bca31a1cb0043277d0d850014599626c2e", size = 2062709 }, - { url = "https://files.pythonhosted.org/packages/b7/ed/f6cd9395e41bfe47dd253d74d2dfc3cab34980d4e20c8878cb1117306085/SQLAlchemy-2.0.36-cp312-cp312-win_amd64.whl", hash = "sha256:b544ad1935a8541d177cb402948b94e871067656b3a0b9e91dbec136b06a2ff5", size = 2088433 }, - { url = "https://files.pythonhosted.org/packages/78/5c/236398ae3678b3237726819b484f15f5c038a9549da01703a771f05a00d6/SQLAlchemy-2.0.36-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b5cc79df7f4bc3d11e4b542596c03826063092611e481fcf1c9dfee3c94355ef", size = 2087651 }, - { url = "https://files.pythonhosted.org/packages/a8/14/55c47420c0d23fb67a35af8be4719199b81c59f3084c28d131a7767b0b0b/SQLAlchemy-2.0.36-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3c01117dd36800f2ecaa238c65365b7b16497adc1522bf84906e5710ee9ba0e8", size = 2078132 }, - { url = "https://files.pythonhosted.org/packages/3d/97/1e843b36abff8c4a7aa2e37f9bea364f90d021754c2de94d792c2d91405b/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9bc633f4ee4b4c46e7adcb3a9b5ec083bf1d9a97c1d3854b92749d935de40b9b", size = 3164559 }, - { url = "https://files.pythonhosted.org/packages/7b/c5/07f18a897b997f6d6b234fab2bf31dccf66d5d16a79fe329aefc95cd7461/SQLAlchemy-2.0.36-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e46ed38affdfc95d2c958de328d037d87801cfcbea6d421000859e9789e61c2", size = 3177897 }, - { url = "https://files.pythonhosted.org/packages/b3/cd/e16f3cbefd82b5c40b33732da634ec67a5f33b587744c7ab41699789d492/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b2985c0b06e989c043f1dc09d4fe89e1616aadd35392aea2844f0458a989eacf", size = 3111289 }, - { url = "https://files.pythonhosted.org/packages/15/85/5b8a3b0bc29c9928aa62b5c91fcc8335f57c1de0a6343873b5f372e3672b/SQLAlchemy-2.0.36-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a121d62ebe7d26fec9155f83f8be5189ef1405f5973ea4874a26fab9f1e262c", size = 3139491 }, - { url = "https://files.pythonhosted.org/packages/a1/95/81babb6089938680dfe2cd3f88cd3fd39cccd1543b7cb603b21ad881bff1/SQLAlchemy-2.0.36-cp313-cp313-win32.whl", hash = "sha256:0572f4bd6f94752167adfd7c1bed84f4b240ee6203a95e05d1e208d488d0d436", size = 2060439 }, - { url = "https://files.pythonhosted.org/packages/c1/ce/5f7428df55660d6879d0522adc73a3364970b5ef33ec17fa125c5dbcac1d/SQLAlchemy-2.0.36-cp313-cp313-win_amd64.whl", hash = "sha256:8c78ac40bde930c60e0f78b3cd184c580f89456dd87fc08f9e3ee3ce8765ce88", size = 2084574 }, - { url = "https://files.pythonhosted.org/packages/b8/49/21633706dd6feb14cd3f7935fc00b60870ea057686035e1a99ae6d9d9d53/SQLAlchemy-2.0.36-py3-none-any.whl", hash = "sha256:fddbe92b4760c6f5d48162aef14824add991aeda8ddadb3c31d56eb15ca69f8e", size = 1883787 }, +sdist = { url = "https://files.pythonhosted.org/packages/3b/20/93ea2518df4d7a14ebe9ace9ab8bb92aaf7df0072b9007644de74172b06c/sqlalchemy-2.0.37.tar.gz", hash = "sha256:12b28d99a9c14eaf4055810df1001557176716de0167b91026e648e65229bffb", size = 9626249 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/21/aaf0cd2e7ee56e464af7cba38a54f9c1203570181ec5d847711f33c9f520/SQLAlchemy-2.0.37-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:da36c3b0e891808a7542c5c89f224520b9a16c7f5e4d6a1156955605e54aef0e", size = 2102915 }, + { url = "https://files.pythonhosted.org/packages/fd/01/6615256759515f13bb7d7b49981326f1f4e80ff1bd92dccd53f99dab79ea/SQLAlchemy-2.0.37-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e7402ff96e2b073a98ef6d6142796426d705addd27b9d26c3b32dbaa06d7d069", size = 2094095 }, + { url = "https://files.pythonhosted.org/packages/6a/f2/400252bda1bd67da7a35bb2ab84d10a8ad43975d42f15b207a9efb765446/SQLAlchemy-2.0.37-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e6f5d254a22394847245f411a2956976401e84da4288aa70cbcd5190744062c1", size = 3076482 }, + { url = "https://files.pythonhosted.org/packages/40/c6/e7e8e894c8f065f96ca202cdb00454d60d4962279b3eb5a81b8766dfa836/SQLAlchemy-2.0.37-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41296bbcaa55ef5fdd32389a35c710133b097f7b2609d8218c0eabded43a1d84", size = 3084750 }, + { url = "https://files.pythonhosted.org/packages/d6/ee/1cdab04b7760e48273f2592037df156afae044e2e6589157673bd2a830c0/SQLAlchemy-2.0.37-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bedee60385c1c0411378cbd4dc486362f5ee88deceea50002772912d798bb00f", size = 3040575 }, + { url = "https://files.pythonhosted.org/packages/4d/af/2dd456bfd8d4b9750792ceedd828bddf83860f2420545e5effbaf722dae5/SQLAlchemy-2.0.37-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:6c67415258f9f3c69867ec02fea1bf6508153709ecbd731a982442a590f2b7e4", size = 3066113 }, + { url = "https://files.pythonhosted.org/packages/dd/d7/ad997559574f94d7bd895a8a63996afef518d07e9eaf5a2a9cbbcb877c16/SQLAlchemy-2.0.37-cp310-cp310-win32.whl", hash = "sha256:650dcb70739957a492ad8acff65d099a9586b9b8920e3507ca61ec3ce650bb72", size = 2075239 }, + { url = "https://files.pythonhosted.org/packages/d0/82/141fbed705a21af2d825068831da1d80d720945df60c2b97ddc5133b3714/SQLAlchemy-2.0.37-cp310-cp310-win_amd64.whl", hash = "sha256:93d1543cd8359040c02b6614421c8e10cd7a788c40047dbc507ed46c29ae5636", size = 2099307 }, + { url = "https://files.pythonhosted.org/packages/7c/37/4915290c1849337be6d24012227fb3c30c575151eec2b182ee5f45e96ce7/SQLAlchemy-2.0.37-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:78361be6dc9073ed17ab380985d1e45e48a642313ab68ab6afa2457354ff692c", size = 2104098 }, + { url = "https://files.pythonhosted.org/packages/4c/f5/8cce9196434014a24cc65f6c68faa9a887080932361ee285986c0a35892d/SQLAlchemy-2.0.37-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b661b49d0cb0ab311a189b31e25576b7ac3e20783beb1e1817d72d9d02508bf5", size = 2094492 }, + { url = "https://files.pythonhosted.org/packages/9c/54/2df4b3d0d11b384b6e9a8788d0f1123243f2d2356e2ccf626f93dcc1a09f/SQLAlchemy-2.0.37-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d57bafbab289e147d064ffbd5cca2d7b1394b63417c0636cea1f2e93d16eb9e8", size = 3212789 }, + { url = "https://files.pythonhosted.org/packages/57/4f/e1db9475f940f1c54c365ed02d4f6390f884fc95a6a4022ece7725956664/SQLAlchemy-2.0.37-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa2c0913f02341d25fb858e4fb2031e6b0813494cca1ba07d417674128ce11b", size = 3212784 }, + { url = "https://files.pythonhosted.org/packages/89/57/d93212e827d1f03a6cd4d0ea13775957c2a95161330fa47449b91153bd09/SQLAlchemy-2.0.37-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9df21b8d9e5c136ea6cde1c50d2b1c29a2b5ff2b1d610165c23ff250e0704087", size = 3149616 }, + { url = "https://files.pythonhosted.org/packages/5f/c2/759347419f69cf0bbb76d330fbdbd24cefb15842095fe86bca623759b9e8/SQLAlchemy-2.0.37-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:db18ff6b8c0f1917f8b20f8eca35c28bbccb9f83afa94743e03d40203ed83de9", size = 3169944 }, + { url = "https://files.pythonhosted.org/packages/22/04/a19ecb53aa19bb8cf491ecdb6bf8c1ac74959cd4962e119e91d4e2b8ecaa/SQLAlchemy-2.0.37-cp311-cp311-win32.whl", hash = "sha256:46954173612617a99a64aee103bcd3f078901b9a8dcfc6ae80cbf34ba23df989", size = 2074686 }, + { url = "https://files.pythonhosted.org/packages/7b/9d/6e030cc2c675539dbc5ef73aa97a3cbe09341e27ad38caed2b70c4273aff/SQLAlchemy-2.0.37-cp311-cp311-win_amd64.whl", hash = "sha256:7b7e772dc4bc507fdec4ee20182f15bd60d2a84f1e087a8accf5b5b7a0dcf2ba", size = 2099891 }, + { url = "https://files.pythonhosted.org/packages/86/62/e5de4a5e0c4f5ceffb2b461aaa2378c0ee00642930a8c38e5b80338add0f/SQLAlchemy-2.0.37-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2952748ecd67ed3b56773c185e85fc084f6bdcdec10e5032a7c25a6bc7d682ef", size = 2102692 }, + { url = "https://files.pythonhosted.org/packages/01/44/3b65f4f16abeffd611da0ebab9e3aadfca45d041a78a67835c41c6d28289/SQLAlchemy-2.0.37-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3151822aa1db0eb5afd65ccfafebe0ef5cda3a7701a279c8d0bf17781a793bb4", size = 2093079 }, + { url = "https://files.pythonhosted.org/packages/a4/d8/e3a6622e86e3ae3a41ba470d1bb095c1f2dedf6b71feae0b4b94b5951017/SQLAlchemy-2.0.37-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eaa8039b6d20137a4e02603aba37d12cd2dde7887500b8855356682fc33933f4", size = 3242509 }, + { url = "https://files.pythonhosted.org/packages/3a/ef/5a53a6a60ac5a5d4ed28959317dac1ff72bc16773ccd9b3fe79713fe27f3/SQLAlchemy-2.0.37-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1cdba1f73b64530c47b27118b7053b8447e6d6f3c8104e3ac59f3d40c33aa9fd", size = 3253368 }, + { url = "https://files.pythonhosted.org/packages/67/f2/30f5012379031cd5389eb06455282f926a4f99258e5ee5ccdcea27f30d67/SQLAlchemy-2.0.37-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1b2690456528a87234a75d1a1644cdb330a6926f455403c8e4f6cad6921f9098", size = 3188655 }, + { url = "https://files.pythonhosted.org/packages/fe/df/905499aa051605aeda62c1faf33d941ffb7fda291159ab1c24ef5207a079/SQLAlchemy-2.0.37-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf5ae8a9dcf657fd72144a7fd01f243236ea39e7344e579a121c4205aedf07bb", size = 3215281 }, + { url = "https://files.pythonhosted.org/packages/94/54/f2769e7e356520f75016d82ca43ed85e47ba50e636a34124db4625ae5976/SQLAlchemy-2.0.37-cp312-cp312-win32.whl", hash = "sha256:ea308cec940905ba008291d93619d92edaf83232ec85fbd514dcb329f3192761", size = 2072972 }, + { url = "https://files.pythonhosted.org/packages/c2/7f/241f059e0b7edb85845368f43964d6b0b41733c2f7fffaa993f8e66548a5/SQLAlchemy-2.0.37-cp312-cp312-win_amd64.whl", hash = "sha256:635d8a21577341dfe4f7fa59ec394b346da12420b86624a69e466d446de16aff", size = 2098597 }, + { url = "https://files.pythonhosted.org/packages/45/d1/e63e56ceab148e69f545703a74b90c8c6dc0a04a857e4e63a4c07a23cf91/SQLAlchemy-2.0.37-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8c4096727193762e72ce9437e2a86a110cf081241919ce3fab8e89c02f6b6658", size = 2097968 }, + { url = "https://files.pythonhosted.org/packages/fd/e5/93ce63310347062bd42aaa8b6785615c78539787ef4380252fcf8e2dcee3/SQLAlchemy-2.0.37-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e4fb5ac86d8fe8151966814f6720996430462e633d225497566b3996966b9bdb", size = 2088445 }, + { url = "https://files.pythonhosted.org/packages/1b/8c/d0e0081c09188dd26040fc8a09c7d87f539e1964df1ac60611b98ff2985a/SQLAlchemy-2.0.37-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e56a139bfe136a22c438478a86f8204c1eb5eed36f4e15c4224e4b9db01cb3e4", size = 3174880 }, + { url = "https://files.pythonhosted.org/packages/79/f7/3396038d8d4ea92c72f636a007e2fac71faae0b59b7e21af46b635243d09/SQLAlchemy-2.0.37-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f95fc8e3f34b5f6b3effb49d10ac97c569ec8e32f985612d9b25dd12d0d2e94", size = 3188226 }, + { url = "https://files.pythonhosted.org/packages/ef/33/7a1d85716b29c86a744ed43690e243cb0e9c32e3b68a67a97eaa6b49ef66/SQLAlchemy-2.0.37-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c505edd429abdfe3643fa3b2e83efb3445a34a9dc49d5f692dd087be966020e0", size = 3121425 }, + { url = "https://files.pythonhosted.org/packages/27/11/fa63a77c88eb2f79bb8b438271fbacd66a546a438e4eaba32d62f11298e2/SQLAlchemy-2.0.37-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:12b0f1ec623cccf058cf21cb544f0e74656618165b083d78145cafde156ea7b6", size = 3149589 }, + { url = "https://files.pythonhosted.org/packages/b6/04/fcdd103b6871f2110460b8275d1c4828daa806997b0fa5a01c1cd7fd522d/SQLAlchemy-2.0.37-cp313-cp313-win32.whl", hash = "sha256:293f9ade06b2e68dd03cfb14d49202fac47b7bb94bffcff174568c951fbc7af2", size = 2070746 }, + { url = "https://files.pythonhosted.org/packages/d4/7c/e024719205bdc1465b7b7d3d22ece8e1ad57bc7d76ef6ed78bb5f812634a/SQLAlchemy-2.0.37-cp313-cp313-win_amd64.whl", hash = "sha256:d70f53a0646cc418ca4853da57cf3ddddbccb8c98406791f24426f2dd77fd0e2", size = 2094612 }, + { url = "https://files.pythonhosted.org/packages/3b/36/59cc97c365f2f79ac9f3f51446cae56dfd82c4f2dd98497e6be6de20fb91/SQLAlchemy-2.0.37-py3-none-any.whl", hash = "sha256:a8998bf9f8658bd3839cbc44ddbe982955641863da0c1efe5b00c1ab4f5c16b1", size = 1894113 }, ] [[package]] @@ -1353,27 +1506,27 @@ wheels = [ [[package]] name = "starlette" -version = "0.41.2" +version = "0.41.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/3e/da/1fb4bdb72ae12b834becd7e1e7e47001d32f91ec0ce8d7bc1b618d9f0bd9/starlette-0.41.2.tar.gz", hash = "sha256:9834fd799d1a87fd346deb76158668cfa0b0d56f85caefe8268e2d97c3468b62", size = 2573867 } +sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 } wheels = [ - { url = "https://files.pythonhosted.org/packages/54/43/f185bfd0ca1d213beb4293bed51d92254df23d8ceaf6c0e17146d508a776/starlette-0.41.2-py3-none-any.whl", hash = "sha256:fbc189474b4731cf30fcef52f18a8d070e3f3b46c6a04c97579e85e6ffca942d", size = 73259 }, + { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 }, ] [[package]] name = "storage3" -version = "0.9.0" +version = "0.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", extra = ["http2"] }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/da/e7/8107787c4aa24c435f44f0b0f3332004c82d84c90b6e449d9b3747100687/storage3-0.9.0.tar.gz", hash = "sha256:e16697f60894c94e1d9df0d2e4af783c1b3f7dd08c9013d61978825c624188c4", size = 9031 } +sdist = { url = "https://files.pythonhosted.org/packages/6b/9f/fa5ce927735f04610038de5864fcdb0a4fc8cd74ac1dc2d223ffda4fffd1/storage3-0.11.0.tar.gz", hash = "sha256:243583f2180686c0f0a19e6117d8a9796fd60c0ca72ec567d62b75a5af0d57a1", size = 9706 } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/2f/ee424eaa9939d1a6a3ae727b24da6c80ab4ef913ee1dc8c4392eebc73a3c/storage3-0.9.0-py3-none-any.whl", hash = "sha256:8b2fb91f0c61583a2f4eac74a8bae67e00d41ff38095c8a6cd3f2ce5e0ab76e7", size = 16175 }, + { url = "https://files.pythonhosted.org/packages/57/cc/7f734e0264edd0e5ef78dc49d859b4207c06da895fee62345a7e80ec041a/storage3-0.11.0-py3-none-any.whl", hash = "sha256:de2d8f9c9103ca91a9a9d0d69d80b07a3ab6f647b93e023e6a1a97d3607b9728", size = 17428 }, ] [[package]] @@ -1387,7 +1540,7 @@ wheels = [ [[package]] name = "supabase" -version = "2.10.0" +version = "2.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gotrue" }, @@ -1397,21 +1550,22 @@ dependencies = [ { name = "storage3" }, { name = "supafunc" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/7f/31/656c8c271b7da5104d2fcda0d7c53c95c6ba009f5d708f598784efb1573b/supabase-2.10.0.tar.gz", hash = "sha256:9ac095f8947bf60780e67c0edcbab53e2db3f6f3f022329397b093500bf2607c", size = 13909 } +sdist = { url = "https://files.pythonhosted.org/packages/66/10/36f47454f9d2c2a9be0c2378966bf04a7886ee4e137d3e008b2a9d9407dd/supabase-2.11.0.tar.gz", hash = "sha256:2a906f7909fd9a50f944cd9332ce66c684e2d37c0864284d34c5815e6c63cc01", size = 13924 } wheels = [ - { url = "https://files.pythonhosted.org/packages/10/8d/ec1dd5f1e17dd51e358809adfceafa0a78f32f171d33b9cbe38bb5eac8a3/supabase-2.10.0-py3-none-any.whl", hash = "sha256:183fb23c04528593f8f81c24ceb8178f3a56bff40fec7ed873b6c55ebc2e420a", size = 16626 }, + { url = "https://files.pythonhosted.org/packages/c6/8b/c90649307e9b9f43a271308abbe61b8a90a72c3d24d44154fd150b4c31fc/supabase-2.11.0-py3-none-any.whl", hash = "sha256:67a0da498895f4cd6554935e2854b4c41f87b297b78fb9c9414902a382041406", size = 16629 }, ] [[package]] name = "supafunc" -version = "0.7.0" +version = "0.9.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", extra = ["http2"] }, + { name = "strenum" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f9/f5/50eae5b8428772fee09e737e9ea958e9d76c04814f72b58d181f8477e730/supafunc-0.7.0.tar.gz", hash = "sha256:5b1c415fba1395740b2b4eedd1d786384bd58b98f6333a11ba7889820a48b6a7", size = 4085 } +sdist = { url = "https://files.pythonhosted.org/packages/a6/57/e62930c1cebb4eb6d4b895a79bf4b87271e41317bc533d17861756ba12f5/supafunc-0.9.2.tar.gz", hash = "sha256:f5164114a3e65e7e552539f3f1050aa3d4970885abdd7405555c17fd216e2da1", size = 4691 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c3/26/bc4cd6d19b6290025fe9068df1540a3aab9806daca8b1dd19c0902072a24/supafunc-0.7.0-py3-none-any.whl", hash = "sha256:4160260dc02bdd906be1e2ffd7cb3ae8b74ae437c892bb475352b6a99d9ff8eb", size = 6936 }, + { url = "https://files.pythonhosted.org/packages/9e/8f/fd92ea672ba0f7bdf0d0990788b6ee4f39c6506256f549bad9d1490af7c0/supafunc-0.9.2-py3-none-any.whl", hash = "sha256:be5ee9f53842c4b0ba5f4abfb5bddf9f9e37e69e755ec0526852bb15af9d2ff5", size = 7616 }, ] [[package]] @@ -1434,11 +1588,56 @@ wheels = [ [[package]] name = "tomli" -version = "2.0.2" +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 } +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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { 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 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "typer" +version = "0.15.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/35/b9/de2a5c0144d7d75a57ff355c0c24054f965b2dc3036456ae03a51ea6264b/tomli-2.0.2.tar.gz", hash = "sha256:d46d457a85337051c36524bc5349dd91b1877838e2979ac5ced3e710ed8a60ed", size = 16096 } +dependencies = [ + { name = "click" }, + { name = "rich" }, + { name = "shellingham" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/ce/dca7b219718afd37a0068f4f2530a727c2b74a8b6e8e0c0080a4c0de4fcd/typer-0.15.1.tar.gz", hash = "sha256:a0588c0a7fa68a1978a069818657778f86abe6ff5ea6abf472f940a08bfe4f0a", size = 99789 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cf/db/ce8eda256fa131af12e0a76d481711abe4681b6923c27efb9a255c9e4594/tomli-2.0.2-py3-none-any.whl", hash = "sha256:2ebe24485c53d303f690b0ec092806a085f07af5a5aa1464f3931eec36caaa38", size = 13237 }, + { url = "https://files.pythonhosted.org/packages/d0/cc/0a838ba5ca64dc832aa43f727bd586309846b0ffb2ce52422543e6075e8a/typer-0.15.1-py3-none-any.whl", hash = "sha256:7994fb7b8155b64d3402518560648446072864beefd44aa2dc36972a5972e847", size = 44908 }, ] [[package]] @@ -1452,30 +1651,138 @@ wheels = [ [[package]] name = "uvicorn" -version = "0.32.0" +version = "0.34.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "click" }, { name = "h11" }, { name = "typing-extensions", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/e0/fc/1d785078eefd6945f3e5bab5c076e4230698046231eb0f3747bc5c8fa992/uvicorn-0.32.0.tar.gz", hash = "sha256:f78b36b143c16f54ccdb8190d0a26b5f1901fe5a3c777e1ab29f26391af8551e", size = 77564 } +sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, +] + +[package.optional-dependencies] +standard = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "httptools" }, + { name = "python-dotenv" }, + { name = "pyyaml" }, + { name = "uvloop", marker = "platform_python_implementation != 'PyPy' and sys_platform != 'cygwin' and sys_platform != 'win32'" }, + { name = "watchfiles" }, + { name = "websockets" }, +] + +[[package]] +name = "uvloop" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/c0/854216d09d33c543f12a44b393c402e89a920b1a0a7dc634c42de91b9cf6/uvloop-0.21.0.tar.gz", hash = "sha256:3bf12b0fda68447806a7ad847bfa591613177275d35b6724b1ee573faa3704e3", size = 2492741 } wheels = [ - { url = "https://files.pythonhosted.org/packages/eb/14/78bd0e95dd2444b6caacbca2b730671d4295ccb628ef58b81bee903629df/uvicorn-0.32.0-py3-none-any.whl", hash = "sha256:60b8f3a5ac027dcd31448f411ced12b5ef452c646f76f02f8cc3f25d8d26fd82", size = 63723 }, + { url = "https://files.pythonhosted.org/packages/3d/76/44a55515e8c9505aa1420aebacf4dd82552e5e15691654894e90d0bd051a/uvloop-0.21.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec7e6b09a6fdded42403182ab6b832b71f4edaf7f37a9a0e371a01db5f0cb45f", size = 1442019 }, + { url = "https://files.pythonhosted.org/packages/35/5a/62d5800358a78cc25c8a6c72ef8b10851bdb8cca22e14d9c74167b7f86da/uvloop-0.21.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:196274f2adb9689a289ad7d65700d37df0c0930fd8e4e743fa4834e850d7719d", size = 801898 }, + { url = "https://files.pythonhosted.org/packages/f3/96/63695e0ebd7da6c741ccd4489b5947394435e198a1382349c17b1146bb97/uvloop-0.21.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f38b2e090258d051d68a5b14d1da7203a3c3677321cf32a95a6f4db4dd8b6f26", size = 3827735 }, + { url = "https://files.pythonhosted.org/packages/61/e0/f0f8ec84979068ffae132c58c79af1de9cceeb664076beea86d941af1a30/uvloop-0.21.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87c43e0f13022b998eb9b973b5e97200c8b90823454d4bc06ab33829e09fb9bb", size = 3825126 }, + { url = "https://files.pythonhosted.org/packages/bf/fe/5e94a977d058a54a19df95f12f7161ab6e323ad49f4dabc28822eb2df7ea/uvloop-0.21.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:10d66943def5fcb6e7b37310eb6b5639fd2ccbc38df1177262b0640c3ca68c1f", size = 3705789 }, + { url = "https://files.pythonhosted.org/packages/26/dd/c7179618e46092a77e036650c1f056041a028a35c4d76945089fcfc38af8/uvloop-0.21.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:67dd654b8ca23aed0a8e99010b4c34aca62f4b7fce88f39d452ed7622c94845c", size = 3800523 }, + { url = "https://files.pythonhosted.org/packages/57/a7/4cf0334105c1160dd6819f3297f8700fda7fc30ab4f61fbf3e725acbc7cc/uvloop-0.21.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c0f3fa6200b3108919f8bdabb9a7f87f20e7097ea3c543754cabc7d717d95cf8", size = 1447410 }, + { url = "https://files.pythonhosted.org/packages/8c/7c/1517b0bbc2dbe784b563d6ab54f2ef88c890fdad77232c98ed490aa07132/uvloop-0.21.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0878c2640cf341b269b7e128b1a5fed890adc4455513ca710d77d5e93aa6d6a0", size = 805476 }, + { url = "https://files.pythonhosted.org/packages/ee/ea/0bfae1aceb82a503f358d8d2fa126ca9dbdb2ba9c7866974faec1cb5875c/uvloop-0.21.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b9fb766bb57b7388745d8bcc53a359b116b8a04c83a2288069809d2b3466c37e", size = 3960855 }, + { url = "https://files.pythonhosted.org/packages/8a/ca/0864176a649838b838f36d44bf31c451597ab363b60dc9e09c9630619d41/uvloop-0.21.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a375441696e2eda1c43c44ccb66e04d61ceeffcd76e4929e527b7fa401b90fb", size = 3973185 }, + { url = "https://files.pythonhosted.org/packages/30/bf/08ad29979a936d63787ba47a540de2132169f140d54aa25bc8c3df3e67f4/uvloop-0.21.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:baa0e6291d91649c6ba4ed4b2f982f9fa165b5bbd50a9e203c416a2797bab3c6", size = 3820256 }, + { url = "https://files.pythonhosted.org/packages/da/e2/5cf6ef37e3daf2f06e651aae5ea108ad30df3cb269102678b61ebf1fdf42/uvloop-0.21.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4509360fcc4c3bd2c70d87573ad472de40c13387f5fda8cb58350a1d7475e58d", size = 3937323 }, + { url = "https://files.pythonhosted.org/packages/8c/4c/03f93178830dc7ce8b4cdee1d36770d2f5ebb6f3d37d354e061eefc73545/uvloop-0.21.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:359ec2c888397b9e592a889c4d72ba3d6befba8b2bb01743f72fffbde663b59c", size = 1471284 }, + { url = "https://files.pythonhosted.org/packages/43/3e/92c03f4d05e50f09251bd8b2b2b584a2a7f8fe600008bcc4523337abe676/uvloop-0.21.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f7089d2dc73179ce5ac255bdf37c236a9f914b264825fdaacaded6990a7fb4c2", size = 821349 }, + { url = "https://files.pythonhosted.org/packages/a6/ef/a02ec5da49909dbbfb1fd205a9a1ac4e88ea92dcae885e7c961847cd51e2/uvloop-0.21.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baa4dcdbd9ae0a372f2167a207cd98c9f9a1ea1188a8a526431eef2f8116cc8d", size = 4580089 }, + { url = "https://files.pythonhosted.org/packages/06/a7/b4e6a19925c900be9f98bec0a75e6e8f79bb53bdeb891916609ab3958967/uvloop-0.21.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:86975dca1c773a2c9864f4c52c5a55631038e387b47eaf56210f873887b6c8dc", size = 4693770 }, + { url = "https://files.pythonhosted.org/packages/ce/0c/f07435a18a4b94ce6bd0677d8319cd3de61f3a9eeb1e5f8ab4e8b5edfcb3/uvloop-0.21.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:461d9ae6660fbbafedd07559c6a2e57cd553b34b0065b6550685f6653a98c1cb", size = 4451321 }, + { url = "https://files.pythonhosted.org/packages/8f/eb/f7032be105877bcf924709c97b1bf3b90255b4ec251f9340cef912559f28/uvloop-0.21.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:183aef7c8730e54c9a3ee3227464daed66e37ba13040bb3f350bc2ddc040f22f", size = 4659022 }, + { url = "https://files.pythonhosted.org/packages/3f/8d/2cbef610ca21539f0f36e2b34da49302029e7c9f09acef0b1c3b5839412b/uvloop-0.21.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:bfd55dfcc2a512316e65f16e503e9e450cab148ef11df4e4e679b5e8253a5281", size = 1468123 }, + { url = "https://files.pythonhosted.org/packages/93/0d/b0038d5a469f94ed8f2b2fce2434a18396d8fbfb5da85a0a9781ebbdec14/uvloop-0.21.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:787ae31ad8a2856fc4e7c095341cccc7209bd657d0e71ad0dc2ea83c4a6fa8af", size = 819325 }, + { url = "https://files.pythonhosted.org/packages/50/94/0a687f39e78c4c1e02e3272c6b2ccdb4e0085fda3b8352fecd0410ccf915/uvloop-0.21.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ee4d4ef48036ff6e5cfffb09dd192c7a5027153948d85b8da7ff705065bacc6", size = 4582806 }, + { url = "https://files.pythonhosted.org/packages/d2/19/f5b78616566ea68edd42aacaf645adbf71fbd83fc52281fba555dc27e3f1/uvloop-0.21.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3df876acd7ec037a3d005b3ab85a7e4110422e4d9c1571d4fc89b0fc41b6816", size = 4701068 }, + { url = "https://files.pythonhosted.org/packages/47/57/66f061ee118f413cd22a656de622925097170b9380b30091b78ea0c6ea75/uvloop-0.21.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd53ecc9a0f3d87ab847503c2e1552b690362e005ab54e8a48ba97da3924c0dc", size = 4454428 }, + { url = "https://files.pythonhosted.org/packages/63/9a/0962b05b308494e3202d3f794a6e85abe471fe3cafdbcf95c2e8c713aabd/uvloop-0.21.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a5c39f217ab3c663dc699c04cbd50c13813e31d917642d459fdcec07555cc553", size = 4660018 }, ] [[package]] name = "virtualenv" -version = "20.27.1" +version = "20.29.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "distlib" }, { name = "filelock" }, { name = "platformdirs" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8c/b3/7b6a79c5c8cf6d90ea681310e169cf2db2884f4d583d16c6e1d5a75a4e04/virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba", size = 6491145 } +sdist = { url = "https://files.pythonhosted.org/packages/a7/ca/f23dcb02e161a9bba141b1c08aa50e8da6ea25e6d780528f1d385a3efe25/virtualenv-20.29.1.tar.gz", hash = "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35", size = 7658028 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ae/92/78324ff89391e00c8f4cf6b8526c41c6ef36b4ea2d2c132250b1a6fc2b8d/virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4", size = 3117838 }, + { url = "https://files.pythonhosted.org/packages/89/9b/599bcfc7064fbe5740919e78c5df18e5dceb0887e676256a1061bb5ae232/virtualenv-20.29.1-py3-none-any.whl", hash = "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779", size = 4282379 }, +] + +[[package]] +name = "watchfiles" +version = "1.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/26/c705fc77d0a9ecdb9b66f1e2976d95b81df3cae518967431e7dbf9b5e219/watchfiles-1.0.4.tar.gz", hash = "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205", size = 94625 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/14/02/22fcaed0396730b0d362bc8d1ffb3be2658fd473eecbb2ba84243e157f11/watchfiles-1.0.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:ba5bb3073d9db37c64520681dd2650f8bd40902d991e7b4cfaeece3e32561d08", size = 395212 }, + { url = "https://files.pythonhosted.org/packages/e9/3d/ec5a2369a46edf3ebe092c39d9ae48e8cb6dacbde51c4b4f98936c524269/watchfiles-1.0.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9f25d0ba0fe2b6d2c921cf587b2bf4c451860086534f40c384329fb96e2044d1", size = 384815 }, + { url = "https://files.pythonhosted.org/packages/df/b4/898991cececbe171e67142c31905510203649569d9817848f47c4177ee42/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47eb32ef8c729dbc4f4273baece89398a4d4b5d21a1493efea77a17059f4df8a", size = 450680 }, + { url = "https://files.pythonhosted.org/packages/58/f7/d4aa3000e812cfb5e5c2c6c0a3ec9d0a46a42489a8727edd160631c4e210/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:076f293100db3b0b634514aa0d294b941daa85fc777f9c698adb1009e5aca0b1", size = 455923 }, + { url = "https://files.pythonhosted.org/packages/dd/95/7e2e4c6aba1b02fb5c76d2f6a450b85215921ec5f8f7ad5efd075369563f/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1eacd91daeb5158c598fe22d7ce66d60878b6294a86477a4715154990394c9b3", size = 482339 }, + { url = "https://files.pythonhosted.org/packages/bb/67/4265b0fabcc2ef2c9e3e8802ba7908cf718a357ebfb49c72e53787156a48/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:13c2ce7b72026cfbca120d652f02c7750f33b4c9395d79c9790b27f014c8a5a2", size = 519908 }, + { url = "https://files.pythonhosted.org/packages/0d/96/b57802d5f8164bdf070befb4fd3dec4edba5a364ec0670965a97eb8098ce/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:90192cdc15ab7254caa7765a98132a5a41471cf739513cc9bcf7d2ffcc0ec7b2", size = 501410 }, + { url = "https://files.pythonhosted.org/packages/8b/18/6db0de4e8911ba14e31853201b40c0fa9fea5ecf3feb86b0ad58f006dfc3/watchfiles-1.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:278aaa395f405972e9f523bd786ed59dfb61e4b827856be46a42130605fd0899", size = 452876 }, + { url = "https://files.pythonhosted.org/packages/df/df/092a961815edf723a38ba2638c49491365943919c3526cc9cf82c42786a6/watchfiles-1.0.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a462490e75e466edbb9fc4cd679b62187153b3ba804868452ef0577ec958f5ff", size = 615353 }, + { url = "https://files.pythonhosted.org/packages/f3/cf/b85fe645de4ff82f3f436c5e9032379fce37c303f6396a18f9726cc34519/watchfiles-1.0.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8d0d0630930f5cd5af929040e0778cf676a46775753e442a3f60511f2409f48f", size = 613187 }, + { url = "https://files.pythonhosted.org/packages/f6/d4/a9fea27aef4dd69689bc3556718c1157a7accb72aa035ece87c1fa8483b5/watchfiles-1.0.4-cp310-cp310-win32.whl", hash = "sha256:cc27a65069bcabac4552f34fd2dce923ce3fcde0721a16e4fb1b466d63ec831f", size = 270799 }, + { url = "https://files.pythonhosted.org/packages/df/02/dbe9d4439f15dd4ad0720b6e039bde9d66d1f830331f34c18eb70fa6608e/watchfiles-1.0.4-cp310-cp310-win_amd64.whl", hash = "sha256:8b1f135238e75d075359cf506b27bf3f4ca12029c47d3e769d8593a2024ce161", size = 284145 }, + { url = "https://files.pythonhosted.org/packages/0f/bb/8461adc4b1fed009546fb797fc0d5698dcfe5e289cb37e1b8f16a93cdc30/watchfiles-1.0.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:2a9f93f8439639dc244c4d2902abe35b0279102bca7bbcf119af964f51d53c19", size = 394869 }, + { url = "https://files.pythonhosted.org/packages/55/88/9ebf36b3547176d1709c320de78c1fa3263a46be31b5b1267571d9102686/watchfiles-1.0.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9eea33ad8c418847dd296e61eb683cae1c63329b6d854aefcd412e12d94ee235", size = 384905 }, + { url = "https://files.pythonhosted.org/packages/03/8a/04335ce23ef78d8c69f0913e8b20cf7d9233e3986543aeef95ef2d6e43d2/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31f1a379c9dcbb3f09cf6be1b7e83b67c0e9faabed0471556d9438a4a4e14202", size = 449944 }, + { url = "https://files.pythonhosted.org/packages/17/4e/c8d5dcd14fe637f4633616dabea8a4af0a10142dccf3b43e0f081ba81ab4/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab594e75644421ae0a2484554832ca5895f8cab5ab62de30a1a57db460ce06c6", size = 456020 }, + { url = "https://files.pythonhosted.org/packages/5e/74/3e91e09e1861dd7fbb1190ce7bd786700dc0fbc2ccd33bb9fff5de039229/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fc2eb5d14a8e0d5df7b36288979176fbb39672d45184fc4b1c004d7c3ce29317", size = 482983 }, + { url = "https://files.pythonhosted.org/packages/a1/3d/e64de2d1ce4eb6a574fd78ce3a28c279da263be9ef3cfcab6f708df192f2/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f68d8e9d5a321163ddacebe97091000955a1b74cd43724e346056030b0bacee", size = 520320 }, + { url = "https://files.pythonhosted.org/packages/2c/bd/52235f7063b57240c66a991696ed27e2a18bd6fcec8a1ea5a040b70d0611/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9ce064e81fe79faa925ff03b9f4c1a98b0bbb4a1b8c1b015afa93030cb21a49", size = 500988 }, + { url = "https://files.pythonhosted.org/packages/3a/b0/ff04194141a5fe650c150400dd9e42667916bc0f52426e2e174d779b8a74/watchfiles-1.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b77d5622ac5cc91d21ae9c2b284b5d5c51085a0bdb7b518dba263d0af006132c", size = 452573 }, + { url = "https://files.pythonhosted.org/packages/3d/9d/966164332c5a178444ae6d165082d4f351bd56afd9c3ec828eecbf190e6a/watchfiles-1.0.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1941b4e39de9b38b868a69b911df5e89dc43767feeda667b40ae032522b9b5f1", size = 615114 }, + { url = "https://files.pythonhosted.org/packages/94/df/f569ae4c1877f96ad4086c153a8eee5a19a3b519487bf5c9454a3438c341/watchfiles-1.0.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4f8c4998506241dedf59613082d1c18b836e26ef2a4caecad0ec41e2a15e4226", size = 613076 }, + { url = "https://files.pythonhosted.org/packages/15/ae/8ce5f29e65d5fa5790e3c80c289819c55e12be2e1b9f5b6a0e55e169b97d/watchfiles-1.0.4-cp311-cp311-win32.whl", hash = "sha256:4ebbeca9360c830766b9f0df3640b791be569d988f4be6c06d6fae41f187f105", size = 271013 }, + { url = "https://files.pythonhosted.org/packages/a4/c6/79dc4a7c598a978e5fafa135090aaf7bbb03b8dec7bada437dfbe578e7ed/watchfiles-1.0.4-cp311-cp311-win_amd64.whl", hash = "sha256:05d341c71f3d7098920f8551d4df47f7b57ac5b8dad56558064c3431bdfc0b74", size = 284229 }, + { url = "https://files.pythonhosted.org/packages/37/3d/928633723211753f3500bfb138434f080363b87a1b08ca188b1ce54d1e05/watchfiles-1.0.4-cp311-cp311-win_arm64.whl", hash = "sha256:32b026a6ab64245b584acf4931fe21842374da82372d5c039cba6bf99ef722f3", size = 276824 }, + { url = "https://files.pythonhosted.org/packages/5b/1a/8f4d9a1461709756ace48c98f07772bc6d4519b1e48b5fa24a4061216256/watchfiles-1.0.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2", size = 391345 }, + { url = "https://files.pythonhosted.org/packages/bc/d2/6750b7b3527b1cdaa33731438432e7238a6c6c40a9924049e4cebfa40805/watchfiles-1.0.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9", size = 381515 }, + { url = "https://files.pythonhosted.org/packages/4e/17/80500e42363deef1e4b4818729ed939aaddc56f82f4e72b2508729dd3c6b/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712", size = 449767 }, + { url = "https://files.pythonhosted.org/packages/10/37/1427fa4cfa09adbe04b1e97bced19a29a3462cc64c78630787b613a23f18/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12", size = 455677 }, + { url = "https://files.pythonhosted.org/packages/c5/7a/39e9397f3a19cb549a7d380412fd9e507d4854eddc0700bfad10ef6d4dba/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844", size = 482219 }, + { url = "https://files.pythonhosted.org/packages/45/2d/7113931a77e2ea4436cad0c1690c09a40a7f31d366f79c6f0a5bc7a4f6d5/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733", size = 518830 }, + { url = "https://files.pythonhosted.org/packages/f9/1b/50733b1980fa81ef3c70388a546481ae5fa4c2080040100cd7bf3bf7b321/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af", size = 497997 }, + { url = "https://files.pythonhosted.org/packages/2b/b4/9396cc61b948ef18943e7c85ecfa64cf940c88977d882da57147f62b34b1/watchfiles-1.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a", size = 452249 }, + { url = "https://files.pythonhosted.org/packages/fb/69/0c65a5a29e057ad0dc691c2fa6c23b2983c7dabaa190ba553b29ac84c3cc/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff", size = 614412 }, + { url = "https://files.pythonhosted.org/packages/7f/b9/319fcba6eba5fad34327d7ce16a6b163b39741016b1996f4a3c96b8dd0e1/watchfiles-1.0.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e", size = 611982 }, + { url = "https://files.pythonhosted.org/packages/f1/47/143c92418e30cb9348a4387bfa149c8e0e404a7c5b0585d46d2f7031b4b9/watchfiles-1.0.4-cp312-cp312-win32.whl", hash = "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94", size = 271822 }, + { url = "https://files.pythonhosted.org/packages/ea/94/b0165481bff99a64b29e46e07ac2e0df9f7a957ef13bec4ceab8515f44e3/watchfiles-1.0.4-cp312-cp312-win_amd64.whl", hash = "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c", size = 285441 }, + { url = "https://files.pythonhosted.org/packages/11/de/09fe56317d582742d7ca8c2ca7b52a85927ebb50678d9b0fa8194658f536/watchfiles-1.0.4-cp312-cp312-win_arm64.whl", hash = "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90", size = 277141 }, + { url = "https://files.pythonhosted.org/packages/08/98/f03efabec64b5b1fa58c0daab25c68ef815b0f320e54adcacd0d6847c339/watchfiles-1.0.4-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9", size = 390954 }, + { url = "https://files.pythonhosted.org/packages/16/09/4dd49ba0a32a45813debe5fb3897955541351ee8142f586303b271a02b40/watchfiles-1.0.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60", size = 381133 }, + { url = "https://files.pythonhosted.org/packages/76/59/5aa6fc93553cd8d8ee75c6247763d77c02631aed21551a97d94998bf1dae/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407", size = 449516 }, + { url = "https://files.pythonhosted.org/packages/4c/aa/df4b6fe14b6317290b91335b23c96b488d365d65549587434817e06895ea/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d", size = 454820 }, + { url = "https://files.pythonhosted.org/packages/5e/71/185f8672f1094ce48af33252c73e39b48be93b761273872d9312087245f6/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d", size = 481550 }, + { url = "https://files.pythonhosted.org/packages/85/d7/50ebba2c426ef1a5cb17f02158222911a2e005d401caf5d911bfca58f4c4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b", size = 518647 }, + { url = "https://files.pythonhosted.org/packages/f0/7a/4c009342e393c545d68987e8010b937f72f47937731225b2b29b7231428f/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590", size = 497547 }, + { url = "https://files.pythonhosted.org/packages/0f/7c/1cf50b35412d5c72d63b2bf9a4fffee2e1549a245924960dd087eb6a6de4/watchfiles-1.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902", size = 452179 }, + { url = "https://files.pythonhosted.org/packages/d6/a9/3db1410e1c1413735a9a472380e4f431ad9a9e81711cda2aaf02b7f62693/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1", size = 614125 }, + { url = "https://files.pythonhosted.org/packages/f2/e1/0025d365cf6248c4d1ee4c3d2e3d373bdd3f6aff78ba4298f97b4fad2740/watchfiles-1.0.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303", size = 611911 }, + { url = "https://files.pythonhosted.org/packages/55/55/035838277d8c98fc8c917ac9beeb0cd6c59d675dc2421df5f9fcf44a0070/watchfiles-1.0.4-cp313-cp313-win32.whl", hash = "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80", size = 271152 }, + { url = "https://files.pythonhosted.org/packages/f0/e5/96b8e55271685ddbadc50ce8bc53aa2dff278fb7ac4c2e473df890def2dc/watchfiles-1.0.4-cp313-cp313-win_amd64.whl", hash = "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc", size = 285216 }, + { url = "https://files.pythonhosted.org/packages/6f/06/175d5ac6b838fb319008c0cd981d7bf289317c510154d411d3584ca2b67b/watchfiles-1.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cdcc92daeae268de1acf5b7befcd6cfffd9a047098199056c72e4623f531de18", size = 396269 }, + { url = "https://files.pythonhosted.org/packages/86/ee/5db93b0b57dc0587abdbac4149296ee73275f615d790a82cb5598af0557f/watchfiles-1.0.4-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d8d3d9203705b5797f0af7e7e5baa17c8588030aaadb7f6a86107b7247303817", size = 386010 }, + { url = "https://files.pythonhosted.org/packages/75/61/fe0dc5fedf152bfc085a53711f740701f6bdb8ab6b5c950402b681d4858b/watchfiles-1.0.4-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bdef5a1be32d0b07dcea3318a0be95d42c98ece24177820226b56276e06b63b0", size = 450913 }, + { url = "https://files.pythonhosted.org/packages/9f/dd/3c7731af3baf1a9957afc643d176f94480921a690ec3237c9f9d11301c08/watchfiles-1.0.4-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:342622287b5604ddf0ed2d085f3a589099c9ae8b7331df3ae9845571586c4f3d", size = 453474 }, ] [[package]] @@ -1539,78 +1846,78 @@ wheels = [ [[package]] name = "yarl" -version = "1.17.1" +version = "1.18.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "multidict" }, { name = "propcache" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/54/9c/9c0a9bfa683fc1be7fdcd9687635151544d992cccd48892dc5e0a5885a29/yarl-1.17.1.tar.gz", hash = "sha256:067a63fcfda82da6b198fa73079b1ca40b7c9b7994995b6ee38acda728b64d47", size = 178163 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/97/63/0e1e3626a323f366a8ff8eeb4d2835d403cb505393c2fce00c68c2be9d1a/yarl-1.17.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b1794853124e2f663f0ea54efb0340b457f08d40a1cef78edfa086576179c91", size = 140627 }, - { url = "https://files.pythonhosted.org/packages/ff/ef/80c92e43f5ca5dfe964f42080252b669097fdd37d40e8c174e5a10d67d2c/yarl-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:fbea1751729afe607d84acfd01efd95e3b31db148a181a441984ce9b3d3469da", size = 93563 }, - { url = "https://files.pythonhosted.org/packages/05/43/add866f8c7e99af126a3ff4a673165537617995a5ae90e86cb95f9a1d4ad/yarl-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ee427208c675f1b6e344a1f89376a9613fc30b52646a04ac0c1f6587c7e46ec", size = 91400 }, - { url = "https://files.pythonhosted.org/packages/b9/44/464aba5761fb7ab448d8854520d98355217481746d2421231b8d07d2de8c/yarl-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b74ff4767d3ef47ffe0cd1d89379dc4d828d4873e5528976ced3b44fe5b0a21", size = 313746 }, - { url = "https://files.pythonhosted.org/packages/c1/0f/3a08d81f1e4ff88b07d62f3bb271603c0e2d063cea12239e500defa800d3/yarl-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:62a91aefff3d11bf60e5956d340eb507a983a7ec802b19072bb989ce120cd948", size = 329234 }, - { url = "https://files.pythonhosted.org/packages/7d/0f/98f29b8637cf13d7589bb7a1fdc4357bcfc0cfc3f20bc65a6970b71a22ec/yarl-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:846dd2e1243407133d3195d2d7e4ceefcaa5f5bf7278f0a9bda00967e6326b04", size = 325776 }, - { url = "https://files.pythonhosted.org/packages/3c/8c/f383fc542a3d2a1837fb0543ce698653f1760cc18954c29e6d6d49713376/yarl-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3e844be8d536afa129366d9af76ed7cb8dfefec99f5f1c9e4f8ae542279a6dc3", size = 318659 }, - { url = "https://files.pythonhosted.org/packages/2b/35/742b4a03ca90e116f70a44b24a36d2138f1b1d776a532ddfece4d60cd93d/yarl-1.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cc7c92c1baa629cb03ecb0c3d12564f172218fb1739f54bf5f3881844daadc6d", size = 310172 }, - { url = "https://files.pythonhosted.org/packages/9b/fc/f1aba4194861f44673d9b432310cbee2e7c3ffa8ff9bdf165c7eaa9c6e38/yarl-1.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:ae3476e934b9d714aa8000d2e4c01eb2590eee10b9d8cd03e7983ad65dfbfcba", size = 318283 }, - { url = "https://files.pythonhosted.org/packages/27/0f/2b20100839064d1c75fb85fa6b5cbd68249d96a4b06a5cf25f9eaaf9b32a/yarl-1.17.1-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c7e177c619342e407415d4f35dec63d2d134d951e24b5166afcdfd1362828e17", size = 317599 }, - { url = "https://files.pythonhosted.org/packages/7b/da/3f2d6643d8cf3003c72587f28a9d9c76829a5b45186cae8f978bac113fc5/yarl-1.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:64cc6e97f14cf8a275d79c5002281f3040c12e2e4220623b5759ea7f9868d6a5", size = 323398 }, - { url = "https://files.pythonhosted.org/packages/9e/f8/881c97cc35603ec63b48875d47e36e1b984648826b36ce7affac16e08261/yarl-1.17.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:84c063af19ef5130084db70ada40ce63a84f6c1ef4d3dbc34e5e8c4febb20822", size = 337601 }, - { url = "https://files.pythonhosted.org/packages/81/da/049b354e00b33019c32126f2a40ecbcc320859f619c4304c556cf23a5dc3/yarl-1.17.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:482c122b72e3c5ec98f11457aeb436ae4aecca75de19b3d1de7cf88bc40db82f", size = 338975 }, - { url = "https://files.pythonhosted.org/packages/26/64/e36e808b249d64cfc33caca7e9ef2d7e636e4f9e8529e4fe5ed4813ac5b0/yarl-1.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:380e6c38ef692b8fd5a0f6d1fa8774d81ebc08cfbd624b1bca62a4d4af2f9931", size = 331078 }, - { url = "https://files.pythonhosted.org/packages/82/cb/6fe205b528cc889f8e13d6d180adbc8721a21a6aac67fc3158294575add3/yarl-1.17.1-cp310-cp310-win32.whl", hash = "sha256:16bca6678a83657dd48df84b51bd56a6c6bd401853aef6d09dc2506a78484c7b", size = 83573 }, - { url = "https://files.pythonhosted.org/packages/55/96/4dcb7110ae4cd53768254fb50ace7bca00e110459e6eff1d16983c513219/yarl-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:561c87fea99545ef7d692403c110b2f99dced6dff93056d6e04384ad3bc46243", size = 89761 }, - { url = "https://files.pythonhosted.org/packages/ec/0f/ce6a2c8aab9946446fb27f1e28f0fd89ce84ae913ab18a92d18078a1c7ed/yarl-1.17.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cbad927ea8ed814622305d842c93412cb47bd39a496ed0f96bfd42b922b4a217", size = 140727 }, - { url = "https://files.pythonhosted.org/packages/9d/df/204f7a502bdc3973cd9fc29e7dfad18ae48b3acafdaaf1ae07c0f41025aa/yarl-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fca4b4307ebe9c3ec77a084da3a9d1999d164693d16492ca2b64594340999988", size = 93560 }, - { url = "https://files.pythonhosted.org/packages/a2/e1/f4d522ae0560c91a4ea31113a50f00f85083be885e1092fc6e74eb43cb1d/yarl-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ff5c6771c7e3511a06555afa317879b7db8d640137ba55d6ab0d0c50425cab75", size = 91497 }, - { url = "https://files.pythonhosted.org/packages/f1/82/783d97bf4a226f1a2e59b1966f2752244c2bf4dc89bc36f61d597b8e34e5/yarl-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b29beab10211a746f9846baa39275e80034e065460d99eb51e45c9a9495bcca", size = 339446 }, - { url = "https://files.pythonhosted.org/packages/e5/ff/615600647048d81289c80907165de713fbc566d1e024789863a2f6563ba3/yarl-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a52a1ffdd824fb1835272e125385c32fd8b17fbdefeedcb4d543cc23b332d74", size = 354616 }, - { url = "https://files.pythonhosted.org/packages/a5/04/bfb7adb452bd19dfe0c35354ffce8ebc3086e028e5f8270e409d17da5466/yarl-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:58c8e9620eb82a189c6c40cb6b59b4e35b2ee68b1f2afa6597732a2b467d7e8f", size = 351801 }, - { url = "https://files.pythonhosted.org/packages/10/e0/efe21edacdc4a638ce911f8cabf1c77cac3f60e9819ba7d891b9ceb6e1d4/yarl-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d216e5d9b8749563c7f2c6f7a0831057ec844c68b4c11cb10fc62d4fd373c26d", size = 343381 }, - { url = "https://files.pythonhosted.org/packages/63/f9/7bc7e69857d6fc3920ecd173592f921d5701f4a0dd3f2ae293b386cfa3bf/yarl-1.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:881764d610e3269964fc4bb3c19bb6fce55422828e152b885609ec176b41cf11", size = 337093 }, - { url = "https://files.pythonhosted.org/packages/93/52/99da61947466275ff17d7bc04b0ac31dfb7ec699bd8d8985dffc34c3a913/yarl-1.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8c79e9d7e3d8a32d4824250a9c6401194fb4c2ad9a0cec8f6a96e09a582c2cc0", size = 346619 }, - { url = "https://files.pythonhosted.org/packages/91/8a/8aaad86a35a16e485ba0e5de0d2ae55bf8dd0c9f1cccac12be4c91366b1d/yarl-1.17.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:299f11b44d8d3a588234adbe01112126010bd96d9139c3ba7b3badd9829261c3", size = 344347 }, - { url = "https://files.pythonhosted.org/packages/af/b6/97f29f626b4a1768ffc4b9b489533612cfcb8905c90f745aade7b2eaf75e/yarl-1.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cc7d768260f4ba4ea01741c1b5fe3d3a6c70eb91c87f4c8761bbcce5181beafe", size = 350316 }, - { url = "https://files.pythonhosted.org/packages/d7/98/8e0e8b812479569bdc34d66dd3e2471176ca33be4ff5c272a01333c4b269/yarl-1.17.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:de599af166970d6a61accde358ec9ded821234cbbc8c6413acfec06056b8e860", size = 361336 }, - { url = "https://files.pythonhosted.org/packages/9e/d3/d1507efa0a85c25285f8eb51df9afa1ba1b6e446dda781d074d775b6a9af/yarl-1.17.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:2b24ec55fad43e476905eceaf14f41f6478780b870eda5d08b4d6de9a60b65b4", size = 365350 }, - { url = "https://files.pythonhosted.org/packages/22/ba/ee7f1830449c96bae6f33210b7d89e8aaf3079fbdaf78ac398e50a9da404/yarl-1.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9fb815155aac6bfa8d86184079652c9715c812d506b22cfa369196ef4e99d1b4", size = 357689 }, - { url = "https://files.pythonhosted.org/packages/a0/85/321c563dc5afe1661108831b965c512d185c61785400f5606006507d2e18/yarl-1.17.1-cp311-cp311-win32.whl", hash = "sha256:7615058aabad54416ddac99ade09a5510cf77039a3b903e94e8922f25ed203d7", size = 83635 }, - { url = "https://files.pythonhosted.org/packages/bc/da/543a32c00860588ff1235315b68f858cea30769099c32cd22b7bb266411b/yarl-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:14bc88baa44e1f84164a392827b5defb4fa8e56b93fecac3d15315e7c8e5d8b3", size = 90218 }, - { url = "https://files.pythonhosted.org/packages/5d/af/e25615c7920396219b943b9ff8b34636ae3e1ad30777649371317d7f05f8/yarl-1.17.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:327828786da2006085a4d1feb2594de6f6d26f8af48b81eb1ae950c788d97f61", size = 141839 }, - { url = "https://files.pythonhosted.org/packages/83/5e/363d9de3495c7c66592523f05d21576a811015579e0c87dd38c7b5788afd/yarl-1.17.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cc353841428d56b683a123a813e6a686e07026d6b1c5757970a877195f880c2d", size = 94125 }, - { url = "https://files.pythonhosted.org/packages/e3/a2/b65447626227ebe36f18f63ac551790068bf42c69bb22dfa3ae986170728/yarl-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c73df5b6e8fabe2ddb74876fb82d9dd44cbace0ca12e8861ce9155ad3c886139", size = 92048 }, - { url = "https://files.pythonhosted.org/packages/a1/f5/2ef86458446f85cde10582054fd5113495ef8ce8477da35aaaf26d2970ef/yarl-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bdff5e0995522706c53078f531fb586f56de9c4c81c243865dd5c66c132c3b5", size = 331472 }, - { url = "https://files.pythonhosted.org/packages/f3/6b/1ba79758ba352cdf2ad4c20cab1b982dd369aa595bb0d7601fc89bf82bee/yarl-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:06157fb3c58f2736a5e47c8fcbe1afc8b5de6fb28b14d25574af9e62150fcaac", size = 341260 }, - { url = "https://files.pythonhosted.org/packages/2d/41/4e07c2afca3f9ed3da5b0e38d43d0280d9b624a3d5c478c425e5ce17775c/yarl-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1654ec814b18be1af2c857aa9000de7a601400bd4c9ca24629b18486c2e35463", size = 340882 }, - { url = "https://files.pythonhosted.org/packages/c3/c0/cd8e94618983c1b811af082e1a7ad7764edb3a6af2bc6b468e0e686238ba/yarl-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f6595c852ca544aaeeb32d357e62c9c780eac69dcd34e40cae7b55bc4fb1147", size = 336648 }, - { url = "https://files.pythonhosted.org/packages/ac/fc/73ec4340d391ffbb8f34eb4c55429784ec9f5bd37973ce86d52d67135418/yarl-1.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:459e81c2fb920b5f5df744262d1498ec2c8081acdcfe18181da44c50f51312f7", size = 325019 }, - { url = "https://files.pythonhosted.org/packages/57/48/da3ebf418fc239d0a156b3bdec6b17a5446f8d2dea752299c6e47b143a85/yarl-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7e48cdb8226644e2fbd0bdb0a0f87906a3db07087f4de77a1b1b1ccfd9e93685", size = 342841 }, - { url = "https://files.pythonhosted.org/packages/5d/79/107272745a470a8167924e353a5312eb52b5a9bb58e22686adc46c94f7ec/yarl-1.17.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d9b6b28a57feb51605d6ae5e61a9044a31742db557a3b851a74c13bc61de5172", size = 341433 }, - { url = "https://files.pythonhosted.org/packages/30/9c/6459668b3b8dcc11cd061fc53e12737e740fb6b1575b49c84cbffb387b3a/yarl-1.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e594b22688d5747b06e957f1ef822060cb5cb35b493066e33ceac0cf882188b7", size = 344927 }, - { url = "https://files.pythonhosted.org/packages/c5/0b/93a17ed733aca8164fc3a01cb7d47b3f08854ce4f957cce67a6afdb388a0/yarl-1.17.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:5f236cb5999ccd23a0ab1bd219cfe0ee3e1c1b65aaf6dd3320e972f7ec3a39da", size = 355732 }, - { url = "https://files.pythonhosted.org/packages/9a/63/ead2ed6aec3c59397e135cadc66572330325a0c24cd353cd5c94f5e63463/yarl-1.17.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:a2a64e62c7a0edd07c1c917b0586655f3362d2c2d37d474db1a509efb96fea1c", size = 362123 }, - { url = "https://files.pythonhosted.org/packages/89/bf/f6b75b4c2fcf0e7bb56edc0ed74e33f37fac45dc40e5a52a3be66b02587a/yarl-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d0eea830b591dbc68e030c86a9569826145df485b2b4554874b07fea1275a199", size = 356355 }, - { url = "https://files.pythonhosted.org/packages/45/1f/50a0257cd07eef65c8c65ad6a21f5fb230012d659e021aeb6ac8a7897bf6/yarl-1.17.1-cp312-cp312-win32.whl", hash = "sha256:46ddf6e0b975cd680eb83318aa1d321cb2bf8d288d50f1754526230fcf59ba96", size = 83279 }, - { url = "https://files.pythonhosted.org/packages/bc/82/fafb2c1268d63d54ec08b3a254fbe51f4ef098211501df646026717abee3/yarl-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:117ed8b3732528a1e41af3aa6d4e08483c2f0f2e3d3d7dca7cf538b3516d93df", size = 89590 }, - { url = "https://files.pythonhosted.org/packages/06/1e/5a93e3743c20eefbc68bd89334d9c9f04f3f2334380f7bbf5e950f29511b/yarl-1.17.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:5d1d42556b063d579cae59e37a38c61f4402b47d70c29f0ef15cee1acaa64488", size = 139974 }, - { url = "https://files.pythonhosted.org/packages/a1/be/4e0f6919013c7c5eaea5c31811c551ccd599d2fc80aa3dd6962f1bbdcddd/yarl-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0167540094838ee9093ef6cc2c69d0074bbf84a432b4995835e8e5a0d984374", size = 93364 }, - { url = "https://files.pythonhosted.org/packages/73/f0/650f994bc491d0cb85df8bb45392780b90eab1e175f103a5edc61445ff67/yarl-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f0a6423295a0d282d00e8701fe763eeefba8037e984ad5de44aa349002562ac", size = 91177 }, - { url = "https://files.pythonhosted.org/packages/f3/e8/9945ed555d14b43ede3ae8b1bd73e31068a694cad2b9d3cad0a28486c2eb/yarl-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e5b078134f48552c4d9527db2f7da0b5359abd49393cdf9794017baec7506170", size = 333086 }, - { url = "https://files.pythonhosted.org/packages/a6/c0/7d167e48e14d26639ca066825af8da7df1d2fcdba827e3fd6341aaf22a3b/yarl-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d401f07261dc5aa36c2e4efc308548f6ae943bfff20fcadb0a07517a26b196d8", size = 343661 }, - { url = "https://files.pythonhosted.org/packages/fa/81/80a266517531d4e3553aecd141800dbf48d02e23ebd52909e63598a80134/yarl-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b5f1ac7359e17efe0b6e5fec21de34145caef22b260e978336f325d5c84e6938", size = 345196 }, - { url = "https://files.pythonhosted.org/packages/b0/77/6adc482ba7f2dc6c0d9b3b492e7cd100edfac4cfc3849c7ffa26fd7beb1a/yarl-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f63d176a81555984e91f2c84c2a574a61cab7111cc907e176f0f01538e9ff6e", size = 338743 }, - { url = "https://files.pythonhosted.org/packages/6d/cc/f0c4c0b92ff3ada517ffde2b127406c001504b225692216d969879ada89a/yarl-1.17.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9e275792097c9f7e80741c36de3b61917aebecc08a67ae62899b074566ff8556", size = 326719 }, - { url = "https://files.pythonhosted.org/packages/18/3b/7bfc80d3376b5fa162189993a87a5a6a58057f88315bd0ea00610055b57a/yarl-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:81713b70bea5c1386dc2f32a8f0dab4148a2928c7495c808c541ee0aae614d67", size = 345826 }, - { url = "https://files.pythonhosted.org/packages/2e/66/cf0b0338107a5c370205c1a572432af08f36ca12ecce127f5b558398b4fd/yarl-1.17.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:aa46dce75078fceaf7cecac5817422febb4355fbdda440db55206e3bd288cfb8", size = 340335 }, - { url = "https://files.pythonhosted.org/packages/2f/52/b084b0eec0fd4d2490e1d33ace3320fad704c5f1f3deaa709f929d2d87fc/yarl-1.17.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1ce36ded585f45b1e9bb36d0ae94765c6608b43bd2e7f5f88079f7a85c61a4d3", size = 345301 }, - { url = "https://files.pythonhosted.org/packages/ef/38/9e2036d948efd3bafcdb4976cb212166fded76615f0dfc6c1492c4ce4784/yarl-1.17.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2d374d70fdc36f5863b84e54775452f68639bc862918602d028f89310a034ab0", size = 354205 }, - { url = "https://files.pythonhosted.org/packages/81/c1/13dfe1e70b86811733316221c696580725ceb1c46d4e4db852807e134310/yarl-1.17.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:2d9f0606baaec5dd54cb99667fcf85183a7477f3766fbddbe3f385e7fc253299", size = 360501 }, - { url = "https://files.pythonhosted.org/packages/91/87/756e05c74cd8bf9e71537df4a2cae7e8211a9ebe0d2350a3e26949e1e41c/yarl-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b0341e6d9a0c0e3cdc65857ef518bb05b410dbd70d749a0d33ac0f39e81a4258", size = 359452 }, - { url = "https://files.pythonhosted.org/packages/06/b2/b2bb09c1e6d59e1c9b1b36a86caa473e22c3dbf26d1032c030e9bfb554dc/yarl-1.17.1-cp313-cp313-win32.whl", hash = "sha256:2e7ba4c9377e48fb7b20dedbd473cbcbc13e72e1826917c185157a137dac9df2", size = 308904 }, - { url = "https://files.pythonhosted.org/packages/f3/27/f084d9a5668853c1f3b246620269b14ee871ef3c3cc4f3a1dd53645b68ec/yarl-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:949681f68e0e3c25377462be4b658500e85ca24323d9619fdc41f68d46a1ffda", size = 314637 }, - { url = "https://files.pythonhosted.org/packages/52/ad/1fe7ff5f3e8869d4c5070f47b96bac2b4d15e67c100a8278d8e7876329fc/yarl-1.17.1-py3-none-any.whl", hash = "sha256:f1790a4b1e8e8e028c391175433b9c8122c39b46e1663228158e61e6f915bf06", size = 44352 }, +sdist = { url = "https://files.pythonhosted.org/packages/b7/9d/4b94a8e6d2b51b599516a5cb88e5bc99b4d8d4583e468057eaa29d5f0918/yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1", size = 181062 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/98/e005bc608765a8a5569f58e650961314873c8469c333616eb40bff19ae97/yarl-1.18.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7df647e8edd71f000a5208fe6ff8c382a1de8edfbccdbbfe649d263de07d8c34", size = 141458 }, + { url = "https://files.pythonhosted.org/packages/df/5d/f8106b263b8ae8a866b46d9be869ac01f9b3fb7f2325f3ecb3df8003f796/yarl-1.18.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c69697d3adff5aa4f874b19c0e4ed65180ceed6318ec856ebc423aa5850d84f7", size = 94365 }, + { url = "https://files.pythonhosted.org/packages/56/3e/d8637ddb9ba69bf851f765a3ee288676f7cf64fb3be13760c18cbc9d10bd/yarl-1.18.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:602d98f2c2d929f8e697ed274fbadc09902c4025c5a9963bf4e9edfc3ab6f7ed", size = 92181 }, + { url = "https://files.pythonhosted.org/packages/76/f9/d616a5c2daae281171de10fba41e1c0e2d8207166fc3547252f7d469b4e1/yarl-1.18.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c654d5207c78e0bd6d749f6dae1dcbbfde3403ad3a4b11f3c5544d9906969dde", size = 315349 }, + { url = "https://files.pythonhosted.org/packages/bb/b4/3ea5e7b6f08f698b3769a06054783e434f6d59857181b5c4e145de83f59b/yarl-1.18.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5094d9206c64181d0f6e76ebd8fb2f8fe274950a63890ee9e0ebfd58bf9d787b", size = 330494 }, + { url = "https://files.pythonhosted.org/packages/55/f1/e0fc810554877b1b67420568afff51b967baed5b53bcc983ab164eebf9c9/yarl-1.18.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35098b24e0327fc4ebdc8ffe336cee0a87a700c24ffed13161af80124b7dc8e5", size = 326927 }, + { url = "https://files.pythonhosted.org/packages/a9/42/b1753949b327b36f210899f2dd0a0947c0c74e42a32de3f8eb5c7d93edca/yarl-1.18.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3236da9272872443f81fedc389bace88408f64f89f75d1bdb2256069a8730ccc", size = 319703 }, + { url = "https://files.pythonhosted.org/packages/f0/6d/e87c62dc9635daefb064b56f5c97df55a2e9cc947a2b3afd4fd2f3b841c7/yarl-1.18.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2c08cc9b16f4f4bc522771d96734c7901e7ebef70c6c5c35dd0f10845270bcd", size = 310246 }, + { url = "https://files.pythonhosted.org/packages/e3/ef/e2e8d1785cdcbd986f7622d7f0098205f3644546da7919c24b95790ec65a/yarl-1.18.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:80316a8bd5109320d38eef8833ccf5f89608c9107d02d2a7f985f98ed6876990", size = 319730 }, + { url = "https://files.pythonhosted.org/packages/fc/15/8723e22345bc160dfde68c4b3ae8b236e868f9963c74015f1bc8a614101c/yarl-1.18.3-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:c1e1cc06da1491e6734f0ea1e6294ce00792193c463350626571c287c9a704db", size = 321681 }, + { url = "https://files.pythonhosted.org/packages/86/09/bf764e974f1516efa0ae2801494a5951e959f1610dd41edbfc07e5e0f978/yarl-1.18.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fea09ca13323376a2fdfb353a5fa2e59f90cd18d7ca4eaa1fd31f0a8b4f91e62", size = 324812 }, + { url = "https://files.pythonhosted.org/packages/f6/4c/20a0187e3b903c97d857cf0272d687c1b08b03438968ae8ffc50fe78b0d6/yarl-1.18.3-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:e3b9fd71836999aad54084906f8663dffcd2a7fb5cdafd6c37713b2e72be1760", size = 337011 }, + { url = "https://files.pythonhosted.org/packages/c9/71/6244599a6e1cc4c9f73254a627234e0dad3883ece40cc33dce6265977461/yarl-1.18.3-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:757e81cae69244257d125ff31663249b3013b5dc0a8520d73694aed497fb195b", size = 338132 }, + { url = "https://files.pythonhosted.org/packages/af/f5/e0c3efaf74566c4b4a41cb76d27097df424052a064216beccae8d303c90f/yarl-1.18.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b1771de9944d875f1b98a745bc547e684b863abf8f8287da8466cf470ef52690", size = 331849 }, + { url = "https://files.pythonhosted.org/packages/8a/b8/3d16209c2014c2f98a8f658850a57b716efb97930aebf1ca0d9325933731/yarl-1.18.3-cp310-cp310-win32.whl", hash = "sha256:8874027a53e3aea659a6d62751800cf6e63314c160fd607489ba5c2edd753cf6", size = 84309 }, + { url = "https://files.pythonhosted.org/packages/fd/b7/2e9a5b18eb0fe24c3a0e8bae994e812ed9852ab4fd067c0107fadde0d5f0/yarl-1.18.3-cp310-cp310-win_amd64.whl", hash = "sha256:93b2e109287f93db79210f86deb6b9bbb81ac32fc97236b16f7433db7fc437d8", size = 90484 }, + { url = "https://files.pythonhosted.org/packages/40/93/282b5f4898d8e8efaf0790ba6d10e2245d2c9f30e199d1a85cae9356098c/yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069", size = 141555 }, + { url = "https://files.pythonhosted.org/packages/6d/9c/0a49af78df099c283ca3444560f10718fadb8a18dc8b3edf8c7bd9fd7d89/yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193", size = 94351 }, + { url = "https://files.pythonhosted.org/packages/5a/a1/205ab51e148fdcedad189ca8dd587794c6f119882437d04c33c01a75dece/yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889", size = 92286 }, + { url = "https://files.pythonhosted.org/packages/ed/fe/88b690b30f3f59275fb674f5f93ddd4a3ae796c2b62e5bb9ece8a4914b83/yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8", size = 340649 }, + { url = "https://files.pythonhosted.org/packages/07/eb/3b65499b568e01f36e847cebdc8d7ccb51fff716dbda1ae83c3cbb8ca1c9/yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca", size = 356623 }, + { url = "https://files.pythonhosted.org/packages/33/46/f559dc184280b745fc76ec6b1954de2c55595f0ec0a7614238b9ebf69618/yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8", size = 354007 }, + { url = "https://files.pythonhosted.org/packages/af/ba/1865d85212351ad160f19fb99808acf23aab9a0f8ff31c8c9f1b4d671fc9/yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae", size = 344145 }, + { url = "https://files.pythonhosted.org/packages/94/cb/5c3e975d77755d7b3d5193e92056b19d83752ea2da7ab394e22260a7b824/yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3", size = 336133 }, + { url = "https://files.pythonhosted.org/packages/19/89/b77d3fd249ab52a5c40859815765d35c91425b6bb82e7427ab2f78f5ff55/yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb", size = 347967 }, + { url = "https://files.pythonhosted.org/packages/35/bd/f6b7630ba2cc06c319c3235634c582a6ab014d52311e7d7c22f9518189b5/yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e", size = 346397 }, + { url = "https://files.pythonhosted.org/packages/18/1a/0b4e367d5a72d1f095318344848e93ea70da728118221f84f1bf6c1e39e7/yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59", size = 350206 }, + { url = "https://files.pythonhosted.org/packages/b5/cf/320fff4367341fb77809a2d8d7fe75b5d323a8e1b35710aafe41fdbf327b/yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d", size = 362089 }, + { url = "https://files.pythonhosted.org/packages/57/cf/aadba261d8b920253204085268bad5e8cdd86b50162fcb1b10c10834885a/yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e", size = 366267 }, + { url = "https://files.pythonhosted.org/packages/54/58/fb4cadd81acdee6dafe14abeb258f876e4dd410518099ae9a35c88d8097c/yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a", size = 359141 }, + { url = "https://files.pythonhosted.org/packages/9a/7a/4c571597589da4cd5c14ed2a0b17ac56ec9ee7ee615013f74653169e702d/yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1", size = 84402 }, + { url = "https://files.pythonhosted.org/packages/ae/7b/8600250b3d89b625f1121d897062f629883c2f45339623b69b1747ec65fa/yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5", size = 91030 }, + { url = "https://files.pythonhosted.org/packages/33/85/bd2e2729752ff4c77338e0102914897512e92496375e079ce0150a6dc306/yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50", size = 142644 }, + { url = "https://files.pythonhosted.org/packages/ff/74/1178322cc0f10288d7eefa6e4a85d8d2e28187ccab13d5b844e8b5d7c88d/yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576", size = 94962 }, + { url = "https://files.pythonhosted.org/packages/be/75/79c6acc0261e2c2ae8a1c41cf12265e91628c8c58ae91f5ff59e29c0787f/yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640", size = 92795 }, + { url = "https://files.pythonhosted.org/packages/6b/32/927b2d67a412c31199e83fefdce6e645247b4fb164aa1ecb35a0f9eb2058/yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2", size = 332368 }, + { url = "https://files.pythonhosted.org/packages/19/e5/859fca07169d6eceeaa4fde1997c91d8abde4e9a7c018e371640c2da2b71/yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75", size = 342314 }, + { url = "https://files.pythonhosted.org/packages/08/75/76b63ccd91c9e03ab213ef27ae6add2e3400e77e5cdddf8ed2dbc36e3f21/yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512", size = 341987 }, + { url = "https://files.pythonhosted.org/packages/1a/e1/a097d5755d3ea8479a42856f51d97eeff7a3a7160593332d98f2709b3580/yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba", size = 336914 }, + { url = "https://files.pythonhosted.org/packages/0b/42/e1b4d0e396b7987feceebe565286c27bc085bf07d61a59508cdaf2d45e63/yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb", size = 325765 }, + { url = "https://files.pythonhosted.org/packages/7e/18/03a5834ccc9177f97ca1bbb245b93c13e58e8225276f01eedc4cc98ab820/yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272", size = 344444 }, + { url = "https://files.pythonhosted.org/packages/c8/03/a713633bdde0640b0472aa197b5b86e90fbc4c5bc05b727b714cd8a40e6d/yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6", size = 340760 }, + { url = "https://files.pythonhosted.org/packages/eb/99/f6567e3f3bbad8fd101886ea0276c68ecb86a2b58be0f64077396cd4b95e/yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e", size = 346484 }, + { url = "https://files.pythonhosted.org/packages/8e/a9/84717c896b2fc6cb15bd4eecd64e34a2f0a9fd6669e69170c73a8b46795a/yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb", size = 359864 }, + { url = "https://files.pythonhosted.org/packages/1e/2e/d0f5f1bef7ee93ed17e739ec8dbcb47794af891f7d165fa6014517b48169/yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393", size = 364537 }, + { url = "https://files.pythonhosted.org/packages/97/8a/568d07c5d4964da5b02621a517532adb8ec5ba181ad1687191fffeda0ab6/yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285", size = 357861 }, + { url = "https://files.pythonhosted.org/packages/7d/e3/924c3f64b6b3077889df9a1ece1ed8947e7b61b0a933f2ec93041990a677/yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2", size = 84097 }, + { url = "https://files.pythonhosted.org/packages/34/45/0e055320daaabfc169b21ff6174567b2c910c45617b0d79c68d7ab349b02/yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477", size = 90399 }, + { url = "https://files.pythonhosted.org/packages/30/c7/c790513d5328a8390be8f47be5d52e141f78b66c6c48f48d241ca6bd5265/yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb", size = 140789 }, + { url = "https://files.pythonhosted.org/packages/30/aa/a2f84e93554a578463e2edaaf2300faa61c8701f0898725842c704ba5444/yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa", size = 94144 }, + { url = "https://files.pythonhosted.org/packages/c6/fc/d68d8f83714b221a85ce7866832cba36d7c04a68fa6a960b908c2c84f325/yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782", size = 91974 }, + { url = "https://files.pythonhosted.org/packages/56/4e/d2563d8323a7e9a414b5b25341b3942af5902a2263d36d20fb17c40411e2/yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0", size = 333587 }, + { url = "https://files.pythonhosted.org/packages/25/c9/cfec0bc0cac8d054be223e9f2c7909d3e8442a856af9dbce7e3442a8ec8d/yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482", size = 344386 }, + { url = "https://files.pythonhosted.org/packages/ab/5d/4c532190113b25f1364d25f4c319322e86232d69175b91f27e3ebc2caf9a/yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186", size = 345421 }, + { url = "https://files.pythonhosted.org/packages/23/d1/6cdd1632da013aa6ba18cee4d750d953104a5e7aac44e249d9410a972bf5/yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58", size = 339384 }, + { url = "https://files.pythonhosted.org/packages/9a/c4/6b3c39bec352e441bd30f432cda6ba51681ab19bb8abe023f0d19777aad1/yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53", size = 326689 }, + { url = "https://files.pythonhosted.org/packages/23/30/07fb088f2eefdc0aa4fc1af4e3ca4eb1a3aadd1ce7d866d74c0f124e6a85/yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2", size = 345453 }, + { url = "https://files.pythonhosted.org/packages/63/09/d54befb48f9cd8eec43797f624ec37783a0266855f4930a91e3d5c7717f8/yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8", size = 341872 }, + { url = "https://files.pythonhosted.org/packages/91/26/fd0ef9bf29dd906a84b59f0cd1281e65b0c3e08c6aa94b57f7d11f593518/yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1", size = 347497 }, + { url = "https://files.pythonhosted.org/packages/d9/b5/14ac7a256d0511b2ac168d50d4b7d744aea1c1aa20c79f620d1059aab8b2/yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a", size = 359981 }, + { url = "https://files.pythonhosted.org/packages/ca/b3/d493221ad5cbd18bc07e642894030437e405e1413c4236dd5db6e46bcec9/yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10", size = 366229 }, + { url = "https://files.pythonhosted.org/packages/04/56/6a3e2a5d9152c56c346df9b8fb8edd2c8888b1e03f96324d457e5cf06d34/yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8", size = 360383 }, + { url = "https://files.pythonhosted.org/packages/fd/b7/4b3c7c7913a278d445cc6284e59b2e62fa25e72758f888b7a7a39eb8423f/yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d", size = 310152 }, + { url = "https://files.pythonhosted.org/packages/f5/d5/688db678e987c3e0fb17867970700b92603cadf36c56e5fb08f23e822a0c/yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", size = 315723 }, + { url = "https://files.pythonhosted.org/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", size = 45109 }, ] diff --git a/compose.yml b/compose.yml new file mode 100644 index 0000000..e69de29 From 9500f418bd24d8fa70abbcf5590a7cb2202f8646 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 19 Jan 2025 17:28:25 +0800 Subject: [PATCH 43/65] chore: update email --- pyproject.toml | 39 ++++++++++++++++++--------------------- scripts/bump.sh | 2 +- 2 files changed, 19 insertions(+), 22 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 47da6b0..dbc134b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -2,14 +2,12 @@ name = "fastapi_supabase_template" version = "0.4.1" description = "" -authors = [ - {name = "Atticus.J.Zeller", email = "atticus.zeller@pm.me"}, -] +authors = [{ name = "Atticus.J.Zeller", email = "hello@atticux.me" }] readme = "README.md" ## VCS [tool.git-cliff.remote.github] -owner = "atticuszz" +owner = "atticuszeller" repo = "fastapi_supabase_template" [tool.git-cliff.changelog] @@ -61,24 +59,24 @@ split_commits = false # regex for preprocessing the commit messages commit_preprocessors = [ # If the spelling is incorrect, it will be automatically fixed. - { pattern = '.*', replace_command = 'typos --write-changes -' } + { pattern = '.*', replace_command = 'typos --write-changes -' }, ] # regex for parsing and grouping commits commit_parsers = [ - { message = "^feat", group = "🚀 Features" }, - { message = "^fix", group = "🐛 Bug Fixes" }, - { message = "^doc", group = "📚 Documentation" }, - { message = "^perf", group = "⚡ Performance" }, - { message = "^refactor", group = "🚜 Refactor" }, - { message = "^style", group = "🎨 Styling" }, - { message = "^test", group = "🧪 Testing" }, - { message = "^chore\\(release\\)", skip = true }, - { message = "^chore\\(deps.*\\)", skip = true }, - { message = "^chore\\(pr\\)", skip = true }, - { message = "^chore\\(pull\\)", skip = true }, - { message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" }, - { body = ".*security", group = "🛡️ Security" }, - { message = "^revert", group = "◀️ Revert" }, + { message = "^feat", group = "🚀 Features" }, + { message = "^fix", group = "🐛 Bug Fixes" }, + { message = "^doc", group = "📚 Documentation" }, + { message = "^perf", group = "⚡ Performance" }, + { message = "^refactor", group = "🚜 Refactor" }, + { message = "^style", group = "🎨 Styling" }, + { message = "^test", group = "🧪 Testing" }, + { message = "^chore\\(release\\)", skip = true }, + { message = "^chore\\(deps.*\\)", skip = true }, + { message = "^chore\\(pr\\)", skip = true }, + { message = "^chore\\(pull\\)", skip = true }, + { message = "^chore|^ci", group = "⚙️ Miscellaneous Tasks" }, + { body = ".*security", group = "🛡️ Security" }, + { message = "^revert", group = "◀️ Revert" }, ] # filter out the commits that are not matched by commit parsers filter_commits = false @@ -101,7 +99,7 @@ tag = true sign_tags = false tag_name = "v{new_version}" tag_message = "chore(release): {current_version} → {new_version}" -allow_dirty = true # git-cliff first then bump patch +allow_dirty = true # git-cliff first then bump patch commit = true message = "chore(release): {current_version} → {new_version}" commit_args = "" @@ -120,5 +118,4 @@ search = "unreleased" replace = "{new_version} - {now:%Y-%m-%d}" - # https://callowayproject.github.io/bump-my-version/reference/search-and-replace-config/ diff --git a/scripts/bump.sh b/scripts/bump.sh index 2bc187e..b727695 100755 --- a/scripts/bump.sh +++ b/scripts/bump.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # update CHANGELOG.md use GITHUB_REPO ENV as github token -uvx git-cliff -o -v --github-repo "atticuszz/python-uv" +uvx git-cliff -o -v --github-repo "atticuszeller/python-uv" # bump version and commit with tags # uvx bump-my-version bump patch # push remote From 83402a29d33a56227cb954a32d926c7e1b854211 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 19 Jan 2025 18:44:32 +0800 Subject: [PATCH 44/65] style: pre-commit format --- .github/workflows/docs.yml | 2 +- .github/workflows/main.yml | 1 - backend/app/api/routes/items.py | 40 +++++++++++++++------------------ backend/scripts/format.sh | 2 +- 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 80fa6b3..fbd21ca 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -30,4 +30,4 @@ jobs: # Reference # 1. https://squidfunk.github.io/mkdocs-material/publishing-your-site/ # 2. https://github.com/Kludex/python-template/blob/main/.github/workflows/docs.yml -# 3. https://github.com/astral-sh/setup-uv/tree/v3/ \ No newline at end of file +# 3. https://github.com/astral-sh/setup-uv/tree/v3/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5e04255..74d6ccd 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -73,4 +73,3 @@ jobs: # 1. https://docs.astral.sh/uv/guides/integration/github/#syncing-and-running # 2. https://github.com/Kludex/python-template/blob/main/.github/workflows/main.yml # 3. https://github.com/softprops/action-gh-release/tree/master/ - diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index 4c6b729..470e51d 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -1,37 +1,33 @@ from fastapi import APIRouter -from app.api.deps import CurrentUser, SessionDep -from app.crud import item -from app.schemas import Item, ItemCreate, ItemUpdate - router = APIRouter() -@router.post("/create-item") -async def create_item(item_in: ItemCreate, session: SessionDep) -> Item: - return await item.create(session, obj_in=item_in) +# @router.post("/create-item") +# async def create_item(item_in: ItemCreate, session: SessionDep) -> Item: +# return await item.create(session, obj_in=item_in) -@router.get("/read-all-item") -async def read_items(session: SessionDep) -> list[Item]: - return await item.get_all(session) +# @router.get("/read-all-item") +# async def read_items(session: SessionDep) -> list[Item]: +# return await item.get_all(session) -@router.get("/get-by-id/{id}") -async def read_item_by_id(id: str, session: SessionDep) -> Item | None: - return await item.get(session, id=id) +# @router.get("/get-by-id/{id}") +# async def read_item_by_id(id: str, session: SessionDep) -> Item | None: +# return await item.get(session, id=id) -@router.get("/get-by-owner") -async def read_item_by_owner(session: SessionDep, user: CurrentUser) -> list[Item]: - return await item.get_multi_by_owner(session, user=user) +# @router.get("/get-by-owner") +# async def read_item_by_owner(session: SessionDep, user: CurrentUser) -> list[Item]: +# return await item.get_multi_by_owner(session, user=user) -@router.put("/update-item") -async def update_item(item_in: ItemUpdate, session: SessionDep) -> Item: - return await item.update(session, obj_in=item_in) +# @router.put("/update-item") +# async def update_item(item_in: ItemUpdate, session: SessionDep) -> Item: +# return await item.update(session, obj_in=item_in) -@router.delete("/delete/{id}") -async def delete_item(id: str, session: SessionDep) -> Item: - return await item.delete(session, id=id) +# @router.delete("/delete/{id}") +# async def delete_item(id: str, session: SessionDep) -> Item: +# return await item.delete(session, id=id) diff --git a/backend/scripts/format.sh b/backend/scripts/format.sh index 8d214af..6e162b3 100755 --- a/backend/scripts/format.sh +++ b/backend/scripts/format.sh @@ -1,4 +1,4 @@ -#!/bin/sh -e +#!/usr/bin/env bash set -x ruff check app scripts tests --fix From e51c83eb0c0c9d76061be606721fb44e1e0279b0 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Sun, 19 Jan 2025 18:45:13 +0800 Subject: [PATCH 45/65] docs: update README.md --- .env | 2 +- README.md | 192 +++++-------------------------------- backend/app/alembic/README | 1 + 3 files changed, 27 insertions(+), 168 deletions(-) create mode 100644 backend/app/alembic/README diff --git a/.env b/.env index 4e6e028..e721346 100644 --- a/.env +++ b/.env @@ -19,7 +19,7 @@ FIRST_SUPERUSER_PASSWORD=admin12345 # API URL SUPABASE_URL=http://localhost:54321 # service_role key -SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU +SUPABASE_KEY=eeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU # Postgres # DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres diff --git a/README.md b/README.md index aaf418a..fcbb889 100644 --- a/README.md +++ b/README.md @@ -1,185 +1,43 @@ -

- Logo -

+# FastAPI Supbase Template -

- - License: MIT - - - codecov - - - CI - - - GitHub release - - Python - - Made with Supabase - -

+## Environment -# ⚡SupaFast⚡ +### Python -___ -> supabase & fastapi crud template +> [uv](https://github.com/astral-sh/uv) is an extremely fast Python package and project manager, written in Rust. -![supafast.drawio.png](docs/assets/supafast.drawio.png) - -## Features 🚀 - -___ - -### FastAPI&supabase - -1. works of authorization all handled by supabase-py and fastapi **dependency** without any extra code -2. supabase-py crud integration with **pydantic** model validation - -### Pytest - -1. pytest integration with **pytest-cov** -2. pytest **fixtures** for fastapi client and supabase client -3. pytest **fixtures** for access_token and refresh_token -4. test for **CRUD** operations -5. test for **api** operations - -### CI/CD - -1. **codecov** for coverage report -2. **poetry** for dependency management and pytest integration -3. **pre-commit** for code quality -4. **latest_changes.yml** for auto update README.md -5. **Semantic Release** for auto release and changelog -6. **docker** for deployment - -## How to use it - -___ -![](docs/assets/usage.gif) - -1. create your github repo and config it - 1. allow ci to access your repo - ![img.png](docs/assets/img.png) - 2. config ci_tokens - 1. `CODECOV_TOKEN` for codecov in `.github/workflows/ci.yml` ,`semantic-release` is optional for auto release - 2. `ATTICUS_PAT`should replace with your GitHub token for latest_changes.yml in `.github/workflows/latest_changes.yml` - 3. `DOCKER_USERNAME` and `DOCKER_PASSWORD` for docker-image.yml in `.github/workflows/docker-image.yml` - 4. replace `tags: atticuszhou/supafast:latest` with your docker repo in `.github/workflows/docker-image.yml` - 3. config fastapi setting in `your_project\src\app\core\config.py` - 4. config `pyproject.toml` with your project name and description,etc - -2. cd your repo and install dependencies with [uv](https://github.com/astral-sh/uv), which is an extremely fast Python package and project manager, written in Rust. - -```shell -uv sync +```bash +cd backend +uv sync --all-groups --dev ``` -3. [start your supabase locally](https://supabase.com/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=linux&queryGroups=access-method&access-method=postgres) +### [Supabase](https://supabase.com/docs/guides/local-development/cli/getting-started?queryGroups=platform&platform=linux&queryGroups=access-method&access-method=postgres) + +install supabase-cli ```bash # brew in linux https://brew.sh/ brew install supabase/tap/supabase -supabase init -supabase start ``` -4. set your supabase env +launch supabase docker containers -```shell -export SUPABASE_URL=your_supabase_url -export SUPABASE_KEY=your_supabase_key -export SUPERUSER_EMAIL=your_superuser_email -export SUPERUSER_PASSWORD=your_superuser_password +```bash +# under repo root dir +supabase start ``` -5. config fastapi settings - -```python -# src/app/core/config.py -class Settings(BaseSettings): - API_V1_STR: str = "/api/v1" - SUPABASE_URL: str = Field(default_factory=lambda: os.getenv("SUPABASE_URL")) - SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv("SUPABASE_KEY")) - SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv("SUPERUSER_EMAIL")) - SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv("SUPERUSER_PASSWORD")) - # SERVER_NAME: str - SERVER_HOST: AnyHttpUrl = "https://localhost" - SERVER_PORT: int = 8000 - BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = [] - PROJECT_NAME: str = "fastapi supabase template" - Config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) -``` +> [!NOTE] +> modify the `.env` from the output of `supabase start` or run `supabase status` manually. -6. run server +## Test -```shell -uv run uvicorn app.main:app --reload +```bash +cd backend +# test connection of db and migration +scripts/pre-start.sh +# unit test +scripts/test.sh +# test connection of db and unit test +scripts/tests-start.sh ``` - -## Roadmap 🫶 - -___ - -- [x] FastAPI backend - - [x] **standard** structure - for **FastAPI** project - - ```text - ── src - │ └── app - │ ├── api - │ │ ├── api_v1 - │ │ │ ├── endpoints - │ │ │ │ ├── __init__.py - │ │ │ │ └── items.py - │ │ │ ├── __init__.py - │ │ │ └── api.py - │ │ ├── __init__.py - │ │ └── deps.py - │ ├── core - │ │ ├── __init__.py - │ │ ├── config.py - │ │ └── events.py - │ ├── crud - │ │ ├── __init__.py - │ │ ├── base.py - │ │ └── crud_item.py - │ ├── schemas - │ │ ├── __init__.py - │ │ ├── auth.py - │ │ ├── base.py - │ │ ├── item.py - │ │ └── msg.py - │ ├── services - │ │ └── __init__.py - │ ├── utils - │ │ └── __init__.py - │ ├── __init__.py - │ └── main.py - ... - ``` - - - [x] **auto-auth** by fastapi dependency with supabase-auth - - [x] **CRUD** operations pytest - - [x] **api** requests pytest -- [ ] Supabase integration - - [x] crud supabase-postgresql - - [ ] websocket with supabase-realtime - - [ ] curd supabase-storage - - [ ] supafunc integration -- [x] deployment - - [x] Full **Docker** integration (Docker based). -- [ ] clone - - [ ] cookiecutter - -## Release Notes 🥸 - -___ - -### Latest Changes - -## License - -This project is licensed under the terms of the MIT license. diff --git a/backend/app/alembic/README b/backend/app/alembic/README new file mode 100644 index 0000000..2500aa1 --- /dev/null +++ b/backend/app/alembic/README @@ -0,0 +1 @@ +Generic single-database configuration. From 31269f868a7bfe6dd5f8bcb5aced26f1e7a4a674 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 29 Jan 2025 10:00:18 +0800 Subject: [PATCH 46/65] fix: test client and db fixture --- README.md | 2 + backend/app/api/main.py | 2 +- backend/app/api/routes/items.py | 2 +- backend/app/main.py | 10 +- backend/app/utils/__init__.py | 5 + backend/pyproject.toml | 1 + backend/tests/conftest.py | 61 ++--- backend/tests/crud/test_item.py | 244 +++++++++--------- backend/tests/pre_start/test_main.py | 8 - .../{pre_start/test_db.py => test_main.py} | 8 + backend/uv.lock | 98 +++---- 11 files changed, 231 insertions(+), 210 deletions(-) delete mode 100644 backend/tests/pre_start/test_main.py rename backend/tests/{pre_start/test_db.py => test_main.py} (61%) diff --git a/README.md b/README.md index fcbb889..1b5e2a0 100644 --- a/README.md +++ b/README.md @@ -41,3 +41,5 @@ scripts/test.sh # test connection of db and unit test scripts/tests-start.sh ``` + +1. [x] test_main.py diff --git a/backend/app/api/main.py b/backend/app/api/main.py index 1e9becb..584979c 100644 --- a/backend/app/api/main.py +++ b/backend/app/api/main.py @@ -3,4 +3,4 @@ from app.api.routes import items api_router = APIRouter() -api_router.include_router(items.router, prefix="/items", tags=["items"]) +api_router.include_router(items.router) diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index 470e51d..00f478c 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -1,6 +1,6 @@ from fastapi import APIRouter -router = APIRouter() +router = APIRouter(prefix="/items", tags=["items"]) # @router.post("/create-item") diff --git a/backend/app/main.py b/backend/app/main.py index cc6d197..9d75b12 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -10,6 +10,7 @@ from app.api.main import api_router from app.core.config import settings +from app.utils import custom_generate_unique_id logger = logging.getLogger("uvicorn") @@ -29,9 +30,10 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 lifespan=lifespan, title=settings.PROJECT_NAME, openapi_url=f"{settings.API_V1_STR}/openapi.json", - generate_unique_id_function=lambda router: f"{router.tags[0]}-{router.name}", + generate_unique_id_function=custom_generate_unique_id, ) + # Set all CORS enabled origins if settings.all_cors_origins: app.add_middleware( @@ -42,10 +44,16 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # noqa ARG001 allow_headers=["*"], ) + # Include the routers app.include_router(api_router, prefix=settings.API_V1_STR) +@app.get("/", tags=["root"]) +async def read_root() -> dict[str, str]: + return {"Hello": "World"} + + # Logger def timestamp_log_config(uvicorn_log_config: dict[str, Any]) -> dict[str, Any]: """https://github.com/fastapi/fastapi/discussions/7457#discussioncomment-5565969""" diff --git a/backend/app/utils/__init__.py b/backend/app/utils/__init__.py index e69de29..37e0f07 100644 --- a/backend/app/utils/__init__.py +++ b/backend/app/utils/__init__.py @@ -0,0 +1,5 @@ +from fastapi.routing import APIRoute + + +def custom_generate_unique_id(route: APIRoute) -> str: + return f"{route.tags[0]}-{route.name}" diff --git a/backend/pyproject.toml b/backend/pyproject.toml index c560446..feeaf64 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -25,6 +25,7 @@ dev = [ "pre-commit>=3.8.0", "pytest-sugar>=1.0.0", "pytest>=8.3.2", + "httpx>=0.28.1", ] [build-system] diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 950fe86..2fea6b1 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,15 +1,11 @@ -import os -from collections.abc import AsyncGenerator, Generator +from collections.abc import AsyncGenerator import pytest -from faker import Faker -from fastapi.testclient import TestClient +from httpx import ASGITransport, AsyncClient from sqlmodel.ext.asyncio.session import AsyncSession -from supabase._async.client import create_client from app.core.db import engine from app.main import app -from app.schemas import Token @pytest.fixture(scope="module") @@ -20,29 +16,36 @@ def anyio_backend() -> str: @pytest.fixture(scope="module") async def db() -> AsyncGenerator[AsyncSession, None]: async with AsyncSession(engine) as session: - yield session + async with session.begin(): + yield session + await session.rollback() @pytest.fixture(scope="module") -def client() -> Generator[TestClient, None, None]: - with TestClient(app) as c: - yield c - - -@pytest.fixture(scope="module") -async def token() -> AsyncGenerator[Token, None]: - url = os.environ.get("SUPABASE_TEST_URL") - assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" - key = os.environ.get("SUPABASE_TEST_KEY") - assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" - db_client = await create_client(url, key) - fake_email = Faker().email() - fake_password = Faker().password() - response = await db_client.auth.sign_up( - {"email": fake_email, "password": fake_password} - ) - assert response.user - assert response.user.email == fake_email - assert response.user.id is not None - - yield Token(access_token=response.session.access_token) +async def client(): + """async client fixture + Ref: https://fastapi.tiangolo.com/advanced/async-tests/#example + """ + async with AsyncClient( + transport=ASGITransport(app=app), base_url="http://test" + ) as ac: + yield ac + + +# @pytest.fixture(scope="module") +# async def token() -> AsyncGenerator[Token, None]: +# url = os.environ.get("SUPABASE_TEST_URL") +# assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" +# key = os.environ.get("SUPABASE_TEST_KEY") +# assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" +# db_client = await create_client(url, key) +# fake_email = Faker().email() +# fake_password = Faker().password() +# response = await db_client.auth.sign_up( +# {"email": fake_email, "password": fake_password} +# ) +# assert response.user +# assert response.user.email == fake_email +# assert response.user.id is not None + +# yield Token(access_token=response.session.access_token) diff --git a/backend/tests/crud/test_item.py b/backend/tests/crud/test_item.py index d94863f..2eef006 100644 --- a/backend/tests/crud/test_item.py +++ b/backend/tests/crud/test_item.py @@ -1,125 +1,125 @@ -import uuid -from collections.abc import AsyncGenerator - -import pytest -from faker import Faker -from sqlmodel import select -from sqlmodel.ext.asyncio.session import AsyncSession - -from app import crud -from app.core.auth import get_super_client -from app.models import User as UserInDB -from app.models.item import Item, ItemCreate, ItemUpdate - -fake = Faker() - - -@pytest.fixture(scope="module") -async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: - """Fixture to create a test user""" - super_client = await get_super_client() - try: - response = await super_client.auth.sign_up( - {"email": fake.email(), "password": "testpassword123"} - ) - yield uuid.UUID(response.user.id) - finally: - result = await db.exec( - select(UserInDB).where(str(UserInDB.id) == response.user.id) - ) - user = result.first() - if user: - await db.delete(user) - await db.commit() - - -@pytest.fixture -async def test_item( - db: AsyncSession, test_user_id: uuid.UUID -) -> AsyncGenerator[Item, None]: - """Fixture to create a test item and clean it up after the test""" - item_in = ItemCreate( - title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) - ) - item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) - yield item - # Cleanup - await crud.item.remove(db, id=item.id) - - -@pytest.mark.anyio -async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: - """Test creating a new item""" - title = fake.sentence(nb_words=3) - description = fake.text(max_nb_chars=200) - item_in = ItemCreate(title=title, description=description) - - item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) - - assert item.id is not None - assert item.title == title - assert item.description == description - assert item.owner_id == test_user_id - - # Cleanup - await crud.item.remove(db, id=item.id) - - -@pytest.mark.anyio -async def test_get_item(db: AsyncSession, test_item: Item) -> None: - """Test retrieving a single item""" - stored_item = await crud.item.get(db, id=test_item.id) - - assert stored_item is not None - assert stored_item.id == test_item.id - assert stored_item.title == test_item.title - assert stored_item.description == test_item.description - assert stored_item.owner_id == test_item.owner_id - - -@pytest.mark.anyio -async def test_get_nonexistent_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: - """Test retrieving a non-existent item""" - nonexistent_item = await crud.item.get(db, id=test_user_id) - assert nonexistent_item is None - - -@pytest.mark.anyio -async def test_update_item(db: AsyncSession, test_item: Item) -> None: - """Test updating an item""" - new_title = fake.sentence(nb_words=3) - new_description = fake.text(max_nb_chars=200) - update_data = ItemUpdate(title=new_title, description=new_description) - - updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) - - assert updated_item is not None - assert updated_item.id == test_item.id - assert updated_item.title == new_title - assert updated_item.description == new_description - assert updated_item.owner_id == test_item.owner_id - - -@pytest.mark.anyio -async def test_update_nonexistent_item( - db: AsyncSession, test_user_id: uuid.UUID -) -> None: - """Test updating a non-existent item""" - update_data = ItemUpdate(title=fake.sentence(nb_words=3)) - updated_item = await crud.item.update(db, id=test_user_id, obj_in=update_data) - assert updated_item is None - - -@pytest.mark.anyio -async def test_delete_item(db: AsyncSession, test_item: Item) -> None: - """Test deleting an item""" - deleted_item = await crud.item.remove(db, id=test_item.id) - assert deleted_item is not None - assert deleted_item.id == test_item.id - - # Verify item is deleted - item = await crud.item.get(db, id=test_item.id) - assert item is None +# import uuid +# from collections.abc import AsyncGenerator + +# import pytest +# from faker import Faker +# from sqlmodel import select +# from sqlmodel.ext.asyncio.session import AsyncSession + +# from app import crud +# from app.core.auth import get_super_client +# from app.models import User as UserInDB +# from app.models.item import Item, ItemCreate, ItemUpdate + +# fake = Faker() + + +# @pytest.fixture(scope="module") +# async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: +# """Fixture to create a test user""" +# super_client = await get_super_client() +# try: +# response = await super_client.auth.sign_up( +# {"email": fake.email(), "password": "testpassword123"} +# ) +# yield uuid.UUID(response.user.id) +# finally: +# result = await db.exec( +# select(UserInDB).where(str(UserInDB.id) == response.user.id) +# ) +# user = result.first() +# if user: +# await db.delete(user) +# await db.commit() + + +# @pytest.fixture +# async def test_item( +# db: AsyncSession, test_user_id: uuid.UUID +# ) -> AsyncGenerator[Item, None]: +# """Fixture to create a test item and clean it up after the test""" +# item_in = ItemCreate( +# title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) +# ) +# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) +# yield item +# # Cleanup +# await crud.item.remove(db, id=item.id) + + +# @pytest.mark.anyio +# async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: +# """Test creating a new item""" +# title = fake.sentence(nb_words=3) +# description = fake.text(max_nb_chars=200) +# item_in = ItemCreate(title=title, description=description) + +# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + +# assert item.id is not None +# assert item.title == title +# assert item.description == description +# assert item.owner_id == test_user_id + +# # Cleanup +# await crud.item.remove(db, id=item.id) + + +# @pytest.mark.anyio +# async def test_get_item(db: AsyncSession, test_item: Item) -> None: +# """Test retrieving a single item""" +# stored_item = await crud.item.get(db, id=test_item.id) + +# assert stored_item is not None +# assert stored_item.id == test_item.id +# assert stored_item.title == test_item.title +# assert stored_item.description == test_item.description +# assert stored_item.owner_id == test_item.owner_id + + +# @pytest.mark.anyio +# async def test_get_nonexistent_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: +# """Test retrieving a non-existent item""" +# nonexistent_item = await crud.item.get(db, id=test_user_id) +# assert nonexistent_item is None + + +# @pytest.mark.anyio +# async def test_update_item(db: AsyncSession, test_item: Item) -> None: +# """Test updating an item""" +# new_title = fake.sentence(nb_words=3) +# new_description = fake.text(max_nb_chars=200) +# update_data = ItemUpdate(title=new_title, description=new_description) + +# updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) + +# assert updated_item is not None +# assert updated_item.id == test_item.id +# assert updated_item.title == new_title +# assert updated_item.description == new_description +# assert updated_item.owner_id == test_item.owner_id + + +# @pytest.mark.anyio +# async def test_update_nonexistent_item( +# db: AsyncSession, test_user_id: uuid.UUID +# ) -> None: +# """Test updating a non-existent item""" +# update_data = ItemUpdate(title=fake.sentence(nb_words=3)) +# updated_item = await crud.item.update(db, id=test_user_id, obj_in=update_data) +# assert updated_item is None + + +# @pytest.mark.anyio +# async def test_delete_item(db: AsyncSession, test_item: Item) -> None: +# """Test deleting an item""" +# deleted_item = await crud.item.remove(db, id=test_item.id) +# assert deleted_item is not None +# assert deleted_item.id == test_item.id + +# # Verify item is deleted +# item = await crud.item.get(db, id=test_item.id) +# assert item is None # @pytest.mark.anyio diff --git a/backend/tests/pre_start/test_main.py b/backend/tests/pre_start/test_main.py deleted file mode 100644 index 800229e..0000000 --- a/backend/tests/pre_start/test_main.py +++ /dev/null @@ -1,8 +0,0 @@ -import pytest -from fastapi.testclient import TestClient - - -@pytest.mark.anyio -async def test_read_main(client: TestClient) -> None: - response = client.get("/docs") - assert response.status_code == 200 diff --git a/backend/tests/pre_start/test_db.py b/backend/tests/test_main.py similarity index 61% rename from backend/tests/pre_start/test_db.py rename to backend/tests/test_main.py index 1a9d849..827fe72 100644 --- a/backend/tests/pre_start/test_db.py +++ b/backend/tests/test_main.py @@ -1,6 +1,7 @@ import logging import pytest +from httpx import AsyncClient from app.core.db import engine from app.utils.init_data import init as init_db @@ -14,3 +15,10 @@ async def test_init_db() -> None: await connect_db(engine) await init_db(engine) + + +@pytest.mark.anyio +async def test_root(client: AsyncClient) -> None: + response = await client.get("/") + assert response.status_code == 200 + assert response.json() == {"Hello": "World"} diff --git a/backend/uv.lock b/backend/uv.lock index 1cb24ef..264a80a 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -102,16 +102,16 @@ wheels = [ [[package]] name = "alembic" -version = "1.14.0" +version = "1.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mako" }, { name = "sqlalchemy" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/1e/8cb8900ba1b6360431e46fb7a89922916d3a1b017a8908a7c0499cc7e5f6/alembic-1.14.0.tar.gz", hash = "sha256:b00892b53b3642d0b8dbedba234dbf1924b69be83a9a769d5a624b01094e304b", size = 1916172 } +sdist = { url = "https://files.pythonhosted.org/packages/99/09/f844822e4e847a3f0bd41797f93c4674cd4d2462a3f6c459aa528cdf786e/alembic-1.14.1.tar.gz", hash = "sha256:496e888245a53adf1498fcab31713a469c65836f8de76e01399aa1c3e90dd213", size = 1918219 } wheels = [ - { url = "https://files.pythonhosted.org/packages/cb/06/8b505aea3d77021b18dcbd8133aa1418f1a1e37e432a465b14c46b2c0eaa/alembic-1.14.0-py3-none-any.whl", hash = "sha256:99bd884ca390466db5e27ffccff1d179ec5c05c965cfefc0607e69f9e411cb25", size = 233482 }, + { url = "https://files.pythonhosted.org/packages/54/7e/ac0991d1745f7d755fc1cd381b3990a45b404b4d008fc75e2a983516fbfe/alembic-1.14.1-py3-none-any.whl", hash = "sha256:1acdd7a3a478e208b0503cd73614d5e4c6efafa4e73518bb60e4f2846a37b1c5", size = 233565 }, ] [[package]] @@ -161,6 +161,7 @@ dev = [ { name = "anyio" }, { name = "coverage" }, { name = "faker" }, + { name = "httpx" }, { name = "mypy" }, { name = "pre-commit" }, { name = "pytest" }, @@ -187,6 +188,7 @@ dev = [ { name = "anyio", specifier = ">=4.6.2.post1" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "faker", specifier = ">=28.0.0" }, + { name = "httpx", specifier = ">=0.28.1" }, { name = "mypy", specifier = ">=1.13.0" }, { name = "pre-commit", specifier = ">=3.8.0" }, { name = "pytest", specifier = ">=8.3.2" }, @@ -247,11 +249,11 @@ wheels = [ [[package]] name = "attrs" -version = "24.3.0" +version = "25.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", size = 805984 } +sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562 } wheels = [ - { url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 }, + { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152 }, ] [[package]] @@ -406,29 +408,29 @@ wheels = [ [[package]] name = "faker" -version = "33.3.1" +version = "35.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "python-dateutil" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/9c/50/48ab6ba3f07ee7d0eac367695aeb8bc9eb9c3debc0445a67cd07e2d62b44/faker-33.3.1.tar.gz", hash = "sha256:49dde3b06a5602177bc2ad013149b6f60a290b7154539180d37b6f876ae79b20", size = 1854895 } +sdist = { url = "https://files.pythonhosted.org/packages/d5/18/86fe668976308d09e0178041c3756e646a1f5ddc676aa7fb0cf3cd52f5b9/faker-35.0.0.tar.gz", hash = "sha256:42f2da8cf561e38c72b25e9891168b1e25fec42b6b0b5b0b6cd6041da54af885", size = 1855098 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c2/01/6acc8b4dba4154cd93b444382a9ad3c099557aac577bdc7d66373e0a0c68/Faker-33.3.1-py3-none-any.whl", hash = "sha256:ac4cf2f967ce02c898efa50651c43180bd658a7707cfd676fcc5410ad1482c03", size = 1894842 }, + { url = "https://files.pythonhosted.org/packages/b8/fe/40452fb1730b10afa34dfe016097b28baa070ad74a1c1a3512ebed438c08/Faker-35.0.0-py3-none-any.whl", hash = "sha256:926d2301787220e0554c2e39afc4dc535ce4b0a8d0a089657137999f66334ef4", size = 1894841 }, ] [[package]] name = "fastapi" -version = "0.115.6" +version = "0.115.7" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pydantic" }, { name = "starlette" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/93/72/d83b98cd106541e8f5e5bfab8ef2974ab45a62e8a6c5b5e6940f26d2ed4b/fastapi-0.115.6.tar.gz", hash = "sha256:9ec46f7addc14ea472958a96aae5b5de65f39721a46aaf5705c480d9a8b76654", size = 301336 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/f5/3f921e59f189e513adb9aef826e2841672d50a399fead4e69afdeb808ff4/fastapi-0.115.7.tar.gz", hash = "sha256:0f106da6c01d88a6786b3248fb4d7a940d071f6f488488898ad5d354b25ed015", size = 293177 } wheels = [ - { url = "https://files.pythonhosted.org/packages/52/b3/7e4df40e585df024fac2f80d1a2d579c854ac37109675db2b0cc22c0bb9e/fastapi-0.115.6-py3-none-any.whl", hash = "sha256:e9240b29e36fa8f4bb7290316988e90c381e5092e0cbe84e7818cc3713bcf305", size = 94843 }, + { url = "https://files.pythonhosted.org/packages/e6/7f/bbd4dcf0faf61bc68a01939256e2ed02d681e9334c1a3cef24d5f77aba9f/fastapi-0.115.7-py3-none-any.whl", hash = "sha256:eb6a8c8bf7f26009e8147111ff15b5177a0e19bb4a45bc3486ab14804539d21e", size = 94777 }, ] [package.optional-dependencies] @@ -462,11 +464,11 @@ standard = [ [[package]] name = "filelock" -version = "3.16.1" +version = "3.17.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9d/db/3ef5bb276dae18d6ec2124224403d1d67bccdbefc17af4cc8f553e341ab1/filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435", size = 18037 } +sdist = { url = "https://files.pythonhosted.org/packages/dc/9c/0b15fb47b464e1b663b1acd1253a062aa5feecb07d4e597daea542ebd2b5/filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e", size = 18027 } wheels = [ - { url = "https://files.pythonhosted.org/packages/b9/f8/feced7779d755758a52d1f6635d990b8d98dc0a29fa568bbe0625f18fdf3/filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0", size = 16163 }, + { url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 }, ] [[package]] @@ -540,15 +542,15 @@ wheels = [ [[package]] name = "gotrue" -version = "2.11.1" +version = "2.11.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", extra = ["http2"] }, { name = "pydantic" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/37/7e/36a105bfa50b6420ed05d56d5cb5838777e283af8c90e6db3645599740e3/gotrue-2.11.1.tar.gz", hash = "sha256:5594ceee60bd873e5f4fdd028b08dece3906f6013b6ed08e7786b71c0092fed0", size = 41813 } +sdist = { url = "https://files.pythonhosted.org/packages/a3/3c/ae4ca1bc5a40bfe1549592af0085dbc6ef7e882e8bd825ff3b6463e74e5a/gotrue-2.11.2.tar.gz", hash = "sha256:8e5347b14c9e4b4b5f07a98869ae4ba6535a44e71f33b2e946266ab60b58be69", size = 41973 } wheels = [ - { url = "https://files.pythonhosted.org/packages/84/71/41b1da628837d4c03ad686388b3554bd29b65d126b65676e593b9eea5e43/gotrue-2.11.1-py3-none-any.whl", hash = "sha256:1b2d915bdc65fd0ad608532759ce9c72fa2e910145c1e6901f2188519e7bcd2d", size = 49058 }, + { url = "https://files.pythonhosted.org/packages/e2/a0/2937451bf0534b740c65679c64392f682ff27488d436bf48c8e73ecebae4/gotrue-2.11.2-py3-none-any.whl", hash = "sha256:d7a7186fa64ebf98c8b045d36dba559aebebd9e2ff5ef7fff59ec6892b3f9aa7", size = 49138 }, ] [[package]] @@ -626,11 +628,11 @@ wheels = [ [[package]] name = "hpack" -version = "4.0.0" +version = "4.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3e/9b/fda93fb4d957db19b0f6b370e79d586b3e8528b20252c729c476a2c02954/hpack-4.0.0.tar.gz", hash = "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095", size = 49117 } +sdist = { url = "https://files.pythonhosted.org/packages/2c/48/71de9ed269fdae9c8057e5a4c0aa7402e8bb16f2c6e90b3aa53327b113f8/hpack-4.1.0.tar.gz", hash = "sha256:ec5eca154f7056aa06f196a557655c5b009b382873ac8d1e66e79e87535f1dca", size = 51276 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/34/e8b383f35b77c402d28563d2b8f83159319b509bc5f760b15d60b0abf165/hpack-4.0.0-py3-none-any.whl", hash = "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", size = 32611 }, + { url = "https://files.pythonhosted.org/packages/07/c6/80c95b1b2b94682a72cbdbfb85b81ae2daffa4291fbfa1b1464502ede10d/hpack-4.1.0-py3-none-any.whl", hash = "sha256:157ac792668d995c657d93111f46b4535ed114f0c9c8d672271bbec7eae1b496", size = 34357 }, ] [[package]] @@ -704,20 +706,20 @@ http2 = [ [[package]] name = "hyperframe" -version = "6.0.1" +version = "6.1.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/2a/4747bff0a17f7281abe73e955d60d80aae537a5d203f417fa1c2e7578ebb/hyperframe-6.0.1.tar.gz", hash = "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914", size = 25008 } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566 } wheels = [ - { url = "https://files.pythonhosted.org/packages/d7/de/85a784bcc4a3779d1753a7ec2dee5de90e18c7bcf402e71b51fcf150b129/hyperframe-6.0.1-py3-none-any.whl", hash = "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", size = 12389 }, + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007 }, ] [[package]] name = "identify" -version = "2.6.5" +version = "2.6.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/cf/92/69934b9ef3c31ca2470980423fda3d00f0460ddefdf30a67adf7f17e2e00/identify-2.6.5.tar.gz", hash = "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc", size = 99213 } +sdist = { url = "https://files.pythonhosted.org/packages/82/bf/c68c46601bacd4c6fb4dd751a42b6e7087240eaabc6487f2ef7a48e0e8fc/identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", size = 99217 } wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/fa/dce098f4cdf7621aa8f7b4f919ce545891f489482f0bfa5102f3eca8608b/identify-2.6.5-py2.py3-none-any.whl", hash = "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566", size = 99078 }, + { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 }, ] [[package]] @@ -998,7 +1000,7 @@ wheels = [ [[package]] name = "postgrest" -version = "0.19.1" +version = "0.19.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "deprecation" }, @@ -1006,14 +1008,14 @@ dependencies = [ { name = "pydantic" }, { name = "strenum", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2c/0c/7b98d366e86a79b13237efb891321c867bb3d2ac6538af0da7c9eb8556b1/postgrest-0.19.1.tar.gz", hash = "sha256:d8fa88953cced4f45efa0f412056c364f64ece8a35b5b35f458a7e58c133fbca", size = 15034 } +sdist = { url = "https://files.pythonhosted.org/packages/63/80/b0306469da7ad89db165ce4c76de2f12eccc7fadb900cab9cbaff760a587/postgrest-0.19.3.tar.gz", hash = "sha256:28a70f03bf3a975aa865a10487b1ce09b7195f56453f7c318a70d3117a3d323c", size = 15095 } wheels = [ - { url = "https://files.pythonhosted.org/packages/56/d2/480b92b0fb237fa00d10aa3c10d6a443a0a2b517ef1f1a492737829f1c02/postgrest-0.19.1-py3-none-any.whl", hash = "sha256:a8e7be4e1abc69fd8eee5a49d7dc3a76dfbffbd778beed0b2bd7accb3f4f3a2a", size = 22115 }, + { url = "https://files.pythonhosted.org/packages/b0/82/f1825a85745912cdd8956aad8ebc4b797d2f891c380c2b8825b35914dbd1/postgrest-0.19.3-py3-none-any.whl", hash = "sha256:03a7e638962454d10bb712c35e63a8a4bc452917917a4e9eb7427bd5b3c6c485", size = 22198 }, ] [[package]] name = "pre-commit" -version = "4.0.1" +version = "4.1.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "cfgv" }, @@ -1022,9 +1024,9 @@ dependencies = [ { name = "pyyaml" }, { name = "virtualenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/2e/c8/e22c292035f1bac8b9f5237a2622305bc0304e776080b246f3df57c4ff9f/pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2", size = 191678 } +sdist = { url = "https://files.pythonhosted.org/packages/2a/13/b62d075317d8686071eb843f0bb1f195eb332f48869d3c31a4c6f1e063ac/pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4", size = 193330 } wheels = [ - { url = "https://files.pythonhosted.org/packages/16/8f/496e10d51edd6671ebe0432e33ff800aa86775d2d147ce7d43389324a525/pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878", size = 218713 }, + { url = "https://files.pythonhosted.org/packages/43/b3/df14c580d82b9627d173ceea305ba898dca135feb360b6d84019d0803d3b/pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b", size = 220560 }, ] [[package]] @@ -1157,16 +1159,16 @@ wheels = [ [[package]] name = "pydantic" -version = "2.10.5" +version = "2.10.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/c7/ca334c2ef6f2e046b1144fe4bb2a5da8a4c574e7f2ebf7e16b34a6a2fa92/pydantic-2.10.5.tar.gz", hash = "sha256:278b38dbbaec562011d659ee05f63346951b3a248a6f3642e1bc68894ea2b4ff", size = 761287 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } wheels = [ - { url = "https://files.pythonhosted.org/packages/58/26/82663c79010b28eddf29dcdd0ea723439535fa917fce5905885c0e9ba562/pydantic-2.10.5-py3-none-any.whl", hash = "sha256:4dd4e322dbe55472cb7ca7e73f4b63574eecccf2835ffa2af9021ce113c83c53", size = 431426 }, + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, ] [package.optional-dependencies] @@ -1378,7 +1380,7 @@ wheels = [ [[package]] name = "realtime" -version = "2.1.0" +version = "2.2.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "aiohttp" }, @@ -1386,9 +1388,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "websockets" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/c7/f7c93b658d486c393c33211e44ef56aba625df570ee93e97bda073483177/realtime-2.1.0.tar.gz", hash = "sha256:ca3ae6be47667a3cf3a307fec982ec1bf60313c38a8e29f016ab0380b76d7adb", size = 18207 } +sdist = { url = "https://files.pythonhosted.org/packages/4f/63/e73d41f69ae597e73437332c017eb5c1afc07123439c4e8fb2a150b5c684/realtime-2.2.0.tar.gz", hash = "sha256:f87a51b6b8dd8c72c30af6c841e0161132dcb32bf8b96178f3fe3866d575ef33", size = 18288 } wheels = [ - { url = "https://files.pythonhosted.org/packages/1c/d5/77d42647c73e328a705881d5466f2df3d8f6d63e60be212538779a9c2473/realtime-2.1.0-py3-none-any.whl", hash = "sha256:e2d4f28bb2a08c1cf80e40fbf31e6116544ad29d67dd4093093e511ad738708c", size = 21438 }, + { url = "https://files.pythonhosted.org/packages/89/81/deb1a8b598e4ae8abdb197ff62d80dd9bbe472dd3cbebe1a72977832d57f/realtime-2.2.0-py3-none-any.whl", hash = "sha256:26dbaa58d143345318344bd7a7d4dc67154d6e0e9c98524327053a78bb3cc6b6", size = 21469 }, ] [[package]] @@ -1506,27 +1508,27 @@ wheels = [ [[package]] name = "starlette" -version = "0.41.3" +version = "0.45.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/1a/4c/9b5764bd22eec91c4039ef4c55334e9187085da2d8a2df7bd570869aae18/starlette-0.41.3.tar.gz", hash = "sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", size = 2574159 } +sdist = { url = "https://files.pythonhosted.org/packages/ff/fb/2984a686808b89a6781526129a4b51266f678b2d2b97ab2d325e56116df8/starlette-0.45.3.tar.gz", hash = "sha256:2cbcba2a75806f8a41c722141486f37c28e30a0921c5f6fe4346cb0dcee1302f", size = 2574076 } wheels = [ - { url = "https://files.pythonhosted.org/packages/96/00/2b325970b3060c7cecebab6d295afe763365822b1306a12eeab198f74323/starlette-0.41.3-py3-none-any.whl", hash = "sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7", size = 73225 }, + { url = "https://files.pythonhosted.org/packages/d9/61/f2b52e107b1fc8944b33ef56bf6ac4ebbe16d91b94d2b87ce013bf63fb84/starlette-0.45.3-py3-none-any.whl", hash = "sha256:dfb6d332576f136ec740296c7e8bb8c8a7125044e7c6da30744718880cdd059d", size = 71507 }, ] [[package]] name = "storage3" -version = "0.11.0" +version = "0.11.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "httpx", extra = ["http2"] }, { name = "python-dateutil" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6b/9f/fa5ce927735f04610038de5864fcdb0a4fc8cd74ac1dc2d223ffda4fffd1/storage3-0.11.0.tar.gz", hash = "sha256:243583f2180686c0f0a19e6117d8a9796fd60c0ca72ec567d62b75a5af0d57a1", size = 9706 } +sdist = { url = "https://files.pythonhosted.org/packages/6d/0a/94a6484b03592f4cdc59208aae7a4c494aec1365fad7e7f09c3e63c2650e/storage3-0.11.1.tar.gz", hash = "sha256:b3bca07108f7077d406d49ef0ddd6805fe22f94fafc186c56bf3a1e2761291f3", size = 9781 } wheels = [ - { url = "https://files.pythonhosted.org/packages/57/cc/7f734e0264edd0e5ef78dc49d859b4207c06da895fee62345a7e80ec041a/storage3-0.11.0-py3-none-any.whl", hash = "sha256:de2d8f9c9103ca91a9a9d0d69d80b07a3ab6f647b93e023e6a1a97d3607b9728", size = 17428 }, + { url = "https://files.pythonhosted.org/packages/03/35/26e802688ca6ff5a6100df620d0d1fa4810ee2bcfd846745db360b0ca519/storage3-0.11.1-py3-none-any.whl", hash = "sha256:a8dcfd1472ff1238c0f4a6a725d7a579f132762539c5395dc1e91806b4e20e45", size = 17572 }, ] [[package]] @@ -1540,7 +1542,7 @@ wheels = [ [[package]] name = "supabase" -version = "2.11.0" +version = "2.12.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "gotrue" }, @@ -1550,9 +1552,9 @@ dependencies = [ { name = "storage3" }, { name = "supafunc" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/66/10/36f47454f9d2c2a9be0c2378966bf04a7886ee4e137d3e008b2a9d9407dd/supabase-2.11.0.tar.gz", hash = "sha256:2a906f7909fd9a50f944cd9332ce66c684e2d37c0864284d34c5815e6c63cc01", size = 13924 } +sdist = { url = "https://files.pythonhosted.org/packages/26/d0/1dac1f26ed34736589e5c6c6be6eec0199f7268e72601713e07dcfdad6d2/supabase-2.12.0.tar.gz", hash = "sha256:284612c3e94ff4ed2f18c985f5eba4d6e17b5e2bf16a9a24290bb83c9c217078", size = 13942 } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/8b/c90649307e9b9f43a271308abbe61b8a90a72c3d24d44154fd150b4c31fc/supabase-2.11.0-py3-none-any.whl", hash = "sha256:67a0da498895f4cd6554935e2854b4c41f87b297b78fb9c9414902a382041406", size = 16629 }, + { url = "https://files.pythonhosted.org/packages/9c/96/d6cbfb6cb679ab1ebe8bae4ed5e8763f615f0a12493b1470fe6a2f9ca51d/supabase-2.12.0-py3-none-any.whl", hash = "sha256:f8896f3314179fdf27f8bb8357947493ec32b98dcdac7114208aaf21cd59ce35", size = 16632 }, ] [[package]] From 61351fad080ab561f449dc3282438204787c3913 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 29 Jan 2025 16:36:34 +0800 Subject: [PATCH 47/65] chore: update pre-commit and ruff --- .pre-commit-config.yaml | 34 ++++++++++++++++++++-------------- backend/pyproject.toml | 1 - 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3cbcd68..c543679 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -8,44 +8,50 @@ repos: hooks: - id: check-toml - id: check-yaml - args: ["--unsafe"] + - id: sort-simple-yaml - id: check-json + - id: pretty-format-json + args: [--autofix, --no-sort-keys ] - id: check-added-large-files - args: ["--maxkb=51200"] - - id: debug-statements + args: [--maxkb=51200] - id: end-of-file-fixer - id: trailing-whitespace - id: detect-private-key - - id: destroyed-symlinks - - id: check-vcs-permalinks - # spell check + - repo: https://github.com/codespell-project/codespell rev: v2.3.0 hooks: - id: codespell - files: \.(py|sh|rst|yml|yaml|md)$ args: [--write-changes] - # lint and format + files: \.(py|sh|json|yml|yaml|md)$ + - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.9.2 hooks: - # Run the linter. - id: ruff - args: [ --fix ] - # Run the formatter. + args: [--fix] - id: ruff-format + - repo: https://github.com/hadolint/hadolint rev: v2.13.1-beta hooks: - id: hadolint name: Lint Dockerfiles description: Runs hadolint to lint Dockerfiles + entry: hadolint language: system types: ["dockerfile"] - entry: hadolint + + - repo: https://github.com/astral-sh/uv-pre-commit + # uv version. + rev: 0.5.21 + hooks: + # Update the uv lockfile + - id: uv-lock + ci: - # Settings for the https://pre-commit.ci/ continuous integration service - autofix_prs: True autofix_commit_msg: 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks + # Settings for the https://pre-commit.ci/ continuous integration service + autofix_prs: true autoupdate_commit_msg: ⬆ [pre-commit.ci] pre-commit autoupdate autoupdate_schedule: monthly diff --git a/backend/pyproject.toml b/backend/pyproject.toml index feeaf64..d70caa6 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -86,7 +86,6 @@ select = [ "B", # flake8-bugbear "C4", # flake8-comprehensions "UP", # pyupgrade - "ARG001", # unused arguments in functions ] ignore = [ "E501", # line too long, handled by black From baa811cef79fde90d24cd772acb46346302f282c Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 29 Jan 2025 16:42:05 +0800 Subject: [PATCH 48/65] test: 100% coverage test crud --- .env | 4 +- .gitignore | 3 +- .vscode/launch.json | 16 ++ README.md | 1 + backend/app/crud/base.py | 8 - backend/app/crud/crud_item.py | 15 -- backend/scripts/test.sh | 4 + backend/tests/.env | 3 - backend/tests/conftest.py | 49 +++++- backend/tests/crud/test_item.py | 264 +++++++++++--------------------- backend/tests/test_main.py | 10 -- 11 files changed, 162 insertions(+), 215 deletions(-) create mode 100644 .vscode/launch.json delete mode 100644 backend/tests/.env diff --git a/.env b/.env index e721346..987a93e 100644 --- a/.env +++ b/.env @@ -19,10 +19,10 @@ FIRST_SUPERUSER_PASSWORD=admin12345 # API URL SUPABASE_URL=http://localhost:54321 # service_role key -SUPABASE_KEY=eeyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU +SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU # Postgres -# DB URL: postgresql://postgres:postgres@127.0.0.1:54322/postgres +# DB URL: postgresql://postgres:postgres@localhost:54322/postgres POSTGRES_SERVER=localhost POSTGRES_PORT=54322 POSTGRES_DB=postgres diff --git a/.gitignore b/.gitignore index c0dc42e..1445758 100644 --- a/.gitignore +++ b/.gitignore @@ -163,4 +163,5 @@ cython_debug/ .idea/ # VSCode -.vscode/ +.vscode/PythonImportHelper-v2-Completion.json +.vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..2e1ba78 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,16 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Python: Debug Tests", + "type": "debugpy", + "request": "launch", + "program": "${file}", + "purpose": [ + "debug-test" + ], + "console": "integratedTerminal", + "justMyCode": false + } + ] +} diff --git a/README.md b/README.md index 1b5e2a0..6fa6bcf 100644 --- a/README.md +++ b/README.md @@ -43,3 +43,4 @@ scripts/tests-start.sh ``` 1. [x] test_main.py +2. [x] test_crud/ diff --git a/backend/app/crud/base.py b/backend/app/crud/base.py index fcc39f6..2a5d742 100644 --- a/backend/app/crud/base.py +++ b/backend/app/crud/base.py @@ -68,11 +68,3 @@ async def remove(self, session: AsyncSession, *, id: uuid.UUID) -> ModelType | N await session.delete(obj) await session.commit() return obj - - async def get_multi_by_owner( - self, session: AsyncSession, *, owner_id: uuid.UUID - ) -> Sequence[ModelType]: - """Get multiple records by owner""" - statement = select(self.model).where(self.model.owner_id == owner_id) - result = await session.exec(statement) - return result.all() diff --git a/backend/app/crud/crud_item.py b/backend/app/crud/crud_item.py index 1ba2b31..9e58d65 100644 --- a/backend/app/crud/crud_item.py +++ b/backend/app/crud/crud_item.py @@ -1,5 +1,4 @@ import uuid -from collections.abc import Sequence from sqlmodel.ext.asyncio.session import AsyncSession @@ -13,24 +12,10 @@ async def create( ) -> Item: return await super().create(session, owner_id=owner_id, obj_in=obj_in) - async def get(self, session: AsyncSession, *, id: uuid.UUID) -> Item | None: - return await super().get(session, id=id) - - async def get_all(self, session: AsyncSession) -> Sequence[Item]: - return await super().get_multi(session) - - async def get_multi_by_owner( - self, session: AsyncSession, *, owner_id: uuid.UUID - ) -> Sequence[Item]: - return await super().get_multi_by_owner(session, owner_id=owner_id) - async def update( self, session: AsyncSession, *, id: uuid.UUID, obj_in: ItemUpdate ) -> Item | None: return await super().update(session, id=id, obj_in=obj_in) - async def remove(self, session: AsyncSession, *, id: uuid.UUID) -> Item | None: - return await super().remove(session, id=id) - item = CRUDItem(Item) diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh index df23f70..8f2cd49 100755 --- a/backend/scripts/test.sh +++ b/backend/scripts/test.sh @@ -3,6 +3,10 @@ set -e set -x +# Enable asyncio debug mode +# Ref: https://github.com/Kludex/fastapi-tips?tab=readme-ov-file#7-enable-asyncio-debug-mode +export PYTHONASYNCIODEBUG=1 + coverage run --source=app -m pytest coverage report --show-missing coverage html --title "${@-coverage}" diff --git a/backend/tests/.env b/backend/tests/.env deleted file mode 100644 index a01f9ae..0000000 --- a/backend/tests/.env +++ /dev/null @@ -1,3 +0,0 @@ -SUPABASE_TEST_URL=http://localhost:54321 - -SUPABASE_TEST_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 2fea6b1..f4ff62f 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,11 +1,17 @@ +import uuid from collections.abc import AsyncGenerator import pytest +from faker import Faker from httpx import ASGITransport, AsyncClient +from sqlmodel import delete from sqlmodel.ext.asyncio.session import AsyncSession -from app.core.db import engine +from app import crud +from app.core.auth import get_super_client +from app.core.db import engine, init_db from app.main import app +from app.models.item import Item, ItemCreate @pytest.fixture(scope="module") @@ -16,9 +22,11 @@ def anyio_backend() -> str: @pytest.fixture(scope="module") async def db() -> AsyncGenerator[AsyncSession, None]: async with AsyncSession(engine) as session: - async with session.begin(): - yield session - await session.rollback() + await init_db(session) + yield session + statement = delete(Item) + await session.exec(statement) # type: ignore + await session.commit() @pytest.fixture(scope="module") @@ -32,6 +40,39 @@ async def client(): yield ac +fake = Faker() + + +@pytest.fixture(scope="function") +async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: + """Fixture to create a test user""" + + super_client = await get_super_client() + + try: + response = await super_client.auth.admin.create_user( + {"email": fake.email(), "password": "testpassword123"} + ) + yield uuid.UUID(response.user.id) + finally: + # clean users + users = await super_client.auth.admin.list_users() + for user in users: + await super_client.auth.admin.delete_user(user.id) + + +@pytest.fixture(scope="function") +async def test_item( + db: AsyncSession, test_user_id: uuid.UUID +) -> AsyncGenerator[Item, None]: + """Fixture to create a test item and clean it up after the test""" + item_in = ItemCreate( + title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) + ) + item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + yield item + + # @pytest.fixture(scope="module") # async def token() -> AsyncGenerator[Token, None]: # url = os.environ.get("SUPABASE_TEST_URL") diff --git a/backend/tests/crud/test_item.py b/backend/tests/crud/test_item.py index 2eef006..d950c07 100644 --- a/backend/tests/crud/test_item.py +++ b/backend/tests/crud/test_item.py @@ -1,172 +1,92 @@ -# import uuid -# from collections.abc import AsyncGenerator - -# import pytest -# from faker import Faker -# from sqlmodel import select -# from sqlmodel.ext.asyncio.session import AsyncSession - -# from app import crud -# from app.core.auth import get_super_client -# from app.models import User as UserInDB -# from app.models.item import Item, ItemCreate, ItemUpdate - -# fake = Faker() - - -# @pytest.fixture(scope="module") -# async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: -# """Fixture to create a test user""" -# super_client = await get_super_client() -# try: -# response = await super_client.auth.sign_up( -# {"email": fake.email(), "password": "testpassword123"} -# ) -# yield uuid.UUID(response.user.id) -# finally: -# result = await db.exec( -# select(UserInDB).where(str(UserInDB.id) == response.user.id) -# ) -# user = result.first() -# if user: -# await db.delete(user) -# await db.commit() - - -# @pytest.fixture -# async def test_item( -# db: AsyncSession, test_user_id: uuid.UUID -# ) -> AsyncGenerator[Item, None]: -# """Fixture to create a test item and clean it up after the test""" -# item_in = ItemCreate( -# title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) -# ) -# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) -# yield item -# # Cleanup -# await crud.item.remove(db, id=item.id) - - -# @pytest.mark.anyio -# async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: -# """Test creating a new item""" -# title = fake.sentence(nb_words=3) -# description = fake.text(max_nb_chars=200) -# item_in = ItemCreate(title=title, description=description) - -# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) - -# assert item.id is not None -# assert item.title == title -# assert item.description == description -# assert item.owner_id == test_user_id - -# # Cleanup -# await crud.item.remove(db, id=item.id) - - -# @pytest.mark.anyio -# async def test_get_item(db: AsyncSession, test_item: Item) -> None: -# """Test retrieving a single item""" -# stored_item = await crud.item.get(db, id=test_item.id) - -# assert stored_item is not None -# assert stored_item.id == test_item.id -# assert stored_item.title == test_item.title -# assert stored_item.description == test_item.description -# assert stored_item.owner_id == test_item.owner_id - - -# @pytest.mark.anyio -# async def test_get_nonexistent_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: -# """Test retrieving a non-existent item""" -# nonexistent_item = await crud.item.get(db, id=test_user_id) -# assert nonexistent_item is None - - -# @pytest.mark.anyio -# async def test_update_item(db: AsyncSession, test_item: Item) -> None: -# """Test updating an item""" -# new_title = fake.sentence(nb_words=3) -# new_description = fake.text(max_nb_chars=200) -# update_data = ItemUpdate(title=new_title, description=new_description) - -# updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) - -# assert updated_item is not None -# assert updated_item.id == test_item.id -# assert updated_item.title == new_title -# assert updated_item.description == new_description -# assert updated_item.owner_id == test_item.owner_id - - -# @pytest.mark.anyio -# async def test_update_nonexistent_item( -# db: AsyncSession, test_user_id: uuid.UUID -# ) -> None: -# """Test updating a non-existent item""" -# update_data = ItemUpdate(title=fake.sentence(nb_words=3)) -# updated_item = await crud.item.update(db, id=test_user_id, obj_in=update_data) -# assert updated_item is None - - -# @pytest.mark.anyio -# async def test_delete_item(db: AsyncSession, test_item: Item) -> None: -# """Test deleting an item""" -# deleted_item = await crud.item.remove(db, id=test_item.id) -# assert deleted_item is not None -# assert deleted_item.id == test_item.id - -# # Verify item is deleted -# item = await crud.item.get(db, id=test_item.id) -# assert item is None - - -# @pytest.mark.anyio -# async def test_get_multi_by_owner(db: AsyncSession, test_user_id: uuid.UUID) -> None: -# """Test retrieving multiple items by owner""" -# # Create multiple items for the same owner -# items_data = [ -# ItemCreate(title=fake.sentence(nb_words=3), description=fake.text()) -# for _ in range(3) -# ] -# created_items = [] -# for item_data in items_data: -# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_data) -# created_items.append(item) - -# # Retrieve items by owner -# items = await crud.item.get_multi_by_owner(db, owner_id=test_user_id) - -# assert len(items) == len(created_items) -# assert all(item.owner_id == test_user_id for item in items) - -# # Cleanup -# for item in created_items: -# await crud.item.remove(db, id=item.id) - - -# @pytest.mark.anyio -# async def test_get_all_items(db: AsyncSession, test_user_id: uuid.UUID) -> None: -# """Test retrieving all items with pagination""" -# # Create multiple items -# items_data = [ -# ItemCreate(title=fake.sentence(nb_words=3), description=fake.text()) -# for _ in range(5) -# ] -# created_items = [] -# for item_data in items_data: -# item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_data) -# created_items.append(item) - -# # Test pagination -# items_page_1 = await crud.item.get_multi(db, skip=0, limit=3) -# items_page_2 = await crud.item.get_multi(db, skip=3, limit=3) - -# assert len(items_page_1) == 3 -# assert len(items_page_2) == 2 - -# # Cleanup -# for item in created_items: -# await crud.item.remove(db, id=item.id) -# await db.commit() +import uuid + +import pytest +from faker import Faker +from sqlmodel.ext.asyncio.session import AsyncSession + +from app import crud +from app.models.item import Item, ItemCreate, ItemUpdate + +fake = Faker() + + +@pytest.mark.anyio +async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: + """Test creating a new item""" + title = fake.sentence(nb_words=3) + description = fake.text(max_nb_chars=200) + item_in = ItemCreate(title=title, description=description) + + item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + + assert item.id is not None + assert item.title == title + assert item.description == description + assert item.owner_id == test_user_id + + +@pytest.mark.anyio +async def test_get_item(db: AsyncSession, test_item: Item) -> None: + """Test retrieving a single item""" + stored_item = await crud.item.get(db, id=test_item.id) + + assert stored_item is not None + assert stored_item.id == test_item.id + assert stored_item.title == test_item.title + assert stored_item.description == test_item.description + assert stored_item.owner_id == test_item.owner_id + + +@pytest.mark.anyio +async def test_get_multi_items(db: AsyncSession, test_user_id: uuid.UUID) -> None: + """Test retrieving multiple items""" + # Create multiple items + items = [] + for _ in range(5): + item_in = ItemCreate( + title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) + ) + item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + items.append(item) + # Retrieve multiple items + stored_items = await crud.item.get_multi(db) + assert len(stored_items) == 5 + # Verify all items are in the list + for item in items: + assert item in stored_items + + +@pytest.mark.anyio +async def test_update_item(db: AsyncSession, test_item: Item) -> None: + """Test updating an item""" + new_title = fake.sentence(nb_words=3) + new_description = fake.text(max_nb_chars=200) + update_data = ItemUpdate(title=new_title, description=new_description) + + updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) + + assert updated_item is not None + assert updated_item.id == test_item.id + assert updated_item.title == new_title + assert updated_item.description == new_description + assert updated_item.owner_id == test_item.owner_id + + # update with empty data + updated_item = await crud.item.update(db, id=uuid.uuid4(), obj_in=update_data) + assert updated_item is None + + +@pytest.mark.anyio +async def test_delete_item(db: AsyncSession, test_item: Item) -> None: + """Test deleting an item""" + deleted_item = await crud.item.remove(db, id=test_item.id) + assert deleted_item is not None + assert deleted_item.id == test_item.id + + # Verify item is deleted + item = await crud.item.get(db, id=test_item.id) + assert item is None + + # delete empty items + deleted_item = await crud.item.remove(db, id=test_item.id) + assert deleted_item is None diff --git a/backend/tests/test_main.py b/backend/tests/test_main.py index 827fe72..56625ba 100644 --- a/backend/tests/test_main.py +++ b/backend/tests/test_main.py @@ -3,20 +3,10 @@ import pytest from httpx import AsyncClient -from app.core.db import engine -from app.utils.init_data import init as init_db -from app.utils.test_pre_start import init as connect_db - logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -@pytest.mark.anyio -async def test_init_db() -> None: - await connect_db(engine) - await init_db(engine) - - @pytest.mark.anyio async def test_root(client: AsyncClient) -> None: response = await client.get("/") From 949937ea0cb161113e3bbc9e5b2dfb6d2f657671 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Wed, 29 Jan 2025 18:37:50 +0800 Subject: [PATCH 49/65] test: add fastapi debug config --- .vscode/launch.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 2e1ba78..95d2b60 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,6 +1,18 @@ { "version": "0.2.0", "configurations": [ + { + "name": "Debug FastAPI Project backend", + "type": "debugpy", + "request": "launch", + "module": "fastapi", + "args": [ + "dev", + "app/main.py" + ], + "cwd": "${workspaceFolder}/backend", + "envFile": "${workspaceFolder}/.env" + }, { "name": "Python: Debug Tests", "type": "debugpy", From fe535bde55bdb96e0e86f5cad97d26071fda862c Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 11:28:35 +0800 Subject: [PATCH 50/65] refactor: using sync db orm --- backend/app/api/deps.py | 4 +- backend/app/core/config.py | 5 +- backend/app/core/db.py | 26 ++--- backend/app/utils/init_data.py | 13 ++- backend/app/utils/test_pre_start.py | 15 ++- backend/pyproject.toml | 14 +-- backend/uv.lock | 145 +++++++++++++++++++--------- 7 files changed, 130 insertions(+), 92 deletions(-) diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py index d7eec92..f0b7266 100644 --- a/backend/app/api/deps.py +++ b/backend/app/api/deps.py @@ -1,7 +1,7 @@ from typing import Annotated from fastapi import Depends -from sqlmodel import Session +from sqlmodel.ext.asyncio.session import AsyncSession from app.core.auth import get_current_user from app.core.db import get_db @@ -10,4 +10,4 @@ CurrentUser = Annotated[UserIn, Depends(get_current_user)] -SessionDep = Annotated[Session, Depends(get_db)] +SessionDep = Annotated[AsyncSession, Depends(get_db)] diff --git a/backend/app/core/config.py b/backend/app/core/config.py index 1263d85..f7d0f6f 100644 --- a/backend/app/core/config.py +++ b/backend/app/core/config.py @@ -66,9 +66,8 @@ def all_cors_origins(self) -> list[str]: @computed_field # type: ignore[prop-decorator] @property def SQLALCHEMY_DATABASE_URI(self) -> PostgresDsn: - return MultiHostUrl.build( - # scheme="postgresql+psycopg", - scheme="postgresql+asyncpg", + return MultiHostUrl.build( # type:ignore + scheme="postgresql+psycopg", username=self.POSTGRES_USER, password=self.POSTGRES_PASSWORD, host=self.POSTGRES_SERVER, diff --git a/backend/app/core/db.py b/backend/app/core/db.py index 2061407..437422b 100644 --- a/backend/app/core/db.py +++ b/backend/app/core/db.py @@ -1,10 +1,8 @@ -from collections.abc import AsyncGenerator +from collections.abc import Generator -from sqlalchemy.ext.asyncio import create_async_engine -from sqlmodel import select -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlmodel import Session, create_engine, select +from supabase import create_client -from app.core.auth import get_super_client from app.core.config import settings from app.models import User @@ -12,17 +10,15 @@ # otherwise, SQLModel might fail to initialize relationships properly # for more details: https://github.com/fastapi/full-stack-fastapi-template/issues/28 -engine = create_async_engine( - str(settings.SQLALCHEMY_DATABASE_URI), echo=True, future=True -) +engine = create_engine(str(settings.SQLALCHEMY_DATABASE_URI)) -async def get_db() -> AsyncGenerator[AsyncSession, None]: - async with AsyncSession(engine) as session: +def get_db() -> Generator[Session, None]: + with Session(engine) as session: yield session -async def init_db(session: AsyncSession) -> None: +def init_db(session: Session) -> None: # Tables should be created with Alembic migrations # But if you don't want to use migrations, create # the tables un-commenting the next lines @@ -30,13 +26,11 @@ async def init_db(session: AsyncSession) -> None: # # This works because the models are already imported and registered from app.models # SQLModel.metadata.create_all(engine) - result = await session.exec( - select(User).where(User.email == settings.FIRST_SUPERUSER) - ) + result = session.exec(select(User).where(User.email == settings.FIRST_SUPERUSER)) user = result.first() if not user: - super_client = await get_super_client() - response = await super_client.auth.sign_up( + super_client = create_client(settings.SUPABASE_URL, settings.SUPABASE_KEY) + response = super_client.auth.sign_up( { "email": settings.FIRST_SUPERUSER, "password": settings.FIRST_SUPERUSER_PASSWORD, diff --git a/backend/app/utils/init_data.py b/backend/app/utils/init_data.py index 99da629..b9d9380 100644 --- a/backend/app/utils/init_data.py +++ b/backend/app/utils/init_data.py @@ -1,8 +1,7 @@ -import asyncio import logging -from sqlalchemy.ext.asyncio import AsyncEngine -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlalchemy import Engine +from sqlmodel import Session from app.core.db import engine, init_db @@ -10,14 +9,14 @@ logger = logging.getLogger(__name__) -async def init(db_ngine: AsyncEngine) -> None: - async with AsyncSession(db_ngine) as session: - await init_db(session) +def init(db_engine: Engine) -> None: + with Session(db_engine) as session: + init_db(session) def main() -> None: logger.info("Creating initial data") - asyncio.run(init(engine)) + init(engine) logger.info("Initial data created") diff --git a/backend/app/utils/test_pre_start.py b/backend/app/utils/test_pre_start.py index 3b201f0..c2f8e29 100644 --- a/backend/app/utils/test_pre_start.py +++ b/backend/app/utils/test_pre_start.py @@ -1,9 +1,7 @@ -import asyncio import logging -from sqlalchemy.ext.asyncio import AsyncEngine -from sqlmodel import select -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlalchemy import Engine +from sqlmodel import Session, select from tenacity import after_log, before_log, retry, stop_after_attempt, wait_fixed from app.core.db import engine @@ -21,10 +19,11 @@ before=before_log(logger, logging.INFO), after=after_log(logger, logging.WARN), ) -async def init(db_engine: AsyncEngine) -> None: +def init(db_engine: Engine) -> None: try: - async with AsyncSession(db_engine) as session: - await session.exec(select(1)) + with Session(db_engine) as session: + # Try to create session to check if DB is awake + session.exec(select(1)) except Exception as e: logger.error(e) raise e @@ -32,7 +31,7 @@ async def init(db_engine: AsyncEngine) -> None: def main() -> None: logger.info("Initializing service") - asyncio.run(init(engine)) + init(engine) logger.info("Service finished initializing") diff --git a/backend/pyproject.toml b/backend/pyproject.toml index d70caa6..a60bad0 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -10,15 +10,15 @@ dependencies = [ "supabase>=2.7.4", "fastapi[standard]>=0.112.2", "sqlmodel>=0.0.22", - "asyncpg>=0.30.0", "alembic>=1.14.0", "tenacity>=9.0.0", "psycopg2-binary>=2.9.10", + "psycopg>=3.2.4", ] [dependency-groups] dev = [ - "anyio>=4.6.2.post1", + "anyio[trio]>=4.6.2.post1", "coverage>=7.6.1", "faker>=28.0.0", "mypy>=1.13.0", @@ -38,13 +38,9 @@ strict = true exclude = ["venv", ".venv", "alembic"] [tool.pytest.ini_options] -# Set additional command line options for pytest= -# -r= show extra test summary info -# X= show extra info on xfailed tests -# s= don't capture stdout (allow print statements) -# --strict-config= any warnings about configuration are treated as errors -# --strict-markers= treat unregistered markers as errors -addopts = "-rXs --strict-config --strict-markers" +# Set additional command line options for pytest +# Ref: https://docs.pytest.org/en/stable/reference/reference.html#command-line-flags +addopts = "-rXs --strict-config --strict-markers --tb=short" xfail_strict = true # Treat tests that are marked as xfail but pass as test failures filterwarnings = ["error"] # Treat all warnings as errors pythonpath = "app" diff --git a/backend/uv.lock b/backend/uv.lock index 264a80a..5217704 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -138,14 +138,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, ] +[package.optional-dependencies] +trio = [ + { name = "trio" }, +] + [[package]] name = "app" version = "0.4.1" source = { editable = "." } dependencies = [ { name = "alembic" }, - { name = "asyncpg" }, { name = "fastapi", extra = ["standard"] }, + { name = "psycopg" }, { name = "psycopg2-binary" }, { name = "pydantic", extra = ["email"] }, { name = "pydantic-settings" }, @@ -158,7 +163,7 @@ dependencies = [ [package.dev-dependencies] dev = [ - { name = "anyio" }, + { name = "anyio", extra = ["trio"] }, { name = "coverage" }, { name = "faker" }, { name = "httpx" }, @@ -171,8 +176,8 @@ dev = [ [package.metadata] requires-dist = [ { name = "alembic", specifier = ">=1.14.0" }, - { name = "asyncpg", specifier = ">=0.30.0" }, { name = "fastapi", extras = ["standard"], specifier = ">=0.112.2" }, + { name = "psycopg", specifier = ">=3.2.4" }, { name = "psycopg2-binary", specifier = ">=2.9.10" }, { name = "pydantic", extras = ["email"], specifier = ">=2.8.2" }, { name = "pydantic-settings", specifier = ">=2.4.0" }, @@ -185,7 +190,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "anyio", specifier = ">=4.6.2.post1" }, + { name = "anyio", extras = ["trio"], specifier = ">=4.6.2.post1" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "faker", specifier = ">=28.0.0" }, { name = "httpx", specifier = ">=0.28.1" }, @@ -204,49 +209,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/fe/ba/e2081de779ca30d473f21f5b30e0e737c438205440784c7dfc81efc2b029/async_timeout-5.0.1-py3-none-any.whl", hash = "sha256:39e3809566ff85354557ec2398b55e096c8364bacac9405a7a1fa429e77fe76c", size = 6233 }, ] -[[package]] -name = "asyncpg" -version = "0.30.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "async-timeout", marker = "python_full_version < '3.11'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/2f/4c/7c991e080e106d854809030d8584e15b2e996e26f16aee6d757e387bc17d/asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851", size = 957746 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/07/1650a8c30e3a5c625478fa8aafd89a8dd7d85999bf7169b16f54973ebf2c/asyncpg-0.30.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfb4dd5ae0699bad2b233672c8fc5ccbd9ad24b89afded02341786887e37927e", size = 673143 }, - { url = "https://files.pythonhosted.org/packages/a0/9a/568ff9b590d0954553c56806766914c149609b828c426c5118d4869111d3/asyncpg-0.30.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:dc1f62c792752a49f88b7e6f774c26077091b44caceb1983509edc18a2222ec0", size = 645035 }, - { url = "https://files.pythonhosted.org/packages/de/11/6f2fa6c902f341ca10403743701ea952bca896fc5b07cc1f4705d2bb0593/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3152fef2e265c9c24eec4ee3d22b4f4d2703d30614b0b6753e9ed4115c8a146f", size = 2912384 }, - { url = "https://files.pythonhosted.org/packages/83/83/44bd393919c504ffe4a82d0aed8ea0e55eb1571a1dea6a4922b723f0a03b/asyncpg-0.30.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c7255812ac85099a0e1ffb81b10dc477b9973345793776b128a23e60148dd1af", size = 2947526 }, - { url = "https://files.pythonhosted.org/packages/08/85/e23dd3a2b55536eb0ded80c457b0693352262dc70426ef4d4a6fc994fa51/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:578445f09f45d1ad7abddbff2a3c7f7c291738fdae0abffbeb737d3fc3ab8b75", size = 2895390 }, - { url = "https://files.pythonhosted.org/packages/9b/26/fa96c8f4877d47dc6c1864fef5500b446522365da3d3d0ee89a5cce71a3f/asyncpg-0.30.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c42f6bb65a277ce4d93f3fba46b91a265631c8df7250592dd4f11f8b0152150f", size = 3015630 }, - { url = "https://files.pythonhosted.org/packages/34/00/814514eb9287614188a5179a8b6e588a3611ca47d41937af0f3a844b1b4b/asyncpg-0.30.0-cp310-cp310-win32.whl", hash = "sha256:aa403147d3e07a267ada2ae34dfc9324e67ccc4cdca35261c8c22792ba2b10cf", size = 568760 }, - { url = "https://files.pythonhosted.org/packages/f0/28/869a7a279400f8b06dd237266fdd7220bc5f7c975348fea5d1e6909588e9/asyncpg-0.30.0-cp310-cp310-win_amd64.whl", hash = "sha256:fb622c94db4e13137c4c7f98834185049cc50ee01d8f657ef898b6407c7b9c50", size = 625764 }, - { url = "https://files.pythonhosted.org/packages/4c/0e/f5d708add0d0b97446c402db7e8dd4c4183c13edaabe8a8500b411e7b495/asyncpg-0.30.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5e0511ad3dec5f6b4f7a9e063591d407eee66b88c14e2ea636f187da1dcfff6a", size = 674506 }, - { url = "https://files.pythonhosted.org/packages/6a/a0/67ec9a75cb24a1d99f97b8437c8d56da40e6f6bd23b04e2f4ea5d5ad82ac/asyncpg-0.30.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:915aeb9f79316b43c3207363af12d0e6fd10776641a7de8a01212afd95bdf0ed", size = 645922 }, - { url = "https://files.pythonhosted.org/packages/5c/d9/a7584f24174bd86ff1053b14bb841f9e714380c672f61c906eb01d8ec433/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c198a00cce9506fcd0bf219a799f38ac7a237745e1d27f0e1f66d3707c84a5a", size = 3079565 }, - { url = "https://files.pythonhosted.org/packages/a0/d7/a4c0f9660e333114bdb04d1a9ac70db690dd4ae003f34f691139a5cbdae3/asyncpg-0.30.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3326e6d7381799e9735ca2ec9fd7be4d5fef5dcbc3cb555d8a463d8460607956", size = 3109962 }, - { url = "https://files.pythonhosted.org/packages/3c/21/199fd16b5a981b1575923cbb5d9cf916fdc936b377e0423099f209e7e73d/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:51da377487e249e35bd0859661f6ee2b81db11ad1f4fc036194bc9cb2ead5056", size = 3064791 }, - { url = "https://files.pythonhosted.org/packages/77/52/0004809b3427534a0c9139c08c87b515f1c77a8376a50ae29f001e53962f/asyncpg-0.30.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bc6d84136f9c4d24d358f3b02be4b6ba358abd09f80737d1ac7c444f36108454", size = 3188696 }, - { url = "https://files.pythonhosted.org/packages/52/cb/fbad941cd466117be58b774a3f1cc9ecc659af625f028b163b1e646a55fe/asyncpg-0.30.0-cp311-cp311-win32.whl", hash = "sha256:574156480df14f64c2d76450a3f3aaaf26105869cad3865041156b38459e935d", size = 567358 }, - { url = "https://files.pythonhosted.org/packages/3c/0a/0a32307cf166d50e1ad120d9b81a33a948a1a5463ebfa5a96cc5606c0863/asyncpg-0.30.0-cp311-cp311-win_amd64.whl", hash = "sha256:3356637f0bd830407b5597317b3cb3571387ae52ddc3bca6233682be88bbbc1f", size = 629375 }, - { url = "https://files.pythonhosted.org/packages/4b/64/9d3e887bb7b01535fdbc45fbd5f0a8447539833b97ee69ecdbb7a79d0cb4/asyncpg-0.30.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c902a60b52e506d38d7e80e0dd5399f657220f24635fee368117b8b5fce1142e", size = 673162 }, - { url = "https://files.pythonhosted.org/packages/6e/eb/8b236663f06984f212a087b3e849731f917ab80f84450e943900e8ca4052/asyncpg-0.30.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aca1548e43bbb9f0f627a04666fedaca23db0a31a84136ad1f868cb15deb6e3a", size = 637025 }, - { url = "https://files.pythonhosted.org/packages/cc/57/2dc240bb263d58786cfaa60920779af6e8d32da63ab9ffc09f8312bd7a14/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c2a2ef565400234a633da0eafdce27e843836256d40705d83ab7ec42074efb3", size = 3496243 }, - { url = "https://files.pythonhosted.org/packages/f4/40/0ae9d061d278b10713ea9021ef6b703ec44698fe32178715a501ac696c6b/asyncpg-0.30.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1292b84ee06ac8a2ad8e51c7475aa309245874b61333d97411aab835c4a2f737", size = 3575059 }, - { url = "https://files.pythonhosted.org/packages/c3/75/d6b895a35a2c6506952247640178e5f768eeb28b2e20299b6a6f1d743ba0/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0f5712350388d0cd0615caec629ad53c81e506b1abaaf8d14c93f54b35e3595a", size = 3473596 }, - { url = "https://files.pythonhosted.org/packages/c8/e7/3693392d3e168ab0aebb2d361431375bd22ffc7b4a586a0fc060d519fae7/asyncpg-0.30.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:db9891e2d76e6f425746c5d2da01921e9a16b5a71a1c905b13f30e12a257c4af", size = 3641632 }, - { url = "https://files.pythonhosted.org/packages/32/ea/15670cea95745bba3f0352341db55f506a820b21c619ee66b7d12ea7867d/asyncpg-0.30.0-cp312-cp312-win32.whl", hash = "sha256:68d71a1be3d83d0570049cd1654a9bdfe506e794ecc98ad0873304a9f35e411e", size = 560186 }, - { url = "https://files.pythonhosted.org/packages/7e/6b/fe1fad5cee79ca5f5c27aed7bd95baee529c1bf8a387435c8ba4fe53d5c1/asyncpg-0.30.0-cp312-cp312-win_amd64.whl", hash = "sha256:9a0292c6af5c500523949155ec17b7fe01a00ace33b68a476d6b5059f9630305", size = 621064 }, - { url = "https://files.pythonhosted.org/packages/3a/22/e20602e1218dc07692acf70d5b902be820168d6282e69ef0d3cb920dc36f/asyncpg-0.30.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05b185ebb8083c8568ea8a40e896d5f7af4b8554b64d7719c0eaa1eb5a5c3a70", size = 670373 }, - { url = "https://files.pythonhosted.org/packages/3d/b3/0cf269a9d647852a95c06eb00b815d0b95a4eb4b55aa2d6ba680971733b9/asyncpg-0.30.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c47806b1a8cbb0a0db896f4cd34d89942effe353a5035c62734ab13b9f938da3", size = 634745 }, - { url = "https://files.pythonhosted.org/packages/8e/6d/a4f31bf358ce8491d2a31bfe0d7bcf25269e80481e49de4d8616c4295a34/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b6fde867a74e8c76c71e2f64f80c64c0f3163e687f1763cfaf21633ec24ec33", size = 3512103 }, - { url = "https://files.pythonhosted.org/packages/96/19/139227a6e67f407b9c386cb594d9628c6c78c9024f26df87c912fabd4368/asyncpg-0.30.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46973045b567972128a27d40001124fbc821c87a6cade040cfcd4fa8a30bcdc4", size = 3592471 }, - { url = "https://files.pythonhosted.org/packages/67/e4/ab3ca38f628f53f0fd28d3ff20edff1c975dd1cb22482e0061916b4b9a74/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9110df111cabc2ed81aad2f35394a00cadf4f2e0635603db6ebbd0fc896f46a4", size = 3496253 }, - { url = "https://files.pythonhosted.org/packages/ef/5f/0bf65511d4eeac3a1f41c54034a492515a707c6edbc642174ae79034d3ba/asyncpg-0.30.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:04ff0785ae7eed6cc138e73fc67b8e51d54ee7a3ce9b63666ce55a0bf095f7ba", size = 3662720 }, - { url = "https://files.pythonhosted.org/packages/e7/31/1513d5a6412b98052c3ed9158d783b1e09d0910f51fbe0e05f56cc370bc4/asyncpg-0.30.0-cp313-cp313-win32.whl", hash = "sha256:ae374585f51c2b444510cdf3595b97ece4f233fde739aa14b50e0d64e8a7a590", size = 560404 }, - { url = "https://files.pythonhosted.org/packages/c8/a4/cec76b3389c4c5ff66301cd100fe88c318563ec8a520e0b2e792b5b84972/asyncpg-0.30.0-cp313-cp313-win_amd64.whl", hash = "sha256:f59b430b8e27557c3fb9869222559f7417ced18688375825f8f12302c34e915e", size = 621623 }, -] - [[package]] name = "attrs" version = "25.1.0" @@ -265,6 +227,25 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, ] +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, +] + [[package]] name = "cfgv" version = "3.4.0" @@ -971,6 +952,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, ] +[[package]] +name = "outcome" +version = "1.3.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 }, +] + [[package]] name = "packaging" version = "24.2" @@ -1102,6 +1095,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/b6/c5319caea262f4821995dca2107483b94a3345d4607ad797c76cb9c36bcc/propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", size = 11818 }, ] +[[package]] +name = "psycopg" +version = "3.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, + { name = "tzdata", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e0/f2/954b1467b3e2ca5945b83b5e320268be1f4df486c3e8ffc90f4e4b707979/psycopg-3.2.4.tar.gz", hash = "sha256:f26f1346d6bf1ef5f5ef1714dd405c67fb365cfd1c6cea07de1792747b167b92", size = 156109 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/49/15114d5f7ee68983f4e1a24d47e75334568960352a07c6f0e796e912685d/psycopg-3.2.4-py3-none-any.whl", hash = "sha256:43665368ccd48180744cab26b74332f46b63b7e06e8ce0775547a3533883d381", size = 198716 }, +] + [[package]] name = "psycopg2-binary" version = "2.9.10" @@ -1157,6 +1163,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, ] +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + [[package]] name = "pydantic" version = "2.10.6" @@ -1448,6 +1463,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] +[[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 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, +] + [[package]] name = "sqlalchemy" version = "2.0.37" @@ -1627,6 +1651,24 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] +[[package]] +name = "trio" +version = "0.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "cffi", marker = "implementation_name != 'pypy' and os_name == 'nt'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "outcome" }, + { name = "sniffio" }, + { name = "sortedcontainers" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/73/57efab729506a8d4b89814f1e356ec8f3369de0ed4fd7e7616974d09646d/trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", size = 580318 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/04/9954a59e1fb6732f5436225c9af963811d7b24ea62a8bf96991f2cb8c26e/trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94", size = 486317 }, +] + [[package]] name = "typer" version = "0.15.1" @@ -1651,6 +1693,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, ] +[[package]] +name = "tzdata" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/0f/fa4723f22942480be4ca9527bbde8d43f6c3f2fe8412f00e7f5f6746bc8b/tzdata-2025.1.tar.gz", hash = "sha256:24894909e88cdb28bd1636c6887801df64cb485bd593f2fd83ef29075a81d694", size = 194950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/dd/84f10e23edd882c6f968c21c2434fe67bd4a528967067515feca9e611e5e/tzdata-2025.1-py2.py3-none-any.whl", hash = "sha256:7e127113816800496f027041c570f50bcd464a020098a3b6b199517772303639", size = 346762 }, +] + [[package]] name = "uvicorn" version = "0.34.0" From 63432b3220a7e4b30a1ed7e8e48849d2376458d0 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 11:58:56 +0800 Subject: [PATCH 51/65] refactor: using sync crud --- backend/app/crud/base.py | 39 ++++++------- backend/app/crud/crud_item.py | 14 ++--- backend/tests/conftest.py | 100 ++++++++++++-------------------- backend/tests/crud/test_item.py | 41 ++++++------- 4 files changed, 81 insertions(+), 113 deletions(-) diff --git a/backend/app/crud/base.py b/backend/app/crud/base.py index 2a5d742..e520db6 100644 --- a/backend/app/crud/base.py +++ b/backend/app/crud/base.py @@ -2,8 +2,7 @@ from collections.abc import Sequence from typing import Generic, TypeVar -from sqlmodel import SQLModel, select -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlmodel import Session, SQLModel, select from app.models.base import InDBBase @@ -23,48 +22,48 @@ def __init__(self, model: type[ModelType]): """ self.model = model - async def get(self, session: AsyncSession, *, id: uuid.UUID) -> ModelType | None: + def get(self, session: Session, *, id: uuid.UUID) -> ModelType | None: """Get a single record by id""" statement = select(self.model).where(self.model.id == id) - result = await session.exec(statement) + result = session.exec(statement) return result.one_or_none() - async def get_multi( - self, session: AsyncSession, *, skip: int = 0, limit: int = 100 + def get_multi( + self, session: Session, *, skip: int = 0, limit: int = 100 ) -> Sequence[ModelType]: """Get multiple records with pagination""" statement = select(self.model).offset(skip).limit(limit) - result = await session.exec(statement) + result = session.exec(statement) return result.all() - async def create( - self, session: AsyncSession, *, owner_id: uuid.UUID, obj_in: CreateSchemaType + def create( + self, session: Session, *, owner_id: uuid.UUID, obj_in: CreateSchemaType ) -> ModelType: """Create new record""" db_obj = self.model(**dict(owner_id=owner_id, **obj_in.model_dump())) session.add(db_obj) - await session.commit() - await session.refresh(db_obj) + session.commit() + session.refresh(db_obj) return db_obj - async def update( - self, session: AsyncSession, *, id: uuid.UUID, obj_in: UpdateSchemaType + def update( + self, session: Session, *, id: uuid.UUID, obj_in: UpdateSchemaType ) -> ModelType | None: """Update existing record""" - db_obj = await self.get(session, id=id) + db_obj = self.get(session, id=id) if db_obj: update_data = obj_in.model_dump(exclude_unset=True) db_obj.sqlmodel_update(update_data) session.add(db_obj) - await session.commit() - await session.refresh(db_obj) + session.commit() + session.refresh(db_obj) return db_obj - async def remove(self, session: AsyncSession, *, id: uuid.UUID) -> ModelType | None: + def remove(self, session: Session, *, id: uuid.UUID) -> ModelType | None: """Remove a record""" - obj = await self.get(session, id=id) + obj = self.get(session, id=id) if obj: - await session.delete(obj) - await session.commit() + session.delete(obj) + session.commit() return obj diff --git a/backend/app/crud/crud_item.py b/backend/app/crud/crud_item.py index 9e58d65..045dc57 100644 --- a/backend/app/crud/crud_item.py +++ b/backend/app/crud/crud_item.py @@ -1,21 +1,21 @@ import uuid -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlmodel import Session from app.crud.base import CRUDBase from app.models.item import Item, ItemCreate, ItemUpdate class CRUDItem(CRUDBase[Item, ItemCreate, ItemUpdate]): - async def create( - self, session: AsyncSession, *, owner_id: uuid.UUID, obj_in: ItemCreate + def create( + self, session: Session, *, owner_id: uuid.UUID, obj_in: ItemCreate ) -> Item: - return await super().create(session, owner_id=owner_id, obj_in=obj_in) + return super().create(session, owner_id=owner_id, obj_in=obj_in) - async def update( - self, session: AsyncSession, *, id: uuid.UUID, obj_in: ItemUpdate + def update( + self, session: Session, *, id: uuid.UUID, obj_in: ItemUpdate ) -> Item | None: - return await super().update(session, id=id, obj_in=obj_in) + return super().update(session, id=id, obj_in=obj_in) item = CRUDItem(Item) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index f4ff62f..4f77459 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -1,92 +1,68 @@ import uuid -from collections.abc import AsyncGenerator +from collections.abc import Generator import pytest from faker import Faker -from httpx import ASGITransport, AsyncClient -from sqlmodel import delete -from sqlmodel.ext.asyncio.session import AsyncSession +from fastapi.testclient import TestClient +from sqlmodel import Session, delete +from supabase import Client, create_client from app import crud -from app.core.auth import get_super_client +from app.core.config import settings from app.core.db import engine, init_db from app.main import app from app.models.item import Item, ItemCreate +from app.schemas.auth import Token @pytest.fixture(scope="module") -def anyio_backend() -> str: - return "asyncio" +def db() -> Generator[Session, None]: + with Session(engine) as session: + init_db(session) + yield session + statement = delete(Item) + session.exec(statement) # type: ignore + session.commit() @pytest.fixture(scope="module") -async def db() -> AsyncGenerator[AsyncSession, None]: - async with AsyncSession(engine) as session: - await init_db(session) - yield session - statement = delete(Item) - await session.exec(statement) # type: ignore - await session.commit() +def client() -> Generator[TestClient, None, None]: + with TestClient(app) as c: + yield c @pytest.fixture(scope="module") -async def client(): - """async client fixture - Ref: https://fastapi.tiangolo.com/advanced/async-tests/#example - """ - async with AsyncClient( - transport=ASGITransport(app=app), base_url="http://test" - ) as ac: - yield ac +def super_client() -> Generator[Client, None]: + super_client = create_client(settings.SUPABASE_URL, settings.SUPABASE_KEY) + yield super_client + # clean users + users = super_client.auth.admin.list_users() + for user in users: + super_client.auth.admin.delete_user(user.id) fake = Faker() @pytest.fixture(scope="function") -async def test_user_id(db: AsyncSession) -> AsyncGenerator[uuid.UUID, None]: - """Fixture to create a test user""" - - super_client = await get_super_client() - - try: - response = await super_client.auth.admin.create_user( - {"email": fake.email(), "password": "testpassword123"} - ) - yield uuid.UUID(response.user.id) - finally: - # clean users - users = await super_client.auth.admin.list_users() - for user in users: - await super_client.auth.admin.delete_user(user.id) +def test_user_id(super_client: Client) -> Generator[uuid.UUID, None]: + response = super_client.auth.admin.create_user( + {"email": fake.email(), "password": "testpassword123"} + ) + yield uuid.UUID(response.user.id) @pytest.fixture(scope="function") -async def test_item( - db: AsyncSession, test_user_id: uuid.UUID -) -> AsyncGenerator[Item, None]: - """Fixture to create a test item and clean it up after the test""" +def test_item(db: Session, test_user_id: uuid.UUID) -> Generator[Item, None]: item_in = ItemCreate( title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) ) - item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) - yield item - - -# @pytest.fixture(scope="module") -# async def token() -> AsyncGenerator[Token, None]: -# url = os.environ.get("SUPABASE_TEST_URL") -# assert url is not None, "Must provide SUPABASE_TEST_URL environment variable" -# key = os.environ.get("SUPABASE_TEST_KEY") -# assert key is not None, "Must provide SUPABASE_TEST_KEY environment variable" -# db_client = await create_client(url, key) -# fake_email = Faker().email() -# fake_password = Faker().password() -# response = await db_client.auth.sign_up( -# {"email": fake_email, "password": fake_password} -# ) -# assert response.user -# assert response.user.email == fake_email -# assert response.user.id is not None - -# yield Token(access_token=response.session.access_token) + yield crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + + +@pytest.fixture(scope="function") +def token(super_client: Client) -> Generator[Token, None]: + response = super_client.auth.sign_up( + {"email": fake.email(), "password": "testpassword123"} + ) + yield Token(access_token=response.session.access_token) diff --git a/backend/tests/crud/test_item.py b/backend/tests/crud/test_item.py index d950c07..81df747 100644 --- a/backend/tests/crud/test_item.py +++ b/backend/tests/crud/test_item.py @@ -1,8 +1,7 @@ import uuid -import pytest from faker import Faker -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlmodel import Session from app import crud from app.models.item import Item, ItemCreate, ItemUpdate @@ -10,14 +9,13 @@ fake = Faker() -@pytest.mark.anyio -async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: +def test_create_item(db: Session, test_user_id: uuid.UUID) -> None: """Test creating a new item""" title = fake.sentence(nb_words=3) description = fake.text(max_nb_chars=200) item_in = ItemCreate(title=title, description=description) - item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + item = crud.item.create(db, owner_id=test_user_id, obj_in=item_in) assert item.id is not None assert item.title == title @@ -25,10 +23,9 @@ async def test_create_item(db: AsyncSession, test_user_id: uuid.UUID) -> None: assert item.owner_id == test_user_id -@pytest.mark.anyio -async def test_get_item(db: AsyncSession, test_item: Item) -> None: +def test_get_item(db: Session, test_item: Item) -> None: """Test retrieving a single item""" - stored_item = await crud.item.get(db, id=test_item.id) + stored_item = crud.item.get(db, id=test_item.id) assert stored_item is not None assert stored_item.id == test_item.id @@ -37,8 +34,7 @@ async def test_get_item(db: AsyncSession, test_item: Item) -> None: assert stored_item.owner_id == test_item.owner_id -@pytest.mark.anyio -async def test_get_multi_items(db: AsyncSession, test_user_id: uuid.UUID) -> None: +def test_get_multi_items(db: Session, test_user_id: uuid.UUID) -> None: """Test retrieving multiple items""" # Create multiple items items = [] @@ -46,24 +42,22 @@ async def test_get_multi_items(db: AsyncSession, test_user_id: uuid.UUID) -> Non item_in = ItemCreate( title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) ) - item = await crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + item = crud.item.create(db, owner_id=test_user_id, obj_in=item_in) items.append(item) # Retrieve multiple items - stored_items = await crud.item.get_multi(db) - assert len(stored_items) == 5 + stored_items = crud.item.get_multi(db) # Verify all items are in the list - for item in items: - assert item in stored_items + assert all(item in stored_items for item in items) -@pytest.mark.anyio -async def test_update_item(db: AsyncSession, test_item: Item) -> None: + +def test_update_item(db: Session, test_item: Item) -> None: """Test updating an item""" new_title = fake.sentence(nb_words=3) new_description = fake.text(max_nb_chars=200) update_data = ItemUpdate(title=new_title, description=new_description) - updated_item = await crud.item.update(db, id=test_item.id, obj_in=update_data) + updated_item = crud.item.update(db, id=test_item.id, obj_in=update_data) assert updated_item is not None assert updated_item.id == test_item.id @@ -72,21 +66,20 @@ async def test_update_item(db: AsyncSession, test_item: Item) -> None: assert updated_item.owner_id == test_item.owner_id # update with empty data - updated_item = await crud.item.update(db, id=uuid.uuid4(), obj_in=update_data) + updated_item = crud.item.update(db, id=uuid.uuid4(), obj_in=update_data) assert updated_item is None -@pytest.mark.anyio -async def test_delete_item(db: AsyncSession, test_item: Item) -> None: +def test_delete_item(db: Session, test_item: Item) -> None: """Test deleting an item""" - deleted_item = await crud.item.remove(db, id=test_item.id) + deleted_item = crud.item.remove(db, id=test_item.id) assert deleted_item is not None assert deleted_item.id == test_item.id # Verify item is deleted - item = await crud.item.get(db, id=test_item.id) + item = crud.item.get(db, id=test_item.id) assert item is None # delete empty items - deleted_item = await crud.item.remove(db, id=test_item.id) + deleted_item = crud.item.remove(db, id=test_item.id) assert deleted_item is None From 6ddcfddf71a3d747dc880f94b4a2940e81758e15 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 12:54:00 +0800 Subject: [PATCH 52/65] chore: remove asyncio debug in pytest --- backend/scripts/test.sh | 4 ---- 1 file changed, 4 deletions(-) diff --git a/backend/scripts/test.sh b/backend/scripts/test.sh index 8f2cd49..df23f70 100755 --- a/backend/scripts/test.sh +++ b/backend/scripts/test.sh @@ -3,10 +3,6 @@ set -e set -x -# Enable asyncio debug mode -# Ref: https://github.com/Kludex/fastapi-tips?tab=readme-ov-file#7-enable-asyncio-debug-mode -export PYTHONASYNCIODEBUG=1 - coverage run --source=app -m pytest coverage report --show-missing coverage html --title "${@-coverage}" From e822040df779524a623373ef3cac4c4555f1e8f4 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 13:07:23 +0800 Subject: [PATCH 53/65] test: refactor fixture and add global clean_up fixture --- backend/tests/conftest.py | 25 ++++++++++++++++--------- backend/tests/crud/test_item.py | 11 ++++++----- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/backend/tests/conftest.py b/backend/tests/conftest.py index 4f77459..f7243a6 100644 --- a/backend/tests/conftest.py +++ b/backend/tests/conftest.py @@ -4,6 +4,7 @@ import pytest from faker import Faker from fastapi.testclient import TestClient +from gotrue import User from sqlmodel import Session, delete from supabase import Client, create_client @@ -31,33 +32,39 @@ def client() -> Generator[TestClient, None, None]: yield c -@pytest.fixture(scope="module") -def super_client() -> Generator[Client, None]: +@pytest.fixture(scope="session", autouse=True) +def global_cleanup() -> Generator[None, None]: + yield + # Clean up all users super_client = create_client(settings.SUPABASE_URL, settings.SUPABASE_KEY) - yield super_client - # clean users users = super_client.auth.admin.list_users() for user in users: super_client.auth.admin.delete_user(user.id) +@pytest.fixture(scope="function") +def super_client() -> Generator[Client, None]: + super_client = create_client(settings.SUPABASE_URL, settings.SUPABASE_KEY) + yield super_client + + fake = Faker() @pytest.fixture(scope="function") -def test_user_id(super_client: Client) -> Generator[uuid.UUID, None]: - response = super_client.auth.admin.create_user( +def test_user(super_client: Client) -> Generator[User, None]: + response = super_client.auth.sign_up( {"email": fake.email(), "password": "testpassword123"} ) - yield uuid.UUID(response.user.id) + yield response.user @pytest.fixture(scope="function") -def test_item(db: Session, test_user_id: uuid.UUID) -> Generator[Item, None]: +def test_item(db: Session, test_user: User) -> Generator[Item, None]: item_in = ItemCreate( title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) ) - yield crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + yield crud.item.create(db, owner_id=uuid.UUID(test_user.id), obj_in=item_in) @pytest.fixture(scope="function") diff --git a/backend/tests/crud/test_item.py b/backend/tests/crud/test_item.py index 81df747..72d44ad 100644 --- a/backend/tests/crud/test_item.py +++ b/backend/tests/crud/test_item.py @@ -1,6 +1,7 @@ import uuid from faker import Faker +from gotrue import User from sqlmodel import Session from app import crud @@ -9,18 +10,18 @@ fake = Faker() -def test_create_item(db: Session, test_user_id: uuid.UUID) -> None: +def test_create_item(db: Session, test_user: User) -> None: """Test creating a new item""" title = fake.sentence(nb_words=3) description = fake.text(max_nb_chars=200) item_in = ItemCreate(title=title, description=description) - item = crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + item = crud.item.create(db, owner_id=uuid.UUID(test_user.id), obj_in=item_in) assert item.id is not None assert item.title == title assert item.description == description - assert item.owner_id == test_user_id + assert item.owner_id == uuid.UUID(test_user.id) def test_get_item(db: Session, test_item: Item) -> None: @@ -34,7 +35,7 @@ def test_get_item(db: Session, test_item: Item) -> None: assert stored_item.owner_id == test_item.owner_id -def test_get_multi_items(db: Session, test_user_id: uuid.UUID) -> None: +def test_get_multi_items(db: Session, test_user: User) -> None: """Test retrieving multiple items""" # Create multiple items items = [] @@ -42,7 +43,7 @@ def test_get_multi_items(db: Session, test_user_id: uuid.UUID) -> None: item_in = ItemCreate( title=fake.sentence(nb_words=3), description=fake.text(max_nb_chars=200) ) - item = crud.item.create(db, owner_id=test_user_id, obj_in=item_in) + item = crud.item.create(db, owner_id=uuid.UUID(test_user.id), obj_in=item_in) items.append(item) # Retrieve multiple items stored_items = crud.item.get_multi(db) From 1e5be41c87a0b6ae0fa867a31b450badea99c88a Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 13:20:11 +0800 Subject: [PATCH 54/65] test: use sync fastapi client and api --- README.md | 1 + backend/app/api/deps.py | 4 +- backend/app/api/routes/items.py | 45 ++--- backend/tests/api/api_v1/test_items.py | 228 ++++++++++++------------- backend/tests/test_main.py | 19 ++- 5 files changed, 155 insertions(+), 142 deletions(-) diff --git a/README.md b/README.md index 6fa6bcf..d5a08c7 100644 --- a/README.md +++ b/README.md @@ -44,3 +44,4 @@ scripts/tests-start.sh 1. [x] test_main.py 2. [x] test_crud/ +3. [x] test_api/ diff --git a/backend/app/api/deps.py b/backend/app/api/deps.py index f0b7266..d7eec92 100644 --- a/backend/app/api/deps.py +++ b/backend/app/api/deps.py @@ -1,7 +1,7 @@ from typing import Annotated from fastapi import Depends -from sqlmodel.ext.asyncio.session import AsyncSession +from sqlmodel import Session from app.core.auth import get_current_user from app.core.db import get_db @@ -10,4 +10,4 @@ CurrentUser = Annotated[UserIn, Depends(get_current_user)] -SessionDep = Annotated[AsyncSession, Depends(get_db)] +SessionDep = Annotated[Session, Depends(get_db)] diff --git a/backend/app/api/routes/items.py b/backend/app/api/routes/items.py index 00f478c..40e93ce 100644 --- a/backend/app/api/routes/items.py +++ b/backend/app/api/routes/items.py @@ -1,33 +1,38 @@ -from fastapi import APIRouter +from uuid import UUID -router = APIRouter(prefix="/items", tags=["items"]) +from fastapi import APIRouter +from app.api.deps import CurrentUser, SessionDep +from app.crud import item +from app.models.item import Item, ItemCreate, ItemUpdate -# @router.post("/create-item") -# async def create_item(item_in: ItemCreate, session: SessionDep) -> Item: -# return await item.create(session, obj_in=item_in) +router = APIRouter(prefix="/items", tags=["items"]) -# @router.get("/read-all-item") -# async def read_items(session: SessionDep) -> list[Item]: -# return await item.get_all(session) +@router.post("/create-item") +async def create_item( + item_in: ItemCreate, user: CurrentUser, session: SessionDep +) -> Item: + return item.create(session, owner_id=UUID(user.id), obj_in=item_in) -# @router.get("/get-by-id/{id}") -# async def read_item_by_id(id: str, session: SessionDep) -> Item | None: -# return await item.get(session, id=id) +@router.get("/get-item/{id}") +async def read_item_by_id(id: str, session: SessionDep) -> Item | None: + return item.get(session, id=UUID(id)) -# @router.get("/get-by-owner") -# async def read_item_by_owner(session: SessionDep, user: CurrentUser) -> list[Item]: -# return await item.get_multi_by_owner(session, user=user) +@router.get("/get-items") +async def read_items( + session: SessionDep, skip: int = 0, limit: int = 100 +) -> list[Item]: + return list(item.get_multi(session, skip=skip, limit=limit)) -# @router.put("/update-item") -# async def update_item(item_in: ItemUpdate, session: SessionDep) -> Item: -# return await item.update(session, obj_in=item_in) +@router.put("/update-item/{id}") +async def update_item(id: str, item_in: ItemUpdate, session: SessionDep) -> Item | None: + return item.update(session, id=UUID(id), obj_in=item_in) -# @router.delete("/delete/{id}") -# async def delete_item(id: str, session: SessionDep) -> Item: -# return await item.delete(session, id=id) +@router.delete("/delete/{id}") +async def delete_item(id: str, session: SessionDep) -> Item | None: + return item.remove(session, id=UUID(id)) diff --git a/backend/tests/api/api_v1/test_items.py b/backend/tests/api/api_v1/test_items.py index 5d6b391..a2468f1 100644 --- a/backend/tests/api/api_v1/test_items.py +++ b/backend/tests/api/api_v1/test_items.py @@ -1,115 +1,113 @@ -# # Additional assertions based on your application's logic -# import pytest -# from app.schemas import Token -# from faker import Faker -# from starlette.testclient import TestClient - -# from supabase._async.client import AsyncClient -# from tests.utils import get_auth_header - - -# @pytest.mark.anyio -# async def test_create_item(client: TestClient, token: Token) -> None: - -# headers = get_auth_header(token.access_token) - -# test_data = Faker().sentence() - - -# response = client.post( -# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} -# ) -# assert response.status_code == 200 -# assert response.json()["test_data"] == test_data - - -# @pytest.mark.anyio -# async def test_read_all_items(client: TestClient, token: Token) -> None: -# headers = get_auth_header(token.access_token) - -# response = client.get("/api/v1/items/read-all-item", headers=headers) -# assert response.status_code == 200 -# assert isinstance(response.json(), list) - - -# @pytest.mark.anyio -# async def test_read_item_by_id(client: TestClient, token: Token) -> None: -# headers = get_auth_header(token.access_token) -# test_data = Faker().sentence() - - -# create_response = client.post( -# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} -# ) -# assert create_response.status_code == 200 -# created_item_id = create_response.json()["id"] - - -# read_response = client.get( -# f"/api/v1/items/get-by-id/{created_item_id}", headers=headers -# ) -# assert read_response.status_code == 200 -# assert read_response.json()["id"] == created_item_id -# assert read_response.json()["test_data"] == test_data - - -# @pytest.mark.anyio -# async def test_read_item_by_owner( -# client: TestClient, token: Token, db: AsyncClient -# ) -> None: -# headers = get_auth_header(token.access_token) -# test_data = Faker().sentence() - -# client.post( -# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} -# ) - -# user = await db.auth.get_user(jwt=token.access_token) -# user_id = user.user.id - -# read_response = client.get("/api/v1/items/get-by-owner", headers=headers) -# assert read_response.status_code == 200 -# items = read_response.json() -# assert isinstance(items, list) -# assert all(item["user_id"] == user_id for item in items) - - -# @pytest.mark.anyio -# async def test_update_item(client: TestClient, token: Token) -> None: -# headers = get_auth_header(token.access_token) -# test_data = Faker().sentence() -# create_response = client.post( -# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} -# ) -# assert create_response.status_code == 200 -# created_item = create_response.json() -# created_item_id = created_item["id"] -# updated_data = {"test_data": Faker().sentence(), "id": created_item_id} - -# update_response = client.put( -# "/api/v1/items/update-item", headers=headers, json=updated_data -# ) -# assert update_response.status_code == 200 -# assert update_response.json()["test_data"] == updated_data["test_data"] - - -# @pytest.mark.anyio -# async def test_delete_item(client: TestClient, token: Token) -> None: -# headers = get_auth_header(token.access_token) -# test_data = Faker().sentence() -# create_response = client.post( -# "/api/v1/items/create-item", headers=headers, json={"test_data": test_data} -# ) -# assert create_response.status_code == 200 -# created_item_id = create_response.json()["id"] - -# delete_response = client.delete( -# f"/api/v1/items/delete/{created_item_id}", headers=headers -# ) -# assert delete_response.status_code == 200 - -# get_response = client.get( -# f"/api/v1/items/get-by-id/{created_item_id}", headers=headers -# ) -# assert get_response.status_code == 200 -# assert get_response.json() is None +from faker import Faker +from fastapi.testclient import TestClient + +from app.core.config import settings +from app.models.item import Item, ItemCreate, ItemUpdate +from app.schemas.auth import Token +from tests.utils import get_auth_header + +fake = Faker() + + +def test_create_item(client: TestClient, token: Token) -> None: + """Test create item endpoint""" + # Prepare test data + title = fake.sentence(nb_words=3) + description = fake.text(max_nb_chars=200) + item_in = ItemCreate(title=title, description=description) + + # Make request + response = client.post( + f"{settings.API_V1_STR}/items/create-item", + headers=get_auth_header(token.access_token), + json=item_in.model_dump(), + ) + + # Assert response + assert response.status_code == 200 + data = response.json() + assert data["title"] == title + assert data["description"] == description + assert "id" in data + assert "owner_id" in data + + +def test_get_item(client: TestClient, token: Token, test_item: Item) -> None: + """Test get item by id endpoint""" + # Make request + response = client.get( + f"{settings.API_V1_STR}/items/get-item/{test_item.id}", + headers=get_auth_header(token.access_token), + ) + + # Assert response + assert response.status_code == 200 + data = response.json() + assert data["id"] == str(test_item.id) + assert data["title"] == test_item.title + assert data["description"] == test_item.description + assert data["owner_id"] == str(test_item.owner_id) + + +def test_get_items(client: TestClient, token: Token, test_item: Item) -> None: + """Test get items list endpoint""" + # Make request + response = client.get( + f"{settings.API_V1_STR}/items/get-items", + headers=get_auth_header(token.access_token), + ) + + # Assert response + assert response.status_code == 200 + data = response.json() + assert isinstance(data, list) + assert len(data) > 0 + + # Verify the test_item is in the response + item_ids = [item["id"] for item in data] + assert str(test_item.id) in item_ids + + +def test_update_item(client: TestClient, token: Token, test_item: Item) -> None: + """Test update item endpoint""" + # Prepare update data + new_title = fake.sentence(nb_words=3) + new_description = fake.text(max_nb_chars=200) + item_update = ItemUpdate(title=new_title, description=new_description) + + # Make request + response = client.put( + f"{settings.API_V1_STR}/items/update-item/{test_item.id}", + headers=get_auth_header(token.access_token), + json=item_update.model_dump(), + ) + + # Assert response + assert response.status_code == 200 + data = response.json() + assert data["id"] == str(test_item.id) + assert data["title"] == new_title + assert data["description"] == new_description + assert data["owner_id"] == str(test_item.owner_id) + + +def test_delete_item(client: TestClient, token: Token, test_item) -> None: + """Test delete item endpoint""" + # Make delete request + response = client.delete( + f"{settings.API_V1_STR}/items/delete/{test_item.id}", + headers=get_auth_header(token.access_token), + ) + + # Assert delete response + assert response.status_code == 200 + data = response.json() + assert data["id"] == str(test_item.id) + + # Verify item is deleted by trying to get it + get_response = client.get( + f"{settings.API_V1_STR}/items/get-item/{test_item.id}", + headers=get_auth_header(token.access_token), + ) + assert get_response.status_code == 200 + assert get_response.json() is None diff --git a/backend/tests/test_main.py b/backend/tests/test_main.py index 56625ba..07c8722 100644 --- a/backend/tests/test_main.py +++ b/backend/tests/test_main.py @@ -1,14 +1,23 @@ import logging -import pytest -from httpx import AsyncClient +from fastapi.testclient import TestClient + +from app.utils.init_data import main as init_db +from app.utils.test_pre_start import main as pre_start logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) -@pytest.mark.anyio -async def test_root(client: AsyncClient) -> None: - response = await client.get("/") +def test_init_db() -> None: + init_db() + + +def test_pre_start() -> None: + pre_start() + + +def test_root(client: TestClient) -> None: + response = client.get("/") assert response.status_code == 200 assert response.json() == {"Hello": "World"} From 54c00b487eec8d6894ae7cb71d97094d73184e14 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 13:27:24 +0800 Subject: [PATCH 55/65] chore: clean up app/ --- README.md | 2 +- backend/pyproject.toml | 3 +- backend/scripts/lint.sh | 2 +- backend/scripts/tests-start.sh | 2 +- backend/uv.lock | 74 ---------------------------------- 5 files changed, 4 insertions(+), 79 deletions(-) diff --git a/README.md b/README.md index d5a08c7..2b81d94 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ cd backend scripts/pre-start.sh # unit test scripts/test.sh -# test connection of db and unit test +# test connection of db and test code scripts/tests-start.sh ``` diff --git a/backend/pyproject.toml b/backend/pyproject.toml index a60bad0..6f7eadf 100644 --- a/backend/pyproject.toml +++ b/backend/pyproject.toml @@ -18,7 +18,6 @@ dependencies = [ [dependency-groups] dev = [ - "anyio[trio]>=4.6.2.post1", "coverage>=7.6.1", "faker>=28.0.0", "mypy>=1.13.0", @@ -42,7 +41,7 @@ exclude = ["venv", ".venv", "alembic"] # Ref: https://docs.pytest.org/en/stable/reference/reference.html#command-line-flags addopts = "-rXs --strict-config --strict-markers --tb=short" xfail_strict = true # Treat tests that are marked as xfail but pass as test failures -filterwarnings = ["error"] # Treat all warnings as errors +# filterwarnings = ["error"] # Treat all warnings as errors pythonpath = "app" [tool.coverage.run] diff --git a/backend/scripts/lint.sh b/backend/scripts/lint.sh index 1be0606..dc52cbf 100755 --- a/backend/scripts/lint.sh +++ b/backend/scripts/lint.sh @@ -4,5 +4,5 @@ set -e set -x mypy app # type check -ruff check app # linter +ruff check app tests # linter ruff format app --check # formatter diff --git a/backend/scripts/tests-start.sh b/backend/scripts/tests-start.sh index 95d4050..b55e9be 100755 --- a/backend/scripts/tests-start.sh +++ b/backend/scripts/tests-start.sh @@ -4,4 +4,4 @@ set -x python -m app.utils.test_pre_start -# bash scripts/test.sh "$@" +bash scripts/test.sh "$@" diff --git a/backend/uv.lock b/backend/uv.lock index 5217704..5a5ceab 100644 --- a/backend/uv.lock +++ b/backend/uv.lock @@ -138,11 +138,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, ] -[package.optional-dependencies] -trio = [ - { name = "trio" }, -] - [[package]] name = "app" version = "0.4.1" @@ -163,7 +158,6 @@ dependencies = [ [package.dev-dependencies] dev = [ - { name = "anyio", extra = ["trio"] }, { name = "coverage" }, { name = "faker" }, { name = "httpx" }, @@ -190,7 +184,6 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ - { name = "anyio", extras = ["trio"], specifier = ">=4.6.2.post1" }, { name = "coverage", specifier = ">=7.6.1" }, { name = "faker", specifier = ">=28.0.0" }, { name = "httpx", specifier = ">=0.28.1" }, @@ -227,25 +220,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, ] -[[package]] -name = "cffi" -version = "1.17.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pycparser" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, - { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, - { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, - { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, - { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, - { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, - { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, - { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, -] - [[package]] name = "cfgv" version = "3.4.0" @@ -952,18 +926,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, ] -[[package]] -name = "outcome" -version = "1.3.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/df/77698abfac98571e65ffeb0c1fba8ffd692ab8458d617a0eed7d9a8d38f2/outcome-1.3.0.post0.tar.gz", hash = "sha256:9dcf02e65f2971b80047b377468e72a268e15c0af3cf1238e6ff14f7f91143b8", size = 21060 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/55/8b/5ab7257531a5d830fc8000c476e63c935488d74609b50f9384a643ec0a62/outcome-1.3.0.post0-py2.py3-none-any.whl", hash = "sha256:e771c5ce06d1415e356078d3bdd68523f284b4ce5419828922b6871e65eda82b", size = 10692 }, -] - [[package]] name = "packaging" version = "24.2" @@ -1163,15 +1125,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/08/50/d13ea0a054189ae1bc21af1d85b6f8bb9bbc5572991055d70ad9006fe2d6/psycopg2_binary-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:27422aa5f11fbcd9b18da48373eb67081243662f9b46e6fd07c3eb46e4535142", size = 2569224 }, ] -[[package]] -name = "pycparser" -version = "2.22" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, -] - [[package]] name = "pydantic" version = "2.10.6" @@ -1463,15 +1416,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, ] -[[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 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575 }, -] - [[package]] name = "sqlalchemy" version = "2.0.37" @@ -1651,24 +1595,6 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, ] -[[package]] -name = "trio" -version = "0.28.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "attrs" }, - { name = "cffi", marker = "implementation_name != 'pypy' and os_name == 'nt'" }, - { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, - { name = "idna" }, - { name = "outcome" }, - { name = "sniffio" }, - { name = "sortedcontainers" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/b3/73/57efab729506a8d4b89814f1e356ec8f3369de0ed4fd7e7616974d09646d/trio-0.28.0.tar.gz", hash = "sha256:4e547896fe9e8a5658e54e4c7c5fa1db748cbbbaa7c965e7d40505b928c73c05", size = 580318 } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b4/04/9954a59e1fb6732f5436225c9af963811d7b24ea62a8bf96991f2cb8c26e/trio-0.28.0-py3-none-any.whl", hash = "sha256:56d58977acc1635735a96581ec70513cc781b8b6decd299c487d3be2a721cd94", size = 486317 }, -] - [[package]] name = "typer" version = "0.15.1" From caa157c709a5cbb3eb386e1501f153b13c6e6401 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 13:35:18 +0800 Subject: [PATCH 56/65] fix: name --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 2fc9f8a..07e5fd9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2024 Atticus Zhou +Copyright (c) 2024 Atticus Zeller Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 917a5c17e04258337ff68abfa60b425dbb51f57c Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 13:51:50 +0800 Subject: [PATCH 57/65] chore: clean up image --- docs/README.md | 168 -------------------------------- docs/assets/img.png | Bin 59692 -> 0 bytes docs/assets/supafast.drawio.png | Bin 35791 -> 0 bytes docs/assets/usage.gif | Bin 70254 -> 0 bytes 4 files changed, 168 deletions(-) delete mode 100644 docs/README.md delete mode 100644 docs/assets/img.png delete mode 100644 docs/assets/supafast.drawio.png delete mode 100644 docs/assets/usage.gif diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index e6a5d99..0000000 --- a/docs/README.md +++ /dev/null @@ -1,168 +0,0 @@ -

- Logo -

- -

- - License: MIT - - - codecov - - - CI - - - GitHub release - - Python - - Made with Supabase - -

- -# ⚡SupaFast⚡ - -___ -> supabase & fastapi crud template - -![supafast.drawio.png](docs/assets/supafast.drawio.png) - -## Features 🚀 - -___ - -### FastAPI&supabase - -1. works of authorization all handled by supabase-py and fastapi **dependency** without any extra code -2. supabase-py crud integration with **pydantic** model validation - -### Pytest - -1. pytest integration with **pytest-cov** -2. pytest **fixtures** for fastapi client and supabase client -3. pytest **fixtures** for access_token and refresh_token -4. test for **CRUD** operations -5. test for **api** operations - -### CI/CD - -1. **codecov** for coverage report -2. **poetry** for dependency management and pytest integration -3. **pre-commit** for code quality -4. **latest_changes.yml** for auto update README.md -5. **Semantic Release** for auto release and changelog -6. **docker** for deployment - -## How to use it - -___ -![](docs/assets/usage.gif) - -1. create your github repo and config it - 1. allow ci to access your repo - ![img.png](docs/assets/img.png) - 2. config ci_tokens - 1. `CODECOV_TOKEN` for codecov in `.github/workflows/ci.yml` ,`semantic-release` is optional for auto release - 2. `ATTICUS_PAT`should replace with your GitHub token for latest_changes.yml in `.github/workflows/latest_changes.yml` - 3. `DOCKER_USERNAME` and `DOCKER_PASSWORD` for docker-image.yml in `.github/workflows/docker-image.yml` - 4. replace `tags: atticuszhou/supafast:latest` with your docker repo in `.github/workflows/docker-image.yml` - 3. config fastapi setting in `your_project\src\app\core\config.py` - 4. config `pyproject.toml` with your project name and description,etc - -2. cd your repo and install dependencies with [uv](https://github.com/astral-sh/uv), which is an extremely fast Python package and project manager, written in Rust. - -```shell -uv sync -``` -3. set your supabase env - -```shell -export SUPABASE_URL=your_supabase_url -export SUPABASE_KEY=your_supabase_key -export SUPERUSER_EMAIL=your_superuser_email -export SUPERUSER_PASSWORD=your_superuser_password -``` -4. config fastapi settings -```python -# src/app/core/config.py -class Settings(BaseSettings): - API_V1_STR: str = "/api/v1" - SUPABASE_URL: str = Field(default_factory=lambda: os.getenv("SUPABASE_URL")) - SUPABASE_KEY: str = Field(default_factory=lambda: os.getenv("SUPABASE_KEY")) - SUPERUSER_EMAIL: str = Field(default_factory=lambda: os.getenv("SUPERUSER_EMAIL")) - SUPERUSER_PASSWORD: str = Field(default=lambda: os.getenv("SUPERUSER_PASSWORD")) - # SERVER_NAME: str - SERVER_HOST: AnyHttpUrl = "https://localhost" - SERVER_PORT: int = 8000 - BACKEND_CORS_ORIGINS: list[AnyHttpUrl] = [] - PROJECT_NAME: str = "fastapi supabase template" - Config: ClassVar[ConfigDict] = ConfigDict(arbitrary_types_allowed=True) -``` - -5. run server -```shell -uv run uvicorn src.app.main:app --reload -``` - -## Roadmap 🫶 -___ - -- [x] FastAPI backend - - [x] **standard** structure - for **FastAPI** project - ```text - ── src - │ └── app - │ ├── api - │ │ ├── api_v1 - │ │ │ ├── endpoints - │ │ │ │ ├── __init__.py - │ │ │ │ └── items.py - │ │ │ ├── __init__.py - │ │ │ └── api.py - │ │ ├── __init__.py - │ │ └── deps.py - │ ├── core - │ │ ├── __init__.py - │ │ ├── config.py - │ │ └── events.py - │ ├── crud - │ │ ├── __init__.py - │ │ ├── base.py - │ │ └── crud_item.py - │ ├── schemas - │ │ ├── __init__.py - │ │ ├── auth.py - │ │ ├── base.py - │ │ ├── item.py - │ │ └── msg.py - │ ├── services - │ │ └── __init__.py - │ ├── utils - │ │ └── __init__.py - │ ├── __init__.py - │ └── main.py - ... - ``` - - [x] **auto-auth** by fastapi dependency with supabase-auth - - [x] **CRUD** operations pytest - - [x] **api** requests pytest -- [ ] Supabase integration - - [x] crud supabase-postgresql - - [ ] websocket with supabase-realtime - - [ ] curd supabase-storage - - [ ] supafunc integration -- [x] deployment - - [x] Full **Docker** integration (Docker based). -- [ ] clone - - [ ] cookiecutter -## Release Notes 🥸 - -___ - -### Latest Changes - -## License - -This project is licensed under the terms of the MIT license. diff --git a/docs/assets/img.png b/docs/assets/img.png deleted file mode 100644 index da5c42da6f7ea71d7a4270232269e75187463c70..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 59692 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

xv;)PFIif^ zE7D6F5)OD{j$d#NdGlqb4Ck)2&|&jTY*yIqhqR}LOccJ4@As18sPNa>=SpUtxoo6$ zvJIG%ZAwVCB@Ff76WkW9@^dVV4|&VXUCEM56vAZLiks(lN&JmK!nZp!7BdD6-~pC} z?NLVOX9IViJbh#%K9FjdXPaNIm?^yAfoKeA@Nor8?`XQSe&+0m^Z1?qp-~^lQvKJH zQX!GFlCa-H+^lGP_y|1CekLYm^eJ zXuY?k61({RVzy9|l-L3P#wQ^;#O0CaMqj|7r-?Il&fV`Y*$Bk1PK&C8ZxLF)xYalxJ#7FqTBb? z0ma7f1kc4lf#`@*{?)R-voC+z;b@1xX}}0IUoL@QP`VKpd#6j4kAh5SWXABuA!zMY zR;U4~MYiS2a;YkhHc!|~Y#n@hqt$`+LtQ~%Y})hD1%F%haBu4qGy!{{udfgA;F$F- zq|qiZ5cN|44e(YUARrvq(a#~@<$J!XuO{y8Ub|&Pc2>f+`s}2wAa)@vF)$nSBCmJ| zm(d$#WmX&Du&QX%$m=)b`4vTSo(+>oc5vCmwS#(;fkTOddcfeAgKcg~7S|lgG=z1L zac}@jd($RtgL#Dd={rZTzEr@1RS=7}hFOYoQ;G^=*D#>d0WSx;?h;qWRZbMCyM1=U z`!3%-V-Vj#$(hVdr;S;+7BU!VcUr+hKM_n7uPZ@z!W6$R4c2O z*Pw!ho7>Y^1$Y&exgSXxt*~Uz4eN@r^K#I3nD>fA0*M*(_D?GS)@m(VE+4&{%j5dK zvtH=nOYU~C#a*zpgQvx7i0P#PO>|uI9oea9(D+CbDR80(2C|A&VPu$qJV_L0FzCzU zd1-$;jc)gfEY2K?O1l2~veDD_&E|jh_2oI)>(25BmQ&7ThohJIqnBs+CtUrHwUZf*;-9#rpQ>E=WmPh%JLxSIvU%;p7XAWx`Axc2;0NrW^^gTr{K;w zT+#E*YXZ}zrd#p6Eli}C9*N*EUsX{o^kb&QU2^LsC4ZgSpGhYph678E(aWR+4TJ~7 z3Kzg{oNL9?FH%S5W`x~i2)9&3;>iz$SWj9m|LjaKJr?oJyFZZJV9-*toU?q2S+XQL zTK77=MZUoU{ws7iwY?5!gb)Yu>m2>rDs`{`ENJdrwgsV_iprl^};*}G#{q|Mw z=#dyu_!ipibE;Z!C|D==%kQS^c8rr(mq4P0PM&4dt9KNrWtDNOlF3Eu%mrpGp52HzHMb8o!&x2V^JUKqNT_{9_niGuQ1++&7;LY9mg$t%|rIt zT{<wZ;)}ll1HU&T&j{xjI?w%)C2-@T_4EhzmatFo-RyNoc;g zQQt~n4TjHFzI-Obj1gK>>e8YZBkGi!`vVm=rKqN+WH z7S`}Xa@K{p`KW<{aMM#IL7Myii~noNr=qiU3O|$xlIh@qz$5S1q*0$U3q;DwciU9& zf7%tk{0ef!ekvr5Ut^G6D&h~nOQ85ItXUTfoG#mSiWt3#o{L8Z*M&Vrlm;Q?N}Ad5 z=%F!COu~Q}HU*n;ZItw+iI|5ssrlQ)9v)x(uU>|ncJF!^h0Pr$t4$$Q&w0i{a(@Se z0$N0L{BJxEK4&6hyVrq~O7xOfX08#NHpi;C?Z7gng9J$e)TsV_xJs0*$;oi zeSbfwKl{s_zwdwIy#5<&`}-mBbJ+h>|3v`3koeyfbrv@CnsUInfK3C+-elQ{(-;|5gbHlS!=KL zGW4>-bMkheG}vdhKpI%;Sz=y_+WcP~{K8a0!RFSZvd@b8T2{w1_BVw6^gBU`GHGzx2<;GY zrY2;xtxl}@Y-KUYlc`|D2$p1iNnYZ(Y~Np7J8N*|7PQ{bt%X&8KIHN)=6vVFQvAaBeC+ z%@rY0Z3^36%U5n)(|pCNL5uAYN~ChSmc271b9xig%MuBSU!2<2JFKstK^=T^K5=k- z4P>lX4m`+mfR?4wj?M5qrnVbDRL84t(F=aW2&v#sDKL*C=gcug`?}|v=wUA1J7bfi8iilGgmZW7Qox`_ARk1@`%tq`T=NOvpkS^!um|x#r0vz=5YI>PS>P>l*H|zdhP#F_W{# zy3hs)QrU>MbAOCAKQ%V7zGrR;W@#9$x5e#>ADJzD%hIthw}3O-s?UJVl^)-RaYSixm()&subA;OI z2qf|nSOh3VzqioQ_Lrnl8hky4*_uk*Q}>Wht4#tP5Ea znoz3Ap=$YLndlqn+qvuesW8%q=&Ho1ZNcn_HR+FOFWxt)>H@$dZg@&o<@rMoO#e~k z@e&+797(H_>Z(*-Lu6LfrrWh29%jTuSTTg^!OEq)ZWv9<=qH;3&X8dA*xF;f!Ns;R z%bu0jR!}|1_r_2}K(N}9kq}cqV6$z9JAU&O!@P1e&qtEYf-8>Q8*>Ug{T?9mg{z^^QyX;vz=Hah}KwNCMMfa zQ#CMC%If%mYK%WJczPRk-ZA+*Ls$Yq(n!lFX7^lpptDWZZ zvl%up=qeEwpfNs-SKfQA!CW1Za}6)%loVlYplxC00@;7skR!M&?n{9?JRZ-CZreG= zl46p>k`ugn62iiC$?_bC15Tu_Oa`kATi>@ad5&M1bH{@aCQ455nrXx zH&@>Ex&rCiDlK44sOA2?^Ji2C z{Ydik^TFpba$BUj&gW@4LxT`aItk8M%Zdwa+P1=d+e{7UsBHXgQt%@z67(E4Be+x? z(XeLYg7gnT&z}f-KkG4!M$bzRkXTGGFfE_ly?*Ole*W9lV`E;3Bu$P7(A05mYKWe$ zPgmX+ARs*F9ORu{RDNu+S<&I`6=mci!MAZ}nB2?q==9$E&(+58GZI^B>C&(?(%qh{ zyvc$4ofr*|hmEe^1UNp_dc9Z1X^&Pt=Ybs@g5ZGF4_y<{4?5VXb`R66lkvg+4G(-H z9FU32K90*Z-YoR0ZAIj&2nY|4cDl_j39C8Oo5M$9Qei%lF>+(BaG?4=kQm4JDdUD}9eki+B^xy!twhW1>870Q}vk z+rnm?&dk8*RfVV*gLtwRcAZCyTqx^kX@?HO54-U|EH_0FPQ4P2Kdn^)N_Ek)9uJ41 zIR|UB8`0*p((C(@?j;Zc&0I}WywUo3?&FxS>o>62)HLYM5 z5fU>_n(~nvefxx7z2LiYrO`;F3MCbZHS4RZfrGh)5wfY?L5Uk@Dp*I~v{;9p(7Il#`e-;; zn^QvOkB0*^i(gYM2hHrwjGU)FiczEqUNM4~E}v|M>9}bR%SzmDnq(iV>olOv zZZx$c>2e1A0l2=u9oAruLx`o0^E-p$@7jF*<2|0|qgAR`PRi&DFHWy7!B|fo+M05B zT5`Pop1fB-(|o0XDNhAjhV&3ZX(>UL)AikaaM+m_%T`kHZrqK(gv$nryZ6-0z&`;R zk*C`G;_yAzMbKMhd`Jbmin+?GW`_tZNk*)I_m8siiBXKA*YEQ3qv8W=PK7p7G+BP3 zQZJ;@J6uMefAzb}2Y-LvK%^2e`#MYEwI_YhBP=*#^sUs8J)R%!;4Y)Ths z%8{P|dF!QLl%Gkg?F4vyr|waWw%&MFs!aJo00ROn{kT3v_!V6ll85VI|6bBY&s;xK z3GqkJqm48;*J0nEV4VOx*B?nexo9A;=m-6na64&fb<+i(BsqzgcNN(WQ`}56Wvz^K_)gW8xtC@yYoGxRP<~e^ZV> zOw&#py^C$_b(XiZv04A9!UqU5nW9Hz1oiW?x%nTCh`FwmudN-9_D6vbCr8oFkMakBnmRXo#r3hNO@!eNU3;WQysmJhfr*=;@c*n_R3;A3d<2mtyixVI>D*hnxmuj zF?s^{(%@GdBcJztStE)ZCkRhUG}eDu8d^(a(lwAhdH6pciWb9~zaD-PEP6)4Fcwf)N`*w#=0Bl76ZpD$AOFW4N#7v#vodAMPn`B7 za+P3iKAq}S<4U^vo%%}&r#l<#JZ*s$tIdz>-A8rqtX*L9V6T77e9Py5yz<9MY7gB- zWJ5|r)lG=9{?byc{C6ywfhfP|=o-Y@UkZ^p0jh&nH4AJq&EH)DsRGUHKgMfoScS+4 zASwd2MfWliVN`bpYt=N^2x0D7rU!0+L`=ktayhfxZtl+tgHcgfhvrFG{>SS6}G^ zOx;iVt0J6Ipzw{-$N-WX0&R8+#XGVcFa}7yc9Vt|SxeNMS`HW~s%Os+>i-ycM~SB4 zx1nD~_Swt-PuLlsOOIo>hl6veKIJ$n^;fPb3o|kpaR!rkd7lUJU2jD_&!9D$m|*-s z9mPc(o?5&DCG@Z8cp$=63GH_GVcxR8Z5A`i;e`v(kM?V8o7qW?0Og=6+y+u*z{RSa zeOFKLaAs?p(Bcm30_2bsxqKDCGe8xU3`~$LPLu!-hMLT6CCm*_?fb7`X%U)#?OeY9 z)nOn1-b{ao*6+wZkBg?SQ2=fA{lNMqy{_stGvhTPbOkc$l|4s7@4c@2MH$F)nqxb?Psk=ENG=x*b8>^&To(Snbso#&vsLR@@fe~ZaFCAE2Tqjsw8OD+Ymu5k+U z+4+^deeUm+5*r0s|HYnly*18d?&otyHpYo2EXw=fs?yGUhBlQ4lCsa3p>i{&c~Qpu z@Od-ZxqK?j$$ZR;`i#}g=?gTg9Se2_gkeZTal5SApwDp=?towuI-XgBm*jjGOx654 zyieU<+lq*JHSVBGCGqco>5>4L{kK9=7VO~BPJUM^0yNfCPINk6stE6;y4S(ddx zW-#Q$9vza$`sPyp;w`yR37RzqkIcjd6#ocqD6&kEeVh~j6RmhCfwm#0Ge_a{?;}NT z7-<<={T@0z4K1$~~VW`19y;2wzp-l&Uj)x@}~2V8$E=DuT+Q$nBzZnH@l!|$v(hSLnVP7yc5Ji7g`}*X(@YtD z*|hJ}%TQ=~0LX9|X6k79QI&c`h6&l&9}|6)@W>{5h>&wuDwr7R+wvuF#$I7N(0?5iC8p#$|$|HX%svdN2Js7*02I)R%v9*Usn&W zCQ}J-=`+tPh9?KFbv88WHLq`D$9ZTQhnER5IvXakKfw{GkZE#6o0q7`8{%$QSQD`a zT(hlWQVUCRSU0raI zlRbyK!mzue_*w1WeP)oiL{_d#*Vvj4gDCf>GNaDhz0j47wcs$;xm=vsT>B*jzEwxL z4UDq_40MWrFr{y7B|pOM$2tr>Yn-$TCjK3V>New+q$D2}1d0iZqkt3i3;X6{zLBB) z8<55?P9gz9X8!VARL1CBz;^ofw6?bQbShIHJDNv^)at%Q-(PxYQGw*>16VbbS&>=T z(38crB-qww!SO2ernBT-&6)AvkvN}U=UK2AoUe{U_oOm6hTC_0wfVXAt#{*4MD8g7 z_4zj7_#qYXURg|Pm0oMn)^dS8|x2!Nk4G44-uoY8i11iKRPEU z35tTkdbZJ5Rcpf6hKE0jb8)R2JPP39GK z$Z-CnjVHDiPXTJqH zUi`)(`o-YeN_-Rq~0Z(<;f&YVDLWgiBG~U0vx4HT&0ZA>ta`7pJ z0Om|PFid9;l-wfhGGK_7x!1*;d26!VX3@nyNp?j0n4a0@waP=1IgG$N=d%!5tMtT`;0vClyfQMK|gOnaW=C-^|T=khYGm?EwgBv0vH zv=H9fDeLR*XWRk(I{%A(*6_^+sQ+r|z?#CTnOl%!?iw+|*Z<=!@b|+d>E+`Mq_W5d zyq0%AU-(pjtwoEUu*-yr%~V@ zhK@z#x-s(4V#TIHvi+oPe#v)7_hJ&D>z)8_Mpi%f*878q_8fU&je+zDf_t@DPKg(^ zdFw*yGbo*P>zp+MipTo0p{r!RQcv9hA9k`63m|&`qMn}pUH2MNJ7WvG2>lZDE$n_4 z8g390kx;l(lPsP`#BlpaCeFk;LwWa45Ai3UE~yYf7?5!>;b2qMXNQ1I+1KJKiSzAc zm%e0!++tl)p$EsCSvuLp}=u71YjzhNm^m7Q+0NTPe z=>uw(V(fZ0{coEO9v=$Ugd>R?Hrh>*^JWDsDUYMOR#O%VJB2gH%sszC@}^Usp4|xB znXgC%Gm3T?SLvSDmr|~(79S?gGyB9{Tw^It7aqG03T&D7|10x!2U<7t|A2XV7N!H| zEUnuHjdXq(LCaC64~i3z0!s*}siLLyZi1#@DYxGin+q(3G}8Mqu)DOJT$IT?@$dpWsypXyAiS~6>n8VL1xr74&Wq^HRPAr}DXK$G zdhNwW!N{v;@dW9$;CC@WzCV0^AYGk7O`NT~&X%B1kkR$VqoP!)Vc7 z8-zgb-*74jtd~$?Yy+(;j}@9TQgSHcb_MED%hyy~8aFbzV_-TRhZ}oNJ)aeM1>PoJ-#b2{M`XvOMrIhDl3Kd<{jBbvTb)S<5dKWJaIQ#osp2W;5_L7bE)Ul=ej-g zma#+f5PqL!MUSQ|g^h_gdxyKEqszr($oTIsiLSEsFuRsMWJ`E<-_~khqEZ!4(GRS= zJK&T&auyxn1xjA@7`^qELCUR>db2J?sdwn_n7JssPM&(wI1~*(Ko#&x{(gMHL^F?K zNj+>g;L2U-?1}XlN!lA}ma^cgr2`g3q?m&dTm->xG3lB_`T3afC{gB7dKi^J?8D7^ zj+KR1z4zN_lD_vioW7z^Lhz~ZTMyP7y#}zl9P<)6-O8HW7#kR{I~Dap8hF1y(Dt~n z`U%2G!|lFBFud*XlWJ~#E-U9^HI+Xe!|h(yK?N5w7?&C--7+b4F!4!g=VXs`E!9n| zeX}KV$SYgs-x;Y_rYhdfCZ1u4!I}dSds7DSG*t=XIfoe+GYrVrq{?rx#DW%O{f@U%`b-%ph}zQwc;<76ct9dW%UCfNKiRWNVox^drpQw95PLRUfbu1m zW6t~GBCQ0`iTHYgZs&Z zA!=LVNjY(j+>jttIIG(>Lq3pJ-8@DQ3qvI|bM#CvI7}uQcuOk4zPV!tE(LMiTRP!2 z{iJ-(Mq(Ys{9L{`=l{nxJI%?QQD%4VePM^)UHX2@QD*z-L5>m9X#r;(Ucgy|MTEAC z4GD3cV3o51up&}F=+$AonA@T?4-VNx4uEL)yn0R$mQYK-l zhz`IE;EjdjI5 z-ycmdtyxY$IkL!Iv9BCi>E+w3bWBBds1iqgIkOpweLggUBD>V+-bK76?Bxr2hZOuBpkMr*N`kt<1Ky%I={MD#Hf~Iqjtz#76)f_K zj-gT@W>MMIb%dr|gwW6I;ZT8K>U~b%A_)~)Ih*S#eyj>`7%oX*xP!>|BCBK_Cv^g+ z?S0x*PAD(ZP*u*)l66j7pxz!Ob5IHuKoN6uD29@f#BL16pu$eP$t2K)i?Td$#IRZT z3At{x-(Ph`tWk>xa1b%@VwBV1?lHTU^mW;Bw-Yuq+Ax3*K*d&!W09s-&G`T5Ntm8w zc(_nTS10JmF2BW8g5c}=gCBRg$sqlxIxbf~;}|B>tEy~mh3Wi+s|hu%7Pg%FvKzj5 zOds<8gI5VJM-t2G`~Z^}!Of@sGw{S_C@FJ}ICt`G+Huz!>o@}x9b^jw>MM5zdYrjp zHt!!D^jdL||2+OMNfSy&nzupBCM~?k2}`pSP~SJ(`t<;P2l`@v6 z>}Mifmf41e2lNHYsis-Z`Fs2<%qS@mryshlp8FFqU$=Kli*?M?Q_G~;qnB=mMMlj} zbRgXGkL{82Q7Hw56X;S?xFwH^)NtWFdVMkztj;njoT;TFx^G855vhAS$nvpgre4-g z%Dx6FV!XC)50{b_gbd2KYD#OJri|3_+#hk8OM`1nbo^&OsE(tYC@Z8YJL1KrjhV^T zn2}7rgeL3n3xuN7LKOPwQd#77J{L^GL0KFUN)*#=nPI=!$4uw&t@r~|xI#+mRa|hW zsq;RKm{Rf*DiR^#$^(1rN|C;3Fvf(v#<=4+ep-aPhf$X;9cv%<} zW2)WGBb7@8RTxOSx*bqCmTx!8r}MST`k<(uyQsu*koy^ki2beP7E-M-6_^om>f05H zdAmfeUtwC!;DZmNxw+6j0^+aJ?78(jHZe-;jNBzr%td`yik}GqY(PaenF9V47d9RS z!9Uw090ca%a>FxFE-v1D#Z0HNUwT$`?fuR(yIs~n;Cji3d_410ZD~C8=%-mL?jwPt zcPZFy8V3Z2?t-un&wE<8$tTmB&%J6P%r_b-Ys>j&onla~oAf)`Z^l*caNs@Ye$u7I zC*Yg?7JECuET7iIVUWwNk7QPR4(T(5Oe*A-k7=+-Q%A3bzs&*U(E#98+{ewghUJ4Q zb&&LSFtBkJ5v4vePBfCR+$}lUWEqRREwV~kj#@PtfpVGo#OIVEI2B zf`U%GR*o0KE08OR=8z>mNQO2t(9f9m$H(9-Q6J5NlOmG^ogJ-~iyA*Kov(@r)+}AB z|1GJbgw>>}P2a*c%q^1!^(dhMS$&RcLS}yx1b-M&?-nPJulm4S`*>FjLFiowjlI3m zBT+!Z`PJX+ui^G)q!bX2t+8so;R56qr?yQb;j8>1xO-MSP`im z#C8;Zek1FG8HKd(%#sIt)$wDg;`In5sMn5??j*5GK3lRD5ld^RHk&%T{8-dXlKsEY zcq`y#)iBS7S=}#YQYW7C#ly^8v;HfO*ZbG^6}mhL*AyQ#kGPhAV1CHe+%##eeOzVU z1^*X5&Ge4#V*6GhbzA$wAB;#K)K<@#!Af;+bK0lG$3i)OR`Vy1ofo4K0CD(#b~wqI&HRrXMVmgbRVnzrBp z=y!hCR+8swx8AE`xGJV=3&F|cBeBpF46_KhzqsQSUp2tX**c0m&s$FBGiSRJr2;XBg z5b-&JgMD4W@ym%dylR>;iMgPrJLAOKD>pwT_<=*vPAju%e#Sg374i$6>qTpZ8XCl8Zuo^IAKPW3n$;#_YHC$(%@uHq5#TN&f21?# z9#v;7HjSG(oxa{)eS-WO;@n6{%Q7I5C;4~gm-S!ga5zQjSs|>em1qoU zY6b1oDx*r8_g-@t-bFM3x%m$?48-Z-ztw$&A8C)^*7yqkOmbynE0nROyiu7voZ*nO z+hs{1u4u!*+QD;j={h8IK9MOl!ezIeZ)*Iun)mtr4d8}A5Eg15^B6%Yb3st~NH&_= zaN6+new9pBd9;xP{rsbm^C$d}K2(>JANSm~Nui)7&MQ?csU&JxJuS^FWa-)9UKWcQ z$qkV;t6{P%hKU@NS+20!SFB7QaLPS2@<`Gd`ek^C=dWchkgxBKUT$%;+AU8KxS9>k zGI(S!5)54e;UCGohXFF9tH6sq+=;bTS)Q1Q>qp27L(~tD?@UyN2FV8pE12Me-NC+k z3ybmtSHi9@G7P@Xw&?k;Q}(C6dWXcQga@+Zwjcm5ffqUqd|8NXTC z#^u^997M*40@t!u-_R(K31Z-?oI*@;O7UHnxLhir9!%%= zrF0M__>YD5k-P*WybS(k>u8hvtllvKF`^V5)Cw+ab!wK1ZFDg%e}j{o#eAcVSksz- zE*(?pjFFc4a7a*va3iKl0yT!Jx+hs9{YkMR(KdKdY{cA@6Iq_9D1r=*Zd2m^w2( zf?oaB(PJ4;iHYSSHO*K}^nZlK4HZ_;zj(*%P4VkGKKge4Gd}`W#nzhGe~V)H<8SDx zp_KMfTGxm-Lokpi8GglNWutoS38r?5ON9^6F@N|Ra}n!a%{+k}Ab51*t?!qYp{^l0 zO2fwnX&c1nbWuJTUu#-*ea68$KQC>Z?GWrxy?rbEce7OeIT{@@k$vKlb#V3NnPQB^ zEgR$jmPgrnVzsVn<=YPx>3_FPNkPebL4e6_e?< z&}VO<+|!cjViv?Z24vf z5IZ_KHqzyN9i`RFp*F@$4IyfeZ3SvekWMK+VB3z7-D#xlc64G_S#a7|*NkrCduw8s zTuNVm3=qqZ+mK3@staKs(W8`mNa!$ktq2|PnbHLZdct#`o*BglfN1W;d2dUbxYvO5 zAe~$q)RAdR9clUbC2;8tgcDwMLI)oHvC2Zy>SMs6+At*NbK%DA*DAyYx0=W};9|Cf zBghkPG_W3f|Q2+#4p^hK&! zU46=%b_rc&{)<@IsXPIOCKAJn3&{NgNT?e2hqdijSBxoa{DTB--SlR)j6AzKnnQQm z=TOMyq{OG4C-x%!(Q(f!exn0kDb^gKG%#Ixx$!$TmsYXVL)80Z~KeD!!D!O7Bq7@Eq>20^wDfYOjKQb{6EwL>^CHxG=$@Sn!t(9aCm_;K3Q1v z%yOoUyAlf=+2!+-hjZ!5$t$2zX$99<1n6oy7&NXvXb^DfAwoCGRdaqX_7gjn>T!Vl zHDMyFAfh-Ut7VGCS8{PW&elj-l{CYr@HkVE76eyUMSmS${3h2JE)NCy(G;GfHs`O9 z%52q9MZ#r=-)_Im+)rwP9;Db|^TeFGt1NVJypxYc!hAQ=F_}m-`)YK{u?wSAGSa8;{?HPXd`tv zlWAJ-FAvHnU2`g+_NKsfqpAgYWvyBW_&4m{u!1sm*xf1ixt)C)ya*JSF!Qy~?k zb1?WDvk$be#Ke#P3F-KM2;#r8&j0!OKj1b0zem9Q&j{egO%fnH3xfd9riLW0sQ@O| z$xiR4YhzZ^>9vCL12c zH$|-gt&U%jnCIV`@k*{leo3lDlt__jI0bmQ+B#kKwN3moRoG?5ovEkFgpZV~YWhOl*>G)geXbQs z5=oO;rNCI;x%_b}SQ<#XA0~R3h@8gPL7hbjnk2^rM#6&cj&w`40Q^O|}P>!*AdXVw9 z=aVn_ig9uzAng-v~$%>x|%9?#R(y!?lJWyi~kVoND-i#Ha4!(~A8#3S+aGJr?%Sevr!Wgo$8b7Lr9za+jOSK?^l52^9pbsupuA844TmEM z9?_&b&pNP|arjUfntsI_#M6+}rEDRzoR=(@3!S&lsRxkTMPp2d5f86Y^M@fwIL)UZ zEx2LnG_t|#{Sh;mb@jV(&~XQ7e40g}GJRsyDEocAH{g8kop{iqLtvVg%1SYSU073} z5+zPe3b@fvyZ;kc;$Xf~N2Q~}{ENSy9$V}J{UhC2`9Py4g=iIjrr#jdmkj(v!;H!Y zKfSY#ZHLt5P;UhDBCF^yWp|7(Yu?BDVf;Lznzz`-pLLO5JogO84RL7Tq-jP>78Wi+ z)mjlcA@AxY#H4>vX}~*0i$gN{5Svv@+Xj1F9I!EbI$~)|E?YDP@inqkDWYLJL?TuW z33uD_xVZxeAZ3pIV z)$zudU*0l+pf`S`Yi+*&4R`A7k_C~juFY7{z>MlTAcKgDLq8`#hOyVjTiePh{mCZg zJD00G6GoeO)bv*w1xLE$TagjDx}%%aQO<}t`}^ZfJ_WO<^o#OT_SA_=vEKV1$?(FT z_tM^d`jPU?J0D-Zn|Tn>jz<@jC@^cm=tT77&ss3ZUVF#TH#J{h`;wMTRis53>r*Gj zM9Vm7zEAlXXuL;>AkdUZa4{J4O!xD*vCrV_V*_84Y|Z5h7?w{lNZ0N@`Z0)uq2>x_%Fey`N+9n<*wO2 z9U9GP&F(pmayZ>CcZ*5^XM7y&#BGw*M0mw=+2Uui^b6MOXm^>GJ%AL;9e4!IxT9y& zWVc5L4XyX>N!(9%KAuK>I_R2;Qw&!SFVo(PoIJNmE{-aar%zSRv#vIQ4^r~_9X`oL zPI@SVKgw+bu69e7hSo2D+yFj`#Sbd zO{J1-EvQ;dXccf1@Yjkgw? zv+|vsK|Xm(_De;wI-y5!=2G)up8P~fzLRCM0A>GZX;@?K+}^fX+MJ1&8)+X8hj~g8 zk}QV^;CQ-du=BbR*i05)r05RKLm-o}e%W9~zUMxJC&;Gp%bQx8G~=El?zpHZ34rmP zZ@#b2qAu@3{=xOog!V9g$<$BZH(~MDd6>h?KSL2;!%o8VhOWl&5DDzF6q3Sl%rA&V zd3s!o*lC!dHspzR#X=($f-Z2U-F)J)GP2vV5oE-rJeQ%>jwaB$Qz@oHOYc%1<7@?J*-tQ<~ON{sn<+^*Az+-xM|5RR)9di&xy3h zxvlYeYVZP7R6wp`9^#5)T|!yI_neh+t*?PDCXl^U_I&nzKRO?_T_Qid(iJ_6>Se*d z3M7Iff)yI54i}NW+06L8t#LisMX=ULfbg7%F0;6kt)ws+3_evgL?igL^oXQj>>6Sr zw_K0fsakmvk(B}hx||?O(#C43vQ(jY%W08#N3?eS-YDJY8*j6!M4OJyUPgHFU0xM$z%9waxd+k?sdYoF`9Si+oCwrhRV<@CH2%8=yaH}F= zsNlLj0bg(&hR3uc4Px!bE~$xWjbM2|C1je4|A}A0={CoPRF3dcUg6UrbsPT;S2S!` z{97SICi;p&_-Nt>?F>h&68*(k(AD{F57p^wcUQ zo`qPJV?cgec-9WA9`qiw!QZn0hp zE`7FY|IA6e#YWu^qTY!X;n2{;AXNz^OO^)R2pl)Q^-9Fl$K|4}0Mfc-O|+V%TA6ZE zyQ`x|ArIMM^pbJr40kB8(%1fMGQ!qi)G)VFYktG90c!7l7puEXPyYUPQ!O;A z8>H1vjHvVXH;3eq(r7f$G@S0MDTy17{S8TV3)d;0y|&I|#BQvp6Z;|9+m+&{s?}YAWt-7|-HJ4owBBcz! zer{Yxu!U;D@XFqTl8_@1fiSSAjgn$=HPuLOx001GSh?!7*-a+C9veu~i)9(_jsy!wv8Z7fQ z%misBv}nP!Uzdv;m{U{Anijf|3t_}?pdV+^kEIAe0``}bA~t5no~!=)mB;YZhQw#D zj6@>~N*V>{yt<~b`NlgtS^I^bDBLn_qY-~jyj^=QUmclOX)?5)8ICFk z862226q;HTLjz3t7|EJ&E8o3#sUFlSa6N9ZH`J`h+!1U!%T2l!{7|i1T2ELR*(5}2 z`oSOnV5B%z2TRtFVu+7&B@=}j>Dmb`jN%u({oB2~8`=QL)3D*?A4o7oUpbJ@pOfhl z(zxx3poSCODD~_uqMVz#Q}#>rBK4KGkQX58^6i%=faylq?{iNIduEIK$bU%DT~8nc zTolu83n?fzk}sW}Zo>_*LtFX)D3wl+88DcGCt*VS)@Lwufn+JI2y12iXE9UmK0<}@ zOSwVNL@E;Byv1^sM{t(wLUnrWb=cx5zqY2aJMS^tb4nhw!jh}PmNZBs8nN6}FUGC+ zXuLN81t>zowQOX2G7@CfRo_e;4&dUfHP!ORT|mvAU$lL>fh7(h_ufB6URV$3GN{!uv>6v!ykd0iyB@aaHA2 z2oKB4(Cbb=UOlB|3(Mm zpt4g7DZw_4^%cnJ#9DYCs^HhS)BC$LHJY9;GobsJuxDXk3>ipu=w7xAYYzf0@&qkf z|Ko7t5Wu%oz-l)e$Y=VD>Nq2t@IQU2=i|M1rRQ|o7s9Wiaz;Wav`T4CT0)O`@mH_2~c@$ zJMZRoZ9e`r_PbC2P@%pz3>#Y2rNvk(9(Ki4ltAM35iU#~b9tO#GHK~!_pWfU_vH^e zg8`cR%JI^_MD?hgB#u^+?NZy_>AJEFl-8Go8gmW{M_a#t*kww)>=0*jzRorAF6dmt zHzp)f)(kY?c#~s;C7h4ifcZJl%Tcx`kNgd1dbRVG;%{wUjf|TP@2x;mv2rOhK}F0m z1UO9zJ8CVcl-O;TcJ@Kdt{DnQfHiVF~A9%Eqr(l(@Aax^9<;I zAek_9J6*X)ClKs*Hf>e`6*$qO?C3=x!jF4dKLvG!s7T>lyb-;wEoCG6ImWdVD zv6}8ia~IyzMgZJtHB$Fp*j%U|+}npS+C}8W1s7KLFQ_bble{C7LNbOO#78UV`ndW| z{_gmeDNy)2o0zNkY#l{LW$ z%)jk~8ceT({wHkNQXAj&nCFs$L%yE50V9+iWN#1Jd{moVVvo`C&*LRngu7y#Aq2=g z*gP0b7`(YHoYG}* zA5}+LlDF1qvr6Pt*gp#n@`=5x;_%hYX%U^0N%H6vYVC z8l9+P!cb5!-OV{3;C(vP(8tw_=&Vo#w;3Bw`&&`^pjAmOgt)2*paaB}LFPE2tOh-S z@yT{8tpSl2CWq6U?1mKq%v`Xk+XX&-mj#_d>=`DRkpeG$4J`;>rZhJl==_P0w!a^= zQixX)Sr#$zgp4z%u-I>B!eI5+Zv8iLYm)tm2h6_-<0qVAP`&90Q(^QaPif%}|3^y4 zgfZ7pDYgFLAL`U@-XY$vcLsRqo1^k#cva6ByWF98C#Ui!M{W!&Nwo~2{gImaMBHOE9id0enaNwQLevTeQ*fAZQ@{nP(Q{$LJOCSE4XsH z1o8v86j*;FpzG-jHBhnT$3R!F->ZD>#Eo;&wQj1~qwSQ6bu~XausSF5*4!6yhh!Pg zQO+#d=Egi(pTGNztFBc=)yrU~cDmFI)oNHc# zKYo|}!n)tU2595oYH*%nH~NQ`fwtk(&c@oz5cQ{+4}scwEa$v4rnt zW|`&6{3~%8G|ipjW0QS9H~9wGU_ z?G!uK_C|>7_|%;Ph?1KyzV4rGOWJIEQGj1WK)%calixq;;Ic(4_p&q2IbpkkZKu|fb>O#Fsbs`ZdKkw8YJby7{VAzeemXVTdsRs+BXc{7 zi|!_NHDMzr?>nJiKTcUwQ*!-Gh+>i>5|SqIJCH3|fD?){~Dox8;N%ELi%ee`vg4 z@yO2=)oZxT3PuS2-}R*cT9ROxe;RFca(sM<&0s?(CJg74>e0_~y{ZOha_kCgR@VWK zeVG>6b&9lvJkoY?@IhCuPUvr29)q91sFhW6Wxwj98h!i><|S(1Z4$*9S|UCX4LayCYC+qK#Ut`hj{G860E?vd3Fh5I-Iy=d8r z2L$TRw^Czl=NCc)LsM!N||zz90(hMVawBE+S$R`@P$XE9QkOY{605~ z-YT^Bhf-GIe8D=D&J7J((Zg@X7_VDBojfbQbms>289YNz#@HrBno{4dqDb&(oN7jfbdK0Pbe z}L$+K9yL6VLRHA$}3x|orWaB*+9s7CszfNzCNB8T_1m1MUl+2KQ{$h zr7NaF7bO2v?Q_L6c-*Wu+E212D||0Q{?MU~Q7gb|YG3saM(uJQ>Heo z0Z1zkt`-zvIIFyl!t_gl!`=^H(w%eJ4{gKt@-cYPTduMF1B116`+YP%tL6~{aMSRb5!$HTjD3x-lO2#3as3eH2RWae3>xNBlQch?=!N2>twf7xL-z6SbqGu* z+j%urAERLBz@5~(Ii@TBQnQq0pf%YRdB3HEEXIe&U^h<;`H5*;^WOM?WS-)Lz8SB* zJCP15fE*LD^tH9QaU{@2nr+`b+Br&GJA=|uX6e&W2L2%Vk^n9HAlt_DANg5qC%|AH z<8fO+%t>{BOwryxi;DV#I>0^a0Tnz5W81sy@7F) z0{Cfp*;aKytHhvBRJvtgsGM3i?veZ6U~sOO^!=nWsWGK2su*{!`oi0$=+l=j8hYO4 z!H$&;6-3ca!RS{A-9g_kGFut4Lt1L!lB# zzD`B?s%w93nw8?bfp1*axT1Flu7BkTmlDK<%&f{+7>~D2F7s50&C?DQ#=A|#Y0Q%2j zSf`CVU8rL?>mnkYH2~urh#qjMSnYow9{MOC0NS&?rwK(3VihuI+^2J41sa|>=*T{0 ztpaX_Wx$Udc|t>#!YLDaU8|{+it*$&Ux}&m-Fx9HC+@gbsn!(L+OvGry>~a_Ts2+{ z@&*h?N!hEy1_sg>I6n@hAqbZ9dU$1mj9Yq%5P;OLGRi^XTuJ(T`8wafE$0#XX#t)9 zR2U8PKi3VtB-S4P@Sb;Yy@1KgT)H*{+RY7A3ozVjeWVn946?!U&=LEp|F=%{cvm~i zI~o{@yI&TR46pg3Riv#?Dr{na1up^O6d_5WZx8%tZ8Fv?blIX@r%=N7Y8GICBv31$ zK5v*pq5>Z@`#>K9gy`tCqNl=J#YncCQ-aOprndhkFPxSL?~$AumJ5+;;<8`D_#Ynk z3GGyNzH5y0+3AUWmLc7Qm&&dXpkw|y$(148$|6gis%`^+E83_3Ra)%`NO7ACP6q{_ z54fplR^>38@sDSqi7@!l9Ii_yzb_9|@>CibXXwI~+YxSG@oh=!*dLm?@40ZW;AbgW ziaKW!FKIRNnOA+^*z9)*4X3sWg|-uqq7$!?aq2TNpaose1IBtWZw;c6I$ zx7*oyUh^)k5IeB7L(hvBKSBvM{Ao6%bwKshwrwL>YBS#DWMlet;F@DF3=NAn)?er_ z$uC~$^e+a(J}&U=5Hc`SM6Ps1363;M<3wOvyw=a!Kwd~edSV3I$v#|l-r@6%oR`Uls{WTa~}{L@nfQi+At^wB3A~{TXH}3(v>m4c38yPQX39VHfwYAxFZQOv*L*C~J$`v7F?C$3icpM1`9xYaPh>_pR zP5q>VSi=T&19&m<-h5-2d}~9p{YPiok+*A$nJ;e0$1Sh3d5yn@}c`EMA(^jIFPQDcRXlD^%;-dH)n>uL-=#G6Q;-l%Ka_RXM&cCB6;)? zaAs%eywVqvv%R;g2y_@{ILG(Ag!GLwM@uK7NCz}0r5mQFDz^H}H)S2a7Xoz4fe*<1 z_F{h}NN4!V2tz_s0h}A3Pt;9@xg(bhhm%Rf(IgiK*Vpct-?cAZEMtI+6H!*kgz(Wv zn$eSO`|+I{d)uyu4#tFuWk`9}|EcPgCy2u~G>=WlGC=mWEz%rmY&h!W%8bM|18;-?5M!YAuq}LpI6z4J-dSs z>CT#2bw`s0`ATk+rq26IcmsZy!}Wn8$||AMN-zn$qCrK+XW}k2_=TKI;k&=j8s3~Q zwwp+K4i=qADA_6HD?f&&a8ybmFo;rjpLRZ~wGV7T;`S?jU{?8!DT*`1iaH3nur=j!BaCS@DPbjS_;iO_QDRb_FFfI<0jAsmN=$HKn3mO$DGpGriRws1(1g%73d>fM>@Xji_3c<{W;P3 zup>t&e{%NjIPXnmNy(Be9H*hV5N3Ap9tY9Jz0FJ}8b)O*qcB``Mms+b@w-Fu?~)6p zdAPCipu^N5Sx|D~T!8b1&i&o*l2Zi(16dc_n(?zQ0Mtk3)H)+auTIXQ*fgNHWffCt zs@=ql?q1o+=*Wy}U-*-U=FFSU_ME3*3z0N}vZfxq8&(gIgv;6&M#|eO83Kzhj6@uj zBV{f=JC0sMO!JV<86=C;8RZOz{`7Rm?;gde9j3e$6;L7}jogFGsb+HDFHr~c;;*TW zO!nvO8ri^5{~q4@glFV1o(N^gUe8l30%(NIo&$N}hZgJrQIn#%0*H{3f3_A}`4!uPUg*_k$&)5|IE z7_iaV44wI|Lp;mX%{R3fKqB#L1Sh`FD%{au_B>_?g_2w6A4+Jzzwx>tZQ$*CmPRb| z9Qz6Jqn@oC56zfjr8Z|a2#Yoh{orURwUEk!xz!EsO#EKe!h9D{aW>4=^EQw74E_al z7atOx0u=vg$piQ(vE%#RT+3|%H`Lh{5IS;OANu2b&=%oVg|KZbI`IsPUwq!WLtdq3 zvM*MabJIoRCeF9N)|nN;GO4i~rknEs;Ya$Fx-ieQeh;>H8oTkk|cE4d% z5}VXX$}V_sPq2A6{@7O73WStD?%Z)-i38U71{CEc55wikOVGge-eX~3b3 zoGSDVS)-i{^S{O z#oO!A9Vdo(YUs>@N@Q%@*@zmE={eOC1z?t$<%7;Yx*B2&a`D19_m6ZPX~ZD+Wnax* zdh}dT86)aga5)>wMRMM!33>gw>GhaD;{69Gl1dZB;u2G=}&i^+hP*GD4huh)fc&O$R<%( z(qJJk^oecH%`D#4{fip1<<@I2H0j2(drSMf zFWTtt5N+ANOS6(7`s}>m6k9VxDB{9NiC#9pLM>vQG|986st8oD?A~MYNzGf?H_MAG zKkp=Yg`YyaTceIdtvTWuQ;6TT)^B~qCLhU{7S`)hBBGawB>jdetY8`bPIS=%X)VD5 z?8Px(mN04yyc$@NP+`eyvDklwg4(mIvA|~;-m&-h1hv;085c{xe0qi|4IS7HtJ$bw z=OK&fA2>36;i+p+)TdL-^KQue{cbZo!uP2d$8mj2U8MnkwUfM017G^KQUEXfAbjyb zE3|vTsX0s;f-_5>DNzn&h*`l=c&O8s&@@-Z%#Jfkl)Op}cf59bL)c<#vM4pF=P+Wj zsWqDA?1#74;4TYW1sgz*t>1h|Y^}*+hGDbp1=VQBv|deDhJVk1Rgqaz)xdIgsVJZY zGtgd7g|$v&iV6zKItKXz#Vlgio5J3^L;U7q1&p@=tP0yaSdj+jdzmvvy#e|fvpw9C zAulXHEKRoH_U@agtj)r#m(JHL-9wI!5|XWGh%*8=X5u2m`#c<(w6A}DVW|H~DyMj` zV3Io+V?gWhvNyNidufYP$1J_Vf_4SA`Lp*;3Mzz zdXl^Ed50(o$|F+Rd;2=+0>^DHFhRFinGwIZYuI`7N;2>9@tf8Uewll+{Y=n}n;5$> z?r7GXH}=GfGtrQIKj+xAf$^i%bCI?`fTr$5zVMIa1(`$Lj|$#JN~TlwxF#B+ks1yU zT;i0pz*X*_?F~2^Vb38A=+Ip?5Di><_eRd;>#>>cYxtX*J^Ctb70{@F=-x9uccrMK zH=JpGE?X*M%eP(nfRc<#;5~`P=t$oD*@USbT@~y4?h*{$$=n^68dM{k>;$s8lD7ul z;dHjn2&LJLE;YM(fWD)2{lST&xY)1vr)z$m2+62}XO}&U<2>h{G9N<>!V|h_Vnqg4$0eux@$KiT(N}yXAI!wvit$=^)*41Ciwn-h5z@~#C zFy$Uk5x6B4BSHI4&v|y1nEU|oeEEoJICPeGe#E#(f-%P zu~0&Sf{^XKFZfFOAxAkSof#Wk`;`pbt$qR~5dE+Wg_bIg%fn#zHC*?^-bPKGu|i$F z64*GKFJrz;r$7T2MMlXpyFiCyZ$DX=5_TY0T|m<wH)_b2IWvly;amg$ z{$SgTM5;S1tud;cScpN&ZOPs&+|?Jz7cz1Axz z;3_#P$H1eW>`EN6f@y_^c_K4*6pN2K*u!>fj@h?|wn5l)fnno@7gDLOh-0Jvf_2cc zu}tpTwX(;(O9P{N?D%@5@KlSq$4J1H*$k!CdG&2=J22O^qkXuhx_`j}PsoMXM;nzM zm*|S2@zVkE$FV^4^)OiTz!7pKN65aQ!-2L=gTc;k-R4=v<`2@5wOvz!JOi1VTY9m% zALrOin%VDCyHn{AJ-+*jemqp(mdG0v4b2ajYClr!)$BB;E$e^@XDUa2U6S?2>>Yo= zPHHFn)pB0`J$EsOA{uYw2{ZQH$c!Viz{)zOVJ1S}+L19jv}4^e8r;(x6@q9P91FRy zKJD0Ki;kfF4i8Ak@_e=q1Ds%0#JwFm1Qzr z*Jbb=n~W)r>SybDiw-=ZWhgeosB#!3CrrDGIq|(2i8Zs3{bae9RqLj2y2wu{(kQl; z_6I62evq^A^%y?tBjSJTl>ywi6i=ERnVYc#pmD-xz$Irz;BJTy5aEwnN_Oxz`sFXgJ zyd@IKO{1{t)@-1qE6uMLhA=A^Lsw!y_Td0oGz>m4u1TR~Qpu5_LGxcexur}@4$-0` zr-y9?yjUqv##vz>~hZ% zPZKS2>b}cMEu;Voo4YE!Ari{Sb%=x;<1CrRw!AfZjCU%qLi`VE$dtF!07_^8DADWtJqQWZlc&f)$R2P8 zJ$3j;vis@`0;@ zs_JbLfV7|L4cI`dnj&2;ryR*l=y`vc@7_o@23=5(f4{`z2Z^18FL$f+B zS5^RRra{y&HG%G30&x0Gc3km!;K9Vhq7y5759q5hrIn0QJF)Us;jj+W_4{O?>&auZ zF4t-2N-vZcdax_Q+Sd|;8Cj&C=MR&=3i6%~k+1Npi@><^*nkqJRl;hbx4H@J_(m=_D##natAE`eG@m|0N)=wT31rxOWx3>Lc204MQjei-IdR` zDtu3B)2wLduR+T0v=ewm|FUwkeM2zE%U0oZC}cTB)xw>fk1mkj_xOt=+d(Gv&JR%$ zKN!b#j7C0DH)MMD^^+2EFxPe@_4PO!H;PV*gAjOfmL4yVuBTwjC#2fFj*0E5z4}@Z zH|K9Nj#o!QM&-f>HvMeRc*PWc!Ur2L-rQMK$Cmm_SiH){XID(I%zO^&V7#uw90ZS| z#xaMcnPW{wtz%6gM_&OCYwFPAg1@}0z~yTDb_ISjPl&ocmpVC_K=aW$NUgKNEwyq3 zVr^kg1A`h6Cp<3P-&ia%O?v)9D#n$xe84K(xm50^M(s_eHz>Y%F3=5Cqph1^5?2Xl zX*dglA;y^`uC%)8w#~JMf@gEEpFcBWY<@E$Y(@bLcCAth5C8ereoesrum%qjhd`mZr-i#{|UuAc)-Z`n|n;SGKg^W zdb$4|h>Em%ph2uM#EhJ+M3e<*ZSGJPEG>O7Z9{fYEd`La4NC`l7Tai+NHbY<0(?Gm z;bk2ybJZy)otzj%T!JX(>U@=<>U7n7%E&$I4#$b$d`^bV7Cje@WR#@l)>x>amzldVWM&EF1!Y?88XJ$T`Z8YM5IX5^`E;C{KK;77rR(r+3O6^#(l(cX+UwGnxb22H-`-L@gN6`U~7MpXE=M+WPUn`InP>4CDJZJxZ z;Un;@C5xO(s1r(#oF(ArDsRe534h_-@M#8T@Oi5n_j)$(8<_qzxTJ^3aQ$i`s14U! zRUB5LF32?E;ChmXA+;j+qeu!MtNXh=7X}tbs}YSQasdWhch<_)g5hp~gKb6LbWR_D(@HtvOWnm_lDD@|4 zXJw@V!>M*Qz)ao${t6C(Vv<&yP#s*EIOvaED@q++yJ9g=z$zGTuwOCxwJocIU$3IW l&ehEf`VYzfpA}Ppw^kia4=WjC0dod99dmK0IC|k9{{$>>=biy*x!Rk*rJT{=h=DN^5)ExK2{Uf%ov-+R5E7k)dFIXO8w-Cn`HSv)3Vf~Zb0uoE%kJCm#no2hPYsGf zV8^;)X{+sw|9`BnQFZ1BMo01ST!7FAucwiUu3b%&;tZXPCwoWI$89^^CFVL_Rodw!sIK z0mTRfj=%{VU49tj=iqA@ou$pyHVd6&Vysi7-`_Er1eKm zdP#ohIW{PvAs95A{tpUyS(iOyl_t_LX@NXgG3HS*hlml*F?(l+j?EUkaI}0JQ_b@Y zXS`zA@B(N7lwE!%NL+1s@xTa%p^}y&#ho)b&~o~R-vCK8iR6dGDG! zleA_KCd*qJ%b?H8=AQ*qw>R{+t*va+j!T~G4jYcDS)gGxUVaglU3LX1NR}5MD7L)e zfw%JJD{7<#yfIsGHwg4Kor^(esG7h0+7%T8$FTy#{kMgEXFS&WD^_+zMcMPxJMXN5#@@ZT-nV#c-_EuT5RZp+1WXE~UO6PjzJoYL{&#I5`QnlqzUlAY3;DQyWz|kPBLW4`SvAVJ)Fip!FTYh%=9sM9#DGil&G}!U&Ld%%}Hh7 zmH&e|Ua=Oy76jS~gX{Xnr{~gJuh3R_r5Z+mm3?5ome(1s zBKPQuGI@o%4gS({+S;d)K2T?cME~R7r@rCS2>uEMT}512D;$8%7-R5Z$+r7Hwz{cc z(6Vh<=`4RzNK=>dKehZT*LKDFLzxxp`ft{Mg$4iTUVor+%Vu#E0pK*(N|hDPP@%QV zFT$Dsmy{d*o7Mf_q1_T(iU+De%QS-PZrdE>9ciUoTV-)Sq0PXo=TZOwbgZ9RUf>E+ zyDNLaCyQ6H+J80isUZeF&P#+9Mtj*0G5xUsTY0XK8qUAeETnpq{`!c8t}^HYu#>CU_f-@aTcOjd>hH=jPqXB}nEqSv^Y@JUr|H69JHk4~G8etlNv(7j zE6faxtmx9pJNZuN^|cjOeL4@a{AT~|Ek7aqe|t+H7y~W%|8PqnRdVV{SB}9=#|&`C z|4sK15I6ug_?LD2$Fsbm_A+nyAJzPX)BL+?wGvSL6=QLlALQ7|C$tLyjubzwqByc; z4AOX{57b2Sz_}Eb7ywD3=J(`nw{6e!{JOLN)-DT^52G_OjsWFM?2)70qJ7!UoGDSH%ee#|BGjr6(x4 zKN>8vzAIN%)pR*rhVcJZlmf?1rNnoahkUvbr=Xl#cEjAt(p0oobfKWifefgCjoX<7Va)=SDdU_yPRHIuIQZ&2lFPpQR z0c}^D+^AB_jhsf#9B09ID`z`14hxwH)BrW7JHwQ2S|B{9%Xze!lwyT6e0<*K`;rz6FO4HVCHFkCJ@ZT%4AW}bzN+#bg4-d z68*_=63B_~O=>deXf^Iw#a5R?#|+%ZG1;38tEH|=Ws2iQtf(Byt98&T8mpFT-8|JA zBGOpl%(3plCV}uySSe0WCr=h4-srT9QD-nJI##jb(v>Pzt8)1o$LCw0^4vIMCKFG= zv|=MGA|?`~!x6eEZ(@=iq%DIGjUrGzD0!eL2LDDjt3%LO$1u8;W#XI$;nis%kh)jq zU4YwYp`#9qXtRk8>sd3YNAoGM(K@oUZ$6Xz)G$krdC1HsYpmw^vGKpD2em0tsrI|)eB@2v*O4*%J=y$;vpkQbhLB~a5sMKw_ zO=1a+7a@#|ooTgfNZ^_nB1F>fv2m1%yJ#N~$!vYhvSJY#vlK#z10`e4a+n)xYKhu6sv_%fQgP_y0a$Z^k=GB&2)%tRkiI)Ci+eq{4+J zH_ULQ24q$Yn4O|VD;nvLjyRwlG6;t-s9o@LdX}hrwUSrR!%Qtp4mj8Zy`d0kS|+`f0*B}IW&<#WROsYO)Hno3;E$V?o3pxa zQKL$>NnwDu^W0E%b<#!tpq%?v`G>w9h z+0I5~UpEJQGxkHAXGDj{rB;jLTtPKR%1MYYlnGx`MJrN-ft{Kvw5drkhl6RwLbKIi zX4J4)n3QQ`h-uV7fy0_l#f(4hNaL1b^%2q~E7>eNja_VD4Iwbk6`&au-1O*iV2d_5 z#(;pMK~BayEiwd_m18>-!wH*Z758~CE_YfIYJD#wX|T*L8%I>^ceH+a)?j*|OG>JJ z5hr1AXQI-)Ug$%zT?#0%n6zS`7^&VBIjtix>Ws<`vu(K6WJO=~O={9WgCVI>Ns=r3 zEzpdsDrKOD)D++xs@^I@QF$5}rKqP@L4o92Fh2qZ0zE)`rM{xUTyCfhIoLp=Q7wYg z^(vIW{erxb^$~HL9pt*oc-8?$;E#7u6`J)}0kb>xq=!b0jLx;>CI`;hC8W$@z{b|J zRJ7Gr6xx%L*lh>$bP^AUCMcZH6*q_mFlRzoO>6SD;v&tWR6s|njawAeDQih3&Jl=e z={?0%&2r8}iAfda#&A{T5@)1#TrFEz<|k75$S8apk@F(eiLwMYu6aeljeMqulT^D< zlY0{zRz;uml|e}xh^{mfEA1(;ACv{iaym7bqSu(>2yVAWh+foc99Rn)E!4~C1S5<@ zHF1A5NopFJ_sJoP3ME{lI<`i4fP}Fbe~iSbX4I!jekLf2+YBRceGtc8Fx_-NGXy86 znmQ{v-G-?8%`hI4tv+e-gbk+2rY)h&hRBRgnAtcxB_}YAh$!2@*@gla1*207MSBVy zIW=*EdbXzqY>{&cExahoWH=p7+LR-wH)6$6$Eq~QA=N?rsaR1tOa$e4UhJ4$GRO?# zOn=xH#c{0_hbzIPB)bjO&0~nE!XW~0d9_grOQwj-=0dqkh`Xb7XrK(~^H9xbTU|yT38aXPgYvM@hbMZV!Jxfy8^vv-Y}2glz}85%5)a`77D{6|c`SVuCP)A543?QR3}%(G_o& zkwz84MykG1o)&Eu;e$@bQD)98!#2b*Sq+k6rq`MD+pz5j&0*>e6MqV~bW@#@4kYC9 zaMteY(_*dAWm+~$648)Ipp0rl!-2|LF2UrSnTFe9tZ%XX_~l!~~Xnb<%HU_mL2I7W(Dv_qlnnB&w@ zK(wkk1LhN5(HXLjqOEK)Y7~L9P!)36pN$Gu%gokC9ZDC%3evCCaHd^v!u&vwM2=M3 zc3qzcyj>A`Qol=&YyPa28n?E>kp@RGU7#S8AXSGZR8B!jQWe#q5|P?8H3n5_hGc3Q zj1y+PTpBgCd|3kP<`qp-tTIVCn8B4&gEeSW?NQS%Z>FlD*Q+&c)~uF=fSyb#)AA)l zg<&F%3K_SHxALWIUL(jsXp)xb_og#O8q`2HrdGZbN45;EnV|hqbHIT}lm;p~C|8=H z!yyI-E9o6VR%%zOWu=irCj%rkT#Ql5+e*mGU9_PJeBbnWCPirdF4S;ydZtA(BBsuI zsM9h_Wsa2j7FEm(lT4|kP#od4bfVx|gPiAz5<&9W62>g{T%I#vPIo%8HAbz zmX}jXXpynn0W0RD38=c%k{WWjD^BzED&ABEJw0^rEF^aHUV!N0s8ybT znW3giq(Lr-1f(RMaDB5>*Hv>xD^0N_|Jhj+kz5 z>T@=dRs4b`5bYtu@LilGkvdoln(G>=8ssy@Mkz;+!x}|4g}4;e!dazCGc}bJX${kW z%WIg;1hs>-*Bwa}TpIWmitcE5Y(eEz{FzQ)AVM>%kA}d^(e%(NQ(TuY$Etv$iaQkb zI#>3+P;QR%J*7!QqN2k1bc{?@K}xaRtkZ|<) zVI{>58`F$EZdleNPeQ#R01~1)$cb zUYZ4>*4D_nJg$ji(8!vG9S{kMJ8*`M1BVGiPH0vF*vXHxL|GZC%^(_<$y^Cd0YaAz)+609{_P3aLpFfRkNTZB<$m!4`lk(~DQKa{u!L3Xp`fL;v;Eb!-I7nCsg+w?yb=I6JKaT4%)-vlPg&vlSOY)J)11s1(CQpjC>j$8K&GAeq<~206enfLp>n zyE2Z&U=jh|*Xh*g{Ge4S{>||u%NNYZ1Q&()xbBCb@lp;W#tnAT zC=}4bpx5Y`-MXsAf~*d*lU{yOX8P%p_jSYtUj-18&5&GUk}Vbn)|iKp0PR~v2T@`q zq(>>Ud0i0E&zB@zsJUc-1nHIRT z+iWMDvYT(@(_z=Gaux>>Bsig~?TOuKcw-1DviPWPMC6REdX)eT$>lRd%_z620q#^7 zk3pzE1Av<1D&&+m>^20r9}s4hy4@aM&oO?MwDMXJU^=>vH@XhtrU5)%lp1g)H}s)k zjLT}v3#+ws;8Qf$Yo@d&Goz)7o{D-=Y7PR$9T2>k1`ZzJtf%TIR#K6u0{&4Ar%D~~ z@{z{ZQ<&^)dg653EL!X{q0WO^5GakbcAbI-M2WA|t5()1H#I2J^jsxY8`Cir0n|gs z^+_r(HKJo9B3re@e&{-c(57Z&62gU~+G=DI-5vKkl5MkbPj2>wp$DQirBh&LHB-p> zwg564^Q6p(by{z*qXg|b3`Iit)MZsus#jG^X|S_w$8?w!#nVk8$wrkvpwxPhpFlmo zkslHTDlX%VzFIC!g>tS1`bPE28t!|5ijfqYkT_Abpc!w-ZG?&F-n0gy6k2q{Sy^PH z7TXlUqF_3ptZmDvSTVZ|9c8;(r=2g67zfI+7Eu8cNY(gmTu(5sYX{v}Rn0Ivjzbk0 zkL^y6Bif9PW-0@8R0^OWQp6*@8sd%NbPRQH6z~QVG|N}(s7(+Z*%Y|xAde|^YKAwt zWkc(<)!tZ>#kgKChD~|Ug&0#3dbP0N_OL7mHWqS*uNYu?Xuz}Rvq&95NMWCmt^|n2mpbU-ndXP*e zA|A*jIdSP`*N@d;?APmwN>4ImJDvt+CO@uISjP;yt}x+)x+Bkqg5~FjIgQ2>Rgou_ zhE!}v@0YxKOQoo8-xF#rp9$rfAdaR+?Rsqc z1k`XKV3a5$(;Sc6w5g#qE=FB>)=~|e?UyW1HIx#dGgz*HPGX{-i%F5L=L<#yZce0Z zG^N~-n~m&d!eXVqG0NCnF~V~RU-C7kP-Sg+U{y0r-*J?h{>`=V}w_s;mE4x zTfl8K#zU{`mSn5%R+9wq0T2b{>Q%l=>XUwM8u)!XC2LeLJQxBzeUVXl&mySM^*V)A zR;v}l> zI+&gDgvo3$8Mza|tlKJ)w#(SrdYpuO((7gMYFFuzs$ZEj0ToUA<1wFxr%JWtK0cm z26V~L@~#+)WCt9V@yIB;R>ta;;8s=iK#?tDOn2IDQLK$-naotE4pPLCaZ9=obek00 zDz{x&fW?5GCP<7?4bDzHTjYT#)Y*F35v*~$HA;Zy$PKf()%uCUsHyplf6%L?kzg zWSVn8SK37{QlWTOM_@9MdA^WRlYDugSEQ0Z0moS`9(UxVn~=V%AVw}V%+0RUXQpU8 z0ybOh)zkr0G&QBq0YPAtvV;E5qs%r*u^&wwjd?Z0AlPg2HA1 zLeNBpYT>DU82O_Vy(Wbe+=bzE3VzIzB%T&gjrO8iAcRCv<}&><*b|NVJ#bp2YQo;DH#PM?3gvCT0YVCM3h(j(9PfY`lbM-+-#7SYdY|U zg;8b*upOntV;kvG&4?PvWFZrm8iLwqtbVytn^9%Q1Q8U?&<(?5ib5v@KgOzFoQ$Uq z+Zvjb+h-s-rw_-9L_ov79gI|xjiXo<7m}S*wfp1Q&4&&Aw%^X0+q&P;hI_V8MxfDm$3O3Tg(pjWS zW1Fxex?ND?x~rIDsDOt-xsQyz)F{|JsKQO8Q8vmEc*-@asl9B2t#o?mj#FWTBh+%+ zu>?WGN{yAr6I;Y}SRzZKx|5Q%cFO>M%J&j97m4(&M3suD%2f+-Ta+3$*8+f$?nF^Z zs%uh59ss8iP)c23r4~p?5Sl$dhvjQ*tZBu#$a_f+7!#^jKysOmEz25}2k9xzYOxdp z<5chy%fJG+&@;S@$U%du-Y5%$L>LYV-G*xhd?Oiyr%49Wuw5iZWv8xp>TzmN@qQt1 zqj-J@IByX1LR-eWi&0f1!m5f1|#fIH*kmvDsxzkYz$1kv5dn8eyeiqjN zT^Y?}JX=aE9Ig%hfm$$G7%IBbM2hp{>M(^lLlbpSC>JwQzLY2Wr7l;7p1jX zz!8b*GA0nHJZ>dYQ|R^VY%ZvFW}JWuppw*eNOV%;v$2#32)R1rV60XsSOLvgvCNH` zwC`>`J0!8{l)<}zN3|1I5ZQWabKBs9=5V+e<4Rzfxk)yIgfpBk3sbW~=lX&JVF{Vx z+LqSgb#&&U@MJ9T0l0;1RMH3?XzvZ#$r{m13VZ- zPRB{M?c}G?h@tvmKPV4uI#tFefu*vIj-Hgb#$XaF%&gQNak!4xa(>lE+8r+J#3aJ8 zR_getWg3?adFBBBMRh_?tocQ0)-BPzi%@(WuQUm=1+sSois`E(;3_GX(Wt--2xQ3j z``z3`!OgIjA<}_V5voSh4Y1Ry44Sok+Dk$-;VLT!5N;Rz(F`7z4X2j+N}q@ulMF*z zcCONPa3z~YU2L}J7y6T=G0f-=ohg8Xg&AN1{BZ!zQd7T=gCV&H4_p>CDF~%33XD!A zQ5)e%Y**^BEP+Ic&;{TD^1?0>^Gw448<|csQQN6W=yuu_H&^LSCL+@`)MY!_h#yS4 z@Q|$Znu9{o^(KB7Y&BL*EUIA>%qYSFp@!15k_l5#RWCFZqvO%lYD(PEBKQZnnm&_y zmC{I{dloGx%M9tPqGO{G;5_M8y`mcf!>p&{rhsXqVA-styDt`$SIYh#4@>UA@3d<^U<2r~Rn7Qv;U+d!oZ~#dUM-y4Ga? zz)ke18V+Z`p-}xyiLFXCFG>hf=-Pb7v3W%e^%-F&+1j*J9Bav}>{>kthE=**_N5V< z=0jQLj59`l3=ZLHwF~*R)@)Q0HPddBHlm^BQYQhBu$gJ0Ma-PF8*T}sQC@0O)iDOg zajC@zZOtwZ)DfeM9If1s!(Ogl=d~2DkL`9@wnd>XT9yJAxPTe=$u_u`k(uTDV|hB` z@=8(=#6%E$wwdTcqc#e}c2z67u86SBBGxVR`jb(RH9_bhhrTppDqc?VkF42i7jT?iQK{kwKp+`xPsuNb7i3D(1)h2GiP08%I zFwhhl17Qtc^oKmr!%T-~dU-?Y7S&pJM!VIltf}?DvvV`5uEA2$4qH}!YK2VI22)B) zLR}H;CYR`iYOmQf8xl1{3BZ1EYIiX3xJfO9K^C3b>A)$UWJD!0Y$J8oM{;U21f_ zgG7K<-Qf(ysyiANk{vG_)oE~Jb>xzAzezSlr2|>ssHCD}ic$0U$o8ikO4>LQCuk{= zWf1b^9l-JRD>ms6;;3g%!;BH799zH0L*S9zu~@~WNdkAHf&a#8fNY|zyQ5(j&@O-mGe1SwbCYo>{l*+7N^tjcTBFREz+M2Y6hlUl!2_s>C39RkrF_FBka@BnzVX zl-Q$~rZ?=NAo9HJlP(C6EM9AmU7N)uIjkWlFJl(w%{1g=P(43PBj*xKqdzUK=q1R|!u9 zoA;)CIWYO$xKd6*La*3XoESJ1y5yJS9_tYG#!zz_+{DyHsMr)xqT28Hot}mb8%4j9 ztM?!);b$-h+s3q-@1%5BDaWYFEH7kCuI(^(fv$$-2GN>&GM8^mQ*0qltw`Eo{SnOX=n>^hQ@s(QcZgXWM?W(sU< zPtRqN2|1JLN{h7Ff{_L1qKxl(LCvZlRw{3_3{0C<96D->hrp!Mc0%gYF!7@-G?lSg zitKzGv3Q{_vCVoe0#MO0n>NmJ*(%2wf|@Iiv|Nh8qNL;EdcQp~IHlI-``sC4YT$CP zPc-TYvC>OGx)2s;(&>caxDttQYFdhz(@70ZfCuVUt0SWdKtCEugLZ(m zK?K}w3MOaAGC*@O7z)kj${>5xbw+8Z+MBY)xQEr-K@%7dknTg|2rAR>>pdcy+OU?F z21>IY_^3AEf?pOexJwSZlP;Rf5V|HNo=Qul0DyV1td3h=A%mi2qSdY9IF8k=Nxj$S zC)rj^VS}_0@Z2;QMXr}Zb6PCHqdX&5ExG3BGxo^Vo4HaC@Y6l`nF`Y%D0cmw7zy=`|4ow5lc-SF% ztQb@a%OVmalVFNN=oZXTMkD1faE*xpz@)PLuz`UH+Z5_duH2?edBZH%%wCN%V_BYY zeX9c}{SFhh6uUdJi$JRBzV8*s6{N1`=`LF9Q}i&`3d77epdyI|L1~i?6KKX&y0(Bi z;AxIJJZ<33RxgKIxtS~=UBt=)HW1vs@8+X{Yxy$-WXMBUw^<#}Ld6+QnrU)At%g~* zrSJ_vfH%$zBdk#MkiJG3fYz>a*nS<>rHfsPnvduWU`Uu*kcb$sKKn9;6YsmxDU%H7)qg5ESX55Xw9$!A;o=8pmI)40hFW`3m(WGRE9_wst-7! z4r5^GU~4#!0^m+fL)&#brrD|Col2D9G@k4W2&+OqL1Tp&ZyS?@o_4E|Y=DP5TD215 z5vA0*)r<%Opc5Hnx&?T|#2Eyk3yq}JZ|4VnY;3?zyBM`io~ZQmReX@v7 zAC2_lp-T<2Zil1W1A=LqBxifG={Q4bAftiR$Kq^?n%NfP&I(L5C*jLzT|*cm2r

  • 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

    O4kD58 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 Date: Thu, 30 Jan 2025 14:15:33 +0800 Subject: [PATCH 58/65] test: add health checker router --- backend/app/api/main.py | 3 ++- backend/app/api/routes/utils.py | 8 ++++++++ backend/tests/api/api_v1/test_utils.py | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 backend/app/api/routes/utils.py create mode 100644 backend/tests/api/api_v1/test_utils.py diff --git a/backend/app/api/main.py b/backend/app/api/main.py index 584979c..2a387e0 100644 --- a/backend/app/api/main.py +++ b/backend/app/api/main.py @@ -1,6 +1,7 @@ from fastapi import APIRouter -from app.api.routes import items +from app.api.routes import items, utils api_router = APIRouter() api_router.include_router(items.router) +api_router.include_router(utils.router) diff --git a/backend/app/api/routes/utils.py b/backend/app/api/routes/utils.py new file mode 100644 index 0000000..e63178e --- /dev/null +++ b/backend/app/api/routes/utils.py @@ -0,0 +1,8 @@ +from fastapi import APIRouter + +router = APIRouter(prefix="/utils", tags=["utils"]) + + +@router.get("/health-check/") +async def health_check() -> bool: + return True diff --git a/backend/tests/api/api_v1/test_utils.py b/backend/tests/api/api_v1/test_utils.py new file mode 100644 index 0000000..66b9cb3 --- /dev/null +++ b/backend/tests/api/api_v1/test_utils.py @@ -0,0 +1,13 @@ +from fastapi.testclient import TestClient + +from app.core.config import settings + + +def test_get_item(client: TestClient) -> None: + """Test get item by id endpoint""" + # Make request + response = client.get(f"{settings.API_V1_STR}/utils/health-check/") + + # Assert response + assert response.status_code == 200 + assert response.content From aec3929e5296374b543e4bb94d4f2a990788afc7 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 15:29:11 +0800 Subject: [PATCH 59/65] fix: pg deps in Dockerimage --- backend/.dockerignore | 1 - backend/Dockerfile | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/backend/.dockerignore b/backend/.dockerignore index 9f2e657..a40f03f 100644 --- a/backend/.dockerignore +++ b/backend/.dockerignore @@ -182,4 +182,3 @@ assets docs CHANGELOG.md mkdocs.yml -tests diff --git a/backend/Dockerfile b/backend/Dockerfile index fc9218e..44db901 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -5,6 +5,13 @@ FROM python:3.12-slim-bookworm # Ref: https://docs.python.org/3/using/cmdline.html#envvar-PYTHONUNBUFFERED ENV PYTHONUNBUFFERED=1 +# Install system dependencies including PostgreSQL client library +# hadolint ignore=DL3008 +RUN apt-get update && apt-get install -y --no-install-recommends\ + libpq-dev \ + gcc \ + && rm -rf /var/lib/apt/lists/* + # Change the working directory to the `app` directory WORKDIR /app From efc00ed7c1071fff3f0db9d16047b23629ae6d4d Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 15:29:31 +0800 Subject: [PATCH 60/65] chore: clean up --- .env | 4 - .../fastapi-supabase-template-for-llm.png | Bin {docs/assets => assets}/logo.png | Bin compose.yml | 0 mkdocs.yml | 184 ------------------ scripts/docs.sh | 21 -- scripts/pre-commit.sh | 3 - supabase/config.toml | 2 +- 8 files changed, 1 insertion(+), 213 deletions(-) rename {docs/assets => assets}/fastapi-supabase-template-for-llm.png (100%) rename {docs/assets => assets}/logo.png (100%) delete mode 100644 compose.yml delete mode 100644 mkdocs.yml delete mode 100755 scripts/docs.sh delete mode 100755 scripts/pre-commit.sh diff --git a/.env b/.env index 987a93e..d8e7686 100644 --- a/.env +++ b/.env @@ -28,7 +28,3 @@ POSTGRES_PORT=54322 POSTGRES_DB=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres - -# Configure these with your own Docker registry images -# DOCKER_IMAGE_BACKEND=backend -# DOCKER_IMAGE_FRONTEND=frontend diff --git a/docs/assets/fastapi-supabase-template-for-llm.png b/assets/fastapi-supabase-template-for-llm.png similarity index 100% rename from docs/assets/fastapi-supabase-template-for-llm.png rename to assets/fastapi-supabase-template-for-llm.png diff --git a/docs/assets/logo.png b/assets/logo.png similarity index 100% rename from docs/assets/logo.png rename to assets/logo.png diff --git a/compose.yml b/compose.yml deleted file mode 100644 index e69de29..0000000 diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 9df793e..0000000 --- a/mkdocs.yml +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright (c) 2016-2024 A.J.Zeller - -# Project information -site_name: fastapi_supabase_template -site_url: https://atticuszz.github.io/fastapi_supabase_template - -# Repository -# To display a link to the repository of your project as part of your documentation: https://squidfunk.github.io/mkdocs-material/setup/adding-a-git-repository/?h=edit+uri#code-actions-edit-this-page:~:text=In%20order%20to%20display%20a%20link%20to%20the%20repository%20of%20your%20project%20as%20part%20of%20your%20documentation -repo_url: https://github.com/Atticuszz/fastapi_supabase_template -repo_name: fastapi_supabase_template -edit_uri: edit/main/docs - -# Copyright -copyright: Copyright © 2016 - 2024 A.J.Zeller - -# Configuration -theme: - name: 'material' - features: - # code - - content.code.copy - - content.action.edit - # footnotes - - content.footnote.tooltips - - ## navigation - # The site_url setting must be set - - navigation.instant - # The progress indicator will only show if the page hasn't finished loading after 400ms - - navigation.instant.progress - # top-level selection move to top tabs - - navigation.tabs - # default to be expand - # - navigation.expand - # enable turn to before or after page in page button - - navigation.footer - # back to top - - navigation.top - # When anchor tracking is enabled, the URL in the address bar is automatically updated with the active anchor as highlighted in the table of contents - - navigation.tracking - - # When anchor following for the table of contents is enabled, the sidebar is automatically scrolled so that the active anchor is always visible - - toc.follow - - # search - - search.suggest - - search.highlight - - search.share - palette: - - # Light mode - - media: "(prefers-color-scheme: light)" - scheme: default - primary: white - accent: green - toggle: - icon: material/brightness-7 - name: Switch to dark mode - - # Dark mode - - media: "(prefers-color-scheme: dark)" - scheme: slate - primary: black - accent: deep purple - toggle: - icon: material/brightness-4 - name: Switch to light mode - - font: - text: 'Lora' - code: 'JetBrains Mono' - - # # logo from https://obsidian.md/brand - # favicon: assets/logo/logo.svg - # logo: assets/logo/logo.svg - - icon: - edit: material/pencil - repo: fontawesome/brands/git-alt - -plugins: - # The git-revision-date-localized plugin adds support for adding the date of last update and creation of a document at the bottom of each page - - git-revision-date-localized: - enable_creation_date: true - type: iso_datetime - # adjust to obsidian path - - obsidian-bridge - - pub-obsidian: # https://mkdocs-publisher.github.io/setup/installation/ - obsidian_dir: .obsidian - backlinks: - enabled: true - callouts: - enabled: true - indentation: spaces - # links: - # wikilinks_enabled: true - # img_lazy: true - # image zoom - - glightbox - - search - # - blog - # - rss: - # match_path: blog/posts/.* - # date_from_meta: - # as_creation: date - # categories: - # - categories - # - tags - -extra: - social: - - icon: fontawesome/solid/paper-plane - link: mailto:zhouge1831@gmail.com - - icon: fontawesome/brands/github - link: https://github.com/Atticuszz - - icon: fontawesome/brands/linkedin - link: https://hk.linkedin.com/in/atticus-zhou-250a88323 - - - -markdown_extensions: - ## page - # The Table of Contents extension automatically generates a table of contents from a document - - toc: - permalink: true - ## basic markdown - # attr_list - - attr_list - - markdown.extensions.codehilite: - guess_lang: true - - markdown.extensions.toc: - permalink: true - # The BetterEm extension improves the detection of Markup to emphasize text in Markdown using special characters, i.e. for **bold** and _italic_ formatting. - - pymdownx.betterem: - smart_enable: all - # list - - def_list - - pymdownx.tasklist: - custom_checkbox: true - - # highlight - - pymdownx.mark - # strikethrough - - pymdownx.tilde - # admonition setting: https://squidfunk.github.io/mkdocs-material/reference/admonitions/#inline-blocks-inline-end:~:text=Custom%20admonitions-,Admonitions,-%C2%B6 - - admonition - - pymdownx.details - # table - - tables - # footnotes - - footnotes - #code - - pymdownx.highlight: - anchor_linenums: true - line_spans: __span - pygments_lang_class: true - - pymdownx.inlinehilite - - pymdownx.snippets - # math - - pymdownx.arithmatex: - generic: true - # mermaid - # - pymdownx.superfences: - # custom_fences: - # - name: mermaid - # class: mermaid - # format: !!python/name:pymdownx.superfences.fence_code_format - # emoji - # - pymdownx.emoji: - # emoji_index: !!python/name:material.extensions.emoji.twemoji - # emoji_generator: !!python/name:material.extensions.emoji.to_svg - # Image - - md_in_html - -# math and mermaid -extra_javascript: - # - js/katex.js - # - https://unpkg.com/katex@0/dist/katex.min.js - - https://unpkg.com/katex@0/dist/contrib/auto-render.min.js - - https://unpkg.com/mermaid/dist/mermaid.min.js - -# extra_css: -# # katex.js -# - https://unpkg.com/katex@0/dist/katex.min.css diff --git a/scripts/docs.sh b/scripts/docs.sh deleted file mode 100755 index b20de66..0000000 --- a/scripts/docs.sh +++ /dev/null @@ -1,21 +0,0 @@ -#!/usr/bin/env bash - -# with plugins -run_uvx() { - uvx --with mkdocs-material \ - --with mkdocs-git-revision-date-localized-plugin \ - --with mkdocs-glightbox \ - --with mkdocs-obsidian-bridge \ - --with mkdocs-publisher \ - --with pymdown-extensions \ - "$@" -} - -if [ "$1" == "dev" ]; then - run_uvx mkdocs serve -elif [ "$1" == "deploy" ]; then - run_uvx mkdocs gh-deploy --force -else - echo "usage: $0 {dev|deploy}" - exit 1 -fi diff --git a/scripts/pre-commit.sh b/scripts/pre-commit.sh deleted file mode 100755 index 6da2e5d..0000000 --- a/scripts/pre-commit.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/usr/bin/env bash - -uvx pre-commit run --all-file diff --git a/supabase/config.toml b/supabase/config.toml index 0f39a75..995f49b 100644 --- a/supabase/config.toml +++ b/supabase/config.toml @@ -1,6 +1,6 @@ # A string used to distinguish different Supabase projects on the same host. Defaults to the # working directory name when running `supabase init`. -project_id = "fastapi_supabase_template" +project_id = "test" [api] enabled = true From 14ff9151c76bfa31235db60ce19a4d9c1611885a Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 16:24:27 +0800 Subject: [PATCH 61/65] chore: add update-env.sh --- .env | 2 +- scripts/update-env.sh | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 scripts/update-env.sh diff --git a/.env b/.env index d8e7686..0e1a2f9 100644 --- a/.env +++ b/.env @@ -17,7 +17,7 @@ FIRST_SUPERUSER_PASSWORD=admin12345 # run `supabase status` # API URL -SUPABASE_URL=http://localhost:54321 +SUPABASE_URL=http://127.0.0.1:54321 # service_role key SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU diff --git a/scripts/update-env.sh b/scripts/update-env.sh new file mode 100644 index 0000000..bf57c16 --- /dev/null +++ b/scripts/update-env.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +temp_file=$(mktemp) +supabase start | tee "$temp_file" + +SUPABASE_URL=$(grep "API URL:" "$temp_file" | awk '{print $3}') +SUPABASE_KEY=$(grep "service_role key:" "$temp_file" | awk '{print $3}') +POSTGRES_PORT=$(grep "DB URL:" "$temp_file" | sed 's/.*:54\([0-9]*\).*/\1/g') + +sed -i.bak \ + -e "s#SUPABASE_URL=.*#SUPABASE_URL=$SUPABASE_URL#" \ + -e "s#SUPABASE_KEY=.*#SUPABASE_KEY=$SUPABASE_KEY#" \ + -e "s#POSTGRES_PORT=.*#POSTGRES_PORT=54$POSTGRES_PORT#" \ + .env + +rm "$temp_file" +rm -f .env.bak + +echo "done" From 122867c7ebf6e3d2d16a8a29216c279bf3eafd1a Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 16:36:07 +0800 Subject: [PATCH 62/65] docs: update README.md --- README.md | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2b81d94..21c8390 100644 --- a/README.md +++ b/README.md @@ -23,11 +23,15 @@ brew install supabase/tap/supabase launch supabase docker containers ```bash -# under repo root dir +# under repo root supabase start ``` > [!NOTE] +>```bash +># Update `.env` +>bash scripts/update-env.sh +>``` > modify the `.env` from the output of `supabase start` or run `supabase status` manually. ## Test @@ -42,6 +46,26 @@ scripts/test.sh scripts/tests-start.sh ``` -1. [x] test_main.py -2. [x] test_crud/ -3. [x] test_api/ +## Docker + +> [!note] +> `atticux/fastapi_supabase_template` is your image tag name, remember replace it with yours + +build + +```bash +cd backend +docker build -t atticux/fastapi_supabase_template . +``` + +test + +```bash +bash scripts/update-env.sh +supabase start +cd backend +docker run --network host \ + --env-file ../.env \ + -it atticux/fastapi_supabase_template:latest \ + bash -c "sh scripts/pre-start.sh && sh scripts/tests-start.sh" +``` From 62ef84efa717730567c2e89914ac174bb3be9164 Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 16:36:26 +0800 Subject: [PATCH 63/65] ci: add tests --- .github/workflows/docker-image.yml | 27 ------------------------ .github/workflows/docs.yml | 33 ------------------------------ .github/workflows/main.yml | 27 +++++++++++++++--------- 3 files changed, 17 insertions(+), 70 deletions(-) delete mode 100644 .github/workflows/docker-image.yml delete mode 100644 .github/workflows/docs.yml diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml deleted file mode 100644 index 5885c83..0000000 --- a/.github/workflows/docker-image.yml +++ /dev/null @@ -1,27 +0,0 @@ -# name: Build and Push FastAPI Docker Image - -# on: -# push: -# branches: -# - main - -# jobs: -# build-and-push: -# runs-on: ubuntu-latest -# steps: -# - name: Checkout code -# uses: actions/checkout@v4 - -# - name: Log in to Docker Hub -# uses: docker/login-action@v3 -# with: -# username: ${{ secrets.DOCKER_HUB_USERNAME }} -# password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} - -# - name: Build and push Docker image -# uses: docker/build-push-action@v6 -# with: -# context: ./ -# file: ./Dockerfile -# push: true -# tags: atticuszhou/supafast:latest diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml deleted file mode 100644 index fbd21ca..0000000 --- a/.github/workflows/docs.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: mkdocs -on: - push: - branches: [ main ] - -permissions: - contents: write - -jobs: - deploy: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - # get full git commit to adjust for git-revision-date-localized plugin - fetch-depth: 0 - - name: Configure Git Credentials - run: | - git config user.name github-actions[bot] - git config user.email 41898282+github-actions[bot]@users.noreply.github.com - - - name: Install uv - uses: astral-sh/setup-uv@v3 - with: - enable-cache: true - cache-dependency-glob: "" - - name: deploy github page - run: bash docs.sh deploy - -# Reference -# 1. https://squidfunk.github.io/mkdocs-material/publishing-your-site/ -# 2. https://github.com/Kludex/python-template/blob/main/.github/workflows/docs.yml -# 3. https://github.com/astral-sh/setup-uv/tree/v3/ diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 74d6ccd..1bbf05f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -21,24 +21,31 @@ jobs: uses: astral-sh/setup-uv@v3 with: enable-cache: true + - name: Install brew + run: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + + - name: Install Supabase + run: brew install supabase/tap/supabase + + - name: Start supabase + run: supabase start + + - name: Update .env + run: bash scripts/update-env.sh - name: Set up Python ${{ matrix.python-version }} run: uv python install ${{ matrix.python-version }} - name: Install dependencies - run: uv sync --python ${{ matrix.python-version }} --all-extras --dev + run: | + cd backend + uv sync --python ${{ matrix.python-version }} --all-extras --dev - name: Run tests - run: uv run bash scripts/test.sh + run: | + uv run bash scripts/pre-start.sh + uv run bash scripts/tests-start.sh - - name: Run linters - run: uv run bash scripts/lint.sh - - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} release: name: Bump Version and Release needs: test From 3d2e84c34159ca432f9258aba332d7c8919d01af Mon Sep 17 00:00:00 2001 From: Atticuszz <1831768457@qq.com> Date: Thu, 30 Jan 2025 16:42:02 +0800 Subject: [PATCH 64/65] ci: update ci --- .github/workflows/main.yml | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1bbf05f..ee458cc 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -25,27 +25,20 @@ jobs: run: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - name: Install Supabase - run: brew install supabase/tap/supabase - - - name: Start supabase - run: supabase start - - - name: Update .env - run: bash scripts/update-env.sh - - - name: Set up Python ${{ matrix.python-version }} - run: uv python install ${{ matrix.python-version }} - - - name: Install dependencies run: | + echo >> /home/runner/.bashrc + echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)"' >> /home/runner/.bashrc + eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv)" + HOMEBREW_NO_INSTALL_CLEANUP=1 + brew install supabase/tap/supabase + bash scripts/update-env.sh + uv python install ${{ matrix.python-version }} cd backend uv sync --python ${{ matrix.python-version }} --all-extras --dev - - - name: Run tests - run: | uv run bash scripts/pre-start.sh uv run bash scripts/tests-start.sh + release: name: Bump Version and Release needs: test From a428566d03d058944ea82063621673ca8a0a87e6 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 30 Jan 2025 09:07:08 +0000 Subject: [PATCH 65/65] =?UTF-8?q?=F0=9F=8E=A8=20[pre-commit.ci]=20Auto=20f?= =?UTF-8?q?ormat=20from=20pre-commit.com=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- uv.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/uv.lock b/uv.lock index dcd599d..2596d9f 100644 --- a/uv.lock +++ b/uv.lock @@ -1,5 +1,5 @@ version = 1 -requires-python = ">=3.12" +requires-python = ">=3.10" [[package]] name = "fastapi-supabase-template"