├── pyproject.toml ├── README.md ├── .gitignore ├── main.py ├── async_main.py └── poetry.lock /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "redis-om-fastapi" 3 | version = "0.1.1" 4 | description = "An example integration between Redis OM and FastAPI" 5 | authors = ["Andrew Brookins "] 6 | license = "BSD-3-Clause" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.7" 10 | fastapi = "^0.70.0" 11 | uvicorn = "^0.15.0" 12 | pydantic = {extras = ["email"], version = "^1.8.2"} 13 | fastapi-cache2 = {extras = ["redis"], version = "^0.1.7"} 14 | redis-om = "^0.0.17" 15 | 16 | [tool.poetry.dev-dependencies] 17 | 18 | [build-system] 19 | requires = ["poetry-core>=1.0.0"] 20 | build-backend = "poetry.core.masonry.api" 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redis-om-fastapi 2 | 3 | This repository contains an example of how to use [Redis OM Python](https://github.com/redis/redis-om-python) with FastAPI. 4 | 5 | ## Installing 6 | 7 | You install this project with Poetry. 8 | 9 | First, [install Poetry](https://python-poetry.org/docs/#installation). You can probably pip install it into your Python environment: 10 | 11 | $ pip install poetry 12 | 13 | Then install the example app's dependencies: 14 | 15 | $ poetry install 16 | 17 | ## Running the Examples 18 | 19 | This project contains two identical FastAPI applications, one synchronous (main.py) and one asynchronous (async_main.py). Both use Redis OM for Python to save and retrieve data from Redis. 20 | 21 | To try the API, first, start the one of the servers. 22 | 23 | You can start the synchronous server like this, from your terminal: 24 | 25 | $ poetry run uvicorn main:app 26 | 27 | Or the async server like this: 28 | 29 | $ poetry run uvicorn async_main:app 30 | 31 | Then, in another shell, create a customer: 32 | 33 | $ curl -X POST "http://localhost:8000/customer" -H 'Content-Type: application/json' -d '{"first_name":"Andrew","last_name":"Brookins","email":"a@example.com","age":"38","join_date":"2020-01-02"}' 34 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 35 | 36 | Copy the "pk" value, which is the model's primary key, and make another request to get that customer: 37 | 38 | $ curl "http://localhost:8000/customer/01FM2G8EP38AVMH7PMTAJ123TA" 39 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 40 | 41 | You can also get a list of all customer PKs: 42 | 43 | $ curl "http://localhost:8000/customers" 44 | {"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]} 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | data 131 | 132 | # Makefile install checker 133 | .install.stamp 134 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Integration with FastAPI. 3 | ========================= 4 | 5 | To test, first, start the server: 6 | 7 | $ poetry run uvicorn main:app 8 | 9 | Then, in another shell, create a customer: 10 | 11 | $ curl -X POST "http://localhost:8000/customer" -H 'Content-Type: application/json' -d '{"first_name":"Andrew","last_name":"Brookins","email":"a@example.com","age":"38","join_date":"2020 12 | -01-02"}' 13 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 14 | 15 | Get a copy of the value for "pk" and make another request to get that customer: 16 | 17 | $ curl "http://localhost:8000/customer/01FM2G8EP38AVMH7PMTAJ123TA" 18 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 19 | 20 | You can also get a list of all customer PKs: 21 | 22 | $ curl "http://localhost:8000/customers" 23 | {"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]} 24 | """ 25 | 26 | import datetime 27 | from typing import Optional 28 | 29 | import aioredis 30 | 31 | from fastapi import FastAPI, HTTPException 32 | from starlette.requests import Request 33 | from starlette.responses import Response 34 | 35 | from fastapi_cache import FastAPICache 36 | from fastapi_cache.backends.redis import RedisBackend 37 | from fastapi_cache.decorator import cache 38 | 39 | from pydantic import EmailStr 40 | 41 | from redis_om.model import HashModel, NotFoundError 42 | from redis_om.connections import get_redis_connection 43 | 44 | # This Redis instance is tuned for durability. 45 | REDIS_DATA_URL = "redis://localhost:6380" 46 | 47 | # This Redis instance is tuned for cache performance. 48 | REDIS_CACHE_URL = "redis://localhost:6381" 49 | 50 | 51 | class Customer(HashModel): 52 | first_name: str 53 | last_name: str 54 | email: EmailStr 55 | join_date: datetime.date 56 | age: int 57 | bio: Optional[str] 58 | 59 | # You can set the Redis OM URL using the REDIS_OM_URL environment 60 | # variable, or by manually creating the connection using your model's 61 | # Meta object. 62 | class Meta: 63 | database = get_redis_connection(url=REDIS_DATA_URL, decode_responses=True) 64 | 65 | 66 | app = FastAPI() 67 | 68 | 69 | @app.post("/customer") 70 | async def save_customer(customer: Customer): 71 | # We can save the model to Redis by calling `save()`: 72 | return customer.save() 73 | 74 | 75 | @app.get("/customers") 76 | async def list_customers(request: Request, response: Response): 77 | # To retrieve this customer with its primary key, we use `Customer.get()`: 78 | return {"customers": Customer.all_pks()} 79 | 80 | 81 | @app.get("/customer/{pk}") 82 | @cache(expire=10) 83 | async def get_customer(pk: str, request: Request, response: Response): 84 | # To retrieve this customer with its primary key, we use `Customer.get()`: 85 | try: 86 | return Customer.get(pk) 87 | except NotFoundError: 88 | raise HTTPException(status_code=404, detail="Customer not found") 89 | 90 | 91 | @app.on_event("startup") 92 | async def startup(): 93 | r = aioredis.from_url(REDIS_CACHE_URL, encoding="utf8", decode_responses=True) 94 | FastAPICache.init(RedisBackend(r), prefix="fastapi-cache") 95 | -------------------------------------------------------------------------------- /async_main.py: -------------------------------------------------------------------------------- 1 | """ 2 | Integration with FastAPI. 3 | ========================= 4 | 5 | To test, first, start the server: 6 | 7 | $ poetry run uvicorn async_main:app 8 | 9 | Then, in another shell, create a customer: 10 | 11 | $ curl -X POST "http://localhost:8000/customer" -H 'Content-Type: application/json' -d '{"first_name":"Andrew","last_name":"Brookins","email":"a@example.com","age":"38","join_date":"2020 12 | -01-02"}' 13 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 14 | 15 | Get a copy of the value for "pk" and make another request to get that customer: 16 | 17 | $ curl "http://localhost:8000/customer/01FM2G8EP38AVMH7PMTAJ123TA" 18 | {"pk":"01FM2G8EP38AVMH7PMTAJ123TA","first_name":"Andrew","last_name":"Brookins","email":"a@example.com","join_date":"2020-01-02","age":38,"bio":""} 19 | 20 | You can also get a list of all customer PKs: 21 | 22 | $ curl "http://localhost:8000/customers" 23 | {"customers":["01FM2G8EP38AVMH7PMTAJ123TA"]} 24 | """ 25 | 26 | import datetime 27 | from typing import Optional 28 | 29 | import aioredis 30 | 31 | from fastapi import FastAPI, HTTPException 32 | from starlette.requests import Request 33 | from starlette.responses import Response 34 | 35 | from fastapi_cache import FastAPICache 36 | from fastapi_cache.backends.redis import RedisBackend 37 | from fastapi_cache.decorator import cache 38 | 39 | from pydantic import EmailStr 40 | 41 | from aredis_om.model import HashModel, NotFoundError 42 | from aredis_om.connections import get_redis_connection 43 | 44 | # This Redis instance is tuned for durability. 45 | REDIS_DATA_URL = "redis://localhost:6380" 46 | 47 | # This Redis instance is tuned for cache performance. 48 | REDIS_CACHE_URL = "redis://localhost:6381" 49 | 50 | 51 | class Customer(HashModel): 52 | first_name: str 53 | last_name: str 54 | email: EmailStr 55 | join_date: datetime.date 56 | age: int 57 | bio: Optional[str] 58 | 59 | # You can set the Redis OM URL using the REDIS_OM_URL environment 60 | # variable, or by manually creating the connection using your model's 61 | # Meta object. 62 | class Meta: 63 | database = get_redis_connection(url=REDIS_DATA_URL, decode_responses=True) 64 | 65 | 66 | app = FastAPI() 67 | 68 | 69 | @app.post("/customer") 70 | async def save_customer(customer: Customer): 71 | # We can save the model to Redis by calling `save()`: 72 | return await customer.save() 73 | 74 | 75 | @app.get("/customers") 76 | async def list_customers(request: Request, response: Response): 77 | # To retrieve this customer with its primary key, we use `Customer.get()`: 78 | return {"customers": [pk async for pk in await Customer.all_pks()]} 79 | 80 | 81 | @app.get("/customer/{pk}") 82 | @cache(expire=10) 83 | async def get_customer(pk: str, request: Request, response: Response): 84 | # To retrieve this customer with its primary key, we use `Customer.get()`: 85 | try: 86 | return await Customer.get(pk) 87 | except NotFoundError: 88 | raise HTTPException(status_code=404, detail="Customer not found") 89 | 90 | 91 | @app.on_event("startup") 92 | async def startup(): 93 | r = aioredis.from_url(REDIS_CACHE_URL, encoding="utf8", decode_responses=True) 94 | FastAPICache.init(RedisBackend(r), prefix="fastapi-cache") 95 | -------------------------------------------------------------------------------- /poetry.lock: -------------------------------------------------------------------------------- 1 | [[package]] 2 | name = "aioredis" 3 | version = "2.0.1" 4 | description = "asyncio (PEP 3156) Redis support" 5 | category = "main" 6 | optional = false 7 | python-versions = ">=3.6" 8 | 9 | [package.dependencies] 10 | async-timeout = "*" 11 | typing-extensions = "*" 12 | 13 | [package.extras] 14 | hiredis = ["hiredis (>=1.0)"] 15 | 16 | [[package]] 17 | name = "anyio" 18 | version = "3.5.0" 19 | description = "High level compatibility layer for multiple asynchronous event loop implementations" 20 | category = "main" 21 | optional = false 22 | python-versions = ">=3.6.2" 23 | 24 | [package.dependencies] 25 | idna = ">=2.8" 26 | sniffio = ">=1.1" 27 | typing-extensions = {version = "*", markers = "python_version < \"3.8\""} 28 | 29 | [package.extras] 30 | doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] 31 | test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] 32 | trio = ["trio (>=0.16)"] 33 | 34 | [[package]] 35 | name = "asgiref" 36 | version = "3.4.1" 37 | description = "ASGI specs, helper code, and adapters" 38 | category = "main" 39 | optional = false 40 | python-versions = ">=3.6" 41 | 42 | [package.dependencies] 43 | typing-extensions = {version = "*", markers = "python_version < \"3.8\""} 44 | 45 | [package.extras] 46 | tests = ["pytest", "pytest-asyncio", "mypy (>=0.800)"] 47 | 48 | [[package]] 49 | name = "async-timeout" 50 | version = "4.0.2" 51 | description = "Timeout context manager for asyncio programs" 52 | category = "main" 53 | optional = false 54 | python-versions = ">=3.6" 55 | 56 | [package.dependencies] 57 | typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} 58 | 59 | [[package]] 60 | name = "cleo" 61 | version = "1.0.0a4" 62 | description = "Cleo allows you to create beautiful and testable command-line interfaces." 63 | category = "main" 64 | optional = false 65 | python-versions = ">=3.6,<4.0" 66 | 67 | [package.dependencies] 68 | crashtest = ">=0.3.1,<0.4.0" 69 | pylev = ">=1.3.0,<2.0.0" 70 | 71 | [[package]] 72 | name = "click" 73 | version = "8.0.3" 74 | description = "Composable command line interface toolkit" 75 | category = "main" 76 | optional = false 77 | python-versions = ">=3.6" 78 | 79 | [package.dependencies] 80 | colorama = {version = "*", markers = "platform_system == \"Windows\""} 81 | importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} 82 | 83 | [[package]] 84 | name = "colorama" 85 | version = "0.4.4" 86 | description = "Cross-platform colored terminal text." 87 | category = "main" 88 | optional = false 89 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 90 | 91 | [[package]] 92 | name = "crashtest" 93 | version = "0.3.1" 94 | description = "Manage Python errors with ease" 95 | category = "main" 96 | optional = false 97 | python-versions = ">=3.6,<4.0" 98 | 99 | [[package]] 100 | name = "deprecated" 101 | version = "1.2.13" 102 | description = "Python @deprecated decorator to deprecate old python classes, functions or methods." 103 | category = "main" 104 | optional = false 105 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 106 | 107 | [package.dependencies] 108 | wrapt = ">=1.10,<2" 109 | 110 | [package.extras] 111 | dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] 112 | 113 | [[package]] 114 | name = "dnspython" 115 | version = "2.2.0" 116 | description = "DNS toolkit" 117 | category = "main" 118 | optional = false 119 | python-versions = ">=3.6,<4.0" 120 | 121 | [package.extras] 122 | dnssec = ["cryptography (>=2.6,<37.0)"] 123 | curio = ["curio (>=1.2,<2.0)", "sniffio (>=1.1,<2.0)"] 124 | doh = ["h2 (>=4.1.0)", "httpx (>=0.21.1)", "requests (>=2.23.0,<3.0.0)", "requests-toolbelt (>=0.9.1,<0.10.0)"] 125 | idna = ["idna (>=2.1,<4.0)"] 126 | trio = ["trio (>=0.14,<0.20)"] 127 | wmi = ["wmi (>=1.5.1,<2.0.0)"] 128 | 129 | [[package]] 130 | name = "email-validator" 131 | version = "1.1.3" 132 | description = "A robust email syntax and deliverability validation library for Python 2.x/3.x." 133 | category = "main" 134 | optional = false 135 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 136 | 137 | [package.dependencies] 138 | dnspython = ">=1.15.0" 139 | idna = ">=2.0.0" 140 | 141 | [[package]] 142 | name = "fastapi" 143 | version = "0.70.1" 144 | description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" 145 | category = "main" 146 | optional = false 147 | python-versions = ">=3.6.1" 148 | 149 | [package.dependencies] 150 | pydantic = ">=1.6.2,<1.7 || >1.7,<1.7.1 || >1.7.1,<1.7.2 || >1.7.2,<1.7.3 || >1.7.3,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0" 151 | starlette = "0.16.0" 152 | 153 | [package.extras] 154 | all = ["requests (>=2.24.0,<3.0.0)", "jinja2 (>=2.11.2,<4.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "itsdangerous (>=1.1.0,<3.0.0)", "pyyaml (>=5.3.1,<6.0.0)", "ujson (>=4.0.1,<5.0.0)", "orjson (>=3.2.1,<4.0.0)", "email_validator (>=1.1.1,<2.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"] 155 | dev = ["python-jose[cryptography] (>=3.3.0,<4.0.0)", "passlib[bcrypt] (>=1.7.2,<2.0.0)", "autoflake (>=1.4.0,<2.0.0)", "flake8 (>=3.8.3,<4.0.0)", "uvicorn[standard] (>=0.12.0,<0.16.0)"] 156 | doc = ["mkdocs (>=1.1.2,<2.0.0)", "mkdocs-material (>=7.1.9,<8.0.0)", "mdx-include (>=1.4.1,<2.0.0)", "mkdocs-markdownextradata-plugin (>=0.1.7,<0.3.0)", "typer-cli (>=0.0.12,<0.0.13)", "pyyaml (>=5.3.1,<6.0.0)"] 157 | test = ["pytest (>=6.2.4,<7.0.0)", "pytest-cov (>=2.12.0,<4.0.0)", "mypy (==0.910)", "flake8 (>=3.8.3,<4.0.0)", "black (==21.9b0)", "isort (>=5.0.6,<6.0.0)", "requests (>=2.24.0,<3.0.0)", "httpx (>=0.14.0,<0.19.0)", "email_validator (>=1.1.1,<2.0.0)", "sqlalchemy (>=1.3.18,<1.5.0)", "peewee (>=3.13.3,<4.0.0)", "databases[sqlite] (>=0.3.2,<0.6.0)", "orjson (>=3.2.1,<4.0.0)", "ujson (>=4.0.1,<5.0.0)", "python-multipart (>=0.0.5,<0.0.6)", "flask (>=1.1.2,<3.0.0)", "anyio[trio] (>=3.2.1,<4.0.0)", "types-ujson (==0.1.1)", "types-orjson (==3.6.0)", "types-dataclasses (==0.1.7)"] 158 | 159 | [[package]] 160 | name = "fastapi-cache2" 161 | version = "0.1.8" 162 | description = "Cache for FastAPI" 163 | category = "main" 164 | optional = false 165 | python-versions = ">=3.7,<4.0" 166 | 167 | [package.dependencies] 168 | aioredis = {version = ">=2.0,<3.0", optional = true, markers = "extra == \"redis\" or extra == \"all\""} 169 | fastapi = "*" 170 | pendulum = "*" 171 | uvicorn = "*" 172 | 173 | [package.extras] 174 | dynamodb = ["aiobotocore (>=1.4.1,<2.0.0)"] 175 | memcache = ["aiomcache"] 176 | all = ["aiomcache", "aioredis (>=2.0,<3.0)"] 177 | redis = ["aioredis (>=2.0,<3.0)"] 178 | 179 | [[package]] 180 | name = "h11" 181 | version = "0.13.0" 182 | description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" 183 | category = "main" 184 | optional = false 185 | python-versions = ">=3.6" 186 | 187 | [package.dependencies] 188 | typing-extensions = {version = "*", markers = "python_version < \"3.8\""} 189 | 190 | [[package]] 191 | name = "hiredis" 192 | version = "2.0.0" 193 | description = "Python wrapper for hiredis" 194 | category = "main" 195 | optional = false 196 | python-versions = ">=3.6" 197 | 198 | [[package]] 199 | name = "idna" 200 | version = "3.3" 201 | description = "Internationalized Domain Names in Applications (IDNA)" 202 | category = "main" 203 | optional = false 204 | python-versions = ">=3.5" 205 | 206 | [[package]] 207 | name = "importlib-metadata" 208 | version = "4.10.1" 209 | description = "Read metadata from Python packages" 210 | category = "main" 211 | optional = false 212 | python-versions = ">=3.7" 213 | 214 | [package.dependencies] 215 | typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} 216 | zipp = ">=0.5" 217 | 218 | [package.extras] 219 | docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] 220 | perf = ["ipython"] 221 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] 222 | 223 | [[package]] 224 | name = "packaging" 225 | version = "21.3" 226 | description = "Core utilities for Python packages" 227 | category = "main" 228 | optional = false 229 | python-versions = ">=3.6" 230 | 231 | [package.dependencies] 232 | pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" 233 | 234 | [[package]] 235 | name = "pendulum" 236 | version = "2.1.2" 237 | description = "Python datetimes made easy" 238 | category = "main" 239 | optional = false 240 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" 241 | 242 | [package.dependencies] 243 | python-dateutil = ">=2.6,<3.0" 244 | pytzdata = ">=2020.1" 245 | 246 | [[package]] 247 | name = "pptree" 248 | version = "3.1" 249 | description = "Pretty print trees" 250 | category = "main" 251 | optional = false 252 | python-versions = "*" 253 | 254 | [[package]] 255 | name = "pydantic" 256 | version = "1.9.0" 257 | description = "Data validation and settings management using python 3.6 type hinting" 258 | category = "main" 259 | optional = false 260 | python-versions = ">=3.6.1" 261 | 262 | [package.dependencies] 263 | email-validator = {version = ">=1.0.3", optional = true, markers = "extra == \"email\""} 264 | typing-extensions = ">=3.7.4.3" 265 | 266 | [package.extras] 267 | dotenv = ["python-dotenv (>=0.10.4)"] 268 | email = ["email-validator (>=1.0.3)"] 269 | 270 | [[package]] 271 | name = "pylev" 272 | version = "1.4.0" 273 | description = "A pure Python Levenshtein implementation that's not freaking GPL'd." 274 | category = "main" 275 | optional = false 276 | python-versions = "*" 277 | 278 | [[package]] 279 | name = "pyparsing" 280 | version = "3.0.6" 281 | description = "Python parsing module" 282 | category = "main" 283 | optional = false 284 | python-versions = ">=3.6" 285 | 286 | [package.extras] 287 | diagrams = ["jinja2", "railroad-diagrams"] 288 | 289 | [[package]] 290 | name = "python-dateutil" 291 | version = "2.8.2" 292 | description = "Extensions to the standard Python datetime module" 293 | category = "main" 294 | optional = false 295 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" 296 | 297 | [package.dependencies] 298 | six = ">=1.5" 299 | 300 | [[package]] 301 | name = "python-dotenv" 302 | version = "0.19.2" 303 | description = "Read key-value pairs from a .env file and set them as environment variables" 304 | category = "main" 305 | optional = false 306 | python-versions = ">=3.5" 307 | 308 | [package.extras] 309 | cli = ["click (>=5.0)"] 310 | 311 | [[package]] 312 | name = "python-ulid" 313 | version = "1.0.3" 314 | description = "Universally Unique Lexicographically Sortable Identifier" 315 | category = "main" 316 | optional = false 317 | python-versions = "*" 318 | 319 | [[package]] 320 | name = "pytzdata" 321 | version = "2020.1" 322 | description = "The Olson timezone database for Python." 323 | category = "main" 324 | optional = false 325 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" 326 | 327 | [[package]] 328 | name = "redis" 329 | version = "4.1.1" 330 | description = "Python client for Redis database and key-value store" 331 | category = "main" 332 | optional = false 333 | python-versions = ">=3.6" 334 | 335 | [package.dependencies] 336 | deprecated = ">=1.2.3" 337 | importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} 338 | packaging = ">=20.4" 339 | 340 | [package.extras] 341 | hiredis = ["hiredis (>=1.0.0)"] 342 | ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] 343 | 344 | [[package]] 345 | name = "redis-om" 346 | version = "0.0.17" 347 | description = "Objecting mapping, and more, for Redis." 348 | category = "main" 349 | optional = false 350 | python-versions = ">=3.7,<4.0" 351 | 352 | [package.dependencies] 353 | aioredis = ">=2.0.0,<3.0.0" 354 | cleo = "1.0.0a4" 355 | click = ">=8.0.1,<9.0.0" 356 | hiredis = ">=2.0.0,<3.0.0" 357 | pptree = ">=3.1,<4.0" 358 | pydantic = ">=1.8.2,<2.0.0" 359 | python-dotenv = ">=0.19.1,<0.20.0" 360 | python-ulid = ">=1.0.3,<2.0.0" 361 | redis = ">=3.5.3,<5.0.0" 362 | six = ">=1.16.0,<2.0.0" 363 | types-redis = ">=3.5.9,<5.0.0" 364 | types-six = ">=1.16.1,<2.0.0" 365 | typing-extensions = ">=4.0.0,<5.0.0" 366 | 367 | [[package]] 368 | name = "six" 369 | version = "1.16.0" 370 | description = "Python 2 and 3 compatibility utilities" 371 | category = "main" 372 | optional = false 373 | python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" 374 | 375 | [[package]] 376 | name = "sniffio" 377 | version = "1.2.0" 378 | description = "Sniff out which async library your code is running under" 379 | category = "main" 380 | optional = false 381 | python-versions = ">=3.5" 382 | 383 | [[package]] 384 | name = "starlette" 385 | version = "0.16.0" 386 | description = "The little ASGI library that shines." 387 | category = "main" 388 | optional = false 389 | python-versions = ">=3.6" 390 | 391 | [package.dependencies] 392 | anyio = ">=3.0.0,<4" 393 | typing-extensions = {version = "*", markers = "python_version < \"3.8\""} 394 | 395 | [package.extras] 396 | full = ["itsdangerous", "jinja2", "python-multipart", "pyyaml", "requests", "graphene"] 397 | 398 | [[package]] 399 | name = "types-redis" 400 | version = "4.1.10" 401 | description = "Typing stubs for redis" 402 | category = "main" 403 | optional = false 404 | python-versions = "*" 405 | 406 | [[package]] 407 | name = "types-six" 408 | version = "1.16.10" 409 | description = "Typing stubs for six" 410 | category = "main" 411 | optional = false 412 | python-versions = "*" 413 | 414 | [[package]] 415 | name = "typing-extensions" 416 | version = "4.0.1" 417 | description = "Backported and Experimental Type Hints for Python 3.6+" 418 | category = "main" 419 | optional = false 420 | python-versions = ">=3.6" 421 | 422 | [[package]] 423 | name = "uvicorn" 424 | version = "0.15.0" 425 | description = "The lightning-fast ASGI server." 426 | category = "main" 427 | optional = false 428 | python-versions = "*" 429 | 430 | [package.dependencies] 431 | asgiref = ">=3.4.0" 432 | click = ">=7.0" 433 | h11 = ">=0.8" 434 | typing-extensions = {version = "*", markers = "python_version < \"3.8\""} 435 | 436 | [package.extras] 437 | standard = ["websockets (>=9.1)", "httptools (>=0.2.0,<0.3.0)", "watchgod (>=0.6)", "python-dotenv (>=0.13)", "PyYAML (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "colorama (>=0.4)"] 438 | 439 | [[package]] 440 | name = "wrapt" 441 | version = "1.13.3" 442 | description = "Module for decorators, wrappers and monkey patching." 443 | category = "main" 444 | optional = false 445 | python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" 446 | 447 | [[package]] 448 | name = "zipp" 449 | version = "3.7.0" 450 | description = "Backport of pathlib-compatible object wrapper for zip files" 451 | category = "main" 452 | optional = false 453 | python-versions = ">=3.7" 454 | 455 | [package.extras] 456 | docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] 457 | testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] 458 | 459 | [metadata] 460 | lock-version = "1.1" 461 | python-versions = "^3.7" 462 | content-hash = "1fd23429afe7e321d4b9f599165691a8f59aa78c3cd2aabd5e7ed58a06734263" 463 | 464 | [metadata.files] 465 | aioredis = [ 466 | {file = "aioredis-2.0.1-py3-none-any.whl", hash = "sha256:9ac0d0b3b485d293b8ca1987e6de8658d7dafcca1cddfcd1d506cae8cdebfdd6"}, 467 | {file = "aioredis-2.0.1.tar.gz", hash = "sha256:eaa51aaf993f2d71f54b70527c440437ba65340588afeb786cd87c55c89cd98e"}, 468 | ] 469 | anyio = [ 470 | {file = "anyio-3.5.0-py3-none-any.whl", hash = "sha256:b5fa16c5ff93fa1046f2eeb5bbff2dad4d3514d6cda61d02816dba34fa8c3c2e"}, 471 | {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, 472 | ] 473 | asgiref = [ 474 | {file = "asgiref-3.4.1-py3-none-any.whl", hash = "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"}, 475 | {file = "asgiref-3.4.1.tar.gz", hash = "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9"}, 476 | ] 477 | async-timeout = [ 478 | {file = "async-timeout-4.0.2.tar.gz", hash = "sha256:2163e1640ddb52b7a8c80d0a67a08587e5d245cc9c553a74a847056bc2976b15"}, 479 | {file = "async_timeout-4.0.2-py3-none-any.whl", hash = "sha256:8ca1e4fcf50d07413d66d1a5e416e42cfdf5851c981d679a09851a6853383b3c"}, 480 | ] 481 | cleo = [ 482 | {file = "cleo-1.0.0a4-py3-none-any.whl", hash = "sha256:cdd0c3458c15ced3a9f0204b1e53a1b4bee3c56ebcb3ac54c872a56acc657a09"}, 483 | {file = "cleo-1.0.0a4.tar.gz", hash = "sha256:a103a065d031b7d936ee88a6b93086a69bd9c1b40fa2ebfe8c056285a66b481d"}, 484 | ] 485 | click = [ 486 | {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, 487 | {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, 488 | ] 489 | colorama = [ 490 | {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, 491 | {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, 492 | ] 493 | crashtest = [ 494 | {file = "crashtest-0.3.1-py3-none-any.whl", hash = "sha256:300f4b0825f57688b47b6d70c6a31de33512eb2fa1ac614f780939aa0cf91680"}, 495 | {file = "crashtest-0.3.1.tar.gz", hash = "sha256:42ca7b6ce88b6c7433e2ce47ea884e91ec93104a4b754998be498a8e6c3d37dd"}, 496 | ] 497 | deprecated = [ 498 | {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, 499 | {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, 500 | ] 501 | dnspython = [ 502 | {file = "dnspython-2.2.0-py3-none-any.whl", hash = "sha256:081649da27ced5e75709a1ee542136eaba9842a0fe4c03da4fb0a3d3ed1f3c44"}, 503 | {file = "dnspython-2.2.0.tar.gz", hash = "sha256:e79351e032d0b606b98d38a4b0e6e2275b31a5b85c873e587cc11b73aca026d6"}, 504 | ] 505 | email-validator = [ 506 | {file = "email_validator-1.1.3-py2.py3-none-any.whl", hash = "sha256:5675c8ceb7106a37e40e2698a57c056756bf3f272cfa8682a4f87ebd95d8440b"}, 507 | {file = "email_validator-1.1.3.tar.gz", hash = "sha256:aa237a65f6f4da067119b7df3f13e89c25c051327b2b5b66dc075f33d62480d7"}, 508 | ] 509 | fastapi = [ 510 | {file = "fastapi-0.70.1-py3-none-any.whl", hash = "sha256:5367226c7bcd7bfb2e17edaf225fd9a983095b1372281e9a3eb661336fb93748"}, 511 | {file = "fastapi-0.70.1.tar.gz", hash = "sha256:21d03979b5336375c66fa5d1f3126c6beca650d5d2166fbb78345a30d33c8d06"}, 512 | ] 513 | fastapi-cache2 = [ 514 | {file = "fastapi-cache2-0.1.8.tar.gz", hash = "sha256:e074a6dad600f9a19f0e7111f58350d6cc7c17d27a0bad1f67336d178b19387b"}, 515 | {file = "fastapi_cache2-0.1.8-py3-none-any.whl", hash = "sha256:7cdd5037cdc0b10a99c0effcef30c42e212f4fc20db49a472dbf0d42174e955a"}, 516 | ] 517 | h11 = [ 518 | {file = "h11-0.13.0-py3-none-any.whl", hash = "sha256:8ddd78563b633ca55346c8cd41ec0af27d3c79931828beffb46ce70a379e7442"}, 519 | {file = "h11-0.13.0.tar.gz", hash = "sha256:70813c1135087a248a4d38cc0e1a0181ffab2188141a93eaf567940c3957ff06"}, 520 | ] 521 | hiredis = [ 522 | {file = "hiredis-2.0.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b4c8b0bc5841e578d5fb32a16e0c305359b987b850a06964bd5a62739d688048"}, 523 | {file = "hiredis-2.0.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0adea425b764a08270820531ec2218d0508f8ae15a448568109ffcae050fee26"}, 524 | {file = "hiredis-2.0.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:3d55e36715ff06cdc0ab62f9591607c4324297b6b6ce5b58cb9928b3defe30ea"}, 525 | {file = "hiredis-2.0.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:5d2a48c80cf5a338d58aae3c16872f4d452345e18350143b3bf7216d33ba7b99"}, 526 | {file = "hiredis-2.0.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:240ce6dc19835971f38caf94b5738092cb1e641f8150a9ef9251b7825506cb05"}, 527 | {file = "hiredis-2.0.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:5dc7a94bb11096bc4bffd41a3c4f2b958257085c01522aa81140c68b8bf1630a"}, 528 | {file = "hiredis-2.0.0-cp36-cp36m-win32.whl", hash = "sha256:139705ce59d94eef2ceae9fd2ad58710b02aee91e7fa0ccb485665ca0ecbec63"}, 529 | {file = "hiredis-2.0.0-cp36-cp36m-win_amd64.whl", hash = "sha256:c39c46d9e44447181cd502a35aad2bb178dbf1b1f86cf4db639d7b9614f837c6"}, 530 | {file = "hiredis-2.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:adf4dd19d8875ac147bf926c727215a0faf21490b22c053db464e0bf0deb0485"}, 531 | {file = "hiredis-2.0.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0f41827028901814c709e744060843c77e78a3aca1e0d6875d2562372fcb405a"}, 532 | {file = "hiredis-2.0.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:508999bec4422e646b05c95c598b64bdbef1edf0d2b715450a078ba21b385bcc"}, 533 | {file = "hiredis-2.0.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:0d5109337e1db373a892fdcf78eb145ffb6bbd66bb51989ec36117b9f7f9b579"}, 534 | {file = "hiredis-2.0.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:04026461eae67fdefa1949b7332e488224eac9e8f2b5c58c98b54d29af22093e"}, 535 | {file = "hiredis-2.0.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:a00514362df15af041cc06e97aebabf2895e0a7c42c83c21894be12b84402d79"}, 536 | {file = "hiredis-2.0.0-cp37-cp37m-win32.whl", hash = "sha256:09004096e953d7ebd508cded79f6b21e05dff5d7361771f59269425108e703bc"}, 537 | {file = "hiredis-2.0.0-cp37-cp37m-win_amd64.whl", hash = "sha256:f8196f739092a78e4f6b1b2172679ed3343c39c61a3e9d722ce6fcf1dac2824a"}, 538 | {file = "hiredis-2.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:294a6697dfa41a8cba4c365dd3715abc54d29a86a40ec6405d677ca853307cfb"}, 539 | {file = "hiredis-2.0.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:3dddf681284fe16d047d3ad37415b2e9ccdc6c8986c8062dbe51ab9a358b50a5"}, 540 | {file = "hiredis-2.0.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:dcef843f8de4e2ff5e35e96ec2a4abbdf403bd0f732ead127bd27e51f38ac298"}, 541 | {file = "hiredis-2.0.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:87c7c10d186f1743a8fd6a971ab6525d60abd5d5d200f31e073cd5e94d7e7a9d"}, 542 | {file = "hiredis-2.0.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:7f0055f1809b911ab347a25d786deff5e10e9cf083c3c3fd2dd04e8612e8d9db"}, 543 | {file = "hiredis-2.0.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:11d119507bb54e81f375e638225a2c057dda748f2b1deef05c2b1a5d42686048"}, 544 | {file = "hiredis-2.0.0-cp38-cp38-win32.whl", hash = "sha256:7492af15f71f75ee93d2a618ca53fea8be85e7b625e323315169977fae752426"}, 545 | {file = "hiredis-2.0.0-cp38-cp38-win_amd64.whl", hash = "sha256:65d653df249a2f95673976e4e9dd7ce10de61cfc6e64fa7eeaa6891a9559c581"}, 546 | {file = "hiredis-2.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ae8427a5e9062ba66fc2c62fb19a72276cf12c780e8db2b0956ea909c48acff5"}, 547 | {file = "hiredis-2.0.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:3f5f7e3a4ab824e3de1e1700f05ad76ee465f5f11f5db61c4b297ec29e692b2e"}, 548 | {file = "hiredis-2.0.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:e3447d9e074abf0e3cd85aef8131e01ab93f9f0e86654db7ac8a3f73c63706ce"}, 549 | {file = "hiredis-2.0.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:8b42c0dc927b8d7c0eb59f97e6e34408e53bc489f9f90e66e568f329bff3e443"}, 550 | {file = "hiredis-2.0.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:b84f29971f0ad4adaee391c6364e6f780d5aae7e9226d41964b26b49376071d0"}, 551 | {file = "hiredis-2.0.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:0b39ec237459922c6544d071cdcf92cbb5bc6685a30e7c6d985d8a3e3a75326e"}, 552 | {file = "hiredis-2.0.0-cp39-cp39-win32.whl", hash = "sha256:a7928283143a401e72a4fad43ecc85b35c27ae699cf5d54d39e1e72d97460e1d"}, 553 | {file = "hiredis-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:a4ee8000454ad4486fb9f28b0cab7fa1cd796fc36d639882d0b34109b5b3aec9"}, 554 | {file = "hiredis-2.0.0-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:1f03d4dadd595f7a69a75709bc81902673fa31964c75f93af74feac2f134cc54"}, 555 | {file = "hiredis-2.0.0-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:04927a4c651a0e9ec11c68e4427d917e44ff101f761cd3b5bc76f86aaa431d27"}, 556 | {file = "hiredis-2.0.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:a39efc3ade8c1fb27c097fd112baf09d7fd70b8cb10ef1de4da6efbe066d381d"}, 557 | {file = "hiredis-2.0.0-pp36-pypy36_pp73-win32.whl", hash = "sha256:07bbf9bdcb82239f319b1f09e8ef4bdfaec50ed7d7ea51a56438f39193271163"}, 558 | {file = "hiredis-2.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:807b3096205c7cec861c8803a6738e33ed86c9aae76cac0e19454245a6bbbc0a"}, 559 | {file = "hiredis-2.0.0-pp37-pypy37_pp73-manylinux1_x86_64.whl", hash = "sha256:1233e303645f468e399ec906b6b48ab7cd8391aae2d08daadbb5cad6ace4bd87"}, 560 | {file = "hiredis-2.0.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:cb2126603091902767d96bcb74093bd8b14982f41809f85c9b96e519c7e1dc41"}, 561 | {file = "hiredis-2.0.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:f52010e0a44e3d8530437e7da38d11fb822acfb0d5b12e9cd5ba655509937ca0"}, 562 | {file = "hiredis-2.0.0.tar.gz", hash = "sha256:81d6d8e39695f2c37954d1011c0480ef7cf444d4e3ae24bc5e89ee5de360139a"}, 563 | ] 564 | idna = [ 565 | {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, 566 | {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, 567 | ] 568 | importlib-metadata = [ 569 | {file = "importlib_metadata-4.10.1-py3-none-any.whl", hash = "sha256:899e2a40a8c4a1aec681feef45733de8a6c58f3f6a0dbed2eb6574b4387a77b6"}, 570 | {file = "importlib_metadata-4.10.1.tar.gz", hash = "sha256:951f0d8a5b7260e9db5e41d429285b5f451e928479f19d80818878527d36e95e"}, 571 | ] 572 | packaging = [ 573 | {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, 574 | {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, 575 | ] 576 | pendulum = [ 577 | {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, 578 | {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, 579 | {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, 580 | {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, 581 | {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, 582 | {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, 583 | {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, 584 | {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, 585 | {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, 586 | {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, 587 | {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, 588 | {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, 589 | {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, 590 | {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, 591 | {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, 592 | {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, 593 | {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, 594 | {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, 595 | {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, 596 | {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, 597 | {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, 598 | ] 599 | pptree = [ 600 | {file = "pptree-3.1.tar.gz", hash = "sha256:4dd0ba2f58000cbd29d68a5b64bac29bcb5a663642f79404877c0059668a69f6"}, 601 | ] 602 | pydantic = [ 603 | {file = "pydantic-1.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cb23bcc093697cdea2708baae4f9ba0e972960a835af22560f6ae4e7e47d33f5"}, 604 | {file = "pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1d5278bd9f0eee04a44c712982343103bba63507480bfd2fc2790fa70cd64cf4"}, 605 | {file = "pydantic-1.9.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ab624700dc145aa809e6f3ec93fb8e7d0f99d9023b713f6a953637429b437d37"}, 606 | {file = "pydantic-1.9.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c8d7da6f1c1049eefb718d43d99ad73100c958a5367d30b9321b092771e96c25"}, 607 | {file = "pydantic-1.9.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:3c3b035103bd4e2e4a28da9da7ef2fa47b00ee4a9cf4f1a735214c1bcd05e0f6"}, 608 | {file = "pydantic-1.9.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3011b975c973819883842c5ab925a4e4298dffccf7782c55ec3580ed17dc464c"}, 609 | {file = "pydantic-1.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:086254884d10d3ba16da0588604ffdc5aab3f7f09557b998373e885c690dd398"}, 610 | {file = "pydantic-1.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0fe476769acaa7fcddd17cadd172b156b53546ec3614a4d880e5d29ea5fbce65"}, 611 | {file = "pydantic-1.9.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c8e9dcf1ac499679aceedac7e7ca6d8641f0193c591a2d090282aaf8e9445a46"}, 612 | {file = "pydantic-1.9.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d1e4c28f30e767fd07f2ddc6f74f41f034d1dd6bc526cd59e63a82fe8bb9ef4c"}, 613 | {file = "pydantic-1.9.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:c86229333cabaaa8c51cf971496f10318c4734cf7b641f08af0a6fbf17ca3054"}, 614 | {file = "pydantic-1.9.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:c0727bda6e38144d464daec31dff936a82917f431d9c39c39c60a26567eae3ed"}, 615 | {file = "pydantic-1.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:dee5ef83a76ac31ab0c78c10bd7d5437bfdb6358c95b91f1ba7ff7b76f9996a1"}, 616 | {file = "pydantic-1.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d9c9bdb3af48e242838f9f6e6127de9be7063aad17b32215ccc36a09c5cf1070"}, 617 | {file = "pydantic-1.9.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ee7e3209db1e468341ef41fe263eb655f67f5c5a76c924044314e139a1103a2"}, 618 | {file = "pydantic-1.9.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b6037175234850ffd094ca77bf60fb54b08b5b22bc85865331dd3bda7a02fa1"}, 619 | {file = "pydantic-1.9.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b2571db88c636d862b35090ccf92bf24004393f85c8870a37f42d9f23d13e032"}, 620 | {file = "pydantic-1.9.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:8b5ac0f1c83d31b324e57a273da59197c83d1bb18171e512908fe5dc7278a1d6"}, 621 | {file = "pydantic-1.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:bbbc94d0c94dd80b3340fc4f04fd4d701f4b038ebad72c39693c794fd3bc2d9d"}, 622 | {file = "pydantic-1.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:e0896200b6a40197405af18828da49f067c2fa1f821491bc8f5bde241ef3f7d7"}, 623 | {file = "pydantic-1.9.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bdfdadb5994b44bd5579cfa7c9b0e1b0e540c952d56f627eb227851cda9db77"}, 624 | {file = "pydantic-1.9.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:574936363cd4b9eed8acdd6b80d0143162f2eb654d96cb3a8ee91d3e64bf4cf9"}, 625 | {file = "pydantic-1.9.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c556695b699f648c58373b542534308922c46a1cda06ea47bc9ca45ef5b39ae6"}, 626 | {file = "pydantic-1.9.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f947352c3434e8b937e3aa8f96f47bdfe6d92779e44bb3f41e4c213ba6a32145"}, 627 | {file = "pydantic-1.9.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5e48ef4a8b8c066c4a31409d91d7ca372a774d0212da2787c0d32f8045b1e034"}, 628 | {file = "pydantic-1.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:96f240bce182ca7fe045c76bcebfa0b0534a1bf402ed05914a6f1dadff91877f"}, 629 | {file = "pydantic-1.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:815ddebb2792efd4bba5488bc8fde09c29e8ca3227d27cf1c6990fc830fd292b"}, 630 | {file = "pydantic-1.9.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6c5b77947b9e85a54848343928b597b4f74fc364b70926b3c4441ff52620640c"}, 631 | {file = "pydantic-1.9.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c68c3bc88dbda2a6805e9a142ce84782d3930f8fdd9655430d8576315ad97ce"}, 632 | {file = "pydantic-1.9.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a79330f8571faf71bf93667d3ee054609816f10a259a109a0738dac983b23c3"}, 633 | {file = "pydantic-1.9.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f5a64b64ddf4c99fe201ac2724daada8595ada0d102ab96d019c1555c2d6441d"}, 634 | {file = "pydantic-1.9.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a733965f1a2b4090a5238d40d983dcd78f3ecea221c7af1497b845a9709c1721"}, 635 | {file = "pydantic-1.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cc6a4cb8a118ffec2ca5fcb47afbacb4f16d0ab8b7350ddea5e8ef7bcc53a16"}, 636 | {file = "pydantic-1.9.0-py3-none-any.whl", hash = "sha256:085ca1de245782e9b46cefcf99deecc67d418737a1fd3f6a4f511344b613a5b3"}, 637 | {file = "pydantic-1.9.0.tar.gz", hash = "sha256:742645059757a56ecd886faf4ed2441b9c0cd406079c2b4bee51bcc3fbcd510a"}, 638 | ] 639 | pylev = [ 640 | {file = "pylev-1.4.0-py2.py3-none-any.whl", hash = "sha256:7b2e2aa7b00e05bb3f7650eb506fc89f474f70493271a35c242d9a92188ad3dd"}, 641 | {file = "pylev-1.4.0.tar.gz", hash = "sha256:9e77e941042ad3a4cc305dcdf2b2dec1aec2fbe3dd9015d2698ad02b173006d1"}, 642 | ] 643 | pyparsing = [ 644 | {file = "pyparsing-3.0.6-py3-none-any.whl", hash = "sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4"}, 645 | {file = "pyparsing-3.0.6.tar.gz", hash = "sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81"}, 646 | ] 647 | python-dateutil = [ 648 | {file = "python-dateutil-2.8.2.tar.gz", hash = "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86"}, 649 | {file = "python_dateutil-2.8.2-py2.py3-none-any.whl", hash = "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9"}, 650 | ] 651 | python-dotenv = [ 652 | {file = "python-dotenv-0.19.2.tar.gz", hash = "sha256:a5de49a31e953b45ff2d2fd434bbc2670e8db5273606c1e737cc6b93eff3655f"}, 653 | {file = "python_dotenv-0.19.2-py2.py3-none-any.whl", hash = "sha256:32b2bdc1873fd3a3c346da1c6db83d0053c3c62f28f1f38516070c4c8971b1d3"}, 654 | ] 655 | python-ulid = [ 656 | {file = "python-ulid-1.0.3.tar.gz", hash = "sha256:5dd8b969312a40e2212cec9c1ad63f25d4b6eafd92ee3195883e0287b6e9d19e"}, 657 | {file = "python_ulid-1.0.3-py3-none-any.whl", hash = "sha256:8704dc20f547f531fe3a41d4369842d737a0f275403b909d0872e7ea0fe8d6f2"}, 658 | ] 659 | pytzdata = [ 660 | {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, 661 | {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, 662 | ] 663 | redis = [ 664 | {file = "redis-4.1.1-py3-none-any.whl", hash = "sha256:bc97d18938ca18d66737d0ef88584a2073069589e4026813cfba9ad6df9a9f40"}, 665 | {file = "redis-4.1.1.tar.gz", hash = "sha256:07420a3fbedd8e012c31d4fadac943fb81568946da202c5a5bc237774e5280a0"}, 666 | ] 667 | redis-om = [ 668 | {file = "redis-om-0.0.17.tar.gz", hash = "sha256:13a23bc4730bc39b0e6ab1d66069087963a4b07d8f79b008ae8864db31d51bc3"}, 669 | {file = "redis_om-0.0.17-py3-none-any.whl", hash = "sha256:2f49e441b7e3998cb04719008fb9ba29b2a1df2df68ace44842961dbca60ad21"}, 670 | ] 671 | six = [ 672 | {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, 673 | {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, 674 | ] 675 | sniffio = [ 676 | {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, 677 | {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, 678 | ] 679 | starlette = [ 680 | {file = "starlette-0.16.0-py3-none-any.whl", hash = "sha256:38eb24bf705a2c317e15868e384c1b8a12ca396e5a3c3a003db7e667c43f939f"}, 681 | {file = "starlette-0.16.0.tar.gz", hash = "sha256:e1904b5d0007aee24bdd3c43994be9b3b729f4f58e740200de1d623f8c3a8870"}, 682 | ] 683 | types-redis = [ 684 | {file = "types-redis-4.1.10.tar.gz", hash = "sha256:cd9fe6689442315a453028b38ff2ba11eff7a46f22320335766508e956164dc6"}, 685 | {file = "types_redis-4.1.10-py3-none-any.whl", hash = "sha256:7b6b5ce5837cdebb9b36efd37a8587204f544956367a51a6cd29b8e62def756e"}, 686 | ] 687 | types-six = [ 688 | {file = "types-six-1.16.10.tar.gz", hash = "sha256:78e6c0fe40c2958e2a95ab1e1adfbf3dab56894dc8cf590dae18fd69f3179eff"}, 689 | {file = "types_six-1.16.10-py2.py3-none-any.whl", hash = "sha256:1038d7a9a7d70004d69c94df97aa375ec177c0ee604bccb91465b1506c3972aa"}, 690 | ] 691 | typing-extensions = [ 692 | {file = "typing_extensions-4.0.1-py3-none-any.whl", hash = "sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b"}, 693 | {file = "typing_extensions-4.0.1.tar.gz", hash = "sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e"}, 694 | ] 695 | uvicorn = [ 696 | {file = "uvicorn-0.15.0-py3-none-any.whl", hash = "sha256:17f898c64c71a2640514d4089da2689e5db1ce5d4086c2d53699bf99513421c1"}, 697 | {file = "uvicorn-0.15.0.tar.gz", hash = "sha256:d9a3c0dd1ca86728d3e235182683b4cf94cd53a867c288eaeca80ee781b2caff"}, 698 | ] 699 | wrapt = [ 700 | {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, 701 | {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, 702 | {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, 703 | {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, 704 | {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, 705 | {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, 706 | {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, 707 | {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, 708 | {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, 709 | {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, 710 | {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, 711 | {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, 712 | {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, 713 | {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, 714 | {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, 715 | {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, 716 | {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, 717 | {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, 718 | {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, 719 | {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, 720 | {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, 721 | {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, 722 | {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, 723 | {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, 724 | {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, 725 | {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, 726 | {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, 727 | {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, 728 | {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, 729 | {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, 730 | {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, 731 | {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, 732 | {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, 733 | {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, 734 | {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, 735 | {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, 736 | {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, 737 | {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, 738 | {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, 739 | {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, 740 | {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, 741 | {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, 742 | {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, 743 | {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, 744 | {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, 745 | {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, 746 | {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, 747 | {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, 748 | {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, 749 | {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, 750 | {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, 751 | ] 752 | zipp = [ 753 | {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, 754 | {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, 755 | ] 756 | --------------------------------------------------------------------------------