From e025517e4dccdaee2e721259095f79e67bb82d1d Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Tue, 21 Mar 2023 06:25:13 -0600 Subject: [PATCH 01/15] Update backend dependencies `requirements.txt` now has sections. These sections are intended to make it easier to know why a dependency is added. Some dependency updates required changes to the backend. Of note, flask_script is no longer supported and flask includes its own cli. Some effort was taken to ensure that existing scripts will still work, but users should update their scripts as soon as possible. * Added * blinker * charset-normalizer * mypy-extensions * numpy * packaging * pathspec * platformdirs * pytz-deprecation-shim * typing_extensions * tzdata * tzlocal * zipp * zope.event * zope.interface * Removed * Flask-Script * Unidecode * appdirs * attrs * chardet * entrypoints * glob2 * newrelic * pyparsing * pyproj * python-editor * toml Signed-off-by: Taylor Smock --- .flaskenv | 5 + docker-compose.yml | 2 +- docs-old/migration.md | 2 +- docs-old/review-pr.md | 6 +- docs-old/setup-development.md | 8 +- docs/developers/development-setup.md | 8 +- manage.py | 40 +- pdm.lock | 1580 ++++++++--------- pyproject.toml | 117 +- requirements.txt | 146 +- .../tasking-manager.template.js | 2 +- .../database/export-import-projects/README | 2 +- .../database/migration-from-tm2-postgres.sql | 2 +- scripts/docker/tasking-manager/Dockerfile | 9 +- .../install/install_on_debian_10_buster.sh | 4 +- scripts/install/install_on_ubuntu_18_04.sh | 6 +- .../integration/api/users/test_actions.py | 2 +- 17 files changed, 927 insertions(+), 1014 deletions(-) create mode 100644 .flaskenv diff --git a/.flaskenv b/.flaskenv new file mode 100644 index 0000000000..7800b14d16 --- /dev/null +++ b/.flaskenv @@ -0,0 +1,5 @@ +# This file is not read for Tasking Manager variables. Use tasking-manager.env instead. +# Flask (the web server framework) uses this file to figure out what the entry point is, +# if it is non-standard. +# For more information, see https://flask.palletsprojects.com/en/2.0.x/cli/#environment-variables-from-dotenv +FLASK_APP=manage.py diff --git a/docker-compose.yml b/docker-compose.yml index 1032c4b914..28af69935d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,7 +25,7 @@ services: <<: *backend container_name: migration restart: on-failure - command: python manage.py db upgrade + command: flask db upgrade frontend: image: hotosm-tasking-manager:frontend diff --git a/docs-old/migration.md b/docs-old/migration.md index afa485b8f6..e37eb2caf1 100644 --- a/docs-old/migration.md +++ b/docs-old/migration.md @@ -11,7 +11,7 @@ $ `psql -d myDataBase -a -f scripts/database/duplicate-priority-area-cleanup.sql Now, migrating from version 3 to version 4 can be done through the build in alembic migrations by simply running: -$ `python manage.py db upgrade` or `pdm run upgrade` +$ `flask db upgrade` or `pdm run upgrade` Depending on the size of your database this might take a good while. diff --git a/docs-old/review-pr.md b/docs-old/review-pr.md index 75e3aa6b31..eb0e699ad5 100644 --- a/docs-old/review-pr.md +++ b/docs-old/review-pr.md @@ -64,7 +64,7 @@ and ask the person to check on the error. * ```pip install --upgrade pdm``` * ```pdm export --without-hashes > requirements.txt``` * ```pip install requirements.txt``` - b. introduced database migrations: `python manage.py db upgrade` + b. introduced database migrations: `flask db upgrade` c. frontend dependency installation: `cd frontend && yarn && cd ..` d. rebuild the frontend: `cd frontend && yarn build && cd ..` @@ -134,7 +134,7 @@ This is important to do even if there are no frontend changes because you may ha Upgrade the database (it may be wise to back up your database first): -`python manage.py db upgrade` or `pdm run upgrade` +`flask db upgrade` or `pdm run upgrade` If you get an error, you may have an upgraded database from a prior PR. Try downgrading to develop (`python manage.py db downgrade`). @@ -169,7 +169,7 @@ After reviewing, you'll want to downgrade your database, return to develop, and # so if a PR contains multiple revisions, # you may have to run this command more than once -python manage.py db downgrade or pdm run downgrade +flask db downgrade or pdm run downgrade # _now_ you can return to develop. # if you do before downgrading, flask_migrate will not diff --git a/docs-old/setup-development.md b/docs-old/setup-development.md index 42cecbb362..150f5e1460 100644 --- a/docs-old/setup-development.md +++ b/docs-old/setup-development.md @@ -129,7 +129,7 @@ cd frontend && yarn build-locales We use [Flask-Migrate](https://flask-migrate.readthedocs.io/en/latest/) to create the database from the migrations directory. Check the instructions on how to setup a PostGIS database with [docker](#creating-a-local-postgis-database-with-docker) or on your [local system](#non-docker). Then you can execute the following command to apply the migrations: ``` -python3 manage.py db upgrade +flask db upgrade ``` or ``` @@ -150,7 +150,7 @@ To be able to create projects and have full permissions as an admin user inside If you plan to only work on the API you only have to build the backend architecture. Install the backend dependencies, and run the server: -`python3 manage.py runserver -d -r` or `pdm run start` +`flask run --debug --reload` or `pdm run start` You can access the API documentation on [http://localhost:5000/api-docs](http://localhost:5000/api-docs), it also allows you to execute requests on your local TM instance. The API docs is also available on our [production](https://tasks.hotosm.org/api-docs) and [staging](https://tasks-stage.hotosm.org/api-docs/) instances. @@ -158,10 +158,10 @@ You can access the API documentation on [http://localhost:5000/api-docs](http:// In order to authenticate on the API, you need to have an Authorization Token. -1. Run the command line `manage.py` with the `gen_token` option and `-u `. The command line can be run in any shell session as long as you are in the tasking-manager directory. +1. Run the command line `manage.py` via `flask` with the `gen_token` option and `-u `. The command line can be run in any shell session as long as you are in the tasking-manager directory. ``` -python manage.py gen_token -u 99999999 +flask gen_token -u 99999999 ``` This will generate a line that looks like this: diff --git a/docs/developers/development-setup.md b/docs/developers/development-setup.md index 6337814878..2419ffa46e 100644 --- a/docs/developers/development-setup.md +++ b/docs/developers/development-setup.md @@ -137,7 +137,7 @@ cd frontend && yarn build-locales We use [Flask-Migrate](https://flask-migrate.readthedocs.io/en/latest/) to create the database from the migrations directory. Check the instructions on how to setup a PostGIS database with [docker](#creating-a-local-postgis-database-with-docker) or on your [local system](#non-docker). Then you can execute the following command to apply the migrations: ``` -python3 manage.py db upgrade +flask db upgrade ``` or ``` @@ -154,7 +154,7 @@ To be able to create projects and have full permissions as an admin user inside If you plan to only work on the API you only have to build the backend architecture. Install the backend dependencies, and run the server: -`python3 manage.py runserver -d -r ` or `pdm run start` +`flask run --debug --reload` or `pdm run start` You can access the API documentation on [http://localhost:5000/api-docs](http://localhost:5000/api-docs), it also allows you to execute requests on your local TM instance. The API docs is also available on our [production](https://tasks.hotosm.org/api-docs) and [staging](https://tasks-stage.hotosm.org/api-docs/) instances. @@ -162,10 +162,10 @@ You can access the API documentation on [http://localhost:5000/api-docs](http:// In order to authenticate on the API, you need to have an Authorization Token. -1. Run the command line `manage.py` with the `gen_token` option and `-u `. The command line can be run in any shell session as long as you are in the tasking-manager directory. +1. Run the command line `manage.py` via `flask` with the `gen_token` option and `-u `. The command line can be run in any shell session as long as you are in the tasking-manager directory. ``` -python manage.py gen_token -u 99999999 +flask gen_token -u 99999999 ``` This will generate a line that looks like this: diff --git a/manage.py b/manage.py index a2d5d0334e..6a3366945f 100644 --- a/manage.py +++ b/manage.py @@ -4,10 +4,10 @@ import csv import datetime -from flask_migrate import MigrateCommand -from flask_script import Manager +import click +from flask_migrate import Migrate from dotenv import load_dotenv -from backend import create_app, initialise_counters +from backend import create_app, initialise_counters, db from backend.services.users.authentication_service import AuthenticationService from backend.services.users.user_service import UserService from backend.services.stats_service import StatsService @@ -47,14 +47,13 @@ warnings.warn("Homepage counters not initialized.") # Add management commands -manager = Manager(application) # Enable db migrations to be run via the command line -manager.add_command("db", MigrateCommand) +migrate = Migrate(application, db) # Job runs once every 2 hours -@manager.command +@application.cli.command("auto_unlock_tasks") def auto_unlock_tasks(): with application.app_context(): # Identify distinct project IDs that were touched in the last 2 hours @@ -84,7 +83,8 @@ def auto_unlock_tasks(): atexit.register(lambda: cron.shutdown(wait=False)) -@manager.option("-u", "--user_id", help="Test User ID") +@application.cli.command("gen_token") +@click.option("-u", "--user_id", help="Test User ID") def gen_token(user_id): """Helper method for generating valid base64 encoded session tokens""" token = AuthenticationService.generate_session_token_for_user(user_id) @@ -93,21 +93,22 @@ def gen_token(user_id): print(f"Your base64 encoded session token: {b64_token}") -@manager.command +@application.cli.command("refresh_levels") def refresh_levels(): print("Started updating mapper levels...") users_updated = UserService.refresh_mapper_level() print(f"Updated {users_updated} user mapper levels") -@manager.command +@application.cli.command("refresh_project_stats") def refresh_project_stats(): print("Started updating project stats...") StatsService.update_all_project_stats() print("Project stats updated") -@manager.command +@application.cli.command("update_project_categories") +@click.argument("filename") def update_project_categories(filename): with open(filename, "r", encoding="ISO-8859-1", newline="") as csvfile: reader = csv.DictReader(csvfile) @@ -132,4 +133,21 @@ def update_project_categories(filename): if __name__ == "__main__": - manager.run() + # This is compatibility code with previous releases + # People should generally prefer `flask `. + from sys import argv + from flask.cli import FlaskGroup + from click import Command + + cli = FlaskGroup(create_app=lambda: application) + cli.add_command( + cmd=Command( + name="runserver", + callback=application.run, + help='Deprecated, use "flask run" instead', + ) + ) + if argv[1] == "runserver": + application.run() + else: + cli() diff --git a/pdm.lock b/pdm.lock index 38f6717636..f4d2f8aeaf 100644 --- a/pdm.lock +++ b/pdm.lock @@ -3,44 +3,32 @@ [[package]] name = "alembic" -version = "1.4.3" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "1.11.1" +requires_python = ">=3.7" summary = "A database migration tool for SQLAlchemy." dependencies = [ "Mako", - "SQLAlchemy>=1.1.0", - "python-dateutil", - "python-editor>=0.3", + "SQLAlchemy>=1.3.0", + "typing-extensions>=4", ] [[package]] name = "aniso8601" -version = "8.0.0" +version = "9.0.1" summary = "A library for parsing ISO 8601 strings." -[[package]] -name = "appdirs" -version = "1.4.4" -summary = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." - [[package]] name = "apscheduler" -version = "3.7.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "3.10.1" +requires_python = ">=3.6" summary = "In-process task scheduler with Cron-like capabilities" dependencies = [ "pytz", "setuptools>=0.7", "six>=1.4.0", - "tzlocal~=2.0", + "tzlocal!=3.*,>=2.0", ] -[[package]] -name = "attrs" -version = "20.2.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -summary = "Classes Without Boilerplate" - [[package]] name = "black" version = "23.3.0" @@ -58,7 +46,7 @@ dependencies = [ [[package]] name = "bleach" -version = "5.0.1" +version = "6.0.0" requires_python = ">=3.7" summary = "An easy safelist-based HTML-sanitizing tool." dependencies = [ @@ -68,19 +56,20 @@ dependencies = [ [[package]] name = "blinker" -version = "1.5" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "1.6.2" +requires_python = ">=3.7" summary = "Fast, simple object-to-object and broadcast signaling" [[package]] name = "cachetools" -version = "4.1.1" -requires_python = "~=3.5" +version = "5.3.0" +requires_python = "~=3.7" summary = "Extensible memoizing collections and decorators" [[package]] name = "certifi" -version = "2020.6.20" +version = "2023.5.7" +requires_python = ">=3.6" summary = "Python package for providing Mozilla's CA Bundle." [[package]] @@ -91,15 +80,10 @@ dependencies = [ "pycparser", ] -[[package]] -name = "chardet" -version = "3.0.4" -summary = "Universal encoding detector for Python 2 and 3" - [[package]] name = "charset-normalizer" -version = "2.0.12" -requires_python = ">=3.5.0" +version = "3.1.0" +requires_python = ">=3.7.0" summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." [[package]] @@ -119,42 +103,38 @@ summary = "Cross-platform colored terminal text." [[package]] name = "coverage" -version = "6.4" +version = "7.2.5" requires_python = ">=3.7" summary = "Code coverage measurement for Python" -[[package]] -name = "entrypoints" -version = "0.3" -requires_python = ">=2.7" -summary = "Discover and load entry points from installed packages." - [[package]] name = "flake8" -version = "3.8.4" -requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" +version = "6.0.0" +requires_python = ">=3.8.1" summary = "the modular source code checker: pep8 pyflakes and co" dependencies = [ - "mccabe<0.7.0,>=0.6.0", - "pycodestyle<2.7.0,>=2.6.0a1", - "pyflakes<2.3.0,>=2.2.0", + "mccabe<0.8.0,>=0.7.0", + "pycodestyle<2.11.0,>=2.10.0", + "pyflakes<3.1.0,>=3.0.0", ] [[package]] name = "flask" -version = "1.1.2" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "2.3.2" +requires_python = ">=3.8" summary = "A simple framework for building complex web applications." dependencies = [ - "Jinja2>=2.10.1", - "Werkzeug>=0.15", - "click>=5.1", - "itsdangerous>=0.24", + "Jinja2>=3.1.2", + "Werkzeug>=2.3.3", + "blinker>=1.6.2", + "click>=8.1.3", + "importlib-metadata>=3.6.0; python_version < \"3.10\"", + "itsdangerous>=2.1.2", ] [[package]] name = "flask-cors" -version = "3.0.9" +version = "3.0.10" summary = "A Flask extension adding a decorator for CORS support" dependencies = [ "Flask>=0.9", @@ -163,10 +143,10 @@ dependencies = [ [[package]] name = "flask-httpauth" -version = "4.1.0" -summary = "Basic and Digest HTTP authentication for Flask routes" +version = "4.8.0" +summary = "HTTP authentication for Flask routes" dependencies = [ - "Flask", + "flask", ] [[package]] @@ -180,17 +160,18 @@ dependencies = [ [[package]] name = "flask-migrate" -version = "2.5.3" -summary = "SQLAlchemy database migrations for Flask applications using Alembic" +version = "4.0.4" +requires_python = ">=3.6" +summary = "SQLAlchemy database migrations for Flask applications using Alembic." dependencies = [ "Flask-SQLAlchemy>=1.0", "Flask>=0.9", - "alembic>=0.7", + "alembic>=1.9.0", ] [[package]] name = "flask-restful" -version = "0.3.8" +version = "0.3.9" summary = "Simple framework for creating REST APIs" dependencies = [ "Flask>=0.8", @@ -199,22 +180,14 @@ dependencies = [ "six>=1.3.0", ] -[[package]] -name = "flask-script" -version = "2.0.6" -summary = "Scripting support for Flask" -dependencies = [ - "Flask", -] - [[package]] name = "flask-sqlalchemy" -version = "2.4.4" -requires_python = ">= 2.7, != 3.0.*, != 3.1.*, != 3.2.*, != 3.3.*" -summary = "Adds SQLAlchemy support to your Flask application." +version = "3.0.3" +requires_python = ">=3.7" +summary = "Add SQLAlchemy support to your Flask application." dependencies = [ - "Flask>=0.10", - "SQLAlchemy>=0.8.0", + "Flask>=2.2", + "SQLAlchemy>=1.4.18", ] [[package]] @@ -228,59 +201,68 @@ dependencies = [ [[package]] name = "geoalchemy2" -version = "0.8.4" +version = "0.13.3" +requires_python = ">=3.7" summary = "Using SQLAlchemy with Spatial Databases" dependencies = [ - "SQLAlchemy>=0.8", + "SQLAlchemy>=1.4", + "packaging", ] [[package]] name = "geojson" -version = "1.3.4" +version = "3.0.1" +requires_python = ">=3.7, <3.12" summary = "Python bindings and utilities for GeoJSON" [[package]] name = "gevent" -version = "21.12.0" +version = "22.10.2" requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5" summary = "Coroutine-based network library" dependencies = [ "cffi>=1.12.2; platform_python_implementation == \"CPython\" and sys_platform == \"win32\"", - "greenlet<2.0,>=1.1.0; platform_python_implementation == \"CPython\"", + "greenlet>=2.0.0; platform_python_implementation == \"CPython\"", "setuptools", "zope-event", "zope-interface", ] -[[package]] -name = "glob2" -version = "0.7" -summary = "Version of the glob module that can capture patterns and supports recursive wildcards" - [[package]] name = "greenlet" -version = "1.1.2" +version = "2.0.2" requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" summary = "Lightweight in-process concurrent programming" [[package]] name = "gunicorn" -version = "20.0.4" -requires_python = ">=3.4" +version = "20.1.0" +requires_python = ">=3.5" summary = "WSGI HTTP Server for UNIX" dependencies = [ "setuptools>=3.0", ] +[[package]] +name = "gunicorn" +version = "20.1.0" +extras = ["gevent"] +requires_python = ">=3.5" +summary = "WSGI HTTP Server for UNIX" +dependencies = [ + "gevent>=1.4.0", + "gunicorn==20.1.0", +] + [[package]] name = "idna" -version = "2.10" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.4" +requires_python = ">=3.5" summary = "Internationalized Domain Names in Applications (IDNA)" [[package]] name = "importlib-metadata" -version = "4.13.0" +version = "6.6.0" requires_python = ">=3.7" summary = "Read metadata from Python packages" dependencies = [ @@ -289,22 +271,22 @@ dependencies = [ [[package]] name = "itsdangerous" -version = "1.1.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -summary = "Various helpers to pass data to untrusted environments and back." +version = "2.1.2" +requires_python = ">=3.7" +summary = "Safely pass data to untrusted environments and back." [[package]] name = "jinja2" -version = "2.11.3" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" +version = "3.1.2" +requires_python = ">=3.7" summary = "A very fast and expressive template engine." dependencies = [ - "MarkupSafe>=0.23", + "MarkupSafe>=2.0", ] [[package]] name = "mako" -version = "1.2.2" +version = "1.2.4" requires_python = ">=3.7" summary = "A super-fast templating language that borrows the best ideas from the existing templating languages." dependencies = [ @@ -313,19 +295,23 @@ dependencies = [ [[package]] name = "markdown" -version = "3.3.3" -requires_python = ">=3.6" -summary = "Python implementation of Markdown." +version = "3.4.3" +requires_python = ">=3.7" +summary = "Python implementation of John Gruber's Markdown." +dependencies = [ + "importlib-metadata>=4.4; python_version < \"3.10\"", +] [[package]] name = "markupsafe" -version = "1.1.1" -requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "2.1.2" +requires_python = ">=3.7" summary = "Safely add untrusted strings to HTML/XML markup." [[package]] name = "mccabe" -version = "0.6.1" +version = "0.7.0" +requires_python = ">=3.6" summary = "McCabe checker, plugin for flake8" [[package]] @@ -334,20 +320,20 @@ version = "1.0.0" requires_python = ">=3.5" summary = "Type system extensions for programs checked with the mypy type checker." -[[package]] -name = "newrelic" -version = "8.8.0" -requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" -summary = "New Relic Python Agent" - [[package]] name = "nose" version = "1.3.7" summary = "nose extends unittest to make testing easier" +[[package]] +name = "numpy" +version = "1.24.3" +requires_python = ">=3.8" +summary = "Fundamental package for array computing in Python" + [[package]] name = "oauthlib" -version = "3.2.0" +version = "3.2.2" requires_python = ">=3.6" summary = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" @@ -365,20 +351,20 @@ summary = "Utility library for gitignore style pattern matching of file paths." [[package]] name = "platformdirs" -version = "3.5.0" +version = "3.5.1" requires_python = ">=3.7" summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." [[package]] name = "psycopg2" -version = "2.8.6" -requires_python = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" +version = "2.9.6" +requires_python = ">=3.6" summary = "psycopg2 - Python-PostgreSQL Database Adapter" [[package]] name = "pycodestyle" -version = "2.6.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.10.0" +requires_python = ">=3.6" summary = "Python style guide checker" [[package]] @@ -389,28 +375,13 @@ summary = "C parser in Python" [[package]] name = "pyflakes" -version = "2.2.0" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "3.0.1" +requires_python = ">=3.6" summary = "passive checker of Python programs" -[[package]] -name = "pyparsing" -version = "2.4.7" -requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" -summary = "Python parsing module" - -[[package]] -name = "pyproj" -version = "3.5.0" -requires_python = ">=3.8" -summary = "Python interface to PROJ (cartographic projections and coordinate transformations library)" -dependencies = [ - "certifi", -] - [[package]] name = "python-dateutil" -version = "2.8.1" +version = "2.8.2" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" summary = "Extensions to the standard Python datetime module" dependencies = [ @@ -419,50 +390,40 @@ dependencies = [ [[package]] name = "python-dotenv" -version = "0.14.0" -summary = "Add .env support to your django/flask apps in development and deployments" - -[[package]] -name = "python-editor" -version = "1.0.4" -summary = "Programmatically open an editor, capture the result." +version = "1.0.0" +requires_python = ">=3.8" +summary = "Read key-value pairs from a .env file and set them as environment variables" [[package]] name = "python-slugify" -version = "4.0.1" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" -summary = "A Python Slugify application that handles Unicode" +version = "8.0.1" +requires_python = ">=3.7" +summary = "A Python slugify application that also handles Unicode" dependencies = [ "text-unidecode>=1.3", ] [[package]] name = "pytz" -version = "2020.1" +version = "2023.3" summary = "World timezone definitions, modern and historical" [[package]] name = "pyyaml" -version = "5.4" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" -summary = "YAML parser and emitter for Python" - -[[package]] -name = "regex" -version = "2022.10.31" +version = "6.0" requires_python = ">=3.6" -summary = "Alternative regular expression module, to replace re." +summary = "YAML parser and emitter for Python" [[package]] name = "requests" -version = "2.27.1" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" +version = "2.30.0" +requires_python = ">=3.7" summary = "Python HTTP for Humans." dependencies = [ "certifi>=2017.4.17", - "charset-normalizer~=2.0.0; python_version >= \"3\"", - "idna<4,>=2.5; python_version >= \"3\"", - "urllib3<1.27,>=1.21.1", + "charset-normalizer<4,>=2", + "idna<4,>=2.5", + "urllib3<3,>=1.21.1", ] [[package]] @@ -482,22 +443,24 @@ summary = "Python Data Structures for Humans" [[package]] name = "sentry-sdk" -version = "1.5.8" +version = "1.23.1" summary = "Python client for Sentry (https://sentry.io)" dependencies = [ "certifi", - "urllib3>=1.10.0", + "urllib3<2.0.0", + "urllib3>=1.26.11; python_version >= \"3.6\"", ] [[package]] name = "sentry-sdk" -version = "1.5.8" +version = "1.23.1" extras = ["flask"] summary = "Python client for Sentry (https://sentry.io)" dependencies = [ "blinker>=1.1", "flask>=0.11", - "sentry-sdk==1.5.8", + "markupsafe", + "sentry-sdk==1.23.1", ] [[package]] @@ -508,67 +471,65 @@ summary = "Easily download, build, install, upgrade, and uninstall Python packag [[package]] name = "shapely" -version = "1.7.1" -summary = "Geometric objects, predicates, and operations" +version = "2.0.1" +requires_python = ">=3.7" +summary = "Manipulation and analysis of geometric objects" +dependencies = [ + "numpy>=1.14", +] [[package]] name = "six" -version = "1.15.0" +version = "1.16.0" requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" summary = "Python 2 and 3 compatibility utilities" [[package]] name = "sqlalchemy" -version = "1.3.20" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.0.13" +requires_python = ">=3.7" summary = "Database Abstraction Library" +dependencies = [ + "greenlet!=0.4.17; 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.2.0", +] [[package]] name = "text-unidecode" version = "1.3" summary = "The most basic Text::Unidecode port" -[[package]] -name = "toml" -version = "0.10.1" -summary = "Python Library for Tom's Obvious, Minimal Language" - [[package]] name = "tomli" version = "2.0.1" requires_python = ">=3.7" summary = "A lil' TOML parser" -[[package]] -name = "typed-ast" -version = "1.5.4" -requires_python = ">=3.6" -summary = "a fork of Python 2 and 3 ast modules with type comment support" - [[package]] name = "typing-extensions" version = "4.5.0" requires_python = ">=3.7" summary = "Backported and Experimental Type Hints for Python 3.7+" +[[package]] +name = "tzdata" +version = "2023.3" +requires_python = ">=2" +summary = "Provider of IANA time zone data" + [[package]] name = "tzlocal" -version = "2.1" +version = "5.0.1" +requires_python = ">=3.7" summary = "tzinfo object for the local timezone" dependencies = [ - "pytz", + "tzdata; platform_system == \"Windows\"", ] -[[package]] -name = "unidecode" -version = "1.1.1" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -summary = "ASCII transliterations of Unicode text" - [[package]] name = "urllib3" -version = "1.26.9" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" +version = "1.26.15" +requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" summary = "HTTP library with thread-safe connection pooling, file post, and more." [[package]] @@ -578,9 +539,12 @@ summary = "Character encoding aliases for legacy web content" [[package]] name = "werkzeug" -version = "0.16.1" -requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +version = "2.3.4" +requires_python = ">=3.8" summary = "The comprehensive WSGI web application library." +dependencies = [ + "MarkupSafe>=2.1.1", +] [[package]] name = "zipp" @@ -608,29 +572,21 @@ dependencies = [ [metadata] lock_version = "4.2" cross_platform = true -groups = ["default"] -content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f2fe279a" +groups = ["default", "lint", "test"] +content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f465aed749" [metadata.files] -"alembic 1.4.3" = [ - {url = "https://files.pythonhosted.org/packages/12/aa/c261dfd7f4ba6ce4701846a2689a46e2a172e012171de4378fc2926e3bf0/alembic-1.4.3-py2.py3-none-any.whl", hash = "sha256:4e02ed2aa796bd179965041afa092c55b51fb077de19d61835673cc80672c01c"}, - {url = "https://files.pythonhosted.org/packages/cd/f5/705578ee067b92bcfbda4ca1122bdf8c7387dc2c691f1a9d39f18d78f84c/alembic-1.4.3.tar.gz", hash = "sha256:5334f32314fb2a56d86b4c4dd1ae34b08c03cae4cb888bc699942104d66bc245"}, -] -"aniso8601 8.0.0" = [ - {url = "https://files.pythonhosted.org/packages/2f/45/f2aec388115ea65a2b95b3dc1ba058a8470675fe16bcd4678a44a59776ea/aniso8601-8.0.0.tar.gz", hash = "sha256:529dcb1f5f26ee0df6c0a1ee84b7b27197c3c50fc3a6321d66c544689237d072"}, - {url = "https://files.pythonhosted.org/packages/eb/e4/787e104b58eadc1a710738d4e418d7e599e4e778e52cb8e5d5ef6ddd5833/aniso8601-8.0.0-py2.py3-none-any.whl", hash = "sha256:c033f63d028b9a58e3ab0c2c7d0532ab4bfa7452bfc788fbfe3ddabd327b181a"}, +"alembic 1.11.1" = [ + {url = "https://files.pythonhosted.org/packages/11/00/46a4f66ad54c661350a1cd5daae4b4ab2232486c55635ee12ff12958b03f/alembic-1.11.1-py3-none-any.whl", hash = "sha256:dc871798a601fab38332e38d6ddb38d5e734f60034baeb8e2db5b642fccd8ab8"}, + {url = "https://files.pythonhosted.org/packages/c6/e3/3d9b95470606b93bd6e6d5c899ed9d0049dfa10246ecca25b18c2c708cdf/alembic-1.11.1.tar.gz", hash = "sha256:6a810a6b012c88b33458fceb869aef09ac75d6ace5291915ba7fae44de372c01"}, ] -"appdirs 1.4.4" = [ - {url = "https://files.pythonhosted.org/packages/3b/00/2344469e2084fb287c2e0b57b72910309874c3245463acd6cf5e3db69324/appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, - {url = "https://files.pythonhosted.org/packages/d7/d8/05696357e0311f5b5c316d7b95f46c669dd9c15aaeecbb48c7d0aeb88c40/appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, +"aniso8601 9.0.1" = [ + {url = "https://files.pythonhosted.org/packages/cb/72/be3db445b03944bfbb2b02b82d00cb2a2bcf96275c4543f14bf60fa79e12/aniso8601-9.0.1.tar.gz", hash = "sha256:72e3117667eedf66951bb2d93f4296a56b94b078a8a95905a052611fb3f1b973"}, + {url = "https://files.pythonhosted.org/packages/e3/04/e97c12dc034791d7b504860acfcdd2963fa21ae61eaca1c9d31245f812c3/aniso8601-9.0.1-py2.py3-none-any.whl", hash = "sha256:1d2b7ef82963909e93c4f24ce48d4de9e66009a21bf1c1e1c85bdd0812fe412f"}, ] -"apscheduler 3.7.0" = [ - {url = "https://files.pythonhosted.org/packages/01/24/5ec33616b0ad830d18641b7c58eef66a1fb25f3202df01682c87bc2fd0d9/APScheduler-3.7.0.tar.gz", hash = "sha256:1cab7f2521e107d07127b042155b632b7a1cd5e02c34be5a28ff62f77c900c6a"}, - {url = "https://files.pythonhosted.org/packages/5d/e9/b5e4f7aaea076bbfb241b04824c63cd42fe8029358103c27375e690bddc0/APScheduler-3.7.0-py2.py3-none-any.whl", hash = "sha256:c06cc796d5bb9eb3c4f77727f6223476eb67749e7eea074d1587550702a7fbe3"}, -] -"attrs 20.2.0" = [ - {url = "https://files.pythonhosted.org/packages/14/df/479736ae1ef59842f512548bacefad1abed705e400212acba43f9b0fa556/attrs-20.2.0-py2.py3-none-any.whl", hash = "sha256:fce7fc47dfc976152e82d53ff92fa0407700c21acd20886a13777a0d20e655dc"}, - {url = "https://files.pythonhosted.org/packages/81/d0/641b698d05f0eaea4df4f9cebaff573d7a5276228ef6b7541240fe02f3ad/attrs-20.2.0.tar.gz", hash = "sha256:26b54ddbbb9ee1d34d5d3668dd37d6cf74990ab23c828c2888dccdceee395594"}, +"apscheduler 3.10.1" = [ + {url = "https://files.pythonhosted.org/packages/d0/08/952d9570f4897dc2b30166fca5afd3a2cd19b3d408abdb470978484e8a09/APScheduler-3.10.1-py3-none-any.whl", hash = "sha256:e813ad5ada7aff36fb08cdda746b520531eaac7757832abc204868ba78e0c8f6"}, + {url = "https://files.pythonhosted.org/packages/ea/ed/f1ad88e88208c24db80dcaae7a5a339bb283956984f8fa59933d2806413a/APScheduler-3.10.1.tar.gz", hash = "sha256:0293937d8f6051a0f493359440c1a1b93e882c57daf0197afeff0e727777b96e"}, ] "black 23.3.0" = [ {url = "https://files.pythonhosted.org/packages/06/1e/273d610249f0335afb1ddb03664a03223f4826e3d1a95170a0142cb19fb4/black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, @@ -659,21 +615,21 @@ content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f {url = "https://files.pythonhosted.org/packages/eb/a5/17b40bfd9b607b69fa726b0b3a473d14b093dcd5191ea1a1dd664eccfee3/black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, {url = "https://files.pythonhosted.org/packages/fd/5b/fc2d7922c1a6bb49458d424b5be71d251f2d0dc97be9534e35d171bdc653/black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, ] -"bleach 5.0.1" = [ - {url = "https://files.pythonhosted.org/packages/c2/5d/d5d45a38163ede3342d6ac1ca01b5d387329daadf534a25718f9a9ba818c/bleach-5.0.1.tar.gz", hash = "sha256:0d03255c47eb9bd2f26aa9bb7f2107732e7e8fe195ca2f64709fcf3b0a4a085c"}, - {url = "https://files.pythonhosted.org/packages/d4/87/508104336a2bc0c4cfdbdceedc0f44dc72da3abc0460c57e323ddd1b3257/bleach-5.0.1-py3-none-any.whl", hash = "sha256:085f7f33c15bd408dd9b17a4ad77c577db66d76203e5984b1bd59baeee948b2a"}, +"bleach 6.0.0" = [ + {url = "https://files.pythonhosted.org/packages/7e/e6/d5f220ca638f6a25557a611860482cb6e54b2d97f0332966b1b005742e1f/bleach-6.0.0.tar.gz", hash = "sha256:1a1a85c1595e07d8db14c5f09f09e6433502c51c595970edc090551f0db99414"}, + {url = "https://files.pythonhosted.org/packages/ac/e2/dfcab68c9b2e7800c8f06b85c76e5f978d05b195a958daa9b1dda54a1db6/bleach-6.0.0-py3-none-any.whl", hash = "sha256:33c16e3353dbd13028ab4799a0f89a83f113405c766e9c122df8a06f5b85b3f4"}, ] -"blinker 1.5" = [ - {url = "https://files.pythonhosted.org/packages/2b/12/82786486cefb68685bb1c151730f510b0f4e5d621d77f245bc0daf9a6c64/blinker-1.5.tar.gz", hash = "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462"}, - {url = "https://files.pythonhosted.org/packages/30/41/caa5da2dbe6d26029dfe11d31dfa8132b4d6d30b6d6b61a24824075a5f06/blinker-1.5-py2.py3-none-any.whl", hash = "sha256:1eb563df6fdbc39eeddc177d953203f99f097e9bf0e2b8f9f3cf18b6ca425e36"}, +"blinker 1.6.2" = [ + {url = "https://files.pythonhosted.org/packages/0d/f1/5f39e771cd730d347539bb74c6d496737b9d5f0a53bc9fdbf3e170f1ee48/blinker-1.6.2-py3-none-any.whl", hash = "sha256:c3d739772abb7bc2860abf5f2ec284223d9ad5c76da018234f6f50d6f31ab1f0"}, + {url = "https://files.pythonhosted.org/packages/e8/f9/a05287f3d5c54d20f51a235ace01f50620984bc7ca5ceee781dc645211c5/blinker-1.6.2.tar.gz", hash = "sha256:4afd3de66ef3a9f8067559fb7a1cbe555c17dcbe15971b05d1b625c3e7abe213"}, ] -"cachetools 4.1.1" = [ - {url = "https://files.pythonhosted.org/packages/cd/5c/f3aa86b6d5482f3051b433c7616668a9b96fbe49a622210e2c9781938a5c/cachetools-4.1.1-py3-none-any.whl", hash = "sha256:513d4ff98dd27f85743a8dc0e92f55ddb1b49e060c2d5961512855cda2c01a98"}, - {url = "https://files.pythonhosted.org/packages/fc/c8/0b52cf3132b4b85c9e83faa3e4d375575afeb3a1710c40b2b2cd2a3e5635/cachetools-4.1.1.tar.gz", hash = "sha256:bbaa39c3dede00175df2dc2b03d0cf18dd2d32a7de7beb68072d13043c9edb20"}, +"cachetools 5.3.0" = [ + {url = "https://files.pythonhosted.org/packages/4d/91/5837e9f9e77342bb4f3ffac19ba216eef2cd9b77d67456af420e7bafe51d/cachetools-5.3.0.tar.gz", hash = "sha256:13dfddc7b8df938c21a940dfa6557ce6e94a2f1cdfa58eb90c805721d58f2c14"}, + {url = "https://files.pythonhosted.org/packages/db/14/2b48a834d349eee94677e8702ea2ef98b7c674b090153ea8d3f6a788584e/cachetools-5.3.0-py3-none-any.whl", hash = "sha256:429e1a1e845c008ea6c85aa35d4b98b65d6a9763eeef3e37e92728a12d1de9d4"}, ] -"certifi 2020.6.20" = [ - {url = "https://files.pythonhosted.org/packages/40/a7/ded59fa294b85ca206082306bba75469a38ea1c7d44ea7e1d64f5443d67a/certifi-2020.6.20.tar.gz", hash = "sha256:5930595817496dd21bb8dc35dad090f1c2cd0adfaf21204bf6732ca5d8ee34d3"}, - {url = "https://files.pythonhosted.org/packages/5e/c4/6c4fe722df5343c33226f0b4e0bb042e4dc13483228b4718baf286f86d87/certifi-2020.6.20-py2.py3-none-any.whl", hash = "sha256:8fc0819f1f30ba15bdb34cceffb9ef04d99f420f68eb75d901e9560b8749fc41"}, +"certifi 2023.5.7" = [ + {url = "https://files.pythonhosted.org/packages/93/71/752f7a4dd4c20d6b12341ed1732368546bc0ca9866139fe812f6009d9ac7/certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, + {url = "https://files.pythonhosted.org/packages/9d/19/59961b522e6757f0c9097e4493fa906031b95b3ebe9360b2c3083561a6b4/certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, ] "cffi 1.15.1" = [ {url = "https://files.pythonhosted.org/packages/00/05/23a265a3db411b0bfb721bf7a116c7cecaf3eb37ebd48a6ea4dfb0a3244d/cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, @@ -741,13 +697,82 @@ content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f {url = "https://files.pythonhosted.org/packages/f9/96/fc9e118c47b7adc45a0676f413b4a47554e5f3b6c99b8607ec9726466ef1/cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, {url = "https://files.pythonhosted.org/packages/ff/fe/ac46ca7b00e9e4f9c62e7928a11bc9227c86e2ff43526beee00cdfb4f0e8/cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, ] -"chardet 3.0.4" = [ - {url = "https://files.pythonhosted.org/packages/bc/a9/01ffebfb562e4274b6487b4bb1ddec7ca55ec7510b22e4c51f14098443b8/chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, - {url = "https://files.pythonhosted.org/packages/fc/bb/a5768c230f9ddb03acc9ef3f0d4a3cf93462473795d18e9535498c8f929d/chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, -] -"charset-normalizer 2.0.12" = [ - {url = "https://files.pythonhosted.org/packages/06/b3/24afc8868eba069a7f03650ac750a778862dc34941a4bebeb58706715726/charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, - {url = "https://files.pythonhosted.org/packages/56/31/7bcaf657fafb3c6db8c787a865434290b726653c912085fbd371e9b92e1c/charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, +"charset-normalizer 3.1.0" = [ + {url = "https://files.pythonhosted.org/packages/00/47/f14533da238134f5067fb1d951eb03d5c4be895d6afb11c7ebd07d111acb/charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28"}, + {url = "https://files.pythonhosted.org/packages/01/c7/0407de35b70525dba2a58a2724a525cf882ee76c3d2171d834463c5d2881/charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb"}, + {url = "https://files.pythonhosted.org/packages/05/f3/86b5fcb5c8fe8b4231362918a7c4d8f549c56561c5fdb495a3c5b41c6862/charset_normalizer-3.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8"}, + {url = "https://files.pythonhosted.org/packages/07/6b/98d41a0221991a806e88c95bfeecf8935fbf465b02eb4b469770d572183a/charset_normalizer-3.1.0-cp37-cp37m-win32.whl", hash = "sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974"}, + {url = "https://files.pythonhosted.org/packages/0a/67/8d3d162ec6641911879651cdef670c3c6136782b711d7f8e82e2fffe06e0/charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017"}, + {url = "https://files.pythonhosted.org/packages/12/12/c5c39f5a149cd6788d2e40cea5618bae37380e2754fcdf53dc9e01bdd33a/charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41"}, + {url = "https://files.pythonhosted.org/packages/12/68/4812f9b05ac0a2b7619ac3dd7d7e3fc52c12006b84617021c615fc2fcf42/charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e"}, + {url = "https://files.pythonhosted.org/packages/13/b7/21729a6d512246aa0bb872b90aea0d9fcd1b293762cdb1d1d33c01140074/charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326"}, + {url = "https://files.pythonhosted.org/packages/16/58/19fd2f62e6ff44ba0db0cd44b584790555e2cde09293149f4409d654811b/charset_normalizer-3.1.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6"}, + {url = "https://files.pythonhosted.org/packages/18/36/7ae10a3dd7f9117b61180671f8d1e4802080cca88ad40aaabd3dad8bab0e/charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62"}, + {url = "https://files.pythonhosted.org/packages/1c/9b/de2adc43345623da8e7c958719528a42b6d87d2601017ce1187d43b8a2d7/charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230"}, + {url = "https://files.pythonhosted.org/packages/1f/be/c6c76cf8fcf6918922223203c83ba8192eff1c6a709e8cfec7f5ca3e7d2d/charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854"}, + {url = "https://files.pythonhosted.org/packages/21/16/1b0d8fdcb81bbf180976af4f867ce0f2244d303ab10d452fde361dec3b5c/charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be"}, + {url = "https://files.pythonhosted.org/packages/23/13/cf5d7bb5bc95f120df64d6c470581189df51d7f011560b2a06a395b7a120/charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137"}, + {url = "https://files.pythonhosted.org/packages/26/20/83e1804a62b25891c4e770c94d9fd80233bbb3f2a51c4fadee7a196e5a5b/charset_normalizer-3.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59"}, + {url = "https://files.pythonhosted.org/packages/2c/2f/ec805104098085728b7cb610deede7195c6fa59f51942422f02cc427b6f6/charset_normalizer-3.1.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649"}, + {url = "https://files.pythonhosted.org/packages/2e/25/3eab2b38fef9ae59f7b4e9c1e62eb50609d911867e5acabace95fe25c0b1/charset_normalizer-3.1.0-cp310-cp310-win32.whl", hash = "sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448"}, + {url = "https://files.pythonhosted.org/packages/31/8b/81c3515a69d06b501fcce69506af57a7a19bd9f42cabd1a667b1b40f2c55/charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b"}, + {url = "https://files.pythonhosted.org/packages/33/10/c87ba15f779f8251ae55fa147631339cd91e7af51c3c133d2687c6e41800/charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11"}, + {url = "https://files.pythonhosted.org/packages/33/97/9967fb2d364a9da38557e4af323abcd58cc05bdd8f77e9fd5ae4882772cc/charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706"}, + {url = "https://files.pythonhosted.org/packages/45/3d/fa2683f5604f99fba5098a7313e5d4846baaecbee754faf115907f21a85f/charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f"}, + {url = "https://files.pythonhosted.org/packages/4e/11/f7077d78b18aca8ea3186a706c0221aa2bc34c442a3d3bdf3ad401a29052/charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0"}, + {url = "https://files.pythonhosted.org/packages/4f/18/92866f050f7114ba38aba4f4a69f83cc2a25dc2e5a8af4b44fd1bfd6d528/charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d"}, + {url = "https://files.pythonhosted.org/packages/4f/7c/af43743567a7da2a069b4f9fa31874c3c02b963cd1fb84fe1e7568a567e6/charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7"}, + {url = "https://files.pythonhosted.org/packages/4f/a2/9031ba4a008e11a21d7b7aa41751290d2f2035a2f14ecb6e589771a17c47/charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b"}, + {url = "https://files.pythonhosted.org/packages/56/24/5f2dedcf3d0673931b6200c410832ae44b376848bc899dbf1fa6c91c4ebe/charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324"}, + {url = "https://files.pythonhosted.org/packages/5d/2b/4d8c80400c04ae3c8dbc847de092e282b5c7b17f8f9505d68bb3e5815c71/charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb"}, + {url = "https://files.pythonhosted.org/packages/61/e3/ad9ae58b28482d1069eba1edec2be87701f5dd6fd6024a665020d66677a0/charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d"}, + {url = "https://files.pythonhosted.org/packages/67/30/dbab1fe5ab2ce5d3d517ad9936170d896e9687f3860a092519f1fe359812/charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1"}, + {url = "https://files.pythonhosted.org/packages/67/df/660e9665ace7ad711e275194a86cb757fb4d4e513fae5ff3d39573db4984/charset_normalizer-3.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60"}, + {url = "https://files.pythonhosted.org/packages/68/77/af702eba147ba963b27eb00832cef6b8c4cb9fcf7404a476993876434b93/charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd"}, + {url = "https://files.pythonhosted.org/packages/69/22/66351781e668158feef71c5e3b059a79ecc9efc3ef84a45888b0f3a933d5/charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f"}, + {url = "https://files.pythonhosted.org/packages/6d/59/59a3f4d8a59ee270da77f9e954a0e284c9d6884d39ec69d696d9aa5ff2f2/charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0"}, + {url = "https://files.pythonhosted.org/packages/72/90/667a6bc6abe42fc10adf4cd2c1e1c399d78e653dbac4c8018350843d4ab7/charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0"}, + {url = "https://files.pythonhosted.org/packages/74/5f/361202de730532028458b729781b8435f320e31a622c27f30e25eec80513/charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0"}, + {url = "https://files.pythonhosted.org/packages/74/f1/d0b8385b574f7e086fb6709e104b696707bd3742d54a6caf0cebbb7e975b/charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce"}, + {url = "https://files.pythonhosted.org/packages/76/ad/516fed8ffaf02e7a01cd6f6e9d101a6dec64d4db53bec89d30802bf30a96/charset_normalizer-3.1.0-cp38-cp38-win32.whl", hash = "sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0"}, + {url = "https://files.pythonhosted.org/packages/82/b9/51b66a647be8685dee75b7807e0f750edf5c1e4f29bc562ad285c501e3c7/charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c"}, + {url = "https://files.pythonhosted.org/packages/84/23/f60cda6c70ae922ad78368982f06e7fef258fba833212f26275fe4727dc4/charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84"}, + {url = "https://files.pythonhosted.org/packages/85/e8/18d408d8fe29a56012c10d6b15960940b83f06620e9d7481581cdc6d9901/charset_normalizer-3.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df"}, + {url = "https://files.pythonhosted.org/packages/94/70/23981e7bf098efbc4037e7c66d28a10e950d9296c08c6dea8ef290f9c79e/charset_normalizer-3.1.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e"}, + {url = "https://files.pythonhosted.org/packages/9a/f1/ff81439aa09070fee64173e6ca6ce1342f2b1cca997bcaae89e443812684/charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f"}, + {url = "https://files.pythonhosted.org/packages/9e/62/a1e0a8f8830c92014602c8a88a1a20b8a68d636378077381f671e6e1cec9/charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a"}, + {url = "https://files.pythonhosted.org/packages/a2/6c/5167f08da5298f383036c33cb749ab5b3405fd07853edc8314c6882c01b8/charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e"}, + {url = "https://files.pythonhosted.org/packages/a4/03/355281b62c26712a50c6a9dd75339d8cdd58488fd7bf2556ba1320ebd315/charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d"}, + {url = "https://files.pythonhosted.org/packages/a9/83/138d2624fdbcb62b7e14715eb721d44347e41a1b4c16544661e940793f49/charset_normalizer-3.1.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f"}, + {url = "https://files.pythonhosted.org/packages/ac/7f/62d5dff4e9cb993e4b0d4ea78a74cc84d7d92120879529e0ce0965765936/charset_normalizer-3.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f"}, + {url = "https://files.pythonhosted.org/packages/ac/c5/990bc41a98b7fa2677c665737fdf278bb74ad4b199c56b6b564b3d4cbfc5/charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c"}, + {url = "https://files.pythonhosted.org/packages/ad/83/994bfca99e29f1bab66b9248e739360ee70b5aae0a5ee488cd776501edbc/charset_normalizer-3.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755"}, + {url = "https://files.pythonhosted.org/packages/b0/55/d8ef4c8c7d2a8b3a16e7d9b03c59475c2ee96a0e0c90b14c99faaac0ee3b/charset_normalizer-3.1.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8"}, + {url = "https://files.pythonhosted.org/packages/bb/dc/58fdef3ab85e8e7953a8b89ef1d2c06938b8ad88d9617f22967e1a90e6b8/charset_normalizer-3.1.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c"}, + {url = "https://files.pythonhosted.org/packages/bc/08/7e7c97399806366ca515a049c3a1e4b644a6a2048bed16e5e67bfaafd0aa/charset_normalizer-3.1.0-cp311-cp311-win32.whl", hash = "sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909"}, + {url = "https://files.pythonhosted.org/packages/bc/92/ac692a303e53cdc8852ce72b1ac364b493ca5c9206a5c8db5b30a7f3019c/charset_normalizer-3.1.0-cp39-cp39-win32.whl", hash = "sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1"}, + {url = "https://files.pythonhosted.org/packages/c2/35/dfb4032f5712747d3dcfdd19d0768f6d8f60910ae24ed066ecbf442be013/charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203"}, + {url = "https://files.pythonhosted.org/packages/c6/ab/43ea052756b2f2dcb6a131897811c0e2704b0288f090336217d3346cd682/charset_normalizer-3.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1"}, + {url = "https://files.pythonhosted.org/packages/c9/8c/a76dd9f2c8803eb147e1e715727f5c3ba0ef39adaadf66a7b3698c113180/charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5"}, + {url = "https://files.pythonhosted.org/packages/cc/f6/21a66e524658bd1dd7b89ac9d1ee8f7823f2d9701a2fbc458ab9ede53c63/charset_normalizer-3.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795"}, + {url = "https://files.pythonhosted.org/packages/d1/ff/51fe7e6446415f143b159740c727850172bc35622b2a06dde3354bdebaf3/charset_normalizer-3.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b"}, + {url = "https://files.pythonhosted.org/packages/d5/92/86c0f0e66e897f6818c46dadef328a5b345d061688f9960fc6ca1fd03dbe/charset_normalizer-3.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31"}, + {url = "https://files.pythonhosted.org/packages/d7/4c/37ad75674e8c6bc22ab01bef673d2d6e46ee44203498c9a26aa23959afe5/charset_normalizer-3.1.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1"}, + {url = "https://files.pythonhosted.org/packages/d8/ca/a7ff600781bf1e5f702ba26bb82f2ba1d3a873a3f8ad73cc44c79dfaefa9/charset_normalizer-3.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14"}, + {url = "https://files.pythonhosted.org/packages/dd/39/6276cf5a395ffd39b77dadf0e2fcbfca8dbfe48c56ada250c40086055143/charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9"}, + {url = "https://files.pythonhosted.org/packages/e1/7c/398600268fc98b7e007f5a716bd60903fff1ecff75e45f5700212df5cd76/charset_normalizer-3.1.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19"}, + {url = "https://files.pythonhosted.org/packages/e1/b4/53678b2a14e0496fc167fe9b9e726ad33d670cfd2011031aa5caeee6b784/charset_normalizer-3.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373"}, + {url = "https://files.pythonhosted.org/packages/e5/aa/9d2d60d6a566423da96c15cd11cbb88a70f9aff9a4db096094ee19179cab/charset_normalizer-3.1.0-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac"}, + {url = "https://files.pythonhosted.org/packages/e6/98/a3f65f57651da1cecaed91d6f75291995d56c97442fa2a43d2a421139adf/charset_normalizer-3.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23"}, + {url = "https://files.pythonhosted.org/packages/ea/38/d31c7906c4be13060c1a5034087966774ef33ab57ff2eee76d71265173c3/charset_normalizer-3.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531"}, + {url = "https://files.pythonhosted.org/packages/ef/81/14b3b8f01ddaddad6cdec97f2f599aa2fa466bd5ee9af99b08b7713ccd29/charset_normalizer-3.1.0-py3-none-any.whl", hash = "sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d"}, + {url = "https://files.pythonhosted.org/packages/f2/b7/e21e16c98575616f4ce09dc766dbccdac0ca119c176b184d46105e971a84/charset_normalizer-3.1.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab"}, + {url = "https://files.pythonhosted.org/packages/f2/d7/6ee92c11eda3f3c9cac1e059901092bfdf07388be7d2e60ac627527eee62/charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1"}, + {url = "https://files.pythonhosted.org/packages/f4/0a/8c03913ed1eca9d831db0c28759edb6ce87af22bb55dbc005a52525a75b6/charset_normalizer-3.1.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a"}, + {url = "https://files.pythonhosted.org/packages/f6/0f/de1c4030fd669e6719277043e3b0f152a83c118dd1020cf85b51d443d04a/charset_normalizer-3.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e"}, + {url = "https://files.pythonhosted.org/packages/f8/ed/500609cb2457b002242b090c814549997424d72690ef3058cfdfca91f68b/charset_normalizer-3.1.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b"}, + {url = "https://files.pythonhosted.org/packages/fa/8e/2e5c742c3082bce3eea2ddd5b331d08050cda458bc362d71c48e07a44719/charset_normalizer-3.1.0-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6"}, + {url = "https://files.pythonhosted.org/packages/ff/d7/8d757f8bd45be079d76309248845a04f09619a7b17d6dfc8c9ff6433cac2/charset-normalizer-3.1.0.tar.gz", hash = "sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5"}, ] "click 8.1.3" = [ {url = "https://files.pythonhosted.org/packages/59/87/84326af34517fca8c58418d148f2403df25303e02736832403587318e9e8/click-8.1.3.tar.gz", hash = "sha256:7682dc8afb30297001674575ea00d1814d808d6a36af415a82bd481d37ba7b8e"}, @@ -757,309 +782,344 @@ content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f {url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -"coverage 6.4" = [ - {url = "https://files.pythonhosted.org/packages/01/af/7d49e6bde1c3f32ffcefab638127557ed86b54c2c966ff2ca9e81f11a3b6/coverage-6.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8099ea680201c2221f8468c372198ceba9338a5fec0e940111962b03b3f716a"}, - {url = "https://files.pythonhosted.org/packages/03/ad/d820de6679d051e20e0f72254a09a2ea2a6f6948dbb94e28dd460e72ea5d/coverage-6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af5b9ee0fc146e907aa0f5fb858c3b3da9199d78b7bb2c9973d95550bd40f701"}, - {url = "https://files.pythonhosted.org/packages/09/0d/5a60d0d14feb2c498ebcd00b5c57c459ba7f779b75e4579e1e74fcb37124/coverage-6.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5a78cf2c43b13aa6b56003707c5203f28585944c277c1f3f109c7b041b16bd39"}, - {url = "https://files.pythonhosted.org/packages/09/2c/2efb6ad3067feaa8934e770e218a05d44de6958062f3c2bf7fdf2515adb4/coverage-6.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a00441f5ea4504f5abbc047589d09e0dc33eb447dc45a1a527c8b74bfdd32c65"}, - {url = "https://files.pythonhosted.org/packages/10/f9/b73c3b068f1db35ab94f9cafe071092ff17c03f31c6e807966e05b7f8138/coverage-6.4-cp38-cp38-win32.whl", hash = "sha256:83bd142cdec5e4a5c4ca1d4ff6fa807d28460f9db919f9f6a31babaaa8b88426"}, - {url = "https://files.pythonhosted.org/packages/13/af/418aa14415712839604fb2eadc307aaf4913540cf42e9b76fd41330b3d74/coverage-6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:60c2147921da7f4d2d04f570e1838db32b95c5509d248f3fe6417e91437eaf41"}, - {url = "https://files.pythonhosted.org/packages/1d/14/964e6e9d77c4dd0c1ff5ed58fcfd1f54d2333c5506b448f81782c5412cec/coverage-6.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e76bd16f0e31bc2b07e0fb1379551fcd40daf8cdf7e24f31a29e442878a827c"}, - {url = "https://files.pythonhosted.org/packages/27/1e/b36f224db34a0d77be90da93224ae972f799373af803718f2a21d9689c6c/coverage-6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:50ed480b798febce113709846b11f5d5ed1e529c88d8ae92f707806c50297abf"}, - {url = "https://files.pythonhosted.org/packages/2b/e7/88b69e5aec5b317c1f8371ea9a0e386dae0e61ded27ab85649ab471a59ce/coverage-6.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a022394996419142b33a0cf7274cb444c01d2bb123727c4bb0b9acabcb515dea"}, - {url = "https://files.pythonhosted.org/packages/43/bf/afd6ab67c0a3b3913afd079a137b54e231fba2b7ae0fd7380d74aaa8e5d7/coverage-6.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:016d7f5cf1c8c84f533a3c1f8f36126fbe00b2ec0ccca47cc5731c3723d327c6"}, - {url = "https://files.pythonhosted.org/packages/46/09/941c11c98d56758eb13e5da0f451f00a051072c751fff3e191bf4723b1d7/coverage-6.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:9229d074e097f21dfe0643d9d0140ee7433814b3f0fc3706b4abffd1e3038632"}, - {url = "https://files.pythonhosted.org/packages/46/5d/7876058ddbf456280325d4e5c95cb35e3934939c9cd42071fe8dfcab56c4/coverage-6.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:033ebec282793bd9eb988d0271c211e58442c31077976c19c442e24d827d356f"}, - {url = "https://files.pythonhosted.org/packages/5c/75/7d941bf5a53180823a80ff5d4b29f7276ab4265813c1f1a0892c0f894ac8/coverage-6.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:742fb8b43835078dd7496c3c25a1ec8d15351df49fb0037bffb4754291ef30ce"}, - {url = "https://files.pythonhosted.org/packages/69/a3/4fd25ee90893ced6f3417b0dfa925e32b46a96383350f5c1cc30b437c97a/coverage-6.4-cp39-cp39-win_amd64.whl", hash = "sha256:e35217031e4b534b09f9b9a5841b9344a30a6357627761d4218818b865d45055"}, - {url = "https://files.pythonhosted.org/packages/70/1a/49199fb842679f716c2cba46b4bf01772e9073c750a9fce79304e8ad37d8/coverage-6.4-cp39-cp39-win32.whl", hash = "sha256:968ed5407f9460bd5a591cefd1388cc00a8f5099de9e76234655ae48cfdbe2c3"}, - {url = "https://files.pythonhosted.org/packages/76/13/dcb5eaa17eba690925c6df76fe896cefc0f0be61e4db90e5d2f602e06d11/coverage-6.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c53ad261dfc8695062fc8811ac7c162bd6096a05a19f26097f411bdf5747aee7"}, - {url = "https://files.pythonhosted.org/packages/78/ac/1abb4ff8e7e58b27684070a8cfecb55636b36c01e4364515814da275cee3/coverage-6.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5cd698341626f3c77784858427bad0cdd54a713115b423d22ac83a28303d1d95"}, - {url = "https://files.pythonhosted.org/packages/7e/3a/ad9b121206034eff6e4d144adf0e017cbecca56bc0b29de4e5fcf20a5941/coverage-6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:26f8f92699756cb7af2b30720de0c5bb8d028e923a95b6d0c891088025a1ac8f"}, - {url = "https://files.pythonhosted.org/packages/8f/e3/61617deb52bb33cc885e834122c9a3d2a239459d429898dc9107830398a4/coverage-6.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:543e172ce4c0de533fa892034cce260467b213c0ea8e39da2f65f9a477425211"}, - {url = "https://files.pythonhosted.org/packages/97/8f/6ee2ed5ce426ad9a40e45731057f07867648c3db570492da1a27030b098b/coverage-6.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:21e6686a95025927775ac501e74f5940cdf6fe052292f3a3f7349b0abae6d00f"}, - {url = "https://files.pythonhosted.org/packages/9f/a3/219f53acb31aa765f208447417d2ec33f4ed267892c8134c2dbf8f283731/coverage-6.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:eef5292b60b6de753d6e7f2d128d5841c7915fb1e3321c3a1fe6acfe76c38052"}, - {url = "https://files.pythonhosted.org/packages/a1/16/31cbfd38986778df2d219c9262cc69c30fb56040d3a1cc0db87ca454f08b/coverage-6.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b5578efe4038be02d76c344007b13119b2b20acd009a88dde8adec2de4f630b5"}, - {url = "https://files.pythonhosted.org/packages/aa/39/4e97e39e3d2afc3c23c7b564a9e25a02f0d3f7565fd3b9f6a9d5aaceb1cf/coverage-6.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:69432946f154c6add0e9ede03cc43b96e2ef2733110a77444823c053b1ff5166"}, - {url = "https://files.pythonhosted.org/packages/ab/5e/5a08e3cbe7ff52005cb40d7d072025743997e32cae773731de2aaf132ccd/coverage-6.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d55fae115ef9f67934e9f1103c9ba826b4c690e4c5bcf94482b8b2398311bf9c"}, - {url = "https://files.pythonhosted.org/packages/ac/83/67ad44859ef4d5d1f19675d8207c9933f52f25f2b39bad1f99af4bf29117/coverage-6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e4f52c272fdc82e7c65ff3f17a7179bc5f710ebc8ce8a5cadac81215e8326740"}, - {url = "https://files.pythonhosted.org/packages/af/c9/91533449c1c8685aa09b89069a73f181a0d841b53a4516798e80af6efc5e/coverage-6.4.tar.gz", hash = "sha256:727dafd7f67a6e1cad808dc884bd9c5a2f6ef1f8f6d2f22b37b96cb0080d4f49"}, - {url = "https://files.pythonhosted.org/packages/b5/5d/f722fe6efb970b7be9edc8904edb7bdf367221216a481a1bf97672c1c644/coverage-6.4-pp36.pp37.pp38-none-any.whl", hash = "sha256:e637ae0b7b481905358624ef2e81d7fb0b1af55f5ff99f9ba05442a444b11e45"}, - {url = "https://files.pythonhosted.org/packages/bc/fb/e6d513645a6f07c2c2dc759e30fd7e87292d835975e923e7d5b6416a2dba/coverage-6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d548edacbf16a8276af13063a2b0669d58bbcfca7c55a255f84aac2870786a61"}, - {url = "https://files.pythonhosted.org/packages/bd/95/3b1732dd0e3ad3edf8368af03c5c420ba94eab342712c8f0b38e18a4a0e7/coverage-6.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:8d2e80dd3438e93b19e1223a9850fa65425e77f2607a364b6fd134fcd52dc9df"}, - {url = "https://files.pythonhosted.org/packages/c5/f5/44933d0f4dbd37c9c371ddb390d603f24e37fb85702d97e96db0142a07cc/coverage-6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:03014a74023abaf5a591eeeaf1ac66a73d54eba178ff4cb1fa0c0a44aae70383"}, - {url = "https://files.pythonhosted.org/packages/d0/ca/507397ce9b948be4ff58f9e55445c02991823c7572bd0e537921135b18f0/coverage-6.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c82f2cd69c71698152e943f4a5a6b83a3ab1db73b88f6e769fabc86074c3b08"}, - {url = "https://files.pythonhosted.org/packages/d3/5b/fe12a83e9671cb9c5a7c9e623735c121cd80ca1e049fd049b371dd704f4f/coverage-6.4-cp310-cp310-win32.whl", hash = "sha256:fb45fe08e1abc64eb836d187b20a59172053999823f7f6ef4f18a819c44ba16f"}, - {url = "https://files.pythonhosted.org/packages/d8/e8/dd4a92c84359e6c5647de9245a7210eba015d919e8e14be8a7b485850805/coverage-6.4-cp310-cp310-win_amd64.whl", hash = "sha256:3cfd07c5889ddb96a401449109a8b97a165be9d67077df6802f59708bfb07720"}, - {url = "https://files.pythonhosted.org/packages/e7/b0/d5456940aaa5c39e834a613031af2be18f5d707788b86208994e8c8c3003/coverage-6.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:62d382f7d77eeeaff14b30516b17bcbe80f645f5cf02bb755baac376591c653c"}, - {url = "https://files.pythonhosted.org/packages/ea/1a/1356f2fe9dbe2f7b61dfecaef298a36503a9392fe961959e0ec6558f0155/coverage-6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:750e13834b597eeb8ae6e72aa58d1d831b96beec5ad1d04479ae3772373a8088"}, - {url = "https://files.pythonhosted.org/packages/eb/be/ad0b20587d8c9cd08b997d7e2ffec96f5cb215105dcf65624c0e291a7852/coverage-6.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b546cf2b1974ddc2cb222a109b37c6ed1778b9be7e6b0c0bc0cf0438d9e45a6"}, - {url = "https://files.pythonhosted.org/packages/ed/3b/68ef445f4a21bcf00aec7f2ed2c513e615d1ff6e5eb7e403e46e1386bfbc/coverage-6.4-cp38-cp38-win_amd64.whl", hash = "sha256:4002f9e8c1f286e986fe96ec58742b93484195defc01d5cc7809b8f7acb5ece3"}, - {url = "https://files.pythonhosted.org/packages/ef/ac/787d66d62a78b8421c670b66f6234e57f438118b2667744ea9859bb4939c/coverage-6.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc173f1ce9ffb16b299f51c9ce53f66a62f4d975abe5640e976904066f3c835d"}, - {url = "https://files.pythonhosted.org/packages/f4/4c/d85d4a008e6a9604186408613e683732146058694778c7919c784a6271f9/coverage-6.4-cp37-cp37m-win32.whl", hash = "sha256:00c8544510f3c98476bbd58201ac2b150ffbcce46a8c3e4fb89ebf01998f806a"}, - {url = "https://files.pythonhosted.org/packages/f4/72/1c556ddb3d061e5a2ef31a08af5ec5b90cf74c6c8ecb2925fefa8d1df292/coverage-6.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:341e9c2008c481c5c72d0e0dbf64980a4b2238631a7f9780b0fe2e95755fb018"}, - {url = "https://files.pythonhosted.org/packages/fe/44/f64f50af6f25394846e1ab83cf5f0e2e2fa0eb16182dd31892ab2696b9f1/coverage-6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:b84ab65444dcc68d761e95d4d70f3cfd347ceca5a029f2ffec37d4f124f61311"}, -] -"entrypoints 0.3" = [ - {url = "https://files.pythonhosted.org/packages/ac/c6/44694103f8c221443ee6b0041f69e2740d89a25641e62fb4f2ee568f2f9c/entrypoints-0.3-py2.py3-none-any.whl", hash = "sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19"}, - {url = "https://files.pythonhosted.org/packages/b4/ef/063484f1f9ba3081e920ec9972c96664e2edb9fdc3d8669b0e3b8fc0ad7c/entrypoints-0.3.tar.gz", hash = "sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451"}, -] -"flake8 3.8.4" = [ - {url = "https://files.pythonhosted.org/packages/71/6a/b3341ef7e7f3585add027d876a7d9837cdfe3320b6c6b5fd0cddfa9ceeac/flake8-3.8.4.tar.gz", hash = "sha256:aadae8761ec651813c24be05c6f7b4680857ef6afaae4651a4eccaef97ce6c3b"}, - {url = "https://files.pythonhosted.org/packages/d4/ca/3971802ee6251da1abead1a22831d7f4743781e2f743bd266bdd2f46c19b/flake8-3.8.4-py2.py3-none-any.whl", hash = "sha256:749dbbd6bfd0cf1318af27bf97a14e28e5ff548ef8e5b1566ccfb25a11e7c839"}, -] -"flask 1.1.2" = [ - {url = "https://files.pythonhosted.org/packages/4e/0b/cb02268c90e67545a0e3a37ea1ca3d45de3aca43ceb7dbf1712fb5127d5d/Flask-1.1.2.tar.gz", hash = "sha256:4efa1ae2d7c9865af48986de8aeb8504bf32c7f3d6fdc9353d34b21f4b127060"}, - {url = "https://files.pythonhosted.org/packages/f2/28/2a03252dfb9ebf377f40fba6a7841b47083260bf8bd8e737b0c6952df83f/Flask-1.1.2-py2.py3-none-any.whl", hash = "sha256:8a4fdd8936eba2512e9c85df320a37e694c93945b33ef33c89946a340a238557"}, -] -"flask-cors 3.0.9" = [ - {url = "https://files.pythonhosted.org/packages/69/7f/d0aeaaafb5c3c76c8d2141dbe2d4f6dca5d6c31872d4e5349768c1958abc/Flask_Cors-3.0.9-py2.py3-none-any.whl", hash = "sha256:cee4480aaee421ed029eaa788f4049e3e26d15b5affb6a880dade6bafad38324"}, - {url = "https://files.pythonhosted.org/packages/99/fc/cd117ea122e28037a5ec60356a7ffae8b77af527713f7b5e4eb63089f669/Flask-Cors-3.0.9.tar.gz", hash = "sha256:6bcfc100288c5d1bcb1dbb854babd59beee622ffd321e444b05f24d6d58466b8"}, -] -"flask-httpauth 4.1.0" = [ - {url = "https://files.pythonhosted.org/packages/79/a0/ff7dc053f03c49f1614a79171d15f58cc7d824c85b1ba11d0df6ef3aa92b/Flask-HTTPAuth-4.1.0.tar.gz", hash = "sha256:9e028e4375039a49031eb9ecc40be4761f0540476040f6eff329a31dabd4d000"}, - {url = "https://files.pythonhosted.org/packages/e1/a8/c1cda654d5da7ba45bc0bd567cd7e2d2508997decfae5191813f31c93b9e/Flask_HTTPAuth-4.1.0-py2.py3-none-any.whl", hash = "sha256:29e0288869a213c7387f0323b6bf2c7191584fb1da8aa024d9af118e5cd70de7"}, +"coverage 7.2.5" = [ + {url = "https://files.pythonhosted.org/packages/00/ee/67f851378e163e5323671c21d42bf6d059a16c058fbf10338cdf2170c90b/coverage-7.2.5-cp311-cp311-win32.whl", hash = "sha256:30dcaf05adfa69c2a7b9f7dfd9f60bc8e36b282d7ed25c308ef9e114de7fc23b"}, + {url = "https://files.pythonhosted.org/packages/01/97/eb8cdc5a82947efd330c13fd17f7985c20135d7fe7263652cc37481298a7/coverage-7.2.5-cp39-cp39-win_amd64.whl", hash = "sha256:338aa9d9883aaaad53695cb14ccdeb36d4060485bb9388446330bef9c361c252"}, + {url = "https://files.pythonhosted.org/packages/07/59/6f310c6b5e71a3dd374af186eb9b1380f0f34b684e805812ca1e93874748/coverage-7.2.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c587f52c81211d4530fa6857884d37f514bcf9453bdeee0ff93eaaf906a5c1b"}, + {url = "https://files.pythonhosted.org/packages/0b/93/c992d89b11661ab4121c7837a5c6cf3e2eabbbbae668132b5d6b8ad95c41/coverage-7.2.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:857abe2fa6a4973f8663e039ead8d22215d31db613ace76e4a98f52ec919068e"}, + {url = "https://files.pythonhosted.org/packages/0b/bc/42b7b5e0a58f9db7f673c4b0709ba3e8d13e1df4b47a1ef1905ab8e4e24a/coverage-7.2.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ae453f655640157d76209f42c62c64c4d4f2c7f97256d3567e3b439bd5c9b06c"}, + {url = "https://files.pythonhosted.org/packages/0b/f2/a54848d2582917d9a132e0adaa74f0e067191079fa66149c8a431bdfb184/coverage-7.2.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:373ea34dca98f2fdb3e5cb33d83b6d801007a8074f992b80311fc589d3e6b790"}, + {url = "https://files.pythonhosted.org/packages/24/d9/a9b24d946804a27b2a9693593a83732c2823db5d6c0f209a2fa0eba85e41/coverage-7.2.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c2c41c1b1866b670573657d584de413df701f482574bad7e28214a2362cb1fd1"}, + {url = "https://files.pythonhosted.org/packages/28/ae/2d01daabe5dd2652be564f8c49d51b553b1f05a263a1c58e74accb400030/coverage-7.2.5-cp39-cp39-win32.whl", hash = "sha256:ddc5a54edb653e9e215f75de377354e2455376f416c4378e1d43b08ec50acc31"}, + {url = "https://files.pythonhosted.org/packages/2c/22/82903d8d343bf6e174e566a4cf3f767315db4dd52a17d7f0255bff7e56c7/coverage-7.2.5-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6f5cab2d7f0c12f8187a376cc6582c477d2df91d63f75341307fcdcb5d60303"}, + {url = "https://files.pythonhosted.org/packages/30/c6/7f263714255cda41443a6f741654499e2f2ef9925b57aa4e159a81785edc/coverage-7.2.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0342a28617e63ad15d96dca0f7ae9479a37b7d8a295f749c14f3436ea59fdcb3"}, + {url = "https://files.pythonhosted.org/packages/31/65/914b45e732a66c892966e97c0611ee1782b6156627f9478a404b6c7acf5a/coverage-7.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883123d0bbe1c136f76b56276074b0c79b5817dd4238097ffa64ac67257f4b6c"}, + {url = "https://files.pythonhosted.org/packages/34/ef/dfbcd7e5687559cbd04933985707cdeb811c3815336a8bd0ae1077d9f11c/coverage-7.2.5-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2b3b05e22a77bb0ae1a3125126a4e08535961c946b62f30985535ed40e26614"}, + {url = "https://files.pythonhosted.org/packages/36/52/5ffdff100e10385c452ad36ea063ac51b192228a5bd5b21529b96b339833/coverage-7.2.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a22cbb5ede6fade0482111fa7f01115ff04039795d7092ed0db43522431b4f2"}, + {url = "https://files.pythonhosted.org/packages/3c/0a/2ea958a9e8571df2f030f9e3d47add9a9372f06cb2bb01e1e0285383ed53/coverage-7.2.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:38c0a497a000d50491055805313ed83ddba069353d102ece8aef5d11b5faf045"}, + {url = "https://files.pythonhosted.org/packages/3d/87/ac5bb366221fe53c55f5ea83b14d476834703cbb395dcc335a92742737c3/coverage-7.2.5.tar.gz", hash = "sha256:f99ef080288f09ffc687423b8d60978cf3a465d3f404a18d1a05474bd8575a47"}, + {url = "https://files.pythonhosted.org/packages/51/7b/cfcea378640bf97d728b56f5926136062abea89f9a617524a57753f364d8/coverage-7.2.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8e575a59315a91ccd00c7757127f6b2488c2f914096077c745c2f1ba5b8c0969"}, + {url = "https://files.pythonhosted.org/packages/55/67/abfcaf4034db803b31f1d012d0e2f532d87a2d10954cb8ede1eb23079496/coverage-7.2.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a063aad9f7b4c9f9da7b2550eae0a582ffc7623dca1c925e50c3fbde7a579771"}, + {url = "https://files.pythonhosted.org/packages/57/36/5a1c4a5ae9c2a7ab948853f10e129fb159b834e23cca767cf72c6ef2bbcd/coverage-7.2.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:780551e47d62095e088f251f5db428473c26db7829884323e56d9c0c3118791a"}, + {url = "https://files.pythonhosted.org/packages/57/a4/e2002682aea70aa50c07e1bd868fe2d59540d51d90b6f6cbe69558efe5f0/coverage-7.2.5-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:292300f76440651529b8ceec283a9370532f4ecba9ad67d120617021bb5ef139"}, + {url = "https://files.pythonhosted.org/packages/5d/de/ab8f77c21d8ad1682d6db9220e5e1f941a9490d2c1bb1baf50f12f4bee64/coverage-7.2.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1637253b11a18f453e34013c665d8bf15904c9e3c44fbda34c643fbdc9d452cd"}, + {url = "https://files.pythonhosted.org/packages/5f/79/da677806f4745a3c9c11ef9c2a2d4fe969975948dcb158fa967623c3f67c/coverage-7.2.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e8a95f243d01ba572341c52f89f3acb98a3b6d1d5d830efba86033dd3687ade"}, + {url = "https://files.pythonhosted.org/packages/62/fc/4f9be6c0d7fe460990d05ffd2316683bfcd8a94758dde26d2da84487a8af/coverage-7.2.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ef9659d1cda9ce9ac9585c045aaa1e59223b143f2407db0eaee0b61a4f266fb6"}, + {url = "https://files.pythonhosted.org/packages/67/b5/6b5751966ffc4da52b0b68aa60de105ff0666f6e99a58e2beea614df399c/coverage-7.2.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6599bf92f33ab041e36e06d25890afbdf12078aacfe1f1d08c713906e49a3fe5"}, + {url = "https://files.pythonhosted.org/packages/6a/ec/6b12580715aae877303c79e025a7591cad83fb76b4f18eef99e78784e064/coverage-7.2.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:706ec567267c96717ab9363904d846ec009a48d5f832140b6ad08aad3791b1f5"}, + {url = "https://files.pythonhosted.org/packages/6d/87/d1b67b09b4d3e461f5364b1e0cd2bc92e77dd2548964c3c2136bb98d4491/coverage-7.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a66e055254a26c82aead7ff420d9fa8dc2da10c82679ea850d8feebf11074d88"}, + {url = "https://files.pythonhosted.org/packages/71/de/0e70397af146b73c2d8c90f0c5529dc442a3aa09aa461f56844cb8605af0/coverage-7.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f3671662dc4b422b15776cdca89c041a6349b4864a43aa2350b6b0b03bbcc7f"}, + {url = "https://files.pythonhosted.org/packages/73/8f/f77ac8cad6cb3a43da0056306f92dfc27b737c2294b773df8cf010db3f1a/coverage-7.2.5-cp38-cp38-win32.whl", hash = "sha256:10b15394c13544fce02382360cab54e51a9e0fd1bd61ae9ce012c0d1e103c813"}, + {url = "https://files.pythonhosted.org/packages/7f/d3/bb35573b7bebd7aba32b5cfd65a355d6186c607451d9d4fae00a05fd8e1e/coverage-7.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:40cc0f91c6cde033da493227797be2826cbf8f388eaa36a0271a97a332bfd7ce"}, + {url = "https://files.pythonhosted.org/packages/81/72/340c4bc7fc32d1148c483c07561850b95113277cdf3e7d44183ebfd372e8/coverage-7.2.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:156192e5fd3dbbcb11cd777cc469cf010a294f4c736a2b2c891c77618cb1379a"}, + {url = "https://files.pythonhosted.org/packages/88/73/d767f0a8d1713be48a83e62824be98036c99de6ae2780f471901fe3a7d33/coverage-7.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d2fbc2a127e857d2f8898aaabcc34c37771bf78a4d5e17d3e1f5c30cd0cbc62a"}, + {url = "https://files.pythonhosted.org/packages/8a/97/f6173b9937ebab116a5a899aa79c1009141eb894911b65a83cd8cd5c0d1f/coverage-7.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:97072cc90f1009386c8a5b7de9d4fc1a9f91ba5ef2146c55c1f005e7b5c5e068"}, + {url = "https://files.pythonhosted.org/packages/8a/d0/11395768fa7eca73643f4ea177883fdc28a68a1fb7f9102fa6ee180efc44/coverage-7.2.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b9a4ee55174b04f6af539218f9f8083140f61a46eabcaa4234f3c2a452c4ed11"}, + {url = "https://files.pythonhosted.org/packages/9b/a4/ed7f5dc3160fcb3d1f86a8f74c59404aa3d47ad71448a9b9d441df6812c7/coverage-7.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c10fbc8a64aa0f3ed136b0b086b6b577bc64d67d5581acd7cc129af52654384e"}, + {url = "https://files.pythonhosted.org/packages/9c/51/2500745ec2f95703016a71cc0686bed494cdad32de5d1ebaa33dd1d2b187/coverage-7.2.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bebea5f5ed41f618797ce3ffb4606c64a5de92e9c3f26d26c2e0aae292f015c1"}, + {url = "https://files.pythonhosted.org/packages/a0/f7/cfa587948bfd61c6a50ea0c208a98ae92b2368ccbef39621bae02cc49e91/coverage-7.2.5-cp38-cp38-win_amd64.whl", hash = "sha256:a0b273fe6dc655b110e8dc89b8ec7f1a778d78c9fd9b4bda7c384c8906072212"}, + {url = "https://files.pythonhosted.org/packages/a4/45/e7533ed5fe3008f820eee159cfaa4622ac9c5de45f1181c82b6a5b90eb46/coverage-7.2.5-cp310-cp310-win32.whl", hash = "sha256:f81c9b4bd8aa747d417407a7f6f0b1469a43b36a85748145e144ac4e8d303cb5"}, + {url = "https://files.pythonhosted.org/packages/a7/1c/b67259cb5dfe9a94eb65d542d8190cffc609f2d387038228b4f31a3e486b/coverage-7.2.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:bd3b4b8175c1db502adf209d06136c000df4d245105c8839e9d0be71c94aefe1"}, + {url = "https://files.pythonhosted.org/packages/a8/45/7dbfe0658925cc096cd8472f8357367e45f02bea3218121c665fd01d30c4/coverage-7.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:dc945064a8783b86fcce9a0a705abd7db2117d95e340df8a4333f00be5efb64c"}, + {url = "https://files.pythonhosted.org/packages/a8/e0/ea6fe3d440ec24b3f1802b177fa92f69d9df7e3ab11d93bd510258588725/coverage-7.2.5-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:066b44897c493e0dcbc9e6a6d9f8bbb6607ef82367cf6810d387c09f0cd4fe9a"}, + {url = "https://files.pythonhosted.org/packages/af/3c/8c6745ff0c58707a70607ccc63f27b3437494fa98715181a40c44388d789/coverage-7.2.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4436cc9ba5414c2c998eaedee5343f49c02ca93b21769c5fdfa4f9d799e84200"}, + {url = "https://files.pythonhosted.org/packages/bf/e9/5e5f5555812d4afd41fd20af3df85183304213904383b7361088ca2a20a1/coverage-7.2.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:cf97ed82ca986e5c637ea286ba2793c85325b30f869bf64d3009ccc1a31ae3fd"}, + {url = "https://files.pythonhosted.org/packages/c1/af/d56666ff64d15d753bbe6c4db8bba76c244be0b5a51061f2ede35d72dc62/coverage-7.2.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:aa387bd7489f3e1787ff82068b295bcaafbf6f79c3dad3cbc82ef88ce3f48ad3"}, + {url = "https://files.pythonhosted.org/packages/c3/88/3d53153687a291cbbcb968d542b3cdd8574246d863fa6aeaad1afb3dc529/coverage-7.2.5-cp37-cp37m-win32.whl", hash = "sha256:509ecd8334c380000d259dc66feb191dd0a93b21f2453faa75f7f9cdcefc0718"}, + {url = "https://files.pythonhosted.org/packages/cc/9c/c79d54b85a00014f466bc967166c9c495e7f06747d26fbd4fec531fb69dd/coverage-7.2.5-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8834e5f17d89e05697c3c043d3e58a8b19682bf365048837383abfe39adaed5"}, + {url = "https://files.pythonhosted.org/packages/d0/01/4a26714b925a9ff8fd54ffebe45471111eef2f1529790a745824f8958864/coverage-7.2.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7ff8f3fb38233035028dbc93715551d81eadc110199e14bbbfa01c5c4a43f8d8"}, + {url = "https://files.pythonhosted.org/packages/d6/54/5ef3171884fff597781f21f683ddb9dd2c35f05af2947aaec0b6d183dbce/coverage-7.2.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b5016e331b75310610c2cf955d9f58a9749943ed5f7b8cfc0bb89c6134ab0a84"}, + {url = "https://files.pythonhosted.org/packages/e6/2f/28a781aecd2d95ecf890cf1a078e021003aea94f307d96db6ec20e90c85e/coverage-7.2.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:a08c7401d0b24e8c2982f4e307124b671c6736d40d1c39e09d7a8687bddf83ed"}, + {url = "https://files.pythonhosted.org/packages/e7/53/3b2c1fb37a990f1a8987e000e7a74ab93646ad287b562f4d5bc113e0665f/coverage-7.2.5-cp37-cp37m-win_amd64.whl", hash = "sha256:12580845917b1e59f8a1c2ffa6af6d0908cb39220f3019e36c110c943dc875b0"}, + {url = "https://files.pythonhosted.org/packages/ed/c7/28ed5ec209f79197b0f9a0b74d1b0d34b513f744eda2e828376cfb13a49f/coverage-7.2.5-pp37.pp38.pp39-none-any.whl", hash = "sha256:8877d9b437b35a85c18e3c6499b23674684bf690f5d96c1006a1ef61f9fdf0f3"}, + {url = "https://files.pythonhosted.org/packages/ef/7a/78d45957963d4a85301ece73cb46352e59dbf17a38d4412542b074cbae87/coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, + {url = "https://files.pythonhosted.org/packages/f6/5c/8aec846dd51d4d374ea87689f24b3ee93b023020160141456f51986aac54/coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, +] +"flake8 6.0.0" = [ + {url = "https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, + {url = "https://files.pythonhosted.org/packages/d9/6a/bb0122ebe280476c924470779d2595f1403878cafe3c8a343ac56a5a9c0e/flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, +] +"flask 2.3.2" = [ + {url = "https://files.pythonhosted.org/packages/4d/00/ef81c18da32fdfcde6381c315f4b11597fb6691180a330418848efee0ae7/Flask-2.3.2.tar.gz", hash = "sha256:8c2f9abd47a9e8df7f0c3f091ce9497d011dc3b31effcf4c85a6e2b50f4114ef"}, + {url = "https://files.pythonhosted.org/packages/fa/1a/f191d32818e5cd985bdd3f47a6e4f525e2db1ce5e8150045ca0c31813686/Flask-2.3.2-py3-none-any.whl", hash = "sha256:77fd4e1249d8c9923de34907236b747ced06e5467ecac1a7bb7115ae0e9670b0"}, +] +"flask-cors 3.0.10" = [ + {url = "https://files.pythonhosted.org/packages/cf/25/e3b2553d22ed542be807739556c69621ad2ab276ae8d5d2560f4ed20f652/Flask-Cors-3.0.10.tar.gz", hash = "sha256:b60839393f3b84a0f3746f6cdca56c1ad7426aa738b70d6c61375857823181de"}, + {url = "https://files.pythonhosted.org/packages/db/84/901e700de86604b1c4ef4b57110d4e947c218b9997adf5d38fa7da493bce/Flask_Cors-3.0.10-py2.py3-none-any.whl", hash = "sha256:74efc975af1194fc7891ff5cd85b0f7478be4f7f59fe158102e91abb72bb4438"}, +] +"flask-httpauth 4.8.0" = [ + {url = "https://files.pythonhosted.org/packages/22/21/0160aa217c4df74e44a04919213f9c8af7e68551c10267b055f1e09d421c/Flask-HTTPAuth-4.8.0.tar.gz", hash = "sha256:66568a05bc73942c65f1e2201ae746295816dc009edd84b482c44c758d75097a"}, + {url = "https://files.pythonhosted.org/packages/83/c4/e64ace124b927cd1f29270050ee0e0ef5faad75a512c5c8d733961dda9ca/Flask_HTTPAuth-4.8.0-py3-none-any.whl", hash = "sha256:a58fedd09989b9975448eef04806b096a3964a7feeebc0a78831ff55685b62b0"}, ] "flask-mail 0.9.1" = [ {url = "https://files.pythonhosted.org/packages/05/2f/6a545452040c2556559779db87148d2a85e78a26f90326647b51dc5e81e9/Flask-Mail-0.9.1.tar.gz", hash = "sha256:22e5eb9a940bf407bcf30410ecc3708f3c56cc44b29c34e1726fe85006935f41"}, ] -"flask-migrate 2.5.3" = [ - {url = "https://files.pythonhosted.org/packages/75/3e/5675d46efdb62eb369bc951c7107657bea9ddf20cea65dab9816dc27e6ee/Flask-Migrate-2.5.3.tar.gz", hash = "sha256:a69d508c2e09d289f6e55a417b3b8c7bfe70e640f53d2d9deb0d056a384f37ee"}, - {url = "https://files.pythonhosted.org/packages/e5/64/c75f173ba5420f5174be6f04dfa8d8250d4808c12a9cd781e84c0b31684f/Flask_Migrate-2.5.3-py2.py3-none-any.whl", hash = "sha256:4dc4a5cce8cbbb06b8dc963fd86cf8136bd7d875aabe2d840302ea739b243732"}, -] -"flask-restful 0.3.8" = [ - {url = "https://files.pythonhosted.org/packages/67/65/84f3218666fc115497a13ff727f16d02374d07d1924cd4fd72e275294e8b/Flask-RESTful-0.3.8.tar.gz", hash = "sha256:5ea9a5991abf2cb69b4aac19793faac6c032300505b325687d7c305ffaa76915"}, - {url = "https://files.pythonhosted.org/packages/e9/83/d0d33c971de2d38e54b0037136c8b8d20b9c83d308bc6c220a25162755fd/Flask_RESTful-0.3.8-py2.py3-none-any.whl", hash = "sha256:d891118b951921f1cec80cabb4db98ea6058a35e6404788f9e70d5b243813ec2"}, +"flask-migrate 4.0.4" = [ + {url = "https://files.pythonhosted.org/packages/a9/70/1286459e3dac091dbe9d7101973ac97eec5c2e0508e276e21f492fb7edf8/Flask-Migrate-4.0.4.tar.gz", hash = "sha256:73293d40b10ac17736e715b377e7b7bde474cb8105165d77474df4c3619b10b3"}, + {url = "https://files.pythonhosted.org/packages/e4/65/9e0a6ce67e1776b0d8a4ebcd40ee519b6c8339a62b05dbc9b153c0d6a17b/Flask_Migrate-4.0.4-py3-none-any.whl", hash = "sha256:77580f27ab39bc68be4906a43c56d7674b45075bc4f883b1d0b985db5164d58f"}, ] -"flask-script 2.0.6" = [ - {url = "https://files.pythonhosted.org/packages/00/a4/cd587b2b19f043b65bf33ceda2f6e4e6cdbd0ce18d01a52b9559781b1da6/Flask-Script-2.0.6.tar.gz", hash = "sha256:6425963d91054cfcc185807141c7314a9c5ad46325911bd24dcb489bd0161c65"}, +"flask-restful 0.3.9" = [ + {url = "https://files.pythonhosted.org/packages/5c/50/4892719b13abd401f40a69359c3d859d0ea76bf78e66db058d6c06a95b01/Flask-RESTful-0.3.9.tar.gz", hash = "sha256:ccec650b835d48192138c85329ae03735e6ced58e9b2d9c2146d6c84c06fa53e"}, + {url = "https://files.pythonhosted.org/packages/a9/02/7e21a73564fe0d9d1a3a4ff478dfc407815c4e2fa4e5121bcfc646ba5d15/Flask_RESTful-0.3.9-py2.py3-none-any.whl", hash = "sha256:4970c49b6488e46c520b325f54833374dc2b98e211f1b272bd4b0c516232afe2"}, ] -"flask-sqlalchemy 2.4.4" = [ - {url = "https://files.pythonhosted.org/packages/af/4b/3dd83c3e2c6e3034b804d971952e0120606506f153990cc56d2d33173b72/Flask_SQLAlchemy-2.4.4-py2.py3-none-any.whl", hash = "sha256:05b31d2034dd3f2a685cbbae4cfc4ed906b2a733cff7964ada450fd5e462b84e"}, - {url = "https://files.pythonhosted.org/packages/cc/d3/58d45c266b1c6e9f54a12af54f444547b142f6312e4520c771de0171d031/Flask-SQLAlchemy-2.4.4.tar.gz", hash = "sha256:bfc7150eaf809b1c283879302f04c42791136060c6eeb12c0c6674fb1291fae5"}, +"flask-sqlalchemy 3.0.3" = [ + {url = "https://files.pythonhosted.org/packages/7a/33/b0418aaeb6b122fccfdea1bf3c06843225ba29159b65c0acf9bd4285ee01/Flask-SQLAlchemy-3.0.3.tar.gz", hash = "sha256:2764335f3c9d7ebdc9ed6044afaf98aae9fa50d7a074cef55dde307ec95903ec"}, + {url = "https://files.pythonhosted.org/packages/cf/93/606d1967d6ef1c663ccccc739b361e7672ec057bf086ca7e4cd23eda18a9/Flask_SQLAlchemy-3.0.3-py3-none-any.whl", hash = "sha256:add5750b2f9cd10512995261ee2aa23fab85bd5626061aa3c564b33bb4aa780a"}, ] "flask-swagger 0.2.14" = [ {url = "https://files.pythonhosted.org/packages/18/78/2da3bf35a978127085ae6aff85d601b8842a4204fe88a506e23d0c79acc7/flask_swagger-0.2.14-py2-none-any.whl", hash = "sha256:3caddb1311388eafc86f82f8e64ba386a5df6b84e5f16dfae19ca08173eba216"}, {url = "https://files.pythonhosted.org/packages/b2/a9/a6c05fbc592ac482bf9557e47957c429d2be8cb8addfbc92853fb862ea8f/flask-swagger-0.2.14.tar.gz", hash = "sha256:b4085f5bc36df4c20b6548cd1413adc9cf35719b0f0695367cd542065145294d"}, ] -"geoalchemy2 0.8.4" = [ - {url = "https://files.pythonhosted.org/packages/5e/5a/d09752518763988e8d00aaade2a34db4fa5f0079aa5fcb0ac0a7877b5f3c/GeoAlchemy2-0.8.4-py2.py3-none-any.whl", hash = "sha256:3b83654db15ed807a7bdb2e7dd1c787a47cfc3e4fb92a0558685001fbb7342da"}, - {url = "https://files.pythonhosted.org/packages/85/51/47573b93570c2f3650814a720d9168ea471b80bbc4fb437f2b08e7d761e7/GeoAlchemy2-0.8.4.tar.gz", hash = "sha256:d9336f17df3e7a10f94d1ea2488dcfb97a8bc23fe7f5edea425ddab553534b0a"}, -] -"geojson 1.3.4" = [ - {url = "https://files.pythonhosted.org/packages/2c/43/4077328fbff35d22a4b567312f4165df7d992b8de19b0e5b8241d191fe5a/geojson-1.3.4-py2.py3-none-any.whl", hash = "sha256:4e479152223799e07126eb81eb495842395e2ea5859a8511553ed3104e84b087"}, - {url = "https://files.pythonhosted.org/packages/93/74/4f7fa364c746b0f22de13631c932f873d6dce5d3e72a15637c6e9218485e/geojson-1.3.4.tar.gz", hash = "sha256:b9dfe2dded0c7f7702730cc9de65ca33c577bd08c8b24b824bc6d19b32612917"}, -] -"gevent 21.12.0" = [ - {url = "https://files.pythonhosted.org/packages/01/a9/25e746c7ab4d8a80747b8ec13355b011941a680034be1b74d58d73a00c54/gevent-21.12.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d86438ede1cbe0fde6ef4cc3f72bf2f1ecc9630d8b633ff344a3aeeca272cdd"}, - {url = "https://files.pythonhosted.org/packages/06/01/8b8fd7868c423a001aba295952f8728ac64537116ad85a5a78e640e67149/gevent-21.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:0082d8a5d23c35812ce0e716a91ede597f6dd2c5ff508a02a998f73598c59397"}, - {url = "https://files.pythonhosted.org/packages/08/37/c5a40fc5be9f03f8d872b8b27f62be88abd3acf1166f7b1d1154fdd80437/gevent-21.12.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f289fae643a3f1c3b909d6b033e6921b05234a4907e9c9c8c3f1fe403e6ac452"}, - {url = "https://files.pythonhosted.org/packages/09/df/b0a1265a8891186fe239c58041ff7534b37e5fba76cf91e3517490d9cc2f/gevent-21.12.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08b4c17064e28f4eb85604486abc89f442c7407d2aed249cf54544ce5c9baee6"}, - {url = "https://files.pythonhosted.org/packages/0c/48/fe934fe1394c747fe3f47fa2b1ab82539c14875f40b522078ac5bbe7094e/gevent-21.12.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e1899b921219fc8959ff9afb94dae36be82e0769ed13d330a393594d478a0b3a"}, - {url = "https://files.pythonhosted.org/packages/0f/30/ca9a6aabca8c6a2b9b0c8559751b4383e9bc91a7c6aff33650a2cfe8817d/gevent-21.12.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:24d3550fbaeef5fddd794819c2853bca45a86c3d64a056a2c268d981518220d1"}, - {url = "https://files.pythonhosted.org/packages/12/be/84a4633ce3279f9afea43e745f35f906bd1ec6fe93728f889b0743edf8db/gevent-21.12.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:542ae891e2aa217d2cf6d8446538fcd2f3263a40eec123b970b899bac391c47a"}, - {url = "https://files.pythonhosted.org/packages/14/6a/c39a5c3cc3c2f924b3b4a3571a5a7f926a1f32bdadc19f9731907c6b20af/gevent-21.12.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ccffcf708094564e442ac6fde46f0ae9e40015cb69d995f4b39cc29a7643881"}, - {url = "https://files.pythonhosted.org/packages/34/37/f00485d24cad0c77ebd28375b43074fec219c0dc32a64fd9dcd627a98f07/gevent-21.12.0-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:eae3c46f9484eaacd67ffcdf4eaf6ca830f587edd543613b0f5c4eb3c11d052d"}, - {url = "https://files.pythonhosted.org/packages/37/b8/c24f05f8116021b90ce5ea98d1da161b6c5f3794d32ae1671485be2b9f81/gevent-21.12.0-cp39-cp39-win32.whl", hash = "sha256:2bcec9f80196c751fdcf389ca9f7141e7b0db960d8465ed79be5e685bfcad682"}, - {url = "https://files.pythonhosted.org/packages/3d/02/c82d67283bd8d4e95a5175c4f31479127cc261574486ef851b5a3502e784/gevent-21.12.0-cp37-cp37m-win32.whl", hash = "sha256:6a02a88723ed3f0fd92cbf1df3c4cd2fbd87d82b0a4bac3e36a8875923115214"}, - {url = "https://files.pythonhosted.org/packages/58/18/9681e7dc22bf2f82103eb585b925b55c840f285394595b5c62b64750b849/gevent-21.12.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:973749bacb7bc4f4181a8fb2a7e0e2ff44038de56d08e856dd54a5ac1d7331b4"}, - {url = "https://files.pythonhosted.org/packages/59/35/1315f0fbaab94480db99da0c89ecb2ecbd95bb6ddde7cb0dc65efeaf1851/gevent-21.12.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:da8d2d51a49b2a5beb02ad619ca9ddbef806ef4870ba04e5ac7b8b41a5b61db3"}, - {url = "https://files.pythonhosted.org/packages/60/64/d81b3b72dd9a874e839338c79dbf581d1cf21453e6b55f295fca8560be28/gevent-21.12.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cfff82f05f14b7f5d9ed53ccb7a609ae8604df522bb05c971bca78ec9d8b2b9"}, - {url = "https://files.pythonhosted.org/packages/63/3f/151963a02af4fe2fafdcba006952fb0ee60d02ca826fd3d840faeb77434a/gevent-21.12.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c43f081cbca41d27fd8fef9c6a32cf83cb979345b20abc07bf68df165cdadb24"}, - {url = "https://files.pythonhosted.org/packages/63/57/d9d28fa16802d34b60592f4a5e669cd64561293e220d553cd5a32e1553c3/gevent-21.12.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01928770972181ad8866ee37ea3504f1824587b188fcab782ef1619ce7538766"}, - {url = "https://files.pythonhosted.org/packages/68/13/95b3272019d69984ba044c6783de5efea76b0d92c97d96bfe832ec7dc6fa/gevent-21.12.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05c5e8a50cd6868dd36536c92fb4468d18090e801bd63611593c0717bab63692"}, - {url = "https://files.pythonhosted.org/packages/68/16/c7e6c784892156dd59af35e0fe90013856c211d928687d35261560c66900/gevent-21.12.0-cp36-cp36m-win32.whl", hash = "sha256:bb5cb8db753469c7a9a0b8a972d2660fe851aa06eee699a1ca42988afb0aaa02"}, - {url = "https://files.pythonhosted.org/packages/78/3f/30fa7c7220f3136b5772bbe8a66e2932349c7fbde4c1b6e182efb633884c/gevent-21.12.0-cp38-cp38-win32.whl", hash = "sha256:3c012c73e6c61f13c75e3a4869dbe6a2ffa025f103421a6de9c85e627e7477b1"}, - {url = "https://files.pythonhosted.org/packages/7d/2d/f16b57647a76bd198fe9cf996e62691eb173d0eb49efc05e242431a453e9/gevent-21.12.0-pp27-pypy_73-win_amd64.whl", hash = "sha256:9f9652d1e4062d4b5b5a0a49ff679fa890430b5f76969d35dccb2df114c55e0f"}, - {url = "https://files.pythonhosted.org/packages/7d/ad/99526612968eb149b3f764039711a7b39419b551bde4652eae26fa5c3345/gevent-21.12.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:7909780f0cf18a1fc32aafd8c8e130cdd93c6e285b11263f7f2d1a0f3678bc50"}, - {url = "https://files.pythonhosted.org/packages/7f/3b/68ca4c78ba8b3be60ff4b871bf8c6f8ac2fb1fd729cd2978b20f29d6b3be/gevent-21.12.0-cp27-cp27m-win32.whl", hash = "sha256:177f93a3a90f46a5009e0841fef561601e5c637ba4332ab8572edd96af650101"}, - {url = "https://files.pythonhosted.org/packages/83/6c/8850930977a298679c03ad597650976e109d00c2c10021975e37f2f2eebf/gevent-21.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:3dad62f55fad839d498c801e139481348991cee6e1c7706041b5fe096cb6a279"}, - {url = "https://files.pythonhosted.org/packages/a0/d4/f6623fb3cc772bad5f7a75c4e24af884104a2be07699cb76a49958ef3260/gevent-21.12.0-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:3baeeccc4791ba3f8db27179dff11855a8f9210ddd754f6c9b48e0d2561c2aea"}, - {url = "https://files.pythonhosted.org/packages/ba/56/76e5ae7008fa4b391c156b6c01ae25fd8b439057015c5469411550db41a5/gevent-21.12.0-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:74fc1ef16b86616cfddcc74f7292642b0f72dde4dd95aebf4c45bb236744be54"}, - {url = "https://files.pythonhosted.org/packages/bd/83/d54947d3648364e06065eb0031c238463e4ffed7b689021c3c60aa49406e/gevent-21.12.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:2afa3f3ad528155433f6ac8bd64fa5cc303855b97004416ec719a6b1ca179481"}, - {url = "https://files.pythonhosted.org/packages/c4/e1/e084f18256b29a660858321f9240981dd1031ec184a48c983391f7196268/gevent-21.12.0-cp27-cp27m-win_amd64.whl", hash = "sha256:a5ad4ed8afa0a71e1927623589f06a9b5e8b5e77810be3125cb4d93050d3fd1f"}, - {url = "https://files.pythonhosted.org/packages/c7/fd/79aee4437e2f181a460b2fb3d88a37d58811353f1b00cf01eeb27187b40e/gevent-21.12.0-cp38-cp38-win_amd64.whl", hash = "sha256:b7709c64afa8bb3000c28bb91ec42c79594a7cb0f322e20427d57f9762366a5b"}, - {url = "https://files.pythonhosted.org/packages/c8/0a/607129ea9ffb024019422b2af055de9afd08f1c78f5a0ff590b83bc85f58/gevent-21.12.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc2fef0f98ee180704cf95ec84f2bc2d86c6c3711bb6b6740d74e0afe708b62c"}, - {url = "https://files.pythonhosted.org/packages/c8/18/631398e45c109987f2d8e57f3adda161cc5ff2bd8738ca830c3a2dd41a85/gevent-21.12.0.tar.gz", hash = "sha256:f48b64578c367b91fa793bf8eaaaf4995cb93c8bc45860e473bf868070ad094e"}, - {url = "https://files.pythonhosted.org/packages/cd/82/291bb4e2fa64a2845d38cb0021f357ae2bce6a41ee9851b0d9494de2d21b/gevent-21.12.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:ec21f9eaaa6a7b1e62da786132d6788675b314f25f98d9541f1bf00584ed4749"}, - {url = "https://files.pythonhosted.org/packages/d2/f1/023aa23faaedcc713e6662386a6ccfeea4df41c663ce54964b674838ae08/gevent-21.12.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c21cb5c9f4e14d75b3fe0b143ec875d7dbd1495fad6d49704b00e57e781ee0f"}, - {url = "https://files.pythonhosted.org/packages/e8/40/826e541d8fec71a3725bdd0a45fbb66999a3c9031145d36580f233fa96c4/gevent-21.12.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:22ce1f38fdfe2149ffe8ec2131ca45281791c1e464db34b3b4321ae9d8d2efbb"}, -] -"glob2 0.7" = [ - {url = "https://files.pythonhosted.org/packages/d7/a5/bbbc3b74a94fbdbd7915e7ad030f16539bfdc1362f7e9003b594f0537950/glob2-0.7.tar.gz", hash = "sha256:85c3dbd07c8aa26d63d7aacee34fa86e9a91a3873bc30bf62ec46e531f92ab8c"}, -] -"greenlet 1.1.2" = [ - {url = "https://files.pythonhosted.org/packages/07/59/f4656193ac084b7134dcf5f5d4d5c4d3a154d222202eecf00b367d367e90/greenlet-1.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:14d4f3cd4e8b524ae9b8aa567858beed70c392fdec26dbdb0a8a418392e71708"}, - {url = "https://files.pythonhosted.org/packages/07/97/6f07d888c4fce65ec4fb2177e75d45e604789eb075a09946dd7e7f88e790/greenlet-1.1.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:f3acda1924472472ddd60c29e5b9db0cec629fbe3c5c5accb74d6d6d14773478"}, - {url = "https://files.pythonhosted.org/packages/08/c6/0bd71c28d7f318ce4a73c6d8d26130233863070f418e5c340ffb7fa609da/greenlet-1.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:572e1787d1460da79590bf44304abbc0a2da944ea64ec549188fa84d89bba7ab"}, - {url = "https://files.pythonhosted.org/packages/0c/10/754e21b5bea89d0e73f99d60c83754df7cc64db74f47d98ab187669ce341/greenlet-1.1.2.tar.gz", hash = "sha256:e30f5ea4ae2346e62cedde8794a56858a67b878dd79f7df76a0767e356b1744a"}, - {url = "https://files.pythonhosted.org/packages/1e/08/63a6757e95589b293d753637a63e951587f9e2cd16e331eaff3c1c47e445/greenlet-1.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9f3cba480d3deb69f6ee2c1825060177a22c7826431458c697df88e6aeb3caee"}, - {url = "https://files.pythonhosted.org/packages/2f/5a/28d7f5d3afddf2669f68f9779b71946a6903c89af1dcfd750a14ce3b55c7/greenlet-1.1.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7227b47e73dedaa513cdebb98469705ef0d66eb5a1250144468e9c3097d6b59b"}, - {url = "https://files.pythonhosted.org/packages/30/1c/5f4df8816093dbfc8ded8b53ab672223deeb39e9dec6a48aaf278c52df99/greenlet-1.1.2-cp38-cp38-win32.whl", hash = "sha256:288c6a76705dc54fba69fbcb59904ae4ad768b4c768839b8ca5fdadec6dd8cfd"}, - {url = "https://files.pythonhosted.org/packages/3d/2a/076407f5f68ec0c3063e0e60d37a23fe2d9dd43014c2aa99d19200f2ef66/greenlet-1.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:903bbd302a2378f984aef528f76d4c9b1748f318fe1294961c072bdc7f2ffa3e"}, - {url = "https://files.pythonhosted.org/packages/40/10/fea5c3ddfb6230e403a1dd6c7a1d1620d2fe096ac43f9ff4fb6a3057ab9b/greenlet-1.1.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8c790abda465726cfb8bb08bd4ca9a5d0a7bd77c7ac1ca1b839ad823b948ea28"}, - {url = "https://files.pythonhosted.org/packages/44/19/9a5f20b0e02e300a2d0a5c3743acd23e02491c63e1b68de26158dc07b9ae/greenlet-1.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e12bdc622676ce47ae9abbf455c189e442afdde8818d9da983085df6312e7a1"}, - {url = "https://files.pythonhosted.org/packages/44/5e/b3acc744a11f35d3109fef1217aea849d244a39f814241bb299f5ad41964/greenlet-1.1.2-cp27-cp27m-win32.whl", hash = "sha256:aa5b467f15e78b82257319aebc78dd2915e4c1436c3c0d1ad6f53e47ba6e2713"}, - {url = "https://files.pythonhosted.org/packages/44/a9/9cffabbae4b85e2ff8622c2f8b2247657885bac1555186f3e34f3e4a2d08/greenlet-1.1.2-cp37-cp37m-win32.whl", hash = "sha256:64e6175c2e53195278d7388c454e0b30997573f3f4bd63697f88d855f7a6a1fc"}, - {url = "https://files.pythonhosted.org/packages/45/ef/63d2b5d09b07dd45e9f8564f9875e3d57f46e7714896703abe0c9fcc1ec9/greenlet-1.1.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:93f81b134a165cc17123626ab8da2e30c0455441d4ab5576eed73a64c025b25c"}, - {url = "https://files.pythonhosted.org/packages/47/20/433693ac90ae70c8577bf4896951859e8d293e59df5818073033f181ee7b/greenlet-1.1.2-cp310-cp310-macosx_10_14_x86_64.whl", hash = "sha256:8639cadfda96737427330a094476d4c7a56ac03de7265622fcf4cfe57c8ae18d"}, - {url = "https://files.pythonhosted.org/packages/47/c6/049c29ded17c356b8894458fe21c4e37d5746f6a99b17c07bad1189c2938/greenlet-1.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:fdcec0b8399108577ec290f55551d926d9a1fa6cad45882093a7a07ac5ec147b"}, - {url = "https://files.pythonhosted.org/packages/4d/70/8bc33ca00820dcae9ad0c7cae19088a45faf386e6d467de015655de395ce/greenlet-1.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b1692f7d6bc45e3200844be0dba153612103db241691088626a33ff1f24a0d88"}, - {url = "https://files.pythonhosted.org/packages/4e/33/2eb5b46e3f1f46b24ff09d04ff227520273820f6be9e2176ea5e39063b3f/greenlet-1.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:8d2f1fb53a421b410751887eb4ff21386d119ef9cde3797bf5e7ed49fb51a3b3"}, - {url = "https://files.pythonhosted.org/packages/4e/39/71870a73ac498c5af423c566bb9ac6c3a3b2147acfa35ed44a9ccc41fab1/greenlet-1.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:abb7a75ed8b968f3061327c433a0fbd17b729947b400747c334a9c29a9af6c58"}, - {url = "https://files.pythonhosted.org/packages/61/f1/314caccf5e024d43801d9efff6facef52528bdfe2f3f3ef0883ae53c17cb/greenlet-1.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0051c6f1f27cb756ffc0ffbac7d2cd48cb0362ac1736871399a739b2885134d3"}, - {url = "https://files.pythonhosted.org/packages/65/62/eb54724f4a4e606c3e46503b55923dd67696395da8f502c835ff5adbefd8/greenlet-1.1.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:fa877ca7f6b48054f847b61d6fa7bed5cebb663ebc55e018fda12db09dcc664c"}, - {url = "https://files.pythonhosted.org/packages/71/49/55a19e26db17ceb77da6855453282af3a6b56f8936579a851a4b2c9f49db/greenlet-1.1.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:7418b6bfc7fe3331541b84bb2141c9baf1ec7132a7ecd9f375912eca810e714e"}, - {url = "https://files.pythonhosted.org/packages/72/2d/53428626ef5cd9837701cfc49d2a60ecefe8e0737c345b5547b1d88dd739/greenlet-1.1.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:00e44c8afdbe5467e4f7b5851be223be68adb4272f44696ee71fe46b7036a711"}, - {url = "https://files.pythonhosted.org/packages/76/5a/a6a693096353c1c17932b21ae864a0280e420fadd2f14399a00b085d3d1b/greenlet-1.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:dd0b1e9e891f69e7675ba5c92e28b90eaa045f6ab134ffe70b52e948aa175b3c"}, - {url = "https://files.pythonhosted.org/packages/87/8a/02881e7abe67c4cd9bae211b12031b53c3edf71ee0ffff170e9a16297610/greenlet-1.1.2-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:95e69877983ea39b7303570fa6760f81a3eec23d0e3ab2021b7144b94d06202d"}, - {url = "https://files.pythonhosted.org/packages/89/75/73d6dccf264a490eb52a36e24ada058b1f5f0e45cbd0cd4cab5bff587416/greenlet-1.1.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:58df5c2a0e293bf665a51f8a100d3e9956febfbf1d9aaf8c0677cf70218910c6"}, - {url = "https://files.pythonhosted.org/packages/9c/aa/49ab5629df48b08c9e509b98a7b2b9f67c923ae800c8d09d7af31e49ecb7/greenlet-1.1.2-cp39-cp39-win32.whl", hash = "sha256:f70a9e237bb792c7cc7e44c531fd48f5897961701cdaa06cf22fc14965c496cf"}, - {url = "https://files.pythonhosted.org/packages/9e/dc/0b1aeaa008144d3d503113aa4c5c3c46311b9942f77c1ae337d04fb703dc/greenlet-1.1.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eff9d20417ff9dcb0d25e2defc2574d10b491bf2e693b4e491914738b7908168"}, - {url = "https://files.pythonhosted.org/packages/a1/b6/949a07551279b770d49efe18e1a732a53a45cf76c5f5981ee6ebd17eab19/greenlet-1.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:eb6ea6da4c787111adf40f697b4e58732ee0942b5d3bd8f435277643329ba627"}, - {url = "https://files.pythonhosted.org/packages/aa/cb/e500854d5bfdfe5fc36e0420845e79f4b52df3c11ca73838f19ebebc1ad2/greenlet-1.1.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21915eb821a6b3d9d8eefdaf57d6c345b970ad722f856cd71739493ce003ad08"}, - {url = "https://files.pythonhosted.org/packages/aa/e0/d6e21c642a477fc97aa667c64c8100fe4a63dd39e9b2dc3faafcfd03bef0/greenlet-1.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f276df9830dba7a333544bd41070e8175762a7ac20350786b322b714b0e654f5"}, - {url = "https://files.pythonhosted.org/packages/af/55/e60bc4c2bd7cad081a29f2e046f1e28e45e8529025c07ce725a84d235312/greenlet-1.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ff61ff178250f9bb3cd89752df0f1dd0e27316a8bd1465351652b1b4a4cdfd3"}, - {url = "https://files.pythonhosted.org/packages/b0/37/be7fd0a351a4e52b72857e24115159754a38d11d41bf9861b607330e3934/greenlet-1.1.2-cp36-cp36m-win32.whl", hash = "sha256:32ca72bbc673adbcfecb935bb3fb1b74e663d10a4b241aaa2f5a75fe1d1f90aa"}, - {url = "https://files.pythonhosted.org/packages/b2/b1/30895f5467c5552bd863b72961b977db95094d3017c39c265cc34f2f7cd8/greenlet-1.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:40b951f601af999a8bf2ce8c71e8aaa4e8c6f78ff8afae7b808aae2dc50d4c40"}, - {url = "https://files.pythonhosted.org/packages/b2/c2/141916d37869e817cf18a590de62e8bc732e602ed6d2786c09f4b365f2cf/greenlet-1.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b336501a05e13b616ef81ce329c0e09ac5ed8c732d9ba7e3e983fcc1a9e86965"}, - {url = "https://files.pythonhosted.org/packages/b7/55/0e1a2c02f043b9fc698e70c6ef247b233c82791a78466929352fefcae5e8/greenlet-1.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:97e5306482182170ade15c4b0d8386ded995a07d7cc2ca8f27958d34d6736497"}, - {url = "https://files.pythonhosted.org/packages/b7/6d/c769c05ece064dac69ab8f54a680b8b63374c745f711da54333a9a75f498/greenlet-1.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f0214eb2a23b85528310dad848ad2ac58e735612929c8072f6093f3585fd342d"}, - {url = "https://files.pythonhosted.org/packages/bb/7b/2ac66aa5f9b7e07d62cd6c2c95d44036b609bda80e8739202e3551ee7bf3/greenlet-1.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:013d61294b6cd8fe3242932c1c5e36e5d1db2c8afb58606c5a67efce62c1f5fd"}, - {url = "https://files.pythonhosted.org/packages/bd/66/143727df72394e768381c3a0e4491edf7c32e786b06f1e4eb5f1753342c7/greenlet-1.1.2-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:aec52725173bd3a7b56fe91bc56eccb26fbdff1386ef123abb63c84c5b43b63a"}, - {url = "https://files.pythonhosted.org/packages/c5/c8/9f41dabc0542f6d1d9e746bd530666ba44b2609533de22e723dc3c160273/greenlet-1.1.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:be5f425ff1f5f4b3c1e33ad64ab994eed12fc284a6ea71c5243fd564502ecbe5"}, - {url = "https://files.pythonhosted.org/packages/cf/cc/1654905f4806009352e60fdfc48cf0573cef8bf519457c6c06ee21d31112/greenlet-1.1.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:17ff94e7a83aa8671a25bf5b59326ec26da379ace2ebc4411d690d80a7fbcf23"}, - {url = "https://files.pythonhosted.org/packages/d0/bf/e6d86812a6d81536afbb4ad0a7a9793fd2d31268a6dabbc9d82534eab5fa/greenlet-1.1.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e6a36bb9474218c7a5b27ae476035497a6990e21d04c279884eb10d9b290f1b1"}, - {url = "https://files.pythonhosted.org/packages/d1/1d/06bf7031a22617197acd5c8427934cc32472bd7887313c82beeaea174d77/greenlet-1.1.2-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b92e29e58bef6d9cfd340c72b04d74c4b4e9f70c9fa7c78b674d1fec18896dc4"}, - {url = "https://files.pythonhosted.org/packages/d4/00/7474a1f27efa5c023fe114d84801fe2ded66db2fa5e72253d698b9a95a2a/greenlet-1.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec8c433b3ab0419100bd45b47c9c8551248a5aee30ca5e9d399a0b57ac04651b"}, - {url = "https://files.pythonhosted.org/packages/d7/6a/3d73858eeea865303319c71115e794cd789453eefe281225548f1f95d96e/greenlet-1.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8c5d5b35f789a030ebb95bff352f1d27a93d81069f2adb3182d99882e095cefe"}, - {url = "https://files.pythonhosted.org/packages/d9/e1/37db23293372c8b077675832b2f6a4ff3168a451c40bd329588825aa02dd/greenlet-1.1.2-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:166eac03e48784a6a6e0e5f041cfebb1ab400b394db188c48b3a84737f505b67"}, - {url = "https://files.pythonhosted.org/packages/da/87/d99bc105cf88b538efcf7e593083f3b4c15be9a081099f534cb25759b997/greenlet-1.1.2-cp35-cp35m-win32.whl", hash = "sha256:7cbd7574ce8e138bda9df4efc6bf2ab8572c9aff640d8ecfece1b006b68da963"}, - {url = "https://files.pythonhosted.org/packages/e7/b3/e4f84cd23ea46676dd88c514457ca0bad7a8efe40be76cffc009fed4b16e/greenlet-1.1.2-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:9633b3034d3d901f0a46b7939f8c4d64427dfba6bbc5a36b1a67364cf148a1b0"}, - {url = "https://files.pythonhosted.org/packages/e8/2e/a8c9772f3adb294f015775547f990aa2d9c3e2dfdcddaa4e5a9d544a6a8c/greenlet-1.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e859fcb4cbe93504ea18008d1df98dee4f7766db66c435e4882ab35cf70cac43"}, - {url = "https://files.pythonhosted.org/packages/eb/4d/97e281170a0f88f2bef182f5c76b78b89dd492fce372ea381bca59f76371/greenlet-1.1.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:833e1551925ed51e6b44c800e71e77dacd7e49181fdc9ac9a0bf3714d515785d"}, - {url = "https://files.pythonhosted.org/packages/ed/18/65451a0b924688ca341a71eee561adb1e9371dbd94960cd012854e9d93b8/greenlet-1.1.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:356b3576ad078c89a6107caa9c50cc14e98e3a6c4874a37c3e0273e4baf33de8"}, - {url = "https://files.pythonhosted.org/packages/ee/1f/521b0c4c7fb010d438881b056785a358e9bde6eecac6d5f10f76021d0918/greenlet-1.1.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9d29ca8a77117315101425ec7ec2a47a22ccf59f5593378fc4077ac5b754fce"}, - {url = "https://files.pythonhosted.org/packages/f3/78/934cb34e853222566d9449435daad7c1d281136115f991be6db7c9d8004a/greenlet-1.1.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b8c008de9d0daba7b6666aa5bbfdc23dcd78cafc33997c9b7741ff6353bafb7f"}, - {url = "https://files.pythonhosted.org/packages/f4/4d/52cdc4fb2d9c7a226c490a19373c32a837b38205abd10010c3ade0b011ca/greenlet-1.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2bde6792f313f4e918caabc46532aa64aa27a0db05d75b20edfc5c6f46479de2"}, - {url = "https://files.pythonhosted.org/packages/f5/34/adc2134c9567dd99254f20e6981a9006a5767dfed287eb94f273ec51e092/greenlet-1.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:b11548073a2213d950c3f671aa88e6f83cda6e2fb97a8b6317b1b5b33d850e06"}, - {url = "https://files.pythonhosted.org/packages/f7/cc/60cc190f564e9fb2ed443ffa48e4ab114236d17d9419f5a0feba9c06ee07/greenlet-1.1.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:049fe7579230e44daef03a259faa24511d10ebfa44f69411d99e6a184fe68073"}, -] -"gunicorn 20.0.4" = [ - {url = "https://files.pythonhosted.org/packages/33/b8/f5fd32e1f46fcfefd7cb5c84dee1cf657ab3540ee92b8a09fc40e4887bf0/gunicorn-20.0.4.tar.gz", hash = "sha256:1904bb2b8a43658807108d59c3f3d56c2b6121a701161de0ddf9ad140073c626"}, - {url = "https://files.pythonhosted.org/packages/69/ca/926f7cd3a2014b16870086b2d0fdc84a9e49473c68a8dff8b57f7c156f43/gunicorn-20.0.4-py2.py3-none-any.whl", hash = "sha256:cd4a810dd51bf497552cf3f863b575dabd73d6ad6a91075b65936b151cbf4f9c"}, -] -"idna 2.10" = [ - {url = "https://files.pythonhosted.org/packages/a2/38/928ddce2273eaa564f6f50de919327bf3a00f091b5baba8dfa9460f3a8a8/idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, - {url = "https://files.pythonhosted.org/packages/ea/b7/e0e3c1c467636186c39925827be42f16fee389dc404ac29e930e9136be70/idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, -] -"importlib-metadata 4.13.0" = [ - {url = "https://files.pythonhosted.org/packages/55/12/ab288357b884ebc807e3f4eff63ce5ba6b941ba61499071bf19f1bbc7f7f/importlib_metadata-4.13.0.tar.gz", hash = "sha256:dd0173e8f150d6815e098fd354f6414b0f079af4644ddfe90c71e2fc6174346d"}, - {url = "https://files.pythonhosted.org/packages/d0/98/c277899f5aa21f6e6946e1c83f2af650cbfee982763ffb91db07ff7d3a13/importlib_metadata-4.13.0-py3-none-any.whl", hash = "sha256:8a8a81bcf996e74fee46f0d16bd3eaa382a7eb20fd82445c3ad11f4090334116"}, -] -"itsdangerous 1.1.0" = [ - {url = "https://files.pythonhosted.org/packages/68/1a/f27de07a8a304ad5fa817bbe383d1238ac4396da447fa11ed937039fa04b/itsdangerous-1.1.0.tar.gz", hash = "sha256:321b033d07f2a4136d3ec762eac9f16a10ccd60f53c0c91af90217ace7ba1f19"}, - {url = "https://files.pythonhosted.org/packages/76/ae/44b03b253d6fade317f32c24d100b3b35c2239807046a4c953c7b89fa49e/itsdangerous-1.1.0-py2.py3-none-any.whl", hash = "sha256:b12271b2047cb23eeb98c8b5622e2e5c5e9abd9784a153e9d8ef9cb4dd09d749"}, -] -"jinja2 2.11.3" = [ - {url = "https://files.pythonhosted.org/packages/4f/e7/65300e6b32e69768ded990494809106f87da1d436418d5f1367ed3966fd7/Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, - {url = "https://files.pythonhosted.org/packages/7e/c2/1eece8c95ddbc9b1aeb64f5783a9e07a286de42191b7204d67b7496ddf35/Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, -] -"mako 1.2.2" = [ - {url = "https://files.pythonhosted.org/packages/6d/f2/8ad2ec3d531c97c4071572a4104e00095300e278a7449511bee197ca22c9/Mako-1.2.2.tar.gz", hash = "sha256:3724869b363ba630a272a5f89f68c070352137b8fd1757650017b7e06fda163f"}, - {url = "https://files.pythonhosted.org/packages/90/12/eb62db8bc346bc41a7ec8fbccd525e91d2747f9acfa6fbfd978948640a85/Mako-1.2.2-py3-none-any.whl", hash = "sha256:8efcb8004681b5f71d09c983ad5a9e6f5c40601a6ec469148753292abc0da534"}, -] -"markdown 3.3.3" = [ - {url = "https://files.pythonhosted.org/packages/ac/ef/24a91ca96efa0d7802dffb83ccc7a3c677027bea19ec3c9ee80be740408e/Markdown-3.3.3-py3-none-any.whl", hash = "sha256:c109c15b7dc20a9ac454c9e6025927d44460b85bd039da028d85e2b6d0bcc328"}, - {url = "https://files.pythonhosted.org/packages/fd/d6/9eeda2f440ef798c8222b77d7355199345ce3477941d8a02a2024ccb9ed2/Markdown-3.3.3.tar.gz", hash = "sha256:5d9f2b5ca24bc4c7a390d22323ca4bad200368612b5aaa7796babf971d2b2f18"}, -] -"markupsafe 1.1.1" = [ - {url = "https://files.pythonhosted.org/packages/04/64/2fc144ee16cb2eed20b3e366045697af04a4e7367ef1e5e65db6f61f1804/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, - {url = "https://files.pythonhosted.org/packages/06/54/f14cf25317b0b3e596457c9a5bea18b6fc27c841c6eb9d23c679b10d63a2/MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, - {url = "https://files.pythonhosted.org/packages/06/b2/575cb8d628820ad23ea55af0d29899ea459de62cde7a78cfdde91608ce5f/MarkupSafe-1.1.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7"}, - {url = "https://files.pythonhosted.org/packages/09/31/fe863b864cf3dfa11bce7a3bd41c4433d59b777ee0750b8d8c9a96f5ca98/MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, - {url = "https://files.pythonhosted.org/packages/0c/12/37f68957526d1ec0883b521934b4e1b8ff3dd8e4fab858a5bf3e487bcee9/MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, - {url = "https://files.pythonhosted.org/packages/0d/98/0fd0f0baf8a59facb65cee37a26c775ee5a114f86e8b0cfe01dad1b8022a/MarkupSafe-1.1.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"}, - {url = "https://files.pythonhosted.org/packages/12/10/8dbe995ab7e5d0471fd7aa90fdb756595ae9ef0ccf3707867b1b56254df8/MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, - {url = "https://files.pythonhosted.org/packages/1c/7d/16a3dd24ec9f901e91a0c1274d871c7dc07a229f35d478fdbf48f16b93b3/MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, - {url = "https://files.pythonhosted.org/packages/20/40/49d725372f8f49df9891e7ea5f5d36489da85a277621177ad4af68992769/MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, - {url = "https://files.pythonhosted.org/packages/2d/0d/119e18ded4869fb781f51ca6a1130f488dfd11d1bd59009101ba1adf01fa/MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f"}, - {url = "https://files.pythonhosted.org/packages/35/25/8560907c79805c1ed2d1b8297c43ad82f5f23a5376d846bc1a2ace2aee53/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, - {url = "https://files.pythonhosted.org/packages/45/17/5b6a3a0afa0cb9827781ee43d8842a3540ac9d49855cad936099c7b9416b/MarkupSafe-1.1.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5"}, - {url = "https://files.pythonhosted.org/packages/4b/20/f6d7648c81cb84815d0be935d5c74cd1cc0239e43eadb1a61062d34b6543/MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, - {url = "https://files.pythonhosted.org/packages/4f/8b/da8a2ae5780d38271ac6e691756fc938cf4df8f225eb8aaced0204304932/MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, - {url = "https://files.pythonhosted.org/packages/51/3c/82b35d63a8e9fe1e7d4078c43a0a8fc631cc4ac9d2beff86c74af0cdb2d9/MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, - {url = "https://files.pythonhosted.org/packages/5b/d4/1deb3c5dc3714fb160c7e2116fc6dff36a063d9156a9328cce54ef35cc52/MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, - {url = "https://files.pythonhosted.org/packages/64/ce/e159d4201a45d56ad14d77b020be7678583898cecbb2a25817f363f71486/MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, - {url = "https://files.pythonhosted.org/packages/65/c6/2399700d236d1dd681af8aebff1725558cddfd6e43d7a5184a675f4711f5/MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, - {url = "https://files.pythonhosted.org/packages/6b/0c/931351f919f60e79ac18c940d31fc13b4c6179e61c82240050ad14346524/MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, - {url = "https://files.pythonhosted.org/packages/6d/d2/0ccd2c0e2cd93b35e765d9b3205cd6602e6b202b522fc7997531353715b3/MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, - {url = "https://files.pythonhosted.org/packages/6e/57/d40124076756c19ff2269678de7ae25a14ebbb3f6314eb5ce9477f191350/MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, - {url = "https://files.pythonhosted.org/packages/70/78/b7f1fac566e6d579a15b020dff0e77bc059093a6c5e6f6a777be4c959384/MarkupSafe-1.1.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193"}, - {url = "https://files.pythonhosted.org/packages/80/16/98afa5c19296aaf7b16d1eb3c7e997656e6cfad79606e7d3885905615e96/MarkupSafe-1.1.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032"}, - {url = "https://files.pythonhosted.org/packages/81/e2/2cb8f60843559cd04a161d838b4c824f4569457d0bbd8b6416c0e68c9d25/MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1"}, - {url = "https://files.pythonhosted.org/packages/83/66/ec77a7000486d4d6acb599993b58dc4c97d510e3f2c37b81d31fb7632c4f/MarkupSafe-1.1.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b"}, - {url = "https://files.pythonhosted.org/packages/85/85/43579939ae1ec6a493c0e68528cd4e26a29fbd4109f5553d4966f6273801/MarkupSafe-1.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c"}, - {url = "https://files.pythonhosted.org/packages/8c/9b/85abd4ff6f9b6d03ce504e6d84589e13d5fd6bc4d63647a57acf1b4abc03/MarkupSafe-1.1.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850"}, - {url = "https://files.pythonhosted.org/packages/93/b8/95b1c38f5b00ed2c0d16cf65f2b07a5ae73eeacf66d2010c0e934737d1d9/MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, - {url = "https://files.pythonhosted.org/packages/97/d8/ea17d2f83e307daa841df7674a42f5ed8d102e0f061fb658065f369779f5/MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, - {url = "https://files.pythonhosted.org/packages/98/7b/ff284bd8c80654e471b769062a9b43cc5d03e7a615048d96f4619df8d420/MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, - {url = "https://files.pythonhosted.org/packages/99/c9/5d5dcf2aa90f1d4500e92467a04f63b3708ee6e5764b40b2445e767ab8dc/MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, - {url = "https://files.pythonhosted.org/packages/9d/d3/75cddfad6ca1d1bb3a017cece499a65e54ceb4583800f1256b8ad07bb57f/MarkupSafe-1.1.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0"}, - {url = "https://files.pythonhosted.org/packages/b1/60/fa4afa6fb4547b46b24bc679dd312242e0e579b4ee5651a2e5f50f814319/MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, - {url = "https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, - {url = "https://files.pythonhosted.org/packages/b7/d5/9d36bdf18173408ce6b16bcc625e4019abf1dd4b52fa66163e231f5b7c98/MarkupSafe-1.1.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2"}, - {url = "https://files.pythonhosted.org/packages/b9/2e/64db92e53b86efccfaea71321f597fa2e1b2bd3853d8ce658568f7a13094/MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, - {url = "https://files.pythonhosted.org/packages/b9/82/833c7714951bff8f502ed054e6fbd8bd00e083d1fd96de6a46905cf23378/MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, - {url = "https://files.pythonhosted.org/packages/b9/bd/c5183b3416a14c221de4208a52665f7038cc8b159e8ad89bd9ccc23de08a/MarkupSafe-1.1.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014"}, - {url = "https://files.pythonhosted.org/packages/be/2e/ad118ca191e44dc6f87182310e5be51da71d4b81ac659e5f8d5f18251806/MarkupSafe-1.1.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85"}, - {url = "https://files.pythonhosted.org/packages/c1/53/96b8c31ee0947bd080b46f6dc9c0a35cceedae8c56a219cc4b9cce0a4f99/MarkupSafe-1.1.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f"}, - {url = "https://files.pythonhosted.org/packages/c2/37/2e4def8ce3739a258998215df907f5815ecd1af71e62147f5eea2d12d4e8/MarkupSafe-1.1.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1"}, - {url = "https://files.pythonhosted.org/packages/ce/c6/f000f1af136ef74e4a95e33785921c73595c5390403f102e9b231b065b7a/MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, - {url = "https://files.pythonhosted.org/packages/d6/e5/348e7d7977202d9a6c7f4cac3c6d8f71b01bb3c91e0bd4b5c23670951fd6/MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, - {url = "https://files.pythonhosted.org/packages/d8/1f/e97c4c6b182e59562f99c207f0f621d15a42fc82a6532a98e0b2d38b7c4e/MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, - {url = "https://files.pythonhosted.org/packages/d8/9d/7a8cad803ef73f47134ae5c3804e20b54149ce62a7d1337204f3cf2d1fa1/MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, - {url = "https://files.pythonhosted.org/packages/dc/d7/e3478fb2c3f2cc446ae4c6dedba1805f04b329bf30237cfe9f484f3d0a0e/MarkupSafe-1.1.1-cp39-cp39-win32.whl", hash = "sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39"}, - {url = "https://files.pythonhosted.org/packages/f0/00/a6aea33f5598b080b86d6b6d1214b51afe3ffa6100b902d5aa465080083f/MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, - {url = "https://files.pythonhosted.org/packages/f0/03/85efaa82ea0c7655b99db9252347623626048b35c03b046fcfde1af43b61/MarkupSafe-1.1.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb"}, - {url = "https://files.pythonhosted.org/packages/f7/58/85258115ce58190f20c28fbb3b91c3b1a0a42e6375b100e489427c30488a/MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, - {url = "https://files.pythonhosted.org/packages/fb/39/de6ecf2652dc1b0fb374888a398f326d6c61f12e8004ed3dccb093e33e00/MarkupSafe-1.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8"}, - {url = "https://files.pythonhosted.org/packages/fb/40/f3adb7cf24a8012813c5edb20329eb22d5d8e2a0ecf73d21d6b85865da11/MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, - {url = "https://files.pythonhosted.org/packages/fe/38/1ee869cf77456412512761cbabe9f0e30912c7a4d8bbb726d2393a4d4723/MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, -] -"mccabe 0.6.1" = [ - {url = "https://files.pythonhosted.org/packages/06/18/fa675aa501e11d6d6ca0ae73a101b2f3571a565e0f7d38e062eec18a91ee/mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, - {url = "https://files.pythonhosted.org/packages/87/89/479dc97e18549e21354893e4ee4ef36db1d237534982482c3681ee6e7b57/mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, +"geoalchemy2 0.13.3" = [ + {url = "https://files.pythonhosted.org/packages/17/56/3e8d472ae86068614cbc284b9607c11386df742c7136a4ebda42b6324e8f/GeoAlchemy2-0.13.3.tar.gz", hash = "sha256:d85a7deaa9a230901733f7419d6bff5674b8730651de1a07f2b6423aa4925d09"}, + {url = "https://files.pythonhosted.org/packages/24/92/4496658fe2cd7c68c73d1ba5e321db82df7955d8710380ef4fb32fc57726/GeoAlchemy2-0.13.3-py3-none-any.whl", hash = "sha256:a29f98cbe2527284d2374a0aa6f7bf31fb7babb61bc56b7e557afdb21610827a"}, +] +"geojson 3.0.1" = [ + {url = "https://files.pythonhosted.org/packages/1e/17/4f866d92f74ac1dcca4dad1665ce2e54c8feb861cd6e4b20de4fbf9b5f7b/geojson-3.0.1.tar.gz", hash = "sha256:ff3d75acab60b1e66504a11f7ea12c104bad32ff3c410a807788663b966dee4a"}, + {url = "https://files.pythonhosted.org/packages/ca/51/2e8e2aae941e64f9cc840ab5cdc4efa9bc6652690c2ac613ce3ef15cad59/geojson-3.0.1-py3-none-any.whl", hash = "sha256:e49df982b204ed481e4c1236c57f587adf71537301cf8faf7120ab27d73c7568"}, +] +"gevent 22.10.2" = [ + {url = "https://files.pythonhosted.org/packages/02/4f/73a79efa65706ded48231f0e932e455cea0dde2cb88ad79c315901055587/gevent-22.10.2-cp310-cp310-macosx_10_15_x86_64.whl", hash = "sha256:990d7069f14dc40674e0d5cb43c68fd3bad8337048613b9bb94a0c4180ffc176"}, + {url = "https://files.pythonhosted.org/packages/05/82/6ebab1a8cff765c91d45b3cad33b04b3532d15bf438a9f34f309a6f7d524/gevent-22.10.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:53ee7f170ed42c7561fe8aff5d381dc9a4124694e70580d0c02fba6aafc0ea37"}, + {url = "https://files.pythonhosted.org/packages/16/42/a2be5df031ef9feb0dcbde5bbcc40ff3e58c5c5b0b682475e09b2cd3fabf/gevent-22.10.2-cp36-cp36m-win32.whl", hash = "sha256:8c192d2073e558e241f0b592c1e2b34127a4481a5be240cad4796533b88b1a98"}, + {url = "https://files.pythonhosted.org/packages/26/5d/f5d1ad8e64ea16543131f4b7c189b675f73f6dc8e9fb6546c6e6421f43a7/gevent-22.10.2-cp311-cp311-win_amd64.whl", hash = "sha256:1e955238f59b2947631c9782a713280dd75884e40e455313b5b6bbc20b92ff73"}, + {url = "https://files.pythonhosted.org/packages/2d/d9/4f0205e365ea1f3f8e9861104d766b17a9c2d44928de658b7652f0ef7fe2/gevent-22.10.2-pp27-pypy_73-win_amd64.whl", hash = "sha256:ed7f16613eebf892a6a744d7a4a8f345bc6f066a0ff3b413e2479f9c0a180193"}, + {url = "https://files.pythonhosted.org/packages/31/7d/1179da0f39eacb115e2bce4677b3aa80b2383b6d956369109b4b00d9d1c7/gevent-22.10.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8729129edef2637a8084258cb9ec4e4d5ca45d97ac77aa7a6ff19ccb530ab731"}, + {url = "https://files.pythonhosted.org/packages/3b/c4/91c6f0b4f49b76865b61fb59ef5029992c1f3aa5644efe8e6ea0497ea08a/gevent-22.10.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1f001cac0ba8da76abfeb392a3057f81fab3d67cc916c7df8ea977a44a2cc989"}, + {url = "https://files.pythonhosted.org/packages/46/49/20b77ca0a791a7bd1c5d34d9229c0771a7704bd3e075afd3411c1a1b8562/gevent-22.10.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6c144e08dfad4106effc043a026e5d0c0eff6ad031904c70bf5090c63f3a6a7"}, + {url = "https://files.pythonhosted.org/packages/46/9b/88e748e892cc45b4bad8aa8f16075b8a11815c0c701b21674b4bb3d07911/gevent-22.10.2-cp39-cp39-win_amd64.whl", hash = "sha256:323b207b281ba0405fea042067fa1a61662e5ac0d574ede4ebbda03efd20c350"}, + {url = "https://files.pythonhosted.org/packages/46/e5/8af9e9165a2757d9c0a27b389870976fb12a3d5d9db8f0b7cebe1856174e/gevent-22.10.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:9d85574eb729f981fea9a78998725a06292d90a3ed50ddca74530c3148c0be41"}, + {url = "https://files.pythonhosted.org/packages/57/f4/604ed4ea6465d44111ab0ad9e875636b988b28ed3d2b87ba5afb122a6b15/gevent-22.10.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:1e1286a76f15b5e15f1e898731d50529e249529095a032453f2c101af3fde71c"}, + {url = "https://files.pythonhosted.org/packages/5b/02/22dad5a61fa2a5ae56e6d4869f5d70dc18df9a89dff2ffe50d8268aad4b0/gevent-22.10.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7ed2346eb9dc4344f9cb0d7963ce5b74fe16fdd031a2809bb6c2b6eba7ebcd5"}, + {url = "https://files.pythonhosted.org/packages/5b/ae/00d45cb9c0460fc90700c3e32aa7750651df73c87bf6b8f8093e8dbab19c/gevent-22.10.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f01c9adbcb605364694b11dcd0542ec468a29ac7aba2fb5665dc6caf17ba4d7e"}, + {url = "https://files.pythonhosted.org/packages/5b/df/43c29c43c6bc3754f04fd94f2af66cf3fb60a83387ee62b10b1ec730e0c1/gevent-22.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c04ee32c11e9fcee47c1b431834878dc987a7a2cc4fe126ddcae3bad723ce89"}, + {url = "https://files.pythonhosted.org/packages/5f/d4/8eb7a273c95782a2e477314d299f290d43e1ce21f30954775442b0cdccef/gevent-22.10.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:58898dbabb5b11e4d0192aae165ad286dc6742c543e1be9d30dc82753547c508"}, + {url = "https://files.pythonhosted.org/packages/61/43/6c17b9d513a406f63ad5870040645d2bfeb0cbbc225162c46f88cc823d92/gevent-22.10.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:84c517e33ed604fa06b7d756dc0171169cc12f7fdd68eb7b17708a62eebf4516"}, + {url = "https://files.pythonhosted.org/packages/6c/81/f24cdc21f5456e1134857b3053bae9da899ca309606f5c1546d36ba81d8f/gevent-22.10.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8f2477e7b0a903a01485c55bacf2089110e5f767014967ba4b287ff390ae2638"}, + {url = "https://files.pythonhosted.org/packages/6f/36/ebabd67fa89964e2d73ea4e8f830636259ab3230153da223edcbfd25bf7c/gevent-22.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5488eba6a568b4d23c072113da4fc0feb1b5f5ede7381656dc913e0d82204e2"}, + {url = "https://files.pythonhosted.org/packages/76/eb/69d278e3b29dfa081a7af0b16ec616ea43fa68854c258713f6c1c52ebd22/gevent-22.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:319d8b1699b7b8134de66d656cd739b308ab9c45ace14d60ae44de7775b456c9"}, + {url = "https://files.pythonhosted.org/packages/86/ab/189b5e0242d07c51f1b641fa26c2f06787f882189648afcfdcc0827a0c69/gevent-22.10.2-cp37-cp37m-win32.whl", hash = "sha256:4114f0f439f0b547bb6f1d474fee99ddb46736944ad2207cef3771828f6aa358"}, + {url = "https://files.pythonhosted.org/packages/8a/c2/d791ad20e1b6589529a131e9b802711e602d821e37ee8b55bcaf6a110ec8/gevent-22.10.2-cp38-cp38-win32.whl", hash = "sha256:ae90226074a6089371a95f20288431cd4b3f6b0b096856afd862e4ac9510cddd"}, + {url = "https://files.pythonhosted.org/packages/8c/00/ed81e9a31322f587e47d92ef530e9bb024cf778e0526a018fbb81168c7f4/gevent-22.10.2-cp27-cp27m-win32.whl", hash = "sha256:59b47e81b399d49a5622f0f503c59f1ce57b7705306ea0196818951dfc2f36c8"}, + {url = "https://files.pythonhosted.org/packages/92/4c/d61af2f4e0319f12bb8e5643cd9c1626b1c42425829f0a0d73409a1c7a4b/gevent-22.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b68f4c9e20e47ad49fe797f37f91d5bbeace8765ce2707f979a8d4ec197e4d"}, + {url = "https://files.pythonhosted.org/packages/96/31/dd60da12cc96eefe1a66335ebf9370a160cd4ed33bd901e25aaea84c5ecb/gevent-22.10.2-cp39-cp39-win32.whl", hash = "sha256:172caa66273315f283e90a315921902cb6549762bdcb0587fd60cb712a9d6263"}, + {url = "https://files.pythonhosted.org/packages/98/fa/471a5df3bc17183e13f7373c3c662c00fbff94315b61f3306d480ac95e8e/gevent-22.10.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:d82081656a5b9a94d37c718c8646c757e1617e389cdc533ea5e6a6f0b8b78545"}, + {url = "https://files.pythonhosted.org/packages/9b/83/541d431d8c86495bfe3b7e0b39f923dd3cc6eddeaae2af1c18f11779fe01/gevent-22.10.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:4197d423e198265eef39a0dea286ef389da9148e070310f34455ecee8172c391"}, + {url = "https://files.pythonhosted.org/packages/9c/33/78f417eebde535d9146dde08b7d15d408176a023c9c02921c04fe235ab10/gevent-22.10.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2929377c8ebfb6f4d868d161cd8de2ea6b9f6c7a5fcd4f78bcd537319c16190b"}, + {url = "https://files.pythonhosted.org/packages/9e/67/5fa93536a787aa43c07a6356b6202ebdd8a867eec71f1d3c64cdb5f67e75/gevent-22.10.2-cp38-cp38-win_amd64.whl", hash = "sha256:494c7f29e94df9a1c3157d67bb7edfa32a46eed786e04d9ee68d39f375e30001"}, + {url = "https://files.pythonhosted.org/packages/9f/4a/e9e57cb9495f0c7943b1d5965c4bdd0d78bc4a433a7c96ee034b16c01520/gevent-22.10.2.tar.gz", hash = "sha256:1ca01da176ee37b3527a2702f7d40dbc9ffb8cfc7be5a03bfa4f9eec45e55c46"}, + {url = "https://files.pythonhosted.org/packages/a5/c1/55711c49d49c08b374a2b7fa1840fc7132c92c5facd930e9d63dfa2fd7b2/gevent-22.10.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:efc003b6c1481165af61f0aeac248e0a9ac8d880bb3acbe469b448674b2d5281"}, + {url = "https://files.pythonhosted.org/packages/a9/2f/a638ef49c8b692fb347dc16ba5444c8019e5faee85d0a1e1ac9b02c08060/gevent-22.10.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:5aa99e4882a9e909b4756ee799c6fa0f79eb0542779fad4cc60efa23ec1b2aa8"}, + {url = "https://files.pythonhosted.org/packages/aa/3c/e8e4d55cf80659bc6c25047140ef73ad191964def3b473ab91d95fd0ab87/gevent-22.10.2-cp36-cp36m-win_amd64.whl", hash = "sha256:a2237451c721a0f874ef89dbb4af4fdc172b76a964befaa69deb15b8fff10f49"}, + {url = "https://files.pythonhosted.org/packages/ac/0b/4954f7554b898242ed4ebae119b511ae78246557141af2dd77eac0e1e830/gevent-22.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1472012493ca1fac103f700d309cb6ef7964dcdb9c788d1768266e77712f5e49"}, + {url = "https://files.pythonhosted.org/packages/ad/df/8a61942136683cb2076e0950fb6a3c6fd225d655228f4ab1e15daa7df52c/gevent-22.10.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:4e2f008c82dc54ec94f4de12ca6feea60e419babb48ec145456907ae61625aa4"}, + {url = "https://files.pythonhosted.org/packages/af/0c/e4ec3d71f0e4fe26b04365595b8b4341df16851088462a541d6f700e08b3/gevent-22.10.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:018f93de7d5318d2fb440f846839a4464738468c3476d5c9cf7da45bb71c18bd"}, + {url = "https://files.pythonhosted.org/packages/b8/0e/d8b864ae61c99798a8f75f1a29c94c3ab271bde30dd74e40ca1f4013f81d/gevent-22.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db562a8519838bddad0c439a2b12246bab539dd50e299ea7ff3644274a33b6a5"}, + {url = "https://files.pythonhosted.org/packages/b9/4b/1ab8a6097126f90fb3fb11220ac8ceceb616547899255ae13213251c0fa9/gevent-22.10.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:96c56c280e3c43cfd075efd10b250350ed5ffd3c1514ec99a080b1b92d7c8374"}, + {url = "https://files.pythonhosted.org/packages/ba/38/4bf86c3063b8ef58ac12d24b8e6a3a1ba7ecf8fccd73e620018e0d217bb0/gevent-22.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98bc510e80f45486ef5b806a1c305e0e89f0430688c14984b0dbdec03331f48b"}, + {url = "https://files.pythonhosted.org/packages/bc/0b/d7d02dd64a0a30f4d522143fd900336bab9b07b18ffa1b763e185037c15c/gevent-22.10.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f4bfd74c178351a4a05c5c7df6f8a0a279ff6f392b57608ce0e83c768207f9"}, + {url = "https://files.pythonhosted.org/packages/c4/6e/dd18a5a1e220aea258d95e909bea1a67ce3528568c61be67ef82244d6ff4/gevent-22.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddaa3e310a8f1a45b5c42cf50b54c31003a3028e7d4e085059090ea0e7a5fddd"}, + {url = "https://files.pythonhosted.org/packages/c4/e5/342678bdf40132f32664fb16f35ec6d9f0c9d62ce6d38efecd6c26caae3c/gevent-22.10.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ff3796692dff50fec2f381b9152438b221335f557c4f9b811f7ded51b7a25a1"}, + {url = "https://files.pythonhosted.org/packages/c7/54/386511e41b7d8f015462ddcacb66c9933cfb7fa68d2d18329805f2bc0ea9/gevent-22.10.2-cp27-cp27m-win_amd64.whl", hash = "sha256:1d543c9407a1e4bca11a8932916988cfb16de00366de5bf7bc9e7a3f61e60b18"}, + {url = "https://files.pythonhosted.org/packages/c7/e0/ac3033e024b4c4f48e32eccaced658d5432ea6d2fee9f061d0f681955922/gevent-22.10.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:97cd42382421779f5d82ec5007199e8a84aa288114975429e4fd0a98f2290f10"}, + {url = "https://files.pythonhosted.org/packages/c9/0c/ed20ce565fd3e4df33b4a402a62bb3a8b5a64dd96a6a0e0c5f0a8181a98e/gevent-22.10.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:d21ad79cca234cdbfa249e727500b0ddcbc7adfff6614a96e6eaa49faca3e4f2"}, + {url = "https://files.pythonhosted.org/packages/ca/35/e9360e3e265ef491b0dcd1cbc6d828fef7b9c5f4b88e2b629326543a44e9/gevent-22.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f23d0997149a816a2a9045af29c66f67f405a221745b34cefeac5769ed451db8"}, + {url = "https://files.pythonhosted.org/packages/d2/b9/f80d57f7141268ccca5876a28f4f276ac44068557d1a6b27da0b883da282/gevent-22.10.2-cp310-cp310-win_amd64.whl", hash = "sha256:3b7eae8a0653ba95a224faaddf629a913ace408edb67384d3117acf42d7dcf89"}, + {url = "https://files.pythonhosted.org/packages/dc/61/57fc6995de5c5b25aef8ae477821c10affabc12ac60919c2d5b60d8fd85f/gevent-22.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da4183f0b9d9a1e25e1758099220d32c51cc2c6340ee0dea3fd236b2b37598e4"}, + {url = "https://files.pythonhosted.org/packages/e6/cd/0928440411690422a6ee337a7325f96dfb581c06c4b0ed76a782e2c6192a/gevent-22.10.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f3329bedbba4d3146ae58c667e0f9ac1e6f1e1e6340c7593976cdc60aa7d1a47"}, + {url = "https://files.pythonhosted.org/packages/ea/6c/86540e4da80ebbc899b771b70231c20618295289706509b4b88da9682d0c/gevent-22.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:877abdb3a669576b1d51ce6a49b7260b2a96f6b2424eb93287e779a3219d20ba"}, + {url = "https://files.pythonhosted.org/packages/ec/20/1dfb2f8c6690660bf51f6511b1198f2189e604b78a4c7bfba896ae831ad4/gevent-22.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b43d500d7d3c0e03070dee813335bb5315215aa1cf6a04c61093dfdd718640b3"}, + {url = "https://files.pythonhosted.org/packages/fa/30/78acb4e6d7dddec4ca5af332c01eb7aef643d87f58683a245bb8c3020443/gevent-22.10.2-cp37-cp37m-win_amd64.whl", hash = "sha256:0d581f22a5be6281b11ad6309b38b18f0638cf896931223cbaa5adb904826ef6"}, + {url = "https://files.pythonhosted.org/packages/fb/0f/53c41a3f7f4594bcc359262df362985a71baf3a48e2ed217ca950f80544d/gevent-22.10.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:a47a4e77e2bc668856aad92a0b8de7ee10768258d93cd03968e6c7ba2e832f76"}, +] +"greenlet 2.0.2" = [ + {url = "https://files.pythonhosted.org/packages/07/ef/6bfa2ea34f76dea02833d66d28ae7cf4729ddab74ee93ee069c7f1d47c4f/greenlet-2.0.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b"}, + {url = "https://files.pythonhosted.org/packages/08/b1/0615df6393464d6819040124eb7bdff6b682f206a464b4537964819dcab4/greenlet-2.0.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db"}, + {url = "https://files.pythonhosted.org/packages/09/57/5fdd37939e0989a756a32d0a838409b68d1c5d348115e9c697f42ee4f87d/greenlet-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df"}, + {url = "https://files.pythonhosted.org/packages/09/93/d7ed73f82b6f1045dd5d98f063fa16da5273d0812c42f38229d28882762b/greenlet-2.0.2-cp39-cp39-win32.whl", hash = "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5"}, + {url = "https://files.pythonhosted.org/packages/0a/46/96b37dcfe9c9d39b2d2f060a5775139ce8a440315a1ca2667a6b83a2860e/greenlet-2.0.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df"}, + {url = "https://files.pythonhosted.org/packages/0a/54/cbc1096b883b2d1c0c1454837f089971de814ba5ce42be04cf0716a06000/greenlet-2.0.2-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099"}, + {url = "https://files.pythonhosted.org/packages/0d/f6/2d406a22767029e785154071bef79b296f91b92d1c199ec3c2202386bf04/greenlet-2.0.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b"}, + {url = "https://files.pythonhosted.org/packages/17/f9/7f5d755380d329e44307c2f6e52096740fdebb92e7e22516811aeae0aec0/greenlet-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91"}, + {url = "https://files.pythonhosted.org/packages/1d/a0/697653ea5e35acaf28e2a1246645ac512beb9b49a86b310fd0151b075342/greenlet-2.0.2-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6"}, + {url = "https://files.pythonhosted.org/packages/1e/1e/632e55a04d732c8184201238d911207682b119c35cecbb9a573a6c566731/greenlet-2.0.2.tar.gz", hash = "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0"}, + {url = "https://files.pythonhosted.org/packages/1f/42/95800f165d20fb8269fe6a3ac494649718ede074b1d8a78f58ee2ebda27a/greenlet-2.0.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33"}, + {url = "https://files.pythonhosted.org/packages/20/28/c93ffaa75f3c907cd010bf44c5c18c7f8f4bb2409146bd67d538163e33b8/greenlet-2.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8"}, + {url = "https://files.pythonhosted.org/packages/29/c4/fe82cb9ff1bffc52a3832e35fa49cce63e5d366808179153ee879ce47cc9/greenlet-2.0.2-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9"}, + {url = "https://files.pythonhosted.org/packages/37/b9/3ebd606768bee3ef2198fe6d5e7c6c3af42ad3e06b56c1d0a89c56faba2a/greenlet-2.0.2-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b"}, + {url = "https://files.pythonhosted.org/packages/3a/69/a6d3d7abd0f36438ff5fab52572fd107966939d59ef9b8309263ab89f607/greenlet-2.0.2-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6"}, + {url = "https://files.pythonhosted.org/packages/42/d0/285b81442d8552b1ae6a2ff38caeec94ab90507c9740da718189416e8e6e/greenlet-2.0.2-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d"}, + {url = "https://files.pythonhosted.org/packages/43/81/e0a656e3a417b172f834ba5a08dde02b55fd249416c1e933d62ffb6734d0/greenlet-2.0.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca"}, + {url = "https://files.pythonhosted.org/packages/49/b8/3ee1723978245e6f0c087908689f424876803ec05555400681240ab2ab33/greenlet-2.0.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b"}, + {url = "https://files.pythonhosted.org/packages/4d/b2/32f737e1fcf67b23351b4860489029df562b41d7ffb568a3e1ae610f7a9b/greenlet-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9"}, + {url = "https://files.pythonhosted.org/packages/50/3d/7e3d95b955722c514f982bdf6bbe92bb76218b0036dd9b093ae0c168d63a/greenlet-2.0.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30"}, + {url = "https://files.pythonhosted.org/packages/52/39/fa5212bc9ac588c62e52213d4fab30a348059842883410724f9d0408c0f4/greenlet-2.0.2-cp27-cp27m-win_amd64.whl", hash = "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343"}, + {url = "https://files.pythonhosted.org/packages/53/0f/637f6e18e1980ebd2eedd8a9918a7898a6fe44f6188f6f39c6d9181c9891/greenlet-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645"}, + {url = "https://files.pythonhosted.org/packages/54/ce/3a589ec27bd5de97707d2a193716bbe412ccbdb1479f0c3f990789c8fa8c/greenlet-2.0.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7"}, + {url = "https://files.pythonhosted.org/packages/57/a8/079c59b8f5406957224f4f4176e9827508d555beba6d8635787d694226d1/greenlet-2.0.2-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43"}, + {url = "https://files.pythonhosted.org/packages/5a/30/5eab5cbb99263c7d8305657587381c84da2a71fddb07dd5efbfaeecf7264/greenlet-2.0.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73"}, + {url = "https://files.pythonhosted.org/packages/6a/3d/77bd8dd7dd0b872eac87f1edf6fcd94d9d7666befb706ae3a08ed25fbea7/greenlet-2.0.2-cp36-cp36m-win32.whl", hash = "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9"}, + {url = "https://files.pythonhosted.org/packages/6b/2f/1cb3f376df561c95cb61b199676f51251f991699e325a2aa5e12693d10b8/greenlet-2.0.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0"}, + {url = "https://files.pythonhosted.org/packages/6b/cd/84301cdf80360571f6aa77ac096f867ba98094fec2cb93e69c93d996b8f8/greenlet-2.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a"}, + {url = "https://files.pythonhosted.org/packages/6e/11/a1f1af20b6a1a8069bc75012569d030acb89fd7ef70f888b6af2f85accc6/greenlet-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470"}, + {url = "https://files.pythonhosted.org/packages/71/c5/c26840ce91bcbbfc42c1a246289d9d4c758663652669f24e37f84bcdae2a/greenlet-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3"}, + {url = "https://files.pythonhosted.org/packages/7c/5f/ee39d27a08ae6b93f14faa953a6593dad888df75ae55ff479135e64ad4fe/greenlet-2.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857"}, + {url = "https://files.pythonhosted.org/packages/7c/f8/275f7fb1585d5e7dfbc18b4eb78282fbc85986f2eb8a185e7ebc60522cc2/greenlet-2.0.2-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0"}, + {url = "https://files.pythonhosted.org/packages/7e/a6/0a34cde83fe520fa4e8192a1bc0fc7bf9f755215fefe3f42c9b97c45c620/greenlet-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5"}, + {url = "https://files.pythonhosted.org/packages/83/d1/cc273f8f5908940d6666a3db8637d2e24913a2e8e5034012b19ac291a2a0/greenlet-2.0.2-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf"}, + {url = "https://files.pythonhosted.org/packages/86/8d/3a18311306830f6db5f5676a1cb8082c8943bfa6c928b40006e5358170fc/greenlet-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2"}, + {url = "https://files.pythonhosted.org/packages/93/40/db2803f88326149ddcd1c00092e1e36ef55d31922812863753143a9aca01/greenlet-2.0.2-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75"}, + {url = "https://files.pythonhosted.org/packages/9d/ae/8ee23a9b63f854acc66ed0da7220130d87c861153cbc8ea07d11b61567f1/greenlet-2.0.2-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292"}, + {url = "https://files.pythonhosted.org/packages/a1/ea/66e69cf3034be99a1959b2bdd178f5176979e0e63107a37a194c90c49b40/greenlet-2.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40"}, + {url = "https://files.pythonhosted.org/packages/a3/6c/dde49c63ab2f12d2ce401620dbe1a80830109f5f310bdd2f96d2e259de37/greenlet-2.0.2-cp36-cp36m-win_amd64.whl", hash = "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f"}, + {url = "https://files.pythonhosted.org/packages/a8/7a/5542d863a91b3309585219bae7d97aa82fe0482499a840c100297262ec8f/greenlet-2.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c"}, + {url = "https://files.pythonhosted.org/packages/aa/21/6bbd8062fee551f747f5334b7ccd503693704ac4f3183fd8232e2af77bff/greenlet-2.0.2-cp35-cp35m-win32.whl", hash = "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a"}, + {url = "https://files.pythonhosted.org/packages/ac/4a/3ceafef892b8428f77468506bc5a12d835fb9f150129d1a9704902cb4a2a/greenlet-2.0.2-cp35-cp35m-win_amd64.whl", hash = "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394"}, + {url = "https://files.pythonhosted.org/packages/b3/89/1d3b78577a6b2762cb254f6ce5faec9b7c7b23052d1cdb7237273ff37d10/greenlet-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564"}, + {url = "https://files.pythonhosted.org/packages/c4/92/bbd9373fb022c21d1c41bc74b043d8d007825f80bb9534f0dd2f7ed62bca/greenlet-2.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a"}, + {url = "https://files.pythonhosted.org/packages/c5/ab/a69a875a45474cc5776b879258bfa685e99aae992ab310a0b8f773fe56a0/greenlet-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088"}, + {url = "https://files.pythonhosted.org/packages/c7/c9/2637e49b0ef3f17d7eaa52c5af5bfbda5f058e8ee97bd9418978b90e1169/greenlet-2.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526"}, + {url = "https://files.pythonhosted.org/packages/ca/1a/90f2ae7e3df48cbd42af5df47cf9ee37a6c6a78b1941acbc7eac029f5a44/greenlet-2.0.2-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae"}, + {url = "https://files.pythonhosted.org/packages/cd/e8/1ebc8f07d795c3677247e37dae23463a655636a4be387b0d739fa8fd9b2f/greenlet-2.0.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb"}, + {url = "https://files.pythonhosted.org/packages/d2/28/5cf37650334935c6a51313c70c4ec00fb1fad801a551c36afcfc9c03e80b/greenlet-2.0.2-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3"}, + {url = "https://files.pythonhosted.org/packages/d6/c4/f91d771a6628155676765c419c70d6d0ede9b5f3c023102c47ee2f45eadf/greenlet-2.0.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86"}, + {url = "https://files.pythonhosted.org/packages/da/45/2600faf65f318767d2c24b6fce6bb0ad3721e8cb3eb9d7743aefcca8a6a6/greenlet-2.0.2-cp38-cp38-win32.whl", hash = "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249"}, + {url = "https://files.pythonhosted.org/packages/e5/ad/91a8f63881c862bb396cefc33d7faa241bf200df7ba96a1961a99329ed15/greenlet-2.0.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a"}, + {url = "https://files.pythonhosted.org/packages/e6/0e/591ea935b63aa3aed3836976779e5d1324aa4b2961f7355ff5d1f296066b/greenlet-2.0.2-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1"}, + {url = "https://files.pythonhosted.org/packages/e8/3a/ebc4fa1e813ae1fa718eb88417c31587e2efb743ed5f6ff0ae066502c349/greenlet-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca"}, + {url = "https://files.pythonhosted.org/packages/e9/29/2ae545c4c0218b042c2bb0760c0f65e114cca1ab5e552dc23b0f118e428a/greenlet-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b"}, + {url = "https://files.pythonhosted.org/packages/f0/2e/20eab0fa6353a08b0de055dd54e2575a6869ee693d86387076430475832d/greenlet-2.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19"}, + {url = "https://files.pythonhosted.org/packages/f4/ad/287efe1d3c8224fa5f9457195a842fc0c4fa4956cb9655a1f4e89914a313/greenlet-2.0.2-cp27-cp27m-win32.whl", hash = "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74"}, + {url = "https://files.pythonhosted.org/packages/f6/04/74e97d545f9276dee994b959eab3f7d70d77588e5aaedc383d15b0057acd/greenlet-2.0.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8"}, + {url = "https://files.pythonhosted.org/packages/fa/9a/e0e99a4aa93b16dd58881acb55ac1e2fb011475f2e46cf87843970001882/greenlet-2.0.2-cp37-cp37m-win_amd64.whl", hash = "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3"}, + {url = "https://files.pythonhosted.org/packages/fc/80/0ed0da38bbb978f39128d7e53ee51c36bed2e4a7460eff92981a3d07f1d4/greenlet-2.0.2-cp37-cp37m-win32.whl", hash = "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7"}, +] +"gunicorn 20.1.0" = [ + {url = "https://files.pythonhosted.org/packages/28/5b/0d1f0296485a6af03366604142ea8f19f0833894db3512a40ed07b2a56dd/gunicorn-20.1.0.tar.gz", hash = "sha256:e0a968b5ba15f8a328fdfd7ab1fcb5af4470c28aaf7e55df02a99bc13138e6e8"}, + {url = "https://files.pythonhosted.org/packages/e4/dd/5b190393e6066286773a67dfcc2f9492058e9b57c4867a95f1ba5caf0a83/gunicorn-20.1.0-py3-none-any.whl", hash = "sha256:9dcc4547dbb1cb284accfb15ab5667a0e5d1881cc443e0677b4882a4067a807e"}, +] +"idna 3.4" = [ + {url = "https://files.pythonhosted.org/packages/8b/e1/43beb3d38dba6cb420cefa297822eac205a277ab43e5ba5d5c46faf96438/idna-3.4.tar.gz", hash = "sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4"}, + {url = "https://files.pythonhosted.org/packages/fc/34/3030de6f1370931b9dbb4dad48f6ab1015ab1d32447850b9fc94e60097be/idna-3.4-py3-none-any.whl", hash = "sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2"}, +] +"importlib-metadata 6.6.0" = [ + {url = "https://files.pythonhosted.org/packages/0b/1f/9de392c2b939384e08812ef93adf37684ec170b5b6e7ea302d9f163c2ea0/importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, + {url = "https://files.pythonhosted.org/packages/30/bb/bf2944b8b88c65b797acc2c6a2cb0fb817f7364debf0675792e034013858/importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, +] +"itsdangerous 2.1.2" = [ + {url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, + {url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, +] +"jinja2 3.1.2" = [ + {url = "https://files.pythonhosted.org/packages/7a/ff/75c28576a1d900e87eb6335b063fab47a8ef3c8b4d88524c4bf78f670cce/Jinja2-3.1.2.tar.gz", hash = "sha256:31351a702a408a9e7595a8fc6150fc3f43bb6bf7e319770cbc0db9df9437e852"}, + {url = "https://files.pythonhosted.org/packages/bc/c3/f068337a370801f372f2f8f6bad74a5c140f6fda3d9de154052708dd3c65/Jinja2-3.1.2-py3-none-any.whl", hash = "sha256:6088930bfe239f0e6710546ab9c19c9ef35e29792895fed6e6e31a023a182a61"}, +] +"mako 1.2.4" = [ + {url = "https://files.pythonhosted.org/packages/03/3b/68690a035ba7347860f1b8c0cde853230ba69ff41df5884ea7d89fe68cd3/Mako-1.2.4-py3-none-any.whl", hash = "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818"}, + {url = "https://files.pythonhosted.org/packages/05/5f/2ba6e026d33a0e6ddc1dddf9958677f76f5f80c236bd65309d280b166d3e/Mako-1.2.4.tar.gz", hash = "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34"}, +] +"markdown 3.4.3" = [ + {url = "https://files.pythonhosted.org/packages/9a/a1/1352b0e5a3c71a79fa9265726e2217f69df9fd4de0bcb5725cc61f62a5df/Markdown-3.4.3-py3-none-any.whl", hash = "sha256:065fd4df22da73a625f14890dd77eb8040edcbd68794bcd35943be14490608b2"}, + {url = "https://files.pythonhosted.org/packages/9d/80/cc67bfb7deb973d5ae662ee6454d2dafaa8f7c106feafd0d1572666ebde5/Markdown-3.4.3.tar.gz", hash = "sha256:8bf101198e004dc93e84a12a7395e31aac6a9c9942848ae1d99b9d72cf9b3520"}, +] +"markupsafe 2.1.2" = [ + {url = "https://files.pythonhosted.org/packages/02/2c/18d55e5df6a9ea33709d6c33e08cb2e07d39e20ad05d8c6fbf9c9bcafd54/MarkupSafe-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:835fb5e38fd89328e9c81067fd642b3593c33e1e17e2fdbf77f5676abb14a156"}, + {url = "https://files.pythonhosted.org/packages/04/cf/9464c3c41b7cdb8df660cda75676697e7fb49ce1be7691a1162fc88da078/MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:085fd3201e7b12809f9e6e9bc1e5c96a368c8523fad5afb02afe3c051ae4afcc"}, + {url = "https://files.pythonhosted.org/packages/06/3b/d026c21cd1dbee89f41127e93113dcf5fa85c6660d108847760b59b3a66d/MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40dfd3fefbef579ee058f139733ac336312663c6706d1163b82b3003fb1925c4"}, + {url = "https://files.pythonhosted.org/packages/0a/88/78cb3d95afebd183d8b04442685ab4c70cfc1138b850ba20e2a07aff2f53/MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:65608c35bfb8a76763f37036547f7adfd09270fbdbf96608be2bead319728fcd"}, + {url = "https://files.pythonhosted.org/packages/0d/15/82b108c697bec4c26c00aed6975b778cf0eac6cbb77598862b10550b7fcc/MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2298c859cfc5463f1b64bd55cb3e602528db6fa0f3cfd568d3605c50678f8f03"}, + {url = "https://files.pythonhosted.org/packages/19/00/3b8eb0093c885576a1ce7f2263e7b8c01e55b9977433f8246f57cd81b0be/MarkupSafe-2.1.2-cp311-cp311-win32.whl", hash = "sha256:7df70907e00c970c60b9ef2938d894a9381f38e6b9db73c5be35e59d92e06625"}, + {url = "https://files.pythonhosted.org/packages/1f/20/76f6337f1e7238a626ab34405ddd634636011b2ff947dcbd8995f16a7776/MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1bea30e9bf331f3fef67e0a3877b2288593c98a21ccb2cf29b74c581a4eb3af0"}, + {url = "https://files.pythonhosted.org/packages/22/88/9c0cae2f5ada778182f2842b377dd273d6be689953345c10b165478831eb/MarkupSafe-2.1.2-cp39-cp39-win32.whl", hash = "sha256:137678c63c977754abe9086a3ec011e8fd985ab90631145dfb9294ad09c102a7"}, + {url = "https://files.pythonhosted.org/packages/29/d2/243e6b860d97c18d848fc2bee2f39d102755a2b04a5ce4d018d839711b46/MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8db032bf0ce9022a8e41a22598eefc802314e81b879ae093f36ce9ddf39ab1ba"}, + {url = "https://files.pythonhosted.org/packages/30/3e/0a69a24adb38df83e2f6989c38d68627a5f27181c82ecaa1fd03d1236dca/MarkupSafe-2.1.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca244fa73f50a800cf8c3ebf7fd93149ec37f5cb9596aa8873ae2c1d23498601"}, + {url = "https://files.pythonhosted.org/packages/34/19/64b0abc021b22766e86efee32b0e2af684c4b731ce8ac1d519c791800c13/MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:340bea174e9761308703ae988e982005aedf427de816d1afe98147668cc03036"}, + {url = "https://files.pythonhosted.org/packages/37/b2/6f4d5cac75ba6fe9f17671304fe339ea45a73c5609b5f5e652aa79c915c8/MarkupSafe-2.1.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:665a36ae6f8f20a4676b53224e33d456a6f5a72657d9c83c2aa00765072f31f7"}, + {url = "https://files.pythonhosted.org/packages/39/8d/5c5ce72deb8567ab48a18fbd99dc0af3dd651b6691b8570947e54a28e0f3/MarkupSafe-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6d6607f98fcf17e534162f0709aaad3ab7a96032723d8ac8750ffe17ae5a0666"}, + {url = "https://files.pythonhosted.org/packages/3d/66/2f636ba803fd6eb4cee7b3106ae02538d1e84a7fb7f4f8775c6528a87d31/MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28057e985dace2f478e042eaa15606c7efccb700797660629da387eb289b9323"}, + {url = "https://files.pythonhosted.org/packages/41/54/6e88795c64ab5dcda31b06406c062c2740d1a64db18219d4e21fc90928c1/MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:c0a33bc9f02c2b17c3ea382f91b4db0e6cde90b63b296422a939886a7a80de1c"}, + {url = "https://files.pythonhosted.org/packages/46/0c/10ee33673c5e36fa3809cf136971f81d951ca38516188ee11a965d9b2fe9/MarkupSafe-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:0576fe974b40a400449768941d5d0858cc624e3249dfd1e0c33674e5c7ca7aed"}, + {url = "https://files.pythonhosted.org/packages/48/cc/d027612e17b56088cfccd2c8e083518995fcb25a7b4f17fc146362a0499d/MarkupSafe-2.1.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:f8ffb705ffcf5ddd0e80b65ddf7bed7ee4f5a441ea7d3419e861a12eaf41af58"}, + {url = "https://files.pythonhosted.org/packages/4b/34/dc837e5ad9e14634aac4342eb8b12a9be20a4f74f50cc0d765f7aa2fc1e3/MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:a4abaec6ca3ad8660690236d11bfe28dfd707778e2442b45addd2f086d6ef094"}, + {url = "https://files.pythonhosted.org/packages/50/41/1442b693a40eb76d835ca2016e86a01479f17d7fd8288f9830f6790e366a/MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8526c6d437855442cdd3d87eede9c425c4445ea011ca38d937db299382e6fa3"}, + {url = "https://files.pythonhosted.org/packages/52/36/b35c577c884ea352fc0c1eaed9ca4946ffc22cc9c3527a70408bfa9e9496/MarkupSafe-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40627dcf047dadb22cd25ea7ecfe9cbf3bbbad0482ee5920b582f3809c97654f"}, + {url = "https://files.pythonhosted.org/packages/56/0d/c9818629672a3368b773fa94597d79da77bdacc3186f097bb85023f785f6/MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0b462104ba25f1ac006fdab8b6a01ebbfbce9ed37fd37fd4acd70c67c973e460"}, + {url = "https://files.pythonhosted.org/packages/5a/94/d056bf5dbadf7f4b193ee2a132b3d49ffa1602371e3847518b2982045425/MarkupSafe-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2bfb563d0211ce16b63c7cb9395d2c682a23187f54c3d79bfec33e6705473c6"}, + {url = "https://files.pythonhosted.org/packages/5e/f6/8eb8a5692c1986b6e863877b0b8a83628aff14e5fbfaf11d9522b532bd9d/MarkupSafe-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22152d00bf4a9c7c83960521fc558f55a1adbc0631fbb00a9471e097b19d72e1"}, + {url = "https://files.pythonhosted.org/packages/66/21/dadb671aade8eb67ef96e0d8f90b1bd5e8cfb6ad9d8c7fa2c870ec0c257b/MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:55f44b440d491028addb3b88f72207d71eeebfb7b5dbf0643f7c023ae1fba619"}, + {url = "https://files.pythonhosted.org/packages/76/b5/05ce70a3e31ecebcd3628cd180dc4761293aa496db85170fdc085ed2d79a/MarkupSafe-2.1.2-cp38-cp38-win32.whl", hash = "sha256:50c42830a633fa0cf9e7d27664637532791bfc31c731a87b202d2d8ac40c3ea2"}, + {url = "https://files.pythonhosted.org/packages/77/26/af46880038c6eac3832e751298f1965f3a550f38d1e9ddaabd674860076b/MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8bca7e26c1dd751236cfb0c6c72d4ad61d986e9a41bbf76cb445f69488b2a2bd"}, + {url = "https://files.pythonhosted.org/packages/78/e6/91c9a20a943ea231c59024e181c4c5480097daf132428f2272670974637f/MarkupSafe-2.1.2-cp310-cp310-win32.whl", hash = "sha256:c4a549890a45f57f1ebf99c067a4ad0cb423a05544accaf2b065246827ed9603"}, + {url = "https://files.pythonhosted.org/packages/79/e2/b818bf277fa6b01244943498cb2127372c01dde5eff7682837cc72740618/MarkupSafe-2.1.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da25303d91526aac3672ee6d49a2f3db2d9502a4a60b55519feb1a4c7714e07d"}, + {url = "https://files.pythonhosted.org/packages/7b/0f/0e99c2f342933c43af69849a6ba63f2eef54e14c6d0e10a26470fb6b40a9/MarkupSafe-2.1.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a6e40afa7f45939ca356f348c8e23048e02cb109ced1eb8420961b2f40fb373a"}, + {url = "https://files.pythonhosted.org/packages/7c/e6/454df09f18e0ea34d189b447a9e1a9f66c2aa332b77fd5577ebc7ca14d42/MarkupSafe-2.1.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:090376d812fb6ac5f171e5938e82e7f2d7adc2b629101cec0db8b267815c85e2"}, + {url = "https://files.pythonhosted.org/packages/80/64/ccb65aadd71e7685caa69a885885a673e8748525a243fb26acea37201b44/MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f03a532d7dee1bed20bc4884194a16160a2de9ffc6354b3878ec9682bb623c54"}, + {url = "https://files.pythonhosted.org/packages/82/70/b3978786c7b576c25d84b009d2a20a11b5300d252fc3ce984e37b932e97c/MarkupSafe-2.1.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:2e7821bffe00aa6bd07a23913b7f4e01328c3d5cc0b40b36c0bd81d362faeb65"}, + {url = "https://files.pythonhosted.org/packages/82/e3/4efcd74f10a7999783955aec36386f71082e6d7dafcc06b77b9df72b325a/MarkupSafe-2.1.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99625a92da8229df6d44335e6fcc558a5037dd0a760e11d84be2260e6f37002f"}, + {url = "https://files.pythonhosted.org/packages/87/a1/d0f05a09c6c1aef89d1eea0ab0ff1ea897d4117d27f1571034a7e3ff515b/MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf877ab4ed6e302ec1d04952ca358b381a882fbd9d1b07cccbfd61783561f98a"}, + {url = "https://files.pythonhosted.org/packages/93/ca/1c3ae0c6a5712d4ba98610cada03781ea0448436b17d1dcd4759115b15a1/MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d9d971ec1e79906046aa3ca266de79eac42f1dbf3612a05dc9368125952bd1a1"}, + {url = "https://files.pythonhosted.org/packages/93/fa/d72f68f84f8537ee8aa3e0764d1eb11e5e025a5ca90c16e94a40f894c2fc/MarkupSafe-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:bb06feb762bade6bf3c8b844462274db0c76acc95c52abe8dbed28ae3d44a147"}, + {url = "https://files.pythonhosted.org/packages/95/7e/68018b70268fb4a2a605e2be44ab7b4dd7ce7808adae6c5ef32e34f4b55a/MarkupSafe-2.1.2.tar.gz", hash = "sha256:abcabc8c2b26036d62d4c746381a6f7cf60aafcc653198ad678306986b09450d"}, + {url = "https://files.pythonhosted.org/packages/95/88/8c8cce021ac1b1eedde349c6a41f6c256da60babf95e572071361ff3f66b/MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63ba06c9941e46fa389d389644e2d8225e0e3e5ebcc4ff1ea8506dce646f8c8a"}, + {url = "https://files.pythonhosted.org/packages/96/92/a873b4a7fa20c2e30bffe883bb560330f3b6ce03aaf278f75f96d161935b/MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7e007132af78ea9df29495dbf7b5824cb71648d7133cf7848a2a5dd00d36f9ff"}, + {url = "https://files.pythonhosted.org/packages/9d/80/8320f182d06a9b289b1a9f266f593feb91d3781c7e104bbe09e0c4c11439/MarkupSafe-2.1.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cf06cdc1dda95223e9d2d3c58d3b178aa5dacb35ee7e3bbac10e4e1faacb419"}, + {url = "https://files.pythonhosted.org/packages/be/18/988e1913a40cc8eb725b1e073eacc130f7803a061577bdc0b9343eb3c696/MarkupSafe-2.1.2-cp37-cp37m-win32.whl", hash = "sha256:7668b52e102d0ed87cb082380a7e2e1e78737ddecdde129acadb0eccc5423859"}, + {url = "https://files.pythonhosted.org/packages/c3/e5/42842a44bfd9ba2955c562b1139334a2f64cedb687e8969777fd07de42a9/MarkupSafe-2.1.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f1cd098434e83e656abf198f103a8207a8187c0fc110306691a2e94a78d0abb2"}, + {url = "https://files.pythonhosted.org/packages/c7/0e/22d0c8e6ee84414e251bd1bc555b2705af6b3fb99f0ba1ead2a0f51d423b/MarkupSafe-2.1.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22731d79ed2eb25059ae3df1dfc9cb1546691cc41f4e3130fe6bfbc3ecbbecfa"}, + {url = "https://files.pythonhosted.org/packages/cf/c1/d7596976a868fe3487212a382cc121358a53dc8e8d85ff2ee2c3d3b40f04/MarkupSafe-2.1.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9cad97ab29dfc3f0249b483412c85c8ef4766d96cdf9dcf5a1e3caa3f3661cf1"}, + {url = "https://files.pythonhosted.org/packages/d1/10/ff89b23d4a24051c4e4f689b79ee06f230d7e9431445e24f5dd9d9a89730/MarkupSafe-2.1.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a806db027852538d2ad7555b203300173dd1b77ba116de92da9afbc3a3be3eed"}, + {url = "https://files.pythonhosted.org/packages/e3/a9/e366665c7eae59c9c9d34b747cd5a3994847719a2304e0c8dec8b604dd98/MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2ec4f2d48ae59bbb9d1f9d7efb9236ab81429a764dedca114f5fdabbc3788013"}, + {url = "https://files.pythonhosted.org/packages/e6/ff/d2378ca3cb3ac4a37af767b820b0f0bf3f5e9193a6acce0eefc379425c1c/MarkupSafe-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608e7073dfa9e38a85d38474c082d4281f4ce276ac0010224eaba11e929dd53a"}, + {url = "https://files.pythonhosted.org/packages/e9/c6/2da36728c1310f141395176556500aeedfdea8c2b02a3b72ba61b69280e8/MarkupSafe-2.1.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a6f2fcca746e8d5910e18782f976489939d54a91f9411c32051b4aab2bd7c513"}, + {url = "https://files.pythonhosted.org/packages/ea/60/2400ba59cf2465fa136487ee7299f52121a9d04b2cf8539ad43ad10e70e8/MarkupSafe-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:e55e40ff0cc8cc5c07996915ad367fa47da6b3fc091fdadca7f5403239c5fec3"}, + {url = "https://files.pythonhosted.org/packages/f9/aa/ebcd114deab08f892b1d70badda4436dbad1747f9e5b72cffb3de4c7129d/MarkupSafe-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7313ce6a199651c4ed9d7e4cfb4aa56fe923b1adf9af3b420ee14e6d9a73df65"}, +] +"mccabe 0.7.0" = [ + {url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, + {url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, ] "mypy-extensions 1.0.0" = [ {url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -"newrelic 8.8.0" = [ - {url = "https://files.pythonhosted.org/packages/06/eb/9226b7d12a768ba6e8f2372733c66b4146b3bcfa30f2a75a699b9997934e/newrelic-8.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caccdf201735df80b470ddf772f60a154f2c07c0c1b2b3f6e999d55e79ce601e"}, - {url = "https://files.pythonhosted.org/packages/0b/73/9c78820ecf2da85b30beca9f926a29cfd05c6cac7df2d9e05991b9c85734/newrelic-8.8.0.tar.gz", hash = "sha256:84d1f71284efa5f1cae696161e0c3cb65eaa2f53116fe5e7c5a62be7d15d9536"}, - {url = "https://files.pythonhosted.org/packages/20/7c/ae3ebc3bc71a9d2780b23673010d0d36f31b0421d768eaaca75cbc46abe9/newrelic-8.8.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9c0d5153b7363d5cb5cac7f8d1a4e03669b074afee2dda201851a67c7bed1e32"}, - {url = "https://files.pythonhosted.org/packages/22/85/8a4e83e88686eed019708d604246dc73abae223378d882c8022bd2c16938/newrelic-8.8.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef9c178329f8c04f0574908c1f04ff1f18b9eba55b869744583fee3eac48e571"}, - {url = "https://files.pythonhosted.org/packages/3d/f8/f70e87096f6a219c9f0b59f418ad0353c6969b73a56e1f7a2286678fa082/newrelic-8.8.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6662ec79493f23f9d0995a015177c87508bea4c541f7c9f17a61b503b82e1367"}, - {url = "https://files.pythonhosted.org/packages/44/3f/8a5cd001ab5a2dc0f6416afbdeabfb988912f2c345661ec737be256b757b/newrelic-8.8.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9355f209ba8d82fd0f9d78d7cc1d9bef0ae4677b3cfed7b7aaec521adbe87559"}, - {url = "https://files.pythonhosted.org/packages/46/08/85dff494ef49185cd39363294c613b7aef62aa3ee2175b3a3df0e71307cd/newrelic-8.8.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:435ac9e3791f78e05c9da8107a6ef49c13e62ac302696858fa2411198fe201ff"}, - {url = "https://files.pythonhosted.org/packages/57/47/3f79edeae09ee5b53eb6d215102ba84764ba3af5afc5acd7d74984169d0b/newrelic-8.8.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:796ed5ff44b04b41e051dc0112e5016e53a37e39e95023c45ff7ecd34c254a7d"}, - {url = "https://files.pythonhosted.org/packages/7e/47/515de1ee4f706188b7ee376bdeac96d4358bff976b97842d98ffe80f2ff4/newrelic-8.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4a0556c6ece49132ab1c32bfe398047a8311f9a8b6862b482495d132fcb0ad4"}, - {url = "https://files.pythonhosted.org/packages/80/3a/faa4137e8ce946ac75a9b27cad2d7dd09306fdf6a656f8c8d06e49db7688/newrelic-8.8.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcd3219e1e816a0fdb51ac993cac6744e6a835c13ee72e21d86bcbc2d16628ce"}, - {url = "https://files.pythonhosted.org/packages/96/14/ec5af84deda6d565a67ca54c0bb0620c0f62104fda193586b2ef7b907620/newrelic-8.8.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:d21af16cee1e0caf4c73c4c1b2d7ba9f33fe6a870d93135dc8b23ac592f49b38"}, - {url = "https://files.pythonhosted.org/packages/b2/69/994eefdc4759f45a98dab654227b013344f6e69b5590144071476cf99286/newrelic-8.8.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da8f2dc31e182768fe314d8ceb6f42acd09956708846f8ae71f07f044a3aa05e"}, - {url = "https://files.pythonhosted.org/packages/c1/6b/30e09d683d57d02827c36090cdcc5390646fb4a8915cb6cf465cf8b42fda/newrelic-8.8.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1bc307d06e2033637e7b484af22f540ca041fb23a54b311bcd5968ca1a64e4ef"}, - {url = "https://files.pythonhosted.org/packages/ee/aa/208f4eedd3d5e750bbbd1a6e50848104be440db6d115f8a9d883c117aca1/newrelic-8.8.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6b4db0e7544232d4e6e835a02ee28637970576f8dce82ffcaa3d675246e822d5"}, - {url = "https://files.pythonhosted.org/packages/f7/06/ae14351252d47260a17e7fca8527c8352efa707f8f3ba24ae4ce0aab5362/newrelic-8.8.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67902b3c53fa497dba887068166261d114ac2347c8a4908d735d7594cca163dc"}, -] "nose 1.3.7" = [ {url = "https://files.pythonhosted.org/packages/15/d8/dd071918c040f50fa1cf80da16423af51ff8ce4a0f2399b7bf8de45ac3d9/nose-1.3.7-py3-none-any.whl", hash = "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac"}, {url = "https://files.pythonhosted.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", hash = "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"}, {url = "https://files.pythonhosted.org/packages/99/4f/13fb671119e65c4dce97c60e67d3fd9e6f7f809f2b307e2611f4701205cb/nose-1.3.7-py2-none-any.whl", hash = "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a"}, ] -"oauthlib 3.2.0" = [ - {url = "https://files.pythonhosted.org/packages/1d/46/5ee2475e1b46a26ca0fa10d3c1d479577fde6ee289f8c6aa6d7ec33e31fd/oauthlib-3.2.0-py3-none-any.whl", hash = "sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe"}, - {url = "https://files.pythonhosted.org/packages/6e/7e/a43cec8b2df28b6494a865324f0ac4be213cb2edcf1e2a717547a93279b0/oauthlib-3.2.0.tar.gz", hash = "sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2"}, +"numpy 1.24.3" = [ + {url = "https://files.pythonhosted.org/packages/0d/43/643629a4a278b4815541c7d69856c07ddb0e99bdc62b43538d3751eae2d8/numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, + {url = "https://files.pythonhosted.org/packages/15/b8/cbe1750b9ec78062e5a00ef39ff8bdf189ce753b411b6b35931ababaee47/numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, + {url = "https://files.pythonhosted.org/packages/1a/62/af7e78a12207608b23e3b2e248fc823fbef75f17d5defc8a127c5661daca/numpy-1.24.3-cp38-cp38-win_amd64.whl", hash = "sha256:56e48aec79ae238f6e4395886b5eaed058abb7231fb3361ddd7bfdf4eed54289"}, + {url = "https://files.pythonhosted.org/packages/2c/d4/590ae7df5044465cc9fa2db152ae12468694d62d952b1528ecff328ef7fc/numpy-1.24.3.tar.gz", hash = "sha256:ab344f1bf21f140adab8e47fdbc7c35a477dc01408791f8ba00d018dd0bc5155"}, + {url = "https://files.pythonhosted.org/packages/53/f7/bf6e2b973c6d6a4c60f722dd95322d4997b4999347d67c5c74a4042a07b7/numpy-1.24.3-cp38-cp38-win32.whl", hash = "sha256:d933fabd8f6a319e8530d0de4fcc2e6a61917e0b0c271fded460032db42a0fe4"}, + {url = "https://files.pythonhosted.org/packages/54/41/fb17c1d48a574c50422ff3f1b17ed979b755adc6ed291c4a44a76e226c67/numpy-1.24.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ec87a7084caa559c36e0a2309e4ecb1baa03b687201d0a847c8b0ed476a7187"}, + {url = "https://files.pythonhosted.org/packages/5a/ab/d0eff89e0c05cc86fa7955c5e54e8ed0957a8a97a2516384b9ffd82008cc/numpy-1.24.3-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:352ee00c7f8387b44d19f4cada524586f07379c0d49270f87233983bc5087ca0"}, + {url = "https://files.pythonhosted.org/packages/62/e4/cd77d5f3d02c30d9ca8f2995df3cb3974c75cf1cc777fad445753475c4e4/numpy-1.24.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8535303847b89aa6b0f00aa1dc62867b5a32923e4d1681a35b5eef2d9591a463"}, + {url = "https://files.pythonhosted.org/packages/65/5d/46da284b0bf6cfbf04082c3c5e84399664d69e41c11a33587ad49b0c64e5/numpy-1.24.3-cp310-cp310-win_amd64.whl", hash = "sha256:ab5f23af8c16022663a652d3b25dcdc272ac3f83c3af4c02eb8b824e6b3ab9d7"}, + {url = "https://files.pythonhosted.org/packages/6f/72/38f9a536bdb5bfb1682f2520f133ec6e08dde8bcca1f632e347641d90763/numpy-1.24.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d926b52ba1367f9acb76b0df6ed21f0b16a1ad87c6720a1121674e5cf63e2b6"}, + {url = "https://files.pythonhosted.org/packages/72/eb/9c77bbc4d2b4ca17ef253621794a2d42897d896f86cd493db3eabe1a7d25/numpy-1.24.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76e3f4e85fc5d4fd311f6e9b794d0c00e7002ec122be271f2019d63376f1d385"}, + {url = "https://files.pythonhosted.org/packages/76/7c/cfb8ac4925defbe222aec15ac6b42b2a3d9bab7c9d13a2e767f534b35c2e/numpy-1.24.3-cp39-cp39-win_amd64.whl", hash = "sha256:d5036197ecae68d7f491fcdb4df90082b0d4960ca6599ba2659957aafced7c17"}, + {url = "https://files.pythonhosted.org/packages/79/4a/63a79242763edde0b5025d104cc2b78c44d89310b1bbc9b0f64a96b72ea0/numpy-1.24.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7776ea65423ca6a15255ba1872d82d207bd1e09f6d0894ee4a64678dd2204078"}, + {url = "https://files.pythonhosted.org/packages/82/19/321d369ede7458500f59151101470129d14f3b6768bb9b99bb7156f526b5/numpy-1.24.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1d3c026f57ceaad42f8231305d4653d5f05dc6332a730ae5c0bea3513de0950"}, + {url = "https://files.pythonhosted.org/packages/83/be/de078ac5e4ff572b1bdac1808b77cea2013b2c6286282f89b1de3e951273/numpy-1.24.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:210461d87fb02a84ef243cac5e814aad2b7f4be953b32cb53327bb49fd77fbb4"}, + {url = "https://files.pythonhosted.org/packages/89/e3/e2f478b2ff131e7c3171044a87e74df61db4b67fbcb90be479c07a44d0a7/numpy-1.24.3-cp310-cp310-win32.whl", hash = "sha256:f21c442fdd2805e91799fbe044a7b999b8571bb0ab0f7850d0cb9641a687092b"}, + {url = "https://files.pythonhosted.org/packages/8b/d9/814a619ab84d8eb0d95e08d4c723e665f1e694b5a6068ca505a61bdc3745/numpy-1.24.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4749e053a29364d3452c034827102ee100986903263e89884922ef01a0a6fd2f"}, + {url = "https://files.pythonhosted.org/packages/94/84/ed45416c8319c02348a5812d5647796a0833e3fb5576d01758f2a72e9200/numpy-1.24.3-cp311-cp311-win32.whl", hash = "sha256:c91c4afd8abc3908e00a44b2672718905b8611503f7ff87390cc0ac3423fb096"}, + {url = "https://files.pythonhosted.org/packages/96/92/2a8c1356e226311cf885e04eff576df8c357b2626c47c9283024bc24e01e/numpy-1.24.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea8282b9bcfe2b5e7d491d0bf7f3e2da29700cec05b49e64d6246923329f2b02"}, + {url = "https://files.pythonhosted.org/packages/a7/fe/72493149c65dcd39d8c8dc09870e242bd689d1db2bde3ec479807bf0d414/numpy-1.24.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecde0f8adef7dfdec993fd54b0f78183051b6580f606111a6d789cd14c61ea0c"}, + {url = "https://files.pythonhosted.org/packages/ca/13/c5bc0100b425f007412c3ba5d71e5ae9c08260fecbffd620764a9df1f4de/numpy-1.24.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ae8d0be48d1b6ed82588934aaaa179875e7dc4f3d84da18d7eae6eb3f06c242c"}, + {url = "https://files.pythonhosted.org/packages/d5/d6/07b37e7fecad7d158aabb4782a1b941e10afe8b80ec24cd64285a5bbb81b/numpy-1.24.3-cp39-cp39-win32.whl", hash = "sha256:784c6da1a07818491b0ffd63c6bbe5a33deaa0e25a20e1b3ea20cf0e43f8046c"}, + {url = "https://files.pythonhosted.org/packages/eb/10/2c3c672034d860bcca50b65d656e24c4e2ace9fb452fdd81da78cb7418a1/numpy-1.24.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7d6acc2e7524c9955e5c903160aa4ea083736fde7e91276b0e5d98e6332812"}, + {url = "https://files.pythonhosted.org/packages/ec/7d/f69c47ea3db0cd8ca444aec241a80b538eb176ae756820489a9d2946ec8c/numpy-1.24.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9a7721ec204d3a237225db3e194c25268faf92e19338a35f3a224469cb6039a3"}, + {url = "https://files.pythonhosted.org/packages/ee/6c/7217a8844dfe22e349bccbecd35571fa72c5d7fe8b33d8c5540e8cc2535c/numpy-1.24.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d6cc757de514c00b24ae8cf5c876af2a7c3df189028d68c0cb4eaa9cd5afc2bf"}, + {url = "https://files.pythonhosted.org/packages/f0/e8/1ea9adebdccaadfc208c7517e09f5145ed5a73069779ff436393085d47a2/numpy-1.24.3-cp311-cp311-win_amd64.whl", hash = "sha256:5342cf6aad47943286afa6f1609cad9b4266a05e7f2ec408e2cf7aea7ff69d80"}, + {url = "https://files.pythonhosted.org/packages/f3/23/7cc851bae09cf4db90d42a701dfe525780883ada86bece45e3da7a07e76b/numpy-1.24.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c1104d3c036fb81ab923f507536daedc718d0ad5a8707c6061cdfd6d184e570"}, + {url = "https://files.pythonhosted.org/packages/fa/7d/8dfb40eecbb6bc83ca00ef979f5cdeca5909a250cb8b642dcf1fbd34c078/numpy-1.24.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:202de8f38fc4a45a3eea4b63e2f376e5f2dc64ef0fa692838e31a808520efaf7"}, +] +"oauthlib 3.2.2" = [ + {url = "https://files.pythonhosted.org/packages/6d/fa/fbf4001037904031639e6bfbfc02badfc7e12f137a8afa254df6c4c8a670/oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"}, + {url = "https://files.pythonhosted.org/packages/7e/80/cab10959dc1faead58dc8384a781dfbf93cb4d33d50988f7a69f1b7c9bbe/oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"}, ] "packaging 23.1" = [ {url = "https://files.pythonhosted.org/packages/ab/c3/57f0601a2d4fe15de7a553c00adbc901425661bf048f2a22dfc500caf121/packaging-23.1-py3-none-any.whl", hash = "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61"}, @@ -1069,216 +1129,98 @@ content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f {url = "https://files.pythonhosted.org/packages/95/60/d93628975242cc515ab2b8f5b2fc831d8be2eff32f5a1be4776d49305d13/pathspec-0.11.1.tar.gz", hash = "sha256:2798de800fa92780e33acca925945e9a19a133b715067cf165b8866c15a31687"}, {url = "https://files.pythonhosted.org/packages/be/c8/551a803a6ebb174ec1c124e68b449b98a0961f0b737def601e3c1fbb4cfd/pathspec-0.11.1-py3-none-any.whl", hash = "sha256:d8af70af76652554bd134c22b3e8a1cc46ed7d91edcdd721ef1a0c51a84a5293"}, ] -"platformdirs 3.5.0" = [ - {url = "https://files.pythonhosted.org/packages/91/17/3836ffe140abb245726d0e21c5b9b984e2569e7027c20d12e969ec69bd8a/platformdirs-3.5.0.tar.gz", hash = "sha256:7954a68d0ba23558d753f73437c55f89027cf8f5108c19844d4b82e5af396335"}, - {url = "https://files.pythonhosted.org/packages/ce/cf/279b73aae00f7ba9d5d7664156ef323ebbf16fb556285bb223ecc45031aa/platformdirs-3.5.0-py3-none-any.whl", hash = "sha256:47692bc24c1958e8b0f13dd727307cff1db103fca36399f457da8e05f222fdc4"}, -] -"psycopg2 2.8.6" = [ - {url = "https://files.pythonhosted.org/packages/00/13/ce81fc492fb61f33e2dd247e638c4c8a2187c58864e61a04de8496429e6e/psycopg2-2.8.6-cp39-cp39-win32.whl", hash = "sha256:2c93d4d16933fea5bbacbe1aaf8fa8c1348740b2e50b3735d1b0bf8154cbf0f3"}, - {url = "https://files.pythonhosted.org/packages/18/35/4be44fc779e8c8a7aedc4b19bf91dcd476edabd471b4d7c82f216b5ba271/psycopg2-2.8.6-cp38-cp38-win_amd64.whl", hash = "sha256:56007a226b8e95aa980ada7abdea6b40b75ce62a433bd27cec7a8178d57f4051"}, - {url = "https://files.pythonhosted.org/packages/44/1f/a6ae3527568bb9a3d49339beb630ede2dcb345c88cc3cdc2a6dfbb78110e/psycopg2-2.8.6-cp37-cp37m-win_amd64.whl", hash = "sha256:56fee7f818d032f802b8eed81ef0c1232b8b42390df189cab9cfa87573fe52c5"}, - {url = "https://files.pythonhosted.org/packages/6f/8f/89b52c494dfb7f4f4c251e310b78b49f204ce0386f28316a92413e0e60bf/psycopg2-2.8.6-cp38-cp38-win32.whl", hash = "sha256:ad2fe8a37be669082e61fb001c185ffb58867fdbb3e7a6b0b0d2ffe232353a3e"}, - {url = "https://files.pythonhosted.org/packages/90/24/53f39fde488210c09869ac6bade7cfefa982fe542197716b190bac826733/psycopg2-2.8.6-cp35-cp35m-win32.whl", hash = "sha256:26e7fd115a6db75267b325de0fba089b911a4a12ebd3d0b5e7acb7028bc46821"}, - {url = "https://files.pythonhosted.org/packages/9f/6f/ec0689612a630f2b34c734c3d8db40f9a385898dec14f49306ed73c2ecd5/psycopg2-2.8.6-cp36-cp36m-win32.whl", hash = "sha256:a49833abfdede8985ba3f3ec641f771cca215479f41523e99dace96d5b8cce2a"}, - {url = "https://files.pythonhosted.org/packages/bc/c1/0bf0150848f600be3839b1ea01b037d6355e191486f04c6f3af4e75d1b38/psycopg2-2.8.6-cp27-cp27m-win_amd64.whl", hash = "sha256:d160744652e81c80627a909a0e808f3c6653a40af435744de037e3172cf277f5"}, - {url = "https://files.pythonhosted.org/packages/d5/14/cf8f9edb6aa1a7eea9587ee446276974b3096b5abed63e28323ede746397/psycopg2-2.8.6-cp34-cp34m-win32.whl", hash = "sha256:b8cae8b2f022efa1f011cc753adb9cbadfa5a184431d09b273fb49b4167561ad"}, - {url = "https://files.pythonhosted.org/packages/d6/eb/ba556d3d642fedf220e2e7e4f16085d6f1f0363a1670fc4b72a26f497c5c/psycopg2-2.8.6-cp39-cp39-win_amd64.whl", hash = "sha256:d5062ae50b222da28253059880a871dc87e099c25cb68acf613d9d227413d6f7"}, - {url = "https://files.pythonhosted.org/packages/e3/a8/aa3d862173bfcc2f7d4a00516c293bc1c660933b35909c4373025636f508/psycopg2-2.8.6-cp35-cp35m-win_amd64.whl", hash = "sha256:00195b5f6832dbf2876b8bf77f12bdce648224c89c880719c745b90515233301"}, - {url = "https://files.pythonhosted.org/packages/e4/08/c0ad8002f69d4d31a656ed1a865f6cc6b3b781f03b6525455e3a79281a94/psycopg2-2.8.6-cp37-cp37m-win32.whl", hash = "sha256:6a3d9efb6f36f1fe6aa8dbb5af55e067db802502c55a9defa47c5a1dad41df84"}, - {url = "https://files.pythonhosted.org/packages/ec/c0/72786579c3d8e87b9b602c32c633c36dc20e346bddbcc506b1085513f8f8/psycopg2-2.8.6-cp34-cp34m-win_amd64.whl", hash = "sha256:f22ea9b67aea4f4a1718300908a2fb62b3e4276cf00bd829a97ab5894af42ea3"}, - {url = "https://files.pythonhosted.org/packages/f4/1f/ca233a88530fb2ad7b6fa291765a55ec9fb7573c454f576e55ac232b0252/psycopg2-2.8.6-cp27-cp27m-win32.whl", hash = "sha256:068115e13c70dc5982dfc00c5d70437fe37c014c808acce119b5448361c03725"}, - {url = "https://files.pythonhosted.org/packages/fd/09/b6c3e8442db0342629d1c95e9c451d7ee0920f6c1152edcc0d4bd0ee7ade/psycopg2-2.8.6-cp36-cp36m-win_amd64.whl", hash = "sha256:f974c96fca34ae9e4f49839ba6b78addf0346777b46c4da27a7bf54f48d3057d"}, - {url = "https://files.pythonhosted.org/packages/fd/ae/98cb7a0cbb1d748ee547b058b14604bd0e9bf285a8e0cc5d148f8a8a952e/psycopg2-2.8.6.tar.gz", hash = "sha256:fb23f6c71107c37fd667cb4ea363ddeb936b348bbd6449278eb92c189699f543"}, -] -"pycodestyle 2.6.0" = [ - {url = "https://files.pythonhosted.org/packages/10/5b/88879fb861ab79aef45c7e199cae3ef7af487b5603dcb363517a50602dd7/pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"}, - {url = "https://files.pythonhosted.org/packages/bb/82/0df047a5347d607be504ad5faa255caa7919562962b934f9372b157e8a70/pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"}, +"platformdirs 3.5.1" = [ + {url = "https://files.pythonhosted.org/packages/89/7e/c6ff9ddcf93b9b36c90d88111c4db354afab7f9a58c7ac3257fa717f1268/platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, + {url = "https://files.pythonhosted.org/packages/9c/0e/ae9ef1049d4b5697e79250c4b2e72796e4152228e67733389868229c92bb/platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, +] +"psycopg2 2.9.6" = [ + {url = "https://files.pythonhosted.org/packages/2f/e0/f0db22e36faf2b62557ed11e942cc47f3b96d52b686fa838a3ca6b3c90b3/psycopg2-2.9.6-cp38-cp38-win32.whl", hash = "sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"}, + {url = "https://files.pythonhosted.org/packages/49/8e/52252e78c8fd2cc91dae13d2686b103237900fd05f80adc1efc366b40f65/psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"}, + {url = "https://files.pythonhosted.org/packages/4b/6a/450b97eb81f64f4788a6c5c4282ef2f73b023cc1ceab906ca63cab864440/psycopg2-2.9.6-cp311-cp311-win32.whl", hash = "sha256:53f4ad0a3988f983e9b49a5d9765d663bbe84f508ed655affdb810af9d0972ad"}, + {url = "https://files.pythonhosted.org/packages/4b/8e/69c0ea73e96afc1efb9f459050a14391fae20db81ff1815bf27c8ddc3160/psycopg2-2.9.6-cp38-cp38-win_amd64.whl", hash = "sha256:d24ead3716a7d093b90b27b3d73459fe8cd90fd7065cf43b3c40966221d8c394"}, + {url = "https://files.pythonhosted.org/packages/9b/e1/04d7d48986b123775840fb64bc07642fe186079564744ed9955162891b24/psycopg2-2.9.6-cp310-cp310-win32.whl", hash = "sha256:f7a7a5ee78ba7dc74265ba69e010ae89dae635eea0e97b055fb641a01a31d2b1"}, + {url = "https://files.pythonhosted.org/packages/ad/8d/88ab18931ee8d7434163671dbc6bbfd8c07ff8777fe6d156fabcb3672927/psycopg2-2.9.6-cp37-cp37m-win32.whl", hash = "sha256:869776630c04f335d4124f120b7fb377fe44b0a7645ab3c34b4ba42516951889"}, + {url = "https://files.pythonhosted.org/packages/af/c4/5726cddb53fe52f0e839eb3da04322364f14493217ebd5818cc5e4c948a5/psycopg2-2.9.6.tar.gz", hash = "sha256:f15158418fd826831b28585e2ab48ed8df2d0d98f502a2b4fe619e7d5ca29011"}, + {url = "https://files.pythonhosted.org/packages/c2/47/d142314e126c0ea7c8f4c0043cad069e359ce04975fd7d296c4af7f5a5c4/psycopg2-2.9.6-cp36-cp36m-win32.whl", hash = "sha256:11aca705ec888e4f4cea97289a0bf0f22a067a32614f6ef64fcf7b8bfbc53744"}, + {url = "https://files.pythonhosted.org/packages/c9/37/f49a95fb00ca9f4678475284e60cb341aea84201ac45faa9f32ad88c02e8/psycopg2-2.9.6-cp311-cp311-win_amd64.whl", hash = "sha256:b81fcb9ecfc584f661b71c889edeae70bae30d3ef74fa0ca388ecda50b1222b7"}, + {url = "https://files.pythonhosted.org/packages/ca/4a/b2f2cc9a3384b438961f9953fd82a20514c60a87f378f4a475f1b9de184b/psycopg2-2.9.6-cp310-cp310-win_amd64.whl", hash = "sha256:f75001a1cbbe523e00b0ef896a5a1ada2da93ccd752b7636db5a99bc57c44494"}, + {url = "https://files.pythonhosted.org/packages/e1/56/6558cc5b4380dc2ef0ea6c96eeb6fcb26111081ec07f0dade2c3b9bc1f06/psycopg2-2.9.6-cp36-cp36m-win_amd64.whl", hash = "sha256:36c941a767341d11549c0fbdbb2bf5be2eda4caf87f65dfcd7d146828bd27f39"}, + {url = "https://files.pythonhosted.org/packages/e2/38/4a2cc3f697f40f09617697a795c73697eec464009f4c5e47cf4050f45b63/psycopg2-2.9.6-cp37-cp37m-win_amd64.whl", hash = "sha256:a8ad4a47f42aa6aec8d061fdae21eaed8d864d4bb0f0cade5ad32ca16fcd6258"}, + {url = "https://files.pythonhosted.org/packages/e3/76/08d3297720f2d0636a934aa30bf3343e6c4b869c12ba6294b8c1739af76b/psycopg2-2.9.6-cp39-cp39-win32.whl", hash = "sha256:1861a53a6a0fd248e42ea37c957d36950da00266378746588eab4f4b5649e95f"}, +] +"pycodestyle 2.10.0" = [ + {url = "https://files.pythonhosted.org/packages/06/6b/5ca0d12ef7dcf7d20dfa35287d02297f3e0f9e515da5183654c03a9636ce/pycodestyle-2.10.0.tar.gz", hash = "sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053"}, + {url = "https://files.pythonhosted.org/packages/a2/54/001fdc0d69e8d0bb86c3423a6fa6dfada8cc26317c2635ab543e9ac411bd/pycodestyle-2.10.0-py2.py3-none-any.whl", hash = "sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610"}, ] "pycparser 2.21" = [ {url = "https://files.pythonhosted.org/packages/5e/0b/95d387f5f4433cb0f53ff7ad859bd2c6051051cebbb564f139a999ab46de/pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, {url = "https://files.pythonhosted.org/packages/62/d5/5f610ebe421e85889f2e55e33b7f9a6795bd982198517d912eb1c76e1a53/pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, ] -"pyflakes 2.2.0" = [ - {url = "https://files.pythonhosted.org/packages/69/5b/fd01b0c696f2f9a6d2c839883b642493b431f28fa32b29abc465ef675473/pyflakes-2.2.0-py2.py3-none-any.whl", hash = "sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92"}, - {url = "https://files.pythonhosted.org/packages/f1/e2/e02fc89959619590eec0c35f366902535ade2728479fc3082c8af8840013/pyflakes-2.2.0.tar.gz", hash = "sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8"}, -] -"pyparsing 2.4.7" = [ - {url = "https://files.pythonhosted.org/packages/8a/bb/488841f56197b13700afd5658fc279a2025a39e22449b7cf29864669b15d/pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, - {url = "https://files.pythonhosted.org/packages/c1/47/dfc9c342c9842bbe0036c7f763d2d6686bcf5eb1808ba3e170afdb282210/pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, -] -"pyproj 3.5.0" = [ - {url = "https://files.pythonhosted.org/packages/09/92/3e89e4bab0a6f0bc2ede2f56197eaf8cf8b7eb3dc88a6302c563e947501d/pyproj-3.5.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2b708fd43453b985642b737d4a6e7f1d6a0ab1677ffa4e14cc258537b49224b0"}, - {url = "https://files.pythonhosted.org/packages/0a/0d/5feef9b2e2e447f23c3289db4dc100e6e28510b87c6cfbd14ad338bdfd49/pyproj-3.5.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:71b65f2a38cd9e16883dbb0f8ae82bdf8f6b79b1b02975c78483ab8428dbbf2f"}, - {url = "https://files.pythonhosted.org/packages/0c/8a/1febafc7bdeeede1f0bf76411ff55db266d25ce5ad713050973b7c3e29b7/pyproj-3.5.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:621d78a9d8bf4d06e08bef2471021fbcb1a65aa629ad4a20c22e521ce729cc20"}, - {url = "https://files.pythonhosted.org/packages/11/3a/c49b3dd5fad200ab0f061540f574b12638cf4c5a3e9d167f2a9e2d5dd5a0/pyproj-3.5.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:fde5ece4d2436b5a57c8f5f97b49b5de06a856d03959f836c957d3e609f2de7e"}, - {url = "https://files.pythonhosted.org/packages/12/e3/3c158c05a43f3ec53091e284100b49733f69dbff359bce64ef749fc2751c/pyproj-3.5.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:385b0341861d3ebc8cad98337a738821dcb548d465576527399f4955ca24b6ed"}, - {url = "https://files.pythonhosted.org/packages/16/d1/683c6264931ff8ecf11b63f7a5d2c705cb5aa91f50bbd3e08a5e5a1e3aee/pyproj-3.5.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38862fe07316ae12b79d82d298e390973a4f00b684f3c2d037238e20e00610ba"}, - {url = "https://files.pythonhosted.org/packages/1b/01/6df17f3b802b2d49480c102516dff30d294c4d300dbc3dfa9a9867b83609/pyproj-3.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b7c2113c4d11184a238077ec85e31eda1dcc58ffeb9a4429830e0a7036e787d"}, - {url = "https://files.pythonhosted.org/packages/43/62/f157de7f1946c075325f67d82e81ab3e424fbac516a8df968b96312494c6/pyproj-3.5.0-cp38-cp38-win32.whl", hash = "sha256:b937215bfbaf404ec8f03ca741fc3f9f2c4c2c5590a02ccddddd820ae3c71331"}, - {url = "https://files.pythonhosted.org/packages/44/b9/c278d17300f931e96dd8cc26a7afb46dc08ec82d74e1515ba355c1df17f1/pyproj-3.5.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:61e4ad57d89b03a7b173793b31bca8ee110112cde1937ef0f42a70b9120c827d"}, - {url = "https://files.pythonhosted.org/packages/47/05/0fafb80be2f90c00d5f5d659919259ba5a051079cf826dc668df5a938dae/pyproj-3.5.0-pp38-pypy38_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:788a5dadb532644a64efe0f5f01bf508c821eb7e984f13a677d56002f1e8a67a"}, - {url = "https://files.pythonhosted.org/packages/54/9e/3aabbd3e521eab15040348e66d7571d6514c528b18532c3e0dbd6268e799/pyproj-3.5.0-cp310-cp310-win32.whl", hash = "sha256:6f316a66031a14e9c5a88c91f8b77aa97f5454895674541ed6ab630b682be35d"}, - {url = "https://files.pythonhosted.org/packages/65/76/4ab2d022d0978ecd1f598c1b0a464a78885070dc41c03ce362f26e513d8b/pyproj-3.5.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bdd2021bb6f7f346bfe1d2a358aa109da017d22c4704af2d994e7c7ee0a7a53"}, - {url = "https://files.pythonhosted.org/packages/75/b4/f1f70c33519f223ecd4c1227ca840d8501e405e07d38b9f783969c41f9c8/pyproj-3.5.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d9a024370e917c899bff9171f03ea6079deecdc7482a146a2c565f3b9df134ea"}, - {url = "https://files.pythonhosted.org/packages/77/77/cbdb48696e33abfab7a342184d9a37274bf67bd7a442b6ab74418b5e6e20/pyproj-3.5.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d711517a8487ef3245b08dc82f781a906df9abb3b6cb0ce0486f0eeb823ca570"}, - {url = "https://files.pythonhosted.org/packages/7d/dc/fc51814f1a1038a344f596aed3e1c5da33893f2965a398ea0c932dfe93f4/pyproj-3.5.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7572983134e310e0ca809c63f1722557a040fe9443df5f247bf11ba887eb1229"}, - {url = "https://files.pythonhosted.org/packages/81/ba/ff6015d09cd8510367114fd1602051043c7847ad8fea077308feca9904d7/pyproj-3.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd5e2b6aa255023c4acd0b977590f1f7cc801ba21b4d806fcf6dfac3474ebb83"}, - {url = "https://files.pythonhosted.org/packages/8d/b0/4de0af66387a6a8ffa2309c92c994872a8e6c49a29a45ed90da4935963a2/pyproj-3.5.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b60d93a200639e8367c6542a964fd0aa2dbd152f256c1831dc18cd5aa470fb8a"}, - {url = "https://files.pythonhosted.org/packages/8e/29/9e37087c94128aff0892080bf6aff9375a3c7d491780ed670cd57ea63dce/pyproj-3.5.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eccb417b91d0be27805dfc97550bfb8b7db94e9fe1db5ebedb98f5b88d601323"}, - {url = "https://files.pythonhosted.org/packages/94/d1/657cff06d9c539b7646b1deea97c1880cbfcf2099e54f49a589682d4b99a/pyproj-3.5.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5674923351e76222e2c10c58b5e1ac119d7a46b270d822c463035971b06f724b"}, - {url = "https://files.pythonhosted.org/packages/99/d7/de65c65e430f603a51d405ff681fd8ac8ba5d2a2702a1eb896b8482f4f40/pyproj-3.5.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e08db25b61cf024648d55973cc3d1c3f1d0818fabf594d5f5a8e2318103d2aa0"}, - {url = "https://files.pythonhosted.org/packages/9a/49/dc0b35684ef1e4a95b11e38be29baa3a298be74fb2149eae3c2b3ed55d1d/pyproj-3.5.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:052c49fce8b5d55943a35c36ccecb87350c68b48ba95bc02a789770c374ef819"}, - {url = "https://files.pythonhosted.org/packages/9c/0c/7e5d4d965fb9eebda44084737b113847134815208f21b967f3a2879f1427/pyproj-3.5.0-cp39-cp39-win32.whl", hash = "sha256:5c4b85ac10d733c42d73a2e6261c8d6745bf52433a31848dd1b6561c9a382da3"}, - {url = "https://files.pythonhosted.org/packages/9c/f5/cd9371194d3c939dffddff9e118a018bb7c2f560549bea4c6bc21b24eadd/pyproj-3.5.0.tar.gz", hash = "sha256:9859d1591c1863414d875ae0759e72c2cffc01ab989dc64137fbac572cc81bf6"}, - {url = "https://files.pythonhosted.org/packages/b8/ab/92a809e5bfe8bb00a7288426de5b1de7bbfd337fce09069cd7caffca1a3d/pyproj-3.5.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73f7960a97225812f9b1d7aeda5fb83812f38de9441e3476fcc8abb3e2b2f4de"}, - {url = "https://files.pythonhosted.org/packages/cc/2d/05a84266790936fc9f65731a1a49f0fd6e4e7c994a2c56948aad5583e5ae/pyproj-3.5.0-cp38-cp38-win_amd64.whl", hash = "sha256:97ed199033c2c770e7eea2ef80ff5e6413426ec2d7ec985b869792f04ab95d05"}, - {url = "https://files.pythonhosted.org/packages/d1/af/fb75eb28ef9a5cddbd0c6352c3defc44235f8afe7feddeb06f8ba17ef51b/pyproj-3.5.0-cp39-cp39-win_amd64.whl", hash = "sha256:1798ff7d65d9057ebb2d017ffe8403268b8452f24d0428b2140018c25c7fa1bc"}, - {url = "https://files.pythonhosted.org/packages/d3/89/0bf944d2e50500eaceab030454af748bf0fdb90a00b1fcdca3e1464850e4/pyproj-3.5.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6475ce653880938468a1a1b7321267243909e34b972ba9e53d5982c41d555918"}, - {url = "https://files.pythonhosted.org/packages/da/01/b69528f2137e35665bf0fa60bb4ead2d06e35ca13e8683ca2b192c0306eb/pyproj-3.5.0-cp310-cp310-win_amd64.whl", hash = "sha256:f7c2f4d9681e810cf40239caaca00079930a6d9ee6591139b88d592d36051d82"}, - {url = "https://files.pythonhosted.org/packages/e0/07/fbc65db1c4c9b387b0c8bf9ed4d26d6544026c40ebe930e645bb22f20ee1/pyproj-3.5.0-cp311-cp311-win_amd64.whl", hash = "sha256:e97573de0ab3bbbcb4c7748bc41f4ceb6da10b45d35b1a294b5820701e7c25f0"}, - {url = "https://files.pythonhosted.org/packages/e1/63/07781eb5463b1aeb255962ad5106a1ccce986aee804d2ac5f8d61796a03b/pyproj-3.5.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1507138ea28bf2134d31797675380791cc1a7156a3aeda484e65a78a4aba9b62"}, - {url = "https://files.pythonhosted.org/packages/e6/ca/cb70a26fcc6d760be897331d9a7c3c3916b31d20074070401a22d7c90db9/pyproj-3.5.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c02742ef3d846401861a878a61ef7ad911ea7539d6cc4619ddb52dbdf7b45aee"}, - {url = "https://files.pythonhosted.org/packages/e9/41/dd2cc950ce31f27983e8eb8ce5d371e367d5a7ccb53f2fbc3c7cead273fb/pyproj-3.5.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a87b419a2a352413fbf759ecb66da9da50bd19861c8f26db6a25439125b27b9"}, - {url = "https://files.pythonhosted.org/packages/f9/77/930b8168355d3ffb483e9fc7974621ff6a54767fc26cb6927741e99b50a1/pyproj-3.5.0-cp311-cp311-win32.whl", hash = "sha256:a730f5b4c98c8a0f312437873e6e34dbd4cc6dc23d5afd91a6691c62724b1f68"}, - {url = "https://files.pythonhosted.org/packages/fa/5b/0637f05785e5f6e11c875dd22ab6bdb59e276f2418fbf64c8471fe189be3/pyproj-3.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8fe6bb1b68a35d07378d38be77b5b2f8dd2bea5910c957bfcc7bee55988d3910"}, - {url = "https://files.pythonhosted.org/packages/fc/90/ae0b79da1bea66ac85d6ff0c433214a1f6e028e64b9fd17d26038954cef8/pyproj-3.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b752b7d9c4b08181c7e8c0d9c7f277cbefff42227f34d3310696a87c863d9dd3"}, -] -"python-dateutil 2.8.1" = [ - {url = "https://files.pythonhosted.org/packages/be/ed/5bbc91f03fa4c839c4c7360375da77f9659af5f7086b7a7bdda65771c8e0/python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, - {url = "https://files.pythonhosted.org/packages/d4/70/d60450c3dd48ef87586924207ae8907090de0b306af2bce5d134d78615cb/python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, -] -"python-dotenv 0.14.0" = [ - {url = "https://files.pythonhosted.org/packages/33/3d/a0c00002bae69321f5b87ea7ed123ddf1933e09d3ff658d277889698ee59/python-dotenv-0.14.0.tar.gz", hash = "sha256:8c10c99a1b25d9a68058a1ad6f90381a62ba68230ca93966882a4dbc3bc9c33d"}, - {url = "https://files.pythonhosted.org/packages/f2/16/28d434b28c5be29a6af8fd0e3a2bda3bd30500ef0cd17bc79f7a6793a8d4/python_dotenv-0.14.0-py2.py3-none-any.whl", hash = "sha256:c10863aee750ad720f4f43436565e4c1698798d763b63234fb5021b6c616e423"}, -] -"python-editor 1.0.4" = [ - {url = "https://files.pythonhosted.org/packages/0a/85/78f4a216d28343a67b7397c99825cff336330893f00601443f7c7b2f2234/python-editor-1.0.4.tar.gz", hash = "sha256:51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b"}, - {url = "https://files.pythonhosted.org/packages/55/a0/3c0ba1c10f2ca381645dd46cb7afbb73fddc8de9f957e1f9e726a846eabc/python_editor-1.0.4-py2-none-any.whl", hash = "sha256:5f98b069316ea1c2ed3f67e7f5df6c0d8f10b689964a4a811ff64f0106819ec8"}, - {url = "https://files.pythonhosted.org/packages/c6/d3/201fc3abe391bbae6606e6f1d598c15d367033332bd54352b12f35513717/python_editor-1.0.4-py3-none-any.whl", hash = "sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d"}, -] -"python-slugify 4.0.1" = [ - {url = "https://files.pythonhosted.org/packages/9f/42/e336f96a8b6007428df772d0d159b8eee9b2f1811593a4931150660402c0/python-slugify-4.0.1.tar.gz", hash = "sha256:69a517766e00c1268e5bbfc0d010a0a8508de0b18d30ad5a1ff357f8ae724270"}, -] -"pytz 2020.1" = [ - {url = "https://files.pythonhosted.org/packages/4f/a4/879454d49688e2fad93e59d7d4efda580b783c745fd2ec2a3adf87b0808d/pytz-2020.1-py2.py3-none-any.whl", hash = "sha256:a494d53b6d39c3c6e44c3bec237336e14305e4f29bbf800b599253057fbb79ed"}, - {url = "https://files.pythonhosted.org/packages/f4/f6/94fee50f4d54f58637d4b9987a1b862aeb6cd969e73623e02c5c00755577/pytz-2020.1.tar.gz", hash = "sha256:c35965d010ce31b23eeb663ed3cc8c906275d6be1a34393a1d73a41febf4a048"}, -] -"pyyaml 5.4" = [ - {url = "https://files.pythonhosted.org/packages/0c/9a/175d8c34ae6275866c2ad926ced27008ca85242faaae1b93979f3c048561/PyYAML-5.4-cp27-cp27m-win_amd64.whl", hash = "sha256:a36a48a51e5471513a5aea920cdad84cbd56d70a5057cca3499a637496ea379c"}, - {url = "https://files.pythonhosted.org/packages/1b/bd/6cbbd6f79e1741ebbc376d8f63ed6fbe22260605a0e56ba17dcd19f3a962/PyYAML-5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:124fd7c7bc1e95b1eafc60825f2daf67c73ce7b33f1194731240d24b0d1bf628"}, - {url = "https://files.pythonhosted.org/packages/2e/36/591fa17e752056a0308c40f9446578ad7dca924594e226098afbb57d9093/PyYAML-5.4-cp39-cp39-win_amd64.whl", hash = "sha256:8bf38641b4713d77da19e91f8b5296b832e4db87338d6aeffe422d42f1ca896d"}, - {url = "https://files.pythonhosted.org/packages/43/e8/31007862b01580c507e24b88aeedb71bb81d6125a71c651a26370e6e0648/PyYAML-5.4-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:02c78d77281d8f8d07a255e57abdbf43b02257f59f50cc6b636937d68efa5dd0"}, - {url = "https://files.pythonhosted.org/packages/55/cb/1ca960ac18a82000e7b35ea314a32bb27a6c549b3dd92d4926741042279b/PyYAML-5.4-cp27-cp27m-win32.whl", hash = "sha256:52bf0930903818e600ae6c2901f748bc4869c0c406056f679ab9614e5d21a166"}, - {url = "https://files.pythonhosted.org/packages/60/a0/c6c7fb6604a6083d1bb7a96e6841132e6256742e9ffbb981f9496adbe97c/PyYAML-5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cc547d3ead3754712223abb7b403f0a184e4c3eae18c9bb7fd15adef1597cc4b"}, - {url = "https://files.pythonhosted.org/packages/71/02/d398b477f89c690f1d4b96d9ea4e807e065d4d49bcd195c406c262726c46/PyYAML-5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:7242790ab6c20316b8e7bb545be48d7ed36e26bbe279fd56f2c4a12510e60b4b"}, - {url = "https://files.pythonhosted.org/packages/73/e8/e213c2752d258c0281c2a513f73a9cc0b937d06f3943f3621988ca46ccac/PyYAML-5.4-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:f7a21e3d99aa3095ef0553e7ceba36fb693998fbb1226f1392ce33681047465f"}, - {url = "https://files.pythonhosted.org/packages/78/73/67c64bbc2e57b6b5e43d6849868c945f4ada0b582405899b7f50861cfc77/PyYAML-5.4-cp39-cp39-win32.whl", hash = "sha256:fdc6b2cb4b19e431994f25a9160695cc59a4e861710cc6fc97161c5e845fc579"}, - {url = "https://files.pythonhosted.org/packages/7f/27/b50b59b50733dcb89d3436707d70310f2329eaa598f9ff28515dc97b7b6b/PyYAML-5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc552b6434b90d9dbed6a4f13339625dc466fd82597119897e9489c953acbc22"}, - {url = "https://files.pythonhosted.org/packages/84/8a/feb2444e1df62c8d209de96e9120b21bd51941f7148a87ab987a939f2af6/PyYAML-5.4-cp38-cp38-win32.whl", hash = "sha256:26fcb33776857f4072601502d93e1a619f166c9c00befb52826e7b774efaa9db"}, - {url = "https://files.pythonhosted.org/packages/86/13/12bee17506e65ff2b7931055e846b6b8c7885d62741063541b2adcb26ff7/PyYAML-5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:f3790156c606299ff499ec44db422f66f05a7363b39eb9d5b064f17bd7d7c47b"}, - {url = "https://files.pythonhosted.org/packages/86/cf/892fb8177b0eb25e118f761eeed5a94df16ad2a82a78a43647c106a11e5f/PyYAML-5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:31ba07c54ef4a897758563e3a0fcc60077698df10180abe4b8165d9895c00ebf"}, - {url = "https://files.pythonhosted.org/packages/8a/f2/d2567a720055e0dc09254edd0db810cfdaae01b922fb5bfd6178631b689a/PyYAML-5.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0dc9f2eb2e3c97640928dec63fd8dc1dd91e6b6ed236bd5ac00332b99b5c2ff9"}, - {url = "https://files.pythonhosted.org/packages/8e/d3/33437da769147dcde81ffdbd7ecc2dff2674a2857e6e6dd82d183934fbac/PyYAML-5.4-cp38-cp38-win_amd64.whl", hash = "sha256:b2243dd033fd02c01212ad5c601dafb44fbb293065f430b0d3dbf03f3254d615"}, - {url = "https://files.pythonhosted.org/packages/99/11/b472b1a7a5904df2c52952d37db264d090b616e330db3c60e0590a08ccb2/PyYAML-5.4-cp36-cp36m-win32.whl", hash = "sha256:5a3f345acff76cad4aa9cb171ee76c590f37394186325d53d1aa25318b0d4a09"}, - {url = "https://files.pythonhosted.org/packages/a1/7a/b20840eda7a55ab7342fd284c6d66203532789d2805845925930bc7e6d9b/PyYAML-5.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8635d53223b1f561b081ff4adecb828fd484b8efffe542edcfdff471997f7c39"}, - {url = "https://files.pythonhosted.org/packages/b5/fd/15638de2da0a5aa91c095718444624aa565f766fc178249ca6faa372f71a/PyYAML-5.4.tar.gz", hash = "sha256:3c49e39ac034fd64fd576d63bb4db53cda89b362768a67f07749d55f128ac18a"}, - {url = "https://files.pythonhosted.org/packages/d3/f8/ca82d242dffa702a0a81f1a70eba04bf1f705b93883e8435b1400861844d/PyYAML-5.4-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:5e7ac4e0e79a53451dc2814f6876c2fa6f71452de1498bbe29c0b54b69a986f4"}, - {url = "https://files.pythonhosted.org/packages/e3/d0/87dd20c93d144fdd15ecc0f2f8904e2ccf1f58203b5f8079d089d79b5c4f/PyYAML-5.4-cp37-cp37m-win32.whl", hash = "sha256:737bd70e454a284d456aa1fa71a0b429dd527bcbf52c5c33f7c8eee81ac16b89"}, - {url = "https://files.pythonhosted.org/packages/f1/86/83ae5504903b4eca5ae1fd3c53b87b640f9c302df2c97fc08331ec7f3c8a/PyYAML-5.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:8b818b6c5a920cbe4203b5a6b14256f0e5244338244560da89b7b0f1313ea4b6"}, -] -"regex 2022.10.31" = [ - {url = "https://files.pythonhosted.org/packages/00/7e/ab5a54f60e36f4de0610850866b848839a7b02ad4f05755bce429fbc1a5a/regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, - {url = "https://files.pythonhosted.org/packages/00/92/25b0b709d591ecd27e1bfb48c64d813a4ed4be0feb0321ea0b55db012099/regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, - {url = "https://files.pythonhosted.org/packages/01/b3/a01602507224e611caa3c0f2a4aa96f4c03fdce482fa4527de61678a3018/regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, - {url = "https://files.pythonhosted.org/packages/04/de/e8ed731b334e5f962ef035a32f151fffb2f839eccfba40c3ebdac9b26e03/regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, - {url = "https://files.pythonhosted.org/packages/07/ba/7021c60d02f7fe7c3e4ee9636d8a2d93bd894a5063c2b5f35e2e31b1f3ad/regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, - {url = "https://files.pythonhosted.org/packages/08/28/f038ff3c5cfd30760bccefbe0b98d51cf61192ec8d3d55dd51564bf6c6b8/regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, - {url = "https://files.pythonhosted.org/packages/08/cb/0445a970e755eb806945a166729210861391f645223187aa11fcbbb606ce/regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, - {url = "https://files.pythonhosted.org/packages/08/e2/94af654d5fdfdad3a05991e104df66c42945650d31713fe290cd446178f1/regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, - {url = "https://files.pythonhosted.org/packages/08/ef/96ef949ee331d39489799b44f2d5aa8a252a2d7aa4a96edbb05425d344f6/regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, - {url = "https://files.pythonhosted.org/packages/09/d3/70714b99c25bac40f81eaf3fe06eb016c5b9b9ac88815145dc6aa7d06b68/regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, - {url = "https://files.pythonhosted.org/packages/0a/cd/4dfdfddca4478ad0ebb6053b2c2923eef1a8660ceb9f495e7a6abb62da15/regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, - {url = "https://files.pythonhosted.org/packages/0b/cc/4f2cacc95e20cdef6421072b896bfea9cb9c54a78c4ea1253eb25a699782/regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, - {url = "https://files.pythonhosted.org/packages/10/13/95d658ca010507b5a179d7fe8376d37d20c22f9be5abdd301832618463a8/regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, - {url = "https://files.pythonhosted.org/packages/10/1c/9b6827dd3be88b39d0ecce25abb27ad2a8104b1816da262c3ffd38311ea3/regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, - {url = "https://files.pythonhosted.org/packages/18/9c/b52170b2dc8d65a69f3369d0bd1a3102df295edfccfef1b41e82b6aef796/regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, - {url = "https://files.pythonhosted.org/packages/1a/1a/e7ae9a041d3e103f98c9a79d8abb235cca738b7bd6da3fb5e4066d30e4d7/regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, - {url = "https://files.pythonhosted.org/packages/1d/d9/a70219b39be741af8a831b98dee154091115bc0e3770e28e006d86511619/regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, - {url = "https://files.pythonhosted.org/packages/1f/f3/895ba11bc0243becd38f8b7560d2e329c465ead247cfb815611c347d7fc1/regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, - {url = "https://files.pythonhosted.org/packages/21/1f/f54c156ac95a89d33113d78a18c03db8c00600392d6d6c5a18249c563c58/regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, - {url = "https://files.pythonhosted.org/packages/23/8d/1df5d30ce1e5ae3edfb775b892c93882d13ba93991314871fec569f16829/regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, - {url = "https://files.pythonhosted.org/packages/27/b5/92d404279fd5f4f0a17235211bb0f5ae7a0d9afb7f439086ec247441ed28/regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, - {url = "https://files.pythonhosted.org/packages/28/9c/e392e9aac4d4c10d81e0991e31e50755bd5f15a924284de4fac1d728b145/regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, - {url = "https://files.pythonhosted.org/packages/2d/db/45ca83007d69cc594c32d7feae20b1b6067f829b2b0d27bb769d7188dfa1/regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, - {url = "https://files.pythonhosted.org/packages/2f/38/1947b056840f27eb6f9cbb28ca70135f75fee117fe4fa546528a8962d275/regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, - {url = "https://files.pythonhosted.org/packages/30/eb/a28fad5b882d3e711c75414b3c99fb2954f78fa450deeed9fe9ad3bf2534/regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, - {url = "https://files.pythonhosted.org/packages/3c/4f/33b5cbd85fb0272e5c1dc00e3cfc89874b37705613455d7ab1c1f3ff7906/regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, - {url = "https://files.pythonhosted.org/packages/3c/d1/49b9a2cb289c20888b23bb7f8f29e3ad7982785b10041477fd56ed5783c5/regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, - {url = "https://files.pythonhosted.org/packages/3e/cf/97a89e2b798988118beed6620dbfbc9b4bd72d8177b3b4ed47d80da26df9/regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, - {url = "https://files.pythonhosted.org/packages/40/54/c6f42a3bb78172493eaab818f62ac2062ab310ead0ae7ecd7f0de5ca9084/regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, - {url = "https://files.pythonhosted.org/packages/42/d8/8a7131e7d0bf237f7bcd3191541a4bf21863c253fe6bee0796900a1a9a29/regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, - {url = "https://files.pythonhosted.org/packages/43/5b/6ba9b08ea991993ad61e4098d88069c86f6d6cc0e52a26fa35f6a66d90ee/regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, - {url = "https://files.pythonhosted.org/packages/48/1e/829551abceba73e7e9b1f94a311a53e9c0f60c7deec8821633fc3b343a58/regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, - {url = "https://files.pythonhosted.org/packages/48/4e/4c1e7dfab3255f4476faa11a9fcc867e03d2c4abb2e101505deb7ef790e0/regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, - {url = "https://files.pythonhosted.org/packages/48/ea/a404ca530fd783d0b427e07451fdf847303ff3eccf851bdcb787872ab2d3/regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, - {url = "https://files.pythonhosted.org/packages/4e/fa/efe2c65d2555a01c61a6522b63f98dd7f77dbfeea810e96d8f7e1d9552a3/regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, - {url = "https://files.pythonhosted.org/packages/54/b2/eb79f7674559f2dbb5bbba5ce5ca3e8539200c96e576ca9e0e619c2690d3/regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, - {url = "https://files.pythonhosted.org/packages/55/73/f71734c0357e41673b00bff0a8675ffb67328ba18f24614ec5af2073b56f/regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, - {url = "https://files.pythonhosted.org/packages/55/c6/7235609772ee24e7f74342f7d0f7c40f043098421cc9fe9358fa98a66c79/regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, - {url = "https://files.pythonhosted.org/packages/56/4b/22c965c2f6847b0581a8d4407b265c04f989cb6df09ddfd7205744b14cbc/regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, - {url = "https://files.pythonhosted.org/packages/56/e3/351029c41f42e29d9c6ae3d217ad332761945b41dfbddb64adc31d434c6b/regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, - {url = "https://files.pythonhosted.org/packages/58/4e/0f0a7b674d6164809db80eac36a3a70bbd3bcf6dc8fb6f89f70f0893b85b/regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, - {url = "https://files.pythonhosted.org/packages/59/68/5d77731c6cb3cfcf8aece4c650cc4a601795387292e2bd61826ed75310eb/regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, - {url = "https://files.pythonhosted.org/packages/5f/7e/23ddf7d405aad0d0a8fa478ba60fc1c46f661403fe4a49e04d48ea1095b4/regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, - {url = "https://files.pythonhosted.org/packages/63/89/7035055b960428a3af1fb1bfdf805cada83a81f88459350dad82a260a08d/regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, - {url = "https://files.pythonhosted.org/packages/65/38/a5e1f46f32c453ec162eddac315d5e0d3a0f26ccd638c6f9d078e802d2aa/regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, - {url = "https://files.pythonhosted.org/packages/69/a4/d8cb52db0a918f8a1cad766c4bc5cf968b2a00a06183aa9b5f71ff6094e3/regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, - {url = "https://files.pythonhosted.org/packages/72/cf/da36a722626572ea66ab799e7019eb9a367fa563d43e3b1ec65a934d12d3/regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, - {url = "https://files.pythonhosted.org/packages/78/74/c8659c8e1b6745299df62099d162002deeb32a9a933bc7632836a3c22374/regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, - {url = "https://files.pythonhosted.org/packages/7c/cf/50844f62052bb858987fe3970315134e3be6167fc76e11d328e7fcf876ff/regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, - {url = "https://files.pythonhosted.org/packages/83/ad/defd48762ff8fb2d06667b1e8bef471c2cc71a1b3d6ead26b841bfd9da99/regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, - {url = "https://files.pythonhosted.org/packages/84/93/67595e62890fa944da394795f0425140917340d35d9cfd49672a8dc48c1a/regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, - {url = "https://files.pythonhosted.org/packages/87/50/e237090e90a0b0c8eab40af7d6f2faaf1432c4dca232de9a9c789faf3154/regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, - {url = "https://files.pythonhosted.org/packages/88/e0/d4251593cde041f3a9b249744da5b6e53d1ac4fa2542dfe251fe8070793b/regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, - {url = "https://files.pythonhosted.org/packages/8d/50/7dd264adf08bf3ca588562bac344a825174e8e57c75ad3e5ed169aba5718/regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, - {url = "https://files.pythonhosted.org/packages/91/4e/fb78efdac24862ef6ea8009b0b9cdb5f25968d1b262cc32abd9d483f50b1/regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, - {url = "https://files.pythonhosted.org/packages/92/3c/17432c77b7d3929adb73077584606b236be4ed832243d426f51f5a0f72f9/regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, - {url = "https://files.pythonhosted.org/packages/9c/1a/63bcd0f28f74619190c4f6f3cf90e3fdccb4b1437aac7e19598e18b51901/regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, - {url = "https://files.pythonhosted.org/packages/a3/60/6084d08f56d424f46ecbfedebd11b2c2d7eb2f9bc36ccd8801821024262c/regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, - {url = "https://files.pythonhosted.org/packages/a6/9b/b6819a467182e94e7648120cedcb6019751ceff9f5f3ef9c340e14ea7992/regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, - {url = "https://files.pythonhosted.org/packages/ad/29/4efb589803fa476e649fcc256886837b74931c4ca1878e69cd5018f77e03/regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, - {url = "https://files.pythonhosted.org/packages/ad/56/c6344d2f3e170229fbd9e7928f85969084905e52ea06446f4d1763c712ce/regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, - {url = "https://files.pythonhosted.org/packages/b3/60/38ea6f8808bf58852b3e08faa2d7418b8887144f891284bc2a1afb7b6967/regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, - {url = "https://files.pythonhosted.org/packages/b3/a2/1c165d7759f501184214e788dccfc0bbca068eb70d6bc4fd7999712a2674/regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, - {url = "https://files.pythonhosted.org/packages/b4/04/daeb6806a2b2e10e548c95b136aefb12818ef81a0aa5f865705bf19e7cd7/regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, - {url = "https://files.pythonhosted.org/packages/b5/3d/6ac9300e7b55979ad4040a4317cd14daf7689be0c09f2c49ca3070e2387a/regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, - {url = "https://files.pythonhosted.org/packages/b7/0a/c865345e6ece671f16ac1fe79bf4ba771c528c2e4a56607898cdf065c285/regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, - {url = "https://files.pythonhosted.org/packages/bb/ba/92096d78cbdd34dce674962392a0e57ce748a9e5f737f12b0001723d959a/regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, - {url = "https://files.pythonhosted.org/packages/be/d3/7e334b8bc597dea6200f7bb969fc693d4c71c4a395750e28d09c8e5a8104/regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, - {url = "https://files.pythonhosted.org/packages/c1/65/3ee862c7a78ce1f9bd748d460e379317464c2658e645a1a7c1304d36e819/regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, - {url = "https://files.pythonhosted.org/packages/c1/7e/18651b654689c7e318e3e09c7f5ed56a48d7648c882ebe69ce8954d3941a/regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, - {url = "https://files.pythonhosted.org/packages/c2/52/b71ff1a281f37016cab322e176e3c63fe1b5c27d68cdacdec769708e49b7/regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, - {url = "https://files.pythonhosted.org/packages/c7/6a/386254696e2ab59ccce2eeee1e014f95538004e3c840606ef817192dbf8a/regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, - {url = "https://files.pythonhosted.org/packages/cc/45/1ecb7ee4f479da2bc23e16a0266a90a5ecd918e1410d9188a1ae457f7c3e/regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, - {url = "https://files.pythonhosted.org/packages/cc/c2/6d41a7a9690d4543b1f438f45576af96523c4f1caeb5307fff3350ec7d0b/regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, - {url = "https://files.pythonhosted.org/packages/ce/ac/519de46093b4162e154f055ec020ba2f3641ba2cf6f1ddefd1abea5043b3/regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, - {url = "https://files.pythonhosted.org/packages/d2/a6/2af9cc002057b75868ec7740fe3acb8f89796c9d29caf5775fefd96c3240/regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, - {url = "https://files.pythonhosted.org/packages/d8/5c/40e197174793b44637dd542c1dee45a5517023d1cac5ca5a68fbe60e4105/regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, - {url = "https://files.pythonhosted.org/packages/dd/08/67feb849ab7288465b7b577cf076c0db5244dfd64bec8740cd8f0e074897/regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, - {url = "https://files.pythonhosted.org/packages/dd/82/2fcd88776b621ce6569ca51aa4bd33e55d49d0f594a0252bc1d97899c2d9/regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, - {url = "https://files.pythonhosted.org/packages/de/82/1e868572aaa6b5468f07512fd184650bf9ade15943d4f1ae83d0dc512872/regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, - {url = "https://files.pythonhosted.org/packages/e5/7d/0b0d25b7bb9a38cdccffd3fdcbf4ad7dd124fdf6ca6067cd973edff804bc/regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, - {url = "https://files.pythonhosted.org/packages/e6/4a/48779981af80558ac01f0f2c0d71c1214215bc74c9b824eb6581e94a847c/regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, - {url = "https://files.pythonhosted.org/packages/ec/26/6577862030d42967657f1132956c4600a95bb7e999741bfa32cc0c5441ff/regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, - {url = "https://files.pythonhosted.org/packages/f8/ca/105a8f6d70499f2687a857570dcd411c0621a347b06c27126cffc32e77e0/regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, - {url = "https://files.pythonhosted.org/packages/fa/54/acb97b65bc556520d61262ff22ad7d4baff96e3219fa1dc5425269def873/regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, - {url = "https://files.pythonhosted.org/packages/fc/be/e2ffc7e7454a6db7650050db188af4575a5e4fc0ce6dc73a5d31c6796c34/regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, - {url = "https://files.pythonhosted.org/packages/fd/12/c5d64d860c2d1be211a91b2416097d5e40699b80296cb4e99a064d4b4ff2/regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, - {url = "https://files.pythonhosted.org/packages/fe/f2/20be658beb9ebef677550be562eae86c5433119b4b2fdb67035e9a841b0f/regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, -] -"requests 2.27.1" = [ - {url = "https://files.pythonhosted.org/packages/2d/61/08076519c80041bc0ffa1a8af0cbd3bf3e2b62af10435d269a9d0f40564d/requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {url = "https://files.pythonhosted.org/packages/60/f3/26ff3767f099b73e0efa138a9998da67890793bfa475d8278f84a30fec77/requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, +"pyflakes 3.0.1" = [ + {url = "https://files.pythonhosted.org/packages/af/4c/b1c7008aa7788b3e26c06c60aa18da7d3aa1f00e344aa3f18ac92768854b/pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, + {url = "https://files.pythonhosted.org/packages/f2/51/506ddcfab10d708e8460554cc1cf37c727a6a2cccbad8dfe57766cfce33c/pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, +] +"python-dateutil 2.8.2" = [ + {url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, + {url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, +] +"python-dotenv 1.0.0" = [ + {url = "https://files.pythonhosted.org/packages/31/06/1ef763af20d0572c032fa22882cfbfb005fba6e7300715a37840858c919e/python-dotenv-1.0.0.tar.gz", hash = "sha256:a8df96034aae6d2d50a4ebe8216326c61c3eb64836776504fcca410e5937a3ba"}, + {url = "https://files.pythonhosted.org/packages/44/2f/62ea1c8b593f4e093cc1a7768f0d46112107e790c3e478532329e434f00b/python_dotenv-1.0.0-py3-none-any.whl", hash = "sha256:f5971a9226b701070a4bf2c38c89e5a3f0d64de8debda981d1db98583009122a"}, +] +"python-slugify 8.0.1" = [ + {url = "https://files.pythonhosted.org/packages/b4/85/6aa722a11307ec572682023b76cad4c52cda708dfc25fcb4b4a6051da7ab/python_slugify-8.0.1-py2.py3-none-any.whl", hash = "sha256:70ca6ea68fe63ecc8fa4fcf00ae651fc8a5d02d93dcd12ae6d4fc7ca46c4d395"}, + {url = "https://files.pythonhosted.org/packages/de/63/0f60208d0d3dde1a87d30a82906fa9b00e902b57f1ae9565d780de4b41d1/python-slugify-8.0.1.tar.gz", hash = "sha256:ce0d46ddb668b3be82f4ed5e503dbc33dd815d83e2eb6824211310d3fb172a27"}, +] +"pytz 2023.3" = [ + {url = "https://files.pythonhosted.org/packages/5e/32/12032aa8c673ee16707a9b6cdda2b09c0089131f35af55d443b6a9c69c1d/pytz-2023.3.tar.gz", hash = "sha256:1d8ce29db189191fb55338ee6d0387d82ab59f3d00eac103412d64e0ebd0c588"}, + {url = "https://files.pythonhosted.org/packages/7f/99/ad6bd37e748257dd70d6f85d916cafe79c0b0f5e2e95b11f7fbc82bf3110/pytz-2023.3-py2.py3-none-any.whl", hash = "sha256:a151b3abb88eda1d4e34a9814df37de2a80e301e68ba0fd856fb9b46bfbbbffb"}, +] +"pyyaml 6.0" = [ + {url = "https://files.pythonhosted.org/packages/02/25/6ba9f6bb50a3d4fbe22c1a02554dc670682a07c8701d1716d19ddea2c940/PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, + {url = "https://files.pythonhosted.org/packages/08/f4/ffa743f860f34a5e8c60abaaa686f82c9ac7a2b50e5a1c3b1eb564d59159/PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, + {url = "https://files.pythonhosted.org/packages/0f/93/5f81d1925ce3b531f5ff215376445ec220887cd1c9a8bde23759554dbdfd/PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, + {url = "https://files.pythonhosted.org/packages/12/fc/a4d5a7554e0067677823f7265cb3ae22aed8a238560b5133b58cda252dad/PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, + {url = "https://files.pythonhosted.org/packages/21/67/b42191239c5650c9e419c4a08a7a022bbf1abf55b0391c380a72c3af5462/PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, + {url = "https://files.pythonhosted.org/packages/2e/b3/13dfd4eeb5e4b2d686b6d1822b40702e991bf3a4194ca5cbcce8d43749db/PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, + {url = "https://files.pythonhosted.org/packages/36/2b/61d51a2c4f25ef062ae3f74576b01638bebad5e045f747ff12643df63844/PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, + {url = "https://files.pythonhosted.org/packages/44/e5/4fea13230bcebf24b28c0efd774a2dd65a0937a2d39e94a4503438b078ed/PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, + {url = "https://files.pythonhosted.org/packages/4d/7d/c2ab8da648cd2b937de11fb35649b127adab4851cbeaf5fd9b60a2dab0f7/PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, + {url = "https://files.pythonhosted.org/packages/55/e3/507a92589994a5b3c3d7f2a7a066339d6ff61c5c839bae56f7eff03d9c7b/PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, + {url = "https://files.pythonhosted.org/packages/56/8f/e8b49ad21d26111493dc2d5cae4d7efbd0e2e065440665f5023515f87f64/PyYAML-6.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782"}, + {url = "https://files.pythonhosted.org/packages/59/00/30e33fcd2a4562cd40c49c7740881009240c5cbbc0e41ca79ca4bba7c24b/PyYAML-6.0-cp311-cp311-win_amd64.whl", hash = "sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf"}, + {url = "https://files.pythonhosted.org/packages/5e/f4/7b4bb01873be78fc9fde307f38f62e380b7111862c165372cf094ca2b093/PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, + {url = "https://files.pythonhosted.org/packages/63/6b/f5dc7942bac17192f4ef00b2d0cdd1ae45eea453d05c1944c0573debe945/PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, + {url = "https://files.pythonhosted.org/packages/67/d4/b95266228a25ef5bd70984c08b4efce2c035a4baa5ccafa827b266e3dc36/PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, + {url = "https://files.pythonhosted.org/packages/68/3f/c027422e49433239267c62323fbc6320d6ac8d7d50cf0cb2a376260dad5f/PyYAML-6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f"}, + {url = "https://files.pythonhosted.org/packages/6c/3d/524c642f3db37e7e7ab8d13a3f8b0c72d04a619abc19100097d987378fc6/PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, + {url = "https://files.pythonhosted.org/packages/74/68/3c13deaa496c14a030c431b7b828d6b343f79eb241b4848c7918091a64a2/PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, + {url = "https://files.pythonhosted.org/packages/77/da/e845437ffe0dffae4e7562faf23a4f264d886431c5d2a2816c853288dc8e/PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, + {url = "https://files.pythonhosted.org/packages/7f/d9/6a0d14ac8d3b5605dc925d177c1d21ee9f0b7b39287799db1e50d197b2f4/PyYAML-6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d"}, + {url = "https://files.pythonhosted.org/packages/81/59/561f7e46916b78f3c4cab8d0c307c81656f11e32c846c0c97fda0019ed76/PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, + {url = "https://files.pythonhosted.org/packages/89/26/0bfd7b756b34c68f8fd158b7bc762b6b1705fc1b3cebf4cdbb53fd9ea75b/PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, + {url = "https://files.pythonhosted.org/packages/91/49/d46d7b15cddfa98533e89f3832f391aedf7e31f37b4d4df3a7a7855a7073/PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, + {url = "https://files.pythonhosted.org/packages/9d/f6/7e91fbb58c9ee528759aea5892e062cccb426720c5830ddcce92eba00ff1/PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, + {url = "https://files.pythonhosted.org/packages/a4/ba/e508fc780e3c94c12753a54fe8f74de535741a10d33b29a576a9bec03500/PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, + {url = "https://files.pythonhosted.org/packages/a4/e6/4d7a01bc0730c8f958a62d6a4c4f3df23b6139ad68c132b168970d84f192/PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, + {url = "https://files.pythonhosted.org/packages/a8/32/1bbe38477fb23f1d83041fefeabf93ef1cd6f0efcf44c221519507315d92/PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, + {url = "https://files.pythonhosted.org/packages/a8/5b/c4d674846ea4b07ee239fbf6010bcc427c4e4552ba5655b446e36b9a40a7/PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, + {url = "https://files.pythonhosted.org/packages/b3/85/79b9e5b4e8d3c0ac657f4e8617713cca8408f6cdc65d2ee6554217cedff1/PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, + {url = "https://files.pythonhosted.org/packages/b7/09/2f6f4851bbca08642fef087bade095edc3c47f28d1e7bff6b20de5262a77/PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, + {url = "https://files.pythonhosted.org/packages/cb/5f/05dd91f5046e2256e35d885f3b8f0f280148568f08e1bf20421887523e9a/PyYAML-6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1"}, + {url = "https://files.pythonhosted.org/packages/d1/c0/4fe04181b0210ee2647cfbb89ecd10a36eef89f10d8aca6a192c201bbe58/PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, + {url = "https://files.pythonhosted.org/packages/d7/42/7ad4b6d67a16229496d4f6e74201bdbebcf4bc1e87d5a70c9297d4961bd2/PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, + {url = "https://files.pythonhosted.org/packages/db/4e/74bc723f2d22677387ab90cd9139e62874d14211be7172ed8c9f9a7c81a9/PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, + {url = "https://files.pythonhosted.org/packages/df/75/ee0565bbf65133e5b6ffa154db43544af96ea4c42439e6b58c1e0eb44b4e/PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, + {url = "https://files.pythonhosted.org/packages/eb/5f/6e6fe6904e1a9c67bc2ca5629a69e7a5a0b17f079da838bab98a1e548b25/PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, + {url = "https://files.pythonhosted.org/packages/ef/ad/b443cce94539e57e1a745a845f95c100ad7b97593d7e104051e43f730ecd/PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, + {url = "https://files.pythonhosted.org/packages/f5/6f/b8b4515346af7c33d3b07cd8ca8ea0700ca72e8d7a750b2b87ac0268ca4e/PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, + {url = "https://files.pythonhosted.org/packages/f8/54/799b059314b13e1063473f76e908f44106014d18f54b16c83a16edccd5ec/PyYAML-6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358"}, + {url = "https://files.pythonhosted.org/packages/fc/48/531ecd926fe0a374346dd811bf1eda59a95583595bb80eadad511f3269b8/PyYAML-6.0-cp311-cp311-win32.whl", hash = "sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7"}, +] +"requests 2.30.0" = [ + {url = "https://files.pythonhosted.org/packages/96/80/034ffeca15c0f4e01b7b9c6ad0fb704b44e190cde4e757edbd60be404c41/requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, + {url = "https://files.pythonhosted.org/packages/e0/69/122171604bcef06825fa1c05bd9e9b1d43bc9feb8c6c0717c42c92cc6f3c/requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, ] "requests-oauthlib 1.3.1" = [ {url = "https://files.pythonhosted.org/packages/6f/bb/5deac77a9af870143c684ab46a7934038a53eb4aa975bc0687ed6ca2c610/requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"}, @@ -1288,144 +1230,132 @@ content_hash = "sha256:90a79ea8e222fe4de9b643cc7490b2d199a9603039066d01da7b32d0f {url = "https://files.pythonhosted.org/packages/a5/e1/c9dca73caf001f82e8479e382a66820cbd29f461f465a12d4b3d7e0b929a/schematics-2.1.1-py2.py3-none-any.whl", hash = "sha256:be2d451bfb86789975e5ec0864aec569b63cea9010f0d24cbbd992a4e564c647"}, {url = "https://files.pythonhosted.org/packages/d8/28/2c25f4c95bce21e37bc6dbe696dceeaa71c7c92665a12134b6c312390736/schematics-2.1.1.tar.gz", hash = "sha256:34c87f51a25063bb498ae1cc201891b134cfcb329baf9e9f4f3ae869b767560f"}, ] -"sentry-sdk 1.5.8" = [ - {url = "https://files.pythonhosted.org/packages/74/74/82f06055ccbcb05ba84b942346acf39f342fdf3937f2638cb780dac3f125/sentry-sdk-1.5.8.tar.gz", hash = "sha256:38fd16a92b5ef94203db3ece10e03bdaa291481dd7e00e77a148aa0302267d47"}, - {url = "https://files.pythonhosted.org/packages/87/54/0a04c906c97073119e4030c9f4d86e8fe70c93aee1b3bc5670257b76eab0/sentry_sdk-1.5.8-py2.py3-none-any.whl", hash = "sha256:32af1a57954576709242beb8c373b3dbde346ac6bd616921def29d68846fb8c3"}, +"sentry-sdk 1.23.1" = [ + {url = "https://files.pythonhosted.org/packages/19/3e/23af11049f2ff6242afbd428c4cf92e2996e151f4f5d46c2210e8204900e/sentry_sdk-1.23.1-py2.py3-none-any.whl", hash = "sha256:a884e2478e0b055776ea2b9234d5de9339b4bae0b3a5e74ae43d131db8ded27e"}, + {url = "https://files.pythonhosted.org/packages/d8/e2/4ae46cb5098d93e258127c191f5e1f97f0e9f17f6871cfef864b92e5663f/sentry-sdk-1.23.1.tar.gz", hash = "sha256:0300fbe7a07b3865b3885929fb863a68ff01f59e3bcfb4e7953d0bf7fd19c67f"}, ] "setuptools 67.7.2" = [ {url = "https://files.pythonhosted.org/packages/2f/8c/f336a966d4097c7cef6fc699b2ecb83b5fb63fd698198c1b5c7905a74f0f/setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, {url = "https://files.pythonhosted.org/packages/fd/53/e5d7ae40d03e4ed20b7cba317cf9c0c97097c8debb39f9d72d182a6578a2/setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, ] -"shapely 1.7.1" = [ - {url = "https://files.pythonhosted.org/packages/00/b6/71bd30edeab05060e8fbfb16bf2a074364b037615cd823945e0052d26484/Shapely-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:35be1c5d869966569d3dfd4ec31832d7c780e9df760e1fe52131105685941891"}, - {url = "https://files.pythonhosted.org/packages/03/7a/3b196a683a641cfa4fe741ad57b60a98c382ad3c72815947448ae00fe32d/Shapely-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:6593026cd3f5daaea12bcc51ae5c979318070fefee210e7990cb8ac2364e79a1"}, - {url = "https://files.pythonhosted.org/packages/0a/e2/1b7aba5ce9804998581efeab455d8a1a902f992f20d2e15dd4ab0a7db4db/Shapely-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:de618e67b64a51a0768d26a9963ecd7d338a2cf6e9e7582d2385f88ad005b3d1"}, - {url = "https://files.pythonhosted.org/packages/21/23/c7e6882fbb9239d54b6794a7f1a78125a53f172751bdbdaf17463101f464/Shapely-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:182716ffb500d114b5d1b75d7fd9d14b7d3414cef3c38c0490534cc9ce20981a"}, - {url = "https://files.pythonhosted.org/packages/24/ac/b0fefd3584551ebc2cb337ce14e781ff80583d17abbccf7595b6c9281eeb/Shapely-1.7.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4c10f317e379cc404f8fc510cd9982d5d3e7ba13a9cfd39aa251d894c6366798"}, - {url = "https://files.pythonhosted.org/packages/27/4a/9b8c5a0bc6da4f1b8573a82640ea045a90774d089a7f4d666649d56450e2/Shapely-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2df5260d0f2983309776cb41bfa85c464ec07018d88c0ecfca23d40bfadae2f1"}, - {url = "https://files.pythonhosted.org/packages/36/a0/7c1d7398f8c176b8d50b70de2608b7128611c1dc15ae5c627a0fda225eb0/Shapely-1.7.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:90a3e2ae0d6d7d50ff2370ba168fbd416a53e7d8448410758c5d6a5920646c1d"}, - {url = "https://files.pythonhosted.org/packages/42/f3/0e1bc2c4f15e05e30c6b99322b9ddaa2babb3f43bc7df2698efdc1553439/Shapely-1.7.1.tar.gz", hash = "sha256:1641724c1055459a7e2b8bbe47ba25bdc89554582e62aec23cb3f3ca25f9b129"}, - {url = "https://files.pythonhosted.org/packages/76/79/a7bffb8eadfdfc98a7d87746e0e4e1043f3c43207e11888154236f8f76ca/Shapely-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:052eb5b9ba756808a7825e8a8020fb146ec489dd5c919e7d139014775411e688"}, - {url = "https://files.pythonhosted.org/packages/7e/e9/eb2a2e07e2ee9a434c0dde5bb6c5ae78eef82f4aebdc45e2525de96dd775/Shapely-1.7.1-1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:46da0ea527da9cf9503e66c18bab6981c5556859e518fe71578b47126e54ca93"}, - {url = "https://files.pythonhosted.org/packages/8c/0f/697f75dcf382293d5cfcbbe15c28d81085446d3c20c0a707d0f42bc5ed04/Shapely-1.7.1-cp35-cp35m-win_amd64.whl", hash = "sha256:791477edb422692e7dc351c5ed6530eb0e949a31b45569946619a0d9cd5f53cb"}, - {url = "https://files.pythonhosted.org/packages/98/f8/db4d3426a1aba9d5dfcc83ed5a3e2935d2b1deb73d350642931791a61c37/Shapely-1.7.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:4f3c59f6dbf86a9fc293546de492f5e07344e045f9333f3a753f2dda903c45d1"}, - {url = "https://files.pythonhosted.org/packages/9d/18/557d4f55453fe00f59807b111cc7b39ce53594e13ada88e16738fb4ff7fb/Shapely-1.7.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8f15b6ce67dcc05b61f19c689b60f3fe58550ba994290ff8332f711f5aaa9840"}, - {url = "https://files.pythonhosted.org/packages/a2/ac/3f05fb517e1b6a5f0770d71572c09f748bbe4b39bebcb09d91c5141ba02c/Shapely-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:6871acba8fbe744efa4f9f34e726d070bfbf9bffb356a8f6d64557846324232b"}, - {url = "https://files.pythonhosted.org/packages/ab/f4/9938e6d19fdb8ece7be7f6b155e4e46dd24a2e2c43bf34d67bebeb919b2f/Shapely-1.7.1-cp38-cp38-win32.whl", hash = "sha256:a3774516c8a83abfd1ddffb8b6ec1b0935d7fe6ea0ff5c31a18bfdae567b4eba"}, - {url = "https://files.pythonhosted.org/packages/bf/3b/2bfa648c733fc233aed12893b20eee2e81c3b8361c34637855667afe5c4a/Shapely-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:60e5b2282619249dbe8dc5266d781cc7d7fb1b27fa49f8241f2167672ad26719"}, - {url = "https://files.pythonhosted.org/packages/c1/98/c6b8846b9e452d355f2bfe342b140c2d374adef912b21f37e7504bbae324/Shapely-1.7.1-cp35-cp35m-win32.whl", hash = "sha256:8e7659dd994792a0aad8fb80439f59055a21163e236faf2f9823beb63a380e19"}, - {url = "https://files.pythonhosted.org/packages/cf/00/4ccaedf7c2805c93aef21116477283b3beb9b6c5a761b08447d51c9f3e0f/Shapely-1.7.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:da38ed3d65b8091447dc3717e5218cc336d20303b77b0634b261bc5c1aa2bae8"}, - {url = "https://files.pythonhosted.org/packages/e5/52/3e2e11453b6b98cb78883aac249bf497a20d9e0c1c71ecf2f98165def72d/Shapely-1.7.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b40cc7bb089ae4aa9ddba1db900b4cd1bce3925d2a4b5837b639e49de054784f"}, - {url = "https://files.pythonhosted.org/packages/e9/1d/4e487dd6c37efb01d107e0bbc48deed299348cf3b1a98ff110c2af923b3c/Shapely-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e3afccf0437edc108eef1e2bb9cc4c7073e7705924eb4cd0bf7715cd1ef0ce1b"}, - {url = "https://files.pythonhosted.org/packages/f7/4c/bcbbe5d6fe5b7b12669b0c6e74479939f793531a08fe20e8eeddd5544986/Shapely-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:a5c3a50d823c192f32615a2a6920e8c046b09e07a58eba220407335a9cd2e8ea"}, - {url = "https://files.pythonhosted.org/packages/f9/5a/d0d3548f1cb698325c44ea8da7fca14c3aea943b5c6199aaaf6f58818a8f/Shapely-1.7.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:17df66e87d0fe0193910aeaa938c99f0b04f67b430edb8adae01e7be557b141b"}, - {url = "https://files.pythonhosted.org/packages/ff/62/69cca822e9ecf3f5eebae2105bccc04ed1818508df4f2b93f8464492f155/Shapely-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:617bf046a6861d7c6b44d2d9cb9e2311548638e684c2cd071d8945f24a926263"}, -] -"six 1.15.0" = [ - {url = "https://files.pythonhosted.org/packages/6b/34/415834bfdafca3c5f451532e8a8d9ba89a21c9743a0c59fbd0205c7f9426/six-1.15.0.tar.gz", hash = "sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259"}, - {url = "https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl", hash = "sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"}, -] -"sqlalchemy 1.3.20" = [ - {url = "https://files.pythonhosted.org/packages/02/6b/f961bcada71f4ebade545af704fbc1751ba9939ab429a9bdd42281f4453d/SQLAlchemy-1.3.20-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:2909dffe5c9a615b7e6c92d1ac2d31e3026dc436440a4f750f4749d114d88ceb"}, - {url = "https://files.pythonhosted.org/packages/05/e0/1e664748662da4abf1cb72838e430074c4fe8099add98491995a7183b5b2/SQLAlchemy-1.3.20-cp38-cp38-win_amd64.whl", hash = "sha256:7c735c7a6db8ee9554a3935e741cf288f7dcbe8706320251eb38c412e6a4281d"}, - {url = "https://files.pythonhosted.org/packages/08/4c/d81902b47d65c36d117c0ac8c4ce4f399e31ebacb9ed4c9e978fc017c0c9/SQLAlchemy-1.3.20-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:7cd40cb4bc50d9e87b3540b23df6e6b24821ba7e1f305c1492b0806c33dbdbec"}, - {url = "https://files.pythonhosted.org/packages/09/0d/97b2ef803cbbf84d873b3bca0c05c48f92213dd744df731d6c3ed0730e4c/SQLAlchemy-1.3.20-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:53fd857c6c8ffc0aa6a5a3a2619f6a74247e42ec9e46b836a8ffa4abe7aab327"}, - {url = "https://files.pythonhosted.org/packages/18/13/9820a971e916dbc6513af7ec021ad5bec241b6bb526b1b766d1bce8ea6d2/SQLAlchemy-1.3.20-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:3aa6d45e149a16aa1f0c46816397e12313d5e37f22205c26e06975e150ffcf2a"}, - {url = "https://files.pythonhosted.org/packages/24/66/962298533cb599e7c4c27791189b750b0ac12140043e48848811fbd82b8d/SQLAlchemy-1.3.20-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:9e379674728f43a0cd95c423ac0e95262500f9bfd81d33b999daa8ea1756d162"}, - {url = "https://files.pythonhosted.org/packages/27/4f/05e30291ec3e1668f0b7f7d611d097b402f5d1328dd34901eff6eda01572/SQLAlchemy-1.3.20-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:bad73f9888d30f9e1d57ac8829f8a12091bdee4949b91db279569774a866a18e"}, - {url = "https://files.pythonhosted.org/packages/2a/c9/3672b3029f0edb9d732054ed533cb88839c88ce13ae01e03ba60c2e48987/SQLAlchemy-1.3.20-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:d3b709d64b5cf064972b3763b47139e4a0dc4ae28a36437757f7663f67b99710"}, - {url = "https://files.pythonhosted.org/packages/2c/e4/d2fda4daf41fbbe3e32c2c1bf425415af5debfbaea48ae35326d8a88cd01/SQLAlchemy-1.3.20-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:0157c269701d88f5faf1fa0e4560e4d814f210c01a5b55df3cab95e9346a8bcc"}, - {url = "https://files.pythonhosted.org/packages/2f/4f/d5562a1be28614225d2c7ba2d65afca1ced0c842b266a6c886c5baeb99ce/SQLAlchemy-1.3.20-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:1f5f369202912be72fdf9a8f25067a5ece31a2b38507bb869306f173336348da"}, - {url = "https://files.pythonhosted.org/packages/32/6e/afb18531c066924cf411dff017fb99928adf4d1cc2a9244ace0b3d25f004/SQLAlchemy-1.3.20-cp38-cp38-win32.whl", hash = "sha256:bf53d8dddfc3e53a5bda65f7f4aa40fae306843641e3e8e701c18a5609471edf"}, - {url = "https://files.pythonhosted.org/packages/35/6f/0a48334d857c0ac25c49585b533d0f6845ad1853dabb4625239b695f68d3/SQLAlchemy-1.3.20-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:c3ab23ee9674336654bf9cac30eb75ac6acb9150dc4b1391bec533a7a4126471"}, - {url = "https://files.pythonhosted.org/packages/3d/4c/5b3a401805678869cdc1f146028e8dcb1620203452b3037033cad4090697/SQLAlchemy-1.3.20-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:84f0ac4a09971536b38cc5d515d6add7926a7e13baa25135a1dbb6afa351a376"}, - {url = "https://files.pythonhosted.org/packages/46/ff/d512dac9b1ef83cfc99cf5befc967b26246e2683f04d5a176d06029375c6/SQLAlchemy-1.3.20-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:b15002b9788ffe84e42baffc334739d3b68008a973d65fad0a410ca5d0531980"}, - {url = "https://files.pythonhosted.org/packages/47/17/f701475fae316c84dbce7ce3f8cd79231cfb1039d065a95d370f491ef312/SQLAlchemy-1.3.20-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:009e8388d4d551a2107632921320886650b46332f61dc935e70c8bcf37d8e0d6"}, - {url = "https://files.pythonhosted.org/packages/49/91/d1c2c2447d085b0dcec00a6eac2e5ebc00a3b4efdfe3f637401d2db92397/SQLAlchemy-1.3.20-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:0a92745bb1ebbcb3985ed7bda379b94627f0edbc6c82e9e4bac4fb5647ae609a"}, - {url = "https://files.pythonhosted.org/packages/53/4a/973d3f74360b728438bad9e9837db95f6d840b23effa08862c324ab95c1a/SQLAlchemy-1.3.20-cp37-cp37m-win32.whl", hash = "sha256:bca4d367a725694dae3dfdc86cf1d1622b9f414e70bd19651f5ac4fb3aa96d61"}, - {url = "https://files.pythonhosted.org/packages/5e/42/085ecdca6e9fcc6b2c8b81b385d03d3a875361fb615c01d6ab033a6e5bd7/SQLAlchemy-1.3.20-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:be41d5de7a8e241864189b7530ca4aaf56a5204332caa70555c2d96379e18079"}, - {url = "https://files.pythonhosted.org/packages/69/ef/6d18860e18db68b8f25e0d268635f2f8cefa7a1cbf6d9d9f90214555a364/SQLAlchemy-1.3.20.tar.gz", hash = "sha256:d2f25c7f410338d31666d7ddedfa67570900e248b940d186b48461bd4e5569a1"}, - {url = "https://files.pythonhosted.org/packages/6a/aa/d27f922dd0d4c983d91cd9f72f404dc788ae7b10be725a933a442125099f/SQLAlchemy-1.3.20-cp39-cp39-win32.whl", hash = "sha256:0cca1844ba870e81c03633a99aa3dc62256fb96323431a5dec7d4e503c26372d"}, - {url = "https://files.pythonhosted.org/packages/6f/9f/deb8d85217a37b79cac24fbec2cf5c872398c548d8e0d197b2333f306125/SQLAlchemy-1.3.20-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:ed53209b5f0f383acb49a927179fa51a6e2259878e164273ebc6815f3a752465"}, - {url = "https://files.pythonhosted.org/packages/70/75/a9eafb9766c1b572a195fce95fc8940b9abcb0f259b321981d9caf0f22c4/SQLAlchemy-1.3.20-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:5cdfe54c1e37279dc70d92815464b77cd8ee30725adc9350f06074f91dbfeed2"}, - {url = "https://files.pythonhosted.org/packages/73/2b/64a45bbfee90b14d7f1ae6ae98c8e358d3222577498270a645a56b90050e/SQLAlchemy-1.3.20-cp27-cp27m-win_amd64.whl", hash = "sha256:5d92c18458a4aa27497a986038d5d797b5279268a2de303cd00910658e8d149c"}, - {url = "https://files.pythonhosted.org/packages/76/57/2cc0d0f78139c33218a111ad0644652cec10d669036cf7854a934a2a3289/SQLAlchemy-1.3.20-cp35-cp35m-win_amd64.whl", hash = "sha256:8dcbf377529a9af167cbfc5b8acec0fadd7c2357fc282a1494c222d3abfc9629"}, - {url = "https://files.pythonhosted.org/packages/77/f1/cc40386f6900a06daa6c50998cf4dfe9167e76808808c4a8d6e04fefdf6d/SQLAlchemy-1.3.20-cp39-cp39-win_amd64.whl", hash = "sha256:d05cef4a164b44ffda58200efcb22355350979e000828479971ebca49b82ddb1"}, - {url = "https://files.pythonhosted.org/packages/7d/a5/c1410d9b425b459426a1d5b3a5f4c1956cf897dae3e7c27d1ac36ee70cb8/SQLAlchemy-1.3.20-cp36-cp36m-win32.whl", hash = "sha256:632b32183c0cb0053194a4085c304bc2320e5299f77e3024556fa2aa395c2a8b"}, - {url = "https://files.pythonhosted.org/packages/8f/9a/116703bae136b611b029ea83598c1dffd96204ac4db66d42dd30973b835b/SQLAlchemy-1.3.20-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:e32e3455db14602b6117f0f422f46bc297a3853ae2c322ecd1e2c4c04daf6ed5"}, - {url = "https://files.pythonhosted.org/packages/8f/9b/d4a71a14bec41610a00bee1d05c415f2a2c1e55992304c2b8792b65f31bf/SQLAlchemy-1.3.20-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:4bdbdb8ca577c6c366d15791747c1de6ab14529115a2eb52774240c412a7b403"}, - {url = "https://files.pythonhosted.org/packages/92/78/c9afa95fa1f693fa66684fd2ded52585e4d03b0d47f163991d8cf0e6cee3/SQLAlchemy-1.3.20-cp35-cp35m-macosx_10_14_x86_64.whl", hash = "sha256:b6f036ecc017ec2e2cc2a40615b41850dc7aaaea6a932628c0afc73ab98ba3fb"}, - {url = "https://files.pythonhosted.org/packages/94/f1/c6d581670743bc73ec5a690add53d260398f6292f6020808f886b1c200c5/SQLAlchemy-1.3.20-cp37-cp37m-win_amd64.whl", hash = "sha256:f605f348f4e6a2ba00acb3399c71d213b92f27f2383fc4abebf7a37368c12142"}, - {url = "https://files.pythonhosted.org/packages/a7/91/f4f202d214849d071d4d4481176b09a3ffb9299ca33a8775629cce47daec/SQLAlchemy-1.3.20-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:2b5dafed97f778e9901b79cc01b88d39c605e0545b4541f2551a2fd785adc15b"}, - {url = "https://files.pythonhosted.org/packages/a9/a7/32989be8294b6a05031c2cb5e7e829c846555a4634255aaaef4c2ff678bd/SQLAlchemy-1.3.20-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:166917a729b9226decff29416f212c516227c2eb8a9c9f920d69ced24e30109f"}, - {url = "https://files.pythonhosted.org/packages/b1/91/7d3f145fe37867a7e74dea7b526b14d8eb0d086e539bfdfd172c91ef38a0/SQLAlchemy-1.3.20-cp27-cp27m-win32.whl", hash = "sha256:2e9bd5b23bba8ae8ce4219c9333974ff5e103c857d9ff0e4b73dc4cb244c7d86"}, - {url = "https://files.pythonhosted.org/packages/c1/ee/128c8af956925c7181d20105b98c8775d4ce004a6451727527933def63b2/SQLAlchemy-1.3.20-cp35-cp35m-win32.whl", hash = "sha256:950f0e17ffba7a7ceb0dd056567bc5ade22a11a75920b0e8298865dc28c0eff6"}, - {url = "https://files.pythonhosted.org/packages/d2/6d/14fe46769bce5029ffd44943a5ab344c6637fbfc390f7263cb2f11d85b55/SQLAlchemy-1.3.20-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:ce64a44c867d128ab8e675f587aae7f61bd2db836a3c4ba522d884cd7c298a77"}, - {url = "https://files.pythonhosted.org/packages/df/83/ede09893440f3a19406282e40134d479d9859f67506c31c2cfd79bebab36/SQLAlchemy-1.3.20-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:fcdb3755a7c355bc29df1b5e6fb8226d5c8b90551d202d69d0076a8a5649d68b"}, - {url = "https://files.pythonhosted.org/packages/ee/d2/ed999d237e60212f9ab8d1f109d7b8dc5527080f51ce7c8d83aea8f18054/SQLAlchemy-1.3.20-cp36-cp36m-win_amd64.whl", hash = "sha256:bbc58fca72ce45a64bb02b87f73df58e29848b693869e58bd890b2ddbb42d83b"}, - {url = "https://files.pythonhosted.org/packages/ef/de/b3d01c027fec10f19a7f4d3476f68aa750911c701cac505206f1670178a8/SQLAlchemy-1.3.20-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:c092fe282de83d48e64d306b4bce03114859cdbfe19bf8a978a78a0d44ddadb1"}, +"shapely 2.0.1" = [ + {url = "https://files.pythonhosted.org/packages/04/67/05e96af1c4ee130e12ac228da1ab86f7581809d8f008aa3a9ec19ea22eb2/shapely-2.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70a18fc7d6418e5aea76ac55dce33f98e75bd413c6eb39cfed6a1ba36469d7d4"}, + {url = "https://files.pythonhosted.org/packages/0e/da/055d5b854a9a702fed0965d37754b79967ecfd67fe8377264e6a00b521ea/shapely-2.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c43755d2c46b75a7b74ac6226d2cc9fa2a76c3263c5ae70c195c6fb4e7b08e79"}, + {url = "https://files.pythonhosted.org/packages/10/a7/de139da3ce303101c357a9ba801328cba85cf6ace157da31a4007bca85e4/shapely-2.0.1.tar.gz", hash = "sha256:66a6b1a3e72ece97fc85536a281476f9b7794de2e646ca8a4517e2e3c1446893"}, + {url = "https://files.pythonhosted.org/packages/18/a6/2e1761f21605e3562b223be7ad82f2edb5c9babdaa8b2d90979112be70f3/shapely-2.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f470a130d6ddb05b810fc1776d918659407f8d025b7f56d2742a596b6dffa6c7"}, + {url = "https://files.pythonhosted.org/packages/1d/a4/931d0780f31f3ea8c4f9ef6464a2825137c5241e6707a5fb03bef760a7eb/shapely-2.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8b0d834b11be97d5ab2b4dceada20ae8e07bcccbc0f55d71df6729965f406ad"}, + {url = "https://files.pythonhosted.org/packages/1f/2a/dc3353c2431cf53e8d04bb8fba27e584410ca3435c9c85f76d71bf0c0e80/shapely-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9a6ac34c16f4d5d3c174c76c9d7614ec8fe735f8f82b6cc97a46b54f386a86bf"}, + {url = "https://files.pythonhosted.org/packages/28/81/0239107ccd32eb30085c99fbf22da686aa72278afcc2c8fdf06fa0fa6320/shapely-2.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:d8f55f355be7821dade839df785a49dc9f16d1af363134d07eb11e9207e0b189"}, + {url = "https://files.pythonhosted.org/packages/2b/cf/c0315a82849de40897ebb09ef441fea4b995570443e4b596b9bc7c8a7fa4/shapely-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:c7eed1fb3008a8a4a56425334b7eb82651a51f9e9a9c2f72844a2fb394f38a6c"}, + {url = "https://files.pythonhosted.org/packages/2d/f2/8ec281d357e8bb7d08dc8d727f0e4c8ef3dae7d3fa75c69c8e452bb82d50/shapely-2.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad81f292fffbd568ae71828e6c387da7eb5384a79db9b4fde14dd9fdeffca9a"}, + {url = "https://files.pythonhosted.org/packages/31/05/cbdfaf562ce7a0e0e89b47b3000d3445967c9fca6f906f833faba371053c/shapely-2.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e55698e0ed95a70fe9ff9a23c763acfe0bf335b02df12142f74e4543095e9a9b"}, + {url = "https://files.pythonhosted.org/packages/35/da/00737e3cd038d489c257a00829c27b3ff2d3ec264c78540a5d168a06922f/shapely-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:b06d031bc64149e340448fea25eee01360a58936c89985cf584134171e05863f"}, + {url = "https://files.pythonhosted.org/packages/36/a4/7e542a209f862f967d7cb8e939eff155f4294a27d17e16441fb8bdd51a2c/shapely-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33403b8896e1d98aaa3a52110d828b18985d740cc9f34f198922018b1e0f8afe"}, + {url = "https://files.pythonhosted.org/packages/41/63/088ea482b1f2a046ec0576b173125a6485d0cc7e3868d50e74f4a89039f5/shapely-2.0.1-cp39-cp39-win32.whl", hash = "sha256:b50c401b64883e61556a90b89948297f1714dbac29243d17ed9284a47e6dd731"}, + {url = "https://files.pythonhosted.org/packages/49/85/ee3d63f3a4affd146ddb01094c69ae74719c4462285e8aad4d3c6ec70a7b/shapely-2.0.1-cp38-cp38-win32.whl", hash = "sha256:3cb256ae0c01b17f7bc68ee2ffdd45aebf42af8992484ea55c29a6151abe4386"}, + {url = "https://files.pythonhosted.org/packages/69/2e/29633eca429c9e7eca1264df1764a7f179ec9ec186ba25d874342dcb1a47/shapely-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45b4833235b90bc87ee26c6537438fa77559d994d2d3be5190dd2e54d31b2820"}, + {url = "https://files.pythonhosted.org/packages/70/21/39c2afae46154f824564d6b5b7213a84d083e243b42b5a1e76de481f91bb/shapely-2.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4641325e065fd3e07d55677849c9ddfd0cf3ee98f96475126942e746d55b17c8"}, + {url = "https://files.pythonhosted.org/packages/74/c6/2099380d719a7e38cf0643df562b50d458f4960c2c7bb493e2fbe850753a/shapely-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f32a748703e7bf6e92dfa3d2936b2fbfe76f8ce5f756e24f49ef72d17d26ad02"}, + {url = "https://files.pythonhosted.org/packages/7b/e3/92ec80d72de8b881c52e47db1fd2f0519d49b6ad65c4c2a3fcbb9f88a91f/shapely-2.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7d3bbeefd8a6a1a1017265d2d36f8ff2d79d0162d8c141aa0d37a87063525656"}, + {url = "https://files.pythonhosted.org/packages/81/8a/7ac076a86b2632f1872284c5e60ed5f2fc26094875a85b35d9fa17b52504/shapely-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:da71de5bf552d83dcc21b78cc0020e86f8d0feea43e202110973987ffa781c21"}, + {url = "https://files.pythonhosted.org/packages/82/12/ed1087cd4b9a6bc6f1f77b35078a49991672fbfa7302ea480322615cd909/shapely-2.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a34a23d6266ca162499e4a22b79159dc0052f4973d16f16f990baa4d29e58b6"}, + {url = "https://files.pythonhosted.org/packages/8a/31/ad4881727b700a9320a4139ac3483972901a9fdd17bb6a599aca810dbd85/shapely-2.0.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:502e0a607f1dcc6dee0125aeee886379be5242c854500ea5fd2e7ac076b9ce6d"}, + {url = "https://files.pythonhosted.org/packages/91/d3/1f7c41508d42b81b4f454ad20a7f17a73225949805ea638125ac09188d33/shapely-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:b4f0711cc83734c6fad94fc8d4ec30f3d52c1787b17d9dca261dc841d4731c64"}, + {url = "https://files.pythonhosted.org/packages/94/0f/09e51e71c3a35818abe1ba75f2d2516a5c90b3596989920a0b116768fe32/shapely-2.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173d24e85e51510e658fb108513d5bc11e3fd2820db6b1bd0522266ddd11f51"}, + {url = "https://files.pythonhosted.org/packages/98/e4/2d5b48e13cbcc976f468b995bb8bcfa8e758a8b73fe307af54184989158e/shapely-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a70a614791ff65f5e283feed747e1cc3d9e6c6ba91556e640636bbb0a1e32a71"}, + {url = "https://files.pythonhosted.org/packages/a7/ae/eab645c4075093584b7a65ab71cb8ff4563a015bd935c9b55dba14b2c1eb/shapely-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:bca57b683e3d94d0919e2f31e4d70fdfbb7059650ef1b431d9f4e045690edcd5"}, + {url = "https://files.pythonhosted.org/packages/a8/a5/403728b5614b28083f6424dfdefec5fcf58068495fb03bb08532671c642f/shapely-2.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce88ec79df55430e37178a191ad8df45cae90b0f6972d46d867bf6ebbb58cc4d"}, + {url = "https://files.pythonhosted.org/packages/b0/b4/b0cedcc974f5d3fba51850f81961f48a1246b4c4ddf4cd3faef6829e4173/shapely-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ac1dfc397475d1de485e76de0c3c91cc9d79bd39012a84bb0f5e8a199fc17bef"}, + {url = "https://files.pythonhosted.org/packages/b4/6f/08bb91f043854ec9e73b8d970437b6dca7323e44c63b53d2af6e80a9edba/shapely-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:193a398d81c97a62fc3634a1a33798a58fd1dcf4aead254d080b273efbb7e3ff"}, + {url = "https://files.pythonhosted.org/packages/bb/9b/c9dc1b43cd4364a247f7e82959f77b7ba63e6fe0b98435e3c98b08ba01d6/shapely-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b519cf3726ddb6c67f6a951d1bb1d29691111eaa67ea19ddca4d454fbe35949c"}, + {url = "https://files.pythonhosted.org/packages/bc/f1/c9db479170a7288d6bd2adcd1892785a3206b7a6f7972e7478714cb39e3c/shapely-2.0.1-cp311-cp311-win32.whl", hash = "sha256:09d6c7763b1bee0d0a2b84bb32a4c25c6359ad1ac582a62d8b211e89de986154"}, + {url = "https://files.pythonhosted.org/packages/cf/0f/c0456b1382d2a6815727cbd9c0713deca11653b330ba14b2cc165f0b9565/shapely-2.0.1-cp310-cp310-win32.whl", hash = "sha256:01224899ff692a62929ef1a3f5fe389043e262698a708ab7569f43a99a48ae82"}, + {url = "https://files.pythonhosted.org/packages/e2/87/b8b8d8d57b429b01aa56b7d723075c09f33c988b8091bb6f790c83436909/shapely-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:05c51a29336e604c084fb43ae5dbbfa2c0ef9bd6fedeae0a0d02c7b57a56ba46"}, + {url = "https://files.pythonhosted.org/packages/e6/7d/4923f27c340339e1c896c77cafc8ed672c8d381a025bbab6c6ddcba27e8f/shapely-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:83a8ec0ee0192b6e3feee9f6a499d1377e9c295af74d7f81ecba5a42a6b195b7"}, + {url = "https://files.pythonhosted.org/packages/e9/7c/76e54fa615a20ceb876e4de6b9f01a56926184bcc2076186c51c27ce39ad/shapely-2.0.1-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:90cfa4144ff189a3c3de62e2f3669283c98fb760cfa2e82ff70df40f11cadb39"}, + {url = "https://files.pythonhosted.org/packages/ea/aa/45fbd031edf3149cb767d8b9f9db45d5faf0324d743c6b8fb0298cc022d0/shapely-2.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2569a4b91caeef54dd5ae9091ae6f63526d8ca0b376b5bb9fd1a3195d047d7d4"}, + {url = "https://files.pythonhosted.org/packages/ec/41/d59208743e737184e1b403e95a937aebb022b8459e99efbcd5208fc8be46/shapely-2.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:865bc3d7cc0ea63189d11a0b1120d1307ed7a64720a8bfa5be2fde5fc6d0d33f"}, + {url = "https://files.pythonhosted.org/packages/f7/17/8bb86d26173982b81675cf6bcb0941ca144ea569a966d67774460121ba55/shapely-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a529218e72a3dbdc83676198e610485fdfa31178f4be5b519a8ae12ea688db14"}, + {url = "https://files.pythonhosted.org/packages/fa/fb/7ce0aff96d317916ec75889068c9c6bd92268b20839efd270e3d4e7107ab/shapely-2.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91575d97fd67391b85686573d758896ed2fc7476321c9d2e2b0c398b628b961c"}, +] +"six 1.16.0" = [ + {url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, + {url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, +] +"sqlalchemy 2.0.13" = [ + {url = "https://files.pythonhosted.org/packages/19/93/c125a8c86a8d953f81baace818f75db481a8cdaabbf19312c1e58f656221/SQLAlchemy-2.0.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9ad883ac4f5225999747f0849643c4d0ec809d9ffe0ddc81a81dd3e68d0af463"}, + {url = "https://files.pythonhosted.org/packages/1c/e7/9d45431cc2a6b4721c15f9dd49256f30a2c5cb0d9a2befdc92eb966a92eb/SQLAlchemy-2.0.13-cp310-cp310-win_amd64.whl", hash = "sha256:ec2f525273528425ed2f51861b7b88955160cb95dddb17af0914077040aff4a5"}, + {url = "https://files.pythonhosted.org/packages/27/2f/615d8e5396b5015fdf4d412480ab06afbd33657713c4f06ded6e860c3838/SQLAlchemy-2.0.13-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e0d20f27edfd6f35b388da2bdcd7769e4ffa374fef8994980ced26eb287e033a"}, + {url = "https://files.pythonhosted.org/packages/28/2e/b140b8dbba463663a025bb86eff8e8dd7c840047320a5412cf3e81ecbc1e/SQLAlchemy-2.0.13.tar.gz", hash = "sha256:8d97b37b4e60073c38bcf94e289e3be09ef9be870de88d163f16e08f2b9ded1a"}, + {url = "https://files.pythonhosted.org/packages/37/31/a23f164647008ad79f23b2941406112d6f7b3b3be940a5ed855cb061a69c/SQLAlchemy-2.0.13-cp311-cp311-win32.whl", hash = "sha256:c61b89803a87a3b2a394089a7dadb79a6c64c89f2e8930cc187fec43b319f8d2"}, + {url = "https://files.pythonhosted.org/packages/3f/f4/e94bc8bc033f7cf1df063b0077e5e4ca5f3f5cb1648aa2d6030a1d0afee3/SQLAlchemy-2.0.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:375b7ba88f261dbd79d044f20cbcd919d88befb63f26af9d084614f10cdf97a6"}, + {url = "https://files.pythonhosted.org/packages/41/56/d02457f36df484dc8539bb0aa8da5f9a39fde45915ef5c2229bf2bbe5d01/SQLAlchemy-2.0.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f3b5236079bc3e318a92bab2cc3f669cc32127075ab03ff61cacbae1c392b8"}, + {url = "https://files.pythonhosted.org/packages/4c/11/d32c6d5ae0db1ae7fea21f89c99eeacdfcd9c6e553edc68b39de18e4a3b3/SQLAlchemy-2.0.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:2ad9688debf1f0ae9c6e0706a4e2d33b1a01281317cee9bd1d7eef8020c5baac"}, + {url = "https://files.pythonhosted.org/packages/55/9e/5d70c35e4a3318f4c15b48053e2fe7dd68264b054c389413b55808aa2258/SQLAlchemy-2.0.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4e08e3831671008888bad5d160d757ef35ce34dbb73b78c3998d16aa1334c97"}, + {url = "https://files.pythonhosted.org/packages/59/61/bb559de442845bd4071008d68e6531ea11696838c2b3fa7e4e37e661169e/SQLAlchemy-2.0.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:db24d2738add6db19d66ca820479d2f8f96d3f5a13c223f27fa28dd2f268a4bd"}, + {url = "https://files.pythonhosted.org/packages/6d/d9/29e3c69579bafdecf50ce909fc7551c9a262b1380ca538b7474f3b3e1da3/SQLAlchemy-2.0.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:566a0ac347cf4632f551e7b28bbd0d215af82e6ffaa2556f565a3b6b51dc3f81"}, + {url = "https://files.pythonhosted.org/packages/6d/e5/c287122d33575c2d3878d5e9cda030a57d712cf82b102f84ac75baa80b72/SQLAlchemy-2.0.13-cp39-cp39-win_amd64.whl", hash = "sha256:881cc388dded44ae6e17a1666364b98bd76bcdc71b869014ae725f06ba298e0e"}, + {url = "https://files.pythonhosted.org/packages/74/d9/5309a1ac2fb24993e5949d8d6907038e3c38c7688e5626da9f8fef8ceed0/SQLAlchemy-2.0.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2424a84f131901fbb20a99844d47b38b517174c6e964c8efb15ea6bb9ced8c2b"}, + {url = "https://files.pythonhosted.org/packages/78/67/d2848efa86d9d3cca99f41eaae1f548bfdce8723c3059c96c1aa4afae715/SQLAlchemy-2.0.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d93ebbff3dcf05274843ad8cf650b48ee634626e752c5d73614e5ec9df45f0ce"}, + {url = "https://files.pythonhosted.org/packages/78/86/b0c40fd69f8b0c1d25c3ae74a12433fc5968e1084f027647ba3e038efbfd/SQLAlchemy-2.0.13-cp311-cp311-win_amd64.whl", hash = "sha256:0aa2cbde85a6eab9263ab480f19e8882d022d30ebcdc14d69e6a8d7c07b0a871"}, + {url = "https://files.pythonhosted.org/packages/79/9c/8bf13ceb09ea8609050e32f595df28700a27ebde0cc0e598ac5dbf5cf8ae/SQLAlchemy-2.0.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fec56c7d1b6a22c8f01557de3975d962ee40270b81b60d1cfdadf2a105d10e84"}, + {url = "https://files.pythonhosted.org/packages/7a/ee/eefbf0f19b1a27184b2500735763b7a97a7d0e8fc9f282942040ee5b5563/SQLAlchemy-2.0.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:a25b4c4fdd633501233924f873e6f6cd8970732859ecfe4ecfb60635881f70be"}, + {url = "https://files.pythonhosted.org/packages/7c/ee/7ddc7f52249b04f98b202ca71ccb6fc5d1a0716900fdb0ee15c3107499be/SQLAlchemy-2.0.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cdf80359b641185ae7e580afb9f88cf560298f309a38182972091165bfe1225d"}, + {url = "https://files.pythonhosted.org/packages/87/62/2012220935bdeed9d1d97fa88c918a9a4de16647239e7c79997d053857a3/SQLAlchemy-2.0.13-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e481e54db8cec1457ee7c05f6d2329e3298a304a70d3b5e2e82e77170850b385"}, + {url = "https://files.pythonhosted.org/packages/89/9e/3e59dfb69f084518b400eca94df881077b64750339bc01fd6ede4f39cffc/SQLAlchemy-2.0.13-cp38-cp38-win32.whl", hash = "sha256:6777673d346071451bf7cccf8d0499024f1bd6a835fc90b4fe7af50373d92ce6"}, + {url = "https://files.pythonhosted.org/packages/8e/b0/6f85288bf1b895685190a4d003089d97bc2664c002b31e580515a0f50812/SQLAlchemy-2.0.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a5e9e78332a5d841422b88b8c490dfd7f761e64b3430249b66c05d02f72ceab0"}, + {url = "https://files.pythonhosted.org/packages/91/a6/6155fedb5bf3cfba2c0dde60c41a8a105072a81c87d64124701316e7d767/SQLAlchemy-2.0.13-cp310-cp310-win32.whl", hash = "sha256:31f72bb300eed7bfdb373c7c046121d84fa0ae6f383089db9505ff553ac27cef"}, + {url = "https://files.pythonhosted.org/packages/92/9b/bece5ba42708360250d84351e6401a96a59c9b326b2a806f7e2cdb17a8f5/SQLAlchemy-2.0.13-cp37-cp37m-win32.whl", hash = "sha256:9136d596111c742d061c0f99bab95c5370016c4101a32e72c2b634ad5e0757e6"}, + {url = "https://files.pythonhosted.org/packages/99/f1/68dcce7b4a84437d28bf2505e7d2174eefdfaf209cac001ec8d52f781867/SQLAlchemy-2.0.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7ad24c85f2a1caf0cd1ae8c2fdb668777a51a02246d9039420f94bd7dbfd37ed"}, + {url = "https://files.pythonhosted.org/packages/9b/e9/92c8dfdd07f124322c418a0c3921adbe39081282f659f2f78a28cb5d6c4f/SQLAlchemy-2.0.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eb14a386a5b610305bec6639b35540b47f408b0a59f75999199aed5b3d40079"}, + {url = "https://files.pythonhosted.org/packages/9c/06/5ce18f4b96c0da6ead4295182e2c3bdad0888ae6192888f30f6c95293d45/SQLAlchemy-2.0.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72746ec17a7d9c5acf2c57a6e6190ceba3dad7127cd85bb17f24e90acc0e8e3f"}, + {url = "https://files.pythonhosted.org/packages/a6/1d/8d3234895192cead943f31da54cd44dff74b3fa572485710958eaf322d0a/SQLAlchemy-2.0.13-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fd0febae872a4042da44e972c070f0fd49a85a0a7727ab6b85425f74348be14e"}, + {url = "https://files.pythonhosted.org/packages/ba/94/d638672f73b8ec579e98a9d347750221cf6f51fde1ee320cfd019dfb53f1/SQLAlchemy-2.0.13-cp39-cp39-win32.whl", hash = "sha256:f463598f9e51ccc04f0fe08500f9a0c3251a7086765350be418598b753b5561d"}, + {url = "https://files.pythonhosted.org/packages/bb/9f/a795826752bf99318fe0c8b9b4469000cfab7ac09161a63995b23a620c41/SQLAlchemy-2.0.13-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bf1aae95e80acea02a0a622e1c12d3fefc52ffd0fe7bda70a30d070373fbb6c3"}, + {url = "https://files.pythonhosted.org/packages/c5/70/00e6c1d4499e38fdf92f59323d9a1a89d69f02bd9415d203fc8cb5abd087/SQLAlchemy-2.0.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:755f653d693f9b8f4286d987aec0d4279821bf8d179a9de8e8a5c685e77e57d6"}, + {url = "https://files.pythonhosted.org/packages/c5/aa/5d3d0065e9fcae3de61cf8cab5dcea1a6546dd8d4374fab1f34f463488dc/SQLAlchemy-2.0.13-cp38-cp38-win_amd64.whl", hash = "sha256:2f0a355264af0952570f18457102984e1f79510f856e5e0ae652e63316d1ca23"}, + {url = "https://files.pythonhosted.org/packages/d3/82/e49059628d82e91027034419456cfa9fc2b2b7defda66094551982913963/SQLAlchemy-2.0.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:37de4010f53f452e94e5ed6684480432cfe6a7a8914307ef819cd028b05b98d5"}, + {url = "https://files.pythonhosted.org/packages/d4/d7/a3e7cb06aabe16cb63a5415e008b5df349561b2991352927ffd080946f8d/SQLAlchemy-2.0.13-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f234ba3bb339ad17803009c8251f5ee65dcf283a380817fe486823b08b26383d"}, + {url = "https://files.pythonhosted.org/packages/d5/19/688857413ba08062634cb203080f4c773211dcb3d8d646a1dd3c91841147/SQLAlchemy-2.0.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a30e4db983faa5145e00ef6eaf894a2d503b3221dbf40a595f3011930d3d0bac"}, + {url = "https://files.pythonhosted.org/packages/d5/1a/79fd551f63090a3550e1cfead4f40a7ae1bbdffa3dcafefefb4c4133309b/SQLAlchemy-2.0.13-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:9119795d2405eb23bf7e6707e228fe38124df029494c1b3576459aa3202ea432"}, + {url = "https://files.pythonhosted.org/packages/da/39/ea18f94d16ea316d290cc1451a3a444f7226a781ce6726407d322d30701c/SQLAlchemy-2.0.13-cp37-cp37m-win_amd64.whl", hash = "sha256:7612a7366a0855a04430363fb4ab392dc6818aaece0b2e325ff30ee77af9b21f"}, + {url = "https://files.pythonhosted.org/packages/de/82/2c350ddcaa8c9d1e3b04044a14c0d281035f50678901aff11d7480ac37a4/SQLAlchemy-2.0.13-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:e5e5dc300a0ca8755ada1569f5caccfcdca28607dfb98b86a54996b288a8ebd3"}, + {url = "https://files.pythonhosted.org/packages/e0/99/24a17d40ff4995496d01b3106f055567a6dd7d29b1fb4533fd5584f4921c/SQLAlchemy-2.0.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:49c138856035cb97f0053e5e57ba90ec936b28a0b8b0020d44965c7b0c0bf03a"}, + {url = "https://files.pythonhosted.org/packages/e5/fb/0097d9b2653ab348d519756e4624eff85190290742917719f11cf0369d9f/SQLAlchemy-2.0.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f717944aee40e9f48776cf85b523bb376aa2d9255a268d6d643c57ab387e7264"}, + {url = "https://files.pythonhosted.org/packages/f4/07/21ca55bd3af3a29494ea60e962dc896620c540acc5270e7ccb9bd0f22c8b/SQLAlchemy-2.0.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4f9832815257969b3ca9bf0501351e4c02c8d60cbd3ec9f9070d5b0f8852900e"}, + {url = "https://files.pythonhosted.org/packages/f6/33/92cf0cc4a58fde3b1e573f348e31ee6a3ef9dfa32f75c440bcc4b6142ca7/SQLAlchemy-2.0.13-py3-none-any.whl", hash = "sha256:0d6979c9707f8b82366ba34b38b5a6fe32f75766b2e901f9820e271e95384070"}, ] "text-unidecode 1.3" = [ {url = "https://files.pythonhosted.org/packages/a6/a5/c0b6468d3824fe3fde30dbb5e1f687b291608f9473681bbf7dabbf5a87d7/text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"}, {url = "https://files.pythonhosted.org/packages/ab/e2/e9a00f0ccb71718418230718b3d900e71a5d16e701a3dae079a21e9cd8f8/text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"}, ] -"toml 0.10.1" = [ - {url = "https://files.pythonhosted.org/packages/9f/e1/1b40b80f2e1663a6b9f497123c11d7d988c0919abbf3c3f2688e448c5363/toml-0.10.1-py2.py3-none-any.whl", hash = "sha256:bda89d5935c2eac546d648028b9901107a595863cb36bae0c73ac804a9b4ce88"}, - {url = "https://files.pythonhosted.org/packages/da/24/84d5c108e818ca294efe7c1ce237b42118643ce58a14d2462b3b2e3800d5/toml-0.10.1.tar.gz", hash = "sha256:926b612be1e5ce0634a2ca03470f95169cf16f939018233a670519cb4ac58b0f"}, -] "tomli 2.0.1" = [ {url = "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, {url = "https://files.pythonhosted.org/packages/c0/3f/d7af728f075fb08564c5949a9c95e44352e23dee646869fa104a3b2060a3/tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -"typed-ast 1.5.4" = [ - {url = "https://files.pythonhosted.org/packages/04/93/482d12fd3334b53ec4087e658ab161ab23affcf8b052166b4cf972ca673b/typed_ast-1.5.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6778e1b2f81dfc7bc58e4b259363b83d2e509a65198e85d5700dfae4c6c8ff1c"}, - {url = "https://files.pythonhosted.org/packages/07/d2/d55702e8deba2c80282fea0df53130790d8f398648be589750954c2dcce4/typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, - {url = "https://files.pythonhosted.org/packages/0b/e7/8ec06fc870254889198f933a595f139b7871b24bab1116d6128440731ea9/typed_ast-1.5.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3e123d878ba170397916557d31c8f589951e353cc95fb7f24f6bb69adc1a8a97"}, - {url = "https://files.pythonhosted.org/packages/0f/59/430b86961d63278fcbced5ba72655ee93aa35e8e908bad4ff138480eb25d/typed_ast-1.5.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:669dd0c4167f6f2cd9f57041e03c3c2ebf9063d0757dc89f79ba1daa2bfca9d4"}, - {url = "https://files.pythonhosted.org/packages/1a/f6/dd891624aaf98b918d7012b9d01753d0192c4eb18cf33ce616c0e08f62ba/typed_ast-1.5.4-cp37-cp37m-win_amd64.whl", hash = "sha256:0261195c2062caf107831e92a76764c81227dae162c4f75192c0d489faf751a2"}, - {url = "https://files.pythonhosted.org/packages/2f/87/25abe9558ed6cbd83ad5bfdccf7210a7eefaaf0232f86de99f65992e91fd/typed_ast-1.5.4-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7d5d014b7daa8b0bf2eaef684295acae12b036d79f54178b92a2b6a56f92278f"}, - {url = "https://files.pythonhosted.org/packages/2f/d5/02059fe6ca70b11bb831007962323160372ca83843e0bf296e8b6d833198/typed_ast-1.5.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebd9d7f80ccf7a82ac5f88c521115cc55d84e35bf8b446fcd7836eb6b98929a3"}, - {url = "https://files.pythonhosted.org/packages/34/2d/17fc1845dd5210345904b054c9fa90f451d64df56de0470f429bc8d63d39/typed_ast-1.5.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cf4afcfac006ece570e32d6fa90ab74a17245b83dfd6655a6f68568098345ff6"}, - {url = "https://files.pythonhosted.org/packages/38/54/48f7d5b1f954f3a4d8f76e1a11c8497ae899b900cd5a67f826fa3937f701/typed_ast-1.5.4-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a94d55d142c9265f4ea46fab70977a1944ecae359ae867397757d836ea5a3f47"}, - {url = "https://files.pythonhosted.org/packages/40/1a/5731a1a3908f60032aead10c2ffc9af12ee708bc9a156ed14a5065a9873a/typed_ast-1.5.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4e964b4ff86550a7a7d56345c7864b18f403f5bd7380edf44a3c1fb4ee7ac6c6"}, - {url = "https://files.pythonhosted.org/packages/48/6c/d96a545d337589dc5d7ecc0f8991122800ffec8dc10a24090619883b515e/typed_ast-1.5.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:211260621ab1cd7324e0798d6be953d00b74e0428382991adfddb352252f1d62"}, - {url = "https://files.pythonhosted.org/packages/4e/c1/cddc664ed3dd7d6bb62c80286c4e088b10556efc9a8db2049b425f8f23f7/typed_ast-1.5.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79b1e0869db7c830ba6a981d58711c88b6677506e648496b1f64ac7d15633aec"}, - {url = "https://files.pythonhosted.org/packages/5c/e3/f539e658614ebf5a521c8ba7cbbb98afc5f5e90ddb0332ea22c164612dad/typed_ast-1.5.4-cp38-cp38-win_amd64.whl", hash = "sha256:683407d92dc953c8a7347119596f0b0e6c55eb98ebebd9b23437501b28dcbb8e"}, - {url = "https://files.pythonhosted.org/packages/70/2c/6d18e111d2c5422bb9e561bbf36885e430407859b2adef9b3fb575f189d5/typed_ast-1.5.4-cp36-cp36m-win_amd64.whl", hash = "sha256:639c5f0b21776605dd6c9dbe592d5228f021404dafd377e2b7ac046b0349b1a1"}, - {url = "https://files.pythonhosted.org/packages/78/18/3ecf5043f227ebd4a43af57e18e6a38f9fe0b81dbfbb8d62eec669d7b69e/typed_ast-1.5.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:370788a63915e82fd6f212865a596a0fefcbb7d408bbbb13dea723d971ed8bdc"}, - {url = "https://files.pythonhosted.org/packages/96/35/612258bab9e1867b28e3137910df35576b7b0fbb9b6f3013cc23435a79ed/typed_ast-1.5.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:267e3f78697a6c00c689c03db4876dd1efdfea2f251a5ad6555e82a26847b4ac"}, - {url = "https://files.pythonhosted.org/packages/9b/d5/5540eb496c6817eaee8120fb759c7adb36f91ef647c6bb2877f09acc0569/typed_ast-1.5.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2efae9db7a8c05ad5547d522e7dbe62c83d838d3906a3716d1478b6c1d61388d"}, - {url = "https://files.pythonhosted.org/packages/c4/90/dacf9226b34961277f357c17c33b7cae3f05a5f5b8a1d23bd630d7a97a36/typed_ast-1.5.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c542eeda69212fa10a7ada75e668876fdec5f856cd3d06829e6aa64ad17c8dfe"}, - {url = "https://files.pythonhosted.org/packages/ca/da/fbc14befbf19d69d05b4b8b019edbc6554d958037a821c6d5585767fe0ff/typed_ast-1.5.4-cp39-cp39-win_amd64.whl", hash = "sha256:0fdbcf2fef0ca421a3f5912555804296f0b0960f0418c440f5d6d3abb549f3e1"}, - {url = "https://files.pythonhosted.org/packages/cd/f3/188eede730be3f6ddb9a788cd6b7289207c5fceebbf8ae190f9716dd8c05/typed_ast-1.5.4-cp310-cp310-win_amd64.whl", hash = "sha256:a9916d2bb8865f973824fb47436fa45e1ebf2efd920f2b9f99342cb7fab93f72"}, - {url = "https://files.pythonhosted.org/packages/d8/4e/db9505b53c44d7bc324a3d2e09bdf82b0943d6e08b183ae382860f482a87/typed_ast-1.5.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98f80dee3c03455e92796b58b98ff6ca0b2a6f652120c263efdba4d6c5e58f72"}, - {url = "https://files.pythonhosted.org/packages/dd/87/09764c19a60a192b935579c93a07e781f6a52def10b723c8c5748e69a863/typed_ast-1.5.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed855bbe3eb3715fca349c80174cfcfd699c2f9de574d40527b8429acae23a66"}, - {url = "https://files.pythonhosted.org/packages/e3/7c/7407838e9c540031439f2948bce2763cdd6882ebb72cc0a25b763c10529e/typed_ast-1.5.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:183afdf0ec5b1b211724dfef3d2cad2d767cbefac291f24d69b00546c1837fb6"}, - {url = "https://files.pythonhosted.org/packages/f9/57/89ac0020d5ffc762487376d0c78e5d02af795657f18c411155b73de3c765/typed_ast-1.5.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4879da6c9b73443f97e731b617184a596ac1235fe91f98d279a7af36c796da35"}, -] "typing-extensions 4.5.0" = [ {url = "https://files.pythonhosted.org/packages/31/25/5abcd82372d3d4a3932e1fa8c3dbf9efac10cc7c0d16e78467460571b404/typing_extensions-4.5.0-py3-none-any.whl", hash = "sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4"}, {url = "https://files.pythonhosted.org/packages/d3/20/06270dac7316220643c32ae61694e451c98f8caf4c8eab3aa80a2bedf0df/typing_extensions-4.5.0.tar.gz", hash = "sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb"}, ] -"tzlocal 2.1" = [ - {url = "https://files.pythonhosted.org/packages/5d/94/d47b0fd5988e6b7059de05720a646a2930920fff247a826f61674d436ba4/tzlocal-2.1-py2.py3-none-any.whl", hash = "sha256:e2cb6c6b5b604af38597403e9852872d7f534962ae2954c7f35efcb1ccacf4a4"}, - {url = "https://files.pythonhosted.org/packages/ce/73/99e4cc30db6b21cba6c3b3b80cffc472cc5a0feaf79c290f01f1ac460710/tzlocal-2.1.tar.gz", hash = "sha256:643c97c5294aedc737780a49d9df30889321cbe1204eac2c2ec6134035a92e44"}, +"tzdata 2023.3" = [ + {url = "https://files.pythonhosted.org/packages/70/e5/81f99b9fced59624562ab62a33df639a11b26c582be78864b339dafa420d/tzdata-2023.3.tar.gz", hash = "sha256:11ef1e08e54acb0d4f95bdb1be05da659673de4acbd21bf9c69e94cc5e907a3a"}, + {url = "https://files.pythonhosted.org/packages/d5/fb/a79efcab32b8a1f1ddca7f35109a50e4a80d42ac1c9187ab46522b2407d7/tzdata-2023.3-py2.py3-none-any.whl", hash = "sha256:7e65763eef3120314099b6939b5546db7adce1e7d6f2e179e3df563c70511eda"}, ] -"unidecode 1.1.1" = [ - {url = "https://files.pythonhosted.org/packages/b1/d6/7e2a98e98c43cf11406de6097e2656d31559f788e9210326ce6544bd7d40/Unidecode-1.1.1.tar.gz", hash = "sha256:2b6aab710c2a1647e928e36d69c21e76b453cd455f4e2621000e54b2a9b8cce8"}, - {url = "https://files.pythonhosted.org/packages/d0/42/d9edfed04228bacea2d824904cae367ee9efd05e6cce7ceaaedd0b0ad964/Unidecode-1.1.1-py2.py3-none-any.whl", hash = "sha256:1d7a042116536098d05d599ef2b8616759f02985c85b4fef50c78a5aaf10822a"}, +"tzlocal 5.0.1" = [ + {url = "https://files.pythonhosted.org/packages/84/d2/730a87f0dbf184760394a85088d0d2366a5a8a32bc32ffd869a83f1de854/tzlocal-5.0.1-py3-none-any.whl", hash = "sha256:f3596e180296aaf2dbd97d124fe76ae3a0e3d32b258447de7b939b3fd4be992f"}, + {url = "https://files.pythonhosted.org/packages/ee/f5/3e644f08771b242f7460438cdc0aaad4d1484c1f060f1e52f4738d342983/tzlocal-5.0.1.tar.gz", hash = "sha256:46eb99ad4bdb71f3f72b7d24f4267753e240944ecfc16f25d2719ba89827a803"}, ] -"urllib3 1.26.9" = [ - {url = "https://files.pythonhosted.org/packages/1b/a5/4eab74853625505725cefdf168f48661b2cd04e7843ab836f3f63abf81da/urllib3-1.26.9.tar.gz", hash = "sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e"}, - {url = "https://files.pythonhosted.org/packages/ec/03/062e6444ce4baf1eac17a6a0ebfe36bb1ad05e1df0e20b110de59c278498/urllib3-1.26.9-py2.py3-none-any.whl", hash = "sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14"}, +"urllib3 1.26.15" = [ + {url = "https://files.pythonhosted.org/packages/21/79/6372d8c0d0641b4072889f3ff84f279b738cd8595b64c8e0496d4e848122/urllib3-1.26.15.tar.gz", hash = "sha256:8a388717b9476f934a21484e8c8e61875ab60644d29b9b39e11e4b9dc1c6b305"}, + {url = "https://files.pythonhosted.org/packages/7b/f5/890a0baca17a61c1f92f72b81d3c31523c99bec609e60c292ea55b387ae8/urllib3-1.26.15-py2.py3-none-any.whl", hash = "sha256:aa751d169e23c7479ce47a0cb0da579e3ede798f994f5816a74e4f4500dcea42"}, ] "webencodings 0.5.1" = [ {url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, {url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, ] -"werkzeug 0.16.1" = [ - {url = "https://files.pythonhosted.org/packages/c2/e4/a859d2fe516f466642fa5c6054fd9646271f9da26b0cac0d2f37fc858c8f/Werkzeug-0.16.1-py2.py3-none-any.whl", hash = "sha256:1e0dedc2acb1f46827daa2e399c1485c8fa17c0d8e70b6b875b4e7f54bf408d2"}, - {url = "https://files.pythonhosted.org/packages/c3/1d/1c0761d9365d166dc9d882a48c437111d22b0df564d6d5768045d9a51fd0/Werkzeug-0.16.1.tar.gz", hash = "sha256:b353856d37dec59d6511359f97f6a4b2468442e454bd1c98298ddce53cac1f04"}, +"werkzeug 2.3.4" = [ + {url = "https://files.pythonhosted.org/packages/2d/bf/5a00bb4a70028f7c6000bc9394492154fa9ae3f5226187e3ddcd0aa5eca1/Werkzeug-2.3.4.tar.gz", hash = "sha256:1d5a58e0377d1fe39d061a5de4469e414e78ccb1e1e59c0f5ad6fa1c36c52b76"}, + {url = "https://files.pythonhosted.org/packages/c2/2f/f0dc628295bd23571c962d5a349307d9c8796a05bfca6571659eaded38e2/Werkzeug-2.3.4-py3-none-any.whl", hash = "sha256:48e5e61472fee0ddee27ebad085614ebedb7af41e88f687aaf881afb723a162f"}, ] "zipp 3.15.0" = [ {url = "https://files.pythonhosted.org/packages/00/27/f0ac6b846684cecce1ee93d32450c45ab607f65c2e0255f0092032d91f07/zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, diff --git a/pyproject.toml b/pyproject.toml index 8bcbbac35b..97394d5e7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,98 +6,55 @@ authors = [ {name = "HOT Sysadmin", email = "sysadmin@hotosm.org"}, ] dependencies = [ - "alembic==1.4.3", - "aniso8601==8.0.0", - "appdirs==1.4.4", - "APScheduler==3.7.0", - "attrs==20.2.0", - "black==23.3.0", - "bleach==5.0.1", - "blinker==1.5", - "cachetools==4.1.1", - "certifi==2020.6.20", - "chardet==3.0.4", - "charset-normalizer==2.0.12", - "click==8.1.3", - "coverage==6.4", - "entrypoints==0.3", - "flake8==3.8.4", - "Flask==1.1.2", - "Flask-Cors==3.0.9", - "Flask-HTTPAuth==4.1.0", + # Direct dependencies (at least one import requires it) + "APScheduler==3.10.1", + "alembic==1.11.1", + "bleach==6.0.0", + "cachetools==5.3.0", + "Flask==2.3.2", + "Flask-Cors==3.0.10", + "Flask-HTTPAuth==4.8.0", + "Flask-Migrate==4.0.4", "Flask-Mail==0.9.1", - "Flask-Migrate==2.5.3", - "Flask-RESTful==0.3.8", - "Flask-Script==2.0.6", - "Flask-SQLAlchemy==2.4.4", + "Flask-RESTful==0.3.9", + "Flask-SQLAlchemy==3.0.3", "flask-swagger==0.2.14", - "GeoAlchemy2==0.8.4", - "geojson==1.3.4", - "gevent==21.12.0", - "glob2==0.7", - "greenlet==1.1.2", - "gunicorn==20.0.4", - "idna==2.10", - "importlib-metadata==4.13.0", - "itsdangerous==1.1.0", - "Jinja2==2.11.3", - "Mako==1.2.2", - "Markdown==3.3.3", - "MarkupSafe==1.1.1", - "mccabe==0.6.1", - "mypy-extensions==1.0.0", - "newrelic==8.8.0", - "nose==1.3.7", - "oauthlib==3.2.0", - "packaging==23.1", - "pathspec==0.11.1", - "platformdirs==3.5.0", - "psycopg2==2.8.6", - "pycodestyle==2.6.0", - "pyflakes==2.2.0", - "pyparsing==2.4.7", - "pyproj==3.5.0", - "python-dateutil==2.8.1", - "python-dotenv==0.14.0", - "python-editor==1.0.4", - "python-slugify==4.0.1", - "pytz==2020.1", - "PyYAML==5.4", - "regex==2022.10.31", - "requests==2.27.1", + "GeoAlchemy2==0.13.3", + "geojson==3.0.1", + "itsdangerous==2.1.2", + "Markdown==3.4.3", + "oauthlib==3.2.2", + "psycopg2==2.9.6", + "python-dateutil==2.8.2", + "python-dotenv==1.0.0", + "python-slugify==8.0.1", + "requests==2.30.0", "requests-oauthlib==1.3.1", "schematics==2.1.1", - "sentry-sdk[flask]==1.5.8", - "setuptools==67.7.2", - "Shapely==1.7.1", - "six==1.15.0", - "SQLAlchemy==1.3.20", - "text-unidecode==1.3", - "toml==0.10.1", - "tomli==2.0.1", - "typed-ast==1.5.4", - "typing-extensions==4.5.0", - "tzlocal==2.1", - "Unidecode==1.1.1", - "urllib3==1.26.9", - "webencodings==0.5.1", - "Werkzeug==0.16.1", - "zipp==3.15.0", - "zope-event==4.6", - "zope-interface==6.0", + "sentry-sdk[flask]==1.23.1", + "shapely==2.0.1", + "SQLAlchemy==2.0.13", + "Werkzeug==2.3.4", + # Indirect, but required dependencies (often required for efficient deployments) + "gevent==22.10.2", + "greenlet==2.0.2", + "gunicorn[gevent]==20.1.0", + "importlib-metadata==6.6.0" # See https://github.com/hotosm/tasking-manager/issues/5395 ] requires-python = ">=3.9,<=3.11" readme = "README.md" license = {text = "BSD-2-Clause"} [tool] -[tool.pdm] +[tool.pdm.dev-dependencies] +test = ["coverage==7.2.5", "nose==1.3.7"] +lint = ["black==23.3.0", "flake8==6.0.0"] [tool.pdm.scripts] -start = "python manage.py runserver -d -r" -migrate = "python manage.py db migrate" -upgrade = "python manage.py db upgrade" -downgrade = "python manage.py db downgrade" +start = "flask run --debug --reload" +migrate = "flask db migrate" +upgrade = "flask db upgrade" +downgrade = "flask db downgrade" test = "python -m unittest discover" lint = "black manage.py backend tests migrations" flake8 = "flake8 manage.py backend tests migrations" diff --git a/requirements.txt b/requirements.txt index 9d41de92f4..b576f9a8f7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,80 +1,82 @@ -alembic==1.4.3 -aniso8601==8.0.0 -appdirs==1.4.4 -APScheduler==3.7.0 -attrs==20.2.0 -black==23.3.0 -bleach==5.0.1 -blinker==1.5 -cachetools==4.1.1 -certifi==2020.6.20 -chardet==3.0.4 -charset-normalizer==2.0.12 -click==8.1.3 -coverage==6.4 -entrypoints==0.3 -flake8==3.8.4 -Flask==1.1.2 -Flask-Cors==3.0.9 -Flask-HTTPAuth==4.1.0 +# Update instructions: +# 1. Delete the virtual environment +# 2. Create a new clean virtual environment +# 3. Remove all unnecessary indirect dependencies in this file ("Indirect dependencies (these can be blown away at any time)") +# 4. Update the relevant packages +# 5. Run `pip install -r requirements.txt` +# 6. Run `pip freeze -r requirements.txt > requirements.new.txt` +# 7. Run `mv requirements.new.txt requirements.txt` +# 8. Run tests +# +# Direct dependencies (at least one import requires it) +APScheduler==3.10.1 +alembic==1.11.1 +bleach==6.0.0 +cachetools==5.3.0 +Flask==2.3.2 +Flask-Cors==3.0.10 +Flask-HTTPAuth==4.8.0 +Flask-Migrate==4.0.4 Flask-Mail==0.9.1 -Flask-Migrate==2.5.3 -Flask-RESTful==0.3.8 -Flask-Script==2.0.6 -Flask-SQLAlchemy==2.4.4 +Flask-RESTful==0.3.9 +Flask-SQLAlchemy==3.0.3 flask-swagger==0.2.14 -GeoAlchemy2==0.8.4 -geojson==1.3.4 -gevent==21.12.0 -glob2==0.7 -greenlet==1.1.2 -gunicorn==20.0.4 -idna==2.10 -importlib-metadata==4.13.0 # See https://github.com/hotosm/tasking-manager/issues/5395 -itsdangerous==1.1.0 -Jinja2==2.11.3 -Mako==1.2.2 -Markdown==3.3.3 -MarkupSafe==1.1.1 -mccabe==0.6.1 -mypy-extensions==1.0.0 -newrelic==8.8.0 +GeoAlchemy2==0.13.3 +geojson==3.0.1 +itsdangerous==2.1.2 +Markdown==3.4.3 +oauthlib==3.2.2 +psycopg2==2.9.6 +python-dateutil==2.8.2 +python-dotenv==1.0.0 +python-slugify==8.0.1 +requests==2.30.0 +requests-oauthlib==1.3.1 +schematics==2.1.1 +sentry-sdk[flask]==1.23.1 +shapely==2.0.1 +SQLAlchemy==2.0.13 +Werkzeug==2.3.4 +# Dev dependencies (stuff useful for development) +black==23.3.0 +coverage==7.2.5 +flake8==6.0.0 nose==1.3.7 -oauthlib==3.2.0 +# Indirect, but required dependencies (often required for efficient deployments) +gevent==22.10.2 +greenlet==2.0.2 +gunicorn==20.1.0 +importlib-metadata==6.6.0 # See https://github.com/hotosm/tasking-manager/issues/5395 +# Indirect dependencies (these can be blown away at any time) + +## The following requirements were added by pip freeze: +aniso8601==9.0.1 +blinker==1.6.2 +certifi==2023.5.7 +charset-normalizer==3.1.0 +click==8.1.3 +idna==3.4 +Jinja2==3.1.2 +Mako==1.2.4 +MarkupSafe==2.1.2 +mccabe==0.7.0 +mypy-extensions==1.0.0 +numpy==1.24.3 packaging==23.1 pathspec==0.11.1 -platformdirs==3.5.0 -psycopg2==2.8.6 -pycodestyle==2.6.0 -pyflakes==2.2.0 -pyparsing==2.4.7 -pyproj==3.5.0 -python-dateutil==2.8.1 -python-dotenv==0.14.0 -python-editor==1.0.4 -python-slugify==4.0.1 -pytz==2020.1 -PyYAML==5.4 -regex==2022.10.31 -requests==2.27.1 -requests-oauthlib==1.3.1 -schematics==2.1.1 -sentry-sdk[flask]==1.5.8 -setuptools==67.7.2 -Shapely==1.7.1 -six==1.15.0 -SQLAlchemy==1.3.20 +platformdirs==3.5.1 +pycodestyle==2.10.0 +pyflakes==3.0.1 +pytz==2023.3 +pytz-deprecation-shim==0.1.0.post0 +PyYAML==6.0 +six==1.16.0 text-unidecode==1.3 -toml==0.10.1 -tomli==2.0.1 -typed-ast==1.5.4 -typing-extensions==4.5.0 -tzlocal==2.1 -Unidecode==1.1.1 -urllib3==1.26.9 +typing_extensions==4.5.0 +tzdata==2023.3 +tzlocal==5.0.1 +urllib3==1.26.15 webencodings==0.5.1 -Werkzeug==0.16.1 zipp==3.15.0 -zope-event==4.6 -zope-interface==6.0 - +zope.event==4.6 +zope.interface==6.0 diff --git a/scripts/aws/cloudformation/tasking-manager.template.js b/scripts/aws/cloudformation/tasking-manager.template.js index b92ddd9e17..e03637dc9e 100644 --- a/scripts/aws/cloudformation/tasking-manager.template.js +++ b/scripts/aws/cloudformation/tasking-manager.template.js @@ -417,7 +417,7 @@ const Resources = { cf.sub('export TM_IMAGE_UPLOAD_API_KEY="${TaskingManagerImageUploadAPIKey}"'), 'psql "host=$POSTGRES_ENDPOINT dbname=$POSTGRES_DB user=$POSTGRES_USER password=$POSTGRES_PASSWORD" -c "CREATE EXTENSION IF NOT EXISTS postgis"', cf.if('DatabaseDumpFileGiven', cf.sub('aws s3 cp ${DatabaseDump} dump.sql; sudo -u postgres psql "postgresql://$POSTGRES_USER:$POSTGRES_PASSWORD@$POSTGRES_ENDPOINT/$POSTGRES_DB" < dump.sql'), ''), - 'python3 manage.py db upgrade', + 'pdm run flask db upgrade', 'echo "------------------------------------------------------------"', cf.sub('export NEW_RELIC_LICENSE_KEY="${NewRelicLicense}"'), cf.sub('export TM_SENTRY_BACKEND_DSN="${SentryBackendDSN}"'), diff --git a/scripts/database/export-import-projects/README b/scripts/database/export-import-projects/README index 976930a85b..c8e6a5c6b3 100644 --- a/scripts/database/export-import-projects/README +++ b/scripts/database/export-import-projects/README @@ -2,7 +2,7 @@ These migration scripts allow to restore deleted projects using postgres commands. For now, there are two scripts: 1. dbtocsv.sh: By setting the required variables, this script reads the defined project ids within the PROJECT_IDS variable and starts saving the required information for each table in a csv file. -2. restart_table.sh: which destroys and then creates with postgis extension the desired database. However, migration tables are not executed within this script. You need to run `python manage.py db upgrade` yourself every time the database is restarted. +2. restart_table.sh: which destroys and then creates with postgis extension the desired database. However, migration tables are not executed within this script. You need to run `flask db upgrade` yourself every time the database is restarted. Tables to migrate and verify if they are necessary to: [x] projects diff --git a/scripts/database/migration-from-tm2-postgres.sql b/scripts/database/migration-from-tm2-postgres.sql index 527d2894db..6e652fed45 100644 --- a/scripts/database/migration-from-tm2-postgres.sql +++ b/scripts/database/migration-from-tm2-postgres.sql @@ -5,7 +5,7 @@ -- Also, we assume you have created the TM3 database by following the README or migration guide, -- meaning you will have a database named "taskingmanager" already. Make sure you have run the alembic -- database upgrades to load the schema of "taskingmanager". As a refresher, this is done in the base --- TM3 directory via: python manage.py db upgrade +-- TM3 directory via: flask db upgrade -- If you run into errors, make sure your environmental variable is set for TM_DB. -- -- Now to the migration... diff --git a/scripts/docker/tasking-manager/Dockerfile b/scripts/docker/tasking-manager/Dockerfile index cd176dfd8d..8d996fdda2 100644 --- a/scripts/docker/tasking-manager/Dockerfile +++ b/scripts/docker/tasking-manager/Dockerfile @@ -1,10 +1,11 @@ -FROM python:3.7-buster +ARG PYTHON_IMG_TAG=3.9 +FROM python:${PYTHON_IMG_TAG}-buster RUN mkdir -p /usr/src/app WORKDIR /usr/src/app -ENV PATH="/usr/src/app/__pypackages__/3.7/bin:$PATH" \ - PYTHONPATH="/usr/src/app/__pypackages__/3.7/lib" +ENV PATH="/usr/src/app/__pypackages__/${PYTHON_IMG_TAG}/bin:$PATH" \ + PYTHONPATH="/usr/src/app/__pypackages__/${PYTHON_IMG_TAG}/lib" # INSTALLATION @@ -39,4 +40,4 @@ RUN cd frontend && npm install && npm run build # INITIALIZATION EXPOSE 5000 -CMD ["python", "manage.py", "runserver", "-h", "0.0.0.0"] +CMD ["pdm", "run", "flask", "run", "-h", "0.0.0.0"] diff --git a/scripts/install/install_on_debian_10_buster.sh b/scripts/install/install_on_debian_10_buster.sh index e8571c1caa..6590350837 100755 --- a/scripts/install/install_on_debian_10_buster.sh +++ b/scripts/install/install_on_debian_10_buster.sh @@ -67,7 +67,7 @@ do sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POS cd ../../ && # Upgrade database -python3 manage.py db upgrade && +pdm run flask db upgrade && # Assamble the tasking manager interface cd frontend/ && @@ -78,4 +78,4 @@ cd ../ && ## Please edit the tasking-manager.env as indicated in the README.md ## # Start the tasking manager -python3 manage.py runserver -d +pdm run flask run -d diff --git a/scripts/install/install_on_ubuntu_18_04.sh b/scripts/install/install_on_ubuntu_18_04.sh index e24598eb8c..1f4ce43b41 100755 --- a/scripts/install/install_on_ubuntu_18_04.sh +++ b/scripts/install/install_on_ubuntu_18_04.sh @@ -68,9 +68,9 @@ do sudo -u postgres psql -c "alter table \"$tbl\" owner to $POSTGRES_USER" $POS cd ../../ && # Upgrade database -python3 manage.py db upgrade && +pdm run flask db upgrade && -# Assamble the tasking manager interface +# Assemble the tasking manager interface cd frontend/ && npm install && npm run build && @@ -79,4 +79,4 @@ cd ../ && ## Please edit the tasking-manager.env as indicated in the README.md ## # Start the tasking manager -python3 manage.py runserver -d +pdm run flask run -d diff --git a/tests/backend/integration/api/users/test_actions.py b/tests/backend/integration/api/users/test_actions.py index 745bfd9e91..a9e9f06e92 100644 --- a/tests/backend/integration/api/users/test_actions.py +++ b/tests/backend/integration/api/users/test_actions.py @@ -116,7 +116,7 @@ def setUp(self): def test_returns_400_if_no_data(self): """Test that the API returns 400 if no data is provided""" # Act - response = self.client.post(self.url) + response = self.client.post(self.url, content_type="application/json") # Assert self.assertEqual(response.status_code, 400) From fb44908684c0a8bbc964b6bce7d2364cc46fc8a5 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 15:20:06 -0600 Subject: [PATCH 02/15] Replace nose with pytest Signed-off-by: Taylor Smock --- pdm.lock | 60 +++++++++++++++++++++++++++++++++++++++--------- pyproject.toml | 2 +- requirements.txt | 6 ++--- 3 files changed, 53 insertions(+), 15 deletions(-) diff --git a/pdm.lock b/pdm.lock index f4d2f8aeaf..9cbef9f27f 100644 --- a/pdm.lock +++ b/pdm.lock @@ -107,6 +107,12 @@ version = "7.2.5" requires_python = ">=3.7" summary = "Code coverage measurement for Python" +[[package]] +name = "exceptiongroup" +version = "1.1.1" +requires_python = ">=3.7" +summary = "Backport of PEP 654 (exception groups)" + [[package]] name = "flake8" version = "6.0.0" @@ -269,6 +275,12 @@ dependencies = [ "zipp>=0.5", ] +[[package]] +name = "iniconfig" +version = "2.0.0" +requires_python = ">=3.7" +summary = "brain-dead simple config-ini parsing" + [[package]] name = "itsdangerous" version = "2.1.2" @@ -320,11 +332,6 @@ version = "1.0.0" requires_python = ">=3.5" summary = "Type system extensions for programs checked with the mypy type checker." -[[package]] -name = "nose" -version = "1.3.7" -summary = "nose extends unittest to make testing easier" - [[package]] name = "numpy" version = "1.24.3" @@ -355,6 +362,12 @@ version = "3.5.1" requires_python = ">=3.7" summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +[[package]] +name = "pluggy" +version = "1.0.0" +requires_python = ">=3.6" +summary = "plugin and hook calling mechanisms for python" + [[package]] name = "psycopg2" version = "2.9.6" @@ -379,6 +392,20 @@ version = "3.0.1" requires_python = ">=3.6" summary = "passive checker of Python programs" +[[package]] +name = "pytest" +version = "7.3.1" +requires_python = ">=3.7" +summary = "pytest: simple powerful testing with Python" +dependencies = [ + "colorama; sys_platform == \"win32\"", + "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", + "iniconfig", + "packaging", + "pluggy<2.0,>=0.12", + "tomli>=1.0.0; python_version < \"3.11\"", +] + [[package]] name = "python-dateutil" version = "2.8.2" @@ -573,7 +600,7 @@ dependencies = [ lock_version = "4.2" cross_platform = true groups = ["default", "lint", "test"] -content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f465aed749" +content_hash = "sha256:5ba64926de94b3b5a7fd4204cb4925a0b72a7b364f9bcf7bc89db774f1525d56" [metadata.files] "alembic 1.11.1" = [ @@ -835,6 +862,10 @@ content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f46 {url = "https://files.pythonhosted.org/packages/ef/7a/78d45957963d4a85301ece73cb46352e59dbf17a38d4412542b074cbae87/coverage-7.2.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:828189fcdda99aae0d6bf718ea766b2e715eabc1868670a0a07bf8404bf58c33"}, {url = "https://files.pythonhosted.org/packages/f6/5c/8aec846dd51d4d374ea87689f24b3ee93b023020160141456f51986aac54/coverage-7.2.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d1f25ee9de21a39b3a8516f2c5feb8de248f17da7eead089c2e04aa097936b47"}, ] +"exceptiongroup 1.1.1" = [ + {url = "https://files.pythonhosted.org/packages/61/97/17ed81b7a8d24d8f69b62c0db37abbd8c0042d4b3fc429c73dab986e7483/exceptiongroup-1.1.1-py3-none-any.whl", hash = "sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e"}, + {url = "https://files.pythonhosted.org/packages/cc/38/57f14ddc8e8baeddd8993a36fe57ce7b4ba174c35048b9a6d270bb01e833/exceptiongroup-1.1.1.tar.gz", hash = "sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785"}, +] "flake8 6.0.0" = [ {url = "https://files.pythonhosted.org/packages/66/53/3ad4a3b74d609b3b9008a10075c40e7c8909eae60af53623c3888f7a529a/flake8-6.0.0.tar.gz", hash = "sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181"}, {url = "https://files.pythonhosted.org/packages/d9/6a/bb0122ebe280476c924470779d2595f1403878cafe3c8a343ac56a5a9c0e/flake8-6.0.0-py2.py3-none-any.whl", hash = "sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7"}, @@ -1006,6 +1037,10 @@ content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f46 {url = "https://files.pythonhosted.org/packages/0b/1f/9de392c2b939384e08812ef93adf37684ec170b5b6e7ea302d9f163c2ea0/importlib_metadata-6.6.0.tar.gz", hash = "sha256:92501cdf9cc66ebd3e612f1b4f0c0765dfa42f0fa38ffb319b6bd84dd675d705"}, {url = "https://files.pythonhosted.org/packages/30/bb/bf2944b8b88c65b797acc2c6a2cb0fb817f7364debf0675792e034013858/importlib_metadata-6.6.0-py3-none-any.whl", hash = "sha256:43dd286a2cd8995d5eaef7fee2066340423b818ed3fd70adf0bad5f1fac53fed"}, ] +"iniconfig 2.0.0" = [ + {url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, + {url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, +] "itsdangerous 2.1.2" = [ {url = "https://files.pythonhosted.org/packages/68/5f/447e04e828f47465eeab35b5d408b7ebaaaee207f48b7136c5a7267a30ae/itsdangerous-2.1.2-py3-none-any.whl", hash = "sha256:2c2349112351b88699d8d4b6b075022c0808887cb7ad10069318a8b0bc88db44"}, {url = "https://files.pythonhosted.org/packages/7f/a1/d3fb83e7a61fa0c0d3d08ad0a94ddbeff3731c05212617dff3a94e097f08/itsdangerous-2.1.2.tar.gz", hash = "sha256:5dbbc68b317e5e42f327f9021763545dc3fc3bfe22e6deb96aaf1fc38874156a"}, @@ -1082,11 +1117,6 @@ content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f46 {url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"}, {url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] -"nose 1.3.7" = [ - {url = "https://files.pythonhosted.org/packages/15/d8/dd071918c040f50fa1cf80da16423af51ff8ce4a0f2399b7bf8de45ac3d9/nose-1.3.7-py3-none-any.whl", hash = "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac"}, - {url = "https://files.pythonhosted.org/packages/58/a5/0dc93c3ec33f4e281849523a5a913fa1eea9a3068acfa754d44d88107a44/nose-1.3.7.tar.gz", hash = "sha256:f1bffef9cbc82628f6e7d7b40d7e255aefaa1adb6a1b1d26c69a8b79e6208a98"}, - {url = "https://files.pythonhosted.org/packages/99/4f/13fb671119e65c4dce97c60e67d3fd9e6f7f809f2b307e2611f4701205cb/nose-1.3.7-py2-none-any.whl", hash = "sha256:dadcddc0aefbf99eea214e0f1232b94f2fa9bd98fa8353711dacb112bfcbbb2a"}, -] "numpy 1.24.3" = [ {url = "https://files.pythonhosted.org/packages/0d/43/643629a4a278b4815541c7d69856c07ddb0e99bdc62b43538d3751eae2d8/numpy-1.24.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4719d5aefb5189f50887773699eaf94e7d1e02bf36c1a9d353d9f46703758ca4"}, {url = "https://files.pythonhosted.org/packages/15/b8/cbe1750b9ec78062e5a00ef39ff8bdf189ce753b411b6b35931ababaee47/numpy-1.24.3-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:35400e6a8d102fd07c71ed7dcadd9eb62ee9a6e84ec159bd48c28235bbb0f8e4"}, @@ -1133,6 +1163,10 @@ content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f46 {url = "https://files.pythonhosted.org/packages/89/7e/c6ff9ddcf93b9b36c90d88111c4db354afab7f9a58c7ac3257fa717f1268/platformdirs-3.5.1-py3-none-any.whl", hash = "sha256:e2378146f1964972c03c085bb5662ae80b2b8c06226c54b2ff4aa9483e8a13a5"}, {url = "https://files.pythonhosted.org/packages/9c/0e/ae9ef1049d4b5697e79250c4b2e72796e4152228e67733389868229c92bb/platformdirs-3.5.1.tar.gz", hash = "sha256:412dae91f52a6f84830f39a8078cecd0e866cb72294a5c66808e74d5e88d251f"}, ] +"pluggy 1.0.0" = [ + {url = "https://files.pythonhosted.org/packages/9e/01/f38e2ff29715251cf25532b9082a1589ab7e4f571ced434f98d0139336dc/pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, + {url = "https://files.pythonhosted.org/packages/a1/16/db2d7de3474b6e37cbb9c008965ee63835bba517e22cdb8c35b5116b5ce1/pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, +] "psycopg2 2.9.6" = [ {url = "https://files.pythonhosted.org/packages/2f/e0/f0db22e36faf2b62557ed11e942cc47f3b96d52b686fa838a3ca6b3c90b3/psycopg2-2.9.6-cp38-cp38-win32.whl", hash = "sha256:2362ee4d07ac85ff0ad93e22c693d0f37ff63e28f0615a16b6635a645f4b9214"}, {url = "https://files.pythonhosted.org/packages/49/8e/52252e78c8fd2cc91dae13d2686b103237900fd05f80adc1efc366b40f65/psycopg2-2.9.6-cp39-cp39-win_amd64.whl", hash = "sha256:ded2faa2e6dfb430af7713d87ab4abbfc764d8d7fb73eafe96a24155f906ebf5"}, @@ -1160,6 +1194,10 @@ content_hash = "sha256:f6977f39ba6a7813264fbeec4494860063bbfefcdea936a73a3ba2f46 {url = "https://files.pythonhosted.org/packages/af/4c/b1c7008aa7788b3e26c06c60aa18da7d3aa1f00e344aa3f18ac92768854b/pyflakes-3.0.1-py2.py3-none-any.whl", hash = "sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf"}, {url = "https://files.pythonhosted.org/packages/f2/51/506ddcfab10d708e8460554cc1cf37c727a6a2cccbad8dfe57766cfce33c/pyflakes-3.0.1.tar.gz", hash = "sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd"}, ] +"pytest 7.3.1" = [ + {url = "https://files.pythonhosted.org/packages/1b/d1/72df649a705af1e3a09ffe14b0c7d3be1fd730da6b98beb4a2ed26b8a023/pytest-7.3.1-py3-none-any.whl", hash = "sha256:3799fa815351fea3a5e96ac7e503a96fa51cc9942c3753cda7651b93c1cfa362"}, + {url = "https://files.pythonhosted.org/packages/ec/d9/36b65598f3d19d0a14d13dc87ad5fa42869ae53bb7471f619a30eaabc4bf/pytest-7.3.1.tar.gz", hash = "sha256:434afafd78b1d78ed0addf160ad2b77a30d35d4bdf8af234fe621919d9ed15e3"}, +] "python-dateutil 2.8.2" = [ {url = "https://files.pythonhosted.org/packages/36/7a/87837f39d0296e723bb9b62bbb257d0355c7f6128853c78955f57342a56d/python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, {url = "https://files.pythonhosted.org/packages/4c/c4/13b4776ea2d76c115c1d1b84579f3764ee6d57204f6be27119f13a61d0a9/python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, diff --git a/pyproject.toml b/pyproject.toml index 97394d5e7d..96083fbc35 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,7 +47,7 @@ license = {text = "BSD-2-Clause"} [tool] [tool.pdm.dev-dependencies] -test = ["coverage==7.2.5", "nose==1.3.7"] +test = ["coverage==7.2.5", "pytest==7.3.1"] lint = ["black==23.3.0", "flake8==6.0.0"] [tool.pdm.scripts] diff --git a/requirements.txt b/requirements.txt index b576f9a8f7..014752a3e4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -41,7 +41,7 @@ Werkzeug==2.3.4 black==23.3.0 coverage==7.2.5 flake8==6.0.0 -nose==1.3.7 +pytest==7.3.1 # Indirect, but required dependencies (often required for efficient deployments) gevent==22.10.2 greenlet==2.0.2 @@ -56,6 +56,7 @@ certifi==2023.5.7 charset-normalizer==3.1.0 click==8.1.3 idna==3.4 +iniconfig==2.0.0 Jinja2==3.1.2 Mako==1.2.4 MarkupSafe==2.1.2 @@ -65,15 +66,14 @@ numpy==1.24.3 packaging==23.1 pathspec==0.11.1 platformdirs==3.5.1 +pluggy==1.0.0 pycodestyle==2.10.0 pyflakes==3.0.1 pytz==2023.3 -pytz-deprecation-shim==0.1.0.post0 PyYAML==6.0 six==1.16.0 text-unidecode==1.3 typing_extensions==4.5.0 -tzdata==2023.3 tzlocal==5.0.1 urllib3==1.26.15 webencodings==0.5.1 From 1838590443e97aa33db028b7849f566e23263924 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Thu, 6 Apr 2023 11:13:25 -0600 Subject: [PATCH 03/15] Switch CI from nosetest to pytest Signed-off-by: Taylor Smock --- .circleci/config.yml | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 2540faf1c8..531bf5f6cd 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -87,18 +87,19 @@ jobs: -c "CREATE EXTENSION postgis;" - run: pip install --upgrade pip pdm - run: pdm config --global python.use_venv False - - run: pdm export --prod --without-hashes > requirements.txt + - run: pdm export --dev --without-hashes > requirements.txt - run: pip install -r requirements.txt - run: mkdir --mode 766 -p /tmp/logs - run: mkdir ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results - run: find ./tests/backend -name "test*.py" -exec chmod -x {} \; - run: echo "export TM_LOG_DIR=/tmp/logs" >> $BASH_ENV + - run: coverage erase - run: name: Run backend functional tests command: | - nosetests ./tests/backend --with-xunit \ - --xunit-file ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/unitresults.xml \ - --with-coverage --cover-erase --cover-package=./backend + coverage run --source ./backend -m pytest \ + --rootdir ./tests/backend \ + --junit-xml ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/unitresults.xml - run: coverage xml -o ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/coverage.xml - store_test_results: path: tests/backend/results/unitresults.xml @@ -184,7 +185,7 @@ jobs: - run: cd ${CIRCLE_WORKING_DIRECTORY} - run: pip install --upgrade pip pdm - run: pdm config --global python.use_venv False - - run: pdm export --prod --without-hashes > requirements.txt + - run: pdm export --dev --without-hashes > requirements.txt - run: pip install -r requirements.txt - run: mkdir ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results - run: find ./tests/backend -name "test*.py" -exec chmod -x {} \; @@ -192,9 +193,9 @@ jobs: - run: name: Run backend tests command: | - nosetests ./tests/backend --with-xunit \ - --xunit-file ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/unitresults.xml \ - --with-coverage --cover-erase --cover-package=./backend + coverage run --source ./backend -m pytest \ + --rootdir ./tests/backend \ + --junit-xml ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/unitresults.xml - run: coverage xml -o ${CIRCLE_WORKING_DIRECTORY}/tests/backend/results/coverage.xml - store_test_results: path: tests/backend/results/unitresults.xml From 3d6338919e4be6c9becfb4fec6190642e422114f Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 12:55:38 -0600 Subject: [PATCH 04/15] Add missing __init__.py files to tests Signed-off-by: Taylor Smock --- backend/api/interests/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 backend/api/interests/__init__.py diff --git a/backend/api/interests/__init__.py b/backend/api/interests/__init__.py new file mode 100644 index 0000000000..e69de29bb2 From 689da91113b1e088d852aa2a2cd88bef1eec9f1c Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Tue, 21 Mar 2023 11:08:06 -0600 Subject: [PATCH 05/15] Update python versions used in CI and docker images Signed-off-by: Taylor Smock --- .circleci/config.yml | 14 +++++++------- .dockerignore | 5 ++++- Dockerfile | 2 +- scripts/docker/Dockerfile.backend | 2 +- scripts/docker/tasking-manager/Dockerfile | 4 ++-- 5 files changed, 15 insertions(+), 12 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 531bf5f6cd..7cdf89c196 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,7 +35,7 @@ jobs: backend-code-check-PEP8: docker: - - image: cimg/python:3.9 + - image: cimg/python:3.10 steps: - checkout - setup_remote_docker @@ -47,7 +47,7 @@ jobs: backend-code-check-Black: docker: - - image: cimg/python:3.9 + - image: cimg/python:3.10 steps: - checkout - setup_remote_docker @@ -61,7 +61,7 @@ jobs: resource_class: large docker: - - image: cimg/python:3.9 + - image: cimg/python:3.10 environment: SQLALCHEMY_DATABASE_URI: postgresql://taskingmanager@localhost/test_tm POSTGRES_TEST_DB: test_tm @@ -162,10 +162,10 @@ jobs: build: working_directory: /home/circleci/app docker: - - image: cimg/python:3.9.14-node + - image: cimg/python:3.10.7-node environment: SQLALCHEMY_DATABASE_URI: postgresql://taskingmanager@localhost/test_tm - - image: cimg/postgres:14.2-postgis + - image: cimg/postgres:14.7-postgis environment: POSTGRES_USER: taskingmanager POSTGRES_DB: test_tm @@ -235,7 +235,7 @@ jobs: working_directory: /home/circleci/tasking-manager resource_class: medium docker: - - image: cimg/python:3.9.14-node + - image: cimg/python:3.10.7-node steps: - checkout - setup_remote_docker @@ -272,7 +272,7 @@ jobs: working_directory: /home/circleci/tasking-manager resource_class: large docker: - - image: cimg/python:3.9.14-node + - image: cimg/python:3.10.7-node parameters: stack_name: description: "the name of the stack for cfn-config" diff --git a/.dockerignore b/.dockerignore index 4776b8538f..8155369a49 100644 --- a/.dockerignore +++ b/.dockerignore @@ -4,5 +4,8 @@ **/__pypackages__ **/node_modules **/npm-debug.log -logs/ +**/venv +docs-old/ docs/ +frontend/ +logs/ diff --git a/Dockerfile b/Dockerfile index b225df4227..e8acc0763a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ ARG ALPINE_IMG_TAG=3.17 -ARG PYTHON_IMG_TAG=3.9 +ARG PYTHON_IMG_TAG=3.10 FROM docker.io/python:${PYTHON_IMG_TAG}-alpine${ALPINE_IMG_TAG} as base ARG APP_VERSION=0.1.0 diff --git a/scripts/docker/Dockerfile.backend b/scripts/docker/Dockerfile.backend index b225df4227..e8acc0763a 100644 --- a/scripts/docker/Dockerfile.backend +++ b/scripts/docker/Dockerfile.backend @@ -1,5 +1,5 @@ ARG ALPINE_IMG_TAG=3.17 -ARG PYTHON_IMG_TAG=3.9 +ARG PYTHON_IMG_TAG=3.10 FROM docker.io/python:${PYTHON_IMG_TAG}-alpine${ALPINE_IMG_TAG} as base ARG APP_VERSION=0.1.0 diff --git a/scripts/docker/tasking-manager/Dockerfile b/scripts/docker/tasking-manager/Dockerfile index 8d996fdda2..9424962b4c 100644 --- a/scripts/docker/tasking-manager/Dockerfile +++ b/scripts/docker/tasking-manager/Dockerfile @@ -1,5 +1,5 @@ -ARG PYTHON_IMG_TAG=3.9 -FROM python:${PYTHON_IMG_TAG}-buster +ARG PYTHON_IMG_TAG=3.10 +FROM python:${PYTHON_IMG_TAG}-bullseye RUN mkdir -p /usr/src/app WORKDIR /usr/src/app From ffea683d40c9706a0eacd191acf6d16e0bed8034 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Thu, 11 May 2023 06:55:43 -0600 Subject: [PATCH 06/15] Fix gevent warning when run with gunicorn --- backend/__init__.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/backend/__init__.py b/backend/__init__.py index aa3295566a..c4ab6fd007 100644 --- a/backend/__init__.py +++ b/backend/__init__.py @@ -1,4 +1,18 @@ import logging + +# gevent.monkey.patch_ssl is required. gevent message as follows: +# MonkeyPatchWarning: Monkey-patching ssl after ssl has already been imported may +# lead to errors, including RecursionError on Python 3.6. It may also silently +# lead to incorrect behaviour on Python 3.7. Please monkey-patch earlier. +# See https://github.com/gevent/gevent/issues/1016. +try: + from gevent import monkey + + monkey.patch_ssl() +except ImportError as e: + logging.warning("Not using gevent") + logging.info(e) + import os from logging.handlers import RotatingFileHandler From c869ffcfbb2cb00d99ddd902a9514b362ad69be4 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Tue, 21 Mar 2023 12:12:18 -0600 Subject: [PATCH 07/15] migrations: Make compatible with SQLAlchemy 2.x The primary change required was wrapping direct SQL commands with sqlalchemy.text (written as "sa.text"). Most of these could be converted to be not be written as direct SQL commands. Signed-off-by: Taylor Smock --- migrations/alembic.ini | 1 + migrations/env.py | 17 +++++- migrations/versions/0a6b82b55983_.py | 4 +- migrations/versions/0eee8c1abd3a_.py | 5 +- migrations/versions/14340f1e0d6b_.py | 77 ++++++++++++++++++---------- migrations/versions/42c45e74752b_.py | 62 ++++++++++++++++++++++ migrations/versions/4ed992117718_.py | 4 +- migrations/versions/7937dae319b5_.py | 5 +- migrations/versions/7bbc01082457_.py | 74 ++++++++++++++++---------- migrations/versions/7d55a089b5bc_.py | 6 +-- migrations/versions/84c793a951b2_.py | 6 +-- migrations/versions/a43b9748ceee_.py | 9 ++-- migrations/versions/bfcf4182dcb5_.py | 2 +- migrations/versions/c40e1fdf6b70_.py | 19 ++++--- migrations/versions/deec8123583d_.py | 7 +-- migrations/versions/f86698c827cc_.py | 47 +++++++++++------ 16 files changed, 243 insertions(+), 102 deletions(-) create mode 100644 migrations/versions/42c45e74752b_.py diff --git a/migrations/alembic.ini b/migrations/alembic.ini index c036ff3eaf..59e0ae6bf6 100644 --- a/migrations/alembic.ini +++ b/migrations/alembic.ini @@ -12,6 +12,7 @@ script_location = /src/migrations # Custom param that enables us to specify tables to ignore when determining migrations [alembic:exclude] tables = spatial_ref_sys +index = idx_username_lower # Logging configuration [loggers] diff --git a/migrations/env.py b/migrations/env.py index 26d4b46068..9a62c50755 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -1,6 +1,7 @@ from __future__ import with_statement from alembic import context from sqlalchemy import engine_from_config, pool +from geoalchemy2 import alembic_helpers from logging.config import fileConfig from flask import current_app import logging @@ -29,6 +30,7 @@ # my_important_option = config.get_main_option("my_important_option") # ... etc. exclude_tables = config.get_section("alembic:exclude").get("tables", "").split(",") +exclude_index = config.get_section("alembic:exclude").get("index", "").split(",") def include_object(object, name, type_, reflected, compare_to): @@ -37,8 +39,12 @@ def include_object(object, name, type_, reflected, compare_to): """ if type_ == "table" and name in exclude_tables: return False + elif type_ == "index" and name in exclude_index: + return False else: - return True + return alembic_helpers.include_object( + object, name, type_, reflected, compare_to + ) def run_migrations_offline(): @@ -54,7 +60,12 @@ def run_migrations_offline(): """ url = config.get_main_option("sqlalchemy.url") - context.configure(url=url, include_object=include_object) + context.configure( + url=url, + include_object=include_object, + process_revision_directives=alembic_helpers.writer, + render_item=alembic_helpers.render_item, + ) with context.begin_transaction(): context.run_migrations() @@ -72,6 +83,7 @@ def run_migrations_online(): # when there are no changes to the schema # reference: http://alembic.readthedocs.org/en/latest/cookbook.html def process_revision_directives(context, revision, directives): + alembic_helpers.writer(context, revision, directives) if getattr(config.cmd_opts, "autogenerate", False): script = directives[0] if script.upgrade_ops.is_empty(): @@ -90,6 +102,7 @@ def process_revision_directives(context, revision, directives): target_metadata=target_metadata, process_revision_directives=process_revision_directives, include_object=include_object, + render_item=alembic_helpers.render_item, **current_app.extensions["migrate"].configure_args, ) diff --git a/migrations/versions/0a6b82b55983_.py b/migrations/versions/0a6b82b55983_.py index 15695db461..1b2a22790d 100644 --- a/migrations/versions/0a6b82b55983_.py +++ b/migrations/versions/0a6b82b55983_.py @@ -47,7 +47,7 @@ def upgrade(): project_existence = {} # Attempt to classify existing messages - messages = conn.execute("select * from messages") + messages = conn.execute(sa.text("select * from messages")) for message in messages: message_type = None project_id = None @@ -85,7 +85,7 @@ def upgrade(): # If we haven't checked yet if this project exists, check now and cache result if project_id not in project_existence: project = conn.execute( - "select * from projects where id = " + str(project_id) + sa.text("select * from projects where id = " + str(project_id)) ).first() project_existence[project_id] = project is not None diff --git a/migrations/versions/0eee8c1abd3a_.py b/migrations/versions/0eee8c1abd3a_.py index f07ecb96f0..d71c5c5f12 100644 --- a/migrations/versions/0eee8c1abd3a_.py +++ b/migrations/versions/0eee8c1abd3a_.py @@ -27,7 +27,7 @@ def upgrade(): op.add_column("projects", sa.Column("country", ARRAY(sa.String()), nullable=True)) - fetch_all_project_geoms = ( + fetch_all_project_geoms = sa.text( "SELECT id, ST_AsText(ST_GeomFromWKB(ST_AsEWKB(centroid))) from projects;" ) projects = conn.execute(fetch_all_project_geoms) @@ -51,6 +51,9 @@ def upgrade(): print("Geometry Exception: Project " + str(project_id) + " " + str(e)) continue + if not project_centroid: + continue + if not project_centroid.is_valid: project_centroid = project_centroid.buffer(0) diff --git a/migrations/versions/14340f1e0d6b_.py b/migrations/versions/14340f1e0d6b_.py index 13ffde5a7a..79ebc84ecb 100644 --- a/migrations/versions/14340f1e0d6b_.py +++ b/migrations/versions/14340f1e0d6b_.py @@ -6,6 +6,7 @@ """ from alembic import op +import sqlalchemy as sa # revision identifiers, used by Alembic. revision = "14340f1e0d6b" @@ -20,9 +21,11 @@ def upgrade(): tm3_pm_team = "TM3-project-managers" conn = op.get_bind() # Create an undefined organisation - conn.execute("insert into organisations (name) values('" + tm3_org_name + "');") + conn.execute( + sa.text("insert into organisations (name) values('" + tm3_org_name + "');") + ) fetch_org_id = "select * from organisations where name = '" + tm3_org_name + "';" - org_id = [r[0] for r in conn.execute(fetch_org_id)][0] + org_id = [r[0] for r in conn.execute(sa.text(fetch_org_id))][0] # Create two new teams associated to `undefined` organisation create_validator_team = ( @@ -32,9 +35,10 @@ def upgrade(): + tm3_validator_team + "');" ) - conn.execute(create_validator_team) + conn.execute(sa.text(create_validator_team)) validator_team_id = [ - r[0] for r in conn.execute("select id from teams order by id desc limit 1;") + r[0] + for r in conn.execute(sa.text("select id from teams order by id desc limit 1;")) ][0] create_pm_team = ( "insert into teams (visibility,invite_only,organisation_id,name) values (1,true," @@ -43,14 +47,15 @@ def upgrade(): + tm3_pm_team + "');" ) - conn.execute(create_pm_team) + conn.execute(sa.text(create_pm_team)) project_manager_team_id = [ - r[0] for r in conn.execute("select id from teams order by id desc limit 1;") + r[0] + for r in conn.execute(sa.text("select id from teams order by id desc limit 1;")) ][0] # Fetch all TM3 users who are validators; role = 4 # Add them as members to the new team created for validators - existing_validators = conn.execute("select id from users where role = 4;") + existing_validators = conn.execute(sa.text("select id from users where role = 4;")) for validator in existing_validators: validator_user_id = validator[0] # team function = 2(member) backend/models/postgis/statuses.py/TeamMemberFunctions @@ -61,14 +66,14 @@ def upgrade(): + str(validator_user_id) + ");" ) - conn.execute(update_validator_team) + conn.execute(sa.text(update_validator_team)) # Fetch all TM3 projects that has validation_permission = 2(TEAMS) or 3(TEAMS_LEVEL) # Refer to backend/models/postgis/statuses.py/ValidationPermission # Map the validator team to these projects with validator role # This is applicable only for legacy TM3 projects for easy transition existing_projects = conn.execute( - "select id from projects where validation_permission in (2,3)" + sa.text("select id from projects where validation_permission in (2,3)") ) for project in existing_projects: project_id = project[0] @@ -80,12 +85,12 @@ def upgrade(): + str(project_id) + ");" ) - conn.execute(update_project_team) + conn.execute(sa.text(update_project_team)) # Fetch all users who are project managers; role = 2 # Add them as members to the new team created for project managers # This team is only to store legacy information and is not used anywhere internally - existing_pms = conn.execute("select id from users where role = 2;") + existing_pms = conn.execute(sa.text("select id from users where role = 2;")) for project_manager in existing_pms: pm_user_id = project_manager[0] # team function = 2(member) backend/models/postgis/statuses.py/TeamMemberFunctions @@ -96,10 +101,10 @@ def upgrade(): + str(pm_user_id) + ");" ) - conn.execute(update_pm_team) + conn.execute(sa.text(update_pm_team)) # Set all users role = 0 (mapper) - conn.execute("update users set role = 0 where role in (2,4);") + conn.execute(sa.text("update users set role = 0 where role in (2,4);")) def downgrade(): @@ -112,44 +117,60 @@ def downgrade(): validator_team_id = [ r[0] for r in conn.execute( - "select id from teams where name = '" + tm3_validator_team + "';" + sa.text("select id from teams where name = '" + tm3_validator_team + "';") ) ][0] pm_team_id = [ r[0] for r in conn.execute( - "select id from teams where name = '" + tm3_pm_team + "';" + sa.text("select id from teams where name = '" + tm3_pm_team + "';") ) ][0] # Disassociate all projects from the team - conn.execute("delete from project_teams where team_id=" + str(validator_team_id)) + conn.execute( + sa.text("delete from project_teams where team_id=" + str(validator_team_id)) + ) # Get all the users in the undefined-validators # Set role = 4 in users for all the selected users validators = conn.execute( - "select user_id from team_members where team_id=" + str(validator_team_id) + ";" + sa.text( + "select user_id from team_members where team_id=" + + str(validator_team_id) + + ";" + ) ) for validator in validators: - conn.execute("update users set role = 4 where id=" + str(validator[0]) + ";") + conn.execute( + sa.text("update users set role = 4 where id=" + str(validator[0]) + ";") + ) # Get all the users in the undefined-pms # Set role = 2 in users for all the selected users pms = conn.execute( - "select user_id from team_members where team_id=" + str(pm_team_id) + ";" + sa.text( + "select user_id from team_members where team_id=" + str(pm_team_id) + ";" + ) ) for pm in pms: - conn.execute("update users set role = 2 where id=" + str(pm[0]) + ";") + conn.execute(sa.text("update users set role = 2 where id=" + str(pm[0]) + ";")) # Remove all users from both the teams conn.execute( - "delete from team_members where team_id in (" - + str(validator_team_id) - + "," - + str(pm_team_id) - + ");" + sa.text( + "delete from team_members where team_id in (" + + str(validator_team_id) + + "," + + str(pm_team_id) + + ");" + ) ) # Delete the teams and organisation - conn.execute("delete from teams where name = '" + tm3_validator_team + "';") - conn.execute("delete from teams where name = '" + tm3_pm_team + "';") - conn.execute("delete from organisations where name = '" + tm3_org_name + "';") + conn.execute( + sa.text("delete from teams where name = '" + tm3_validator_team + "';") + ) + conn.execute(sa.text("delete from teams where name = '" + tm3_pm_team + "';")) + conn.execute( + sa.text("delete from organisations where name = '" + tm3_org_name + "';") + ) diff --git a/migrations/versions/42c45e74752b_.py b/migrations/versions/42c45e74752b_.py new file mode 100644 index 0000000000..155f8e73b4 --- /dev/null +++ b/migrations/versions/42c45e74752b_.py @@ -0,0 +1,62 @@ +"""empty message + +Revision ID: 42c45e74752b +Revises: a9cbd2c6c213 +Create Date: 2023-03-29 09:07:55.771834 + +""" +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision = "42c45e74752b" +down_revision = "a9cbd2c6c213" +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("application_keys", schema=None) as batch_op: + batch_op.alter_column("id", existing_type=sa.INTEGER(), type_=sa.BigInteger()) + + with op.batch_alter_table("priority_areas", schema=None) as batch_op: + batch_op.create_geospatial_index( + "idx_priority_areas_geometry", + ["geometry"], + unique=False, + postgresql_using="gist", + postgresql_ops={}, + ) + + with op.batch_alter_table("tasks", schema=None) as batch_op: + batch_op.create_geospatial_index( + "idx_tasks_geometry", + ["geometry"], + unique=False, + postgresql_using="gist", + postgresql_ops={}, + ) + + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + with op.batch_alter_table("tasks", schema=None) as batch_op: + batch_op.drop_geospatial_index( + "idx_tasks_geometry", postgresql_using="gist", column_name="geometry" + ) + + with op.batch_alter_table("priority_areas", schema=None) as batch_op: + batch_op.drop_geospatial_index( + "idx_priority_areas_geometry", + postgresql_using="gist", + column_name="geometry", + ) + + with op.batch_alter_table("application_keys", schema=None) as batch_op: + batch_op.alter_column("id", existing_type=sa.BigInteger(), type_=sa.INTEGER()) + + # ### end Alembic commands ### diff --git a/migrations/versions/4ed992117718_.py b/migrations/versions/4ed992117718_.py index 63951fed53..b4fef308a3 100644 --- a/migrations/versions/4ed992117718_.py +++ b/migrations/versions/4ed992117718_.py @@ -42,8 +42,8 @@ def downgrade(): sa.Column("invite_only", sa.BOOLEAN(), autoincrement=False, nullable=True), ) op.execute( - f"UPDATE teams SET invite_only = true WHERE join_method = {TeamJoinMethod.BY_REQUEST.value}" - f"UPDATE teams SET invite_only = false WHERE join_method != {TeamJoinMethod.BY_REQUEST.value}" + f"UPDATE teams SET invite_only = true WHERE join_method = {TeamJoinMethod.BY_REQUEST.value};" + f"UPDATE teams SET invite_only = false WHERE join_method != {TeamJoinMethod.BY_REQUEST.value};" ) op.alter_column("teams", "invite_only", nullable=False) op.drop_column("teams", "join_method") diff --git a/migrations/versions/7937dae319b5_.py b/migrations/versions/7937dae319b5_.py index 02e3c20069..91704f216a 100644 --- a/migrations/versions/7937dae319b5_.py +++ b/migrations/versions/7937dae319b5_.py @@ -6,6 +6,7 @@ """ from alembic import op +import sqlalchemy as sa import requests @@ -24,7 +25,7 @@ def upgrade(): fetch_countries = ( "select distinct(unnest(country)) from projects where country is not null;" ) - countries = conn.execute(fetch_countries) + countries = conn.execute(sa.text(fetch_countries)) for country in countries: country = country[0] # search by name @@ -40,7 +41,7 @@ def upgrade(): + "']::varchar[]" + ";" ) - conn.execute(update_project) + conn.execute(sa.text(update_project)) def downgrade(): diff --git a/migrations/versions/7bbc01082457_.py b/migrations/versions/7bbc01082457_.py index d0ac828a91..33db25d568 100644 --- a/migrations/versions/7bbc01082457_.py +++ b/migrations/versions/7bbc01082457_.py @@ -178,7 +178,9 @@ def upgrade(): print("Populating organisation information for Projects....") # Select all existing distinct organisation tags from projects table org_tags = conn.execute( - "select distinct(organisation_tag) from projects where organisation_tag is not null" + sa.text( + "select distinct(organisation_tag) from projects where organisation_tag is not null" + ) ) total_orgs = org_tags.rowcount print("Total distinct organisations in the DB: " + str(total_orgs)) @@ -198,7 +200,7 @@ def upgrade(): mapped_org = mapped_org[:quote_index] + "'" + mapped_org[quote_index:] select_org_id = conn.execute( - "select id from organisations where name ='" + mapped_org + "'" + sa.text("select id from organisations where name ='" + mapped_org + "'") ).scalar() # Create new organisation only if it has not been inserted earlier @@ -208,11 +210,15 @@ def upgrade(): and (mapped_org not in orgs_inserted) ): conn.execute( - "insert into organisations (name) values ('" + mapped_org + "')" + sa.text( + "insert into organisations (name) values ('" + mapped_org + "')" + ) ) # Fetch organisation ID after the insert select_org_id = conn.execute( - "select id from organisations where name ='" + mapped_org + "'" + sa.text( + "select id from organisations where name ='" + mapped_org + "'" + ) ).scalar() org_id = str(select_org_id) @@ -227,31 +233,37 @@ def upgrade(): # Update organisation ID conn.execute( - "update projects set organisation_id=" - + org_id - + " where organisation_tag='" - + original_org_name - + "'" + sa.text( + "update projects set organisation_id=" + + org_id + + " where organisation_tag='" + + original_org_name + + "'" + ) ) # Identify projects related to the org name fetch_first_author_id = conn.execute( - "select author_id from projects where organisation_tag='" - + original_org_name - + "' limit 1" + sa.text( + "select author_id from projects where organisation_tag='" + + original_org_name + + "' limit 1" + ) ).scalar() org_manager = str(fetch_first_author_id) if mapped_org not in orgs_inserted: org_managers[mapped_org] = org_manager conn.execute( - "insert into organisation_managers \ + sa.text( + "insert into organisation_managers \ (organisation_id,user_id) \ values(" - + org_id - + "," - + org_manager - + ")" + + org_id + + "," + + org_manager + + ")" + ) ) print( str(count) @@ -273,22 +285,28 @@ def downgrade(): conn = op.get_bind() op.add_column("projects", sa.Column("organisation_tag", sa.String(), nullable=True)) # Remove all mappings made - org_ids = conn.execute("select id, name from organisations") + org_ids = conn.execute(sa.text("select id, name from organisations")) for org_id, org_name in org_ids: quote_index = org_name.find("'") if quote_index > -1: org_name = org_name[:quote_index] + "'" + org_name[quote_index:] conn.execute( - "update projects set organisation_tag='" - + str(org_name) - + "' where organisation_id=" - + str(org_id) + sa.text( + "update projects set organisation_tag='" + + str(org_name) + + "' where organisation_id=" + + str(org_id) + ) ) - conn.execute("delete from project_teams where team_id is not null") - conn.execute("delete from team_members where team_id is not null") - conn.execute("delete from teams where organisation_id is not null") - conn.execute("delete from organisation_managers where organisation_id is not null") + conn.execute(sa.text("delete from project_teams where team_id is not null")) + conn.execute(sa.text("delete from team_members where team_id is not null")) + conn.execute(sa.text("delete from teams where organisation_id is not null")) conn.execute( - "update projects set organisation_id = null where organisation_id is not null" + sa.text("delete from organisation_managers where organisation_id is not null") + ) + conn.execute( + sa.text( + "update projects set organisation_id = null where organisation_id is not null" + ) ) - conn.execute("delete from organisations where name is not null") + conn.execute(sa.text("delete from organisations where name is not null")) diff --git a/migrations/versions/7d55a089b5bc_.py b/migrations/versions/7d55a089b5bc_.py index de62c80d29..f2699e1e2e 100644 --- a/migrations/versions/7d55a089b5bc_.py +++ b/migrations/versions/7d55a089b5bc_.py @@ -30,17 +30,17 @@ def upgrade(): # Content migration: Check the amount of zoom levels in tasks of a project and set # task_creation_mode to 1 or 0 accordingly. - projects = conn.execute("select * from projects") + projects = conn.execute(sa.text("select * from projects")) for project in projects: query = "select distinct zoom from tasks where project_id = " + str(project.id) - zooms = conn.execute(query).fetchall() + zooms = conn.execute(sa.text(query)).fetchall() if len(zooms) == 1 and zooms[0] == (None,): query = "update projects set task_creation_mode = 1 where id = " + str( project.id ) - op.execute(query) + op.execute(sa.text(query)) def downgrade(): diff --git a/migrations/versions/84c793a951b2_.py b/migrations/versions/84c793a951b2_.py index a20382f590..8ee3aaa577 100644 --- a/migrations/versions/84c793a951b2_.py +++ b/migrations/versions/84c793a951b2_.py @@ -32,10 +32,10 @@ def upgrade(): "idx_notifications_user_id", "notifications", ["user_id"], unique=False ) fetch_all_users = "select id from users;" - all_users = conn.execute(fetch_all_users) + all_users = conn.execute(sa.text(fetch_all_users)) for user in all_users: user_id = user[0] - insert_user_info = ( + insert_user_info = sa.text( "insert into notifications (user_id,unread_count,date) values (" + str(user_id) + "," @@ -47,7 +47,7 @@ def upgrade(): op.execute(insert_user_info) fetch_all_unread_counts = "select to_user_id, count(*) from messages where read = false group by to_user_id;" - unread_counts = conn.execute(fetch_all_unread_counts) + unread_counts = conn.execute(sa.text(fetch_all_unread_counts)) for unread_count in unread_counts: user_id = unread_count[0] user_unread_count = unread_count[1] diff --git a/migrations/versions/a43b9748ceee_.py b/migrations/versions/a43b9748ceee_.py index 9538fd894b..010d5f621e 100644 --- a/migrations/versions/a43b9748ceee_.py +++ b/migrations/versions/a43b9748ceee_.py @@ -6,6 +6,7 @@ """ from alembic import op +import sqlalchemy as sa from backend.models.postgis.statuses import TaskStatus @@ -32,7 +33,7 @@ def upgrade(): # Recalculate tasks stats based on the task states in projects conn = op.get_bind() - projects = conn.execute("select id from projects") + projects = conn.execute(sa.text("select id from projects")) print("Recalculating projects' tasks stats... can take a bit") for project_id in projects: _set_project_counters_from_task_states(project_id[0]) @@ -43,8 +44,10 @@ def _set_project_counters_from_task_states(project_id: int): conn = op.get_bind() tasks_statuses = conn.execute( - "SELECT task_status, count(task_status) FROM tasks WHERE project_id={0} GROUP BY task_status" - "".format(project_id) + sa.text( + "SELECT task_status, count(task_status) FROM tasks WHERE project_id={0} GROUP BY task_status" + "".format(project_id) + ) ) tasks_statuses = [r for r in tasks_statuses] diff --git a/migrations/versions/bfcf4182dcb5_.py b/migrations/versions/bfcf4182dcb5_.py index b3af370bd7..63f34b5ae2 100644 --- a/migrations/versions/bfcf4182dcb5_.py +++ b/migrations/versions/bfcf4182dcb5_.py @@ -24,7 +24,7 @@ def upgrade(): op.add_column( "organisations", sa.Column("slug", sa.String(length=255), nullable=True) ) - orgs = conn.execute("select name from organisations;") + orgs = conn.execute(sa.text("select name from organisations;")) for org in orgs: name = handle_special_chars(org[0]) query = ( diff --git a/migrations/versions/c40e1fdf6b70_.py b/migrations/versions/c40e1fdf6b70_.py index f467478555..93d64de31e 100644 --- a/migrations/versions/c40e1fdf6b70_.py +++ b/migrations/versions/c40e1fdf6b70_.py @@ -6,6 +6,7 @@ """ from alembic import op +import sqlalchemy as sa # revision identifiers, used by Alembic. revision = "c40e1fdf6b70" @@ -41,11 +42,11 @@ def determine_validation_permission(self, val, reverse=False): def upgrade(): conn = op.get_bind() - conn.execute("ALTER TABLE projects ADD mapping_permission Integer;") - conn.execute("ALTER TABLE projects ADD validation_permission Integer;") + conn.execute(sa.text("ALTER TABLE projects ADD mapping_permission Integer;")) + conn.execute(sa.text("ALTER TABLE projects ADD validation_permission Integer;")) fetch_all_projects = "select id, restrict_mapping_level_to_project, \ restrict_validation_role, restrict_validation_level_intermediate from projects;" - all_projects = conn.execute(fetch_all_projects) + all_projects = conn.execute(sa.text(fetch_all_projects)) for project in all_projects: mapping_permission = None validation_permission = None @@ -80,15 +81,19 @@ def upgrade(): def downgrade(): conn = op.get_bind() - conn.execute("ALTER TABLE projects ADD restrict_mapping_level_to_project boolean;") - conn.execute("ALTER TABLE projects ADD restrict_validation_role boolean;") conn.execute( - "ALTER TABLE projects ADD restrict_validation_level_intermediate boolean;" + sa.text("ALTER TABLE projects ADD restrict_mapping_level_to_project boolean;") + ) + conn.execute(sa.text("ALTER TABLE projects ADD restrict_validation_role boolean;")) + conn.execute( + sa.text( + "ALTER TABLE projects ADD restrict_validation_level_intermediate boolean;" + ) ) fetch_all_projects = ( "select id, mapping_permission, validation_permission from projects;" ) - all_projects = conn.execute(fetch_all_projects) + all_projects = conn.execute(sa.text(fetch_all_projects)) for project in all_projects: project_id = project[0] mapping_permission = project[1] diff --git a/migrations/versions/deec8123583d_.py b/migrations/versions/deec8123583d_.py index dfed4b0ab8..36d5ebfa56 100644 --- a/migrations/versions/deec8123583d_.py +++ b/migrations/versions/deec8123583d_.py @@ -6,6 +6,7 @@ """ from alembic import op +import sqlalchemy as sa # revision identifiers, used by Alembic. @@ -18,7 +19,7 @@ def upgrade(): conn = op.get_bind() - projects = conn.execute("select * from projects") + projects = conn.execute(sa.text("select * from projects")) # Content migration: Check the amount of zoom levels in tasks of a project and set # task_creation_mode to 1 or 0 accordingly. @@ -26,7 +27,7 @@ def upgrade(): select_query = "select distinct zoom from tasks where project_id = " + str( project.id ) - zooms = conn.execute(select_query) + zooms = conn.execute(sa.text(select_query)) zooms = zooms.fetchall() if len(zooms) == 1 and zooms[0] == (None,): @@ -40,7 +41,7 @@ def upgrade(): + str(project.id) ) - op.execute(update_query) + op.execute(sa.text(update_query)) def downgrade(): diff --git a/migrations/versions/f86698c827cc_.py b/migrations/versions/f86698c827cc_.py index 9c45bb6d9c..8ae21cfd1c 100644 --- a/migrations/versions/f86698c827cc_.py +++ b/migrations/versions/f86698c827cc_.py @@ -19,7 +19,7 @@ def upgrade(): conn = op.get_bind() campaign_tags = conn.execute( - "select distinct(campaigns) from tags where campaigns is not null" + sa.text("select distinct(campaigns) from tags where campaigns is not null") ) total_campaigns = campaign_tags.rowcount @@ -36,11 +36,13 @@ def upgrade(): for project_id in projects: project_id = project_id[0] conn.execute( - "insert into campaign_projects (campaign_id, project_id) values (" - + str(new_campaign_id) - + "," - + str(project_id) - + ")" + sa.text( + "insert into campaign_projects (campaign_id, project_id) values (" + + str(new_campaign_id) + + "," + + str(project_id) + + ")" + ) ) op.drop_table("tags") op.drop_index("ix_projects_campaign_tag", table_name="projects") @@ -65,25 +67,36 @@ def downgrade(): sa.UniqueConstraint("campaigns", name="tags_campaigns_key"), sa.UniqueConstraint("organisations", name="tags_organisations_key"), ) - campaigns = conn.execute("select id, name from campaigns") + campaigns = conn.execute(sa.text("select id, name from campaigns")) for campaign_id, campaign_tag in campaigns: - conn.execute("insert into tags (campaigns) values ('" + campaign_tag + "')") + conn.execute( + sa.text("insert into tags (campaigns) values ('" + campaign_tag + "')") + ) projects = conn.execute( - "select project_id from campaign_projects where campaign_id=" - + str(campaign_id) + sa.text( + "select project_id from campaign_projects where campaign_id=" + + str(campaign_id) + ) ) for project in projects: project_id = project[0] conn.execute( - "update projects set campaign_tag='" - + campaign_tag - + "' where id=" - + str(project_id) + sa.text( + "update projects set campaign_tag='" + + campaign_tag + + "' where id=" + + str(project_id) + ) ) conn.execute( - "delete from campaign_organisations where campaign_id=" + str(campaign_id) + sa.text( + "delete from campaign_organisations where campaign_id=" + + str(campaign_id) + ) ) conn.execute( - "delete from campaign_projects where campaign_id=" + str(campaign_id) + sa.text( + "delete from campaign_projects where campaign_id=" + str(campaign_id) + ) ) - conn.execute("delete from campaigns where id=" + str(campaign_id)) + conn.execute(sa.text("delete from campaigns where id=" + str(campaign_id))) From d623323362d410ffe686157daae14b4b53bfb2b1 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 12:44:44 -0600 Subject: [PATCH 08/15] Update flask calls --- backend/api/projects/resources.py | 6 +++--- backend/api/tasks/resources.py | 6 +++--- backend/services/messaging/message_service.py | 12 ++++-------- tests/backend/base.py | 14 ++++++++++---- 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/backend/api/projects/resources.py b/backend/api/projects/resources.py index 4f9de90c94..00bb4e97f0 100644 --- a/backend/api/projects/resources.py +++ b/backend/api/projects/resources.py @@ -106,7 +106,7 @@ def get(self, project_id): io.BytesIO(geojson.dumps(project_dto).encode("utf-8")), mimetype="application/json", as_attachment=True, - attachment_filename=f"project_{str(project_id)}.json", + download_name=f"project_{str(project_id)}.json", ) return project_dto, 200 @@ -1032,7 +1032,7 @@ def get(self, project_id): io.BytesIO(geojson.dumps(project_dto).encode("utf-8")), mimetype="application/json", as_attachment=True, - attachment_filename=f"project_{str(project_id)}.json", + download_name=f"project_{str(project_id)}.json", ) return project_dto, 200 @@ -1154,7 +1154,7 @@ def get(self, project_id): io.BytesIO(geojson.dumps(project_aoi).encode("utf-8")), mimetype="application/json", as_attachment=True, - attachment_filename=f"{str(project_id)}.geojson", + download_name=f"{str(project_id)}.geojson", ) return project_aoi, 200 diff --git a/backend/api/tasks/resources.py b/backend/api/tasks/resources.py index 8a37634deb..0fda4b8f56 100644 --- a/backend/api/tasks/resources.py +++ b/backend/api/tasks/resources.py @@ -122,7 +122,7 @@ def get(self, project_id): io.BytesIO(tasks_json), mimetype="application/json", as_attachment=True, - attachment_filename=f"{str(project_id)}-tasks.geojson", + download_name=f"{str(project_id)}-tasks.geojson", ) return tasks_json, 200 @@ -268,7 +268,7 @@ def get(self, project_id): io.BytesIO(xml), mimetype="text.xml", as_attachment=True, - attachment_filename=f"HOT-project-{project_id}.osm", + download_name=f"HOT-project-{project_id}.osm", ) return Response(xml, mimetype="text/xml", status=200) @@ -341,7 +341,7 @@ def get(self, project_id): io.BytesIO(xml), mimetype="text.xml", as_attachment=True, - attachment_filename=f"HOT-project-{project_id}.gpx", + download_name=f"HOT-project-{project_id}.gpx", ) return Response(xml, mimetype="text/xml", status=200) diff --git a/backend/services/messaging/message_service.py b/backend/services/messaging/message_service.py index aa166fb782..e0f2d3de53 100644 --- a/backend/services/messaging/message_service.py +++ b/backend/services/messaging/message_service.py @@ -8,7 +8,7 @@ from sqlalchemy import text, func from markdown import markdown -from backend import create_app, db +from backend import db from backend.models.dtos.message_dto import MessageDTO, MessagesDTO from backend.models.dtos.stats_dto import Pagination from backend.models.postgis.message import Message, MessageType, NotFound @@ -122,9 +122,7 @@ def send_message_to_all_contributors(project_id: int, message_dto: MessageDTO): over a minute to run, so this method is expected to be called on its own thread """ - app = ( - create_app() - ) # Because message-all run on background thread it needs it's own app context + app = current_app # Because message-all run on background thread it needs it's own app context with app.app_context(): contributors = Message.get_all_contributors(project_id) @@ -318,9 +316,7 @@ def send_project_transfer_message( transferred_by: str, ): """Will send a message to the manager of the organization after a project is transferred""" - app = ( - create_app() - ) # Because message-all run on background thread it needs it's own app context + app = current_app # Because message-all run on background thread it needs it's own app context with app.app_context(): project = Project.get(project_id) @@ -466,7 +462,7 @@ def send_message_after_chat( ): """Send alert to user if they were @'d in a chat message""" # Because message-all run on background thread it needs it's own app context - app = create_app() + app = current_app with app.app_context(): usernames = MessageService._parse_message_for_username(chat, project_id) if len(usernames) != 0: diff --git a/tests/backend/base.py b/tests/backend/base.py index a0b4b9a6e8..999e6181d9 100644 --- a/tests/backend/base.py +++ b/tests/backend/base.py @@ -13,15 +13,21 @@ class BaseTestCase(unittest.TestCase): def setUpClass(cls): super(BaseTestCase, cls).setUpClass() cls.app = create_app("backend.config.TestEnvironmentConfig") + cls.app.config.update({"TESTING": True}) cls.db = db cls.db.app = cls.app - cls.db.create_all() + with cls.app.app_context(): + cls.db.create_all() @classmethod def tearDownClass(cls): - db.session.remove() - cls.db.drop_all() - cls.db.get_engine(cls.app).dispose() + with cls.app.app_context(): + db.session.remove() + cls.db.drop_all() + if cls.app in cls.db.engines: + cls.db.engines[cls.app].dispose() + if None in cls.db.engines: + cls.db.engines[None].dispose() super(BaseTestCase, cls).tearDownClass() def setUp(self): From 41e97b79a3a5fe1868546afa3bc25e8a18f5fbc1 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 12:46:50 -0600 Subject: [PATCH 09/15] Shapely updates Signed-off-by: Taylor Smock --- backend/api/projects/actions.py | 12 ++++++++++++ backend/models/postgis/priority_area.py | 8 ++++---- backend/models/postgis/task.py | 7 ++++--- backend/services/grid/grid_service.py | 8 ++++---- backend/services/grid/split_service.py | 6 ++++-- backend/services/mapping_service.py | 4 ++-- backend/services/project_admin_service.py | 5 ++--- .../integration/api/projects/test_resources.py | 6 ++++-- 8 files changed, 36 insertions(+), 20 deletions(-) diff --git a/backend/api/projects/actions.py b/backend/api/projects/actions.py index b56f414444..0bdccf5ec4 100644 --- a/backend/api/projects/actions.py +++ b/backend/api/projects/actions.py @@ -15,6 +15,8 @@ from backend.services.users.authentication_service import token_auth, tm from backend.services.interests_service import InterestService from backend.models.postgis.utils import InvalidGeoJson + +from shapely import GEOSException from shapely.errors import TopologicalError @@ -432,6 +434,16 @@ def post(self): "error": "Invalid geometry. Polygon is self intersecting", "SubCode": "SelfIntersectingAOI", }, 400 + except GEOSException as wrapped: + if ( + isinstance(wrapped.args[0], str) + and "Self-intersection" in wrapped.args[0] + ): + return { + "error": "Invalid geometry. Polygon is self intersecting", + "SubCode": "SelfIntersectingAOI", + }, 400 + return {"error": str(wrapped), "SubCode": "InternalServerError"} except Exception as e: error_msg = f"IntersectingTiles GET API - unhandled error: {str(e)}" current_app.logger.critical(error_msg) diff --git a/backend/models/postgis/priority_area.py b/backend/models/postgis/priority_area.py index 033a2ac0a7..c38a950de7 100644 --- a/backend/models/postgis/priority_area.py +++ b/backend/models/postgis/priority_area.py @@ -29,10 +29,9 @@ def from_dict(cls, area_poly: dict): if type(pa_geojson) is not geojson.Polygon: raise InvalidGeoJson("Priority Areas must be supplied as Polygons") - is_valid_geojson = geojson.is_valid(pa_geojson) - if is_valid_geojson["valid"] == "no": + if not pa_geojson.is_valid: raise InvalidGeoJson( - f"Priority Area: Invalid Polygon - {is_valid_geojson['message']}" + "Priority Area: Invalid Polygon - " + ", ".join(pa_geojson.errors()) ) pa = cls() @@ -42,5 +41,6 @@ def from_dict(cls, area_poly: dict): def get_as_geojson(self): """Helper to translate geometry back to a GEOJson Poly""" - pa_geojson = db.engine.execute(self.geometry.ST_AsGeoJSON()).scalar() + with db.engine.connect() as conn: + pa_geojson = conn.execute(self.geometry.ST_AsGeoJSON()).scalar() return geojson.loads(pa_geojson) diff --git a/backend/models/postgis/task.py b/backend/models/postgis/task.py index 07db2aa246..3984ceebbc 100644 --- a/backend/models/postgis/task.py +++ b/backend/models/postgis/task.py @@ -563,9 +563,10 @@ def from_geojson_feature(cls, task_id, task_feature): if type(task_geometry) is not geojson.MultiPolygon: raise InvalidGeoJson("MustBeMultiPloygon- Geometry must be a MultiPolygon") - is_valid_geojson = geojson.is_valid(task_geometry) - if is_valid_geojson["valid"] == "no": - raise InvalidGeoJson(f"InvalidMultiPolygon- {is_valid_geojson['message']}") + if not task_geometry.is_valid: + raise InvalidGeoJson( + "InvalidMultiPolygon - " + ", ".join(task_geometry.errors()) + ) task = cls() try: diff --git a/backend/services/grid/grid_service.py b/backend/services/grid/grid_service.py index e7880f19e2..00f8bb8c67 100644 --- a/backend/services/grid/grid_service.py +++ b/backend/services/grid/grid_service.py @@ -119,10 +119,10 @@ def merge_to_multi_polygon( "MustBeMultiPloygon- Area Of Interest: geometry must be a MultiPolygon" ) - is_valid_geojson = geojson.is_valid(aoi_multi_polygon_geojson) - if is_valid_geojson["valid"] == "no": + if not aoi_multi_polygon_geojson.is_valid: raise InvalidGeoJson( - f"InvalidMultipolygon- Area of Interest: Invalid MultiPolygon - {is_valid_geojson['message']}" + "InvalidMultipolygon- Area of Interest: Invalid MultiPolygon - " + + ", ".join(aoi_multi_polygon_geojson.errors()) ) return aoi_multi_polygon_geojson @@ -183,7 +183,7 @@ def _adapt_feature_geometry(feature: geojson.Feature) -> geojson.Feature: ): # adapt the geometry for use as a shapely geometry # http://toblerity.org/shapely/manual.html#shapely.geometry.asShape - feature.geometry = shapely.geometry.asShape(feature.geometry) + feature.geometry = shapely.geometry.shape(feature.geometry) return feature else: return None diff --git a/backend/services/grid/split_service.py b/backend/services/grid/split_service.py index d5e6ccb10b..264fa9e284 100644 --- a/backend/services/grid/split_service.py +++ b/backend/services/grid/split_service.py @@ -147,11 +147,13 @@ def _as_halves(geometries, centroid, axis) -> list: """ first_half = [ g - for g in geometries + for g in geometries.geoms if getattr(g.centroid, axis) <= getattr(centroid, axis) ] second_half = [ - g for g in geometries if getattr(g.centroid, axis) > getattr(centroid, axis) + g + for g in geometries.geoms + if getattr(g.centroid, axis) > getattr(centroid, axis) ] return (MultiPolygon(first_half), MultiPolygon(second_half)) diff --git a/backend/services/mapping_service.py b/backend/services/mapping_service.py index b9e0871776..41d7999cb9 100644 --- a/backend/services/mapping_service.py +++ b/backend/services/mapping_service.py @@ -258,7 +258,7 @@ def generate_gpx(project_id: int, task_ids_str: str, timestamp=None): for task in tasks: task_geom = shape.to_shape(task.geometry) - for poly in task_geom: + for poly in task_geom.geoms: trkseg = ET.SubElement(trk, "trkseg") for point in poly.exterior.coords: ET.SubElement( @@ -304,7 +304,7 @@ def generate_osm_xml(project_id: int, task_ids_str: str) -> str: "way", attrib=dict(id=str((task.id * -1)), action="modify", visible="true"), ) - for poly in task_geom: + for poly in task_geom.geoms: for point in poly.exterior.coords: ET.SubElement( root, diff --git a/backend/services/project_admin_service.py b/backend/services/project_admin_service.py index a9f32def43..a0df1c8837 100644 --- a/backend/services/project_admin_service.py +++ b/backend/services/project_admin_service.py @@ -222,10 +222,9 @@ def _attach_tasks_to_project(draft_project: Project, tasks_geojson): "MustBeFeatureCollection- Invalid: GeoJson must be FeatureCollection" ) - is_valid_geojson = geojson.is_valid(tasks) - if is_valid_geojson["valid"] == "no": + if not tasks.is_valid: raise InvalidGeoJson( - f"InvalidFeatureCollection- {is_valid_geojson['message']}" + "InvalidFeatureCollection - " + ", ".join(tasks.errors()) ) task_count = 1 diff --git a/tests/backend/integration/api/projects/test_resources.py b/tests/backend/integration/api/projects/test_resources.py index 416618ba79..82953899b3 100644 --- a/tests/backend/integration/api/projects/test_resources.py +++ b/tests/backend/integration/api/projects/test_resources.py @@ -259,14 +259,16 @@ def assert_project_response(project_response, expected_project, assert_type="ful assert expected_project.id == project_response["projectId"] # Since some of the fields are not returned in summary mode we need to skip them if assert_type != "summary": - assert geojson.is_valid(project_response["areaOfInterest"]) + assert geojson.loads( + geojson.dumps(project_response["areaOfInterest"]) + ).is_valid assert ["type", "coordinates"] == list( project_response["areaOfInterest"].keys() ) if assert_type == "notasks": assert "tasks" not in project_response else: - assert geojson.is_valid(project_response["tasks"]) + assert geojson.loads(geojson.dumps(project_response["tasks"])).is_valid assert ( is_known_task_creation_mode(project_response["taskCreationMode"]) is None From 0793aff8b4123ed8f0d2b2c345ccc899038e0e42 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 12:48:15 -0600 Subject: [PATCH 10/15] ORM updates This is largely paginate changes, along query methodology updates, and db execution method updates. There is also a change in backend/services/organisation_service.py that fixes a test failure (`datetime.today()` -> `func.now()`). Signed-off-by: Taylor Smock --- backend/models/postgis/project.py | 28 +++++++++++++------ backend/models/postgis/project_chat.py | 2 +- backend/models/postgis/user.py | 8 ++++-- backend/services/grid/split_service.py | 21 ++++++++------ backend/services/messaging/message_service.py | 16 ++++++----- backend/services/organisation_service.py | 4 +-- backend/services/project_search_service.py | 14 ++++++---- backend/services/stats_service.py | 8 ++---- backend/services/team_service.py | 4 ++- backend/services/users/user_service.py | 6 ++-- backend/services/validator_service.py | 2 +- tests/backend/base.py | 1 - .../services/test_project_admin_service.py | 2 +- 13 files changed, 67 insertions(+), 49 deletions(-) diff --git a/backend/models/postgis/project.py b/backend/models/postgis/project.py index 307a433c05..2c935bd535 100644 --- a/backend/models/postgis/project.py +++ b/backend/models/postgis/project.py @@ -9,7 +9,7 @@ from geoalchemy2 import Geometry from geoalchemy2.shape import to_shape from sqlalchemy.sql.expression import cast, or_ -from sqlalchemy import text, desc, func, Time, orm, literal +from sqlalchemy import desc, func, Time, orm, literal from shapely.geometry import shape from sqlalchemy.dialects.postgresql import ARRAY import requests @@ -354,15 +354,21 @@ def clone(project_id: int, author_id: int): return new_proj @staticmethod - def get(project_id: int): + def get(project_id: int) -> Optional["Project"]: """ Gets specified project :param project_id: project ID in scope :return: Project if found otherwise None """ - return Project.query.options( - orm.noload("tasks"), orm.noload("messages"), orm.noload("project_chat") - ).get(project_id) + return db.session.get( + Project, + project_id, + options=[ + orm.noload(Project.tasks), + orm.noload(Project.messages), + orm.noload(Project.project_chat), + ], + ) def update(self, project_dto: ProjectDTO): """Updates project from DTO""" @@ -647,10 +653,13 @@ def get_project_stats(self) -> ProjectStatsDTO: """Create Project Stats model for postgis project object""" project_stats = ProjectStatsDTO() project_stats.project_id = self.id - project_area_sql = "select ST_Area(geometry, true)/1000000 as area from public.projects where id = :id" - project_area_result = db.engine.execute(text(project_area_sql), id=self.id) + project_stats.area = ( + db.session.query(func.ST_Area(Project.geometry, True)) + .where(Project.id == self.id) + .first()[0] + / 1000000 + ) - project_stats.area = project_area_result.fetchone()["area"] project_stats.total_mappers = ( db.session.query(User).filter(User.projects_mapped.any(self.id)).count() ) @@ -926,7 +935,8 @@ def get_project_total_contributions(project_id: int) -> int: def get_aoi_geometry_as_geojson(self): """Helper which returns the AOI geometry as a geojson object""" - aoi_geojson = db.engine.execute(self.geometry.ST_AsGeoJSON()).scalar() + with db.engine.connect() as conn: + aoi_geojson = conn.execute(self.geometry.ST_AsGeoJSON()).scalar() return geojson.loads(aoi_geojson) def get_project_teams(self): diff --git a/backend/models/postgis/project_chat.py b/backend/models/postgis/project_chat.py index 790aec9fdb..9070bd917c 100644 --- a/backend/models/postgis/project_chat.py +++ b/backend/models/postgis/project_chat.py @@ -69,7 +69,7 @@ def get_messages(project_id: int, page: int, per_page: int = 20) -> ProjectChatD project_messages = ( ProjectChat.query.filter_by(project_id=project_id) .order_by(ProjectChat.time_stamp.desc()) - .paginate(page, per_page, True) + .paginate(page=page, per_page=per_page, error_out=True) ) dto = ProjectChatDTO() diff --git a/backend/models/postgis/user.py b/backend/models/postgis/user.py index 1d805ddf0a..d40aeffc66 100644 --- a/backend/models/postgis/user.py +++ b/backend/models/postgis/user.py @@ -69,7 +69,9 @@ class User(db.Model): last_validation_date = db.Column(db.DateTime, default=timestamp) # Relationships - accepted_licenses = db.relationship("License", secondary=user_licenses_table) + accepted_licenses = db.relationship( + "License", secondary=user_licenses_table, overlaps="users" + ) interests = db.relationship(Interest, secondary=user_interests, backref="users") def create(self): @@ -158,7 +160,7 @@ def get_all_users(query: UserSearchQuery) -> UserSearchDTO: base = base.filter(User.role.in_(role_array)) if query.pagination: results = base.order_by(User.username).paginate( - query.page, query.per_page, True + page=query.page, per_page=query.per_page, error_out=True ) else: per_page = base.count() @@ -198,7 +200,7 @@ def filter_users(user_filter: str, project_id: int, page: int) -> UserFilterDTO: .order_by(desc("participant").nullslast(), User.username) ) - results = query.paginate(page, 20, True) + results = query.paginate(page=page, per_page=20, error_out=True) if results.total == 0: raise NotFound() diff --git a/backend/services/grid/split_service.py b/backend/services/grid/split_service.py index 264fa9e284..e39252e286 100644 --- a/backend/services/grid/split_service.py +++ b/backend/services/grid/split_service.py @@ -88,9 +88,10 @@ def _create_square(x, y, zoom) -> geojson.MultiPolygon: transformed_geometry = ST_Transform(shape.from_shape(multipolygon, 3857), 4326) # use DB to get the geometry as geojson - return geojson.loads( - db.engine.execute(transformed_geometry.ST_AsGeoJSON()).scalar() - ) + with db.engine.connect() as conn: + return geojson.loads( + conn.execute(transformed_geometry.ST_AsGeoJSON()).scalar() + ) @staticmethod def _create_split_tasks_from_geometry(task) -> list: @@ -127,9 +128,10 @@ def _create_split_tasks_from_geometry(task) -> list: feature = geojson.Feature() # Tasks expect multipolygons. Convert and use the database to get as GeoJSON multipolygon_geometry = shape.from_shape(split_geometry, 4326) - feature.geometry = geojson.loads( - db.engine.execute(multipolygon_geometry.ST_AsGeoJSON()).scalar() - ) + with db.engine.connect() as conn: + feature.geometry = geojson.loads( + conn.execute(multipolygon_geometry.ST_AsGeoJSON()).scalar() + ) feature.properties["x"] = None feature.properties["y"] = None feature.properties["zoom"] = None @@ -174,9 +176,10 @@ def split_task(split_task_dto: SplitTaskDTO) -> TaskDTOs: original_geometry = shape.to_shape(original_task.geometry) # Fetch the task geometry in meters - original_task_area_m = db.engine.execute( - ST_Area(ST_GeogFromWKB(original_task.geometry)) - ).scalar() + with db.engine.connect() as conn: + original_task_area_m = conn.execute( + ST_Area(ST_GeogFromWKB(original_task.geometry)) + ).scalar() if ( original_task.zoom and original_task.zoom >= 18 diff --git a/backend/services/messaging/message_service.py b/backend/services/messaging/message_service.py index e0f2d3de53..3ecbe1d76e 100644 --- a/backend/services/messaging/message_service.py +++ b/backend/services/messaging/message_service.py @@ -492,9 +492,10 @@ def send_message_after_chat( MessageService._push_messages(messages) query = """ select user_id from project_favorites where project_id = :project_id""" - favorited_users_results = db.engine.execute( - text(query), project_id=project_id - ) + with db.engine.connect() as conn: + favorited_users_results = conn.execute( + text(query), project_id=project_id + ) favorited_users = [r[0] for r in favorited_users_results] # Notify all contributors except the user that created the comment. @@ -568,9 +569,10 @@ def send_favorite_project_activities(user_id: int): project_name = ProjectInfo.get_dto_for_locale( project.id, project.default_locale ).name - last_active_users = db.engine.execute( - text(query_last_active_users), project_id=project.id - ) + with db.engine.connect() as conn: + last_active_users = conn.execute( + text(query_last_active_users), project_id=project.id + ) for recent_user_id in last_active_users: recent_user_details = UserService.get_user_by_id(recent_user_id) @@ -715,7 +717,7 @@ def get_all_messages( results = ( query.filter(Message.to_user_id == user_id) .order_by(sort_column) - .paginate(page, page_size, True) + .paginate(page=page, per_page=page_size, error_out=True) ) # if results.total == 0: # raise NotFound() diff --git a/backend/services/organisation_service.py b/backend/services/organisation_service.py index 35d5eb59c6..2b000bb018 100644 --- a/backend/services/organisation_service.py +++ b/backend/services/organisation_service.py @@ -205,9 +205,7 @@ def get_organisation_stats( ).filter(Project.organisation_id == organisation_id) if year: start_date = f"{year}/01/01" - projects = projects.filter( - Project.created.between(start_date, datetime.today()) - ) + projects = projects.filter(Project.created.between(start_date, func.now())) published_projects = projects.filter( Project.status == ProjectStatus.PUBLISHED.value diff --git a/backend/services/project_search_service.py b/backend/services/project_search_service.py index 74fc5f0193..a440427a00 100644 --- a/backend/services/project_search_service.py +++ b/backend/services/project_search_service.py @@ -382,7 +382,9 @@ def _filter_projects(search_dto: ProjectSearchDTO, user): query_result.add_column(Project.priority) all_results = query_result.all() - paginated_results = query.paginate(search_dto.page, 14, True) + paginated_results = query.paginate( + page=search_dto.page, per_page=14, error_out=True + ) return all_results, paginated_results @@ -546,7 +548,8 @@ def _make_4326_polygon_from_bbox(bbox: list, srid: int) -> Polygon: polygon = box(bbox[0], bbox[1], bbox[2], bbox[3]) if not srid == 4326: geometry = shape.from_shape(polygon, srid) - geom_4326 = db.engine.execute(ST_Transform(geometry, 4326)).scalar() + with db.engine.connect() as conn: + geom_4326 = conn.execute(ST_Transform(geometry, 4326)).scalar() polygon = shape.to_shape(geom_4326) except Exception as e: current_app.logger.error(f"InvalidData- error making polygon: {e}") @@ -556,9 +559,10 @@ def _make_4326_polygon_from_bbox(bbox: list, srid: int) -> Polygon: @staticmethod def _get_area_sqm(polygon: Polygon) -> float: """get the area of the polygon in square metres""" - return db.engine.execute( - ST_Area(ST_Transform(shape.from_shape(polygon, 4326), 3857)) - ).scalar() + with db.engine.connect() as conn: + return conn.execute( + ST_Area(ST_Transform(shape.from_shape(polygon, 4326), 3857)) + ).scalar() @staticmethod def validate_bbox_area(polygon: Polygon) -> bool: diff --git a/backend/services/stats_service.py b/backend/services/stats_service.py index 7c7647af27..1f309ac876 100644 --- a/backend/services/stats_service.py +++ b/backend/services/stats_service.py @@ -1,6 +1,6 @@ from cachetools import TTLCache, cached from datetime import date, timedelta -from sqlalchemy import func, desc, cast, extract, or_, tuple_ +from sqlalchemy import func, desc, cast, extract, or_ from sqlalchemy.sql.functions import coalesce from sqlalchemy.types import Time @@ -136,7 +136,7 @@ def get_latest_activity(project_id: int, page: int) -> ProjectActivityDTO: TaskHistory.action != TaskAction.COMMENT.name, ) .order_by(TaskHistory.action_date.desc()) - .paginate(page, 10, True) + .paginate(page=page, per_page=10, error_out=True) ) activity_dto = ProjectActivityDTO() @@ -547,9 +547,7 @@ def get_task_stats( func.DATE(TaskHistory.action_date).label("day"), ) .distinct( - tuple_( - TaskHistory.project_id, TaskHistory.task_id, TaskHistory.action_text - ) + TaskHistory.project_id, TaskHistory.task_id, TaskHistory.action_text ) .filter( TaskHistory.action == "STATE_CHANGE", diff --git a/backend/services/team_service.py b/backend/services/team_service.py index bf59959435..b1df1f3329 100644 --- a/backend/services/team_service.py +++ b/backend/services/team_service.py @@ -288,7 +288,9 @@ def get_all_teams(search_dto: TeamSearchDTO) -> TeamsListDTO: teams_list_dto = TeamsListDTO() if search_dto.paginate: - paginated = query.paginate(search_dto.page, search_dto.per_page, True) + paginated = query.paginate( + page=search_dto.page, per_page=search_dto.per_page, error_out=True + ) teams_list_dto.pagination = Pagination(paginated) teams_list = paginated.items else: diff --git a/backend/services/users/user_service.py b/backend/services/users/user_service.py index f88b08f583..9ebb894cdd 100644 --- a/backend/services/users/user_service.py +++ b/backend/services/users/user_service.py @@ -2,7 +2,7 @@ from flask import current_app import datetime from sqlalchemy.sql.expression import literal -from sqlalchemy import func, or_, desc, and_, distinct, cast, Time +from sqlalchemy import func, or_, desc, and_, distinct, cast, Time, column from backend import db from backend.models.dtos.project_dto import ProjectFavoritesDTO, ProjectSearchResultsDTO from backend.models.dtos.user_dto import ( @@ -291,7 +291,7 @@ def get_tasks_dto( Task.project_id == sq.c.project_id, ), ) - tasks = tasks.add_columns("max", "comments") + tasks = tasks.add_columns(column("max"), column("comments")) if sort_by == "action_date": tasks = tasks.order_by(sq.c.max) @@ -311,7 +311,7 @@ def get_tasks_dto( if project_id: tasks = tasks.filter_by(project_id=project_id) - results = tasks.paginate(page, page_size, True) + results = tasks.paginate(page=page, per_page=page_size, error_out=True) task_list = [] diff --git a/backend/services/validator_service.py b/backend/services/validator_service.py index 47d197b7c0..90ecd8fd75 100644 --- a/backend/services/validator_service.py +++ b/backend/services/validator_service.py @@ -317,7 +317,7 @@ def get_user_invalidated_tasks( query = query.filter_by(project_id=project_id) results = query.order_by(text(sort_by + " " + sort_direction)).paginate( - page, page_size, True + page=page, per_page=page_size, error_out=True ) project_names = {} invalidated_tasks_dto = InvalidatedTasks() diff --git a/tests/backend/base.py b/tests/backend/base.py index 999e6181d9..ac7ea33274 100644 --- a/tests/backend/base.py +++ b/tests/backend/base.py @@ -35,7 +35,6 @@ def setUp(self): self.client = self.app.test_client() self.app_context = self.app.app_context() self.app_context.push() - self.db.session.begin(subtransactions=True) clean_db(self.db) def tearDown(self): diff --git a/tests/backend/unit/services/test_project_admin_service.py b/tests/backend/unit/services/test_project_admin_service.py index 43f86d11a1..6ab65612ae 100644 --- a/tests/backend/unit/services/test_project_admin_service.py +++ b/tests/backend/unit/services/test_project_admin_service.py @@ -111,7 +111,7 @@ def test_attempting_to_attach_non_existant_license_raise_error(self, license_moc ProjectAdminService._validate_imagery_licence(1) @patch.object(ProjectAdminService, "_get_project_by_id") - @patch("flask_sqlalchemy._QueryProperty.__get__") + @patch("flask_sqlalchemy.model._QueryProperty.__get__") @patch.object(Task, "set_task_history") def test_reset_all_tasks(self, mock_set_task_history, mock_query, mock_get_project): user_id = 123 From 44e948e067bf37c4993a680a755155c5bf173ae9 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Wed, 22 Mar 2023 15:19:47 -0600 Subject: [PATCH 11/15] Various fixes for test breakage Signed-off-by: Taylor Smock --- backend/api/organisations/resources.py | 4 +- backend/api/tasks/actions.py | 4 +- backend/services/mapping_service.py | 6 +-- tests/backend/base.py | 43 +++++++++++++++++++ .../integration/api/projects/test_actions.py | 4 +- .../api/projects/test_resources.py | 33 +------------- .../services/grid/test_split_service.py | 4 +- .../unit/services/grid/test_grid_service.py | 6 +-- 8 files changed, 59 insertions(+), 45 deletions(-) diff --git a/backend/api/organisations/resources.py b/backend/api/organisations/resources.py index 1a7aa2309a..291c57d07c 100644 --- a/backend/api/organisations/resources.py +++ b/backend/api/organisations/resources.py @@ -462,8 +462,8 @@ def get(self): ) # Validate abbreviated. - omit_managers = strtobool(request.args.get("omitManagerList", "false")) - omit_stats = strtobool(request.args.get("omitOrgStats", "true")) + omit_managers = bool(strtobool(request.args.get("omitManagerList", "false"))) + omit_stats = bool(strtobool(request.args.get("omitOrgStats", "true"))) # Obtain organisations try: results_dto = OrganisationService.get_organisations_as_dto( diff --git a/backend/api/tasks/actions.py b/backend/api/tasks/actions.py index a2f365fbf3..0faea71faf 100644 --- a/backend/api/tasks/actions.py +++ b/backend/api/tasks/actions.py @@ -171,7 +171,9 @@ def post(self, project_id, task_id): description: Internal Server Error """ try: - stop_task = StopMappingTaskDTO(request.get_json()) + stop_task = StopMappingTaskDTO( + request.get_json() if request.is_json else {} + ) stop_task.user_id = token_auth.current_user() stop_task.task_id = task_id stop_task.project_id = project_id diff --git a/backend/services/mapping_service.py b/backend/services/mapping_service.py index 41d7999cb9..7178fa681e 100644 --- a/backend/services/mapping_service.py +++ b/backend/services/mapping_service.py @@ -221,9 +221,9 @@ def generate_gpx(project_id: int, task_ids_str: str, timestamp=None): root = ET.Element( "gpx", attrib=dict( - xmlns="http://www.topografix.com/GPX/1/1", version="1.1", creator="HOT Tasking Manager", + xmlns="http://www.topografix.com/GPX/1/1", ), ) @@ -247,7 +247,7 @@ def generate_gpx(project_id: int, task_ids_str: str, timestamp=None): # Construct trkseg elements if task_ids_str is not None: - task_ids = map(int, task_ids_str.split(",")) + task_ids = list(map(int, task_ids_str.split(","))) tasks = Task.get_tasks(project_id, task_ids) if not tasks or len(tasks) == 0: raise NotFound() @@ -287,7 +287,7 @@ def generate_osm_xml(project_id: int, task_ids_str: str) -> str: ) if task_ids_str: - task_ids = map(int, task_ids_str.split(",")) + task_ids = list(map(int, task_ids_str.split(","))) tasks = Task.get_tasks(project_id, task_ids) if not tasks or len(tasks) == 0: raise NotFound() diff --git a/tests/backend/base.py b/tests/backend/base.py index ac7ea33274..faedd751a6 100644 --- a/tests/backend/base.py +++ b/tests/backend/base.py @@ -1,5 +1,6 @@ import unittest +from shapely.geometry import shape from backend import create_app, db @@ -42,3 +43,45 @@ def tearDown(self): self.db.session.rollback() self.db.session.close() self.app_context.pop() + + # Code modified from https://github.com/larsbutler/oq-engine/blob/master/tests/utils/helpers.py + # Note: Was originally in test_resources.py (author Aadesh-Baral) + def assertDeepAlmostEqual(self, expected, actual, *args, **kwargs): + """ + Assert that two complex structures have almost equal contents. + + Compares lists, dicts and tuples recursively. Checks numeric values + using test_case's :py:meth:`unittest.TestCase.assertAlmostEqual` and + checks all other values with :py:meth:`unittest.TestCase.assertEqual`. + Accepts additional positional and keyword arguments and pass those + intact to assertAlmostEqual() (that's how you specify comparison + precision). + + :type test_case: :py:class:`unittest.TestCase` object + """ + kwargs.pop("__trace", "ROOT") + if ( + hasattr(expected, "__geo_interface__") + and hasattr(actual, "__geo_interface__") + and expected.__geo_interface__["type"] == actual.__geo_interface__["type"] + and expected.__geo_interface__["type"] + not in ["Feature", "FeatureCollection"] + ): + shape_expected = shape(expected) + shape_actual = shape(actual) + assert shape_expected.equals(shape_actual) + elif isinstance(expected, (int, float, complex)): + self.assertAlmostEqual(expected, actual, *args, **kwargs) + elif isinstance(expected, (list, tuple)): + self.assertEqual(len(expected), len(actual)) + for index in range(len(expected)): + v1, v2 = expected[index], actual[index] + self.assertDeepAlmostEqual(v1, v2, __trace=repr(index), *args, **kwargs) + elif isinstance(expected, dict): + self.assertEqual(set(expected), set(actual)) + for key in expected: + self.assertDeepAlmostEqual( + expected[key], actual[key], __trace=repr(key), *args, **kwargs + ) + else: + self.assertEqual(expected, actual) diff --git a/tests/backend/integration/api/projects/test_actions.py b/tests/backend/integration/api/projects/test_actions.py index 8a42d91092..63dd809a70 100644 --- a/tests/backend/integration/api/projects/test_actions.py +++ b/tests/backend/integration/api/projects/test_actions.py @@ -65,7 +65,7 @@ def test_returns_clipped_grid_if_clip_to_aoi_set_true(self): ) # Assert self.assertEqual(response.status_code, 200) - self.assertDictEqual(response.json, expected_response) + self.assertDeepAlmostEqual(response.json, expected_response, places=6) def test_returns_not_clipped_grid_if_clip_to_aoi_set_false(self): """Test that the endpoint returns a not clipped grid if clipToAoi is set to false""" @@ -83,7 +83,7 @@ def test_returns_not_clipped_grid_if_clip_to_aoi_set_false(self): ) # Assert self.assertEqual(response.status_code, 200) - self.assertDictEqual(response.json, expected_response) + self.assertDeepAlmostEqual(response.json, expected_response, places=6) def test_raises_invalid_geojson_exception_if_invalid_aoi(self): """Test that the endpoint raises an InvalidGeoJson exception if the grid is invalid""" diff --git a/tests/backend/integration/api/projects/test_resources.py b/tests/backend/integration/api/projects/test_resources.py index 82953899b3..dd4dfcebed 100644 --- a/tests/backend/integration/api/projects/test_resources.py +++ b/tests/backend/integration/api/projects/test_resources.py @@ -1998,37 +1998,6 @@ def setUp(self): self.test_project.save() self.url = f"/api/v2/projects/{self.test_project.id}/queries/priority-areas/" - # Code modified from https://github.com/larsbutler/oq-engine/blob/master/tests/utils/helpers.py - def assertDeepAlmostEqual(self, expected, actual, *args, **kwargs): - """ - Assert that two complex structures have almost equal contents. - - Compares lists, dicts and tuples recursively. Checks numeric values - using test_case's :py:meth:`unittest.TestCase.assertAlmostEqual` and - checks all other values with :py:meth:`unittest.TestCase.assertEqual`. - Accepts additional positional and keyword arguments and pass those - intact to assertAlmostEqual() (that's how you specify comparison - precision). - - :type test_case: :py:class:`unittest.TestCase` object - """ - kwargs.pop("__trace", "ROOT") - if isinstance(expected, (int, float, complex)): - self.assertAlmostEqual(expected, actual, *args, **kwargs) - elif isinstance(expected, (list, tuple)): - self.assertEqual(len(expected), len(actual)) - for index in range(len(expected)): - v1, v2 = expected[index], actual[index] - self.assertDeepAlmostEqual(v1, v2, __trace=repr(index), *args, **kwargs) - elif isinstance(expected, dict): - self.assertEqual(set(expected), set(actual)) - for key in expected: - self.assertDeepAlmostEqual( - expected[key], actual[key], __trace=repr(key), *args, **kwargs - ) - else: - self.assertEqual(expected, actual) - def returns_404_if_project_doesnt_exist(self): """ Test 404 is returned if project doesn't exist @@ -2052,7 +2021,7 @@ def test_authentication_is_not_required(self): self.assertEqual(response.status_code, 200) self.assertEqual(len(response.json), 1) self.assertDeepAlmostEqual( - response.json[0], json_data["priorityAreas"][0], places=8 + response.json[0], json_data["priorityAreas"][0], places=6 ) diff --git a/tests/backend/integration/services/grid/test_split_service.py b/tests/backend/integration/services/grid/test_split_service.py index fea3b5433c..f62f5cfd36 100644 --- a/tests/backend/integration/services/grid/test_split_service.py +++ b/tests/backend/integration/services/grid/test_split_service.py @@ -35,7 +35,7 @@ def test_split_geom_returns_split_geometries(self): # act result = SplitService._create_split_tasks(x, y, zoom, task_stub) # assert - self.assertEqual(str(expected), str(result)) + self.assertDeepAlmostEqual(expected, result, places=6) def test_split_geom_raise_grid_service_error_when_task_not_usable(self): with self.assertRaises(SplitServiceError): @@ -115,4 +115,4 @@ def test_split_non_square_task(self, mock_task): json.dumps(get_canned_json("non_square_split_results.json")) ) result = SplitService._create_split_tasks(task.x, task.y, task.zoom, task) - self.assertEqual(str(expected), str(result)) + self.assertDeepAlmostEqual(expected, result, places=6) diff --git a/tests/backend/unit/services/grid/test_grid_service.py b/tests/backend/unit/services/grid/test_grid_service.py index 9d008878b0..cc78e73724 100644 --- a/tests/backend/unit/services/grid/test_grid_service.py +++ b/tests/backend/unit/services/grid/test_grid_service.py @@ -23,7 +23,7 @@ def test_feature_collection_to_multi_polygon_dissolve(self): result = GridService.merge_to_multi_polygon(aoi_geojson, True) # assert - self.assertEqual(str(expected), str(result)) + self.assertDeepAlmostEqual(expected, result) def test_feature_collection_to_multi_polygon_nodissolve(self): # arrange @@ -52,7 +52,7 @@ def test_trim_grid_to_aoi_clip(self): result = GridService.trim_grid_to_aoi(grid_dto) # assert - self.assertEqual(str(expected), str(result)) + self.assertDeepAlmostEqual(expected, result, places=6) def test_trim_grid_to_aoi_noclip(self): # arrange @@ -67,7 +67,7 @@ def test_trim_grid_to_aoi_noclip(self): result = GridService.trim_grid_to_aoi(grid_dto) # assert - self.assertEqual(str(expected), str(result)) + self.assertDeepAlmostEqual(expected, result) def test_tasks_from_aoi_features(self): # arrange From aa3ab8928e9655487cfbe5e63f3dae11aa53af15 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Thu, 23 Mar 2023 07:07:16 -0600 Subject: [PATCH 12/15] geojson precision updates Signed-off-by: Taylor Smock --- backend/services/grid/grid_service.py | 8 +- tests/backend/base.py | 15 + .../clipped_feature_collection.json | 970 ++++++++---------- .../test_files/feature_collection.json | 116 +-- .../test_files/non_square_split_results.json | 136 +-- .../integration/api/projects/test_actions.py | 4 +- .../services/grid/test_split_service.py | 4 +- 7 files changed, 520 insertions(+), 733 deletions(-) diff --git a/backend/services/grid/grid_service.py b/backend/services/grid/grid_service.py index 00f8bb8c67..7564f92d8b 100644 --- a/backend/services/grid/grid_service.py +++ b/backend/services/grid/grid_service.py @@ -1,7 +1,7 @@ import geojson import json from shapely.geometry import MultiPolygon, mapping -from shapely.ops import cascaded_union +from shapely.ops import unary_union import shapely.geometry from flask import current_app from backend.models.dtos.grid_dto import GridDTO @@ -26,8 +26,8 @@ def trim_grid_to_aoi(grid_dto: GridDTO) -> geojson.FeatureCollection: :return: geojson.FeatureCollection trimmed task grid """ # get items out of the dto - grid = grid_dto.grid - aoi = grid_dto.area_of_interest + grid = geojson.loads(geojson.dumps(grid_dto.grid)) + aoi = geojson.loads(geojson.dumps(grid_dto.area_of_interest)) clip_to_aoi = grid_dto.clip_to_aoi # create a shapely shape from the aoi @@ -229,7 +229,7 @@ def _dissolve(geoms: MultiPolygon) -> MultiPolygon: :return: Multipolygon """ # http://toblerity.org/shapely/manual.html#shapely.ops.cascaded_union - geometry = cascaded_union(geoms) + geometry = unary_union(geoms) if geometry.geom_type == "Polygon": # shapely may return a POLYGON rather than a MULTIPOLYGON if there is just one shape # force Multipolygon diff --git a/tests/backend/base.py b/tests/backend/base.py index faedd751a6..c8fa9b4756 100644 --- a/tests/backend/base.py +++ b/tests/backend/base.py @@ -1,7 +1,11 @@ import unittest +from typing import Optional from shapely.geometry import shape from backend import create_app, db +import geojson +from flask import Flask +from flask_sqlalchemy import SQLAlchemy def clean_db(db): @@ -10,9 +14,19 @@ def clean_db(db): class BaseTestCase(unittest.TestCase): + DEFAULT_PRECISION: Optional[int] + app: Optional[Flask] + db: Optional[SQLAlchemy] + @classmethod def setUpClass(cls): super(BaseTestCase, cls).setUpClass() + cls.DEFAULT_PRECISION = geojson.geometry.DEFAULT_PRECISION + # OSM uses 7, which means the worst error of longitude is ±5.56595 mm + # at the equator. The worst error for 6 decimal places of longitude is + # ±5.56595 cm at the equator. This is the default, and realistically + # is probably more than enough for the TM. + geojson.geometry.DEFAULT_PRECISION = 7 cls.app = create_app("backend.config.TestEnvironmentConfig") cls.app.config.update({"TESTING": True}) cls.db = db @@ -22,6 +36,7 @@ def setUpClass(cls): @classmethod def tearDownClass(cls): + geojson.geometry.DEFAULT_PRECISION = cls.DEFAULT_PRECISION with cls.app.app_context(): db.session.remove() cls.db.drop_all() diff --git a/tests/backend/helpers/test_files/clipped_feature_collection.json b/tests/backend/helpers/test_files/clipped_feature_collection.json index 2302f9ae17..c81c2f4eb2 100644 --- a/tests/backend/helpers/test_files/clipped_feature_collection.json +++ b/tests/backend/helpers/test_files/clipped_feature_collection.json @@ -1,1259 +1,1145 @@ { + "type":"FeatureCollection", "features":[ { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275046.0685966313, - 2828781.542271093 + 1275034.3899838, + 2828857.9792994 ], [ - 1275016.64554516, - 2828781.542271093 + 1275046.0685966, + 2828857.9792994 ], [ - 1275034.3899837115, - 2828857.9792993665 + 1275046.0685966, + 2828781.5422711 ], [ - 1275046.0685966313, - 2828857.9792993665 + 1275016.6455452, + 2828781.5422711 ], [ - 1275046.0685966313, - 2828781.542271093 + 1275034.3899838, + 2828857.9792994 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278824, "y":299152, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275034.3899837115, - 2828857.9792993665 + 1275046.0685966, + 2828908.286806 ], [ - 1275046.0685966313, - 2828908.286806327 + 1275046.0685966, + 2828857.9792994 ], [ - 1275046.0685966313, - 2828857.9792993665 + 1275034.3899838, + 2828857.9792994 ], [ - 1275034.3899837115, - 2828857.9792993665 + 1275046.0685966, + 2828908.286806 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278824, "y":299153, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275122.5056249015, - 2828781.542271093 + 1275046.0685966, + 2828781.5422711 ], [ - 1275046.0685966313, - 2828781.542271093 + 1275046.0685966, + 2828857.9792994 ], [ - 1275046.0685966313, - 2828857.9792993665 + 1275122.5056249, + 2828857.9792994 ], [ - 1275122.5056249015, - 2828857.9792993665 + 1275122.5056249, + 2828781.5422711 ], [ - 1275122.5056249015, - 2828781.542271093 + 1275046.0685966, + 2828781.5422711 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ - "isSquare":false, + "isSquare":true, "x":278825, "y":299152, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275046.0685966313, - 2828908.286806327 + 1275052.1344223, + 2828934.4163276 ], [ - 1275052.1344222624, - 2828934.4163276367 + 1275122.5056249, + 2828934.4163276 ], [ - 1275122.5056249015, - 2828934.4163276367 + 1275122.5056249, + 2828857.9792994 ], [ - 1275122.5056249015, - 2828857.9792993665 + 1275046.0685966, + 2828857.9792994 ], [ - 1275046.0685966313, - 2828857.9792993665 + 1275046.0685966, + 2828908.286806 ], [ - 1275046.0685966313, - 2828908.286806327 + 1275052.1344223, + 2828934.4163276 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278825, "y":299153, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275052.1344222624, - 2828934.4163276367 + 1275069.8788608, + 2829010.8533559 ], [ - 1275069.8788608133, - 2829010.853355907 + 1275122.5056249, + 2829010.8533559 ], [ - 1275122.5056249015, - 2829010.853355907 + 1275122.5056249, + 2828934.4163276 ], [ - 1275122.5056249015, - 2828934.4163276367 + 1275052.1344223, + 2828934.4163276 ], [ - 1275052.1344222624, - 2828934.4163276367 + 1275069.8788608, + 2829010.8533559 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278825, "y":299154, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275069.8788608133, - 2829010.853355907 + 1275087.6232994, + 2829087.2903842 ], [ - 1275087.623299365, - 2829087.290384181 + 1275122.5056249, + 2829087.2903842 ], [ - 1275122.5056249015, - 2829087.290384181 + 1275122.5056249, + 2829010.8533559 ], [ - 1275122.5056249015, - 2829010.853355907 + 1275069.8788608, + 2829010.8533559 ], [ - 1275069.8788608133, - 2829010.853355907 + 1275087.6232994, + 2829087.2903842 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278825, "y":299155, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275198.9426531754, - 2828781.542271093 + 1275122.5056249, + 2828781.5422711 ], [ - 1275122.5056249015, - 2828781.542271093 + 1275122.5056249, + 2828857.9792994 ], [ - 1275122.5056249015, - 2828857.9792993665 + 1275198.9426532, + 2828857.9792994 ], [ - 1275198.9426531754, - 2828857.9792993665 + 1275198.9426532, + 2828781.5422711 ], [ - 1275198.9426531754, - 2828781.542271093 + 1275122.5056249, + 2828781.5422711 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ - "isSquare":false, + "isSquare":true, "x":278826, "y":299152, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275122.5056249015, - 2828857.9792993665 + 1275122.5056249, + 2828857.9792994 ], [ - 1275122.5056249015, - 2828934.4163276367 + 1275122.5056249, + 2828934.4163276 ], [ - 1275198.9426531754, - 2828934.4163276367 + 1275198.9426532, + 2828934.4163276 ], [ - 1275198.9426531754, - 2828857.9792993665 + 1275198.9426532, + 2828857.9792994 ], [ - 1275122.5056249015, - 2828857.9792993665 + 1275122.5056249, + 2828857.9792994 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278826, "y":299153, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275122.5056249015, - 2828934.4163276367 + 1275122.5056249, + 2828934.4163276 ], [ - 1275122.5056249015, - 2829010.853355907 + 1275122.5056249, + 2829010.8533559 ], [ - 1275198.9426531754, - 2829010.853355907 + 1275198.9426532, + 2829010.8533559 ], [ - 1275198.9426531754, - 2828934.4163276367 + 1275198.9426532, + 2828934.4163276 ], [ - 1275122.5056249015, - 2828934.4163276367 + 1275122.5056249, + 2828934.4163276 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278826, "y":299154, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275122.5056249015, - 2829010.853355907 + 1275122.5056249, + 2829010.8533559 ], [ - 1275122.5056249015, - 2829087.290384181 + 1275122.5056249, + 2829087.2903842 ], [ - 1275198.9426531754, - 2829087.290384181 + 1275198.9426532, + 2829087.2903842 ], [ - 1275198.9426531754, - 2829010.853355907 + 1275198.9426532, + 2829010.8533559 ], [ - 1275122.5056249015, - 2829010.853355907 + 1275122.5056249, + 2829010.8533559 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278826, "y":299155, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275275.379681445, - 2828783.098289569 + 1275275.3796814, + 2828783.0982896 ], [ - 1275200.690770448, - 2828781.542271093 + 1275200.6907704, + 2828781.5422711 ], [ - 1275198.9426531754, - 2828781.542271093 + 1275198.9426532, + 2828781.5422711 ], [ - 1275198.9426531754, - 2828857.9792993665 + 1275198.9426532, + 2828857.9792994 ], [ - 1275275.379681445, - 2828857.9792993665 + 1275275.3796814, + 2828857.9792994 ], [ - 1275275.379681445, - 2828783.098289569 + 1275275.3796814, + 2828783.0982896 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278827, "y":299152, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275275.379681445, - 2828934.4163276367 + 1275198.9426532, + 2828857.9792994 ], [ - 1275275.379681445, - 2828857.9792993665 + 1275198.9426532, + 2828934.4163276 ], [ - 1275198.9426531754, - 2828857.9792993665 + 1275275.3796814, + 2828934.4163276 ], [ - 1275198.9426531754, - 2828934.4163276367 + 1275275.3796814, + 2828857.9792994 ], [ - 1275275.379681445, - 2828934.4163276367 + 1275198.9426532, + 2828857.9792994 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ - "isSquare":false, + "isSquare":true, "x":278827, "y":299153, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275275.379681445, - 2829010.853355907 + 1275198.9426532, + 2828934.4163276 ], [ - 1275275.379681445, - 2828934.4163276367 + 1275198.9426532, + 2829010.8533559 ], [ - 1275198.9426531754, - 2828934.4163276367 + 1275275.3796814, + 2829010.8533559 ], [ - 1275198.9426531754, - 2829010.853355907 + 1275275.3796814, + 2828934.4163276 ], [ - 1275275.379681445, - 2829010.853355907 + 1275198.9426532, + 2828934.4163276 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ - "isSquare":false, + "isSquare":true, "x":278827, "y":299154, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275198.9426531754, - 2829087.290384181 + 1275198.9426532, + 2829010.8533559 ], [ - 1275275.379681445, - 2829087.290384181 + 1275198.9426532, + 2829087.2903842 ], [ - 1275275.379681445, - 2829010.853355907 + 1275275.3796814, + 2829087.2903842 ], [ - 1275198.9426531754, - 2829010.853355907 + 1275275.3796814, + 2829010.8533559 ], [ - 1275198.9426531754, - 2829087.290384181 + 1275198.9426532, + 2829010.8533559 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ - "isSquare":false, + "isSquare":true, "x":278827, "y":299155, "zoom":19 - }, - "type":"Feature" - }, - { - "geometry":{ - "coordinates":[ - [ - [ - [ - 1275581.1277945302, - 2829087.290384181 - ], - [ - 1275581.12779453, - 2829087.290384181 - ], - [ - 1275581.12779453, - 2829163.727412451 - ], - [ - 1275581.1277945302, - 2829163.727412451 - ], - [ - 1275581.1277945302, - 2829087.290384181 - ] - ] - ] - ], - "type":"MultiPolygon" - }, - "properties":{ - "isSquare":false, - "x":278831, - "y":299156, - "zoom":19 - }, - "type":"Feature" - }, - { - "geometry":{ - "coordinates":[ - [ - [ - [ - 1275581.12779453, - 2829163.727412451 - ], - [ - 1275581.12779453, - 2829240.1644407213 - ], - [ - 1275581.1277945302, - 2829240.1644407213 - ], - [ - 1275581.1277945302, - 2829163.727412451 - ], - [ - 1275581.12779453, - 2829163.727412451 - ] - ] - ] - ], - "type":"MultiPolygon" - }, - "properties":{ - "isSquare":false, - "x":278831, - "y":299157, - "zoom":19 - }, - "type":"Feature" - }, - { - "geometry":{ - "coordinates":[ - [ - [ - [ - 1275581.12779453, - 2829306.621247852 - ], - [ - 1275581.1277945302, - 2829306.621247852 - ], - [ - 1275581.1277945302, - 2829240.1644407213 - ], - [ - 1275581.12779453, - 2829240.1644407213 - ], - [ - 1275581.12779453, - 2829306.621247852 - ] - ] - ] - ], - "type":"MultiPolygon" - }, - "properties":{ - "isSquare":false, - "x":278831, - "y":299158, - "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275581.1277945302, - 2829087.290384181 + 1275581.1277945, + 2829087.2903842 ], [ - 1275581.1277945302, - 2829163.727412451 + 1275581.1277945, + 2829163.7274125 ], [ - 1275657.5648228042, - 2829163.727412451 + 1275657.5648228, + 2829163.7274125 ], [ - 1275657.5648228042, - 2829087.290384181 + 1275657.5648228, + 2829087.2903842 ], [ - 1275581.1277945302, - 2829087.290384181 + 1275581.1277945, + 2829087.2903842 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278832, "y":299156, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275581.1277945302, - 2829163.727412451 + 1275581.1277945, + 2829163.7274125 ], [ - 1275581.1277945302, - 2829240.1644407213 + 1275581.1277945, + 2829240.1644407 ], [ - 1275657.5648228042, - 2829240.1644407213 + 1275657.5648228, + 2829240.1644407 ], [ - 1275657.5648228042, - 2829163.727412451 + 1275657.5648228, + 2829163.7274125 ], [ - 1275581.1277945302, - 2829163.727412451 + 1275581.1277945, + 2829163.7274125 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278832, "y":299157, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275581.1277945302, - 2829306.621247852 + 1275581.1277945, + 2829306.6212479 ], [ - 1275657.5648228042, - 2829305.559622672 + 1275657.5648228, + 2829305.5596227 ], [ - 1275657.5648228042, - 2829240.1644407213 + 1275657.5648228, + 2829240.1644407 ], [ - 1275581.1277945302, - 2829240.1644407213 + 1275581.1277945, + 2829240.1644407 ], [ - 1275581.1277945302, - 2829306.621247852 + 1275581.1277945, + 2829306.6212479 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278832, "y":299158, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275657.5648228042, - 2829087.290384181 + 1275657.5648228, + 2829087.2903842 ], [ - 1275657.5648228042, - 2829163.727412451 + 1275657.5648228, + 2829163.7274125 ], [ - 1275734.0018510744, - 2829163.727412451 + 1275734.0018511, + 2829163.7274125 ], [ - 1275734.0018510744, - 2829087.290384181 + 1275734.0018511, + 2829087.2903842 ], [ - 1275657.5648228042, - 2829087.290384181 + 1275657.5648228, + 2829087.2903842 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278833, "y":299156, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275657.5648228042, - 2829163.727412451 + 1275657.5648228, + 2829163.7274125 ], [ - 1275657.5648228042, - 2829240.1644407213 + 1275657.5648228, + 2829240.1644407 ], [ - 1275734.0018510744, - 2829240.1644407213 + 1275734.0018511, + 2829240.1644407 ], [ - 1275734.0018510744, - 2829163.727412451 + 1275734.0018511, + 2829163.7274125 ], [ - 1275657.5648228042, - 2829163.727412451 + 1275657.5648228, + 2829163.7274125 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278833, "y":299157, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275657.5648228042, - 2829305.559622672 + 1275734.0018511, + 2829304.4979975 ], [ - 1275734.0018510744, - 2829304.4979974916 + 1275734.0018511, + 2829240.1644407 ], [ - 1275734.0018510744, - 2829240.1644407213 + 1275657.5648228, + 2829240.1644407 ], [ - 1275657.5648228042, - 2829240.1644407213 + 1275657.5648228, + 2829305.5596227 ], [ - 1275657.5648228042, - 2829305.559622672 + 1275734.0018511, + 2829304.4979975 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278833, "y":299158, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275734.0018510744, - 2829087.290384181 + 1275734.0018511, + 2829087.2903842 ], [ - 1275734.0018510744, - 2829163.727412451 + 1275734.0018511, + 2829163.7274125 ], [ - 1275810.4388793446, - 2829163.727412451 + 1275810.4388793, + 2829163.7274125 ], [ - 1275810.4388793446, - 2829087.290384181 + 1275810.4388793, + 2829087.2903842 ], [ - 1275734.0018510744, - 2829087.290384181 + 1275734.0018511, + 2829087.2903842 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278834, "y":299156, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275734.0018510744, - 2829163.727412451 + 1275734.0018511, + 2829163.7274125 ], [ - 1275734.0018510744, - 2829240.1644407213 + 1275734.0018511, + 2829240.1644407 ], [ - 1275810.4388793446, - 2829240.1644407213 + 1275810.4388793, + 2829240.1644407 ], [ - 1275810.4388793446, - 2829163.727412451 + 1275810.4388793, + 2829163.7274125 ], [ - 1275734.0018510744, - 2829163.727412451 + 1275734.0018511, + 2829163.7274125 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":true, "x":278834, "y":299157, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275734.0018510744, - 2829304.4979974916 + 1275810.4388793, + 2829303.4363723 ], [ - 1275810.4388793446, - 2829303.4363723113 + 1275810.4388793, + 2829240.1644407 ], [ - 1275810.4388793446, - 2829240.1644407213 + 1275734.0018511, + 2829240.1644407 ], [ - 1275734.0018510744, - 2829240.1644407213 + 1275734.0018511, + 2829304.4979975 ], [ - 1275734.0018510744, - 2829304.4979974916 + 1275810.4388793, + 2829303.4363723 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278834, "y":299158, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275856.840137125, - 2829163.727412451 + 1275810.4388793, + 2829087.2903842 ], [ - 1275872.704275511, - 2829087.290384181 + 1275810.4388793, + 2829163.7274125 ], [ - 1275810.4388793446, - 2829087.290384181 + 1275856.8401371, + 2829163.7274125 ], [ - 1275810.4388793446, - 2829163.727412451 + 1275872.7042755, + 2829087.2903842 ], [ - 1275856.840137125, - 2829163.727412451 + 1275810.4388793, + 2829087.2903842 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278835, "y":299156, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275840.9759987388, - 2829240.1644407213 + 1275856.8401371, + 2829163.7274125 ], [ - 1275856.840137125, - 2829163.727412451 + 1275810.4388793, + 2829163.7274125 ], [ - 1275810.4388793446, - 2829163.727412451 + 1275810.4388793, + 2829240.1644407 ], [ - 1275810.4388793446, - 2829240.1644407213 + 1275840.9759988, + 2829240.1644407 ], [ - 1275840.9759987388, - 2829240.1644407213 + 1275856.8401371, + 2829163.7274125 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278835, "y":299157, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275810.4388793446, - 2829303.4363723113 + 1275827.8945302, + 2829303.1939328 ], [ - 1275827.894530152, - 2829303.193932765 + 1275840.9759988, + 2829240.1644407 ], [ - 1275840.9759987388, - 2829240.1644407213 + 1275810.4388793, + 2829240.1644407 ], [ - 1275810.4388793446, - 2829240.1644407213 + 1275810.4388793, + 2829303.4363723 ], [ - 1275810.4388793446, - 2829303.4363723113 + 1275827.8945302, + 2829303.1939328 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278835, "y":299158, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275920.2974494277, - 2828857.9792993665 + 1275886.8759076, + 2828795.8377961 ], [ - 1275932.995444044, - 2828796.798620377 + 1275886.8759076, + 2828857.9792994 ], [ - 1275886.875907619, - 2828795.837796132 + 1275920.2974494, + 2828857.9792994 ], [ - 1275886.875907619, - 2828857.9792993665 + 1275932.995444, + 2828796.7986204 ], [ - 1275920.2974494277, - 2828857.9792993665 + 1275886.8759076, + 2828795.8377961 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278836, "y":299152, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275904.4330133097, - 2828934.4163276367 + 1275886.8759076, + 2828934.4163276 ], [ - 1275920.2974494277, - 2828857.9792993665 + 1275904.4330133, + 2828934.4163276 ], [ - 1275886.875907619, - 2828857.9792993665 + 1275920.2974494, + 2828857.9792994 ], [ - 1275886.875907619, - 2828934.4163276367 + 1275886.8759076, + 2828857.9792994 ], [ - 1275904.4330133097, - 2828934.4163276367 + 1275886.8759076, + 2828934.4163276 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278836, "y":299153, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275888.568577192, - 2829010.853355907 + 1275886.8759076, + 2829010.8533559 ], [ - 1275904.4330133097, - 2828934.4163276367 + 1275888.5685772, + 2829010.8533559 ], [ - 1275886.875907619, - 2828934.4163276367 + 1275904.4330133, + 2828934.4163276 ], [ - 1275886.875907619, - 2829010.853355907 + 1275886.8759076, + 2828934.4163276 ], [ - 1275888.568577192, - 2829010.853355907 + 1275886.8759076, + 2829010.8533559 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278836, "y":299154, "zoom":19 - }, - "type":"Feature" + } }, { + "type":"Feature", "geometry":{ + "type":"MultiPolygon", "coordinates":[ [ [ [ - 1275886.875907619, - 2829019.008869979 + 1275886.8759076, + 2829019.00887 ], [ - 1275888.568577192, - 2829010.853355907 + 1275888.5685772, + 2829010.8533559 ], [ - 1275886.875907619, - 2829010.853355907 + 1275886.8759076, + 2829010.8533559 ], [ - 1275886.875907619, - 2829019.008869979 + 1275886.8759076, + 2829019.00887 ] ] ] - ], - "type":"MultiPolygon" + ] }, "properties":{ "isSquare":false, "x":278836, "y":299155, "zoom":19 - }, - "type":"Feature" + } } - ], - "type":"FeatureCollection" -} \ No newline at end of file + ] +} diff --git a/tests/backend/helpers/test_files/feature_collection.json b/tests/backend/helpers/test_files/feature_collection.json index b237311167..79c474a2fc 100644 --- a/tests/backend/helpers/test_files/feature_collection.json +++ b/tests/backend/helpers/test_files/feature_collection.json @@ -532,120 +532,6 @@ }, "type": "Feature" }, - { - "geometry": { - "coordinates": [ - [ - [ - [ - 1275504.69076626, - 2829087.290384181 - ], - [ - 1275504.69076626, - 2829163.727412451 - ], - [ - 1275581.1277945302, - 2829163.727412451 - ], - [ - 1275581.1277945302, - 2829087.290384181 - ], - [ - 1275504.69076626, - 2829087.290384181 - ] - ] - ] - ], - "type": "MultiPolygon" - }, - "properties": { - "isSquare": true, - "x": 278831, - "y": 299156, - "zoom": 19 - }, - "type": "Feature" - }, - { - "geometry": { - "coordinates": [ - [ - [ - [ - 1275504.69076626, - 2829163.727412451 - ], - [ - 1275504.69076626, - 2829240.1644407213 - ], - [ - 1275581.1277945302, - 2829240.1644407213 - ], - [ - 1275581.1277945302, - 2829163.727412451 - ], - [ - 1275504.69076626, - 2829163.727412451 - ] - ] - ] - ], - "type": "MultiPolygon" - }, - "properties": { - "isSquare": true, - "x": 278831, - "y": 299157, - "zoom": 19 - }, - "type": "Feature" - }, - { - "geometry": { - "coordinates": [ - [ - [ - [ - 1275504.69076626, - 2829240.1644407213 - ], - [ - 1275504.69076626, - 2829316.601468995 - ], - [ - 1275581.1277945302, - 2829316.601468995 - ], - [ - 1275581.1277945302, - 2829240.1644407213 - ], - [ - 1275504.69076626, - 2829240.1644407213 - ] - ] - ] - ], - "type": "MultiPolygon" - }, - "properties": { - "isSquare": true, - "x": 278831, - "y": 299158, - "zoom": 19 - }, - "type": "Feature" - }, { "geometry": { "coordinates": [ @@ -1256,4 +1142,4 @@ } ], "type": "FeatureCollection" -} \ No newline at end of file +} diff --git a/tests/backend/helpers/test_files/non_square_split_results.json b/tests/backend/helpers/test_files/non_square_split_results.json index 57c22e9337..67ef17f98b 100644 --- a/tests/backend/helpers/test_files/non_square_split_results.json +++ b/tests/backend/helpers/test_files/non_square_split_results.json @@ -5,24 +5,24 @@ [ [ [ - 152.401607946, - -31.952162233 + 152.401608, + -31.9521622 ], [ - 151.874999973, - -31.952162233 + 151.875, + -31.9521622 ], [ - 151.874999973, - -31.311279627 + 151.875, + -31.3112796 ], [ - 152.401607946, - -31.311279627 + 152.401608, + -31.3112796 ], [ - 152.401607946, - -31.952162233 + 152.401608, + -31.9521622 ] ] ] @@ -43,24 +43,24 @@ [ [ [ - 151.874999973, - -31.311279627 + 151.875, + -31.3112796 ], [ - 151.874999973, - -30.751277771 + 151.875, + -30.7512778 ], [ - 152.401607946, - -30.751277771 + 152.401608, + -30.7512778 ], [ - 152.401607946, - -31.311279627 + 152.401608, + -31.3112796 ], [ - 151.874999973, - -31.311279627 + 151.875, + -31.3112796 ] ] ] @@ -81,56 +81,56 @@ [ [ [ - 152.964694643, - -31.311279627 + 152.9646946, + -31.3112796 ], [ - 152.964694643, - -31.314876311 + 152.9646946, + -31.3148763 ], [ - 152.94092667, - -31.360552708 + 152.9409267, + -31.3605527 ], [ - 152.949562214, - -31.445384196 + 152.9495622, + -31.4453842 ], [ - 152.905274711, - -31.47718046 + 152.9052747, + -31.4771805 ], [ - 152.857738766, - -31.573415644 + 152.8577388, + -31.5734156 ], [ - 152.804260827, - -31.669551593 + 152.8042608, + -31.6695516 ], [ - 152.732956909, - -31.816093707 + 152.7329569, + -31.8160937 ], [ - 152.673536977, - -31.881709671 + 152.673537, + -31.8817097 ], [ 152.5951471, - -31.952162233 + -31.9521622 ], [ - 152.401607946, - -31.952162233 + 152.401608, + -31.9521622 ], [ - 152.401607946, - -31.311279627 + 152.401608, + -31.3112796 ], [ - 152.964694643, - -31.311279627 + 152.9646946, + -31.3112796 ] ] ] @@ -151,52 +151,52 @@ [ [ [ - 153.002629854, - -30.751277771 + 153.0026299, + -30.7512778 ], [ - 153.012230588, - -30.800769981 + 153.0122306, + -30.80077 ], [ - 153.041940554, + 153.0419406, -30.8568964 ], [ 153.0894765, - -30.912989989 + -30.91299 ], [ - 153.047882548, - -30.994521987 + 153.0478825, + -30.994522 ], [ - 153.041940554, - -31.065805365 + 153.0419406, + -31.0658054 ], [ - 153.000346602, - -31.126862915 + 153.0003466, + -31.1268629 ], [ - 152.964694643, - -31.223457045 + 152.9646946, + -31.223457 ], [ - 152.964694643, - -31.311279627 + 152.9646946, + -31.3112796 ], [ - 152.401607946, - -31.311279627 + 152.401608, + -31.3112796 ], [ - 152.401607946, - -30.751277771 + 152.401608, + -30.7512778 ], [ - 153.002629854, - -30.751277771 + 153.0026299, + -30.7512778 ] ] ] @@ -211,4 +211,4 @@ }, "type": "Feature" } -] \ No newline at end of file +] diff --git a/tests/backend/integration/api/projects/test_actions.py b/tests/backend/integration/api/projects/test_actions.py index 63dd809a70..08e0415eb3 100644 --- a/tests/backend/integration/api/projects/test_actions.py +++ b/tests/backend/integration/api/projects/test_actions.py @@ -65,7 +65,7 @@ def test_returns_clipped_grid_if_clip_to_aoi_set_true(self): ) # Assert self.assertEqual(response.status_code, 200) - self.assertDeepAlmostEqual(response.json, expected_response, places=6) + self.assertDeepAlmostEqual(expected_response, geojson.loads(response.text)) def test_returns_not_clipped_grid_if_clip_to_aoi_set_false(self): """Test that the endpoint returns a not clipped grid if clipToAoi is set to false""" @@ -83,7 +83,7 @@ def test_returns_not_clipped_grid_if_clip_to_aoi_set_false(self): ) # Assert self.assertEqual(response.status_code, 200) - self.assertDeepAlmostEqual(response.json, expected_response, places=6) + self.assertDeepAlmostEqual(expected_response, geojson.loads(response.text)) def test_raises_invalid_geojson_exception_if_invalid_aoi(self): """Test that the endpoint raises an InvalidGeoJson exception if the grid is invalid""" diff --git a/tests/backend/integration/services/grid/test_split_service.py b/tests/backend/integration/services/grid/test_split_service.py index f62f5cfd36..8bd61ac617 100644 --- a/tests/backend/integration/services/grid/test_split_service.py +++ b/tests/backend/integration/services/grid/test_split_service.py @@ -35,7 +35,7 @@ def test_split_geom_returns_split_geometries(self): # act result = SplitService._create_split_tasks(x, y, zoom, task_stub) # assert - self.assertDeepAlmostEqual(expected, result, places=6) + self.assertDeepAlmostEqual(expected, result) def test_split_geom_raise_grid_service_error_when_task_not_usable(self): with self.assertRaises(SplitServiceError): @@ -115,4 +115,4 @@ def test_split_non_square_task(self, mock_task): json.dumps(get_canned_json("non_square_split_results.json")) ) result = SplitService._create_split_tasks(task.x, task.y, task.zoom, task) - self.assertDeepAlmostEqual(expected, result, places=6) + self.assertDeepAlmostEqual(expected, result) From 390ed7ff1cf96a2f088071869022206f989fb753 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Mon, 10 Apr 2023 12:41:16 -0600 Subject: [PATCH 13/15] test_project: Add explanation for why the test is flaky Also, add debug output for exception Signed-off-by: Taylor Smock --- backend/models/postgis/project.py | 13 ++++++++++--- tests/backend/unit/models/postgis/test_project.py | 5 ++++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/backend/models/postgis/project.py b/backend/models/postgis/project.py index 2c935bd535..2eb89e44e4 100644 --- a/backend/models/postgis/project.py +++ b/backend/models/postgis/project.py @@ -267,11 +267,18 @@ def set_country_info(self): current_app.config["OSM_NOMINATIM_SERVER_URL"], lat, lng ) try: - country_info = requests.get(url).json() # returns a dict + response = requests.get(url) + response.raise_for_status() + country_info = response.json() # returns a dict if country_info["address"].get("country") is not None: self.country = [country_info["address"]["country"]] - except (KeyError, AttributeError, requests.exceptions.ConnectionError): - pass + except ( + KeyError, + AttributeError, + requests.exceptions.ConnectionError, + requests.exceptions.HTTPError, + ) as e: + current_app.logger.debug(e, exc_info=True) self.save() diff --git a/tests/backend/unit/models/postgis/test_project.py b/tests/backend/unit/models/postgis/test_project.py index 1d9186f925..5698852725 100644 --- a/tests/backend/unit/models/postgis/test_project.py +++ b/tests/backend/unit/models/postgis/test_project.py @@ -61,4 +61,7 @@ def test_set_country_info(self): # Act test_project.set_country_info() # Assert - self.assertNotEqual(0, len(test_project.country)) + self.assertNotEqual( + 0, len(test_project.country), "Nominatim may have given a bad response" + ) + self.assertEqual(["United Kingdom"], test_project.country) From 1467c5a9903ec88dfa30ee66c838935ba500d60b Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Thu, 18 May 2023 13:18:33 -0600 Subject: [PATCH 14/15] ORM updates -- fix deprecation warnings shown in tests (and only those shown by tests) Signed-off-by: Taylor Smock --- backend/models/postgis/custom_editors.py | 2 +- backend/models/postgis/interests.py | 2 +- backend/models/postgis/licenses.py | 2 +- backend/models/postgis/mapping_issues.py | 2 +- backend/models/postgis/organisation.py | 2 +- backend/models/postgis/project.py | 8 ++++---- backend/models/postgis/team.py | 2 +- backend/models/postgis/user.py | 2 +- backend/services/campaign_service.py | 10 +++++----- backend/services/messaging/message_service.py | 6 +++--- backend/services/project_search_service.py | 8 +++++--- 11 files changed, 24 insertions(+), 22 deletions(-) diff --git a/backend/models/postgis/custom_editors.py b/backend/models/postgis/custom_editors.py index 58d2f50e1b..5c74cfb4dd 100644 --- a/backend/models/postgis/custom_editors.py +++ b/backend/models/postgis/custom_editors.py @@ -23,7 +23,7 @@ def save(self): @staticmethod def get_by_project_id(project_id: int): """Get custom editor by it's project id""" - return CustomEditor.query.get(project_id) + return db.session.get(CustomEditor, project_id) @classmethod def create_from_dto(cls, project_id: int, dto: CustomEditorDTO): diff --git a/backend/models/postgis/interests.py b/backend/models/postgis/interests.py index bcffe329e8..ba282e9fe2 100644 --- a/backend/models/postgis/interests.py +++ b/backend/models/postgis/interests.py @@ -30,7 +30,7 @@ class Interest(db.Model): @staticmethod def get_by_id(interest_id: int): """Get interest by id""" - interest = Interest.query.get(interest_id) + interest = db.session.get(Interest, interest_id) if interest is None: raise NotFound(f"Interest id {interest_id} not found") diff --git a/backend/models/postgis/licenses.py b/backend/models/postgis/licenses.py index 5a2db77456..3c65de60f8 100644 --- a/backend/models/postgis/licenses.py +++ b/backend/models/postgis/licenses.py @@ -29,7 +29,7 @@ class License(db.Model): @staticmethod def get_by_id(license_id: int): """Get license by id""" - map_license = License.query.get(license_id) + map_license = db.session.get(License, license_id) if map_license is None: raise NotFound() diff --git a/backend/models/postgis/mapping_issues.py b/backend/models/postgis/mapping_issues.py index 135a5d337b..ef7bc8a3d5 100644 --- a/backend/models/postgis/mapping_issues.py +++ b/backend/models/postgis/mapping_issues.py @@ -20,7 +20,7 @@ def __init__(self, name): @staticmethod def get_by_id(category_id: int): """Get category by id""" - return MappingIssueCategory.query.get(category_id) + return db.session.get(MappingIssueCategory, category_id) @classmethod def create_from_dto(cls, dto: MappingIssueCategoryDTO) -> int: diff --git a/backend/models/postgis/organisation.py b/backend/models/postgis/organisation.py index b9b50df084..dff50df8ad 100644 --- a/backend/models/postgis/organisation.py +++ b/backend/models/postgis/organisation.py @@ -131,7 +131,7 @@ def get(organisation_id: int): :param organisation_id: organisation ID in scope :return: Organisation if found otherwise None """ - return Organisation.query.get(organisation_id) + return db.session.get(Organisation, organisation_id) @staticmethod def get_organisation_by_name(organisation_name: str): diff --git a/backend/models/postgis/project.py b/backend/models/postgis/project.py index 2eb89e44e4..8ccff257b6 100644 --- a/backend/models/postgis/project.py +++ b/backend/models/postgis/project.py @@ -295,7 +295,7 @@ def save(self): def clone(project_id: int, author_id: int): """Clone project""" - orig = Project.query.get(project_id) + orig = db.session.get(Project, project_id) if orig is None: raise NotFound() @@ -530,19 +530,19 @@ def exists(project_id): return db.session.query(literal(True)).filter(query).scalar() def is_favorited(self, user_id: int) -> bool: - user = User.query.get(user_id) + user = db.session.get(User, user_id) if user not in self.favorited: return False return True def favorite(self, user_id: int): - user = User.query.get(user_id) + user = db.session.get(User, user_id) self.favorited.append(user) db.session.commit() def unfavorite(self, user_id: int): - user = User.query.get(user_id) + user = db.session.get(User, user_id) if user not in self.favorited: raise ValueError("NotFeatured- Project not been favorited by user") self.favorited.remove(user) diff --git a/backend/models/postgis/team.py b/backend/models/postgis/team.py index 66ba8a2009..f224965c56 100644 --- a/backend/models/postgis/team.py +++ b/backend/models/postgis/team.py @@ -175,7 +175,7 @@ def get(team_id: int): :param team_id: team ID in scope :return: Team if found otherwise None """ - return Team.query.get(team_id) + return db.session.get(Team, team_id) def get_team_by_name(team_name: str): """ diff --git a/backend/models/postgis/user.py b/backend/models/postgis/user.py index d40aeffc66..8541f82062 100644 --- a/backend/models/postgis/user.py +++ b/backend/models/postgis/user.py @@ -85,7 +85,7 @@ def save(self): @staticmethod def get_by_id(user_id: int): """Return the user for the specified id, or None if not found""" - return User.query.get(user_id) + return db.session.get(User, user_id) @staticmethod def get_by_username(username: str): diff --git a/backend/services/campaign_service.py b/backend/services/campaign_service.py index a4c4038a6a..6090981aab 100644 --- a/backend/services/campaign_service.py +++ b/backend/services/campaign_service.py @@ -23,7 +23,7 @@ class CampaignService: @staticmethod def get_campaign(campaign_id: int) -> Campaign: """Gets the specified campaign""" - campaign = Campaign.query.get(campaign_id) + campaign = db.session.get(Campaign, campaign_id) if campaign is None: raise NotFound() @@ -42,7 +42,7 @@ def get_campaign_by_name(campaign_name: str) -> Campaign: @staticmethod def delete_campaign(campaign_id: int): """Delete campaign for a project""" - campaign = Campaign.query.get(campaign_id) + campaign = db.session.get(Campaign, campaign_id) campaign.delete() campaign.save() @@ -162,8 +162,8 @@ def campaign_organisation_exists(campaign_id: int, org_id: int): @staticmethod def delete_organisation_campaign(organisation_id: int, campaign_id: int): """Delete campaign for a organisation""" - campaign = Campaign.query.get(campaign_id) - org = Organisation.query.get(organisation_id) + campaign = db.session.get(Campaign, campaign_id) + org = db.session.get(Organisation, organisation_id) try: org.campaign.remove(campaign) except ValueError: @@ -176,7 +176,7 @@ def delete_organisation_campaign(organisation_id: int, campaign_id: int): @staticmethod def update_campaign(campaign_dto: CampaignDTO, campaign_id: int): - campaign = Campaign.query.get(campaign_id) + campaign = db.session.get(Campaign, campaign_id) if not campaign: raise NotFound(f"Campaign id {campaign_id} not found") try: diff --git a/backend/services/messaging/message_service.py b/backend/services/messaging/message_service.py index 3ecbe1d76e..a056c87458 100644 --- a/backend/services/messaging/message_service.py +++ b/backend/services/messaging/message_service.py @@ -381,7 +381,7 @@ def send_request_to_join_team( message.message = f"{user_link} has requested to join the {team_link} team.\ Access the team management page to accept or reject that request." MessageService._push_messages( - [dict(message=message, user=User.query.get(to_user))] + [dict(message=message, user=db.session.get(User, to_user))] ) @staticmethod @@ -613,7 +613,7 @@ def _parse_message_for_bulk_mentions( parsed = parser.findall(message) usernames = [] - project = Project.query.get(project_id) + project = db.session.get(Project, project_id) if project is None: return usernames @@ -740,7 +740,7 @@ def get_all_messages( @staticmethod def get_message(message_id: int, user_id: int) -> Message: """Gets the specified message""" - message = Message.query.get(message_id) + message = db.session.get(Message, message_id) if message is None: raise NotFound() diff --git a/backend/services/project_search_service.py b/backend/services/project_search_service.py index a440427a00..6f69da1737 100644 --- a/backend/services/project_search_service.py +++ b/backend/services/project_search_service.py @@ -377,9 +377,11 @@ def _filter_projects(search_dto: ProjectSearchDTO, user): if not search_dto.omit_map_results: query_result = query query_result.column_descriptions.clear() - query_result.add_column(Project.id) - query_result.add_column(Project.centroid.ST_AsGeoJSON().label("centroid")) - query_result.add_column(Project.priority) + query_result.add_columns( + Project.id, + Project.centroid.ST_AsGeoJSON().label("centroid"), + Project.priority, + ) all_results = query_result.all() paginated_results = query.paginate( From c3bd7b8cf22f462370dd261e049df9606b474c32 Mon Sep 17 00:00:00 2001 From: Taylor Smock Date: Mon, 22 May 2023 11:08:09 -0600 Subject: [PATCH 15/15] CI: Set TM_ORG_CODE and TM_ORG_NAME Signed-off-by: Taylor Smock --- .circleci/config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7cdf89c196..7691352ee7 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -67,6 +67,8 @@ jobs: POSTGRES_TEST_DB: test_tm POSTGRES_USER: taskingmanager POSTGRES_ENDPOINT: localhost + TM_ORG_CODE: "CICode" + TM_ORG_NAME: "CircleCI Test Organisation" - image: cimg/postgres:14.2-postgis environment: