From f5acd6fbe21b26e4b8919d084d896f127bd5fd68 Mon Sep 17 00:00:00 2001 From: Eugene Yurtsev Date: Thu, 29 Feb 2024 14:27:26 -0500 Subject: [PATCH] Initial draft --- .github/actions/poetry_setup/action.yml | 91 + .github/workflows/_lint.yml | 83 + .github/workflows/_test.yml | 57 + .github/workflows/ci.yml | 108 + .gitignore | 162 + LICENSE | 21 + README.md | 63 + backend/Makefile | 60 + backend/README.md | 1 + backend/db/__init__.py | 0 backend/db/models.py | 134 + backend/extraction/__init__.py | 0 backend/extraction/parsing.py | 65 + backend/extraction/utils.py | 52 + backend/poetry.lock | 4243 +++++++++++++++++ backend/pyproject.toml | 91 + backend/scripts/__init__.py | 0 backend/scripts/run_migrations.py | 59 + backend/server/__init__.py | 0 backend/server/api/__init__.py | 0 backend/server/api/examples.py | 74 + backend/server/api/extract.py | 56 + backend/server/api/extractors.py | 93 + backend/server/extraction_runnable.py | 208 + backend/server/main.py | 65 + backend/server/retrieval.py | 72 + backend/server/settings.py | 24 + backend/server/validators.py | 15 + backend/tests/__init__.py | 0 backend/tests/db.py | 51 + backend/tests/integration_tests/__init__.py | 0 .../integration_tests/test_extraction.py | 88 + backend/tests/unit_tests/__init__.py | 0 backend/tests/unit_tests/api/__init__.py | 0 .../api/test_api_defining_extractors.py | 72 + .../tests/unit_tests/api/test_api_examples.py | 76 + .../tests/unit_tests/api/test_api_extract.py | 86 + backend/tests/unit_tests/conftest.py | 3 + backend/tests/unit_tests/fake/__init__.py | 0 backend/tests/unit_tests/fake/chat_model.py | 45 + .../unit_tests/fake/test_fake_chat_model.py | 30 + backend/tests/unit_tests/fixtures/__init__.py | 11 + backend/tests/unit_tests/fixtures/sample.docx | Bin 0 -> 36715 bytes backend/tests/unit_tests/fixtures/sample.epub | Bin 0 -> 32134 bytes backend/tests/unit_tests/fixtures/sample.html | 1 + backend/tests/unit_tests/fixtures/sample.odt | Bin 0 -> 42127 bytes backend/tests/unit_tests/fixtures/sample.pdf | Bin 0 -> 79140 bytes backend/tests/unit_tests/fixtures/sample.rtf | 160 + backend/tests/unit_tests/fixtures/sample.txt | 42 + .../tests/unit_tests/test_deduplication.py | 54 + backend/tests/unit_tests/test_parsing.py | 46 + backend/tests/unit_tests/test_upload.py | 22 + backend/tests/unit_tests/test_utils.py | 104 + backend/tests/unit_tests/test_validators.py | 16 + backend/tests/unit_tests/utils.py | 25 + docker-compose.yml | 30 + 56 files changed, 6859 insertions(+) create mode 100644 .github/actions/poetry_setup/action.yml create mode 100644 .github/workflows/_lint.yml create mode 100644 .github/workflows/_test.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 backend/Makefile create mode 100644 backend/README.md create mode 100644 backend/db/__init__.py create mode 100644 backend/db/models.py create mode 100644 backend/extraction/__init__.py create mode 100644 backend/extraction/parsing.py create mode 100644 backend/extraction/utils.py create mode 100644 backend/poetry.lock create mode 100644 backend/pyproject.toml create mode 100644 backend/scripts/__init__.py create mode 100755 backend/scripts/run_migrations.py create mode 100644 backend/server/__init__.py create mode 100644 backend/server/api/__init__.py create mode 100644 backend/server/api/examples.py create mode 100644 backend/server/api/extract.py create mode 100644 backend/server/api/extractors.py create mode 100644 backend/server/extraction_runnable.py create mode 100644 backend/server/main.py create mode 100644 backend/server/retrieval.py create mode 100644 backend/server/settings.py create mode 100644 backend/server/validators.py create mode 100644 backend/tests/__init__.py create mode 100644 backend/tests/db.py create mode 100644 backend/tests/integration_tests/__init__.py create mode 100644 backend/tests/integration_tests/test_extraction.py create mode 100644 backend/tests/unit_tests/__init__.py create mode 100644 backend/tests/unit_tests/api/__init__.py create mode 100644 backend/tests/unit_tests/api/test_api_defining_extractors.py create mode 100644 backend/tests/unit_tests/api/test_api_examples.py create mode 100644 backend/tests/unit_tests/api/test_api_extract.py create mode 100644 backend/tests/unit_tests/conftest.py create mode 100644 backend/tests/unit_tests/fake/__init__.py create mode 100644 backend/tests/unit_tests/fake/chat_model.py create mode 100644 backend/tests/unit_tests/fake/test_fake_chat_model.py create mode 100644 backend/tests/unit_tests/fixtures/__init__.py create mode 100644 backend/tests/unit_tests/fixtures/sample.docx create mode 100644 backend/tests/unit_tests/fixtures/sample.epub create mode 100644 backend/tests/unit_tests/fixtures/sample.html create mode 100644 backend/tests/unit_tests/fixtures/sample.odt create mode 100644 backend/tests/unit_tests/fixtures/sample.pdf create mode 100644 backend/tests/unit_tests/fixtures/sample.rtf create mode 100644 backend/tests/unit_tests/fixtures/sample.txt create mode 100644 backend/tests/unit_tests/test_deduplication.py create mode 100644 backend/tests/unit_tests/test_parsing.py create mode 100644 backend/tests/unit_tests/test_upload.py create mode 100644 backend/tests/unit_tests/test_utils.py create mode 100644 backend/tests/unit_tests/test_validators.py create mode 100644 backend/tests/unit_tests/utils.py create mode 100644 docker-compose.yml diff --git a/.github/actions/poetry_setup/action.yml b/.github/actions/poetry_setup/action.yml new file mode 100644 index 0000000..d134246 --- /dev/null +++ b/.github/actions/poetry_setup/action.yml @@ -0,0 +1,91 @@ +# An action for setting up poetry install with caching. +# Using a custom action since the default action does not +# take poetry install groups into account. +# Action code from: +# https://github.com/actions/setup-python/issues/505#issuecomment-1273013236 +name: poetry-install-with-caching +description: Poetry install with support for caching of dependency groups. + +inputs: + python-version: + description: Python version, supporting MAJOR.MINOR only + required: true + + poetry-version: + description: Poetry version + required: true + + cache-key: + description: Cache key to use for manual handling of caching + required: true + + working-directory: + description: Directory whose poetry.lock file should be cached + required: true + +runs: + using: composite + steps: + - uses: actions/setup-python@v4 + name: Setup python ${{ inputs.python-version }} + with: + python-version: ${{ inputs.python-version }} + + - uses: actions/cache@v3 + id: cache-bin-poetry + name: Cache Poetry binary - Python ${{ inputs.python-version }} + env: + SEGMENT_DOWNLOAD_TIMEOUT_MIN: "1" + with: + path: | + /opt/pipx/venvs/poetry + # This step caches the poetry installation, so make sure it's keyed on the poetry version as well. + key: bin-poetry-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-${{ inputs.poetry-version }} + + - name: Refresh shell hashtable and fixup softlinks + if: steps.cache-bin-poetry.outputs.cache-hit == 'true' + shell: bash + env: + POETRY_VERSION: ${{ inputs.poetry-version }} + PYTHON_VERSION: ${{ inputs.python-version }} + run: | + set -eux + + # Refresh the shell hashtable, to ensure correct `which` output. + hash -r + + # `actions/cache@v3` doesn't always seem able to correctly unpack softlinks. + # Delete and recreate the softlinks pipx expects to have. + rm /opt/pipx/venvs/poetry/bin/python + cd /opt/pipx/venvs/poetry/bin + ln -s "$(which "python$PYTHON_VERSION")" python + chmod +x python + cd /opt/pipx_bin/ + ln -s /opt/pipx/venvs/poetry/bin/poetry poetry + chmod +x poetry + + # Ensure everything got set up correctly. + /opt/pipx/venvs/poetry/bin/python --version + /opt/pipx_bin/poetry --version + + - name: Install poetry + if: steps.cache-bin-poetry.outputs.cache-hit != 'true' + shell: bash + env: + POETRY_VERSION: ${{ inputs.poetry-version }} + PYTHON_VERSION: ${{ inputs.python-version }} + run: pipx install "poetry==$POETRY_VERSION" --python "python$PYTHON_VERSION" --verbose + + - name: Restore pip and poetry cached dependencies + uses: actions/cache@v3 + env: + SEGMENT_DOWNLOAD_TIMEOUT_MIN: "4" + WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }} + with: + path: | + ~/.cache/pip + ~/.cache/pypoetry/virtualenvs + ~/.cache/pypoetry/cache + ~/.cache/pypoetry/artifacts + ${{ env.WORKDIR }}/.venv + key: py-deps-${{ runner.os }}-${{ runner.arch }}-py-${{ inputs.python-version }}-poetry-${{ inputs.poetry-version }}-${{ inputs.cache-key }}-${{ hashFiles(format('{0}/**/poetry.lock', env.WORKDIR)) }} diff --git a/.github/workflows/_lint.yml b/.github/workflows/_lint.yml new file mode 100644 index 0000000..0cef335 --- /dev/null +++ b/.github/workflows/_lint.yml @@ -0,0 +1,83 @@ +name: lint + +on: + workflow_call: + inputs: + working-directory: + required: true + type: string + description: "From which folder this pipeline executes" + +env: + POETRY_VERSION: "1.7.1" + WORKDIR: ${{ inputs.working-directory == '' && '.' || inputs.working-directory }} + +jobs: + build: + runs-on: ubuntu-latest + env: + # This number is set "by eye": we want it to be big enough + # so that it's bigger than the number of commits in any reasonable PR, + # and also as small as possible since increasing the number makes + # the initial `git fetch` slower. + FETCH_DEPTH: 50 + strategy: + matrix: + # Only lint on the min and max supported Python versions. + # It's extremely unlikely that there's a lint issue on any version in between + # that doesn't show up on the min or max versions. + # + # GitHub rate-limits how many jobs can be running at any one time. + # Starting new jobs is also relatively slow, + # so linting on fewer versions makes CI faster. + python-version: + - "3.8" + - "3.11" + steps: + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }} + uses: "./.github/actions/poetry_setup" + with: + python-version: ${{ matrix.python-version }} + poetry-version: ${{ env.POETRY_VERSION }} + working-directory: ${{ inputs.working-directory }} + cache-key: lint-with-extras + + - name: Check Poetry File + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + poetry check + + - name: Check lock file + shell: bash + working-directory: ${{ inputs.working-directory }} + run: | + poetry lock --check + + - name: Install dependencies + # Also installs dev/lint/test/typing dependencies, to ensure we have + # type hints for as many of our libraries as possible. + # This helps catch errors that require dependencies to be spotted, for example: + # https://github.com/langchain-ai/langchain/pull/10249/files#diff-935185cd488d015f026dcd9e19616ff62863e8cde8c0bee70318d3ccbca98341 + # + # If you change this configuration, make sure to change the `cache-key` + # in the `poetry_setup` action above to stop using the old cache. + # It doesn't matter how you change it, any change will cause a cache-bust. + working-directory: ${{ inputs.working-directory }} + run: | + poetry install --with dev,lint,test,typing + + - name: Get .mypy_cache to speed up mypy + uses: actions/cache@v3 + env: + SEGMENT_DOWNLOAD_TIMEOUT_MIN: "2" + with: + path: | + ${{ env.WORKDIR }}/.mypy_cache + key: mypy-${{ runner.os }}-${{ runner.arch }}-py${{ matrix.python-version }}-${{ inputs.working-directory }}-${{ hashFiles(format('{0}/poetry.lock', env.WORKDIR)) }} + + - name: Analysing the code with our lint + working-directory: ${{ inputs.working-directory }} + run: | + make lint diff --git a/.github/workflows/_test.yml b/.github/workflows/_test.yml new file mode 100644 index 0000000..6d45e61 --- /dev/null +++ b/.github/workflows/_test.yml @@ -0,0 +1,57 @@ +name: test + +on: + workflow_call: + inputs: + working-directory: + required: true + type: string + description: "From which folder this pipeline executes" + +env: + POETRY_VERSION: "1.7.1" + +jobs: + build: + defaults: + run: + working-directory: ${{ inputs.working-directory }} + runs-on: ubuntu-latest + strategy: + matrix: + python-version: + - "3.8" + - "3.9" + - "3.10" + - "3.11" + name: Python ${{ matrix.python-version }} + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }} + uses: "./.github/actions/poetry_setup" + with: + python-version: ${{ matrix.python-version }} + poetry-version: ${{ env.POETRY_VERSION }} + working-directory: ${{ inputs.working-directory }} + cache-key: core + + - name: Install dependencies + shell: bash + run: poetry install + + - name: Run core tests + shell: bash + run: make test + + - name: Ensure the tests did not create any additional files + shell: bash + run: | + set -eu + + STATUS="$(git status)" + echo "$STATUS" + + # grep will exit non-zero if the target message isn't found, + # and `set -e` above will cause the step to fail. + echo "$STATUS" | grep 'nothing to commit, working tree clean' diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..ff1ed81 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,108 @@ +--- +name: Run CI Tests + +on: + push: + branches: [ main ] + pull_request: + workflow_dispatch: # Allows to trigger the workflow manually in GitHub UI + +# If another push to the same PR or branch happens while this workflow is still running, +# cancel the earlier run in favor of the next run. +# +# There's no point in testing an outdated version of the code. GitHub only allows +# a limited number of job runners to be active at the same time, so it's better to cancel +# pointless jobs early so that more useful jobs can run sooner. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + POETRY_VERSION: "1.7.1" + WORKDIR: "./backend" + +jobs: + lint: + uses: + ./.github/workflows/_lint.yml + with: + working-directory: ./backend + secrets: inherit + test: + timeout-minutes: 5 + runs-on: ubuntu-latest + defaults: + run: + working-directory: ${{ env.WORKDIR }} + services: + postgres: + # ensure postgres version this stays in sync with prod database + # and with postgres version used in docker compose + image: postgres:16 + env: + # optional (defaults to `postgres`) + POSTGRES_DB: langchain_test + # required + POSTGRES_PASSWORD: langchain + # optional (defaults to `5432`) + POSTGRES_PORT: 5432 + # optional (defaults to `postgres`) + POSTGRES_USER: langchain + ports: + # maps tcp port 5432 on service container to the host + - 5432:5432 + # set health checks to wait until postgres has started + options: >- + --health-cmd pg_isready + --health-interval 3s + --health-timeout 5s + --health-retries 10 + strategy: + matrix: + python-version: + - "3.8" + - "3.9" + - "3.10" + - "3.11" + name: Python ${{ matrix.python-version }} tests + steps: + - uses: actions/checkout@v3 + + - name: Set up Python ${{ matrix.python-version }} + Poetry ${{ env.POETRY_VERSION }} + uses: "./.github/actions/poetry_setup" + with: + python-version: ${{ matrix.python-version }} + poetry-version: ${{ env.POETRY_VERSION }} + working-directory: ${{ env.WORKDIR }} + cache-key: langchain-extract-all + - name: Test database connection + run: | + # Set up postgresql-client + sudo apt-get install -y postgresql-client + # Test psql connection + psql -h localhost -p 5432 -U langchain -d langchain_test -c "SELECT 1;" + env: + # postgress password is required; alternatively, you can run: + # `PGPASSWORD=postgres_password psql ...` + PGPASSWORD: langchain + + - name: Install dependencies + shell: bash + run: | + echo "Running tests, installing dependencies with poetry..." + poetry install --with test,lint,typing,docs + + - name: Run tests + run: make test + + - name: Ensure the tests did not create any additional files + shell: bash + run: | + set -eu + + STATUS="$(git status)" + echo "$STATUS" + + # grep will exit non-zero if the target message isn't found, + # and `set -e` above will cause the step to fail. + echo "$STATUS" | grep 'nothing to commit, working tree clean' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..30967a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,162 @@ +### Python template +# 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 + +# 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/#use-with-ide +.pdm.toml + +# 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/ +.DS_Store diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..bc9deae --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024-Present Langchain AI + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..868ac29 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +🚧 Under Active Development 🚧 + +Please expect breaking changes! + +# πŸ¦œπŸ“ LangChain Extract + +[![CI](https://github.com/langchain-ai/langchain-extract/actions/workflows/ci.yml/badge.svg)](https://github.com/langchain-ai/langchain-extract/actions/workflows/ci.yml) +[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) +[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/langchainai.svg?style=social&label=Follow%20%40LangChainAI)](https://twitter.com/langchainai) +[![](https://dcbadge.vercel.app/api/server/6adMQxSpJS?compact=true&style=flat)](https://discord.gg/6adMQxSpJS) +[![Open Issues](https://img.shields.io/github/issues-raw/langchain-ai/langchain-extract)](https://github.com/langchain-ai/langchain-extract/issues) + + +# Set up + +## Services + +The root folder contains a docker compose file which will a launch a postgres +instance. + +``` +docker compose up +``` + +At the time of writing, the app wasn't using postgres yet! + +## App + +```sh +cd [root]/backend +``` + +Set up the environment using poetry: + +```sh +poetry install --with lint,dev,test +``` + +Verify that unit tests pass (they probably wont?) + +# Test and format + +Testing and formatting is done using a Makefile inside `[root]/backend` + +```sh +make format +``` + +```sh +make test +``` + +# Launch Server + +From `[root]/backend`: + +```sh +python -m server.main +``` + +# Example client + +See `docs/source/notebooks` for an example client. diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000..c0b4fca --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,60 @@ +.PHONY: all lint format test help + +# Default target executed when no arguments are given to make. +all: help + +###################### +# TESTING AND COVERAGE +###################### + +# Define a variable for the test file path. +TEST_FILE ?= tests/unit_tests/ + +test: + poetry run pytest --disable-socket --allow-unix-socket $(TEST_FILE) + +test_watch: + poetry run ptw . -- $(TEST_FILE) + +openapi: + OPENAI_API_KEY=placeholder python -c "from server import main; import json; print(json.dumps(main.app.openapi()))" > openapi.json + + +###################### +# LINTING AND FORMATTING +###################### + +# Define a variable for Python and notebook files. +lint format: PYTHON_FILES=. +lint_diff format_diff: PYTHON_FILES=$(shell git diff --relative=. --name-only --diff-filter=d master | grep -E '\.py$$|\.ipynb$$') + +lint lint_diff: + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES) --diff + # [ "$(PYTHON_FILES)" = "" ] || poetry run mypy $(PYTHON_FILES) + +format format_diff: + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff format $(PYTHON_FILES) + [ "$(PYTHON_FILES)" = "" ] || poetry run ruff --select I --fix $(PYTHON_FILES) + +spell_check: + poetry run codespell --toml pyproject.toml + +spell_fix: + poetry run codespell --toml pyproject.toml -w + +###################### +# HELP +###################### + +help: + @echo '====================' + @echo '-- LINTING --' + @echo 'format - run code formatters' + @echo 'lint - run linters' + @echo 'spell_check - run codespell on the project' + @echo 'spell_fix - run codespell on the project and fix the errors' + @echo '-- TESTS --' + @echo 'coverage - run unit tests and generate coverage report' + @echo 'test - run unit tests' + @echo 'test TEST_FILE= - run all tests in file' + @echo '-- DOCUMENTATION tasks are from the top-level Makefile --' diff --git a/backend/README.md b/backend/README.md new file mode 100644 index 0000000..35c7dd5 --- /dev/null +++ b/backend/README.md @@ -0,0 +1 @@ +See readme at repo root. diff --git a/backend/db/__init__.py b/backend/db/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/db/models.py b/backend/db/models.py new file mode 100644 index 0000000..6008cd7 --- /dev/null +++ b/backend/db/models.py @@ -0,0 +1,134 @@ +import uuid +from datetime import datetime +from typing import Generator + +from sqlalchemy import Column, DateTime, ForeignKey, String, Text, create_engine +from sqlalchemy.dialects.postgresql import JSONB, UUID +from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import Session, relationship, sessionmaker +from sqlalchemy.sql import func + +from server.settings import get_postgres_url + +ENGINE = create_engine(get_postgres_url()) +SessionClass = sessionmaker(bind=ENGINE) + +Base = declarative_base() + + +# TODO(Eugene): Convert to async code +def get_session() -> Generator[Session, None, None]: + """Create a new session.""" + session = SessionClass() + + try: + yield session + except: + session.rollback() + raise + finally: + session.close() + + +class TimestampedModel(Base): + """An abstract base model that includes the timestamp fields.""" + + __abstract__ = True + + created_at = Column( + DateTime, + default=datetime.utcnow, + comment="The time the record was created (UTC).", + ) + updated_at = Column( + DateTime, + default=datetime.utcnow, + onupdate=datetime.utcnow, + doc="The time the record was last updated (UTC).", + ) + + # This is our own uuid assigned to the artifact. + # By construction guaranteed to be unique no matter what. + uuid = Column( + UUID(as_uuid=True), + primary_key=True, + default=lambda: str(uuid.uuid4()), + doc="Unique identifier for this model.", + ) + + +class Extractor(TimestampedModel): + __tablename__ = "extractors" + + name = Column( + String(100), + nullable=False, + server_default="", + comment="The name of the extractor.", + ) + created_at = Column( + DateTime(timezone=True), + server_default=func.now(), + comment="Time when this extracted was originally created.", + ) + modified_at = Column( + DateTime(timezone=True), + onupdate=func.now(), + comment="Last time this was modified.", + ) + schema = Column( + JSONB, + nullable=False, + comment="JSON Schema that describes what content will be extracted from the document", + ) + description = Column( + String(100), + nullable=False, + server_default="", + comment="Surfaced via UI to the users.", + ) + instruction = Column( + Text, nullable=False, comment="The prompt to the language model." + ) # TODO: This will need to evolve + + examples = relationship("Example", backref="extractor") + + def __repr__(self) -> str: + return f"" + + +class Example(TimestampedModel): + """A representation of an example. + + Examples consist of content together with the expected output. + + The output is a JSON object that is expected to be extracted from the content. + + The JSON object should be valid according to the schema of the associated extractor. + + The JSON object is defined by the schema of the associated extractor, so + it's perfectly fine for a given example to represent the extraction + of multiple instances of some object from the content since + the JSON schema can represent a list of objects. + """ + + __tablename__ = "examples" + + content = Column( + Text, + nullable=False, + comment="The input portion of the example.", + ) + output = Column( + JSONB, + comment="The output associated with the example.", + ) + extractor_id = Column( + UUID(as_uuid=True), + ForeignKey("extractors.uuid", ondelete="CASCADE"), + nullable=False, + comment="Foreign key referencing the associated extractor.", + ) + + def __repr__(self) -> str: + return f"" diff --git a/backend/extraction/__init__.py b/backend/extraction/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/extraction/parsing.py b/backend/extraction/parsing.py new file mode 100644 index 0000000..8d0e897 --- /dev/null +++ b/backend/extraction/parsing.py @@ -0,0 +1,65 @@ +"""Convert binary input to blobs and parse them using the appropriate parser.""" +from __future__ import annotations + +from typing import BinaryIO, List + +from langchain.document_loaders.parsers import BS4HTMLParser, PDFMinerParser +from langchain.document_loaders.parsers.generic import MimeTypeBasedParser +from langchain.document_loaders.parsers.txt import TextParser +from langchain_community.document_loaders import Blob +from langchain_core.documents import Document + +HANDLERS = { + "application/pdf": PDFMinerParser(), + "text/plain": TextParser(), + "text/html": BS4HTMLParser(), + # Disable for now as they rely on unstructured and there's some install + # issue with unstructured. + # from langchain.document_loaders.parsers.msword import MsWordParser + # "application/msword": MsWordParser(), + # "application/vnd.openxmlformats-officedocument.wordprocessingml.document": ( + # MsWordParser() + # ), +} + +SUPPORTED_MIMETYPES = sorted(HANDLERS.keys()) + + +def _guess_mimetype(file_bytes: bytes) -> str: + """Guess the mime-type of a file.""" + try: + import magic + except ImportError as e: + raise ImportError( + "magic package not found, please install it with `pip install python-magic`" + ) from e + + mime = magic.Magic(mime=True) + mime_type = mime.from_buffer(file_bytes) + return mime_type + + +# PUBLIC API + +MIMETYPE_BASED_PARSER = MimeTypeBasedParser( + handlers=HANDLERS, + fallback_parser=None, +) + + +def convert_binary_input_to_blob(data: BinaryIO) -> Blob: + """Convert ingestion input to blob.""" + file_data = data.read() + mimetype = _guess_mimetype(file_data) + file_name = data.name + return Blob.from_data( + data=file_data, + path=file_name, + mime_type=mimetype, + ) + + +def parse_binary_input(data: BinaryIO) -> List[Document]: + """Parse binary input.""" + blob = convert_binary_input_to_blob(data) + return MIMETYPE_BASED_PARSER.parse(blob) diff --git a/backend/extraction/utils.py b/backend/extraction/utils.py new file mode 100644 index 0000000..f6835cd --- /dev/null +++ b/backend/extraction/utils.py @@ -0,0 +1,52 @@ +"""Adapters to convert between different formats.""" +from __future__ import annotations + +from langchain_core.utils.json_schema import dereference_refs + + +def _rm_titles(kv: dict) -> dict: + """Remove titles from a dictionary.""" + new_kv = {} + for k, v in kv.items(): + if k == "title": + continue + elif isinstance(v, dict): + new_kv[k] = _rm_titles(v) + else: + new_kv[k] = v + return new_kv + + +# PUBLIC API + + +def convert_json_schema_to_openai_schema( + schema: dict, + *, + rm_titles: bool = True, + multi: bool = True, +) -> dict: + """Convert JSON schema to a corresponding OpenAI function call.""" + if multi: + # Wrap the schema in an object called "Root" with a property called: "data" + # which will be a json array of the original schema. + schema_ = { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": dereference_refs(schema), + }, + }, + "required": ["data"], + } + else: + raise NotImplementedError("Only multi is supported for now.") + + schema_.pop("definitions", None) + + return { + "name": "extractor", + "description": "Extract information matching the given schema.", + "parameters": _rm_titles(schema_) if rm_titles else schema_, + } diff --git a/backend/poetry.lock b/backend/poetry.lock new file mode 100644 index 0000000..dc9fbae --- /dev/null +++ b/backend/poetry.lock @@ -0,0 +1,4243 @@ +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. + +[[package]] +name = "aiofiles" +version = "22.1.0" +description = "File support for asyncio." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "aiofiles-22.1.0-py3-none-any.whl", hash = "sha256:1142fa8e80dbae46bb6339573ad4c8c0841358f79c6eb50a493dceca14621bad"}, + {file = "aiofiles-22.1.0.tar.gz", hash = "sha256:9107f1ca0b2a5553987a94a3c9959fe5b491fdf731389aa5b7b1bd0733e32de6"}, +] + +[[package]] +name = "aiohttp" +version = "3.9.3" +description = "Async http client/server framework (asyncio)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:939677b61f9d72a4fa2a042a5eee2a99a24001a67c13da113b2e30396567db54"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f5cd333fcf7590a18334c90f8c9147c837a6ec8a178e88d90a9b96ea03194cc"}, + {file = "aiohttp-3.9.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:82e6aa28dd46374f72093eda8bcd142f7771ee1eb9d1e223ff0fa7177a96b4a5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f56455b0c2c7cc3b0c584815264461d07b177f903a04481dfc33e08a89f0c26b"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bca77a198bb6e69795ef2f09a5f4c12758487f83f33d63acde5f0d4919815768"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e083c285857b78ee21a96ba1eb1b5339733c3563f72980728ca2b08b53826ca5"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab40e6251c3873d86ea9b30a1ac6d7478c09277b32e14745d0d3c6e76e3c7e29"}, + {file = "aiohttp-3.9.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:df822ee7feaaeffb99c1a9e5e608800bd8eda6e5f18f5cfb0dc7eeb2eaa6bbec"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:acef0899fea7492145d2bbaaaec7b345c87753168589cc7faf0afec9afe9b747"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cd73265a9e5ea618014802ab01babf1940cecb90c9762d8b9e7d2cc1e1969ec6"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:a78ed8a53a1221393d9637c01870248a6f4ea5b214a59a92a36f18151739452c"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b0e029353361f1746bac2e4cc19b32f972ec03f0f943b390c4ab3371840aabf"}, + {file = "aiohttp-3.9.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7cf5c9458e1e90e3c390c2639f1017a0379a99a94fdfad3a1fd966a2874bba52"}, + {file = "aiohttp-3.9.3-cp310-cp310-win32.whl", hash = "sha256:3e59c23c52765951b69ec45ddbbc9403a8761ee6f57253250c6e1536cacc758b"}, + {file = "aiohttp-3.9.3-cp310-cp310-win_amd64.whl", hash = "sha256:055ce4f74b82551678291473f66dc9fb9048a50d8324278751926ff0ae7715e5"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b88f9386ff1ad91ace19d2a1c0225896e28815ee09fc6a8932fded8cda97c3d"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c46956ed82961e31557b6857a5ca153c67e5476972e5f7190015018760938da2"}, + {file = "aiohttp-3.9.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07b837ef0d2f252f96009e9b8435ec1fef68ef8b1461933253d318748ec1acdc"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad46e6f620574b3b4801c68255492e0159d1712271cc99d8bdf35f2043ec266"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5ed3e046ea7b14938112ccd53d91c1539af3e6679b222f9469981e3dac7ba1ce"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:039df344b45ae0b34ac885ab5b53940b174530d4dd8a14ed8b0e2155b9dddccb"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7943c414d3a8d9235f5f15c22ace69787c140c80b718dcd57caaade95f7cd93b"}, + {file = "aiohttp-3.9.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84871a243359bb42c12728f04d181a389718710129b36b6aad0fc4655a7647d4"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5eafe2c065df5401ba06821b9a054d9cb2848867f3c59801b5d07a0be3a380ae"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:9d3c9b50f19704552f23b4eaea1fc082fdd82c63429a6506446cbd8737823da3"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:f033d80bc6283092613882dfe40419c6a6a1527e04fc69350e87a9df02bbc283"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2c895a656dd7e061b2fd6bb77d971cc38f2afc277229ce7dd3552de8313a483e"}, + {file = "aiohttp-3.9.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1f5a71d25cd8106eab05f8704cd9167b6e5187bcdf8f090a66c6d88b634802b4"}, + {file = "aiohttp-3.9.3-cp311-cp311-win32.whl", hash = "sha256:50fca156d718f8ced687a373f9e140c1bb765ca16e3d6f4fe116e3df7c05b2c5"}, + {file = "aiohttp-3.9.3-cp311-cp311-win_amd64.whl", hash = "sha256:5fe9ce6c09668063b8447f85d43b8d1c4e5d3d7e92c63173e6180b2ac5d46dd8"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:38a19bc3b686ad55804ae931012f78f7a534cce165d089a2059f658f6c91fa60"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:770d015888c2a598b377bd2f663adfd947d78c0124cfe7b959e1ef39f5b13869"}, + {file = "aiohttp-3.9.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ee43080e75fc92bf36219926c8e6de497f9b247301bbf88c5c7593d931426679"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52df73f14ed99cee84865b95a3d9e044f226320a87af208f068ecc33e0c35b96"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9b311743a78043b26ffaeeb9715dc360335e5517832f5a8e339f8a43581e4d"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b955ed993491f1a5da7f92e98d5dad3c1e14dc175f74517c4e610b1f2456fb11"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:504b6981675ace64c28bf4a05a508af5cde526e36492c98916127f5a02354d53"}, + {file = "aiohttp-3.9.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6fe5571784af92b6bc2fda8d1925cccdf24642d49546d3144948a6a1ed58ca5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:ba39e9c8627edc56544c8628cc180d88605df3892beeb2b94c9bc857774848ca"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:e5e46b578c0e9db71d04c4b506a2121c0cb371dd89af17a0586ff6769d4c58c1"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:938a9653e1e0c592053f815f7028e41a3062e902095e5a7dc84617c87267ebd5"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:c3452ea726c76e92f3b9fae4b34a151981a9ec0a4847a627c43d71a15ac32aa6"}, + {file = "aiohttp-3.9.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ff30218887e62209942f91ac1be902cc80cddb86bf00fbc6783b7a43b2bea26f"}, + {file = "aiohttp-3.9.3-cp312-cp312-win32.whl", hash = "sha256:38f307b41e0bea3294a9a2a87833191e4bcf89bb0365e83a8be3a58b31fb7f38"}, + {file = "aiohttp-3.9.3-cp312-cp312-win_amd64.whl", hash = "sha256:b791a3143681a520c0a17e26ae7465f1b6f99461a28019d1a2f425236e6eedb5"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0ed621426d961df79aa3b963ac7af0d40392956ffa9be022024cd16297b30c8c"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7f46acd6a194287b7e41e87957bfe2ad1ad88318d447caf5b090012f2c5bb528"}, + {file = "aiohttp-3.9.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:feeb18a801aacb098220e2c3eea59a512362eb408d4afd0c242044c33ad6d542"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f734e38fd8666f53da904c52a23ce517f1b07722118d750405af7e4123933511"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b40670ec7e2156d8e57f70aec34a7216407848dfe6c693ef131ddf6e76feb672"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fdd215b7b7fd4a53994f238d0f46b7ba4ac4c0adb12452beee724ddd0743ae5d"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:017a21b0df49039c8f46ca0971b3a7fdc1f56741ab1240cb90ca408049766168"}, + {file = "aiohttp-3.9.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e99abf0bba688259a496f966211c49a514e65afa9b3073a1fcee08856e04425b"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:648056db9a9fa565d3fa851880f99f45e3f9a771dd3ff3bb0c048ea83fb28194"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8aacb477dc26797ee089721536a292a664846489c49d3ef9725f992449eda5a8"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:522a11c934ea660ff8953eda090dcd2154d367dec1ae3c540aff9f8a5c109ab4"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:5bce0dc147ca85caa5d33debc4f4d65e8e8b5c97c7f9f660f215fa74fc49a321"}, + {file = "aiohttp-3.9.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4b4af9f25b49a7be47c0972139e59ec0e8285c371049df1a63b6ca81fdd216a2"}, + {file = "aiohttp-3.9.3-cp38-cp38-win32.whl", hash = "sha256:298abd678033b8571995650ccee753d9458dfa0377be4dba91e4491da3f2be63"}, + {file = "aiohttp-3.9.3-cp38-cp38-win_amd64.whl", hash = "sha256:69361bfdca5468c0488d7017b9b1e5ce769d40b46a9f4a2eed26b78619e9396c"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:0fa43c32d1643f518491d9d3a730f85f5bbaedcbd7fbcae27435bb8b7a061b29"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:835a55b7ca49468aaaac0b217092dfdff370e6c215c9224c52f30daaa735c1c1"}, + {file = "aiohttp-3.9.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06a9b2c8837d9a94fae16c6223acc14b4dfdff216ab9b7202e07a9a09541168f"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abf151955990d23f84205286938796c55ff11bbfb4ccfada8c9c83ae6b3c89a3"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:59c26c95975f26e662ca78fdf543d4eeaef70e533a672b4113dd888bd2423caa"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f95511dd5d0e05fd9728bac4096319f80615aaef4acbecb35a990afebe953b0e"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:595f105710293e76b9dc09f52e0dd896bd064a79346234b521f6b968ffdd8e58"}, + {file = "aiohttp-3.9.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7c8b816c2b5af5c8a436df44ca08258fc1a13b449393a91484225fcb7545533"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f1088fa100bf46e7b398ffd9904f4808a0612e1d966b4aa43baa535d1b6341eb"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f59dfe57bb1ec82ac0698ebfcdb7bcd0e99c255bd637ff613760d5f33e7c81b3"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:361a1026c9dd4aba0109e4040e2aecf9884f5cfe1b1b1bd3d09419c205e2e53d"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:363afe77cfcbe3a36353d8ea133e904b108feea505aa4792dad6585a8192c55a"}, + {file = "aiohttp-3.9.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8e2c45c208c62e955e8256949eb225bd8b66a4c9b6865729a786f2aa79b72e9d"}, + {file = "aiohttp-3.9.3-cp39-cp39-win32.whl", hash = "sha256:f7217af2e14da0856e082e96ff637f14ae45c10a5714b63c77f26d8884cf1051"}, + {file = "aiohttp-3.9.3-cp39-cp39-win_amd64.whl", hash = "sha256:27468897f628c627230dba07ec65dc8d0db566923c48f29e084ce382119802bc"}, + {file = "aiohttp-3.9.3.tar.gz", hash = "sha256:90842933e5d1ff760fae6caca4b2b3edba53ba8f4b71e95dacf2818a2aca06f7"}, +] + +[package.dependencies] +aiosignal = ">=1.1.2" +async-timeout = {version = ">=4.0,<5.0", markers = "python_version < \"3.11\""} +attrs = ">=17.3.0" +frozenlist = ">=1.1.1" +multidict = ">=4.5,<7.0" +yarl = ">=1.0,<2.0" + +[package.extras] +speedups = ["Brotli", "aiodns", "brotlicffi"] + +[[package]] +name = "aiosignal" +version = "1.3.1" +description = "aiosignal: a list of registered asynchronous callbacks" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17"}, + {file = "aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc"}, +] + +[package.dependencies] +frozenlist = ">=1.1.0" + +[[package]] +name = "aiosqlite" +version = "0.19.0" +description = "asyncio bridge to the standard sqlite3 module" +optional = false +python-versions = ">=3.7" +files = [ + {file = "aiosqlite-0.19.0-py3-none-any.whl", hash = "sha256:edba222e03453e094a3ce605db1b970c4b3376264e56f32e2a4959f948d66a96"}, + {file = "aiosqlite-0.19.0.tar.gz", hash = "sha256:95ee77b91c8d2808bd08a59fbebf66270e9090c3d92ffbf260dc0db0b979577d"}, +] + +[package.extras] +dev = ["aiounittest (==1.4.1)", "attribution (==1.6.2)", "black (==23.3.0)", "coverage[toml] (==7.2.3)", "flake8 (==5.0.4)", "flake8-bugbear (==23.3.12)", "flit (==3.7.1)", "mypy (==1.2.0)", "ufmt (==2.1.0)", "usort (==1.0.6)"] +docs = ["sphinx (==6.1.3)", "sphinx-mdinclude (==0.5.3)"] + +[[package]] +name = "alembic" +version = "1.13.1" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.8" +files = [ + {file = "alembic-1.13.1-py3-none-any.whl", hash = "sha256:2edcc97bed0bd3272611ce3a98d98279e9c209e7186e43e75bbb1b2bdfdbcc43"}, + {file = "alembic-1.13.1.tar.gz", hash = "sha256:4932c8558bf68f2ee92b9bbcb8218671c627064d5b08939437af6d77dc05e595"}, +] + +[package.dependencies] +importlib-metadata = {version = "*", markers = "python_version < \"3.9\""} +importlib-resources = {version = "*", markers = "python_version < \"3.9\""} +Mako = "*" +SQLAlchemy = ">=1.3.0" +typing-extensions = ">=4" + +[package.extras] +tz = ["backports.zoneinfo"] + +[[package]] +name = "anyio" +version = "4.2.0" +description = "High level compatibility layer for multiple asynchronous event loop implementations" +optional = false +python-versions = ">=3.8" +files = [ + {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, + {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, +] + +[package.dependencies] +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} +idna = ">=2.8" +sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} + +[package.extras] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] + +[[package]] +name = "appnope" +version = "0.1.4" +description = "Disable App Nap on macOS >= 10.9" +optional = false +python-versions = ">=3.6" +files = [ + {file = "appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c"}, + {file = "appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee"}, +] + +[[package]] +name = "argon2-cffi" +version = "23.1.0" +description = "Argon2 for Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea"}, + {file = "argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08"}, +] + +[package.dependencies] +argon2-cffi-bindings = "*" + +[package.extras] +dev = ["argon2-cffi[tests,typing]", "tox (>4)"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-copybutton", "sphinx-notfound-page"] +tests = ["hypothesis", "pytest"] +typing = ["mypy"] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +description = "Low-level CFFI bindings for Argon2" +optional = false +python-versions = ">=3.6" +files = [ + {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, + {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, + {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, + {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, + {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, +] + +[package.dependencies] +cffi = ">=1.0.1" + +[package.extras] +dev = ["cogapp", "pre-commit", "pytest", "wheel"] +tests = ["pytest"] + +[[package]] +name = "arrow" +version = "1.3.0" +description = "Better dates & times for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80"}, + {file = "arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85"}, +] + +[package.dependencies] +python-dateutil = ">=2.7.0" +types-python-dateutil = ">=2.8.10" + +[package.extras] +doc = ["doc8", "sphinx (>=7.0.0)", "sphinx-autobuild", "sphinx-autodoc-typehints", "sphinx_rtd_theme (>=1.3.0)"] +test = ["dateparser (==1.*)", "pre-commit", "pytest", "pytest-cov", "pytest-mock", "pytz (==2021.1)", "simplejson (==3.*)"] + +[[package]] +name = "asttokens" +version = "2.4.1" +description = "Annotate AST trees with source code positions" +optional = false +python-versions = "*" +files = [ + {file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"}, + {file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"}, +] + +[package.dependencies] +six = ">=1.12.0" + +[package.extras] +astroid = ["astroid (>=1,<2)", "astroid (>=2,<4)"] +test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] + +[[package]] +name = "async-timeout" +version = "4.0.3" +description = "Timeout context manager for asyncio programs" +optional = false +python-versions = ">=3.7" +files = [ + {file = "async-timeout-4.0.3.tar.gz", hash = "sha256:4640d96be84d82d02ed59ea2b7105a0f7b33abe8703703cd0ab0bf87c427522f"}, + {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, +] + +[[package]] +name = "attrs" +version = "23.2.0" +description = "Classes Without Boilerplate" +optional = false +python-versions = ">=3.7" +files = [ + {file = "attrs-23.2.0-py3-none-any.whl", hash = "sha256:99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1"}, + {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, +] + +[package.extras] +cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] +dev = ["attrs[tests]", "pre-commit"] +docs = ["furo", "myst-parser", "sphinx", "sphinx-notfound-page", "sphinxcontrib-towncrier", "towncrier", "zope-interface"] +tests = ["attrs[tests-no-zope]", "zope-interface"] +tests-mypy = ["mypy (>=1.6)", "pytest-mypy-plugins"] +tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "pytest (>=4.3.0)", "pytest-xdist[psutil]"] + +[[package]] +name = "babel" +version = "2.14.0" +description = "Internationalization utilities" +optional = false +python-versions = ">=3.7" +files = [ + {file = "Babel-2.14.0-py3-none-any.whl", hash = "sha256:efb1a25b7118e67ce3a259bed20545c29cb68be8ad2c784c83689981b7a57287"}, + {file = "Babel-2.14.0.tar.gz", hash = "sha256:6919867db036398ba21eb5c7a0f6b28ab8cbc3ae7a73a44ebe34ae74a4e7d363"}, +] + +[package.dependencies] +pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} + +[package.extras] +dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] + +[[package]] +name = "backcall" +version = "0.2.0" +description = "Specifications for callback functions passed in to an API" +optional = false +python-versions = "*" +files = [ + {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, + {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +description = "Screen-scraping library" +optional = false +python-versions = ">=3.6.0" +files = [ + {file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"}, + {file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"}, +] + +[package.dependencies] +soupsieve = ">1.2" + +[package.extras] +cchardet = ["cchardet"] +chardet = ["chardet"] +charset-normalizer = ["charset-normalizer"] +html5lib = ["html5lib"] +lxml = ["lxml"] + +[[package]] +name = "bleach" +version = "6.1.0" +description = "An easy safelist-based HTML-sanitizing tool." +optional = false +python-versions = ">=3.8" +files = [ + {file = "bleach-6.1.0-py3-none-any.whl", hash = "sha256:3225f354cfc436b9789c66c4ee030194bee0568fbf9cbdad3bc8b5c26c5f12b6"}, + {file = "bleach-6.1.0.tar.gz", hash = "sha256:0a31f1837963c41d46bbf1331b8778e1308ea0791db03cc4e7357b97cf42a8fe"}, +] + +[package.dependencies] +six = ">=1.9.0" +webencodings = "*" + +[package.extras] +css = ["tinycss2 (>=1.1.0,<1.3)"] + +[[package]] +name = "certifi" +version = "2024.2.2" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +files = [ + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, +] + +[[package]] +name = "cffi" +version = "1.16.0" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +files = [ + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.3.2" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:25baf083bf6f6b341f4121c2f3c548875ee6f5339300e08be3f2b2ba1721cdd3"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:06435b539f889b1f6f4ac1758871aae42dc3a8c0e24ac9e60c2384973ad73027"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9063e24fdb1e498ab71cb7419e24622516c4a04476b17a2dab57e8baa30d6e03"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6897af51655e3691ff853668779c7bad41579facacf5fd7253b0133308cf000d"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d3193f4a680c64b4b6a9115943538edb896edc190f0b222e73761716519268e"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd70574b12bb8a4d2aaa0094515df2463cb429d8536cfb6c7ce983246983e5a6"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8465322196c8b4d7ab6d1e049e4c5cb460d0394da4a27d23cc242fbf0034b6b5"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9a8e9031d613fd2009c182b69c7b2c1ef8239a0efb1df3f7c8da66d5dd3d537"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:beb58fe5cdb101e3a055192ac291b7a21e3b7ef4f67fa1d74e331a7f2124341c"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e06ed3eb3218bc64786f7db41917d4e686cc4856944f53d5bdf83a6884432e12"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:2e81c7b9c8979ce92ed306c249d46894776a909505d8f5a4ba55b14206e3222f"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:572c3763a264ba47b3cf708a44ce965d98555f618ca42c926a9c1616d8f34269"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd1abc0d89e30cc4e02e4064dc67fcc51bd941eb395c502aac3ec19fab46b519"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win32.whl", hash = "sha256:3d47fa203a7bd9c5b6cee4736ee84ca03b8ef23193c0d1ca99b5089f72645c73"}, + {file = "charset_normalizer-3.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:10955842570876604d404661fbccbc9c7e684caf432c09c715ec38fbae45ae09"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:802fe99cca7457642125a8a88a084cef28ff0cf9407060f7b93dca5aa25480db"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:573f6eac48f4769d667c4442081b1794f52919e7edada77495aaed9236d13a96"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:549a3a73da901d5bc3ce8d24e0600d1fa85524c10287f6004fbab87672bf3e1e"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f27273b60488abe721a075bcca6d7f3964f9f6f067c8c4c605743023d7d3944f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ceae2f17a9c33cb48e3263960dc5fc8005351ee19db217e9b1bb15d28c02574"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:65f6f63034100ead094b8744b3b97965785388f308a64cf8d7c34f2f2e5be0c4"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:753f10e867343b4511128c6ed8c82f7bec3bd026875576dfd88483c5c73b2fd8"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4a78b2b446bd7c934f5dcedc588903fb2f5eec172f3d29e52a9096a43722adfc"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e537484df0d8f426ce2afb2d0f8e1c3d0b114b83f8850e5f2fbea0e797bd82ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:eb6904c354526e758fda7167b33005998fb68c46fbc10e013ca97f21ca5c8887"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:deb6be0ac38ece9ba87dea880e438f25ca3eddfac8b002a2ec3d9183a454e8ae"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:4ab2fe47fae9e0f9dee8c04187ce5d09f48eabe611be8259444906793ab7cbce"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:80402cd6ee291dcb72644d6eac93785fe2c8b9cb30893c1af5b8fdd753b9d40f"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win32.whl", hash = "sha256:7cd13a2e3ddeed6913a65e66e94b51d80a041145a026c27e6bb76c31a853c6ab"}, + {file = "charset_normalizer-3.3.2-cp311-cp311-win_amd64.whl", hash = "sha256:663946639d296df6a2bb2aa51b60a2454ca1cb29835324c640dafb5ff2131a77"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:ddbb2551d7e0102e7252db79ba445cdab71b26640817ab1e3e3648dad515003b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f4a014bc36d3c57402e2977dada34f9c12300af536839dc38c0beab8878f38a"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a10af20b82360ab00827f916a6058451b723b4e65030c5a18577c8b2de5b3389"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8d756e44e94489e49571086ef83b2bb8ce311e730092d2c34ca8f7d925cb20aa"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ac7ffc7ad6d040517be39eb591cac5ff87416c2537df6ba3cba3bae290c0fed"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:7ed9e526742851e8d5cc9e6cf41427dfc6068d4f5a3bb03659444b4cabf6bc26"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8bdb58ff7ba23002a4c5808d608e4e6c687175724f54a5dade5fa8c67b604e4d"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:6b3251890fff30ee142c44144871185dbe13b11bab478a88887a639655be1068"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b4a23f61ce87adf89be746c8a8974fe1c823c891d8f86eb218bb957c924bb143"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:efcb3f6676480691518c177e3b465bcddf57cea040302f9f4e6e191af91174d4"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win32.whl", hash = "sha256:d965bba47ddeec8cd560687584e88cf699fd28f192ceb452d1d7ee807c5597b7"}, + {file = "charset_normalizer-3.3.2-cp312-cp312-win_amd64.whl", hash = "sha256:96b02a3dc4381e5494fad39be677abcb5e6634bf7b4fa83a6dd3112607547001"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:95f2a5796329323b8f0512e09dbb7a1860c46a39da62ecb2324f116fa8fdc85c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c002b4ffc0be611f0d9da932eb0f704fe2602a9a949d1f738e4c34c75b0863d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a981a536974bbc7a512cf44ed14938cf01030a99e9b3a06dd59578882f06f985"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3287761bc4ee9e33561a7e058c72ac0938c4f57fe49a09eae428fd88aafe7bb6"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42cb296636fcc8b0644486d15c12376cb9fa75443e00fb25de0b8602e64c1714"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a55554a2fa0d408816b3b5cedf0045f4b8e1a6065aec45849de2d6f3f8e9786"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c083af607d2515612056a31f0a8d9e0fcb5876b7bfc0abad3ecd275bc4ebc2d5"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:87d1351268731db79e0f8e745d92493ee2841c974128ef629dc518b937d9194c"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:bd8f7df7d12c2db9fab40bdd87a7c09b1530128315d047a086fa3ae3435cb3a8"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:c180f51afb394e165eafe4ac2936a14bee3eb10debc9d9e4db8958fe36afe711"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c622a5fe39a48f78944a87d4fb8a53ee07344641b0562c540d840748571b811"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win32.whl", hash = "sha256:db364eca23f876da6f9e16c9da0df51aa4f104a972735574842618b8c6d999d4"}, + {file = "charset_normalizer-3.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:86216b5cee4b06df986d214f664305142d9c76df9b6512be2738aa72a2048f99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6463effa3186ea09411d50efc7d85360b38d5f09b870c48e4600f63af490e56a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6c4caeef8fa63d06bd437cd4bdcf3ffefe6738fb1b25951440d80dc7df8c03ac"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:37e55c8e51c236f95b033f6fb391d7d7970ba5fe7ff453dad675e88cf303377a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb69256e180cb6c8a894fee62b3afebae785babc1ee98b81cdf68bbca1987f33"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ae5f4161f18c61806f411a13b0310bea87f987c7d2ecdbdaad0e94eb2e404238"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b2b0a0c0517616b6869869f8c581d4eb2dd83a4d79e0ebcb7d373ef9956aeb0a"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:45485e01ff4d3630ec0d9617310448a8702f70e9c01906b0d0118bdf9d124cf2"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eb00ed941194665c332bf8e078baf037d6c35d7c4f3102ea2d4f16ca94a26dc8"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:2127566c664442652f024c837091890cb1942c30937add288223dc895793f898"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a50aebfa173e157099939b17f18600f72f84eed3049e743b68ad15bd69b6bf99"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:4d0d1650369165a14e14e1e47b372cfcb31d6ab44e6e33cb2d4e57265290044d"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:923c0c831b7cfcb071580d3f46c4baf50f174be571576556269530f4bbd79d04"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:06a81e93cd441c56a9b65d8e1d043daeb97a3d0856d177d5c90ba85acb3db087"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win32.whl", hash = "sha256:6ef1d82a3af9d3eecdba2321dc1b3c238245d890843e040e41e470ffa64c3e25"}, + {file = "charset_normalizer-3.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:eb8821e09e916165e160797a6c17edda0679379a4be5c716c260e836e122f54b"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:c235ebd9baae02f1b77bcea61bce332cb4331dc3617d254df3323aa01ab47bd4"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5b4c145409bef602a690e7cfad0a15a55c13320ff7a3ad7ca59c13bb8ba4d45d"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:68d1f8a9e9e37c1223b656399be5d6b448dea850bed7d0f87a8311f1ff3dabb0"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22afcb9f253dac0696b5a4be4a1c0f8762f8239e21b99680099abd9b2b1b2269"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e27ad930a842b4c5eb8ac0016b0a54f5aebbe679340c26101df33424142c143c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f79682fbe303db92bc2b1136016a38a42e835d932bab5b3b1bfcfbf0640e519"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b261ccdec7821281dade748d088bb6e9b69e6d15b30652b74cbbac25e280b796"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:122c7fa62b130ed55f8f285bfd56d5f4b4a5b503609d181f9ad85e55c89f4185"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d0eccceffcb53201b5bfebb52600a5fb483a20b61da9dbc885f8b103cbe7598c"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f96df6923e21816da7e0ad3fd47dd8f94b2a5ce594e00677c0013018b813458"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:7f04c839ed0b6b98b1a7501a002144b76c18fb1c1850c8b98d458ac269e26ed2"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:34d1c8da1e78d2e001f363791c98a272bb734000fcef47a491c1e3b0505657a8"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ff8fa367d09b717b2a17a052544193ad76cd49979c805768879cb63d9ca50561"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win32.whl", hash = "sha256:aed38f6e4fb3f5d6bf81bfa990a07806be9d83cf7bacef998ab1a9bd660a581f"}, + {file = "charset_normalizer-3.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:b01b88d45a6fcb69667cd6d2f7a9aeb4bf53760d7fc536bf679ec94fe9f3ff3d"}, + {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"}, +] + +[[package]] +name = "click" +version = "8.1.7" +description = "Composable command line interface toolkit" +optional = false +python-versions = ">=3.7" +files = [ + {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, + {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "comm" +version = "0.2.1" +description = "Jupyter Python Comm implementation, for usage in ipykernel, xeus-python etc." +optional = false +python-versions = ">=3.8" +files = [ + {file = "comm-0.2.1-py3-none-any.whl", hash = "sha256:87928485c0dfc0e7976fd89fc1e187023cf587e7c353e4a9b417555b44adf021"}, + {file = "comm-0.2.1.tar.gz", hash = "sha256:0bc91edae1344d39d3661dcbc36937181fdaddb304790458f8b044dbc064b89a"}, +] + +[package.dependencies] +traitlets = ">=4" + +[package.extras] +test = ["pytest"] + +[[package]] +name = "coverage" +version = "7.4.1" +description = "Code coverage measurement for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, + {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, + {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, + {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, + {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, + {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, + {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, + {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, + {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, + {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, + {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, + {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, + {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, + {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, +] + +[package.dependencies] +tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} + +[package.extras] +toml = ["tomli"] + +[[package]] +name = "cryptography" +version = "42.0.4" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = ">=3.7" +files = [ + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449"}, + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b"}, + {file = "cryptography-42.0.4-cp37-abi3-win32.whl", hash = "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925"}, + {file = "cryptography-42.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923"}, + {file = "cryptography-42.0.4-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0"}, + {file = "cryptography-42.0.4-cp39-abi3-win32.whl", hash = "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129"}, + {file = "cryptography-42.0.4-cp39-abi3-win_amd64.whl", hash = "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f8907fcf57392cd917892ae83708761c6ff3c37a8e835d7246ff0ad251d9298"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:12d341bd42cdb7d4937b0cabbdf2a94f949413ac4504904d0cdbdce4a22cbf88"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1cdcdbd117681c88d717437ada72bdd5be9de117f96e3f4d50dab3f59fd9ab20"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0e89f7b84f421c56e7ff69f11c441ebda73b8a8e6488d322ef71746224c20fce"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f1e85a178384bf19e36779d91ff35c7617c885da487d689b05c1366f9933ad74"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d2a27aca5597c8a71abbe10209184e1a8e91c1fd470b5070a2ea60cafec35bcd"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4e36685cb634af55e0677d435d425043967ac2f3790ec652b2b88ad03b85c27b"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f47be41843200f7faec0683ad751e5ef11b9a56a220d57f300376cd8aba81660"}, + {file = "cryptography-42.0.4.tar.gz", hash = "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] +nox = ["nox"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] +sdist = ["build"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "dataclasses-json" +version = "0.6.4" +description = "Easily serialize dataclasses to and from JSON." +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "dataclasses_json-0.6.4-py3-none-any.whl", hash = "sha256:f90578b8a3177f7552f4e1a6e535e84293cd5da421fcce0642d49c0d7bdf8df2"}, + {file = "dataclasses_json-0.6.4.tar.gz", hash = "sha256:73696ebf24936560cca79a2430cbc4f3dd23ac7bf46ed17f38e5e5e7657a6377"}, +] + +[package.dependencies] +marshmallow = ">=3.18.0,<4.0.0" +typing-inspect = ">=0.4.0,<1" + +[[package]] +name = "debugpy" +version = "1.8.1" +description = "An implementation of the Debug Adapter Protocol for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "debugpy-1.8.1-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:3bda0f1e943d386cc7a0e71bfa59f4137909e2ed947fb3946c506e113000f741"}, + {file = "debugpy-1.8.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dda73bf69ea479c8577a0448f8c707691152e6c4de7f0c4dec5a4bc11dee516e"}, + {file = "debugpy-1.8.1-cp310-cp310-win32.whl", hash = "sha256:3a79c6f62adef994b2dbe9fc2cc9cc3864a23575b6e387339ab739873bea53d0"}, + {file = "debugpy-1.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:7eb7bd2b56ea3bedb009616d9e2f64aab8fc7000d481faec3cd26c98a964bcdd"}, + {file = "debugpy-1.8.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:016a9fcfc2c6b57f939673c874310d8581d51a0fe0858e7fac4e240c5eb743cb"}, + {file = "debugpy-1.8.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd97ed11a4c7f6d042d320ce03d83b20c3fb40da892f994bc041bbc415d7a099"}, + {file = "debugpy-1.8.1-cp311-cp311-win32.whl", hash = "sha256:0de56aba8249c28a300bdb0672a9b94785074eb82eb672db66c8144fff673146"}, + {file = "debugpy-1.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:1a9fe0829c2b854757b4fd0a338d93bc17249a3bf69ecf765c61d4c522bb92a8"}, + {file = "debugpy-1.8.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:3ebb70ba1a6524d19fa7bb122f44b74170c447d5746a503e36adc244a20ac539"}, + {file = "debugpy-1.8.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2e658a9630f27534e63922ebf655a6ab60c370f4d2fc5c02a5b19baf4410ace"}, + {file = "debugpy-1.8.1-cp312-cp312-win32.whl", hash = "sha256:caad2846e21188797a1f17fc09c31b84c7c3c23baf2516fed5b40b378515bbf0"}, + {file = "debugpy-1.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:edcc9f58ec0fd121a25bc950d4578df47428d72e1a0d66c07403b04eb93bcf98"}, + {file = "debugpy-1.8.1-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:7a3afa222f6fd3d9dfecd52729bc2e12c93e22a7491405a0ecbf9e1d32d45b39"}, + {file = "debugpy-1.8.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d915a18f0597ef685e88bb35e5d7ab968964b7befefe1aaea1eb5b2640b586c7"}, + {file = "debugpy-1.8.1-cp38-cp38-win32.whl", hash = "sha256:92116039b5500633cc8d44ecc187abe2dfa9b90f7a82bbf81d079fcdd506bae9"}, + {file = "debugpy-1.8.1-cp38-cp38-win_amd64.whl", hash = "sha256:e38beb7992b5afd9d5244e96ad5fa9135e94993b0c551ceebf3fe1a5d9beb234"}, + {file = "debugpy-1.8.1-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:bfb20cb57486c8e4793d41996652e5a6a885b4d9175dd369045dad59eaacea42"}, + {file = "debugpy-1.8.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efd3fdd3f67a7e576dd869c184c5dd71d9aaa36ded271939da352880c012e703"}, + {file = "debugpy-1.8.1-cp39-cp39-win32.whl", hash = "sha256:58911e8521ca0c785ac7a0539f1e77e0ce2df753f786188f382229278b4cdf23"}, + {file = "debugpy-1.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:6df9aa9599eb05ca179fb0b810282255202a66835c6efb1d112d21ecb830ddd3"}, + {file = "debugpy-1.8.1-py2.py3-none-any.whl", hash = "sha256:28acbe2241222b87e255260c76741e1fbf04fdc3b6d094fcf57b6c6f75ce1242"}, + {file = "debugpy-1.8.1.zip", hash = "sha256:f696d6be15be87aef621917585f9bb94b1dc9e8aced570db1b8a6fc14e8f9b42"}, +] + +[[package]] +name = "decorator" +version = "5.1.1" +description = "Decorators for Humans" +optional = false +python-versions = ">=3.5" +files = [ + {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, + {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +description = "XML bomb protection for Python stdlib modules" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, + {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, +] + +[[package]] +name = "distro" +version = "1.9.0" +description = "Distro - an OS platform information API" +optional = false +python-versions = ">=3.6" +files = [ + {file = "distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2"}, + {file = "distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed"}, +] + +[[package]] +name = "docopt" +version = "0.6.2" +description = "Pythonic argument parser, that will make you smile" +optional = false +python-versions = "*" +files = [ + {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, +] + +[[package]] +name = "entrypoints" +version = "0.4" +description = "Discover and load entry points from installed packages." +optional = false +python-versions = ">=3.6" +files = [ + {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, + {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.0" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +files = [ + {file = "exceptiongroup-1.2.0-py3-none-any.whl", hash = "sha256:4bfd3996ac73b41e9b9628b04e079f193850720ea5945fc96a08633c66912f14"}, + {file = "exceptiongroup-1.2.0.tar.gz", hash = "sha256:91f5c769735f051a4290d52edd0858999b57e5876e9f85937691bd4c9fa3ed68"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "executing" +version = "2.0.1" +description = "Get the currently executing AST node of a frame, and other information" +optional = false +python-versions = ">=3.5" +files = [ + {file = "executing-2.0.1-py2.py3-none-any.whl", hash = "sha256:eac49ca94516ccc753f9fb5ce82603156e590b27525a8bc32cce8ae302eb61bc"}, + {file = "executing-2.0.1.tar.gz", hash = "sha256:35afe2ce3affba8ee97f2d69927fa823b08b472b7b994e36a52a964b93d16147"}, +] + +[package.extras] +tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"] + +[[package]] +name = "faiss-cpu" +version = "1.7.4" +description = "A library for efficient similarity search and clustering of dense vectors." +optional = false +python-versions = "*" +files = [ + {file = "faiss-cpu-1.7.4.tar.gz", hash = "sha256:265dc31b0c079bf4433303bf6010f73922490adff9188b915e2d3f5e9c82dd0a"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50d4ebe7f1869483751c558558504f818980292a9b55be36f9a1ee1009d9a686"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b1db7fae7bd8312aeedd0c41536bcd19a6e297229e1dce526bde3a73ab8c0b5"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:17b7fa7194a228a84929d9e6619d0e7dbf00cc0f717e3462253766f5e3d07de8"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dca531952a2e3eac56f479ff22951af4715ee44788a3fe991d208d766d3f95f3"}, + {file = "faiss_cpu-1.7.4-cp310-cp310-win_amd64.whl", hash = "sha256:7173081d605e74766f950f2e3d6568a6f00c53f32fd9318063e96728c6c62821"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d0bbd6f55d7940cc0692f79e32a58c66106c3c950cee2341b05722de9da23ea3"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e13c14280376100f143767d0efe47dcb32618f69e62bbd3ea5cd38c2e1755926"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c521cb8462f3b00c0c7dfb11caff492bb67816528b947be28a3b76373952c41d"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afdd9fe1141117fed85961fd36ee627c83fc3b9fd47bafb52d3c849cc2f088b7"}, + {file = "faiss_cpu-1.7.4-cp311-cp311-win_amd64.whl", hash = "sha256:2ff7f57889ea31d945e3b87275be3cad5d55b6261a4e3f51c7aba304d76b81fb"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:eeaf92f27d76249fb53c1adafe617b0f217ab65837acf7b4ec818511caf6e3d8"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:102b1bd763e9b0c281ac312590af3eaf1c8b663ccbc1145821fe6a9f92b8eaaf"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5512da6707c967310c46ff712b00418b7ae28e93cb609726136e826e9f2f14fa"}, + {file = "faiss_cpu-1.7.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0c2e5b9d8c28c99f990e87379d5bbcc6c914da91ebb4250166864fd12db5755b"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:43f67f325393145d360171cd98786fcea6120ce50397319afd3bb78be409fb8a"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:6a4e4af194b8fce74c4b770cad67ad1dd1b4673677fc169723e4c50ba5bd97a8"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:31bfb7b9cffc36897ae02a983e04c09fe3b8c053110a287134751a115334a1df"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52d7de96abef2340c0d373c1f5cbc78026a3cebb0f8f3a5920920a00210ead1f"}, + {file = "faiss_cpu-1.7.4-cp38-cp38-win_amd64.whl", hash = "sha256:699feef85b23c2c729d794e26ca69bebc0bee920d676028c06fd0e0becc15c7e"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:559a0133f5ed44422acb09ee1ac0acffd90c6666d1bc0d671c18f6e93ad603e2"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1d71539fe3dc0f1bed41ef954ca701678776f231046bf0ca22ccea5cf5bef6"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12d45e0157024eb3249842163162983a1ac8b458f1a8b17bbf86f01be4585a99"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2f0eab359e066d32c874f51a7d4bf6440edeec068b7fe47e6d803c73605a8b4c"}, + {file = "faiss_cpu-1.7.4-cp39-cp39-win_amd64.whl", hash = "sha256:98459ceeeb735b9df1a5b94572106ffe0a6ce740eb7e4626715dd218657bb4dc"}, +] + +[[package]] +name = "fastapi" +version = "0.109.2" +description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" +optional = false +python-versions = ">=3.8" +files = [ + {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, + {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, +] + +[package.dependencies] +pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" +starlette = ">=0.36.3,<0.37.0" +typing-extensions = ">=4.8.0" + +[package.extras] +all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] + +[[package]] +name = "fastjsonschema" +version = "2.19.1" +description = "Fastest Python implementation of JSON schema" +optional = false +python-versions = "*" +files = [ + {file = "fastjsonschema-2.19.1-py3-none-any.whl", hash = "sha256:3672b47bc94178c9f23dbb654bf47440155d4db9df5f7bc47643315f9c405cd0"}, + {file = "fastjsonschema-2.19.1.tar.gz", hash = "sha256:e3126a94bdc4623d3de4485f8d468a12f02a67921315ddc87836d6e456dc789d"}, +] + +[package.extras] +devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benchmark", "pytest-cache", "validictory"] + +[[package]] +name = "fqdn" +version = "1.5.1" +description = "Validates fully-qualified domain names against RFC 1123, so that they are acceptable to modern bowsers" +optional = false +python-versions = ">=2.7, !=3.0, !=3.1, !=3.2, !=3.3, !=3.4, <4" +files = [ + {file = "fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014"}, + {file = "fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f"}, +] + +[[package]] +name = "frozenlist" +version = "1.4.1" +description = "A list-like structure which implements collections.abc.MutableSequence" +optional = false +python-versions = ">=3.8" +files = [ + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f9aa1878d1083b276b0196f2dfbe00c9b7e752475ed3b682025ff20c1c1f51ac"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:29acab3f66f0f24674b7dc4736477bcd4bc3ad4b896f5f45379a67bce8b96868"}, + {file = "frozenlist-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:74fb4bee6880b529a0c6560885fce4dc95936920f9f20f53d99a213f7bf66776"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:590344787a90ae57d62511dd7c736ed56b428f04cd8c161fcc5e7232c130c69a"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:068b63f23b17df8569b7fdca5517edef76171cf3897eb68beb01341131fbd2ad"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5c849d495bf5154cd8da18a9eb15db127d4dba2968d88831aff6f0331ea9bd4c"}, + {file = "frozenlist-1.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9750cc7fe1ae3b1611bb8cfc3f9ec11d532244235d75901fb6b8e42ce9229dfe"}, + {file = "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"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0633c8d5337cb5c77acbccc6357ac49a1770b8c487e5b3505c57b949b4b82e98"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:27657df69e8801be6c3638054e202a135c7f299267f1a55ed3a598934f6c0d75"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:f9a3ea26252bd92f570600098783d1371354d89d5f6b7dfd87359d669f2109b5"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:4f57dab5fe3407b6c0c1cc907ac98e8a189f9e418f3b6e54d65a718aaafe3950"}, + {file = "frozenlist-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e02a0e11cf6597299b9f3bbd3f93d79217cb90cfd1411aec33848b13f5c656cc"}, + {file = "frozenlist-1.4.1-cp310-cp310-win32.whl", hash = "sha256:a828c57f00f729620a442881cc60e57cfcec6842ba38e1b19fd3e47ac0ff8dc1"}, + {file = "frozenlist-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:f56e2333dda1fe0f909e7cc59f021eba0d2307bc6f012a1ccf2beca6ba362439"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a0cb6f11204443f27a1628b0e460f37fb30f624be6051d490fa7d7e26d4af3d0"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b46c8ae3a8f1f41a0d2ef350c0b6e65822d80772fe46b653ab6b6274f61d4a49"}, + {file = "frozenlist-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fde5bd59ab5357e3853313127f4d3565fc7dad314a74d7b5d43c22c6a5ed2ced"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:722e1124aec435320ae01ee3ac7bec11a5d47f25d0ed6328f2273d287bc3abb0"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2471c201b70d58a0f0c1f91261542a03d9a5e088ed3dc6c160d614c01649c106"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c757a9dd70d72b076d6f68efdbb9bc943665ae954dad2801b874c8c69e185068"}, + {file = "frozenlist-1.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f146e0911cb2f1da549fc58fc7bcd2b836a44b79ef871980d605ec392ff6b0d2"}, + {file = "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"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c302220494f5c1ebeb0912ea782bcd5e2f8308037b3c7553fad0e48ebad6ad82"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:442acde1e068288a4ba7acfe05f5f343e19fac87bfc96d89eb886b0363e977ec"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:1b280e6507ea8a4fa0c0a7150b4e526a8d113989e28eaaef946cc77ffd7efc0a"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:fe1a06da377e3a1062ae5fe0926e12b84eceb8a50b350ddca72dc85015873f74"}, + {file = "frozenlist-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db9e724bebd621d9beca794f2a4ff1d26eed5965b004a97f1f1685a173b869c2"}, + {file = "frozenlist-1.4.1-cp311-cp311-win32.whl", hash = "sha256:e774d53b1a477a67838a904131c4b0eef6b3d8a651f8b138b04f748fccfefe17"}, + {file = "frozenlist-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:fb3c2db03683b5767dedb5769b8a40ebb47d6f7f45b1b3e3b4b51ec8ad9d9825"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:1979bc0aeb89b33b588c51c54ab0161791149f2461ea7c7c946d95d5f93b56ae"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cc7b01b3754ea68a62bd77ce6020afaffb44a590c2289089289363472d13aedb"}, + {file = "frozenlist-1.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c9c92be9fd329ac801cc420e08452b70e7aeab94ea4233a4804f0915c14eba9b"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c3894db91f5a489fc8fa6a9991820f368f0b3cbdb9cd8849547ccfab3392d86"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba60bb19387e13597fb059f32cd4d59445d7b18b69a745b8f8e5db0346f33480"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8aefbba5f69d42246543407ed2461db31006b0f76c4e32dfd6f42215a2c41d09"}, + {file = "frozenlist-1.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780d3a35680ced9ce682fbcf4cb9c2bad3136eeff760ab33707b71db84664e3a"}, + {file = "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"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:23b701e65c7b36e4bf15546a89279bd4d8675faabc287d06bbcfac7d3c33e1e6"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:3e0153a805a98f5ada7e09826255ba99fb4f7524bb81bf6b47fb702666484ae1"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:dd9b1baec094d91bf36ec729445f7769d0d0cf6b64d04d86e45baf89e2b9059b"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:1a4471094e146b6790f61b98616ab8e44f72661879cc63fa1049d13ef711e71e"}, + {file = "frozenlist-1.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:5667ed53d68d91920defdf4035d1cdaa3c3121dc0b113255124bcfada1cfa1b8"}, + {file = "frozenlist-1.4.1-cp312-cp312-win32.whl", hash = "sha256:beee944ae828747fd7cb216a70f120767fc9f4f00bacae8543c14a6831673f89"}, + {file = "frozenlist-1.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:64536573d0a2cb6e625cf309984e2d873979709f2cf22839bf2d61790b448ad5"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:20b51fa3f588ff2fe658663db52a41a4f7aa6c04f6201449c6c7c476bd255c0d"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:410478a0c562d1a5bcc2f7ea448359fcb050ed48b3c6f6f4f18c313a9bdb1826"}, + {file = "frozenlist-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c6321c9efe29975232da3bd0af0ad216800a47e93d763ce64f291917a381b8eb"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48f6a4533887e189dae092f1cf981f2e3885175f7a0f33c91fb5b7b682b6bab6"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6eb73fa5426ea69ee0e012fb59cdc76a15b1283d6e32e4f8dc4482ec67d1194d"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbeb989b5cc29e8daf7f976b421c220f1b8c731cbf22b9130d8815418ea45887"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32453c1de775c889eb4e22f1197fe3bdfe457d16476ea407472b9442e6295f7a"}, + {file = "frozenlist-1.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693945278a31f2086d9bf3df0fe8254bbeaef1fe71e1351c3bd730aa7d31c41b"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1d0ce09d36d53bbbe566fe296965b23b961764c0bcf3ce2fa45f463745c04701"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:3a670dc61eb0d0eb7080890c13de3066790f9049b47b0de04007090807c776b0"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dca69045298ce5c11fd539682cff879cc1e664c245d1c64da929813e54241d11"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a06339f38e9ed3a64e4c4e43aec7f59084033647f908e4259d279a52d3757d09"}, + {file = "frozenlist-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b7f2f9f912dca3934c1baec2e4585a674ef16fe00218d833856408c48d5beee7"}, + {file = "frozenlist-1.4.1-cp38-cp38-win32.whl", hash = "sha256:e7004be74cbb7d9f34553a5ce5fb08be14fb33bc86f332fb71cbe5216362a497"}, + {file = "frozenlist-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:5a7d70357e7cee13f470c7883a063aae5fe209a493c57d86eb7f5a6f910fae09"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bfa4a17e17ce9abf47a74ae02f32d014c5e9404b6d9ac7f729e01562bbee601e"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b7e3ed87d4138356775346e6845cccbe66cd9e207f3cd11d2f0b9fd13681359d"}, + {file = "frozenlist-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c99169d4ff810155ca50b4da3b075cbde79752443117d89429595c2e8e37fed8"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edb678da49d9f72c9f6c609fbe41a5dfb9a9282f9e6a2253d5a91e0fc382d7c0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6db4667b187a6742b33afbbaf05a7bc551ffcf1ced0000a571aedbb4aa42fc7b"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55fdc093b5a3cb41d420884cdaf37a1e74c3c37a31f46e66286d9145d2063bd0"}, + {file = "frozenlist-1.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:82e8211d69a4f4bc360ea22cd6555f8e61a1bd211d1d5d39d3d228b48c83a897"}, + {file = "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"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9d3e0c25a2350080e9319724dede4f31f43a6c9779be48021a7f4ebde8b2d742"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7268252af60904bf52c26173cbadc3a071cece75f873705419c8681f24d3edea"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:0c250a29735d4f15321007fb02865f0e6b6a41a6b88f1f523ca1596ab5f50bd5"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:96ec70beabbd3b10e8bfe52616a13561e58fe84c0101dd031dc78f250d5128b9"}, + {file = "frozenlist-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:23b2d7679b73fe0e5a4560b672a39f98dfc6f60df63823b0a9970525325b95f6"}, + {file = "frozenlist-1.4.1-cp39-cp39-win32.whl", hash = "sha256:a7496bfe1da7fb1a4e1cc23bb67c58fab69311cc7d32b5a99c2007b4b2a0e932"}, + {file = "frozenlist-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e6a20a581f9ce92d389a8c7d7c3dd47c81fd5d6e655c8dddf341e14aa48659d0"}, + {file = "frozenlist-1.4.1-py3-none-any.whl", hash = "sha256:04ced3e6a46b4cfffe20f9ae482818e34eba9b5fb0ce4056e4cc9b6e212d09b7"}, + {file = "frozenlist-1.4.1.tar.gz", hash = "sha256:c037a86e8513059a2613aaba4d817bb90b9d9b6b69aace3ce9c877e8c8ed402b"}, +] + +[[package]] +name = "greenlet" +version = "3.0.3" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.7" +files = [ + {file = "greenlet-3.0.3-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9da2bd29ed9e4f15955dd1595ad7bc9320308a3b766ef7f837e23ad4b4aac31a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d353cadd6083fdb056bb46ed07e4340b0869c305c8ca54ef9da3421acbdf6881"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dca1e2f3ca00b84a396bc1bce13dd21f680f035314d2379c4160c98153b2059b"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ed7fb269f15dc662787f4119ec300ad0702fa1b19d2135a37c2c4de6fadfd4a"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd4f49ae60e10adbc94b45c0b5e6a179acc1736cf7a90160b404076ee283cf83"}, + {file = "greenlet-3.0.3-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:73a411ef564e0e097dbe7e866bb2dda0f027e072b04da387282b02c308807405"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7f362975f2d179f9e26928c5b517524e89dd48530a0202570d55ad6ca5d8a56f"}, + {file = "greenlet-3.0.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:649dde7de1a5eceb258f9cb00bdf50e978c9db1b996964cd80703614c86495eb"}, + {file = "greenlet-3.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:68834da854554926fbedd38c76e60c4a2e3198c6fbed520b106a8986445caaf9"}, + {file = "greenlet-3.0.3-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b1b5667cced97081bf57b8fa1d6bfca67814b0afd38208d52538316e9422fc61"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:52f59dd9c96ad2fc0d5724107444f76eb20aaccb675bf825df6435acb7703559"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:afaff6cf5200befd5cec055b07d1c0a5a06c040fe5ad148abcd11ba6ab9b114e"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe754d231288e1e64323cfad462fcee8f0288654c10bdf4f603a39ed923bef33"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2797aa5aedac23af156bbb5a6aa2cd3427ada2972c828244eb7d1b9255846379"}, + {file = "greenlet-3.0.3-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7f009caad047246ed379e1c4dbcb8b020f0a390667ea74d2387be2998f58a22"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:c5e1536de2aad7bf62e27baf79225d0d64360d4168cf2e6becb91baf1ed074f3"}, + {file = "greenlet-3.0.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:894393ce10ceac937e56ec00bb71c4c2f8209ad516e96033e4b3b1de270e200d"}, + {file = "greenlet-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:1ea188d4f49089fc6fb283845ab18a2518d279c7cd9da1065d7a84e991748728"}, + {file = "greenlet-3.0.3-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:70fb482fdf2c707765ab5f0b6655e9cfcf3780d8d87355a063547b41177599be"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4d1ac74f5c0c0524e4a24335350edad7e5f03b9532da7ea4d3c54d527784f2e"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149e94a2dd82d19838fe4b2259f1b6b9957d5ba1b25640d2380bea9c5df37676"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:15d79dd26056573940fcb8c7413d84118086f2ec1a8acdfa854631084393efcc"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:881b7db1ebff4ba09aaaeae6aa491daeb226c8150fc20e836ad00041bcb11230"}, + {file = "greenlet-3.0.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fcd2469d6a2cf298f198f0487e0a5b1a47a42ca0fa4dfd1b6862c999f018ebbf"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f672519db1796ca0d8753f9e78ec02355e862d0998193038c7073045899f305"}, + {file = "greenlet-3.0.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2516a9957eed41dd8f1ec0c604f1cdc86758b587d964668b5b196a9db5bfcde6"}, + {file = "greenlet-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:bba5387a6975598857d86de9eac14210a49d554a77eb8261cc68b7d082f78ce2"}, + {file = "greenlet-3.0.3-cp37-cp37m-macosx_11_0_universal2.whl", hash = "sha256:5b51e85cb5ceda94e79d019ed36b35386e8c37d22f07d6a751cb659b180d5274"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:daf3cb43b7cf2ba96d614252ce1684c1bccee6b2183a01328c98d36fcd7d5cb0"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99bf650dc5d69546e076f413a87481ee1d2d09aaaaaca058c9251b6d8c14783f"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2dd6e660effd852586b6a8478a1d244b8dc90ab5b1321751d2ea15deb49ed414"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e3391d1e16e2a5a1507d83e4a8b100f4ee626e8eca43cf2cadb543de69827c4c"}, + {file = "greenlet-3.0.3-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1f145462f1fa6e4a4ae3c0f782e580ce44d57c8f2c7aae1b6fa88c0b2efdb41"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a7191e42732df52cb5f39d3527217e7ab73cae2cb3694d241e18f53d84ea9a7"}, + {file = "greenlet-3.0.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0448abc479fab28b00cb472d278828b3ccca164531daab4e970a0458786055d6"}, + {file = "greenlet-3.0.3-cp37-cp37m-win32.whl", hash = "sha256:b542be2440edc2d48547b5923c408cbe0fc94afb9f18741faa6ae970dbcb9b6d"}, + {file = "greenlet-3.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:01bc7ea167cf943b4c802068e178bbf70ae2e8c080467070d01bfa02f337ee67"}, + {file = "greenlet-3.0.3-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:1996cb9306c8595335bb157d133daf5cf9f693ef413e7673cb07e3e5871379ca"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ddc0f794e6ad661e321caa8d2f0a55ce01213c74722587256fb6566049a8b04"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c9db1c18f0eaad2f804728c67d6c610778456e3e1cc4ab4bbd5eeb8e6053c6fc"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7170375bcc99f1a2fbd9c306f5be8764eaf3ac6b5cb968862cad4c7057756506"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b66c9c1e7ccabad3a7d037b2bcb740122a7b17a53734b7d72a344ce39882a1b"}, + {file = "greenlet-3.0.3-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:098d86f528c855ead3479afe84b49242e174ed262456c342d70fc7f972bc13c4"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:81bb9c6d52e8321f09c3d165b2a78c680506d9af285bfccbad9fb7ad5a5da3e5"}, + {file = "greenlet-3.0.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:fd096eb7ffef17c456cfa587523c5f92321ae02427ff955bebe9e3c63bc9f0da"}, + {file = "greenlet-3.0.3-cp38-cp38-win32.whl", hash = "sha256:d46677c85c5ba00a9cb6f7a00b2bfa6f812192d2c9f7d9c4f6a55b60216712f3"}, + {file = "greenlet-3.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:419b386f84949bf0e7c73e6032e3457b82a787c1ab4a0e43732898a761cc9dbf"}, + {file = "greenlet-3.0.3-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:da70d4d51c8b306bb7a031d5cff6cc25ad253affe89b70352af5f1cb68e74b53"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086152f8fbc5955df88382e8a75984e2bb1c892ad2e3c80a2508954e52295257"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d73a9fe764d77f87f8ec26a0c85144d6a951a6c438dfe50487df5595c6373eac"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7dcbe92cc99f08c8dd11f930de4d99ef756c3591a5377d1d9cd7dd5e896da71"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1551a8195c0d4a68fac7a4325efac0d541b48def35feb49d803674ac32582f61"}, + {file = "greenlet-3.0.3-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:64d7675ad83578e3fc149b617a444fab8efdafc9385471f868eb5ff83e446b8b"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b37eef18ea55f2ffd8f00ff8fe7c8d3818abd3e25fb73fae2ca3b672e333a7a6"}, + {file = "greenlet-3.0.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:77457465d89b8263bca14759d7c1684df840b6811b2499838cc5b040a8b5b113"}, + {file = "greenlet-3.0.3-cp39-cp39-win32.whl", hash = "sha256:57e8974f23e47dac22b83436bdcf23080ade568ce77df33159e019d161ce1d1e"}, + {file = "greenlet-3.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:c5ee858cfe08f34712f548c3c363e807e7186f03ad7a5039ebadb29e8c6be067"}, + {file = "greenlet-3.0.3.tar.gz", hash = "sha256:43374442353259554ce33599da8b692d5aa96f8976d567d4badf263371fbe491"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "h11" +version = "0.14.0" +description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +optional = false +python-versions = ">=3.7" +files = [ + {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, + {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, +] + +[[package]] +name = "httpcore" +version = "1.0.3" +description = "A minimal low-level HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpcore-1.0.3-py3-none-any.whl", hash = "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2"}, + {file = "httpcore-1.0.3.tar.gz", hash = "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544"}, +] + +[package.dependencies] +certifi = "*" +h11 = ">=0.13,<0.15" + +[package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.24.0)"] + +[[package]] +name = "httpx" +version = "0.26.0" +description = "The next generation HTTP client." +optional = false +python-versions = ">=3.8" +files = [ + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, +] + +[package.dependencies] +anyio = "*" +certifi = "*" +httpcore = "==1.*" +idna = "*" +sniffio = "*" + +[package.extras] +brotli = ["brotli", "brotlicffi"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +http2 = ["h2 (>=3,<5)"] +socks = ["socksio (==1.*)"] + +[[package]] +name = "idna" +version = "3.6" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.5" +files = [ + {file = "idna-3.6-py3-none-any.whl", hash = "sha256:c05567e9c24a6b9faaa835c4821bad0590fbb9d5779e7caa6e1cc4978e7eb24f"}, + {file = "idna-3.6.tar.gz", hash = "sha256:9ecdbbd083b06798ae1e86adcbfe8ab1479cf864e4ee30fe4e46a003d12491ca"}, +] + +[[package]] +name = "importlib-metadata" +version = "7.0.1" +description = "Read metadata from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_metadata-7.0.1-py3-none-any.whl", hash = "sha256:4805911c3a4ec7c3966410053e9ec6a1fecd629117df5adee56dfc9432a1081e"}, + {file = "importlib_metadata-7.0.1.tar.gz", hash = "sha256:f238736bb06590ae52ac1fab06a3a9ef1d8dce2b7a35b5ab329371d6c8f5d2cc"}, +] + +[package.dependencies] +zipp = ">=0.5" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +perf = ["ipython"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] + +[[package]] +name = "importlib-resources" +version = "6.1.1" +description = "Read resources from Python packages" +optional = false +python-versions = ">=3.8" +files = [ + {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, + {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, +] + +[package.dependencies] +zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] + +[[package]] +name = "iniconfig" +version = "2.0.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, + {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, +] + +[[package]] +name = "ipykernel" +version = "6.29.2" +description = "IPython Kernel for Jupyter" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipykernel-6.29.2-py3-none-any.whl", hash = "sha256:50384f5c577a260a1d53f1f59a828c7266d321c9b7d00d345693783f66616055"}, + {file = "ipykernel-6.29.2.tar.gz", hash = "sha256:3bade28004e3ff624ed57974948116670604ac5f676d12339693f3142176d3f0"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "platform_system == \"Darwin\""} +comm = ">=0.1.1" +debugpy = ">=1.6.5" +ipython = ">=7.23.1" +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +matplotlib-inline = ">=0.1" +nest-asyncio = "*" +packaging = "*" +psutil = "*" +pyzmq = ">=24" +tornado = ">=6.1" +traitlets = ">=5.4.0" + +[package.extras] +cov = ["coverage[toml]", "curio", "matplotlib", "pytest-cov", "trio"] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "trio"] +pyqt5 = ["pyqt5"] +pyside6 = ["pyside6"] +test = ["flaky", "ipyparallel", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (==0.23.4)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "ipython" +version = "8.12.3" +description = "IPython: Productive Interactive Computing" +optional = false +python-versions = ">=3.8" +files = [ + {file = "ipython-8.12.3-py3-none-any.whl", hash = "sha256:b0340d46a933d27c657b211a329d0be23793c36595acf9e6ef4164bc01a1804c"}, + {file = "ipython-8.12.3.tar.gz", hash = "sha256:3910c4b54543c2ad73d06579aa771041b7d5707b033bd488669b4cf544e3b363"}, +] + +[package.dependencies] +appnope = {version = "*", markers = "sys_platform == \"darwin\""} +backcall = "*" +colorama = {version = "*", markers = "sys_platform == \"win32\""} +decorator = "*" +jedi = ">=0.16" +matplotlib-inline = "*" +pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} +pickleshare = "*" +prompt-toolkit = ">=3.0.30,<3.0.37 || >3.0.37,<3.1.0" +pygments = ">=2.4.0" +stack-data = "*" +traitlets = ">=5" +typing-extensions = {version = "*", markers = "python_version < \"3.10\""} + +[package.extras] +all = ["black", "curio", "docrepr", "ipykernel", "ipyparallel", "ipywidgets", "matplotlib", "matplotlib (!=3.2.0)", "nbconvert", "nbformat", "notebook", "numpy (>=1.21)", "pandas", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "qtconsole", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "trio", "typing-extensions"] +black = ["black"] +doc = ["docrepr", "ipykernel", "matplotlib", "pytest (<7)", "pytest (<7.1)", "pytest-asyncio", "setuptools (>=18.5)", "sphinx (>=1.3)", "sphinx-rtd-theme", "stack-data", "testpath", "typing-extensions"] +kernel = ["ipykernel"] +nbconvert = ["nbconvert"] +nbformat = ["nbformat"] +notebook = ["ipywidgets", "notebook"] +parallel = ["ipyparallel"] +qtconsole = ["qtconsole"] +test = ["pytest (<7.1)", "pytest-asyncio", "testpath"] +test-extra = ["curio", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.21)", "pandas", "pytest (<7.1)", "pytest-asyncio", "testpath", "trio"] + +[[package]] +name = "ipython-genutils" +version = "0.2.0" +description = "Vestigial utilities from IPython" +optional = false +python-versions = "*" +files = [ + {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, + {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +description = "Operations with ISO 8601 durations" +optional = false +python-versions = ">=3.7" +files = [ + {file = "isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042"}, + {file = "isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9"}, +] + +[package.dependencies] +arrow = ">=0.15.0" + +[[package]] +name = "jedi" +version = "0.19.1" +description = "An autocompletion tool for Python that can be used for text editors." +optional = false +python-versions = ">=3.6" +files = [ + {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"}, + {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"}, +] + +[package.dependencies] +parso = ">=0.8.3,<0.9.0" + +[package.extras] +docs = ["Jinja2 (==2.11.3)", "MarkupSafe (==1.1.1)", "Pygments (==2.8.1)", "alabaster (==0.7.12)", "babel (==2.9.1)", "chardet (==4.0.0)", "commonmark (==0.8.1)", "docutils (==0.17.1)", "future (==0.18.2)", "idna (==2.10)", "imagesize (==1.2.0)", "mock (==1.0.1)", "packaging (==20.9)", "pyparsing (==2.4.7)", "pytz (==2021.1)", "readthedocs-sphinx-ext (==2.1.4)", "recommonmark (==0.5.0)", "requests (==2.25.1)", "six (==1.15.0)", "snowballstemmer (==2.1.0)", "sphinx (==1.8.5)", "sphinx-rtd-theme (==0.4.3)", "sphinxcontrib-serializinghtml (==1.1.4)", "sphinxcontrib-websupport (==1.2.4)", "urllib3 (==1.26.4)"] +qa = ["flake8 (==5.0.4)", "mypy (==0.971)", "types-setuptools (==67.2.0.1)"] +testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] + +[[package]] +name = "jinja2" +version = "3.1.3" +description = "A very fast and expressive template engine." +optional = false +python-versions = ">=3.7" +files = [ + {file = "Jinja2-3.1.3-py3-none-any.whl", hash = "sha256:7d6d50dd97d52cbc355597bd845fabfbac3f551e1f99619e39a35ce8c370b5fa"}, + {file = "Jinja2-3.1.3.tar.gz", hash = "sha256:ac8bd6544d4bb2c9792bf3a159e80bba8fda7f07e81bc3aed565432d5925ba90"}, +] + +[package.dependencies] +MarkupSafe = ">=2.0" + +[package.extras] +i18n = ["Babel (>=2.7)"] + +[[package]] +name = "json5" +version = "0.9.14" +description = "A Python implementation of the JSON5 data format." +optional = false +python-versions = "*" +files = [ + {file = "json5-0.9.14-py2.py3-none-any.whl", hash = "sha256:740c7f1b9e584a468dbb2939d8d458db3427f2c93ae2139d05f47e453eae964f"}, + {file = "json5-0.9.14.tar.gz", hash = "sha256:9ed66c3a6ca3510a976a9ef9b8c0787de24802724ab1860bc0153c7fdd589b02"}, +] + +[package.extras] +dev = ["hypothesis"] + +[[package]] +name = "jsonpatch" +version = "1.33" +description = "Apply JSON-Patches (RFC 6902)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade"}, + {file = "jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c"}, +] + +[package.dependencies] +jsonpointer = ">=1.9" + +[[package]] +name = "jsonpointer" +version = "2.4" +description = "Identify specific nodes in a JSON document (RFC 6901)" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*" +files = [ + {file = "jsonpointer-2.4-py2.py3-none-any.whl", hash = "sha256:15d51bba20eea3165644553647711d150376234112651b4f1811022aecad7d7a"}, + {file = "jsonpointer-2.4.tar.gz", hash = "sha256:585cee82b70211fa9e6043b7bb89db6e1aa49524340dde8ad6b63206ea689d88"}, +] + +[[package]] +name = "jsonschema" +version = "4.21.1" +description = "An implementation of JSON Schema validation for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, + {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +fqdn = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +idna = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +isoduration = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +jsonpointer = {version = ">1.13", optional = true, markers = "extra == \"format-nongpl\""} +jsonschema-specifications = ">=2023.03.6" +pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} +referencing = ">=0.28.4" +rfc3339-validator = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +rfc3986-validator = {version = ">0.1.0", optional = true, markers = "extra == \"format-nongpl\""} +rpds-py = ">=0.7.1" +uri-template = {version = "*", optional = true, markers = "extra == \"format-nongpl\""} +webcolors = {version = ">=1.11", optional = true, markers = "extra == \"format-nongpl\""} + +[package.extras] +format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] +format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] + +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +referencing = ">=0.31.0" + +[[package]] +name = "jupyter-client" +version = "7.4.9" +description = "Jupyter protocol implementation and client libraries" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_client-7.4.9-py3-none-any.whl", hash = "sha256:214668aaea208195f4c13d28eb272ba79f945fc0cf3f11c7092c20b2ca1980e7"}, + {file = "jupyter_client-7.4.9.tar.gz", hash = "sha256:52be28e04171f07aed8f20e1616a5a552ab9fee9cbbe6c1896ae170c3880d392"}, +] + +[package.dependencies] +entrypoints = "*" +jupyter-core = ">=4.9.2" +nest-asyncio = ">=1.5.4" +python-dateutil = ">=2.8.2" +pyzmq = ">=23.0" +tornado = ">=6.2" +traitlets = "*" + +[package.extras] +doc = ["ipykernel", "myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] +test = ["codecov", "coverage", "ipykernel (>=6.12)", "ipython", "mypy", "pre-commit", "pytest", "pytest-asyncio (>=0.18)", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-core" +version = "5.7.1" +description = "Jupyter core package. A base package on which Jupyter projects rely." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_core-5.7.1-py3-none-any.whl", hash = "sha256:c65c82126453a723a2804aa52409930434598fd9d35091d63dfb919d2b765bb7"}, + {file = "jupyter_core-5.7.1.tar.gz", hash = "sha256:de61a9d7fc71240f688b2fb5ab659fbb56979458dc66a71decd098e03c79e218"}, +] + +[package.dependencies] +platformdirs = ">=2.5" +pywin32 = {version = ">=300", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} +traitlets = ">=5.3" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-spelling", "traitlets"] +test = ["ipykernel", "pre-commit", "pytest", "pytest-cov", "pytest-timeout"] + +[[package]] +name = "jupyter-events" +version = "0.9.0" +description = "Jupyter Event System library" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_events-0.9.0-py3-none-any.whl", hash = "sha256:d853b3c10273ff9bc8bb8b30076d65e2c9685579db736873de6c2232dde148bf"}, + {file = "jupyter_events-0.9.0.tar.gz", hash = "sha256:81ad2e4bc710881ec274d31c6c50669d71bbaa5dd9d01e600b56faa85700d399"}, +] + +[package.dependencies] +jsonschema = {version = ">=4.18.0", extras = ["format-nongpl"]} +python-json-logger = ">=2.0.4" +pyyaml = ">=5.3" +referencing = "*" +rfc3339-validator = "*" +rfc3986-validator = ">=0.1.1" +traitlets = ">=5.3" + +[package.extras] +cli = ["click", "rich"] +docs = ["jupyterlite-sphinx", "myst-parser", "pydata-sphinx-theme", "sphinxcontrib-spelling"] +test = ["click", "pre-commit", "pytest (>=7.0)", "pytest-asyncio (>=0.19.0)", "pytest-console-scripts", "rich"] + +[[package]] +name = "jupyter-server" +version = "2.12.5" +description = "The backendβ€”i.e. core services, APIs, and REST endpointsβ€”to Jupyter web applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server-2.12.5-py3-none-any.whl", hash = "sha256:184a0f82809a8522777cfb6b760ab6f4b1bb398664c5860a27cec696cb884923"}, + {file = "jupyter_server-2.12.5.tar.gz", hash = "sha256:0edb626c94baa22809be1323f9770cf1c00a952b17097592e40d03e6a3951689"}, +] + +[package.dependencies] +anyio = ">=3.1.0" +argon2-cffi = "*" +jinja2 = "*" +jupyter-client = ">=7.4.4" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +jupyter-events = ">=0.9.0" +jupyter-server-terminals = "*" +nbconvert = ">=6.4.4" +nbformat = ">=5.3.0" +overrides = "*" +packaging = "*" +prometheus-client = "*" +pywinpty = {version = "*", markers = "os_name == \"nt\""} +pyzmq = ">=24" +send2trash = ">=1.8.2" +terminado = ">=0.8.3" +tornado = ">=6.2.0" +traitlets = ">=5.6.0" +websocket-client = "*" + +[package.extras] +docs = ["ipykernel", "jinja2", "jupyter-client", "jupyter-server", "myst-parser", "nbformat", "prometheus-client", "pydata-sphinx-theme", "send2trash", "sphinx-autodoc-typehints", "sphinxcontrib-github-alt", "sphinxcontrib-openapi (>=0.8.0)", "sphinxcontrib-spelling", "sphinxemoji", "tornado", "typing-extensions"] +test = ["flaky", "ipykernel", "pre-commit", "pytest (>=7.0)", "pytest-console-scripts", "pytest-jupyter[server] (>=0.4)", "pytest-timeout", "requests"] + +[[package]] +name = "jupyter-server-fileid" +version = "0.9.1" +description = "Jupyter Server extension providing an implementation of the File ID service." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_server_fileid-0.9.1-py3-none-any.whl", hash = "sha256:76dd05a45b78c7ec0cba0be98ece289984c6bcfc1ca2da216d42930e506a4d68"}, + {file = "jupyter_server_fileid-0.9.1.tar.gz", hash = "sha256:7486bca3acf9bbaab7ce5127f9f64d2df58f5d2de377609fb833291a7217a6a2"}, +] + +[package.dependencies] +jupyter-events = ">=0.5.0" +jupyter-server = ">=1.15,<3" + +[package.extras] +cli = ["click"] +test = ["jupyter-server[test] (>=1.15,<3)", "pytest", "pytest-cov", "pytest-jupyter"] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.2" +description = "A Jupyter Server Extension Providing Terminals." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyter_server_terminals-0.5.2-py3-none-any.whl", hash = "sha256:1b80c12765da979513c42c90215481bbc39bd8ae7c0350b4f85bc3eb58d0fa80"}, + {file = "jupyter_server_terminals-0.5.2.tar.gz", hash = "sha256:396b5ccc0881e550bf0ee7012c6ef1b53edbde69e67cab1d56e89711b46052e8"}, +] + +[package.dependencies] +pywinpty = {version = ">=2.0.3", markers = "os_name == \"nt\""} +terminado = ">=0.8.3" + +[package.extras] +docs = ["jinja2", "jupyter-server", "mistune (<4.0)", "myst-parser", "nbformat", "packaging", "pydata-sphinx-theme", "sphinxcontrib-github-alt", "sphinxcontrib-openapi", "sphinxcontrib-spelling", "sphinxemoji", "tornado"] +test = ["jupyter-server (>=2.0.0)", "pytest (>=7.0)", "pytest-jupyter[server] (>=0.5.3)", "pytest-timeout"] + +[[package]] +name = "jupyter-server-ydoc" +version = "0.8.0" +description = "A Jupyter Server Extension Providing Y Documents." +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_server_ydoc-0.8.0-py3-none-any.whl", hash = "sha256:969a3a1a77ed4e99487d60a74048dc9fa7d3b0dcd32e60885d835bbf7ba7be11"}, + {file = "jupyter_server_ydoc-0.8.0.tar.gz", hash = "sha256:a6fe125091792d16c962cc3720c950c2b87fcc8c3ecf0c54c84e9a20b814526c"}, +] + +[package.dependencies] +jupyter-server-fileid = ">=0.6.0,<1" +jupyter-ydoc = ">=0.2.0,<0.4.0" +ypy-websocket = ">=0.8.2,<0.9.0" + +[package.extras] +test = ["coverage", "jupyter-server[test] (>=2.0.0a0)", "pytest (>=7.0)", "pytest-cov", "pytest-timeout", "pytest-tornasync"] + +[[package]] +name = "jupyter-ydoc" +version = "0.2.5" +description = "Document structures for collaborative editing using Ypy" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyter_ydoc-0.2.5-py3-none-any.whl", hash = "sha256:5759170f112c70320a84217dd98d287699076ae65a7f88d458d57940a9f2b882"}, + {file = "jupyter_ydoc-0.2.5.tar.gz", hash = "sha256:5a02ca7449f0d875f73e8cb8efdf695dddef15a8e71378b1f4eda6b7c90f5382"}, +] + +[package.dependencies] +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +y-py = ">=0.6.0,<0.7.0" + +[package.extras] +dev = ["click", "jupyter-releaser"] +test = ["pre-commit", "pytest", "pytest-asyncio", "websockets (>=10.0)", "ypy-websocket (>=0.8.4,<0.9.0)"] + +[[package]] +name = "jupyterlab" +version = "3.6.7" +description = "JupyterLab computational environment" +optional = false +python-versions = ">=3.7" +files = [ + {file = "jupyterlab-3.6.7-py3-none-any.whl", hash = "sha256:d92d57d402f53922bca5090654843aa08e511290dff29fdb0809eafbbeb6df98"}, + {file = "jupyterlab-3.6.7.tar.gz", hash = "sha256:2fadeaec161b0d1aec19f17721d8b803aef1d267f89c8b636b703be14f435c8f"}, +] + +[package.dependencies] +ipython = "*" +jinja2 = ">=2.1" +jupyter-core = "*" +jupyter-server = ">=1.16.0,<3" +jupyter-server-ydoc = ">=0.8.0,<0.9.0" +jupyter-ydoc = ">=0.2.4,<0.3.0" +jupyterlab-server = ">=2.19,<3.0" +nbclassic = "*" +notebook = "<7" +packaging = "*" +tomli = {version = "*", markers = "python_version < \"3.11\""} +tornado = ">=6.1.0" + +[package.extras] +docs = ["jsx-lexer", "myst-parser", "pytest", "pytest-check-links", "pytest-tornasync", "sphinx (>=1.8)", "sphinx-copybutton", "sphinx-rtd-theme"] +test = ["check-manifest", "coverage", "jupyterlab-server[test]", "pre-commit", "pytest (>=6.0)", "pytest-check-links (>=0.5)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter (>=0.5.3)", "requests", "requests-cache", "virtualenv"] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +description = "Pygments theme using JupyterLab CSS variables" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780"}, + {file = "jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d"}, +] + +[[package]] +name = "jupyterlab-server" +version = "2.25.3" +description = "A set of server components for JupyterLab and JupyterLab like applications." +optional = false +python-versions = ">=3.8" +files = [ + {file = "jupyterlab_server-2.25.3-py3-none-any.whl", hash = "sha256:c48862519fded9b418c71645d85a49b2f0ec50d032ba8316738e9276046088c1"}, + {file = "jupyterlab_server-2.25.3.tar.gz", hash = "sha256:846f125a8a19656611df5b03e5912c8393cea6900859baa64fa515eb64a8dc40"}, +] + +[package.dependencies] +babel = ">=2.10" +importlib-metadata = {version = ">=4.8.3", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0.3" +json5 = ">=0.9.0" +jsonschema = ">=4.18.0" +jupyter-server = ">=1.21,<3" +packaging = ">=21.3" +requests = ">=2.31" + +[package.extras] +docs = ["autodoc-traits", "jinja2 (<3.2.0)", "mistune (<4)", "myst-parser", "pydata-sphinx-theme", "sphinx", "sphinx-copybutton", "sphinxcontrib-openapi (>0.8)"] +openapi = ["openapi-core (>=0.18.0,<0.19.0)", "ruamel-yaml"] +test = ["hatch", "ipykernel", "openapi-core (>=0.18.0,<0.19.0)", "openapi-spec-validator (>=0.6.0,<0.8.0)", "pytest (>=7.0)", "pytest-console-scripts", "pytest-cov", "pytest-jupyter[server] (>=0.6.2)", "pytest-timeout", "requests-mock", "ruamel-yaml", "sphinxcontrib-spelling", "strict-rfc3339", "werkzeug"] + +[[package]] +name = "langchain" +version = "0.1.5" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain-0.1.5-py3-none-any.whl", hash = "sha256:4614118d4a95b2e7ba3611a0b6b21707a259a21652a04fbe3c31205bcf3fcd50"}, + {file = "langchain-0.1.5.tar.gz", hash = "sha256:69603a5bb21b044ddea69d38131dbbf47475afdf79728644faa67d1ad325d652"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +async-timeout = {version = ">=4.0.0,<5.0.0", markers = "python_version < \"3.11\""} +dataclasses-json = ">=0.5.7,<0.7" +jsonpatch = ">=1.33,<2.0" +langchain-community = ">=0.0.17,<0.1" +langchain-core = ">=0.1.16,<0.2" +langsmith = ">=0.0.83,<0.1" +numpy = ">=1,<2" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +azure = ["azure-ai-formrecognizer (>=3.2.1,<4.0.0)", "azure-ai-textanalytics (>=5.3.0,<6.0.0)", "azure-ai-vision (>=0.11.1b1,<0.12.0)", "azure-cognitiveservices-speech (>=1.28.0,<2.0.0)", "azure-core (>=1.26.4,<2.0.0)", "azure-cosmos (>=4.4.0b1,<5.0.0)", "azure-identity (>=1.12.0,<2.0.0)", "azure-search-documents (==11.4.0b8)", "openai (<2)"] +clarifai = ["clarifai (>=9.1.0)"] +cli = ["typer (>=0.9.0,<0.10.0)"] +cohere = ["cohere (>=4,<5)"] +docarray = ["docarray[hnswlib] (>=0.32.0,<0.33.0)"] +embeddings = ["sentence-transformers (>=2,<3)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "couchbase (>=4.1.9,<5.0.0)", "dashvector (>=1.0.1,<2.0.0)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "langchain-openai (>=0.0.2,<0.1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)"] +javascript = ["esprima (>=4.0.1,<5.0.0)"] +llms = ["clarifai (>=9.1.0)", "cohere (>=4,<5)", "huggingface_hub (>=0,<1)", "manifest-ml (>=0.0.1,<0.0.2)", "nlpcloud (>=1,<2)", "openai (<2)", "openlm (>=0.0.5,<0.0.6)", "torch (>=1,<3)", "transformers (>=4,<5)"] +openai = ["openai (<2)", "tiktoken (>=0.3.2,<0.6.0)"] +qdrant = ["qdrant-client (>=1.3.1,<2.0.0)"] +text-helpers = ["chardet (>=5.1.0,<6.0.0)"] + +[[package]] +name = "langchain-community" +version = "0.0.18" +description = "Community contributed LangChain integrations." +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_community-0.0.18-py3-none-any.whl", hash = "sha256:b87e20c1fa3f37e9608d7ccc08b4d8ed86f875b8c1e735d0464ae986e41c5a71"}, + {file = "langchain_community-0.0.18.tar.gz", hash = "sha256:f044f331b418f16148b76929f27cc2107fce2d190ea3fae0cdaf155ceda9892f"}, +] + +[package.dependencies] +aiohttp = ">=3.8.3,<4.0.0" +dataclasses-json = ">=0.5.7,<0.7" +langchain-core = ">=0.1.19,<0.2" +langsmith = ">=0.0.83,<0.1" +numpy = ">=1,<2" +PyYAML = ">=5.3" +requests = ">=2,<3" +SQLAlchemy = ">=1.4,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +cli = ["typer (>=0.9.0,<0.10.0)"] +extended-testing = ["aiosqlite (>=0.19.0,<0.20.0)", "aleph-alpha-client (>=2.15.0,<3.0.0)", "anthropic (>=0.3.11,<0.4.0)", "arxiv (>=1.4,<2.0)", "assemblyai (>=0.17.0,<0.18.0)", "atlassian-python-api (>=3.36.0,<4.0.0)", "azure-ai-documentintelligence (>=1.0.0b1,<2.0.0)", "beautifulsoup4 (>=4,<5)", "bibtexparser (>=1.4.0,<2.0.0)", "cassio (>=0.1.0,<0.2.0)", "chardet (>=5.1.0,<6.0.0)", "cohere (>=4,<5)", "databricks-vectorsearch (>=0.21,<0.22)", "datasets (>=2.15.0,<3.0.0)", "dgml-utils (>=0.3.0,<0.4.0)", "elasticsearch (>=8.12.0,<9.0.0)", "esprima (>=4.0.1,<5.0.0)", "faiss-cpu (>=1,<2)", "feedparser (>=6.0.10,<7.0.0)", "fireworks-ai (>=0.9.0,<0.10.0)", "geopandas (>=0.13.1,<0.14.0)", "gitpython (>=3.1.32,<4.0.0)", "google-cloud-documentai (>=2.20.1,<3.0.0)", "gql (>=3.4.1,<4.0.0)", "gradientai (>=1.4.0,<2.0.0)", "hdbcli (>=2.19.21,<3.0.0)", "hologres-vector (>=0.0.6,<0.0.7)", "html2text (>=2020.1.16,<2021.0.0)", "httpx (>=0.24.1,<0.25.0)", "javelin-sdk (>=0.1.8,<0.2.0)", "jinja2 (>=3,<4)", "jq (>=1.4.1,<2.0.0)", "jsonschema (>1)", "lxml (>=4.9.2,<5.0.0)", "markdownify (>=0.11.6,<0.12.0)", "motor (>=3.3.1,<4.0.0)", "msal (>=1.25.0,<2.0.0)", "mwparserfromhell (>=0.6.4,<0.7.0)", "mwxml (>=0.3.3,<0.4.0)", "newspaper3k (>=0.2.8,<0.3.0)", "numexpr (>=2.8.6,<3.0.0)", "nvidia-riva-client (>=2.14.0,<3.0.0)", "oci (>=2.119.1,<3.0.0)", "openai (<2)", "openapi-pydantic (>=0.3.2,<0.4.0)", "oracle-ads (>=2.9.1,<3.0.0)", "pandas (>=2.0.1,<3.0.0)", "pdfminer-six (>=20221105,<20221106)", "pgvector (>=0.1.6,<0.2.0)", "praw (>=7.7.1,<8.0.0)", "psychicapi (>=0.8.0,<0.9.0)", "py-trello (>=0.19.0,<0.20.0)", "pymupdf (>=1.22.3,<2.0.0)", "pypdf (>=3.4.0,<4.0.0)", "pypdfium2 (>=4.10.0,<5.0.0)", "pyspark (>=3.4.0,<4.0.0)", "rank-bm25 (>=0.2.2,<0.3.0)", "rapidfuzz (>=3.1.1,<4.0.0)", "rapidocr-onnxruntime (>=1.3.2,<2.0.0)", "rdflib (==7.0.0)", "requests-toolbelt (>=1.0.0,<2.0.0)", "rspace_client (>=2.5.0,<3.0.0)", "scikit-learn (>=1.2.2,<2.0.0)", "sqlite-vss (>=0.1.2,<0.2.0)", "streamlit (>=1.18.0,<2.0.0)", "sympy (>=1.12,<2.0)", "telethon (>=1.28.5,<2.0.0)", "timescale-vector (>=0.0.1,<0.0.2)", "tqdm (>=4.48.0)", "upstash-redis (>=0.15.0,<0.16.0)", "xata (>=1.0.0a7,<2.0.0)", "xmltodict (>=0.13.0,<0.14.0)", "zhipuai (>=1.0.7,<2.0.0)"] + +[[package]] +name = "langchain-core" +version = "0.1.19" +description = "Building applications with LLMs through composability" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_core-0.1.19-py3-none-any.whl", hash = "sha256:46b5fd54181df5aa6d3041d61beb2b91e5437b6742274e7924a97734ed62cf43"}, + {file = "langchain_core-0.1.19.tar.gz", hash = "sha256:30539190a63dff53e995f10aefb943b4f7e01aba4bf28fd1e13016b040c0e9da"}, +] + +[package.dependencies] +anyio = ">=3,<5" +jsonpatch = ">=1.33,<2.0" +langsmith = ">=0.0.83,<0.1" +packaging = ">=23.2,<24.0" +pydantic = ">=1,<3" +PyYAML = ">=5.3" +requests = ">=2,<3" +tenacity = ">=8.1.0,<9.0.0" + +[package.extras] +extended-testing = ["jinja2 (>=3,<4)"] + +[[package]] +name = "langchain-openai" +version = "0.0.6" +description = "An integration package connecting OpenAI and LangChain" +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langchain_openai-0.0.6-py3-none-any.whl", hash = "sha256:2ef040e4447a26a9d3bd45dfac9cefa00797ea58555a3d91ab4f88699eb3a005"}, + {file = "langchain_openai-0.0.6.tar.gz", hash = "sha256:f5c4ebe46f2c8635c8f0c26cc8df27700aacafea025410e418d5a080039974dd"}, +] + +[package.dependencies] +langchain-core = ">=0.1.16,<0.2" +numpy = ">=1,<2" +openai = ">=1.10.0,<2.0.0" +tiktoken = ">=0.5.2,<1" + +[[package]] +name = "langserve" +version = "0.0.41" +description = "" +optional = false +python-versions = ">=3.8.1,<4.0.0" +files = [ + {file = "langserve-0.0.41-py3-none-any.whl", hash = "sha256:99583a6a4f2a6c3f98ffcf0c9eeed2a1ef6278b0cfaf9d789dfd517c49d0062a"}, + {file = "langserve-0.0.41.tar.gz", hash = "sha256:8583d9d01b202b4111e21e3c94d91ca6b61093ebff55fdfd0f92c6c8d155a6e5"}, +] + +[package.dependencies] +httpx = ">=0.23.0" +langchain = ">=0.0.333" +orjson = ">=2" +pydantic = ">=1" + +[package.extras] +all = ["fastapi (>=0.90.1,<1)", "httpx-sse (>=0.3.1)", "sse-starlette (>=1.3.0,<2.0.0)"] +client = ["httpx-sse (>=0.3.1)"] +server = ["fastapi (>=0.90.1,<1)", "sse-starlette (>=1.3.0,<2.0.0)"] + +[[package]] +name = "langsmith" +version = "0.0.92" +description = "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform." +optional = false +python-versions = ">=3.8.1,<4.0" +files = [ + {file = "langsmith-0.0.92-py3-none-any.whl", hash = "sha256:ddcf65e3b5ca11893ae8ef9816ce2a11a089d051be491886e43a2c4556b88fd0"}, + {file = "langsmith-0.0.92.tar.gz", hash = "sha256:61a3a502222bdd221b7f592b6fc14756d74c4fc088aa6bd8834b92adfe9ee583"}, +] + +[package.dependencies] +pydantic = ">=1,<3" +requests = ">=2,<3" + +[[package]] +name = "lxml" +version = "5.1.0" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=3.6" +files = [ + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:704f5572ff473a5f897745abebc6df40f22d4133c1e0a1f124e4f2bd3330ff7e"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9d3c0f8567ffe7502d969c2c1b809892dc793b5d0665f602aad19895f8d508da"}, + {file = "lxml-5.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5fcfbebdb0c5d8d18b84118842f31965d59ee3e66996ac842e21f957eb76138c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f37c6d7106a9d6f0708d4e164b707037b7380fcd0b04c5bd9cae1fb46a856fb"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2befa20a13f1a75c751f47e00929fb3433d67eb9923c2c0b364de449121f447c"}, + {file = "lxml-5.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22b7ee4c35f374e2c20337a95502057964d7e35b996b1c667b5c65c567d2252a"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:bf8443781533b8d37b295016a4b53c1494fa9a03573c09ca5104550c138d5c05"}, + {file = "lxml-5.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:82bddf0e72cb2af3cbba7cec1d2fd11fda0de6be8f4492223d4a268713ef2147"}, + {file = "lxml-5.1.0-cp310-cp310-win32.whl", hash = "sha256:b66aa6357b265670bb574f050ffceefb98549c721cf28351b748be1ef9577d93"}, + {file = "lxml-5.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:4946e7f59b7b6a9e27bef34422f645e9a368cb2be11bf1ef3cafc39a1f6ba68d"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:14deca1460b4b0f6b01f1ddc9557704e8b365f55c63070463f6c18619ebf964f"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ed8c3d2cd329bf779b7ed38db176738f3f8be637bb395ce9629fc76f78afe3d4"}, + {file = "lxml-5.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:436a943c2900bb98123b06437cdd30580a61340fbdb7b28aaf345a459c19046a"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:acb6b2f96f60f70e7f34efe0c3ea34ca63f19ca63ce90019c6cbca6b676e81fa"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:af8920ce4a55ff41167ddbc20077f5698c2e710ad3353d32a07d3264f3a2021e"}, + {file = "lxml-5.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cfced4a069003d8913408e10ca8ed092c49a7f6cefee9bb74b6b3e860683b45"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9e5ac3437746189a9b4121db2a7b86056ac8786b12e88838696899328fc44bb2"}, + {file = "lxml-5.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f4c9bda132ad108b387c33fabfea47866af87f4ea6ffb79418004f0521e63204"}, + {file = "lxml-5.1.0-cp311-cp311-win32.whl", hash = "sha256:bc64d1b1dab08f679fb89c368f4c05693f58a9faf744c4d390d7ed1d8223869b"}, + {file = "lxml-5.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:a5ab722ae5a873d8dcee1f5f45ddd93c34210aed44ff2dc643b5025981908cda"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9aa543980ab1fbf1720969af1d99095a548ea42e00361e727c58a40832439114"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:6f11b77ec0979f7e4dc5ae081325a2946f1fe424148d3945f943ceaede98adb8"}, + {file = "lxml-5.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a36c506e5f8aeb40680491d39ed94670487ce6614b9d27cabe45d94cd5d63e1e"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f643ffd2669ffd4b5a3e9b41c909b72b2a1d5e4915da90a77e119b8d48ce867a"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:16dd953fb719f0ffc5bc067428fc9e88f599e15723a85618c45847c96f11f431"}, + {file = "lxml-5.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:16018f7099245157564d7148165132c70adb272fb5a17c048ba70d9cc542a1a1"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:82cd34f1081ae4ea2ede3d52f71b7be313756e99b4b5f829f89b12da552d3aa3"}, + {file = "lxml-5.1.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:19a1bc898ae9f06bccb7c3e1dfd73897ecbbd2c96afe9095a6026016e5ca97b8"}, + {file = "lxml-5.1.0-cp312-cp312-win32.whl", hash = "sha256:13521a321a25c641b9ea127ef478b580b5ec82aa2e9fc076c86169d161798b01"}, + {file = "lxml-5.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:1ad17c20e3666c035db502c78b86e58ff6b5991906e55bdbef94977700c72623"}, + {file = "lxml-5.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:24ef5a4631c0b6cceaf2dbca21687e29725b7c4e171f33a8f8ce23c12558ded1"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8d2900b7f5318bc7ad8631d3d40190b95ef2aa8cc59473b73b294e4a55e9f30f"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:601f4a75797d7a770daed8b42b97cd1bb1ba18bd51a9382077a6a247a12aa38d"}, + {file = "lxml-5.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4b68c961b5cc402cbd99cca5eb2547e46ce77260eb705f4d117fd9c3f932b95"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:afd825e30f8d1f521713a5669b63657bcfe5980a916c95855060048b88e1adb7"}, + {file = "lxml-5.1.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:262bc5f512a66b527d026518507e78c2f9c2bd9eb5c8aeeb9f0eb43fcb69dc67"}, + {file = "lxml-5.1.0-cp36-cp36m-win32.whl", hash = "sha256:e856c1c7255c739434489ec9c8aa9cdf5179785d10ff20add308b5d673bed5cd"}, + {file = "lxml-5.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c7257171bb8d4432fe9d6fdde4d55fdbe663a63636a17f7f9aaba9bcb3153ad7"}, + {file = "lxml-5.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b9e240ae0ba96477682aa87899d94ddec1cc7926f9df29b1dd57b39e797d5ab5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a96f02ba1bcd330807fc060ed91d1f7a20853da6dd449e5da4b09bfcc08fdcf5"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3898ae2b58eeafedfe99e542a17859017d72d7f6a63de0f04f99c2cb125936"}, + {file = "lxml-5.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61c5a7edbd7c695e54fca029ceb351fc45cd8860119a0f83e48be44e1c464862"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:3aeca824b38ca78d9ee2ab82bd9883083d0492d9d17df065ba3b94e88e4d7ee6"}, + {file = "lxml-5.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8f52fe6859b9db71ee609b0c0a70fea5f1e71c3462ecf144ca800d3f434f0764"}, + {file = "lxml-5.1.0-cp37-cp37m-win32.whl", hash = "sha256:d42e3a3fc18acc88b838efded0e6ec3edf3e328a58c68fbd36a7263a874906c8"}, + {file = "lxml-5.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:eac68f96539b32fce2c9b47eb7c25bb2582bdaf1bbb360d25f564ee9e04c542b"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ae15347a88cf8af0949a9872b57a320d2605ae069bcdf047677318bc0bba45b1"}, + {file = "lxml-5.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c26aab6ea9c54d3bed716b8851c8bfc40cb249b8e9880e250d1eddde9f709bf5"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:342e95bddec3a698ac24378d61996b3ee5ba9acfeb253986002ac53c9a5f6f84"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:725e171e0b99a66ec8605ac77fa12239dbe061482ac854d25720e2294652eeaa"}, + {file = "lxml-5.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d184e0d5c918cff04cdde9dbdf9600e960161d773666958c9d7b565ccc60c45"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:98f3f020a2b736566c707c8e034945c02aa94e124c24f77ca097c446f81b01f1"}, + {file = "lxml-5.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d48fc57e7c1e3df57be5ae8614bab6d4e7b60f65c5457915c26892c41afc59e"}, + {file = "lxml-5.1.0-cp38-cp38-win32.whl", hash = "sha256:7ec465e6549ed97e9f1e5ed51c657c9ede767bc1c11552f7f4d022c4df4a977a"}, + {file = "lxml-5.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:b21b4031b53d25b0858d4e124f2f9131ffc1530431c6d1321805c90da78388d1"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:52427a7eadc98f9e62cb1368a5079ae826f94f05755d2d567d93ee1bc3ceb354"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6a2a2c724d97c1eb8cf966b16ca2915566a4904b9aad2ed9a09c748ffe14f969"}, + {file = "lxml-5.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:843b9c835580d52828d8f69ea4302537337a21e6b4f1ec711a52241ba4a824f3"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9b99f564659cfa704a2dd82d0684207b1aadf7d02d33e54845f9fc78e06b7581"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4f8b0c78e7aac24979ef09b7f50da871c2de2def043d468c4b41f512d831e912"}, + {file = "lxml-5.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bcf86dfc8ff3e992fed847c077bd875d9e0ba2fa25d859c3a0f0f76f07f0c8d"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:49a9b4af45e8b925e1cd6f3b15bbba2c81e7dba6dce170c677c9cda547411e14"}, + {file = "lxml-5.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:280f3edf15c2a967d923bcfb1f8f15337ad36f93525828b40a0f9d6c2ad24890"}, + {file = "lxml-5.1.0-cp39-cp39-win32.whl", hash = "sha256:ed7326563024b6e91fef6b6c7a1a2ff0a71b97793ac33dbbcf38f6005e51ff6e"}, + {file = "lxml-5.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:8d7b4beebb178e9183138f552238f7e6613162a42164233e2bda00cb3afac58f"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:9bd0ae7cc2b85320abd5e0abad5ccee5564ed5f0cc90245d2f9a8ef330a8deae"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c1d679df4361408b628f42b26a5d62bd3e9ba7f0c0e7969f925021554755aa"}, + {file = "lxml-5.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2ad3a8ce9e8a767131061a22cd28fdffa3cd2dc193f399ff7b81777f3520e372"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:304128394c9c22b6569eba2a6d98392b56fbdfbad58f83ea702530be80d0f9df"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d74fcaf87132ffc0447b3c685a9f862ffb5b43e70ea6beec2fb8057d5d2a1fea"}, + {file = "lxml-5.1.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:8cf5877f7ed384dabfdcc37922c3191bf27e55b498fecece9fd5c2c7aaa34c33"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:877efb968c3d7eb2dad540b6cabf2f1d3c0fbf4b2d309a3c141f79c7e0061324"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f14a4fb1c1c402a22e6a341a24c1341b4a3def81b41cd354386dcb795f83897"}, + {file = "lxml-5.1.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:25663d6e99659544ee8fe1b89b1a8c0aaa5e34b103fab124b17fa958c4a324a6"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8b9f19df998761babaa7f09e6bc169294eefafd6149aaa272081cbddc7ba4ca3"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e53d7e6a98b64fe54775d23a7c669763451340c3d44ad5e3a3b48a1efbdc96f"}, + {file = "lxml-5.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c3cd1fc1dc7c376c54440aeaaa0dcc803d2126732ff5c6b68ccd619f2e64be4f"}, + {file = "lxml-5.1.0.tar.gz", hash = "sha256:3eea6ed6e6c918e468e693c41ef07f3c3acc310b70ddd9cc72d9ef84bc9564ca"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=3.0.7)"] + +[[package]] +name = "mako" +version = "1.3.2" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +files = [ + {file = "Mako-1.3.2-py3-none-any.whl", hash = "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c"}, + {file = "Mako-1.3.2.tar.gz", hash = "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markupsafe" +version = "2.1.5" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.7" +files = [ + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, +] + +[[package]] +name = "marshmallow" +version = "3.20.2" +description = "A lightweight library for converting complex datatypes to and from native Python datatypes." +optional = false +python-versions = ">=3.8" +files = [ + {file = "marshmallow-3.20.2-py3-none-any.whl", hash = "sha256:c21d4b98fee747c130e6bc8f45c4b3199ea66bc00c12ee1f639f0aeca034d5e9"}, + {file = "marshmallow-3.20.2.tar.gz", hash = "sha256:4c1daff273513dc5eb24b219a8035559dc573c8f322558ef85f5438ddd1236dd"}, +] + +[package.dependencies] +packaging = ">=17.0" + +[package.extras] +dev = ["pre-commit (>=2.4,<4.0)", "pytest", "pytz", "simplejson", "tox"] +docs = ["alabaster (==0.7.15)", "autodocsumm (==0.2.12)", "sphinx (==7.2.6)", "sphinx-issues (==3.0.1)", "sphinx-version-warning (==1.1.2)"] +lint = ["pre-commit (>=2.4,<4.0)"] +tests = ["pytest", "pytz", "simplejson"] + +[[package]] +name = "matplotlib-inline" +version = "0.1.6" +description = "Inline Matplotlib backend for Jupyter" +optional = false +python-versions = ">=3.5" +files = [ + {file = "matplotlib-inline-0.1.6.tar.gz", hash = "sha256:f887e5f10ba98e8d2b150ddcf4702c1e5f8b3a20005eb0f74bfdbd360ee6f304"}, + {file = "matplotlib_inline-0.1.6-py3-none-any.whl", hash = "sha256:f1f41aab5328aa5aaea9b16d083b128102f8712542f819fe7e6a420ff581b311"}, +] + +[package.dependencies] +traitlets = "*" + +[[package]] +name = "mistune" +version = "3.0.2" +description = "A sane and fast Markdown parser with useful plugins and renderers" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mistune-3.0.2-py3-none-any.whl", hash = "sha256:71481854c30fdbc938963d3605b72501f5c10a9320ecd412c121c163a1c7d205"}, + {file = "mistune-3.0.2.tar.gz", hash = "sha256:fc7f93ded930c92394ef2cb6f04a8aabab4117a91449e72dcc8dfa646a508be8"}, +] + +[[package]] +name = "multidict" +version = "6.0.5" +description = "multidict implementation" +optional = false +python-versions = ">=3.7" +files = [ + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604"}, + {file = "multidict-6.0.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae"}, + {file = "multidict-6.0.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef"}, + {file = "multidict-6.0.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc"}, + {file = "multidict-6.0.5-cp310-cp310-win32.whl", hash = "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319"}, + {file = "multidict-6.0.5-cp310-cp310-win_amd64.whl", hash = "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e"}, + {file = "multidict-6.0.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed"}, + {file = "multidict-6.0.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc"}, + {file = "multidict-6.0.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e"}, + {file = "multidict-6.0.5-cp311-cp311-win32.whl", hash = "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c"}, + {file = "multidict-6.0.5-cp311-cp311-win_amd64.whl", hash = "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b"}, + {file = "multidict-6.0.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226"}, + {file = "multidict-6.0.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6"}, + {file = "multidict-6.0.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda"}, + {file = "multidict-6.0.5-cp312-cp312-win32.whl", hash = "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5"}, + {file = "multidict-6.0.5-cp312-cp312-win_amd64.whl", hash = "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556"}, + {file = "multidict-6.0.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626"}, + {file = "multidict-6.0.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3"}, + {file = "multidict-6.0.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc"}, + {file = "multidict-6.0.5-cp37-cp37m-win32.whl", hash = "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee"}, + {file = "multidict-6.0.5-cp37-cp37m-win_amd64.whl", hash = "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d"}, + {file = "multidict-6.0.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50"}, + {file = "multidict-6.0.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461"}, + {file = "multidict-6.0.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44"}, + {file = "multidict-6.0.5-cp38-cp38-win32.whl", hash = "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241"}, + {file = "multidict-6.0.5-cp38-cp38-win_amd64.whl", hash = "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9"}, + {file = "multidict-6.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c"}, + {file = "multidict-6.0.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479"}, + {file = "multidict-6.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c"}, + {file = "multidict-6.0.5-cp39-cp39-win32.whl", hash = "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b"}, + {file = "multidict-6.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755"}, + {file = "multidict-6.0.5-py3-none-any.whl", hash = "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7"}, + {file = "multidict-6.0.5.tar.gz", hash = "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da"}, +] + +[[package]] +name = "mypy" +version = "1.8.0" +description = "Optional static typing for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, + {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, + {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, + {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, + {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, + {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, + {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, + {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, + {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, + {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, + {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, + {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, + {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, + {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, + {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, + {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, + {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, + {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typing-extensions = ">=4.1.0" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +mypyc = ["setuptools (>=50)"] +reports = ["lxml"] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +description = "Type system extensions for programs checked with the mypy type checker." +optional = false +python-versions = ">=3.5" +files = [ + {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, + {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, +] + +[[package]] +name = "nbclassic" +version = "1.0.0" +description = "Jupyter Notebook as a Jupyter Server extension." +optional = false +python-versions = ">=3.7" +files = [ + {file = "nbclassic-1.0.0-py3-none-any.whl", hash = "sha256:f99e4769b4750076cd4235c044b61232110733322384a94a63791d2e7beacc66"}, + {file = "nbclassic-1.0.0.tar.gz", hash = "sha256:0ae11eb2319455d805596bf320336cda9554b41d99ab9a3c31bf8180bffa30e3"}, +] + +[package.dependencies] +argon2-cffi = "*" +ipykernel = "*" +ipython-genutils = "*" +jinja2 = "*" +jupyter-client = ">=6.1.1" +jupyter-core = ">=4.6.1" +jupyter-server = ">=1.8" +nbconvert = ">=5" +nbformat = "*" +nest-asyncio = ">=1.5" +notebook-shim = ">=0.2.3" +prometheus-client = "*" +pyzmq = ">=17" +Send2Trash = ">=1.8.0" +terminado = ">=0.8.3" +tornado = ">=6.1" +traitlets = ">=4.2.1" + +[package.extras] +docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] +json-logging = ["json-logging"] +test = ["coverage", "nbval", "pytest", "pytest-cov", "pytest-jupyter", "pytest-playwright", "pytest-tornasync", "requests", "requests-unixsocket", "testpath"] + +[[package]] +name = "nbclient" +version = "0.9.0" +description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." +optional = false +python-versions = ">=3.8.0" +files = [ + {file = "nbclient-0.9.0-py3-none-any.whl", hash = "sha256:a3a1ddfb34d4a9d17fc744d655962714a866639acd30130e9be84191cd97cd15"}, + {file = "nbclient-0.9.0.tar.gz", hash = "sha256:4b28c207877cf33ef3a9838cdc7a54c5ceff981194a82eac59d558f05487295e"}, +] + +[package.dependencies] +jupyter-client = ">=6.1.12" +jupyter-core = ">=4.12,<5.0.dev0 || >=5.1.dev0" +nbformat = ">=5.1" +traitlets = ">=5.4" + +[package.extras] +dev = ["pre-commit"] +docs = ["autodoc-traits", "mock", "moto", "myst-parser", "nbclient[test]", "sphinx (>=1.7)", "sphinx-book-theme", "sphinxcontrib-spelling"] +test = ["flaky", "ipykernel (>=6.19.3)", "ipython", "ipywidgets", "nbconvert (>=7.0.0)", "pytest (>=7.0)", "pytest-asyncio", "pytest-cov (>=4.0)", "testpath", "xmltodict"] + +[[package]] +name = "nbconvert" +version = "7.16.0" +description = "Converting Jupyter Notebooks" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbconvert-7.16.0-py3-none-any.whl", hash = "sha256:ad3dc865ea6e2768d31b7eb6c7ab3be014927216a5ece3ef276748dd809054c7"}, + {file = "nbconvert-7.16.0.tar.gz", hash = "sha256:813e6553796362489ae572e39ba1bff978536192fb518e10826b0e8cadf03ec8"}, +] + +[package.dependencies] +beautifulsoup4 = "*" +bleach = "!=5.0.0" +defusedxml = "*" +importlib-metadata = {version = ">=3.6", markers = "python_version < \"3.10\""} +jinja2 = ">=3.0" +jupyter-core = ">=4.7" +jupyterlab-pygments = "*" +markupsafe = ">=2.0" +mistune = ">=2.0.3,<4" +nbclient = ">=0.5.0" +nbformat = ">=5.7" +packaging = "*" +pandocfilters = ">=1.4.1" +pygments = ">=2.4.1" +tinycss2 = "*" +traitlets = ">=5.1" + +[package.extras] +all = ["nbconvert[docs,qtpdf,serve,test,webpdf]"] +docs = ["ipykernel", "ipython", "myst-parser", "nbsphinx (>=0.2.12)", "pydata-sphinx-theme", "sphinx (==5.0.2)", "sphinxcontrib-spelling"] +qtpdf = ["nbconvert[qtpng]"] +qtpng = ["pyqtwebengine (>=5.15)"] +serve = ["tornado (>=6.1)"] +test = ["flaky", "ipykernel", "ipywidgets (>=7.5)", "pytest"] +webpdf = ["playwright"] + +[[package]] +name = "nbformat" +version = "5.9.2" +description = "The Jupyter Notebook format" +optional = false +python-versions = ">=3.8" +files = [ + {file = "nbformat-5.9.2-py3-none-any.whl", hash = "sha256:1c5172d786a41b82bcfd0c23f9e6b6f072e8fb49c39250219e4acfff1efe89e9"}, + {file = "nbformat-5.9.2.tar.gz", hash = "sha256:5f98b5ba1997dff175e77e0c17d5c10a96eaed2cbd1de3533d1fc35d5e111192"}, +] + +[package.dependencies] +fastjsonschema = "*" +jsonschema = ">=2.6" +jupyter-core = "*" +traitlets = ">=5.1" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx", "sphinxcontrib-github-alt", "sphinxcontrib-spelling"] +test = ["pep440", "pre-commit", "pytest", "testpath"] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +description = "Patch asyncio to allow nested event loops" +optional = false +python-versions = ">=3.5" +files = [ + {file = "nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c"}, + {file = "nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe"}, +] + +[[package]] +name = "notebook" +version = "6.5.6" +description = "A web-based notebook environment for interactive computing" +optional = false +python-versions = ">=3.7" +files = [ + {file = "notebook-6.5.6-py3-none-any.whl", hash = "sha256:c1e2eb2e3b6079a0552a04974883a48d04c3c05792170d64a4b23d707d453181"}, + {file = "notebook-6.5.6.tar.gz", hash = "sha256:b4625a4b7a597839dd3156b140d5ba2c7123761f98245a3290f67a8b8ee048d9"}, +] + +[package.dependencies] +argon2-cffi = "*" +ipykernel = "*" +ipython-genutils = "*" +jinja2 = "*" +jupyter-client = ">=5.3.4,<8" +jupyter-core = ">=4.6.1" +nbclassic = ">=0.4.7" +nbconvert = ">=5" +nbformat = "*" +nest-asyncio = ">=1.5" +prometheus-client = "*" +pyzmq = ">=17,<25" +Send2Trash = ">=1.8.0" +terminado = ">=0.8.3" +tornado = ">=6.1" +traitlets = ">=4.2.1" + +[package.extras] +docs = ["myst-parser", "nbsphinx", "sphinx", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] +json-logging = ["json-logging"] +test = ["coverage", "nbval", "pytest", "pytest-cov", "requests", "requests-unixsocket", "selenium (==4.1.5)", "testpath"] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +description = "A shim layer for notebook traits and config" +optional = false +python-versions = ">=3.7" +files = [ + {file = "notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef"}, + {file = "notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb"}, +] + +[package.dependencies] +jupyter-server = ">=1.8,<3" + +[package.extras] +test = ["pytest", "pytest-console-scripts", "pytest-jupyter", "pytest-tornasync"] + +[[package]] +name = "numpy" +version = "1.24.4" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "numpy-1.24.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64"}, + {file = "numpy-1.24.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4"}, + {file = "numpy-1.24.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6"}, + {file = "numpy-1.24.4-cp310-cp310-win32.whl", hash = "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc"}, + {file = "numpy-1.24.4-cp310-cp310-win_amd64.whl", hash = "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810"}, + {file = "numpy-1.24.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7"}, + {file = "numpy-1.24.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5"}, + {file = "numpy-1.24.4-cp311-cp311-win32.whl", hash = "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d"}, + {file = "numpy-1.24.4-cp311-cp311-win_amd64.whl", hash = "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61"}, + {file = "numpy-1.24.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e"}, + {file = "numpy-1.24.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc"}, + {file = "numpy-1.24.4-cp38-cp38-win32.whl", hash = "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2"}, + {file = "numpy-1.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400"}, + {file = "numpy-1.24.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9"}, + {file = "numpy-1.24.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d"}, + {file = "numpy-1.24.4-cp39-cp39-win32.whl", hash = "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835"}, + {file = "numpy-1.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a"}, + {file = "numpy-1.24.4-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2"}, + {file = "numpy-1.24.4.tar.gz", hash = "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463"}, +] + +[[package]] +name = "openai" +version = "1.12.0" +description = "The official Python library for the openai API" +optional = false +python-versions = ">=3.7.1" +files = [ + {file = "openai-1.12.0-py3-none-any.whl", hash = "sha256:a54002c814e05222e413664f651b5916714e4700d041d5cf5724d3ae1a3e3481"}, + {file = "openai-1.12.0.tar.gz", hash = "sha256:99c5d257d09ea6533d689d1cc77caa0ac679fa21efef8893d8b0832a86877f1b"}, +] + +[package.dependencies] +anyio = ">=3.5.0,<5" +distro = ">=1.7.0,<2" +httpx = ">=0.23.0,<1" +pydantic = ">=1.9.0,<3" +sniffio = "*" +tqdm = ">4" +typing-extensions = ">=4.7,<5" + +[package.extras] +datalib = ["numpy (>=1)", "pandas (>=1.2.3)", "pandas-stubs (>=1.1.0.11)"] + +[[package]] +name = "orjson" +version = "3.9.14" +description = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy" +optional = false +python-versions = ">=3.8" +files = [ + {file = "orjson-3.9.14-cp310-cp310-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:793f6c9448ab6eb7d4974b4dde3f230345c08ca6c7995330fbceeb43a5c8aa5e"}, + {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6bc7928d161840096adc956703494b5c0193ede887346f028216cac0af87500"}, + {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:58b36f54da759602d8e2f7dad958752d453dfe2c7122767bc7f765e17dc59959"}, + {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:abcda41ecdc950399c05eff761c3de91485d9a70d8227cb599ad3a66afe93bcc"}, + {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df76ecd17b1b3627bddfd689faaf206380a1a38cc9f6c4075bd884eaedcf46c2"}, + {file = "orjson-3.9.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d450a8e0656efb5d0fcb062157b918ab02dcca73278975b4ee9ea49e2fcf5bd5"}, + {file = "orjson-3.9.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:95c03137b0cf66517c8baa65770507a756d3a89489d8ecf864ea92348e1beabe"}, + {file = "orjson-3.9.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:20837e10835c98973673406d6798e10f821e7744520633811a5a3d809762d8cc"}, + {file = "orjson-3.9.14-cp310-none-win32.whl", hash = "sha256:1f7b6f3ef10ae8e3558abb729873d033dbb5843507c66b1c0767e32502ba96bb"}, + {file = "orjson-3.9.14-cp310-none-win_amd64.whl", hash = "sha256:ea890e6dc1711aeec0a33b8520e395c2f3d59ead5b4351a788e06bf95fc7ba81"}, + {file = "orjson-3.9.14-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c19009ff37f033c70acd04b636380379499dac2cba27ae7dfc24f304deabbc81"}, + {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19cdea0664aec0b7f385be84986d4defd3334e9c3c799407686ee1c26f7b8251"}, + {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:135d518f73787ce323b1a5e21fb854fe22258d7a8ae562b81a49d6c7f826f2a3"}, + {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2cf1d0557c61c75e18cf7d69fb689b77896e95553e212c0cc64cf2087944b84"}, + {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7c11667421df2d8b18b021223505dcc3ee51be518d54e4dc49161ac88ac2b87"}, + {file = "orjson-3.9.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2eefc41ba42e75ed88bc396d8fe997beb20477f3e7efa000cd7a47eda452fbb2"}, + {file = "orjson-3.9.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:917311d6a64d1c327c0dfda1e41f3966a7fb72b11ca7aa2e7a68fcccc7db35d9"}, + {file = "orjson-3.9.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4dc1c132259b38d12c6587d190cd09cd76e3b5273ce71fe1372437b4cbc65f6f"}, + {file = "orjson-3.9.14-cp311-none-win32.whl", hash = "sha256:6f39a10408478f4c05736a74da63727a1ae0e83e3533d07b19443400fe8591ca"}, + {file = "orjson-3.9.14-cp311-none-win_amd64.whl", hash = "sha256:26280a7fcb62d8257f634c16acebc3bec626454f9ab13558bbf7883b9140760e"}, + {file = "orjson-3.9.14-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:08e722a8d06b13b67a51f247a24938d1a94b4b3862e40e0eef3b2e98c99cd04c"}, + {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2591faa0c031cf3f57e5bce1461cfbd6160f3f66b5a72609a130924917cb07d"}, + {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e2450d87dd7b4f277f4c5598faa8b49a0c197b91186c47a2c0b88e15531e4e3e"}, + {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:90903d2908158a2c9077a06f11e27545de610af690fb178fd3ba6b32492d4d1c"}, + {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce6f095eef0026eae76fc212f20f786011ecf482fc7df2f4c272a8ae6dd7b1ef"}, + {file = "orjson-3.9.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:751250a31fef2bac05a2da2449aae7142075ea26139271f169af60456d8ad27a"}, + {file = "orjson-3.9.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9a1af21160a38ee8be3f4fcf24ee4b99e6184cadc7f915d599f073f478a94d2c"}, + {file = "orjson-3.9.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:449bf090b2aa4e019371d7511a6ea8a5a248139205c27d1834bb4b1e3c44d936"}, + {file = "orjson-3.9.14-cp312-none-win_amd64.whl", hash = "sha256:a603161318ff699784943e71f53899983b7dee571b4dd07c336437c9c5a272b0"}, + {file = "orjson-3.9.14-cp38-cp38-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:814f288c011efdf8f115c5ebcc1ab94b11da64b207722917e0ceb42f52ef30a3"}, + {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a88cafb100af68af3b9b29b5ccd09fdf7a48c63327916c8c923a94c336d38dd3"}, + {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ba3518b999f88882ade6686f1b71e207b52e23546e180499be5bbb63a2f9c6e6"}, + {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:978f416bbff9da8d2091e3cf011c92da68b13f2c453dcc2e8109099b2a19d234"}, + {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75fc593cf836f631153d0e21beaeb8d26e144445c73645889335c2247fcd71a0"}, + {file = "orjson-3.9.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d1528db3c7554f9d6eeb09df23cb80dd5177ec56eeb55cc5318826928de506"}, + {file = "orjson-3.9.14-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:7183cc68ee2113b19b0b8714221e5e3b07b3ba10ca2bb108d78fd49cefaae101"}, + {file = "orjson-3.9.14-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:df3266d54246cb56b8bb17fa908660d2a0f2e3f63fbc32451ffc1b1505051d07"}, + {file = "orjson-3.9.14-cp38-none-win32.whl", hash = "sha256:7913079b029e1b3501854c9a78ad938ed40d61fe09bebab3c93e60ff1301b189"}, + {file = "orjson-3.9.14-cp38-none-win_amd64.whl", hash = "sha256:29512eb925b620e5da2fd7585814485c67cc6ba4fe739a0a700c50467a8a8065"}, + {file = "orjson-3.9.14-cp39-cp39-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:5bf597530544db27a8d76aced49cfc817ee9503e0a4ebf0109cd70331e7bbe0c"}, + {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac650d49366fa41fe702e054cb560171a8634e2865537e91f09a8d05ea5b1d37"}, + {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:236230433a9a4968ab895140514c308fdf9f607cb8bee178a04372b771123860"}, + {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3014ccbda9be0b1b5f8ea895121df7e6524496b3908f4397ff02e923bcd8f6dd"}, + {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ac0c7eae7ad3a223bde690565442f8a3d620056bd01196f191af8be58a5248e1"}, + {file = "orjson-3.9.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fca33fdd0b38839b01912c57546d4f412ba7bfa0faf9bf7453432219aec2df07"}, + {file = "orjson-3.9.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:f75823cc1674a840a151e999a7dfa0d86c911150dd6f951d0736ee9d383bf415"}, + {file = "orjson-3.9.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f52ac2eb49e99e7373f62e2a68428c6946cda52ce89aa8fe9f890c7278e2d3a"}, + {file = "orjson-3.9.14-cp39-none-win32.whl", hash = "sha256:0572f174f50b673b7df78680fb52cd0087a8585a6d06d295a5f790568e1064c6"}, + {file = "orjson-3.9.14-cp39-none-win_amd64.whl", hash = "sha256:ab90c02cb264250b8a58cedcc72ed78a4a257d956c8d3c8bebe9751b818dfad8"}, + {file = "orjson-3.9.14.tar.gz", hash = "sha256:06fb40f8e49088ecaa02f1162581d39e2cf3fd9dbbfe411eb2284147c99bad79"}, +] + +[[package]] +name = "overrides" +version = "7.7.0" +description = "A decorator to automatically detect mismatch when overriding a method." +optional = false +python-versions = ">=3.6" +files = [ + {file = "overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49"}, + {file = "overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a"}, +] + +[[package]] +name = "packaging" +version = "23.2" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.7" +files = [ + {file = "packaging-23.2-py3-none-any.whl", hash = "sha256:8c491190033a9af7e1d931d0b5dacc2ef47509b34dd0de67ed209b5203fc88c7"}, + {file = "packaging-23.2.tar.gz", hash = "sha256:048fb0e9405036518eaaf48a55953c750c11e1a1b68e0dd1a9d62ed0c092cfc5"}, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +description = "Utilities for writing pandoc filters in python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc"}, + {file = "pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e"}, +] + +[[package]] +name = "parso" +version = "0.8.3" +description = "A Python Parser" +optional = false +python-versions = ">=3.6" +files = [ + {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, + {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, +] + +[package.extras] +qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] +testing = ["docopt", "pytest (<6.0.0)"] + +[[package]] +name = "pdfminer-six" +version = "20231228" +description = "PDF parser and analyzer" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pdfminer.six-20231228-py3-none-any.whl", hash = "sha256:e8d3c3310e6fbc1fe414090123ab01351634b4ecb021232206c4c9a8ca3e3b8f"}, + {file = "pdfminer.six-20231228.tar.gz", hash = "sha256:6004da3ad1a7a4d45930cb950393df89b068e73be365a6ff64a838d37bcb08c4"}, +] + +[package.dependencies] +charset-normalizer = ">=2.0.0" +cryptography = ">=36.0.0" + +[package.extras] +dev = ["black", "mypy (==0.931)", "nox", "pytest"] +docs = ["sphinx", "sphinx-argparse"] +image = ["Pillow"] + +[[package]] +name = "pexpect" +version = "4.9.0" +description = "Pexpect allows easy control of interactive console applications." +optional = false +python-versions = "*" +files = [ + {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"}, + {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"}, +] + +[package.dependencies] +ptyprocess = ">=0.5" + +[[package]] +name = "pickleshare" +version = "0.7.5" +description = "Tiny 'shelve'-like database with concurrency support" +optional = false +python-versions = "*" +files = [ + {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, + {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, +] + +[[package]] +name = "pkgutil-resolve-name" +version = "1.3.10" +description = "Resolve a name to an object." +optional = false +python-versions = ">=3.6" +files = [ + {file = "pkgutil_resolve_name-1.3.10-py3-none-any.whl", hash = "sha256:ca27cc078d25c5ad71a9de0a7a330146c4e014c2462d9af19c6b828280649c5e"}, + {file = "pkgutil_resolve_name-1.3.10.tar.gz", hash = "sha256:357d6c9e6a755653cfd78893817c0853af365dd51ec97f3d358a819373bbd174"}, +] + +[[package]] +name = "platformdirs" +version = "4.2.0" +description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +optional = false +python-versions = ">=3.8" +files = [ + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, +] + +[package.extras] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] + +[[package]] +name = "pluggy" +version = "1.4.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "prometheus-client" +version = "0.20.0" +description = "Python client for the Prometheus monitoring system." +optional = false +python-versions = ">=3.8" +files = [ + {file = "prometheus_client-0.20.0-py3-none-any.whl", hash = "sha256:cde524a85bce83ca359cc837f28b8c0db5cac7aa653a588fd7e84ba061c329e7"}, + {file = "prometheus_client-0.20.0.tar.gz", hash = "sha256:287629d00b147a32dcb2be0b9df905da599b2d82f80377083ec8463309a4bb89"}, +] + +[package.extras] +twisted = ["twisted"] + +[[package]] +name = "prompt-toolkit" +version = "3.0.43" +description = "Library for building powerful interactive command lines in Python" +optional = false +python-versions = ">=3.7.0" +files = [ + {file = "prompt_toolkit-3.0.43-py3-none-any.whl", hash = "sha256:a11a29cb3bf0a28a387fe5122cdb649816a957cd9261dcedf8c9f1fef33eacf6"}, + {file = "prompt_toolkit-3.0.43.tar.gz", hash = "sha256:3527b7af26106cbc65a040bcc84839a3566ec1b051bb0bfe953631e704b0ff7d"}, +] + +[package.dependencies] +wcwidth = "*" + +[[package]] +name = "psutil" +version = "5.9.8" +description = "Cross-platform lib for process and system monitoring in Python." +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +files = [ + {file = "psutil-5.9.8-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:26bd09967ae00920df88e0352a91cff1a78f8d69b3ecabbfe733610c0af486c8"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:05806de88103b25903dff19bb6692bd2e714ccf9e668d050d144012055cbca73"}, + {file = "psutil-5.9.8-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:611052c4bc70432ec770d5d54f64206aa7203a101ec273a0cd82418c86503bb7"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:50187900d73c1381ba1454cf40308c2bf6f34268518b3f36a9b663ca87e65e36"}, + {file = "psutil-5.9.8-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:02615ed8c5ea222323408ceba16c60e99c3f91639b07da6373fb7e6539abc56d"}, + {file = "psutil-5.9.8-cp27-none-win32.whl", hash = "sha256:36f435891adb138ed3c9e58c6af3e2e6ca9ac2f365efe1f9cfef2794e6c93b4e"}, + {file = "psutil-5.9.8-cp27-none-win_amd64.whl", hash = "sha256:bd1184ceb3f87651a67b2708d4c3338e9b10c5df903f2e3776b62303b26cb631"}, + {file = "psutil-5.9.8-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:aee678c8720623dc456fa20659af736241f575d79429a0e5e9cf88ae0605cc81"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8cb6403ce6d8e047495a701dc7c5bd788add903f8986d523e3e20b98b733e421"}, + {file = "psutil-5.9.8-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d06016f7f8625a1825ba3732081d77c94589dca78b7a3fc072194851e88461a4"}, + {file = "psutil-5.9.8-cp36-cp36m-win32.whl", hash = "sha256:7d79560ad97af658a0f6adfef8b834b53f64746d45b403f225b85c5c2c140eee"}, + {file = "psutil-5.9.8-cp36-cp36m-win_amd64.whl", hash = "sha256:27cc40c3493bb10de1be4b3f07cae4c010ce715290a5be22b98493509c6299e2"}, + {file = "psutil-5.9.8-cp37-abi3-win32.whl", hash = "sha256:bc56c2a1b0d15aa3eaa5a60c9f3f8e3e565303b465dbf57a1b730e7a2b9844e0"}, + {file = "psutil-5.9.8-cp37-abi3-win_amd64.whl", hash = "sha256:8db4c1b57507eef143a15a6884ca10f7c73876cdf5d51e713151c1236a0e68cf"}, + {file = "psutil-5.9.8-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:d16bbddf0693323b8c6123dd804100241da461e41d6e332fb0ba6058f630f8c8"}, + {file = "psutil-5.9.8.tar.gz", hash = "sha256:6be126e3225486dff286a8fb9a06246a5253f4c7c53b475ea5f5ac934e64194c"}, +] + +[package.extras] +test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] + +[[package]] +name = "psycopg2" +version = "2.9.9" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "psycopg2-2.9.9-cp310-cp310-win32.whl", hash = "sha256:38a8dcc6856f569068b47de286b472b7c473ac7977243593a288ebce0dc89516"}, + {file = "psycopg2-2.9.9-cp310-cp310-win_amd64.whl", hash = "sha256:426f9f29bde126913a20a96ff8ce7d73fd8a216cfb323b1f04da402d452853c3"}, + {file = "psycopg2-2.9.9-cp311-cp311-win32.whl", hash = "sha256:ade01303ccf7ae12c356a5e10911c9e1c51136003a9a1d92f7aa9d010fb98372"}, + {file = "psycopg2-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:121081ea2e76729acfb0673ff33755e8703d45e926e416cb59bae3a86c6a4981"}, + {file = "psycopg2-2.9.9-cp312-cp312-win32.whl", hash = "sha256:d735786acc7dd25815e89cc4ad529a43af779db2e25aa7c626de864127e5a024"}, + {file = "psycopg2-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:a7653d00b732afb6fc597e29c50ad28087dcb4fbfb28e86092277a559ae4e693"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win32.whl", hash = "sha256:5e0d98cade4f0e0304d7d6f25bbfbc5bd186e07b38eac65379309c4ca3193efa"}, + {file = "psycopg2-2.9.9-cp37-cp37m-win_amd64.whl", hash = "sha256:7e2dacf8b009a1c1e843b5213a87f7c544b2b042476ed7755be813eaf4e8347a"}, + {file = "psycopg2-2.9.9-cp38-cp38-win32.whl", hash = "sha256:ff432630e510709564c01dafdbe996cb552e0b9f3f065eb89bdce5bd31fabf4c"}, + {file = "psycopg2-2.9.9-cp38-cp38-win_amd64.whl", hash = "sha256:bac58c024c9922c23550af2a581998624d6e02350f4ae9c5f0bc642c633a2d5e"}, + {file = "psycopg2-2.9.9-cp39-cp39-win32.whl", hash = "sha256:c92811b2d4c9b6ea0285942b2e7cac98a59e166d59c588fe5cfe1eda58e72d59"}, + {file = "psycopg2-2.9.9-cp39-cp39-win_amd64.whl", hash = "sha256:de80739447af31525feddeb8effd640782cf5998e1a4e9192ebdf829717e3913"}, + {file = "psycopg2-2.9.9.tar.gz", hash = "sha256:d1454bde93fb1e224166811694d600e746430c006fbb031ea06ecc2ea41bf156"}, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +description = "Run a subprocess in a pseudo terminal" +optional = false +python-versions = "*" +files = [ + {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, + {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, +] + +[[package]] +name = "pure-eval" +version = "0.2.2" +description = "Safely evaluate AST nodes without side effects" +optional = false +python-versions = "*" +files = [ + {file = "pure_eval-0.2.2-py3-none-any.whl", hash = "sha256:01eaab343580944bc56080ebe0a674b39ec44a945e6d09ba7db3cb8cec289350"}, + {file = "pure_eval-0.2.2.tar.gz", hash = "sha256:2b45320af6dfaa1750f543d714b6d1c520a1688dec6fd24d339063ce0aaa9ac3"}, +] + +[package.extras] +tests = ["pytest"] + +[[package]] +name = "py" +version = "1.11.0" +description = "library with cross-python path, ini-parsing, io, code, log facilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, + {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, +] + +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + +[[package]] +name = "pydantic" +version = "1.10.14" +description = "Data validation and settings management using python type hints" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, + {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, + {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, + {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, + {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, + {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, + {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, + {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, + {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, +] + +[package.dependencies] +typing-extensions = ">=4.2.0" + +[package.extras] +dotenv = ["python-dotenv (>=0.10.4)"] +email = ["email-validator (>=1.0.3)"] + +[[package]] +name = "pygments" +version = "2.17.2" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pygments-2.17.2-py3-none-any.whl", hash = "sha256:b27c2826c47d0f3219f29554824c30c5e8945175d888647acd804ddd04af846c"}, + {file = "pygments-2.17.2.tar.gz", hash = "sha256:da46cec9fd2de5be3a8a784f434e4c4ab670b4ff54d605c4c2717e9d49c4c367"}, +] + +[package.extras] +plugins = ["importlib-metadata"] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pytest" +version = "7.4.4" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, + {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=0.12,<2.0" +tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} + +[package.extras] +testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "pytest-asyncio" +version = "0.21.1" +description = "Pytest support for asyncio" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"}, + {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"}, +] + +[package.dependencies] +pytest = ">=7.0.0" + +[package.extras] +docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] +testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] + +[[package]] +name = "pytest-cov" +version = "4.1.0" +description = "Pytest plugin for measuring coverage." +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-cov-4.1.0.tar.gz", hash = "sha256:3904b13dfbfec47f003b8e77fd5b589cd11904a21ddf1ab38a64f204d6a10ef6"}, + {file = "pytest_cov-4.1.0-py3-none-any.whl", hash = "sha256:6ba70b9e97e69fcc3fb45bfeab2d0a138fb65c4d0d6a41ef33983ad114be8c3a"}, +] + +[package.dependencies] +coverage = {version = ">=5.2.1", extras = ["toml"]} +pytest = ">=4.6" + +[package.extras] +testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] + +[[package]] +name = "pytest-mock" +version = "3.12.0" +description = "Thin-wrapper around the mock package for easier use with pytest" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"}, + {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"}, +] + +[package.dependencies] +pytest = ">=5.0" + +[package.extras] +dev = ["pre-commit", "pytest-asyncio", "tox"] + +[[package]] +name = "pytest-socket" +version = "0.6.0" +description = "Pytest Plugin to disable socket calls during tests" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "pytest_socket-0.6.0-py3-none-any.whl", hash = "sha256:cca72f134ff01e0023c402e78d31b32e68da3efdf3493bf7788f8eba86a6824c"}, + {file = "pytest_socket-0.6.0.tar.gz", hash = "sha256:363c1d67228315d4fc7912f1aabfd570de29d0e3db6217d61db5728adacd7138"}, +] + +[package.dependencies] +pytest = ">=3.6.3" + +[[package]] +name = "pytest-timeout" +version = "2.2.0" +description = "pytest plugin to abort hanging tests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pytest-timeout-2.2.0.tar.gz", hash = "sha256:3b0b95dabf3cb50bac9ef5ca912fa0cfc286526af17afc806824df20c2f72c90"}, + {file = "pytest_timeout-2.2.0-py3-none-any.whl", hash = "sha256:bde531e096466f49398a59f2dde76fa78429a09a12411466f88a07213e220de2"}, +] + +[package.dependencies] +pytest = ">=5.0.0" + +[[package]] +name = "pytest-watch" +version = "4.2.0" +description = "Local continuous test runner with pytest and watchdog." +optional = false +python-versions = "*" +files = [ + {file = "pytest-watch-4.2.0.tar.gz", hash = "sha256:06136f03d5b361718b8d0d234042f7b2f203910d8568f63df2f866b547b3d4b9"}, +] + +[package.dependencies] +colorama = ">=0.3.3" +docopt = ">=0.4.0" +pytest = ">=2.6.4" +watchdog = ">=0.6.0" + +[[package]] +name = "python-dateutil" +version = "2.8.2" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +files = [ + {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, + {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "python-json-logger" +version = "2.0.7" +description = "A python library adding a json log formatter" +optional = false +python-versions = ">=3.6" +files = [ + {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, + {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, +] + +[[package]] +name = "python-magic" +version = "0.4.27" +description = "File type identification using libmagic" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "python-magic-0.4.27.tar.gz", hash = "sha256:c1ba14b08e4a5f5c31a302b7721239695b2f0f058d125bd5ce1ee36b9d9d3c3b"}, + {file = "python_magic-0.4.27-py2.py3-none-any.whl", hash = "sha256:c212960ad306f700aa0d01e5d7a325d20548ff97eb9920dcd29513174f0294d3"}, +] + +[[package]] +name = "python-multipart" +version = "0.0.9" +description = "A streaming multipart parser for Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "python_multipart-0.0.9-py3-none-any.whl", hash = "sha256:97ca7b8ea7b05f977dc3849c3ba99d51689822fab725c3703af7c866a0c2b215"}, + {file = "python_multipart-0.0.9.tar.gz", hash = "sha256:03f54688c663f1b7977105f021043b0793151e4cb1c1a9d4a11fc13d622c4026"}, +] + +[package.extras] +dev = ["atomicwrites (==1.4.1)", "attrs (==23.2.0)", "coverage (==7.4.1)", "hatch", "invoke (==2.2.0)", "more-itertools (==10.2.0)", "pbr (==6.0.0)", "pluggy (==1.4.0)", "py (==1.11.0)", "pytest (==8.0.0)", "pytest-cov (==4.1.0)", "pytest-timeout (==2.2.0)", "pyyaml (==6.0.1)", "ruff (==0.2.1)"] + +[[package]] +name = "pytz" +version = "2024.1" +description = "World timezone definitions, modern and historical" +optional = false +python-versions = "*" +files = [ + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, +] + +[[package]] +name = "pywin32" +version = "306" +description = "Python for Window Extensions" +optional = false +python-versions = "*" +files = [ + {file = "pywin32-306-cp310-cp310-win32.whl", hash = "sha256:06d3420a5155ba65f0b72f2699b5bacf3109f36acbe8923765c22938a69dfc8d"}, + {file = "pywin32-306-cp310-cp310-win_amd64.whl", hash = "sha256:84f4471dbca1887ea3803d8848a1616429ac94a4a8d05f4bc9c5dcfd42ca99c8"}, + {file = "pywin32-306-cp311-cp311-win32.whl", hash = "sha256:e65028133d15b64d2ed8f06dd9fbc268352478d4f9289e69c190ecd6818b6407"}, + {file = "pywin32-306-cp311-cp311-win_amd64.whl", hash = "sha256:a7639f51c184c0272e93f244eb24dafca9b1855707d94c192d4a0b4c01e1100e"}, + {file = "pywin32-306-cp311-cp311-win_arm64.whl", hash = "sha256:70dba0c913d19f942a2db25217d9a1b726c278f483a919f1abfed79c9cf64d3a"}, + {file = "pywin32-306-cp312-cp312-win32.whl", hash = "sha256:383229d515657f4e3ed1343da8be101000562bf514591ff383ae940cad65458b"}, + {file = "pywin32-306-cp312-cp312-win_amd64.whl", hash = "sha256:37257794c1ad39ee9be652da0462dc2e394c8159dfd913a8a4e8eb6fd346da0e"}, + {file = "pywin32-306-cp312-cp312-win_arm64.whl", hash = "sha256:5821ec52f6d321aa59e2db7e0a35b997de60c201943557d108af9d4ae1ec7040"}, + {file = "pywin32-306-cp37-cp37m-win32.whl", hash = "sha256:1c73ea9a0d2283d889001998059f5eaaba3b6238f767c9cf2833b13e6a685f65"}, + {file = "pywin32-306-cp37-cp37m-win_amd64.whl", hash = "sha256:72c5f621542d7bdd4fdb716227be0dd3f8565c11b280be6315b06ace35487d36"}, + {file = "pywin32-306-cp38-cp38-win32.whl", hash = "sha256:e4c092e2589b5cf0d365849e73e02c391c1349958c5ac3e9d5ccb9a28e017b3a"}, + {file = "pywin32-306-cp38-cp38-win_amd64.whl", hash = "sha256:e8ac1ae3601bee6ca9f7cb4b5363bf1c0badb935ef243c4733ff9a393b1690c0"}, + {file = "pywin32-306-cp39-cp39-win32.whl", hash = "sha256:e25fd5b485b55ac9c057f67d94bc203f3f6595078d1fb3b458c9c28b7153a802"}, + {file = "pywin32-306-cp39-cp39-win_amd64.whl", hash = "sha256:39b61c15272833b5c329a2989999dcae836b1eed650252ab1b7bfbe1d59f30f4"}, +] + +[[package]] +name = "pywinpty" +version = "2.0.12" +description = "Pseudo terminal support for Windows from Python." +optional = false +python-versions = ">=3.8" +files = [ + {file = "pywinpty-2.0.12-cp310-none-win_amd64.whl", hash = "sha256:21319cd1d7c8844fb2c970fb3a55a3db5543f112ff9cfcd623746b9c47501575"}, + {file = "pywinpty-2.0.12-cp311-none-win_amd64.whl", hash = "sha256:853985a8f48f4731a716653170cd735da36ffbdc79dcb4c7b7140bce11d8c722"}, + {file = "pywinpty-2.0.12-cp312-none-win_amd64.whl", hash = "sha256:1617b729999eb6713590e17665052b1a6ae0ad76ee31e60b444147c5b6a35dca"}, + {file = "pywinpty-2.0.12-cp38-none-win_amd64.whl", hash = "sha256:189380469ca143d06e19e19ff3fba0fcefe8b4a8cc942140a6b863aed7eebb2d"}, + {file = "pywinpty-2.0.12-cp39-none-win_amd64.whl", hash = "sha256:7520575b6546db23e693cbd865db2764097bd6d4ef5dc18c92555904cd62c3d4"}, + {file = "pywinpty-2.0.12.tar.gz", hash = "sha256:8197de460ae8ebb7f5d1701dfa1b5df45b157bb832e92acba316305e18ca00dd"}, +] + +[[package]] +name = "pyyaml" +version = "6.0.1" +description = "YAML parser and emitter for Python" +optional = false +python-versions = ">=3.6" +files = [ + {file = "PyYAML-6.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a"}, + {file = "PyYAML-6.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, + {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, + {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, + {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, + {file = "PyYAML-6.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, + {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, + {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, + {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, + {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, + {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win32.whl", hash = "sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585"}, + {file = "PyYAML-6.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa"}, + {file = "PyYAML-6.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3"}, + {file = "PyYAML-6.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win32.whl", hash = "sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba"}, + {file = "PyYAML-6.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867"}, + {file = "PyYAML-6.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, + {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, + {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, + {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, + {file = "PyYAML-6.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, + {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, + {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, + {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, + {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, +] + +[[package]] +name = "pyzmq" +version = "24.0.1" +description = "Python bindings for 0MQ" +optional = false +python-versions = ">=3.6" +files = [ + {file = "pyzmq-24.0.1-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:28b119ba97129d3001673a697b7cce47fe6de1f7255d104c2f01108a5179a066"}, + {file = "pyzmq-24.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bcbebd369493d68162cddb74a9c1fcebd139dfbb7ddb23d8f8e43e6c87bac3a6"}, + {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae61446166983c663cee42c852ed63899e43e484abf080089f771df4b9d272ef"}, + {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:87f7ac99b15270db8d53f28c3c7b968612993a90a5cf359da354efe96f5372b4"}, + {file = "pyzmq-24.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9dca7c3956b03b7663fac4d150f5e6d4f6f38b2462c1e9afd83bcf7019f17913"}, + {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8c78bfe20d4c890cb5580a3b9290f700c570e167d4cdcc55feec07030297a5e3"}, + {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:48f721f070726cd2a6e44f3c33f8ee4b24188e4b816e6dd8ba542c8c3bb5b246"}, + {file = "pyzmq-24.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:afe1f3bc486d0ce40abb0a0c9adb39aed3bbac36ebdc596487b0cceba55c21c1"}, + {file = "pyzmq-24.0.1-cp310-cp310-win32.whl", hash = "sha256:3e6192dbcefaaa52ed81be88525a54a445f4b4fe2fffcae7fe40ebb58bd06bfd"}, + {file = "pyzmq-24.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:86de64468cad9c6d269f32a6390e210ca5ada568c7a55de8e681ca3b897bb340"}, + {file = "pyzmq-24.0.1-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:838812c65ed5f7c2bd11f7b098d2e5d01685a3f6d1f82849423b570bae698c00"}, + {file = "pyzmq-24.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dfb992dbcd88d8254471760879d48fb20836d91baa90f181c957122f9592b3dc"}, + {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7abddb2bd5489d30ffeb4b93a428130886c171b4d355ccd226e83254fcb6b9ef"}, + {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94010bd61bc168c103a5b3b0f56ed3b616688192db7cd5b1d626e49f28ff51b3"}, + {file = "pyzmq-24.0.1-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:8242543c522d84d033fe79be04cb559b80d7eb98ad81b137ff7e0a9020f00ace"}, + {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ccb94342d13e3bf3ffa6e62f95b5e3f0bc6bfa94558cb37f4b3d09d6feb536ff"}, + {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6640f83df0ae4ae1104d4c62b77e9ef39be85ebe53f636388707d532bee2b7b8"}, + {file = "pyzmq-24.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:a180dbd5ea5d47c2d3b716d5c19cc3fb162d1c8db93b21a1295d69585bfddac1"}, + {file = "pyzmq-24.0.1-cp311-cp311-win32.whl", hash = "sha256:624321120f7e60336be8ec74a172ae7fba5c3ed5bf787cc85f7e9986c9e0ebc2"}, + {file = "pyzmq-24.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:1724117bae69e091309ffb8255412c4651d3f6355560d9af312d547f6c5bc8b8"}, + {file = "pyzmq-24.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:15975747462ec49fdc863af906bab87c43b2491403ab37a6d88410635786b0f4"}, + {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b947e264f0e77d30dcbccbb00f49f900b204b922eb0c3a9f0afd61aaa1cedc3d"}, + {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ec91f1bad66f3ee8c6deb65fa1fe418e8ad803efedd69c35f3b5502f43bd1dc"}, + {file = "pyzmq-24.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:db03704b3506455d86ec72c3358a779e9b1d07b61220dfb43702b7b668edcd0d"}, + {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e7e66b4e403c2836ac74f26c4b65d8ac0ca1eef41dfcac2d013b7482befaad83"}, + {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:7a23ccc1083c260fa9685c93e3b170baba45aeed4b524deb3f426b0c40c11639"}, + {file = "pyzmq-24.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:fa0ae3275ef706c0309556061185dd0e4c4cd3b7d6f67ae617e4e677c7a41e2e"}, + {file = "pyzmq-24.0.1-cp36-cp36m-win32.whl", hash = "sha256:f01de4ec083daebf210531e2cca3bdb1608dbbbe00a9723e261d92087a1f6ebc"}, + {file = "pyzmq-24.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:de4217b9eb8b541cf2b7fde4401ce9d9a411cc0af85d410f9d6f4333f43640be"}, + {file = "pyzmq-24.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:78068e8678ca023594e4a0ab558905c1033b2d3e806a0ad9e3094e231e115a33"}, + {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77c2713faf25a953c69cf0f723d1b7dd83827b0834e6c41e3fb3bbc6765914a1"}, + {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8bb4af15f305056e95ca1bd086239b9ebc6ad55e9f49076d27d80027f72752f6"}, + {file = "pyzmq-24.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0f14cffd32e9c4c73da66db97853a6aeceaac34acdc0fae9e5bbc9370281864c"}, + {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0108358dab8c6b27ff6b985c2af4b12665c1bc659648284153ee501000f5c107"}, + {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d66689e840e75221b0b290b0befa86f059fb35e1ee6443bce51516d4d61b6b99"}, + {file = "pyzmq-24.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae08ac90aa8fa14caafc7a6251bd218bf6dac518b7bff09caaa5e781119ba3f2"}, + {file = "pyzmq-24.0.1-cp37-cp37m-win32.whl", hash = "sha256:8421aa8c9b45ea608c205db9e1c0c855c7e54d0e9c2c2f337ce024f6843cab3b"}, + {file = "pyzmq-24.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54d8b9c5e288362ec8595c1d98666d36f2070fd0c2f76e2b3c60fbad9bd76227"}, + {file = "pyzmq-24.0.1-cp38-cp38-macosx_10_15_universal2.whl", hash = "sha256:acbd0a6d61cc954b9f535daaa9ec26b0a60a0d4353c5f7c1438ebc88a359a47e"}, + {file = "pyzmq-24.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:47b11a729d61a47df56346283a4a800fa379ae6a85870d5a2e1e4956c828eedc"}, + {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:abe6eb10122f0d746a0d510c2039ae8edb27bc9af29f6d1b05a66cc2401353ff"}, + {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:07bec1a1b22dacf718f2c0e71b49600bb6a31a88f06527dfd0b5aababe3fa3f7"}, + {file = "pyzmq-24.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0d945a85b70da97ae86113faf9f1b9294efe66bd4a5d6f82f2676d567338b66"}, + {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:1b7928bb7580736ffac5baf814097be342ba08d3cfdfb48e52773ec959572287"}, + {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b946da90dc2799bcafa682692c1d2139b2a96ec3c24fa9fc6f5b0da782675330"}, + {file = "pyzmq-24.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c8840f064b1fb377cffd3efeaad2b190c14d4c8da02316dae07571252d20b31f"}, + {file = "pyzmq-24.0.1-cp38-cp38-win32.whl", hash = "sha256:4854f9edc5208f63f0841c0c667260ae8d6846cfa233c479e29fdc85d42ebd58"}, + {file = "pyzmq-24.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:42d4f97b9795a7aafa152a36fe2ad44549b83a743fd3e77011136def512e6c2a"}, + {file = "pyzmq-24.0.1-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:52afb0ac962963fff30cf1be775bc51ae083ef4c1e354266ab20e5382057dd62"}, + {file = "pyzmq-24.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bad8210ad4df68c44ff3685cca3cda448ee46e20d13edcff8909eba6ec01ca4"}, + {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:dabf1a05318d95b1537fd61d9330ef4313ea1216eea128a17615038859da3b3b"}, + {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5bd3d7dfd9cd058eb68d9a905dec854f86649f64d4ddf21f3ec289341386c44b"}, + {file = "pyzmq-24.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8012bce6836d3f20a6c9599f81dfa945f433dab4dbd0c4917a6fb1f998ab33d"}, + {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c31805d2c8ade9b11feca4674eee2b9cce1fec3e8ddb7bbdd961a09dc76a80ea"}, + {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:3104f4b084ad5d9c0cb87445cc8cfd96bba710bef4a66c2674910127044df209"}, + {file = "pyzmq-24.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:df0841f94928f8af9c7a1f0aaaffba1fb74607af023a152f59379c01c53aee58"}, + {file = "pyzmq-24.0.1-cp39-cp39-win32.whl", hash = "sha256:a435ef8a3bd95c8a2d316d6e0ff70d0db524f6037411652803e118871d703333"}, + {file = "pyzmq-24.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:2032d9cb994ce3b4cba2b8dfae08c7e25bc14ba484c770d4d3be33c27de8c45b"}, + {file = "pyzmq-24.0.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:bb5635c851eef3a7a54becde6da99485eecf7d068bd885ac8e6d173c4ecd68b0"}, + {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:83ea1a398f192957cb986d9206ce229efe0ee75e3c6635baff53ddf39bd718d5"}, + {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:941fab0073f0a54dc33d1a0460cb04e0d85893cb0c5e1476c785000f8b359409"}, + {file = "pyzmq-24.0.1-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e8f482c44ccb5884bf3f638f29bea0f8dc68c97e38b2061769c4cb697f6140d"}, + {file = "pyzmq-24.0.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:613010b5d17906c4367609e6f52e9a2595e35d5cc27d36ff3f1b6fa6e954d944"}, + {file = "pyzmq-24.0.1-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:65c94410b5a8355cfcf12fd600a313efee46ce96a09e911ea92cf2acf6708804"}, + {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:20e7eeb1166087db636c06cae04a1ef59298627f56fb17da10528ab52a14c87f"}, + {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a2712aee7b3834ace51738c15d9ee152cc5a98dc7d57dd93300461b792ab7b43"}, + {file = "pyzmq-24.0.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a7c280185c4da99e0cc06c63bdf91f5b0b71deb70d8717f0ab870a43e376db8"}, + {file = "pyzmq-24.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:858375573c9225cc8e5b49bfac846a77b696b8d5e815711b8d4ba3141e6e8879"}, + {file = "pyzmq-24.0.1-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:80093b595921eed1a2cead546a683b9e2ae7f4a4592bb2ab22f70d30174f003a"}, + {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f3f3154fde2b1ff3aa7b4f9326347ebc89c8ef425ca1db8f665175e6d3bd42f"}, + {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abb756147314430bee5d10919b8493c0ccb109ddb7f5dfd2fcd7441266a25b75"}, + {file = "pyzmq-24.0.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e706bac34e9f50779cb8c39f10b53a4d15aebb97235643d3112ac20bd577b4"}, + {file = "pyzmq-24.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:687700f8371643916a1d2c61f3fdaa630407dd205c38afff936545d7b7466066"}, + {file = "pyzmq-24.0.1.tar.gz", hash = "sha256:216f5d7dbb67166759e59b0479bca82b8acf9bed6015b526b8eb10143fb08e77"}, +] + +[package.dependencies] +cffi = {version = "*", markers = "implementation_name == \"pypy\""} +py = {version = "*", markers = "implementation_name == \"pypy\""} + +[[package]] +name = "referencing" +version = "0.33.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, + {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + +[[package]] +name = "regex" +version = "2023.12.25" +description = "Alternative regular expression module, to replace re." +optional = false +python-versions = ">=3.7" +files = [ + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, +] + +[[package]] +name = "requests" +version = "2.31.0" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.7" +files = [ + {file = "requests-2.31.0-py3-none-any.whl", hash = "sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f"}, + {file = "requests-2.31.0.tar.gz", hash = "sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +description = "A pure python RFC3339 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa"}, + {file = "rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b"}, +] + +[package.dependencies] +six = "*" + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +description = "Pure python rfc3986 validator" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +files = [ + {file = "rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9"}, + {file = "rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055"}, +] + +[[package]] +name = "rpds-py" +version = "0.18.0" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88"}, + {file = "rpds_py-0.18.0-cp310-none-win32.whl", hash = "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337"}, + {file = "rpds_py-0.18.0-cp310-none-win_amd64.whl", hash = "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836"}, + {file = "rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1"}, + {file = "rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7"}, + {file = "rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98"}, + {file = "rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594"}, + {file = "rpds_py-0.18.0-cp38-none-win32.whl", hash = "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"}, + {file = "rpds_py-0.18.0-cp38-none-win_amd64.whl", hash = "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20"}, + {file = "rpds_py-0.18.0-cp39-none-win32.whl", hash = "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7"}, + {file = "rpds_py-0.18.0-cp39-none-win_amd64.whl", hash = "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f"}, + {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, +] + +[[package]] +name = "ruff" +version = "0.1.15" +description = "An extremely fast Python linter and code formatter, written in Rust." +optional = false +python-versions = ">=3.7" +files = [ + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, + {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, + {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, + {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, + {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, +] + +[[package]] +name = "send2trash" +version = "1.8.2" +description = "Send file to trash natively under Mac OS X, Windows and Linux" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" +files = [ + {file = "Send2Trash-1.8.2-py3-none-any.whl", hash = "sha256:a384719d99c07ce1eefd6905d2decb6f8b7ed054025bb0e618919f945de4f679"}, + {file = "Send2Trash-1.8.2.tar.gz", hash = "sha256:c132d59fa44b9ca2b1699af5c86f57ce9f4c5eb56629d5d55fbb7a35f84e2312"}, +] + +[package.extras] +nativelib = ["pyobjc-framework-Cocoa", "pywin32"] +objc = ["pyobjc-framework-Cocoa"] +win32 = ["pywin32"] + +[[package]] +name = "six" +version = "1.16.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" +files = [ + {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, + {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, +] + +[[package]] +name = "sniffio" +version = "1.3.0" +description = "Sniff out which async library your code is running under" +optional = false +python-versions = ">=3.7" +files = [ + {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, + {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, +] + +[[package]] +name = "soupsieve" +version = "2.5" +description = "A modern CSS selector implementation for Beautiful Soup." +optional = false +python-versions = ">=3.8" +files = [ + {file = "soupsieve-2.5-py3-none-any.whl", hash = "sha256:eaa337ff55a1579b6549dc679565eac1e3d000563bcb1c8ab0d0fefbc0c2cdc7"}, + {file = "soupsieve-2.5.tar.gz", hash = "sha256:5663d5a7b3bfaeee0bc4372e7fc48f9cff4940b3eec54a6451cc5299f1097690"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.27" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d04e579e911562f1055d26dab1868d3e0bb905db3bccf664ee8ad109f035618a"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c7a596d0be71b7baa037f4ac10d5e057d276f65a9a611c46970f012752ebf2d"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:954d9735ee9c3fa74874c830d089a815b7b48df6f6b6e357a74130e478dbd951"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5cd20f58c29bbf2680039ff9f569fa6d21453fbd2fa84dbdb4092f006424c2e6"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:03f448ffb731b48323bda68bcc93152f751436ad6037f18a42b7e16af9e91c07"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-win32.whl", hash = "sha256:d997c5938a08b5e172c30583ba6b8aad657ed9901fc24caf3a7152eeccb2f1b4"}, + {file = "SQLAlchemy-2.0.27-cp310-cp310-win_amd64.whl", hash = "sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6c5bad7c60a392850d2f0fee8f355953abaec878c483dd7c3836e0089f046bf6"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3012ab65ea42de1be81fff5fb28d6db893ef978950afc8130ba707179b4284a"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbcd77c4d94b23e0753c5ed8deba8c69f331d4fd83f68bfc9db58bc8983f49cd"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d177b7e82f6dd5e1aebd24d9c3297c70ce09cd1d5d37b43e53f39514379c029c"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:680b9a36029b30cf063698755d277885d4a0eab70a2c7c6e71aab601323cba45"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1306102f6d9e625cebaca3d4c9c8f10588735ef877f0360b5cdb4fdfd3fd7131"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-win32.whl", hash = "sha256:5b78aa9f4f68212248aaf8943d84c0ff0f74efc65a661c2fc68b82d498311fd5"}, + {file = "SQLAlchemy-2.0.27-cp311-cp311-win_amd64.whl", hash = "sha256:15e19a84b84528f52a68143439d0c7a3a69befcd4f50b8ef9b7b69d2628ae7c4"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:0de1263aac858f288a80b2071990f02082c51d88335a1db0d589237a3435fe71"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce850db091bf7d2a1f2fdb615220b968aeff3849007b1204bf6e3e50a57b3d32"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8dfc936870507da96aebb43e664ae3a71a7b96278382bcfe84d277b88e379b18"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c4fbe6a766301f2e8a4519f4500fe74ef0a8509a59e07a4085458f26228cd7cc"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4535c49d961fe9a77392e3a630a626af5baa967172d42732b7a43496c8b28876"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:0fb3bffc0ced37e5aa4ac2416f56d6d858f46d4da70c09bb731a246e70bff4d5"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-win32.whl", hash = "sha256:7f470327d06400a0aa7926b375b8e8c3c31d335e0884f509fe272b3c700a7254"}, + {file = "SQLAlchemy-2.0.27-cp312-cp312-win_amd64.whl", hash = "sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e97cf143d74a7a5a0f143aa34039b4fecf11343eed66538610debc438685db4a"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7b5a3e2120982b8b6bd1d5d99e3025339f7fb8b8267551c679afb39e9c7c7f1"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e36aa62b765cf9f43a003233a8c2d7ffdeb55bc62eaa0a0380475b228663a38f"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:5ada0438f5b74c3952d916c199367c29ee4d6858edff18eab783b3978d0db16d"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b1d9d1bfd96eef3c3faedb73f486c89e44e64e40e5bfec304ee163de01cf996f"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-win32.whl", hash = "sha256:ca891af9f3289d24a490a5fde664ea04fe2f4984cd97e26de7442a4251bd4b7c"}, + {file = "SQLAlchemy-2.0.27-cp37-cp37m-win_amd64.whl", hash = "sha256:fd8aafda7cdff03b905d4426b714601c0978725a19efc39f5f207b86d188ba01"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:ec1f5a328464daf7a1e4e385e4f5652dd9b1d12405075ccba1df842f7774b4fc"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ad862295ad3f644e3c2c0d8b10a988e1600d3123ecb48702d2c0f26771f1c396"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48217be1de7d29a5600b5c513f3f7664b21d32e596d69582be0a94e36b8309cb"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e56afce6431450442f3ab5973156289bd5ec33dd618941283847c9fd5ff06bf"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:611068511b5531304137bcd7fe8117c985d1b828eb86043bd944cebb7fae3910"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b86abba762ecfeea359112b2bb4490802b340850bbee1948f785141a5e020de8"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-win32.whl", hash = "sha256:30d81cc1192dc693d49d5671cd40cdec596b885b0ce3b72f323888ab1c3863d5"}, + {file = "SQLAlchemy-2.0.27-cp38-cp38-win_amd64.whl", hash = "sha256:120af1e49d614d2525ac247f6123841589b029c318b9afbfc9e2b70e22e1827d"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d07ee7793f2aeb9b80ec8ceb96bc8cc08a2aec8a1b152da1955d64e4825fcbac"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cb0845e934647232b6ff5150df37ceffd0b67b754b9fdbb095233deebcddbd4a"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fc19ae2e07a067663dd24fca55f8ed06a288384f0e6e3910420bf4b1270cc51"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b90053be91973a6fb6020a6e44382c97739736a5a9d74e08cc29b196639eb979"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2f5c9dfb0b9ab5e3a8a00249534bdd838d943ec4cfb9abe176a6c33408430230"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:33e8bde8fff203de50399b9039c4e14e42d4d227759155c21f8da4a47fc8053c"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-win32.whl", hash = "sha256:d873c21b356bfaf1589b89090a4011e6532582b3a8ea568a00e0c3aab09399dd"}, + {file = "SQLAlchemy-2.0.27-cp39-cp39-win_amd64.whl", hash = "sha256:ff2f1b7c963961d41403b650842dc2039175b906ab2093635d8319bef0b7d620"}, + {file = "SQLAlchemy-2.0.27-py3-none-any.whl", hash = "sha256:1ab4e0448018d01b142c916cc7119ca573803a4745cfe341b8f95657812700ac"}, + {file = "SQLAlchemy-2.0.27.tar.gz", hash = "sha256:86a6ed69a71fe6b88bf9331594fa390a2adda4a49b5c06f98e47bf0d392534f8"}, +] + +[package.dependencies] +greenlet = {version = "!=0.4.17", markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\""} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] +aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sse-starlette" +version = "2.0.0" +description = "SSE plugin for Starlette" +optional = false +python-versions = ">=3.8" +files = [ + {file = "sse_starlette-2.0.0-py3-none-any.whl", hash = "sha256:c4dd134302cb9708d47cae23c365fe0a089aa2a875d2f887ac80f235a9ee5744"}, + {file = "sse_starlette-2.0.0.tar.gz", hash = "sha256:0c43cc43aca4884c88c8416b65777c4de874cc4773e6458d3579c0a353dc2fb7"}, +] + +[package.dependencies] +anyio = "*" +starlette = "*" +uvicorn = "*" + +[package.extras] +examples = ["fastapi"] + +[[package]] +name = "stack-data" +version = "0.6.3" +description = "Extract data from python stack frames and tracebacks for informative displays" +optional = false +python-versions = "*" +files = [ + {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"}, + {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"}, +] + +[package.dependencies] +asttokens = ">=2.1.0" +executing = ">=1.2.0" +pure-eval = "*" + +[package.extras] +tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] + +[[package]] +name = "starlette" +version = "0.36.3" +description = "The little ASGI library that shines." +optional = false +python-versions = ">=3.8" +files = [ + {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, + {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, +] + +[package.dependencies] +anyio = ">=3.4.0,<5" +typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} + +[package.extras] +full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] + +[[package]] +name = "tenacity" +version = "8.2.3" +description = "Retry code until it succeeds" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tenacity-8.2.3-py3-none-any.whl", hash = "sha256:ce510e327a630c9e1beaf17d42e6ffacc88185044ad85cf74c0a8887c6a0f88c"}, + {file = "tenacity-8.2.3.tar.gz", hash = "sha256:5398ef0d78e63f40007c1fb4c0bff96e1911394d2fa8d194f77619c05ff6cc8a"}, +] + +[package.extras] +doc = ["reno", "sphinx", "tornado (>=4.5)"] + +[[package]] +name = "terminado" +version = "0.18.0" +description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." +optional = false +python-versions = ">=3.8" +files = [ + {file = "terminado-0.18.0-py3-none-any.whl", hash = "sha256:87b0d96642d0fe5f5abd7783857b9cab167f221a39ff98e3b9619a788a3c0f2e"}, + {file = "terminado-0.18.0.tar.gz", hash = "sha256:1ea08a89b835dd1b8c0c900d92848147cef2537243361b2e3f4dc15df9b6fded"}, +] + +[package.dependencies] +ptyprocess = {version = "*", markers = "os_name != \"nt\""} +pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} +tornado = ">=6.1.0" + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["pre-commit", "pytest (>=7.0)", "pytest-timeout"] +typing = ["mypy (>=1.6,<2.0)", "traitlets (>=5.11.1)"] + +[[package]] +name = "tiktoken" +version = "0.6.0" +description = "tiktoken is a fast BPE tokeniser for use with OpenAI's models" +optional = false +python-versions = ">=3.8" +files = [ + {file = "tiktoken-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:277de84ccd8fa12730a6b4067456e5cf72fef6300bea61d506c09e45658d41ac"}, + {file = "tiktoken-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9c44433f658064463650d61387623735641dcc4b6c999ca30bc0f8ba3fccaf5c"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afb9a2a866ae6eef1995ab656744287a5ac95acc7e0491c33fad54d053288ad3"}, + {file = "tiktoken-0.6.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c62c05b3109fefca26fedb2820452a050074ad8e5ad9803f4652977778177d9f"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0ef917fad0bccda07bfbad835525bbed5f3ab97a8a3e66526e48cdc3e7beacf7"}, + {file = "tiktoken-0.6.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e095131ab6092d0769a2fda85aa260c7c383072daec599ba9d8b149d2a3f4d8b"}, + {file = "tiktoken-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:05b344c61779f815038292a19a0c6eb7098b63c8f865ff205abb9ea1b656030e"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cefb9870fb55dca9e450e54dbf61f904aab9180ff6fe568b61f4db9564e78871"}, + {file = "tiktoken-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:702950d33d8cabc039845674107d2e6dcabbbb0990ef350f640661368df481bb"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e8d49d076058f23254f2aff9af603863c5c5f9ab095bc896bceed04f8f0b013a"}, + {file = "tiktoken-0.6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:430bc4e650a2d23a789dc2cdca3b9e5e7eb3cd3935168d97d43518cbb1f9a911"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:293cb8669757301a3019a12d6770bd55bec38a4d3ee9978ddbe599d68976aca7"}, + {file = "tiktoken-0.6.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7bd1a288b7903aadc054b0e16ea78e3171f70b670e7372432298c686ebf9dd47"}, + {file = "tiktoken-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac76e000183e3b749634968a45c7169b351e99936ef46f0d2353cd0d46c3118d"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17cc8a4a3245ab7d935c83a2db6bb71619099d7284b884f4b2aea4c74f2f83e3"}, + {file = "tiktoken-0.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:284aebcccffe1bba0d6571651317df6a5b376ff6cfed5aeb800c55df44c78177"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c1a3a5d33846f8cd9dd3b7897c1d45722f48625a587f8e6f3d3e85080559be8"}, + {file = "tiktoken-0.6.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6318b2bb2337f38ee954fd5efa82632c6e5ced1d52a671370fa4b2eff1355e91"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:1f5f0f2ed67ba16373f9a6013b68da298096b27cd4e1cf276d2d3868b5c7efd1"}, + {file = "tiktoken-0.6.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:75af4c0b16609c2ad02581f3cdcd1fb698c7565091370bf6c0cf8624ffaba6dc"}, + {file = "tiktoken-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:45577faf9a9d383b8fd683e313cf6df88b6076c034f0a16da243bb1c139340c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7c1492ab90c21ca4d11cef3a236ee31a3e279bb21b3fc5b0e2210588c4209e68"}, + {file = "tiktoken-0.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e2b380c5b7751272015400b26144a2bab4066ebb8daae9c3cd2a92c3b508fe5a"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9f497598b9f58c99cbc0eb764b4a92272c14d5203fc713dd650b896a03a50ad"}, + {file = "tiktoken-0.6.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e65e8bd6f3f279d80f1e1fbd5f588f036b9a5fa27690b7f0cc07021f1dfa0839"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5f1495450a54e564d236769d25bfefbf77727e232d7a8a378f97acddee08c1ae"}, + {file = "tiktoken-0.6.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6c4e4857d99f6fb4670e928250835b21b68c59250520a1941618b5b4194e20c3"}, + {file = "tiktoken-0.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:168d718f07a39b013032741867e789971346df8e89983fe3c0ef3fbd5a0b1cb9"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:47fdcfe11bd55376785a6aea8ad1db967db7f66ea81aed5c43fad497521819a4"}, + {file = "tiktoken-0.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fb7d2ccbf1a7784810aff6b80b4012fb42c6fc37eaa68cb3b553801a5cc2d1fc"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ccb7a111ee76af5d876a729a347f8747d5ad548e1487eeea90eaf58894b3138"}, + {file = "tiktoken-0.6.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2048e1086b48e3c8c6e2ceeac866561374cd57a84622fa49a6b245ffecb7744"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:07f229a5eb250b6403a61200199cecf0aac4aa23c3ecc1c11c1ca002cbb8f159"}, + {file = "tiktoken-0.6.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:432aa3be8436177b0db5a2b3e7cc28fd6c693f783b2f8722539ba16a867d0c6a"}, + {file = "tiktoken-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:8bfe8a19c8b5c40d121ee7938cd9c6a278e5b97dc035fd61714b4f0399d2f7a1"}, + {file = "tiktoken-0.6.0.tar.gz", hash = "sha256:ace62a4ede83c75b0374a2ddfa4b76903cf483e9cb06247f566be3bf14e6beed"}, +] + +[package.dependencies] +regex = ">=2022.1.18" +requests = ">=2.26.0" + +[package.extras] +blobfile = ["blobfile (>=2)"] + +[[package]] +name = "tinycss2" +version = "1.2.1" +description = "A tiny CSS parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tinycss2-1.2.1-py3-none-any.whl", hash = "sha256:2b80a96d41e7c3914b8cda8bc7f705a4d9c49275616e886103dd839dfc847847"}, + {file = "tinycss2-1.2.1.tar.gz", hash = "sha256:8cff3a8f066c2ec677c06dbc7b45619804a6938478d9d73c284b29d14ecb0627"}, +] + +[package.dependencies] +webencodings = ">=0.4" + +[package.extras] +doc = ["sphinx", "sphinx_rtd_theme"] +test = ["flake8", "isort", "pytest"] + +[[package]] +name = "tomli" +version = "2.0.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, + {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, +] + +[[package]] +name = "tornado" +version = "6.4" +description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." +optional = false +python-versions = ">= 3.8" +files = [ + {file = "tornado-6.4-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:02ccefc7d8211e5a7f9e8bc3f9e5b0ad6262ba2fbb683a6443ecc804e5224ce0"}, + {file = "tornado-6.4-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:27787de946a9cffd63ce5814c33f734c627a87072ec7eed71f7fc4417bb16263"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7894c581ecdcf91666a0912f18ce5e757213999e183ebfc2c3fdbf4d5bd764e"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e43bc2e5370a6a8e413e1e1cd0c91bedc5bd62a74a532371042a18ef19e10579"}, + {file = "tornado-6.4-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0251554cdd50b4b44362f73ad5ba7126fc5b2c2895cc62b14a1c2d7ea32f212"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:fd03192e287fbd0899dd8f81c6fb9cbbc69194d2074b38f384cb6fa72b80e9c2"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_i686.whl", hash = "sha256:88b84956273fbd73420e6d4b8d5ccbe913c65d31351b4c004ae362eba06e1f78"}, + {file = "tornado-6.4-cp38-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:71ddfc23a0e03ef2df1c1397d859868d158c8276a0603b96cf86892bff58149f"}, + {file = "tornado-6.4-cp38-abi3-win32.whl", hash = "sha256:6f8a6c77900f5ae93d8b4ae1196472d0ccc2775cc1dfdc9e7727889145c45052"}, + {file = "tornado-6.4-cp38-abi3-win_amd64.whl", hash = "sha256:10aeaa8006333433da48dec9fe417877f8bcc21f48dda8d661ae79da357b2a63"}, + {file = "tornado-6.4.tar.gz", hash = "sha256:72291fa6e6bc84e626589f1c29d90a5a6d593ef5ae68052ee2ef000dfd273dee"}, +] + +[[package]] +name = "tqdm" +version = "4.66.2" +description = "Fast, Extensible Progress Meter" +optional = false +python-versions = ">=3.7" +files = [ + {file = "tqdm-4.66.2-py3-none-any.whl", hash = "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9"}, + {file = "tqdm-4.66.2.tar.gz", hash = "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "platform_system == \"Windows\""} + +[package.extras] +dev = ["pytest (>=6)", "pytest-cov", "pytest-timeout", "pytest-xdist"] +notebook = ["ipywidgets (>=6)"] +slack = ["slack-sdk"] +telegram = ["requests"] + +[[package]] +name = "traitlets" +version = "5.14.1" +description = "Traitlets Python configuration system" +optional = false +python-versions = ">=3.8" +files = [ + {file = "traitlets-5.14.1-py3-none-any.whl", hash = "sha256:2e5a030e6eff91737c643231bfcf04a65b0132078dad75e4936700b213652e74"}, + {file = "traitlets-5.14.1.tar.gz", hash = "sha256:8585105b371a04b8316a43d5ce29c098575c2e477850b62b848b964f1444527e"}, +] + +[package.extras] +docs = ["myst-parser", "pydata-sphinx-theme", "sphinx"] +test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0,<7.5)", "pytest-mock", "pytest-mypy-testing"] + +[[package]] +name = "types-python-dateutil" +version = "2.8.19.20240106" +description = "Typing stubs for python-dateutil" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, + {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, +] + +[[package]] +name = "typing-extensions" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +files = [ + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, +] + +[[package]] +name = "typing-inspect" +version = "0.9.0" +description = "Runtime inspection utilities for typing module." +optional = false +python-versions = "*" +files = [ + {file = "typing_inspect-0.9.0-py3-none-any.whl", hash = "sha256:9ee6fc59062311ef8547596ab6b955e1b8aa46242d854bfc78f4f6b0eff35f9f"}, + {file = "typing_inspect-0.9.0.tar.gz", hash = "sha256:b23fc42ff6f6ef6954e4852c1fb512cdd18dbea03134f91f856a95ccc9461f78"}, +] + +[package.dependencies] +mypy-extensions = ">=0.3.0" +typing-extensions = ">=3.7.4" + +[[package]] +name = "uri-template" +version = "1.3.0" +description = "RFC 6570 URI Template Processor" +optional = false +python-versions = ">=3.7" +files = [ + {file = "uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7"}, + {file = "uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363"}, +] + +[package.extras] +dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake8-commas", "flake8-comprehensions", "flake8-continuation", "flake8-datetimez", "flake8-docstrings", "flake8-import-order", "flake8-literal", "flake8-modern-annotations", "flake8-noqa", "flake8-pyproject", "flake8-requirements", "flake8-typechecking-import", "flake8-use-fstring", "mypy", "pep8-naming", "types-PyYAML"] + +[[package]] +name = "urllib3" +version = "2.2.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.8" +files = [ + {file = "urllib3-2.2.0-py3-none-any.whl", hash = "sha256:ce3711610ddce217e6d113a2732fafad960a03fd0318c91faa79481e35c11224"}, + {file = "urllib3-2.2.0.tar.gz", hash = "sha256:051d961ad0c62a94e50ecf1af379c3aba230c66c710493493560c0c223c49f20"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9)", "brotlicffi (>=0.8.0)"] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[[package]] +name = "uvicorn" +version = "0.27.1" +description = "The lightning-fast ASGI server." +optional = false +python-versions = ">=3.8" +files = [ + {file = "uvicorn-0.27.1-py3-none-any.whl", hash = "sha256:5c89da2f3895767472a35556e539fd59f7edbe9b1e9c0e1c99eebeadc61838e4"}, + {file = "uvicorn-0.27.1.tar.gz", hash = "sha256:3d9a267296243532db80c83a959a3400502165ade2c1338dea4e67915fd4745a"}, +] + +[package.dependencies] +click = ">=7.0" +h11 = ">=0.8" +typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} + +[package.extras] +standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] + +[[package]] +name = "watchdog" +version = "4.0.0" +description = "Filesystem events monitoring" +optional = false +python-versions = ">=3.8" +files = [ + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, +] + +[package.extras] +watchmedo = ["PyYAML (>=3.10)"] + +[[package]] +name = "wcwidth" +version = "0.2.13" +description = "Measures the displayed width of unicode strings in a terminal" +optional = false +python-versions = "*" +files = [ + {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"}, + {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"}, +] + +[[package]] +name = "webcolors" +version = "1.13" +description = "A library for working with the color formats defined by HTML and CSS." +optional = false +python-versions = ">=3.7" +files = [ + {file = "webcolors-1.13-py3-none-any.whl", hash = "sha256:29bc7e8752c0a1bd4a1f03c14d6e6a72e93d82193738fa860cbff59d0fcc11bf"}, + {file = "webcolors-1.13.tar.gz", hash = "sha256:c225b674c83fa923be93d235330ce0300373d02885cef23238813b0d5668304a"}, +] + +[package.extras] +docs = ["furo", "sphinx", "sphinx-copybutton", "sphinx-inline-tabs", "sphinx-notfound-page", "sphinxext-opengraph"] +tests = ["pytest", "pytest-cov"] + +[[package]] +name = "webencodings" +version = "0.5.1" +description = "Character encoding aliases for legacy web content" +optional = false +python-versions = "*" +files = [ + {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, + {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, +] + +[[package]] +name = "websocket-client" +version = "1.7.0" +description = "WebSocket client for Python with low level API options" +optional = false +python-versions = ">=3.8" +files = [ + {file = "websocket-client-1.7.0.tar.gz", hash = "sha256:10e511ea3a8c744631d3bd77e61eb17ed09304c413ad42cf6ddfa4c7787e8fe6"}, + {file = "websocket_client-1.7.0-py3-none-any.whl", hash = "sha256:f4c3d22fec12a2461427a29957ff07d35098ee2d976d3ba244e688b8b4057588"}, +] + +[package.extras] +docs = ["Sphinx (>=6.0)", "sphinx-rtd-theme (>=1.1.0)"] +optional = ["python-socks", "wsaccel"] +test = ["websockets"] + +[[package]] +name = "y-py" +version = "0.6.2" +description = "Python bindings for the Y-CRDT built from yrs (Rust)" +optional = false +python-versions = "*" +files = [ + {file = "y_py-0.6.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:c26bada6cd109095139237a46f50fc4308f861f0d304bc9e70acbc6c4503d158"}, + {file = "y_py-0.6.2-cp310-cp310-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:bae1b1ad8d2b8cf938a60313f8f7461de609621c5dcae491b6e54975f76f83c5"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e794e44fa260300b8850246c6371d94014753c73528f97f6ccb42f5e7ce698ae"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2686d7d8ca31531458a48e08b0344a8eec6c402405446ce7d838e2a7e43355a"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d917f5bc27b85611ceee4eb85f0e4088b0a03b4eed22c472409933a94ee953cf"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f6071328aad06fdcc0a4acc2dc4839396d645f5916de07584af807eb7c08407"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:266ec46ab9f9cb40fbb5e649f55c329fc4620fa0b1a8117bdeefe91595e182dc"}, + {file = "y_py-0.6.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ce15a842c2a0bf46180ae136743b561fa276300dd7fa61fe76daf00ec7dc0c2d"}, + {file = "y_py-0.6.2-cp310-none-win32.whl", hash = "sha256:1d5b544e79ace93fdbd0b36ed329c86e346898153ac7ba2ec62bc9b4c6b745c9"}, + {file = "y_py-0.6.2-cp310-none-win_amd64.whl", hash = "sha256:80a827e173372682959a57e6b8cc4f6468b1a4495b4bc7a775ef6ca05ae3e8e8"}, + {file = "y_py-0.6.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:a21148b8ea09a631b752d975f9410ee2a31c0e16796fdc113422a6d244be10e5"}, + {file = "y_py-0.6.2-cp311-cp311-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:898fede446ca1926b8406bdd711617c2aebba8227ee8ec1f0c2f8568047116f7"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce7c20b9395696d3b5425dccf2706d374e61ccf8f3656bff9423093a6df488f5"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a3932f53418b408fa03bd002e6dc573a74075c2c092926dde80657c39aa2e054"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:df35ea436592eb7e30e59c5403ec08ec3a5e7759e270cf226df73c47b3e739f5"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26cb1307c3ca9e21a3e307ab2c2099677e071ae9c26ec10ddffb3faceddd76b3"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:863e175ce5585f9ff3eba2aa16626928387e2a576157f02c8eb247a218ecdeae"}, + {file = "y_py-0.6.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:35fcb9def6ce137540fdc0e91b08729677548b9c393c0151a6359fd199da3bd7"}, + {file = "y_py-0.6.2-cp311-none-win32.whl", hash = "sha256:86422c6090f34906c062fd3e4fdfdccf3934f2922021e979573ae315050b4288"}, + {file = "y_py-0.6.2-cp311-none-win_amd64.whl", hash = "sha256:6c2f2831c5733b404d2f2da4bfd02bb4612ae18d0822e14ae79b0b92436b816d"}, + {file = "y_py-0.6.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:7cbefd4f1060f05768227ddf83be126397b1d430b026c64e0eb25d3cf50c5734"}, + {file = "y_py-0.6.2-cp312-cp312-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:032365dfe932bfab8e80937ad6093b4c22e67d63ad880096b5fa8768f8d829ba"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a70aee572da3994238c974694767365f237fc5949a550bee78a650fe16f83184"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae80d505aee7b3172cdcc2620ca6e2f85586337371138bb2b71aa377d2c31e9a"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2a497ebe617bec6a420fc47378856caae40ab0652e756f3ed40c5f1fe2a12220"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e8638355ae2f996356f7f281e03a3e3ce31f1259510f9d551465356532e0302c"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8448da4092265142662bbd3fc46cb8b0796b1e259189c020bc8f738899abd0b5"}, + {file = "y_py-0.6.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:69cfbcbe0a05f43e780e6a198080ba28034bf2bb4804d7d28f71a0379bfd1b19"}, + {file = "y_py-0.6.2-cp37-cp37m-macosx_10_7_x86_64.whl", hash = "sha256:1f798165158b76365a463a4f8aa2e3c2a12eb89b1fc092e7020e93713f2ad4dc"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92878cc05e844c8da937204bc34c2e6caf66709ce5936802fbfb35f04132892"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9b8822a5c0fd9a8cffcabfcc0cd7326bad537ee614fc3654e413a03137b6da1a"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e13cba03c7af8c8a846c4495875a09d64362cc4caeed495ada5390644411bbe7"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:82f2e5b31678065e7a7fa089ed974af5a4f076673cf4f414219bdadfc3246a21"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1935d12e503780b859d343161a80df65205d23cad7b4f6c3df6e50321e188a3"}, + {file = "y_py-0.6.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:bd302c6d46a3be57664571a5f0d4224646804be9890a01d73a0b294f2d3bbff1"}, + {file = "y_py-0.6.2-cp37-none-win32.whl", hash = "sha256:5415083f7f10eac25e1c434c87f07cb9bfa58909a6cad6649166fdad21119fc5"}, + {file = "y_py-0.6.2-cp37-none-win_amd64.whl", hash = "sha256:376c5cc0c177f03267340f36aec23e5eaf19520d41428d87605ca2ca3235d845"}, + {file = "y_py-0.6.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:3c011303eb2b360695d2bd4bd7ca85f42373ae89fcea48e7fa5b8dc6fc254a98"}, + {file = "y_py-0.6.2-cp38-cp38-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:c08311db17647a47d4898fc6f8d9c1f0e58b927752c894877ff0c38b3db0d6e1"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9b7cafbe946b4cafc1e5709957e6dd5c6259d241d48ed75713ded42a5e8a4663"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3ba99d0bdbd9cabd65f914cd07b4fb2e939ce199b54ae5ace1639ce1edf8e0a2"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dab84c52f64e10adc79011a08673eb80286c159b14e8fb455524bf2994f0cb38"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72875641a907523d37f4619eb4b303611d17e0a76f2ffc423b62dd1ca67eef41"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c31240e30d5636ded02a54b7280aa129344fe8e964fd63885e85d9a8a83db206"}, + {file = "y_py-0.6.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:4c28d977f516d4928f6bc0cd44561f6d0fdd661d76bac7cdc4b73e3c209441d9"}, + {file = "y_py-0.6.2-cp38-none-win32.whl", hash = "sha256:c011997f62d0c3b40a617e61b7faaaf6078e4eeff2e95ce4c45838db537816eb"}, + {file = "y_py-0.6.2-cp38-none-win_amd64.whl", hash = "sha256:ce0ae49879d10610cf3c40f4f376bb3cc425b18d939966ac63a2a9c73eb6f32a"}, + {file = "y_py-0.6.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:47fcc19158150dc4a6ae9a970c5bc12f40b0298a2b7d0c573a510a7b6bead3f3"}, + {file = "y_py-0.6.2-cp39-cp39-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:2d2b054a1a5f4004967532a4b82c6d1a45421ef2a5b41d35b6a8d41c7142aabe"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0787e85645bb4986c27e271715bc5ce21bba428a17964e5ec527368ed64669bc"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:17bce637a89f6e75f0013be68becac3e38dc082e7aefaf38935e89215f0aa64a"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:beea5ad9bd9e56aa77a6583b6f4e347d66f1fe7b1a2cb196fff53b7634f9dc84"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d1dca48687f41efd862355e58b0aa31150586219324901dbea2989a506e291d4"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17edd21eef863d230ea00004ebc6d582cc91d325e7132deb93f0a90eb368c855"}, + {file = "y_py-0.6.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:de9cfafe97c75cd3ea052a24cd4aabf9fb0cfc3c0f9f810f00121cdf123db9e4"}, + {file = "y_py-0.6.2-cp39-none-win32.whl", hash = "sha256:82f5ca62bedbf35aaf5a75d1f53b4457a1d9b6ff033497ca346e2a0cedf13d14"}, + {file = "y_py-0.6.2-cp39-none-win_amd64.whl", hash = "sha256:7227f232f2daf130ba786f6834548f2cfcfa45b7ec4f0d449e72560ac298186c"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:0649a41cd3c98e290c16592c082dbe42c7ffec747b596172eebcafb7fd8767b0"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:bf6020560584671e76375b7a0539e0d5388fc70fa183c99dc769895f7ef90233"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cf817a72ffec4295def5c5be615dd8f1e954cdf449d72ebac579ff427951328"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7c7302619fc962e53093ba4a94559281491c045c925e5c4defec5dac358e0568"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cd6213c3cf2b9eee6f2c9867f198c39124c557f4b3b77d04a73f30fd1277a59"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2b4fac4ea2ce27b86d173ae45765ced7f159120687d4410bb6d0846cbdb170a3"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:932abb560fe739416b50716a72ba6c6c20b219edded4389d1fc93266f3505d4b"}, + {file = "y_py-0.6.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e42258f66ad9f16d9b62e9c9642742982acb1f30b90f5061522048c1cb99814f"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:cfc8381df1f0f873da8969729974f90111cfb61a725ef0a2e0e6215408fe1217"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-macosx_10_9_x86_64.macosx_11_0_arm64.macosx_10_9_universal2.whl", hash = "sha256:613f83713714972886e81d71685403098a83ffdacf616f12344b52bc73705107"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316e5e1c40259d482883d1926fd33fa558dc87b2bd2ca53ce237a6fe8a34e473"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:015f7f6c1ce8a83d57955d1dc7ddd57cb633ae00576741a4fc9a0f72ed70007d"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff32548e45e45bf3280ac1d28b3148337a5c6714c28db23aeb0693e33eba257e"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0f2d881f0f8bf5674f8fe4774a438c545501e40fa27320c73be4f22463af4b05"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3bbe2f925cc587545c8d01587b4523177408edd252a32ce6d61b97113fe234d"}, + {file = "y_py-0.6.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8f5c14d25611b263b876e9ada1701415a13c3e9f02ea397224fbe4ca9703992b"}, + {file = "y_py-0.6.2.tar.gz", hash = "sha256:4757a82a50406a0b3a333aa0122019a331bd6f16e49fed67dca423f928b3fd4d"}, +] + +[[package]] +name = "yarl" +version = "1.9.4" +description = "Yet another URL library" +optional = false +python-versions = ">=3.7" +files = [ + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a8c1df72eb746f4136fe9a2e72b0c9dc1da1cbd23b5372f94b5820ff8ae30e0e"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a3a6ed1d525bfb91b3fc9b690c5a21bb52de28c018530ad85093cc488bee2dd2"}, + {file = "yarl-1.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c38c9ddb6103ceae4e4498f9c08fac9b590c5c71b0370f98714768e22ac6fa66"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d9e09c9d74f4566e905a0b8fa668c58109f7624db96a2171f21747abc7524234"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8477c1ee4bd47c57d49621a062121c3023609f7a13b8a46953eb6c9716ca392"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5ff2c858f5f6a42c2a8e751100f237c5e869cbde669a724f2062d4c4ef93551"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:357495293086c5b6d34ca9616a43d329317feab7917518bc97a08f9e55648455"}, + {file = "yarl-1.9.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54525ae423d7b7a8ee81ba189f131054defdb122cde31ff17477951464c1691c"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:801e9264d19643548651b9db361ce3287176671fb0117f96b5ac0ee1c3530d53"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:e516dc8baf7b380e6c1c26792610230f37147bb754d6426462ab115a02944385"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:7d5aaac37d19b2904bb9dfe12cdb08c8443e7ba7d2852894ad448d4b8f442863"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:54beabb809ffcacbd9d28ac57b0db46e42a6e341a030293fb3185c409e626b8b"}, + {file = "yarl-1.9.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bac8d525a8dbc2a1507ec731d2867025d11ceadcb4dd421423a5d42c56818541"}, + {file = "yarl-1.9.4-cp310-cp310-win32.whl", hash = "sha256:7855426dfbddac81896b6e533ebefc0af2f132d4a47340cee6d22cac7190022d"}, + {file = "yarl-1.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:848cd2a1df56ddbffeb375535fb62c9d1645dde33ca4d51341378b3f5954429b"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:35a2b9396879ce32754bd457d31a51ff0a9d426fd9e0e3c33394bf4b9036b099"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4c7d56b293cc071e82532f70adcbd8b61909eec973ae9d2d1f9b233f3d943f2c"}, + {file = "yarl-1.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d8a1c6c0be645c745a081c192e747c5de06e944a0d21245f4cf7c05e457c36e0"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b3c1ffe10069f655ea2d731808e76e0f452fc6c749bea04781daf18e6039525"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:549d19c84c55d11687ddbd47eeb348a89df9cb30e1993f1b128f4685cd0ebbf8"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7409f968456111140c1c95301cadf071bd30a81cbd7ab829169fb9e3d72eae9"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e23a6d84d9d1738dbc6e38167776107e63307dfc8ad108e580548d1f2c587f42"}, + {file = "yarl-1.9.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8b889777de69897406c9fb0b76cdf2fd0f31267861ae7501d93003d55f54fbe"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:03caa9507d3d3c83bca08650678e25364e1843b484f19986a527630ca376ecce"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:4e9035df8d0880b2f1c7f5031f33f69e071dfe72ee9310cfc76f7b605958ceb9"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:c0ec0ed476f77db9fb29bca17f0a8fcc7bc97ad4c6c1d8959c507decb22e8572"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:ee04010f26d5102399bd17f8df8bc38dc7ccd7701dc77f4a68c5b8d733406958"}, + {file = "yarl-1.9.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:49a180c2e0743d5d6e0b4d1a9e5f633c62eca3f8a86ba5dd3c471060e352ca98"}, + {file = "yarl-1.9.4-cp311-cp311-win32.whl", hash = "sha256:81eb57278deb6098a5b62e88ad8281b2ba09f2f1147c4767522353eaa6260b31"}, + {file = "yarl-1.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:d1d2532b340b692880261c15aee4dc94dd22ca5d61b9db9a8a361953d36410b1"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0d2454f0aef65ea81037759be5ca9947539667eecebca092733b2eb43c965a81"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:44d8ffbb9c06e5a7f529f38f53eda23e50d1ed33c6c869e01481d3fafa6b8142"}, + {file = "yarl-1.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:aaaea1e536f98754a6e5c56091baa1b6ce2f2700cc4a00b0d49eca8dea471074"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3777ce5536d17989c91696db1d459574e9a9bd37660ea7ee4d3344579bb6f129"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9fc5fc1eeb029757349ad26bbc5880557389a03fa6ada41703db5e068881e5f2"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ea65804b5dc88dacd4a40279af0cdadcfe74b3e5b4c897aa0d81cf86927fee78"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa102d6d280a5455ad6a0f9e6d769989638718e938a6a0a2ff3f4a7ff8c62cc4"}, + {file = "yarl-1.9.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09efe4615ada057ba2d30df871d2f668af661e971dfeedf0c159927d48bbeff0"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:008d3e808d03ef28542372d01057fd09168419cdc8f848efe2804f894ae03e51"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6f5cb257bc2ec58f437da2b37a8cd48f666db96d47b8a3115c29f316313654ff"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:992f18e0ea248ee03b5a6e8b3b4738850ae7dbb172cc41c966462801cbf62cf7"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:0e9d124c191d5b881060a9e5060627694c3bdd1fe24c5eecc8d5d7d0eb6faabc"}, + {file = "yarl-1.9.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3986b6f41ad22988e53d5778f91855dc0399b043fc8946d4f2e68af22ee9ff10"}, + {file = "yarl-1.9.4-cp312-cp312-win32.whl", hash = "sha256:4b21516d181cd77ebd06ce160ef8cc2a5e9ad35fb1c5930882baff5ac865eee7"}, + {file = "yarl-1.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a9bd00dc3bc395a662900f33f74feb3e757429e545d831eef5bb280252631984"}, + {file = "yarl-1.9.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:63b20738b5aac74e239622d2fe30df4fca4942a86e31bf47a81a0e94c14df94f"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7d7f7de27b8944f1fee2c26a88b4dabc2409d2fea7a9ed3df79b67277644e17"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c74018551e31269d56fab81a728f683667e7c28c04e807ba08f8c9e3bba32f14"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ca06675212f94e7a610e85ca36948bb8fc023e458dd6c63ef71abfd482481aa5"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aef935237d60a51a62b86249839b51345f47564208c6ee615ed2a40878dccdd"}, + {file = "yarl-1.9.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b134fd795e2322b7684155b7855cc99409d10b2e408056db2b93b51a52accc7"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d25039a474c4c72a5ad4b52495056f843a7ff07b632c1b92ea9043a3d9950f6e"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f7d6b36dd2e029b6bcb8a13cf19664c7b8e19ab3a58e0fefbb5b8461447ed5ec"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:957b4774373cf6f709359e5c8c4a0af9f6d7875db657adb0feaf8d6cb3c3964c"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:d7eeb6d22331e2fd42fce928a81c697c9ee2d51400bd1a28803965883e13cead"}, + {file = "yarl-1.9.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6a962e04b8f91f8c4e5917e518d17958e3bdee71fd1d8b88cdce74dd0ebbf434"}, + {file = "yarl-1.9.4-cp37-cp37m-win32.whl", hash = "sha256:f3bc6af6e2b8f92eced34ef6a96ffb248e863af20ef4fde9448cc8c9b858b749"}, + {file = "yarl-1.9.4-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4d7a90a92e528aadf4965d685c17dacff3df282db1121136c382dc0b6014d2"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ec61d826d80fc293ed46c9dd26995921e3a82146feacd952ef0757236fc137be"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8be9e837ea9113676e5754b43b940b50cce76d9ed7d2461df1af39a8ee674d9f"}, + {file = "yarl-1.9.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bef596fdaa8f26e3d66af846bbe77057237cb6e8efff8cd7cc8dff9a62278bbf"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d47552b6e52c3319fede1b60b3de120fe83bde9b7bddad11a69fb0af7db32f1"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:84fc30f71689d7fc9168b92788abc977dc8cefa806909565fc2951d02f6b7d57"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4aa9741085f635934f3a2583e16fcf62ba835719a8b2b28fb2917bb0537c1dfa"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:206a55215e6d05dbc6c98ce598a59e6fbd0c493e2de4ea6cc2f4934d5a18d130"}, + {file = "yarl-1.9.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07574b007ee20e5c375a8fe4a0789fad26db905f9813be0f9fef5a68080de559"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5a2e2433eb9344a163aced6a5f6c9222c0786e5a9e9cac2c89f0b28433f56e23"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6ad6d10ed9b67a382b45f29ea028f92d25bc0bc1daf6c5b801b90b5aa70fb9ec"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6fe79f998a4052d79e1c30eeb7d6c1c1056ad33300f682465e1b4e9b5a188b78"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:a825ec844298c791fd28ed14ed1bffc56a98d15b8c58a20e0e08c1f5f2bea1be"}, + {file = "yarl-1.9.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8619d6915b3b0b34420cf9b2bb6d81ef59d984cb0fde7544e9ece32b4b3043c3"}, + {file = "yarl-1.9.4-cp38-cp38-win32.whl", hash = "sha256:686a0c2f85f83463272ddffd4deb5e591c98aac1897d65e92319f729c320eece"}, + {file = "yarl-1.9.4-cp38-cp38-win_amd64.whl", hash = "sha256:a00862fb23195b6b8322f7d781b0dc1d82cb3bcac346d1e38689370cc1cc398b"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:604f31d97fa493083ea21bd9b92c419012531c4e17ea6da0f65cacdcf5d0bd27"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8a854227cf581330ffa2c4824d96e52ee621dd571078a252c25e3a3b3d94a1b1"}, + {file = "yarl-1.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ba6f52cbc7809cd8d74604cce9c14868306ae4aa0282016b641c661f981a6e91"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a6327976c7c2f4ee6816eff196e25385ccc02cb81427952414a64811037bbc8b"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8397a3817d7dcdd14bb266283cd1d6fc7264a48c186b986f32e86d86d35fbac5"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0381b4ce23ff92f8170080c97678040fc5b08da85e9e292292aba67fdac6c34"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23d32a2594cb5d565d358a92e151315d1b2268bc10f4610d098f96b147370136"}, + {file = "yarl-1.9.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb2a5c08a4eaaba605340fdee8fc08e406c56617566d9643ad8bf6852778fc7"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:26a1dc6285e03f3cc9e839a2da83bcbf31dcb0d004c72d0730e755b33466c30e"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:18580f672e44ce1238b82f7fb87d727c4a131f3a9d33a5e0e82b793362bf18b4"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:29e0f83f37610f173eb7e7b5562dd71467993495e568e708d99e9d1944f561ec"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:1f23e4fe1e8794f74b6027d7cf19dc25f8b63af1483d91d595d4a07eca1fb26c"}, + {file = "yarl-1.9.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:db8e58b9d79200c76956cefd14d5c90af54416ff5353c5bfd7cbe58818e26ef0"}, + {file = "yarl-1.9.4-cp39-cp39-win32.whl", hash = "sha256:c7224cab95645c7ab53791022ae77a4509472613e839dab722a72abe5a684575"}, + {file = "yarl-1.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:824d6c50492add5da9374875ce72db7a0733b29c2394890aef23d533106e2b15"}, + {file = "yarl-1.9.4-py3-none-any.whl", hash = "sha256:928cecb0ef9d5a7946eb6ff58417ad2fe9375762382f1bf5c55e61645f2c43ad"}, + {file = "yarl-1.9.4.tar.gz", hash = "sha256:566db86717cf8080b99b58b083b773a908ae40f06681e87e589a976faf8246bf"}, +] + +[package.dependencies] +idna = ">=2.0" +multidict = ">=4.0" + +[[package]] +name = "ypy-websocket" +version = "0.8.4" +description = "WebSocket connector for Ypy" +optional = false +python-versions = ">=3.7" +files = [ + {file = "ypy_websocket-0.8.4-py3-none-any.whl", hash = "sha256:b1ba0dfcc9762f0ca168d2378062d3ca1299d39076b0f145d961359121042be5"}, + {file = "ypy_websocket-0.8.4.tar.gz", hash = "sha256:43a001473f5c8abcf182f603049cf305cbc855ad8deaa9dfa0f3b5a7cea9d0ff"}, +] + +[package.dependencies] +aiofiles = ">=22.1.0,<23" +aiosqlite = ">=0.17.0,<1" +y-py = ">=0.6.0,<0.7.0" + +[package.extras] +test = ["mypy", "pre-commit", "pytest", "pytest-asyncio", "websockets (>=10.0)"] + +[[package]] +name = "zipp" +version = "3.17.0" +description = "Backport of pathlib-compatible object wrapper for zip files" +optional = false +python-versions = ">=3.8" +files = [ + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] + +[metadata] +lock-version = "2.0" +python-versions = "^3.8.1" +content-hash = "302511765abb89cb2227b4a4af29fb2ed9d6c23ad7d8b08d1a87d85ffc2aa4ac" diff --git a/backend/pyproject.toml b/backend/pyproject.toml new file mode 100644 index 0000000..c35350a --- /dev/null +++ b/backend/pyproject.toml @@ -0,0 +1,91 @@ +[tool.poetry] +name = "langchain-extract" +version = "0.0.1" +description = "Sample extraction backend." +authors = ["LangChain AI"] +license = "MIT" +readme = "README.md" + +[tool.poetry.dependencies] +python = "^3.8.1" +langchain = "~0.1" +langsmith = ">=0.0.66" +fastapi = "^0.109.2" +langserve = "^0.0.41" +uvicorn = "^0.27.1" +pydantic = "^1.10" +langchain-openai = "^0.0.6" +jsonschema = "^4.21.1" +sse-starlette = "^2.0.0" +alembic = "^1.13.1" +psycopg2 = "^2.9.9" +python-magic = "^0.4.27" +pdfminer-six = "^20231228" +beautifulsoup4 = "^4.12.3" +lxml = "^5.1.0" +faiss-cpu = "^1.7.4" +python-multipart = "^0.0.9" + +[tool.poetry.group.dev.dependencies] +jupyterlab = "^3.6.1" + +[tool.poetry.group.typing.dependencies] +mypy = "^1.7.0" + +[tool.poetry.group.lint.dependencies] +ruff = "^0.1.5" + +[tool.poetry.group.docs.dependencies] + +[tool.poetry.group.test.dependencies] +pytest = "^7.2.1" +pytest-cov = "^4.0.0" +pytest-asyncio = "^0.21.1" +pytest-mock = "^3.11.1" +pytest-socket = "^0.6.0" +pytest-watch = "^4.2.0" +pytest-timeout = "^2.2.0" + + +[tool.ruff] +select = [ + "E", # pycodestyle + "F", # pyflakes + "I", # isort +] +extend-include = ["*.ipynb"] + +# Same as Black. +line-length = 88 + +[tool.mypy] +disallow_untyped_defs = "True" +ignore_missing_imports = "True" + +[tool.coverage.run] +omit = [ + "tests/*", +] + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.pytest.ini_options] +# --strict-markers will raise errors on unknown marks. +# https://docs.pytest.org/en/7.1.x/how-to/mark.html#raising-errors-on-unknown-marks +# +# https://docs.pytest.org/en/7.1.x/reference/reference.html +# --strict-config any warnings encountered while parsing the `pytest` +# section of the configuration file raise errors. +addopts = "--strict-markers --strict-config --durations=5 -vv" +# Global timeout for all tests. There shuold be a good reason for a test to +# take more than 5 second +timeout = 5 +# Registering custom markers. +# https://docs.pytest.org/en/7.1.x/example/markers.html#registering-markers +markers = [ + "asyncio: mark tests as requiring asyncio", +] +asyncio_mode = "auto" diff --git a/backend/scripts/__init__.py b/backend/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/scripts/run_migrations.py b/backend/scripts/run_migrations.py new file mode 100755 index 0000000..7639fef --- /dev/null +++ b/backend/scripts/run_migrations.py @@ -0,0 +1,59 @@ +#!/usr/bin/env python +"""Run migrations.""" +import click + +from db.models import ENGINE, Base + + +@click.group() +def cli(): + """Database migration commands.""" + pass + + +@cli.command() +def create(): + """Create all tables.""" + Base.metadata.create_all(ENGINE) + click.echo("All tables created successfully.") + + +@cli.command() +@click.confirmation_option(prompt="Are you sure you want to drop all tables?") +def drop(): + """Drop all tables.""" + Base.metadata.drop_all(ENGINE) + click.echo("All tables dropped successfully.") + + +@cli.command() +def create_test_db(): + """Create a test database called langchain_test used for testing purposes.""" + import psycopg2 + from psycopg2.errors import DuplicateDatabase + + # establishing the connection + conn = psycopg2.connect( + database="langchain", + user="langchain", + password="langchain", + host="localhost", + port="5432", + ) + conn.autocommit = True + + # Creating a cursor object using the cursor() method + with conn.cursor() as cursor: + # Preparing query to create a database + sql = "CREATE DATABASE langchain_test;" + + # Creating a database + try: + cursor.execute(sql) + print("Database created successfully.") + except DuplicateDatabase: + print("Database already exists") + + +if __name__ == "__main__": + cli() diff --git a/backend/server/__init__.py b/backend/server/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/server/api/__init__.py b/backend/server/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/server/api/examples.py b/backend/server/api/examples.py new file mode 100644 index 0000000..98ee41d --- /dev/null +++ b/backend/server/api/examples.py @@ -0,0 +1,74 @@ +"""Endpoints for managing definition of examples..""" +from typing import Any, Dict, List +from uuid import UUID + +from fastapi import APIRouter, Depends +from sqlalchemy.orm import Session +from typing_extensions import Annotated, TypedDict + +from db.models import Example, get_session + +router = APIRouter( + prefix="/examples", + tags=["example definitions"], + responses={404: {"description": "Not found"}}, +) + + +class CreateExample(TypedDict): + """A request to create an example.""" + + extractor_id: Annotated[UUID, "The extractor ID that this is an example for."] + content: Annotated[str, "The input portion of the example."] + output: Annotated[ + List[Any], "JSON object that is expected to be extracted from the content." + ] + + +class CreateExampleResponse(TypedDict): + """Response for creating an example.""" + + uuid: UUID + + +@router.post("") +def create( + create_request: CreateExample, + *, + session: Session = Depends(get_session), +) -> CreateExampleResponse: + """Endpoint to create an example.""" + instance = Example( + extractor_id=create_request["extractor_id"], + content=create_request["content"], + output=create_request["output"], + ) + session.add(instance) + session.commit() + return {"uuid": instance.uuid} + + +@router.get("") +def list( + extractor_id: UUID, + *, + limit: int = 10, + offset: int = 0, + session=Depends(get_session), +) -> List[Any]: + """Endpoint to get all examples.""" + return ( + session.query(Example) + .filter(Example.extractor_id == extractor_id) + .order_by(Example.uuid) + .limit(limit) + .offset(offset) + .all() + ) + + +@router.delete("/{uuid}") +def delete(uuid: UUID, *, session: Session = Depends(get_session)) -> None: + """Endpoint to delete an example.""" + session.query(Example).filter(Example.uuid == str(uuid)).delete() + session.commit() diff --git a/backend/server/api/extract.py b/backend/server/api/extract.py new file mode 100644 index 0000000..f36a8b3 --- /dev/null +++ b/backend/server/api/extract.py @@ -0,0 +1,56 @@ +from typing import Literal, Optional +from uuid import UUID + +from fastapi import APIRouter, Depends, File, Form, HTTPException, UploadFile +from sqlalchemy.orm import Session +from typing_extensions import Annotated + +from db.models import Extractor, get_session +from extraction.parsing import parse_binary_input +from server.extraction_runnable import ExtractResponse, extract_entire_document +from server.retrieval import extract_from_content + +router = APIRouter( + prefix="/extract", + tags=["extract"], + responses={404: {"description": "Not found"}}, +) + + +@router.post("", response_model=ExtractResponse) +async def extract_using_existing_extractor( + *, + extractor_id: Annotated[UUID, Form()], + text: Optional[str] = Form(None), + mode: Literal["entire_document", "retrieval"] = Form("entire_document"), + file: Optional[UploadFile] = File(None), + session: Session = Depends(get_session), +) -> ExtractResponse: + """Endpoint that is used with an existing extractor. + + This endpoint will be expanded to support upload of binary files as well as + text files. + """ + if text is None and file is None: + raise HTTPException(status_code=422, detail="No text or file provided.") + + extractor = session.query(Extractor).filter(Extractor.uuid == extractor_id).scalar() + if extractor is None: + raise HTTPException(status_code=404, detail="Extractor not found.") + + if text: + text_ = text + else: + documents = parse_binary_input(file.file) + # TODO: Add metadata like location from original file where + # the text was extracted from + text_ = "\n".join([document.page_content for document in documents]) + + if mode == "entire_document": + return await extract_entire_document(text_, extractor) + elif mode == "retrieval": + return await extract_from_content(text_, extractor) + else: + raise ValueError( + f"Invalid mode {mode}. Expected one of 'entire_document', 'retrieval'." + ) diff --git a/backend/server/api/extractors.py b/backend/server/api/extractors.py new file mode 100644 index 0000000..c8e96c3 --- /dev/null +++ b/backend/server/api/extractors.py @@ -0,0 +1,93 @@ +"""Endpoints for managing definition of extractors.""" +from typing import Any, Dict, List +from uuid import UUID + +from fastapi import APIRouter, Depends, HTTPException +from pydantic import BaseModel, Field, validator +from sqlalchemy.orm import Session + +from db.models import Extractor, get_session +from server.validators import validate_json_schema + +router = APIRouter( + prefix="/extractors", + tags=["extractor definitions"], + responses={404: {"description": "Not found"}}, +) + + +class CreateExtractor(BaseModel): + """A request to create an extractor.""" + + name: str = Field(default="", description="The name of the extractor.") + + description: str = Field( + default="", description="Short description of the extractor." + ) + json_schema: Dict[str, Any] = Field( + ..., description="The schema to use for extraction.", alias="schema" + ) + instruction: str = Field(..., description="The instruction to use for extraction.") + + @validator("json_schema") + def validate_schema(cls, v: Any) -> Dict[str, Any]: + """Validate the schema.""" + validate_json_schema(v) + return v + + +class CreateExtractorResponse(BaseModel): + """Response for creating an extractor.""" + + uuid: UUID + + +@router.post("") +def create( + create_request: CreateExtractor, *, session: Session = Depends(get_session) +) -> CreateExtractorResponse: + """Endpoint to create an extractor.""" + instance = Extractor( + name=create_request.name, + schema=create_request.json_schema, + description=create_request.description, + instruction=create_request.instruction, + ) + session.add(instance) + session.commit() + return CreateExtractorResponse(uuid=instance.uuid) + + +@router.get("/{uuid}") +def get( + uuid: UUID, *, session: Session = Depends(get_session) +) -> Dict[str, Any]: + """Endpoint to get an extractor.""" + extractor = session.query(Extractor).filter(Extractor.uuid == str(uuid)).scalar() + if extractor is None: + raise HTTPException(status_code=404, detail="Extractor not found.") + return { + "uuid": extractor.uuid, + "name": extractor.name, + "description": extractor.description, + "schema": extractor.schema, + "instruction": extractor.instruction, + } + + +@router.get("") +def list( + *, + limit: int = 10, + offset: int = 0, + session=Depends(get_session), +) -> List[Any]: + """Endpoint to get all extractors.""" + return session.query(Extractor).limit(limit).offset(offset).all() + + +@router.delete("/{uuid}") +def delete(uuid: UUID, *, session: Session = Depends(get_session)) -> None: + """Endpoint to delete an extractor.""" + session.query(Extractor).filter(Extractor.uuid == str(uuid)).delete() + session.commit() diff --git a/backend/server/extraction_runnable.py b/backend/server/extraction_runnable.py new file mode 100644 index 0000000..d0842a8 --- /dev/null +++ b/backend/server/extraction_runnable.py @@ -0,0 +1,208 @@ +from __future__ import annotations + +import json +from typing import Any, Dict, List, Optional, Sequence + +from fastapi import HTTPException +from jsonschema import Draft202012Validator, exceptions +from langchain.chains.openai_functions import create_openai_fn_runnable +from langchain.text_splitter import TokenTextSplitter +from langchain_core.messages import AIMessage, HumanMessage +from langchain_core.prompts import ChatPromptTemplate +from langchain_core.runnables import chain +from langserve import CustomUserType +from pydantic import BaseModel, Field, validator +from typing_extensions import TypedDict + +from db.models import Example, Extractor +from extraction.utils import ( + convert_json_schema_to_openai_schema, +) +from server.settings import CHUNK_SIZE, MODEL_NAME, model +from server.validators import validate_json_schema + + +class ExtractionExample(BaseModel): + """An example extraction. + + This example consists of a text and the expected output of the extraction. + """ + + text: str = Field(..., description="The input text") + output: List[Dict[str, Any]] = Field( + ..., description="The expected output of the example. A list of objects." + ) + + +class ExtractRequest(CustomUserType): + """Request body for the extract endpoint.""" + + text: str = Field(..., description="The text to extract from.") + json_schema: Dict[str, Any] = Field( + ..., + description="JSON schema that describes what content should be extracted " + "from the text.", + alias="schema", + ) + instructions: Optional[str] = Field( + None, description="Supplemental system instructions." + ) + examples: Optional[List[ExtractionExample]] = Field( + None, description="Examples of extractions." + ) + + @validator("json_schema") + def validate_schema(cls, v: Any) -> Dict[str, Any]: + """Validate the schema.""" + validate_json_schema(v) + return v + + +class ExtractResponse(TypedDict): + """Response body for the extract endpoint.""" + + data: List[Any] + + +def _deduplicate( + extract_responses: Sequence[ExtractResponse], +) -> ExtractResponse: + """Deduplicate the results. + + The deduplication is done by comparing the serialized JSON of each of the results + and only keeping the unique ones. + """ + unique_extracted = [] + seen = set() + for response in extract_responses: + for data_item in response["data"]: + # Serialize the data item for comparison purposes + serialized = json.dumps(data_item, sort_keys=True) + if serialized not in seen: + seen.add(serialized) + unique_extracted.append(data_item) + + return { + "data": unique_extracted, + } + + +def _cast_example_to_dict(example: Example) -> Dict[str, Any]: + """Cast example record to dictionary.""" + return { + "text": example.content, + "output": example.output, + } + + +def _make_prompt_template( + instructions: Optional[str], + examples: Optional[Sequence[ExtractionExample]], + function_name: str, +) -> ChatPromptTemplate: + """Make a system message from instructions and examples.""" + prefix = ( + "You are a top-tier algorithm for extracting information from text. " + "Only extract information that is relevant to the provided text. " + "If no information is relevant, use the schema and output " + "an empty list where appropriate." + ) + if instructions: + system_message = ("system", f"{prefix}\n\n{instructions}") + else: + system_message = ("system", prefix) + prompt_components = [system_message] + if examples is not None: + few_shot_prompt = [] + for example in examples: + # TODO: We'll need to refactor this at some point to + # support other encoding strategies. The function calling logic here + # has some hard-coded assumptions (e.g., name of parameters like `data`). + function_call = { + "arguments": json.dumps( + { + "data": example.output, + } + ), + "name": function_name, + } + few_shot_prompt.extend( + [ + HumanMessage(content=example.text), + AIMessage( + content="", additional_kwargs={"function_call": function_call} + ), + ] + ) + prompt_components.extend(few_shot_prompt) + + prompt_components.append( + ( + "human", + "I need to extract information from " + "the following text: ```\n{text}\n```\n", + ), + ) + return ChatPromptTemplate.from_messages(prompt_components) + + +# PUBLIC API + + +def get_examples_from_extractor(extractor: Extractor) -> List[Dict[str, Any]]: + """Get examples from an extractor.""" + return [_cast_example_to_dict(example) for example in extractor.examples] + + +@chain +async def extraction_runnable(extraction_request: ExtractRequest) -> ExtractResponse: + """An end point to extract content from a given text object.""" + # TODO: Add validation for model context window size + schema = extraction_request.json_schema + try: + Draft202012Validator.check_schema(schema) + except exceptions.ValidationError as e: + raise HTTPException(status_code=422, detail=f"Invalid schema: {e.message}") + + openai_function = convert_json_schema_to_openai_schema(schema) + function_name = openai_function["name"] + prompt = _make_prompt_template( + extraction_request.instructions, + extraction_request.examples, + function_name, + ) + runnable = create_openai_fn_runnable( + functions=[openai_function], llm=model, prompt=prompt + ) + return await runnable.ainvoke({"text": extraction_request.text}) + + +async def extract_entire_document( + content: str, + extractor: Extractor, +) -> ExtractResponse: + """Extract from entire document.""" + + json_schema = extractor.schema + examples = get_examples_from_extractor(extractor) + text_splitter = TokenTextSplitter( + chunk_size=CHUNK_SIZE, + chunk_overlap=20, + model_name=MODEL_NAME, + ) + texts = text_splitter.split_text(content) + extraction_requests = [ + ExtractRequest( + text=text, + schema=json_schema, + instructions=extractor.instruction, # TODO: consistent naming + examples=examples, + ) + for text in texts + ] + # Run extractions which may potentially yield duplicate results + extract_responses: List[ExtractResponse] = await extraction_runnable.abatch( + extraction_requests, {"max_concurrency": 1} + ) + # Deduplicate the results + return _deduplicate(extract_responses) diff --git a/backend/server/main.py b/backend/server/main.py new file mode 100644 index 0000000..98825c4 --- /dev/null +++ b/backend/server/main.py @@ -0,0 +1,65 @@ +"""Entry point into the server.""" + +from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware +from langserve import add_routes +from sqlalchemy.orm import Session +from typing_extensions import Annotated + +from server.api import examples, extract, extractors +from server.extraction_runnable import ( + ExtractRequest, + ExtractResponse, + extraction_runnable, +) + +app = FastAPI( + title="Extraction Powered by LangChain", + description="An extraction service powered by LangChain.", + version="0.0.1", + openapi_tags=[ + { + "name": "extraction", + "description": "Operations related to extracting content from text.", + } + ], +) + + +origins = [ + "http://localhost:5173", +] + +app.add_middleware( + CORSMiddleware, + allow_origins=origins, + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + + +@app.get("/ready") +def ready(): + return "ok" + + +# Include API endpoints for extractor definitions +app.include_router(extractors.router) +app.include_router(examples.router) +app.include_router(extract.router) + +add_routes( + app, + extraction_runnable.with_types( + input_type=ExtractRequest, output_type=ExtractResponse + ), + path="/extract_text", + enabled_endpoints=["invoke", "playground", "stream_log"], +) + + +if __name__ == "__main__": + import uvicorn + + uvicorn.run(app, host="localhost", port=8000) diff --git a/backend/server/retrieval.py b/backend/server/retrieval.py new file mode 100644 index 0000000..4515913 --- /dev/null +++ b/backend/server/retrieval.py @@ -0,0 +1,72 @@ +from operator import itemgetter +from typing import Any, Dict, List, Optional + +from langchain.text_splitter import CharacterTextSplitter +from langchain_community.vectorstores import FAISS +from langchain_core.documents import Document +from langchain_core.runnables import RunnableLambda +from langchain_openai import OpenAIEmbeddings + +from db.models import Extractor +from server.extraction_runnable import ( + ExtractRequest, + ExtractResponse, + extraction_runnable, + get_examples_from_extractor, +) + + +def _get_top_doc_content(docs: List[Document]) -> str: + if docs: + return docs[0].page_content + else: + return "" + + +def _make_extract_request(input_dict: Dict[str, Any]) -> ExtractRequest: + return ExtractRequest(**input_dict) + + +async def extract_from_content( + content: str, + extractor: Extractor, + *, + text_splitter_kwargs: Optional[Dict[str, Any]] = None, + multi: bool = True, +) -> ExtractResponse: + """Extract from potentially long-form content.""" + if text_splitter_kwargs is None: + text_splitter_kwargs = { + "separator": "\n\n", + "chunk_size": 1000, + "chunk_overlap": 50, + } + text_splitter = CharacterTextSplitter(**text_splitter_kwargs) + docs = text_splitter.create_documents([content]) + doc_contents = [doc.page_content for doc in docs] + + vectorstore = FAISS.from_texts(doc_contents, embedding=OpenAIEmbeddings()) + retriever = vectorstore.as_retriever() + + runnable = ( + { + "text": itemgetter("query") | retriever | _get_top_doc_content, + "schema": itemgetter("schema"), + "instructions": lambda x: x.get("instructions"), + "examples": lambda x: x.get("examples"), + } + | RunnableLambda(_make_extract_request) + | extraction_runnable + ) + schema = extractor.schema + examples = get_examples_from_extractor(extractor) + description = extractor.description # TODO: improve this + result = await runnable.ainvoke( + { + "query": description, + "schema": schema, + "examples": examples, + "instructions": extractor.instruction, + } + ) + return ExtractResponse(extracted=[result.extracted]) diff --git a/backend/server/settings.py b/backend/server/settings.py new file mode 100644 index 0000000..822b742 --- /dev/null +++ b/backend/server/settings.py @@ -0,0 +1,24 @@ +from __future__ import annotations + +from langchain_openai import ChatOpenAI +from sqlalchemy.engine import URL + +MODEL_NAME = "gpt-3.5-turbo" +CHUNK_SIZE = int(4_096 * 0.8) +# Max concurrency for the model. +MAX_CONCURRENCY = 1 + + +def get_postgres_url(): + url = URL.create( + drivername="postgresql", + username="langchain", + password="langchain", + host="localhost", + database="langchain", + port=5432, + ) + return url + + +model = ChatOpenAI(model=MODEL_NAME, temperature=0) diff --git a/backend/server/validators.py b/backend/server/validators.py new file mode 100644 index 0000000..d977b8f --- /dev/null +++ b/backend/server/validators.py @@ -0,0 +1,15 @@ +from typing import Any, Dict + +from fastapi import HTTPException +from jsonschema import exceptions +from jsonschema.validators import Draft202012Validator + + +def validate_json_schema(schema: Dict[str, Any]) -> None: + """Validate a JSON schema.""" + try: + Draft202012Validator.check_schema(schema) + except exceptions.ValidationError as e: + raise HTTPException( + status_code=422, detail=f"Not a valid JSON schema: {e.message}" + ) diff --git a/backend/tests/__init__.py b/backend/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/db.py b/backend/tests/db.py new file mode 100644 index 0000000..543a21e --- /dev/null +++ b/backend/tests/db.py @@ -0,0 +1,51 @@ +"""Utility code that sets up a test database and client for tests.""" +from contextlib import asynccontextmanager +from typing import Generator + +from httpx import AsyncClient +from sqlalchemy import URL, create_engine +from sqlalchemy.orm import sessionmaker + +from db.models import Base, get_session +from server.main import app + +url = URL.create( + drivername="postgresql", + username="langchain", + password="langchain", + host="localhost", + database="langchain_test", + port=5432, +) +engine = create_engine(url) +TestingSession = sessionmaker(bind=engine) + + +def override_get_session() -> Generator[TestingSession, None, None]: + """Override the get_session dependency with a test session. + + This fixture also re-creats the database before each test and drops it after to + ensure a clean slate for each test. + """ + try: + session = TestingSession() + yield session + finally: + session.close() + + +app.dependency_overrides[get_session] = override_get_session + + +@asynccontextmanager +async def get_async_client() -> AsyncClient: + """Get an async client.""" + # Clear the database before each test + Base.metadata.drop_all(engine) + Base.metadata.create_all(engine) + + async_client = AsyncClient(app=app, base_url="http://test") + try: + yield async_client + finally: + await async_client.aclose() diff --git a/backend/tests/integration_tests/__init__.py b/backend/tests/integration_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/integration_tests/test_extraction.py b/backend/tests/integration_tests/test_extraction.py new file mode 100644 index 0000000..fb3b713 --- /dev/null +++ b/backend/tests/integration_tests/test_extraction.py @@ -0,0 +1,88 @@ +"""Makes it easy to run an integration tests using a real chat model.""" +from contextlib import asynccontextmanager +from typing import Optional + +import httpx +from fastapi import FastAPI +from httpx import AsyncClient +from langchain_core.pydantic_v1 import BaseModel + +from server.main import app + + +@asynccontextmanager +async def get_async_test_client( + server: FastAPI, *, path: Optional[str] = None, raise_app_exceptions: bool = True +) -> AsyncClient: + """Get an async client.""" + url = "http://localhost:9999/" + if path: + url += path + transport = httpx.ASGITransport( + app=server, + raise_app_exceptions=raise_app_exceptions, + ) + async_client = AsyncClient(app=server, base_url=url, transport=transport) + try: + yield async_client + finally: + await async_client.aclose() + + +async def test_extraction_api() -> None: + """Test the extraction API endpoint.""" + + class Person(BaseModel): + age: Optional[int] + name: Optional[str] + alias: Optional[str] + + async with get_async_test_client(app) as client: + text = """ + My name is Chester. I am young. I love cats. I have two cats. My age + is the number of cats I have to the power of 5. (Approximately.) + I also have a friend. His name is Neo. He is older than me. He is + also a cat lover. He has 3 cats. He is 25 years old. + """ + result = await client.post( + "/extract_text/invoke", + json={"input": {"text": text, "schema": Person.schema()}}, + ) + assert result.status_code == 200, result.text + response_data = result.json() + assert response_data == {} + assert isinstance(response_data["output"]["data"], list) + + # Test with instructions + result = await client.post( + "/extract_text/invoke", + json={ + "input": { + "text": text, + "schema": Person.schema(), + "instructions": "Very important: Chester's alias is Neo.", + } + }, + ) + response_data = result.json() + assert result.status_code == 200, result.text + + # Test with few shot examples + examples = [ + { + "text": "My name is Grung. I am 100.", + "output": [Person(age=100, name="######").dict()], + }, + ] + result = await client.post( + "/extract_text/invoke", + json={ + "input": { + "text": text, + "schema": Person(), + "instructions": "Redact all names using the characters `######`", + "examples": examples, + } + }, + ) + assert result.status_code == 200, result.text diff --git a/backend/tests/unit_tests/__init__.py b/backend/tests/unit_tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/unit_tests/api/__init__.py b/backend/tests/unit_tests/api/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/unit_tests/api/test_api_defining_extractors.py b/backend/tests/unit_tests/api/test_api_defining_extractors.py new file mode 100644 index 0000000..28e5ac0 --- /dev/null +++ b/backend/tests/unit_tests/api/test_api_defining_extractors.py @@ -0,0 +1,72 @@ +"""Code to test API endpoints.""" +import uuid + +from tests.db import get_async_client + + +async def test_extractors_api() -> None: + """This will test a few of the extractors API endpoints.""" + # First verify that the database is empty + async with get_async_client() as client: + response = await client.get("/extractors") + assert response.status_code == 200 + assert response.json() == [] + + # Verify that we can create an extractor + create_request = { + "description": "Test Description", + "schema": {"type": "object"}, + "instruction": "Test Instruction", + } + response = await client.post("/extractors", json=create_request) + assert response.status_code == 200 + + # Verify that the extractor was created + response = await client.get("/extractors") + assert response.status_code == 200 + assert len(response.json()) == 1 + + # Verify that we can delete an extractor + get_response = response.json() + uuid_str = get_response[0]["uuid"] + _ = uuid.UUID(uuid_str) # assert valid uuid + response = await client.delete(f"/extractors/{uuid_str}") + assert response.status_code == 200 + + get_response = await client.get("/extractors") + assert get_response.status_code == 200 + assert get_response.json() == [] + + # Verify that we can create an extractor + create_request = { + "description": "Test Description", + "schema": {"type": "object"}, + "instruction": "Test Instruction", + } + response = await client.post("/extractors", json=create_request) + assert response.status_code == 200 + + # Verify that the extractor was created + response = await client.get("/extractors") + assert response.status_code == 200 + assert len(response.json()) == 1 + + # Verify that we can delete an extractor + get_response = response.json() + uuid_str = get_response[0]["uuid"] + _ = uuid.UUID(uuid_str) # assert valid uuid + response = await client.delete(f"/extractors/{uuid_str}") + assert response.status_code == 200 + + get_response = await client.get("/extractors") + assert get_response.status_code == 200 + assert get_response.json() == [] + + # Verify that we can create an extractor + create_request = { + "description": "Test Description", + "schema": {"type": "object"}, + "instruction": "Test Instruction", + } + response = await client.post("/extractors", json=create_request) + assert response.status_code == 200 diff --git a/backend/tests/unit_tests/api/test_api_examples.py b/backend/tests/unit_tests/api/test_api_examples.py new file mode 100644 index 0000000..a078976 --- /dev/null +++ b/backend/tests/unit_tests/api/test_api_examples.py @@ -0,0 +1,76 @@ +"""Code to test API endpoints.""" + +from tests.db import get_async_client + + +async def _list_extractors() -> list: + async with get_async_client() as client: + response = await client.get("/extractors") + assert response.status_code == 200 + return response.json() + + +async def test_examples_api() -> None: + """Runs through a set of API calls to test the examples API.""" + async with get_async_client() as client: + # First create an extractor + create_request = { + "description": "Test Description", + "name": "Test Name", + "schema": {"type": "object"}, + "instruction": "Test Instruction", + } + response = await client.post("/extractors", json=create_request) + assert response.status_code == 200 + # Get the extractor id + extractor_id = response.json()["uuid"] + + # Let's verify that there are no examples + response = await client.get("/examples?extractor_id=" + extractor_id) + assert response.status_code == 200 + assert response.json() == [] + + # Now let's create an example + create_request = { + "extractor_id": extractor_id, + "content": "Test Content", + "output": [ + { + "age": 100, + "name": "Grung", + } + ], + } + response = await client.post("/examples", json=create_request) + assert response.status_code == 200 + example_id = response.json()["uuid"] + + # Verify that the example was created + response = await client.get("/examples?extractor_id=" + extractor_id) + assert response.status_code == 200 + assert len(response.json()) == 1 + + keys = ["content", "extractor_id", "output", "uuid"] + projected_response = { + key: record[key] for key in keys for record in response.json() + } + assert projected_response == { + "content": "Test Content", + "extractor_id": extractor_id, + "output": [ + { + "age": 100, + "name": "Grung", + } + ], + "uuid": example_id, + } + + # Verify that we can delete an example + response = await client.delete(f"/examples/{example_id}") + assert response.status_code == 200 + + # Verify that the example was deleted + response = await client.get("/examples?extractor_id=" + extractor_id) + assert response.status_code == 200 + assert response.json() == [] diff --git a/backend/tests/unit_tests/api/test_api_extract.py b/backend/tests/unit_tests/api/test_api_extract.py new file mode 100644 index 0000000..755e7cf --- /dev/null +++ b/backend/tests/unit_tests/api/test_api_extract.py @@ -0,0 +1,86 @@ +"""Code to test API endpoints.""" +import tempfile +from unittest.mock import patch +from uuid import UUID + +from langchain.text_splitter import CharacterTextSplitter +from langchain_core.runnables import RunnableLambda + +from tests.db import get_async_client + + +def mock_extraction_runnable(*args, **kwargs): + """Mock the extraction_runnable function.""" + extract_request = args[0] + return { + "data": [ + extract_request.text[:10], + ] + } + + +def mock_text_splitter(*args, **kwargs): + return CharacterTextSplitter() + + +@patch( + "server.extraction_runnable.extraction_runnable", + new=RunnableLambda(mock_extraction_runnable), +) +@patch("server.extraction_runnable.TokenTextSplitter", mock_text_splitter) +async def test_extract_from_file() -> None: + """Test extract from file API.""" + async with get_async_client() as client: + # Test with invalid extractor + extractor_id = UUID(int=1027) # 1027 is a good number. + response = await client.post( + "/extract", + data={ + "extractor_id": str(extractor_id), + "text": "Test Content", + }, + ) + assert response.status_code == 404, response.text + + # First create an extractor + create_request = { + "name": "Test Name", + "description": "Test Description", + "schema": {"type": "object"}, + "instruction": "Test Instruction", + } + response = await client.post("/extractors", json=create_request) + assert response.status_code == 200, response.text + # Get the extractor id + extractor_id = response.json()["uuid"] + + # Run an extraction. + # We'll use multi-form data here. + response = await client.post( + "/extract", + data={ + "extractor_id": extractor_id, + "text": "Test Content", + "mode": "entire_document", + }, + ) + assert response.status_code == 200 + assert response.json() == {"data": ["Test Conte"]} + + # We'll use multi-form data here. + # Create a named temporary file + with tempfile.NamedTemporaryFile(mode="w+t", delete=False) as f: + f.write("This is a named temporary file.") + f.seek(0) + f.flush() + response = await client.post( + "/extract", + data={ + "extractor_id": extractor_id, + "mode": "entire_document", + }, + files={"file": f}, + ) + + assert response.status_code == 200, response.text + assert response.json() == {"data": ["This is a "]} diff --git a/backend/tests/unit_tests/conftest.py b/backend/tests/unit_tests/conftest.py new file mode 100644 index 0000000..2529043 --- /dev/null +++ b/backend/tests/unit_tests/conftest.py @@ -0,0 +1,3 @@ +import os + +os.environ["OPENAI_API_KEY"] = "placeholder" diff --git a/backend/tests/unit_tests/fake/__init__.py b/backend/tests/unit_tests/fake/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/backend/tests/unit_tests/fake/chat_model.py b/backend/tests/unit_tests/fake/chat_model.py new file mode 100644 index 0000000..8fda560 --- /dev/null +++ b/backend/tests/unit_tests/fake/chat_model.py @@ -0,0 +1,45 @@ +"""Fake Chat Model wrapper for testing purposes.""" +from typing import Any, Iterator, List, Optional + +from langchain_core.callbacks.manager import ( + CallbackManagerForLLMRun, +) +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_core.messages import ( + AIMessage, + BaseMessage, +) +from langchain_core.outputs import ChatGeneration, ChatResult + + +class GenericFakeChatModel(BaseChatModel): + """A generic fake chat model that can be used to test the chat model interface.""" + + messages: Iterator[AIMessage] + """Get an iterator over messages. + + This can be expanded to accept other types like Callables / dicts / strings + to make the interface more generic if needed. + + Note: if you want to pass a list, you can use `iter` to convert it to an iterator. + + Please note that streaming is not implemented yet. We should try to implement it + in the future by delegating to invoke and then breaking the resulting output + into message chunks. + """ + + def _generate( + self, + messages: List[BaseMessage], + stop: Optional[List[str]] = None, + run_manager: Optional[CallbackManagerForLLMRun] = None, + **kwargs: Any, + ) -> ChatResult: + """Top Level call""" + message = next(self.messages) + generation = ChatGeneration(message=message) + return ChatResult(generations=[generation]) + + @property + def _llm_type(self) -> str: + return "generic-fake-chat-model" diff --git a/backend/tests/unit_tests/fake/test_fake_chat_model.py b/backend/tests/unit_tests/fake/test_fake_chat_model.py new file mode 100644 index 0000000..469b3d2 --- /dev/null +++ b/backend/tests/unit_tests/fake/test_fake_chat_model.py @@ -0,0 +1,30 @@ +"""Tests for verifying that testing utility code works as expected.""" +from itertools import cycle + +from langchain_core.messages import AIMessage + +from tests.unit_tests.fake.chat_model import GenericFakeChatModel + + +def test_generic_fake_chat_model_invoke() -> None: + # Will alternate between responding with hello and goodbye + infinite_cycle = cycle([AIMessage(content="hello"), AIMessage(content="goodbye")]) + model = GenericFakeChatModel(messages=infinite_cycle) + response = model.invoke("meow") + assert response == AIMessage(content="hello") + response = model.invoke("kitty") + assert response == AIMessage(content="goodbye") + response = model.invoke("meow") + assert response == AIMessage(content="hello") + + +async def test_generic_fake_chat_model_ainvoke() -> None: + # Will alternate between responding with hello and goodbye + infinite_cycle = cycle([AIMessage(content="hello"), AIMessage(content="goodbye")]) + model = GenericFakeChatModel(messages=infinite_cycle) + response = await model.ainvoke("meow") + assert response == AIMessage(content="hello") + response = await model.ainvoke("kitty") + assert response == AIMessage(content="goodbye") + response = await model.ainvoke("meow") + assert response == AIMessage(content="hello") diff --git a/backend/tests/unit_tests/fixtures/__init__.py b/backend/tests/unit_tests/fixtures/__init__.py new file mode 100644 index 0000000..e51d3bc --- /dev/null +++ b/backend/tests/unit_tests/fixtures/__init__.py @@ -0,0 +1,11 @@ +from pathlib import Path +from typing import List + +HERE = Path(__file__).parent + +# PUBLIC API + + +def get_sample_paths() -> List[Path]: + """List all fixtures.""" + return list(HERE.glob("sample.*")) diff --git a/backend/tests/unit_tests/fixtures/sample.docx b/backend/tests/unit_tests/fixtures/sample.docx new file mode 100644 index 0000000000000000000000000000000000000000..a45ff96daf510c99c07e6f76855d49569ce675a8 GIT binary patch literal 36715 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 YC*-d2 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 literal 0 HcmV?d00001 diff --git a/backend/tests/unit_tests/fixtures/sample.epub b/backend/tests/unit_tests/fixtures/sample.epub new file mode 100644 index 0000000000000000000000000000000000000000..db5a111200706fd25e631e3fe1b41ef7f0f4597f GIT binary patch literal 32134 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 literal 0 HcmV?d00001 diff --git a/backend/tests/unit_tests/fixtures/sample.html b/backend/tests/unit_tests/fixtures/sample.html new file mode 100644 index 0000000..42635ef --- /dev/null +++ b/backend/tests/unit_tests/fixtures/sample.html @@ -0,0 +1 @@ +

🦜️ LangChain

Underline

Bold

Italics

Col 1

Col 2

Row 1

1

2

Row 2

3

4

Link: https://www.langchain.com/

  • Item 1
  • Item 2
  • Item 3
  • We also love cats 🐱

Image

\ No newline at end of file diff --git a/backend/tests/unit_tests/fixtures/sample.odt b/backend/tests/unit_tests/fixtures/sample.odt new file mode 100644 index 0000000000000000000000000000000000000000..1eab5412c0cef0db0cac73cea397e7997c9215d4 GIT binary patch literal 42127 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 E0Tu<$ng9R* literal 0 HcmV?d00001 diff --git a/backend/tests/unit_tests/fixtures/sample.pdf b/backend/tests/unit_tests/fixtures/sample.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7c60310c3e63e543204f9e3150d4237634fde438 GIT binary patch literal 79140 zcmeEug;$kZ*ROOVNH-$g9a0j~NC*Pb-O`O9-Jp~p2m*@I-Q6LG2-4jkjS_-zC+~aj z_{JUM{t4G{#yJPv@$B`?HRrF^W>A-v@>+WDl z%j{SW&U~)O)Kx@WDO6LbuxFO)wFzJVd-k= z$|50w3IBWhN__wGisq)YJeXY4s60&Di8PnysVawvn4H;u9}&hrMWvi&%@09 zKfh6QG_{7O>)2Yj+t7*#@ndo+SlU|KxYP1-3u1D~I5{}EK6N%Vhv&*#dfJ*>YRXH) zo7uX%sav|rI5|2yy|8@YPAiPbC1>m44vWJj=V0n?DQju&WC1U$V)?=vUYA!uh?`$R zg4WI5)zZ`v(>rsw#lxR);N+$aA01g5T`Jfw7&#c#%j@np7h#gQ_5Nkwh^}Q^G%sPw z`}IvtsAqRDUcX)oUHnz`@8wyUlc%-kgpi{6%@V$+eWSfqQ&Ev$V^QnN2k61H|No!= zYXv&Z#9sb&KUiovo%la%bC2le`qF8>(ZhcHOOWJl36>Nd^6fwL)JDzT%R4&{{Z1YH z*rfmaOFYkwgSMOan3yKtKRaPqBxYu2hsJJ78T_`Il@gY4UuCS?g&$QjPJet-P8@+>juhJeEF_}JrT_1`-+R~>PZi=e+w9|J zxOv(WLsFpmX+>Xj3A>1$PeMWhu9-^IbDYC%vGrwf`%pUHVuPFfmEHN_vOg0>HSb0I z?W<%Uhz6c)sQTH%ZCU={zWoCwtE8yNK8Bcs?!g0w#duPlV81r!MD5fDx6LR0zv4cM zTMdyK(HgiM6)`BM9+okxzO$IwyS)Xq7VCp4+%siHEtPe2@H1{7+>hB0Qb_xY*XOGV z_kzUzP7j@!RMI|F4t@CW0j}qlAyT%)%ZFU$@(I){I&D|SSU0Tn^xbP2bZ})3NZ0|x z?*vXZN7VGM;b-?CM~CT3hBK!K912GKdancOn_9&rMmq;vEv@8?40xlE-vJb4WP0T$ zQpu^DhK>4lFQSZbD1~27*1Wv*Omd1gxviJc(NXJfnebt7t;G3p?}g$#YKuuoXoH&x z71tW@ZzruI`NPi`60Rqi!bjKt{P+Z#18*eQPp2x(iFTr6VnqE;*|G7jorln%YE8xA zc|Bc!xA$xOE{++_0*aoM6!z-tSKHu+@_g^dX#df9lr*KEoGBR?@J!=drikfl)h4Qy zj8oGW^Nlq&qq&@%oV#xr)v}spqwd*H6yJv`EbhBF*<{lxEv8^2;;d`Yz6_L=lY_Sr zc$%*=SAKbZUj1VJp_tfQHDci3Z6?Cw!)2M4MWeQW7I;j#WO3$ zX$9SOwuL&U#ebJ)9&Ha@*U*Lf;YRT55?)zj^B*3?8rH){Lo4bT7_gnKb(Awyj_mI3 zHKXrIVpsq0sP4slaBwhp;xP?=+qV$3ySpV1r0AvdRWrgH98=l#zHj@U?Q?8k^}iQA z%aMuLEm^ALv;Jl=lJ$N%DB$1UWn'SJfT$$;hx6tj)}U%&M8RmfUU1Fx?xm?dSx zvBiCV>$dt|f(?sNiz2ATDZm{`b$XSTa6hcHP6> z>8f3Vv`C#YBNS9r*9VgJ6YP0|(Bb$?--)>8@9U)LEfpakq55B)zX^=A4&Ih5!lD+| z;@yl#@AN0;H0UQ^`}1pZuLR2!%Op$}@vTvduSlm=ZCVVed^gw<%(%ajSnp z{#6tKQ#`eJqj_Ka9FmypTIBR|CR=Xnj-*UM$9MZWb6H>f#ij5VBp{owLSDXrVpfr4#BhMiQY+PVmI_|C7I=W(L`)J zy>nGONla>1aopO4T6VRR?TvpgF0_lDsSfks=j4n(ptEw{8CSe#n!%lFHT-T_F<&t$ zADVMw8FzP8)fa4+oG4m!HjAaND`4OZ~dSaXdCjMzX|LQSz1F;wD}d-KCK@EQ3qhK(|+t{b6ym(!;;1 zTshb1ft8QZ7GPpR8=KfN?)`fUU$l2+ZLQk!E3v@aOko$qV=NL*Ej<)b@(XC^@KKKa zlcA6WWq#4)7|WaOF0|;=al5W5T$e1^Y$8jg-3jDD>y0IQaN+rDqU1_Hr9zVfSMs8C zG;8TKr9vo`rZ5(OKmY#yd+5>j(s5}| z3Av0iYp$rped#+=6ZCsOgaq=S_u5Cr#PIEiEFH7!RUT?U8??NK;NRIMu>6}qieBRS zXK-ss09wRr5Ai%Y^QGh7IEs_3pG{s)QSCpAbS~;x%|AWQtg)YTrD|?zVGxR(<6qKN5!XQM&e1cdkZao4JfJfHHve)Gd1?z zk@$vjM5w&^vm8*?Zn=nB!i{&Zfya;)K>UC%YHknz2C~ahD zUpk+)w6ydRUgw;4fhGejEv?u7oRN{y7S(%EFG0H!4;Zz@`VIBk_) zt-}cH(Wjr3K8^O)jXP$`YMR4^`jd61mQ4j*9m#9KcJulB+xCynztdT#db>Y6KN%-4 zx5t>MX^;$B{ioM*WlauOS5^R!lePF2X9vBh#-;mHFK8lRH$?0l~Jh*j~ie}w+_k59HDZ_0VnPB(_qpXP~c z2Q}2T{Jg(=w^$vpPMSvLbkp_v*SGf7M{nul_a&dNl?E5$PzbtvdEFeZ$GBd+zWP(C4pM}9TjiNYf-QLASASze^V@hJ~<>UNOc3%Hlx8rzgAYvW*BLL z6)44gj%9NeOP<#Z274Ukt()9j|08Cf){I0Wr4V}I@Esxi5p*10>u(NP%tX59P!(0r zk2i)duP)q9su|H&U#)7?I_OOxZVqQyJ9(hX-)Ciw_KVsPa!tdY?bEM!HXWFinfm$A zV<(wS=gBuj^Q^74wecJowDn_iGqagGr))vTnM4NV&aPyCEKviPD=!W`j9tjT?))sO zvi#bs)HQdXoBQ?6+tt-oBpy-D5-3J2^VIBYn%Q)�T=YSiQ(iUI$rKReWq@PqCGW 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

uBn|l=i@NGBBem>v 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�b#X)rM{` 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 i2ZPL9T$VL({?z4hB;!cr None: + """Test deduplication of extraction results.""" + result = _deduplicate( + [ + {"data": [{"name": "Chester", "age": 42}]}, + {"data": [{"name": "Jane", "age": 42}]}, + ] + ) + expected = ExtractResponse( + data=[ + {"name": "Chester", "age": 42}, + {"name": "Jane", "age": 42}, + ] + ) + assert expected == result + + result = _deduplicate( + [ + { + "data": [ + {"field_1": 1, "field_2": "a"}, + {"field_1": 2, "field_2": "b"}, + ] + }, + { + "data": [ + {"field_1": 1, "field_2": "a"}, + {"field_1": 2, "field_2": "c"}, + ] + }, + ] + ) + + expected = ExtractResponse( + data=[ + {"field_1": 1, "field_2": "a"}, + {"field_1": 2, "field_2": "b"}, + {"field_1": 2, "field_2": "c"}, + ] + ) + assert expected == result + + # Test with data being a list of strings + result = _deduplicate([{"data": ["1", "2"]}, {"data": ["1", "3"]}]) + expected = ExtractResponse(data=["1", "2", "3"]) + assert expected == result + + # Test with data being a mix of integer and string + result = _deduplicate([{"data": [1, "2"]}, {"data": ["1", "3"]}]) + expected = ExtractResponse(data=[1, "2", "1", "3"]) + assert expected == result diff --git a/backend/tests/unit_tests/test_parsing.py b/backend/tests/unit_tests/test_parsing.py new file mode 100644 index 0000000..a98c198 --- /dev/null +++ b/backend/tests/unit_tests/test_parsing.py @@ -0,0 +1,46 @@ +"""Test parsing logic.""" +import mimetypes + +from langchain.document_loaders import Blob + +from extraction.parsing import ( + MIMETYPE_BASED_PARSER, + SUPPORTED_MIMETYPES, +) +from tests.unit_tests.fixtures import get_sample_paths + + +def test_list_of_supported_mimetypes() -> None: + """This list should generally grow! Protecting against typos in mimetypes.""" + assert SUPPORTED_MIMETYPES == [ + # Two MS Word mimetypes are disabled for now + # Need to install unstructured to enable them + # "application/msword", + "application/pdf", + # "application/vnd.openxmlformats-officedocument.wordprocessingml.document", + "text/html", + "text/plain", + ] + + +def test_attempt_to_parse_each_fixture() -> None: + """Attempt to parse supported fixtures.""" + seen_mimetypes = set() + for path in get_sample_paths(): + type_, _ = mimetypes.guess_type(path) + if type_ not in SUPPORTED_MIMETYPES: + continue + seen_mimetypes.add(type_) + blob = Blob.from_path(path) + documents = MIMETYPE_BASED_PARSER.parse(blob) + try: + assert len(documents) == 1 + doc = documents[0] + assert "source" in doc.metadata + assert doc.metadata["source"] == str(path) + assert "🦜" in doc.page_content + except Exception as e: + raise AssertionError(f"Failed to parse {path}") from e + + known_missing = {"application/msword"} + assert set(SUPPORTED_MIMETYPES) - known_missing == seen_mimetypes diff --git a/backend/tests/unit_tests/test_upload.py b/backend/tests/unit_tests/test_upload.py new file mode 100644 index 0000000..fc48319 --- /dev/null +++ b/backend/tests/unit_tests/test_upload.py @@ -0,0 +1,22 @@ +from extraction.parsing import _guess_mimetype +from tests.unit_tests.fixtures import get_sample_paths + + +async def test_mimetype_guessing() -> None: + """Verify mimetype guessing for all fixtures.""" + name_to_mime = {} + for file in sorted(get_sample_paths()): + data = file.read_bytes() + name_to_mime[file.name] = _guess_mimetype(data) + + assert { + "sample.docx": ( + "application/vnd.openxmlformats-officedocument.wordprocessingml.document" + ), + "sample.epub": "application/epub+zip", + "sample.html": "text/html", + "sample.odt": "application/vnd.oasis.opendocument.text", + "sample.pdf": "application/pdf", + "sample.rtf": "text/rtf", + "sample.txt": "text/plain", + } == name_to_mime diff --git a/backend/tests/unit_tests/test_utils.py b/backend/tests/unit_tests/test_utils.py new file mode 100644 index 0000000..be96d58 --- /dev/null +++ b/backend/tests/unit_tests/test_utils.py @@ -0,0 +1,104 @@ +from typing import List + +import pytest +from langchain.pydantic_v1 import BaseModel, Field + +from extraction.utils import ( + convert_json_schema_to_openai_schema, +) +from server.extraction_runnable import ExtractionExample, _make_prompt_template + + +def test_convert_json_schema_to_openai_schema() -> None: + """Test converting a JSON schema to an OpenAI schema.""" + + class Person(BaseModel): + name: str = Field(..., description="The name of the person.") + age: int = Field(..., description="The age of the person.") + + schema = Person.schema() + + assert schema == { + "properties": { + "age": { + "description": "The age of the person.", + "title": "Age", + "type": "integer", + }, + "name": { + "description": "The name of the person.", + "title": "Name", + "type": "string", + }, + }, + "required": ["name", "age"], + "title": "Person", + "type": "object", + } + + openai_schema = convert_json_schema_to_openai_schema(schema) + assert openai_schema == { + "description": "Extract information matching the given schema.", + "name": "extractor", + "parameters": { + "properties": { + "data": { + "items": { + "properties": { + "age": { + "description": "The age of the person.", + "type": "integer", + }, + "name": { + "description": "The name of the person.", + "type": "string", + }, + }, + "required": ["name", "age"], + "type": "object", + }, + "type": "array", + } + }, + "required": ["data"], + "type": "object", + }, + } + + +def test_make_prompt_template() -> None: + """Test making a system message from instructions and examples.""" + instructions = "Test instructions." + examples = [ + ExtractionExample( + text="Test text.", + output=[ + {"name": "Test Name", "age": 0}, + {"name": "Test Name 2", "age": 1}, + ], + ) + ] + prefix = ( + "You are a top-tier algorithm for extracting information from text. " + "Only extract information that is relevant to the provided text. " + "If no information is relevant, use the schema and output " + "an empty list where appropriate." + ) + prompt = _make_prompt_template(instructions, examples, "name") + messages = prompt.messages + assert 4 == len(messages) + system = messages[0].prompt.template + assert system.startswith(prefix) + assert system.endswith(instructions) + + example_input = messages[1] + assert example_input.content == "Test text." + example_output = messages[2] + assert "function_call" in example_output.additional_kwargs + assert example_output.additional_kwargs["function_call"]["name"] == "name" + + prompt = _make_prompt_template(instructions, None, "name") + assert 2 == len(prompt.messages) + + prompt = _make_prompt_template(None, examples, "name") + assert 4 == len(prompt.messages) diff --git a/backend/tests/unit_tests/test_validators.py b/backend/tests/unit_tests/test_validators.py new file mode 100644 index 0000000..3d7c778 --- /dev/null +++ b/backend/tests/unit_tests/test_validators.py @@ -0,0 +1,16 @@ +import pytest + +from server.validators import validate_json_schema + + +def test_validate_json_schema() -> None: + """Test validate_json_schema.""" + # TODO: Validate more extensively to make sure that it actually validates + # the schema as expected. + with pytest.raises(Exception): + validate_json_schema({"type": "meow"}) + + with pytest.raises(Exception): + validate_json_schema({"type": "str"}) + + validate_json_schema({"type": "string"}) diff --git a/backend/tests/unit_tests/utils.py b/backend/tests/unit_tests/utils.py new file mode 100644 index 0000000..013aeeb --- /dev/null +++ b/backend/tests/unit_tests/utils.py @@ -0,0 +1,25 @@ +from contextlib import asynccontextmanager +from typing import Optional + +import httpx +from fastapi import FastAPI +from httpx import AsyncClient + + +@asynccontextmanager +async def get_async_test_client( + server: FastAPI, *, path: Optional[str] = None, raise_app_exceptions: bool = True +) -> AsyncClient: + """Get an async client.""" + url = "http://localhost:9999/" + if path: + url += path + transport = httpx.ASGITransport( + app=server, + raise_app_exceptions=raise_app_exceptions, + ) + async_client = AsyncClient(app=server, base_url=url, transport=transport) + try: + yield async_client + finally: + await async_client.aclose() diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..e8ecd40 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,30 @@ +version: "3" +name: langchain-extract + +services: + postgres: + # Careful if bumping postgres version. + # Make sure to keep in sync with CI + # version if being tested on CI. + image: postgres:16 + ports: + - "5432:5432" + environment: + POSTGRES_DB: langchain + POSTGRES_USER: langchain + POSTGRES_PASSWORD: langchain + volumes: + - postgres_data:/var/lib/postgresql/data + +# For rely on docker compose to spin up postgres +# but developer using docker +# Add backend when we actually need it +# backend: +# build: ./backend +# ports: +# - "8000:8000" +# depends_on: +# - postgres + +volumes: + postgres_data: