diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3717be8..1205f21 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,12 +2,17 @@ name: ci on: [ push, pull_request ] jobs: ci: + strategy: + matrix: + python: ["3.7", "3.8", "3.9", "3.10", "3.11"] + + name: "Test on Python ${{ matrix.python }}" runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-python@v4 with: - python-version: "3.x" + python-version: "${{ matrix.python }}" - name: Install and configure Poetry run: | pip install -U pip poetry diff --git a/Makefile b/Makefile index c82de1d..7cf944a 100644 --- a/Makefile +++ b/Makefile @@ -14,6 +14,8 @@ style: deps check: deps @black $(checkfiles) || (echo "Please run 'make style' to auto-fix style issues" && false) @flake8 $(checkfiles) + @mypy ${checkfiles} + @pyright ${checkfiles} test: deps $(py_warn) pytest diff --git a/examples/in_memory/main.py b/examples/in_memory/main.py index eb469af..44ad088 100644 --- a/examples/in_memory/main.py +++ b/examples/in_memory/main.py @@ -1,3 +1,6 @@ +# pyright: reportGeneralTypeIssues=false +from typing import Dict, Optional + import pendulum import uvicorn from fastapi import FastAPI @@ -84,9 +87,9 @@ app.get("/method")(cache(namespace="test")(instance.handler_method)) # cache a Pydantic model instance; the return type annotation is required in this case class Item(BaseModel): name: str - description: str | None = None + description: Optional[str] = None price: float - tax: float | None = None + tax: Optional[float] = None @app.get("/pydantic_instance") @@ -110,7 +113,7 @@ async def uncached_put(): @cache(namespace="test", expire=5, injected_dependency_namespace="monty_python") def namespaced_injection( __fastapi_cache_request: int = 42, __fastapi_cache_response: int = 17 -) -> dict[str, int]: +) -> Dict[str, int]: return { "__fastapi_cache_request": __fastapi_cache_request, "__fastapi_cache_response": __fastapi_cache_response, @@ -123,4 +126,4 @@ async def startup(): if __name__ == "__main__": - uvicorn.run("main:app", debug=True, reload=True) + uvicorn.run("main:app", reload=True) diff --git a/examples/redis/main.py b/examples/redis/main.py index e05eda5..bac677d 100644 --- a/examples/redis/main.py +++ b/examples/redis/main.py @@ -1,3 +1,4 @@ +# pyright: reportGeneralTypeIssues=false import time import pendulum @@ -87,4 +88,4 @@ async def startup(): if __name__ == "__main__": - uvicorn.run("main:app", debug=True, reload=True) + uvicorn.run("main:app", reload=True) diff --git a/fastapi_cache/backends/dynamodb.py b/fastapi_cache/backends/dynamodb.py index 547cfb8..94318c9 100644 --- a/fastapi_cache/backends/dynamodb.py +++ b/fastapi_cache/backends/dynamodb.py @@ -1,11 +1,16 @@ import datetime -from typing import Optional, Tuple +from typing import TYPE_CHECKING, Optional, Tuple from aiobotocore.client import AioBaseClient -from aiobotocore.session import get_session, AioSession +from aiobotocore.session import AioSession, get_session from fastapi_cache.backends import Backend +if TYPE_CHECKING: + from types_aiobotocore_dynamodb import DynamoDBClient +else: + DynamoDBClient = AioBaseClient + class DynamoBackend(Backend): """ @@ -25,14 +30,18 @@ class DynamoBackend(Backend): >> FastAPICache.init(dynamodb) """ + client: DynamoDBClient + session: AioSession + table_name: str + region: Optional[str] + def __init__(self, table_name: str, region: Optional[str] = None) -> None: self.session: AioSession = get_session() - self.client: Optional[AioBaseClient] = None # Needs async init self.table_name = table_name self.region = region async def init(self) -> None: - self.client = await self.session.create_client( + self.client = await self.session.create_client( # pyright: ignore[reportUnknownMemberType] "dynamodb", region_name=self.region ).__aenter__() @@ -60,6 +69,7 @@ class DynamoBackend(Backend): response = await self.client.get_item(TableName=self.table_name, Key={"key": {"S": key}}) if "Item" in response: return response["Item"].get("value", {}).get("B") + return None async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None: ttl = ( diff --git a/fastapi_cache/backends/redis.py b/fastapi_cache/backends/redis.py index 928af88..22a63ef 100644 --- a/fastapi_cache/backends/redis.py +++ b/fastapi_cache/backends/redis.py @@ -13,18 +13,18 @@ class RedisBackend(Backend): async def get_with_ttl(self, key: str) -> Tuple[int, Optional[bytes]]: async with self.redis.pipeline(transaction=not self.is_cluster) as pipe: - return await pipe.ttl(key).get(key).execute() + return await pipe.ttl(key).get(key).execute() # type: ignore[union-attr,no-any-return] async def get(self, key: str) -> Optional[bytes]: - return await self.redis.get(key) + return await self.redis.get(key) # type: ignore[union-attr] async def set(self, key: str, value: bytes, expire: Optional[int] = None) -> None: - return await self.redis.set(key, value, ex=expire) + await self.redis.set(key, value, ex=expire) # type: ignore[union-attr] async def clear(self, namespace: Optional[str] = None, key: Optional[str] = None) -> int: if namespace: lua = f"for i, name in ipairs(redis.call('KEYS', '{namespace}:*')) do redis.call('DEL', name); end" - return await self.redis.eval(lua, numkeys=0) + return await self.redis.eval(lua, numkeys=0) # type: ignore[union-attr,no-any-return] elif key: - return await self.redis.delete(key) + return await self.redis.delete(key) # type: ignore[union-attr] return 0 diff --git a/fastapi_cache/coder.py b/fastapi_cache/coder.py index 30c0ee2..1652d7b 100644 --- a/fastapi_cache/coder.py +++ b/fastapi_cache/coder.py @@ -8,28 +8,31 @@ import pendulum from fastapi.encoders import jsonable_encoder from pydantic import BaseConfig, ValidationError, fields from starlette.responses import JSONResponse -from starlette.templating import _TemplateResponse as TemplateResponse +from starlette.templating import ( + _TemplateResponse as TemplateResponse, # pyright: ignore[reportPrivateUsage] +) -_T = TypeVar("_T") +_T = TypeVar("_T", bound=type) -CONVERTERS: dict[str, Callable[[str], Any]] = { - "date": lambda x: pendulum.parse(x, exact=True), - "datetime": lambda x: pendulum.parse(x, exact=True), +CONVERTERS: Dict[str, Callable[[str], Any]] = { + # Pendulum 3.0.0 adds parse to __all__, at which point these ignores can be removed + "date": lambda x: pendulum.parse(x, exact=True), # type: ignore[attr-defined] + "datetime": lambda x: pendulum.parse(x, exact=True), # type: ignore[attr-defined] "decimal": Decimal, } class JsonEncoder(json.JSONEncoder): - def default(self, obj: Any) -> Any: - if isinstance(obj, datetime.datetime): - return {"val": str(obj), "_spec_type": "datetime"} - elif isinstance(obj, datetime.date): - return {"val": str(obj), "_spec_type": "date"} - elif isinstance(obj, Decimal): - return {"val": str(obj), "_spec_type": "decimal"} + def default(self, o: Any) -> Any: + if isinstance(o, datetime.datetime): + return {"val": str(o), "_spec_type": "datetime"} + elif isinstance(o, datetime.date): + return {"val": str(o), "_spec_type": "date"} + elif isinstance(o, Decimal): + return {"val": str(o), "_spec_type": "decimal"} else: - return jsonable_encoder(obj) + return jsonable_encoder(o) def object_hook(obj: Any) -> Any: diff --git a/fastapi_cache/decorator.py b/fastapi_cache/decorator.py index 679e221..0089dbc 100644 --- a/fastapi_cache/decorator.py +++ b/fastapi_cache/decorator.py @@ -2,7 +2,7 @@ import logging import sys from functools import wraps from inspect import Parameter, Signature, isawaitable, iscoroutinefunction -from typing import Awaitable, Callable, Optional, Type, TypeVar +from typing import Awaitable, Callable, List, Optional, Type, TypeVar, Union, cast if sys.version_info >= (3, 10): from typing import ParamSpec @@ -29,14 +29,14 @@ def _augment_signature(signature: Signature, *extra: Parameter) -> Signature: return signature parameters = list(signature.parameters.values()) - variadic_keyword_params = [] + variadic_keyword_params: List[Parameter] = [] while parameters and parameters[-1].kind is Parameter.VAR_KEYWORD: variadic_keyword_params.append(parameters.pop()) return signature.replace(parameters=[*parameters, *extra, *variadic_keyword_params]) -def _locate_param(sig: Signature, dep: Parameter, to_inject: list[Parameter]) -> Parameter: +def _locate_param(sig: Signature, dep: Parameter, to_inject: List[Parameter]) -> Parameter: """Locate an existing parameter in the decorated endpoint If not found, returns the injectable parameter, and adds it to the to_inject list. @@ -56,9 +56,9 @@ def cache( expire: Optional[int] = None, coder: Optional[Type[Coder]] = None, key_builder: Optional[KeyBuilder] = None, - namespace: Optional[str] = "", + namespace: str = "", injected_dependency_namespace: str = "__fastapi_cache", -) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[R]]]: +) -> Callable[[Callable[P, Awaitable[R]]], Callable[P, Awaitable[Union[R, Response]]]]: """ cache all function :param namespace: @@ -80,16 +80,16 @@ def cache( kind=Parameter.KEYWORD_ONLY, ) - def wrapper(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[R]]: + def wrapper(func: Callable[P, Awaitable[R]]) -> Callable[P, Awaitable[Union[R, Response]]]: # get_typed_signature ensures that any forward references are resolved first wrapped_signature = get_typed_signature(func) - to_inject: list[Parameter] = [] + to_inject: List[Parameter] = [] request_param = _locate_param(wrapped_signature, injected_request, to_inject) response_param = _locate_param(wrapped_signature, injected_response, to_inject) return_type = get_typed_return_annotation(func) @wraps(func) - async def inner(*args: P.args, **kwargs: P.kwargs) -> R: + async def inner(*args: P.args, **kwargs: P.kwargs) -> Union[R, Response]: nonlocal coder nonlocal expire nonlocal key_builder @@ -111,11 +111,11 @@ def cache( else: # sync, wrap in thread and return async # see above why we have to await even although caller also awaits. - return await run_in_threadpool(func, *args, **kwargs) + return await run_in_threadpool(func, *args, **kwargs) # type: ignore[arg-type] copy_kwargs = kwargs.copy() - request: Optional[Request] = copy_kwargs.pop(request_param.name, None) - response: Optional[Response] = copy_kwargs.pop(response_param.name, None) + request: Optional[Request] = copy_kwargs.pop(request_param.name, None) # type: ignore[assignment] + response: Optional[Response] = copy_kwargs.pop(response_param.name, None) # type: ignore[assignment] if ( request and request.headers.get("Cache-Control") in ("no-store", "no-cache") ) or not FastAPICache.get_enable(): @@ -137,17 +137,18 @@ def cache( ) if isawaitable(cache_key): cache_key = await cache_key + assert isinstance(cache_key, str) try: - ttl, ret = await backend.get_with_ttl(cache_key) + ttl, cached = await backend.get_with_ttl(cache_key) except Exception: logger.warning( f"Error retrieving cache key '{cache_key}' from backend:", exc_info=True ) - ttl, ret = 0, None + ttl, cached = 0, None if not request: - if ret is not None: - return coder.decode_as_type(ret, type_=return_type) + if cached is not None: + return cast(R, coder.decode_as_type(cached, type_=return_type)) ret = await ensure_async_func(*args, **kwargs) try: await backend.set(cache_key, coder.encode(ret), expire) @@ -161,15 +162,15 @@ def cache( return await ensure_async_func(*args, **kwargs) if_none_match = request.headers.get("if-none-match") - if ret is not None: + if cached is not None: if response: response.headers["Cache-Control"] = f"max-age={ttl}" - etag = f"W/{hash(ret)}" + etag = f"W/{hash(cached)}" if if_none_match == etag: response.status_code = 304 return response response.headers["ETag"] = etag - return coder.decode_as_type(ret, type_=return_type) + return cast(R, coder.decode_as_type(cached, type_=return_type)) ret = await ensure_async_func(*args, **kwargs) encoded_ret = coder.encode(ret) @@ -179,12 +180,13 @@ def cache( except Exception: logger.warning(f"Error setting cache key '{cache_key}' in backend:", exc_info=True) - response.headers["Cache-Control"] = f"max-age={expire}" - etag = f"W/{hash(encoded_ret)}" - response.headers["ETag"] = etag + if response: + response.headers["Cache-Control"] = f"max-age={expire}" + etag = f"W/{hash(encoded_ret)}" + response.headers["ETag"] = etag return ret - inner.__signature__ = _augment_signature(wrapped_signature, *to_inject) + inner.__signature__ = _augment_signature(wrapped_signature, *to_inject) # type: ignore[attr-defined] return inner return wrapper diff --git a/fastapi_cache/key_builder.py b/fastapi_cache/key_builder.py index c680619..281c750 100644 --- a/fastapi_cache/key_builder.py +++ b/fastapi_cache/key_builder.py @@ -1,5 +1,5 @@ import hashlib -from typing import Any, Callable, Optional +from typing import Any, Callable, Dict, Optional, Tuple from starlette.requests import Request from starlette.responses import Response @@ -8,10 +8,11 @@ from starlette.responses import Response def default_key_builder( func: Callable[..., Any], namespace: str = "", + *, request: Optional[Request] = None, response: Optional[Response] = None, - args: Optional[tuple[Any, ...]] = None, - kwargs: Optional[dict[str, Any]] = None, + args: Tuple[Any, ...], + kwargs: Dict[str, Any], ) -> str: cache_key = hashlib.md5( # nosec:B303 f"{func.__module__}:{func.__name__}:{args}:{kwargs}".encode() diff --git a/fastapi_cache/types.py b/fastapi_cache/types.py index c409dfb..63192ab 100644 --- a/fastapi_cache/types.py +++ b/fastapi_cache/types.py @@ -1,7 +1,8 @@ -from typing import Any, Awaitable, Callable, Optional, Protocol, Union +from typing import Any, Awaitable, Callable, Dict, Optional, Tuple, Union from starlette.requests import Request from starlette.responses import Response +from typing_extensions import Protocol _Func = Callable[..., Any] @@ -10,12 +11,12 @@ _Func = Callable[..., Any] class KeyBuilder(Protocol): def __call__( self, - _function: _Func, - _namespace: str = ..., + __function: _Func, + __namespace: str = ..., *, request: Optional[Request] = ..., response: Optional[Response] = ..., - args: tuple[Any, ...] = ..., - kwargs: dict[str, Any] = ..., + args: Tuple[Any, ...], + kwargs: Dict[str, Any], ) -> Union[Awaitable[str], str]: ... diff --git a/poetry.lock b/poetry.lock index 785614c..488191e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -302,18 +302,111 @@ urllib3 = ">=1.25.4,<1.27" [package.extras] crt = ["awscrt (==0.11.24)"] +[[package]] +name = "botocore-stubs" +version = "1.29.130" +description = "Type annotations and code completion for botocore" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "botocore_stubs-1.29.130-py3-none-any.whl", hash = "sha256:622c4a5cd740498439008d81c5ded612146f4f0d575341c12591f978edbbe733"}, + {file = "botocore_stubs-1.29.130.tar.gz", hash = "sha256:5f6f1967d23c45834858a055cbf65b66863f9f28d05f32f57bf52864a13512d9"}, +] + +[package.dependencies] +types-awscrt = "*" +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} + [[package]] name = "certifi" -version = "2022.12.7" +version = "2023.5.7" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2022.12.7-py3-none-any.whl", hash = "sha256:4ad3232f5e926d6718ec31cfc1fcadfde020920e278684144551c91769c7bc18"}, - {file = "certifi-2022.12.7.tar.gz", hash = "sha256:35824b4c3a97115964b408844d64aa14db1cc518f6562e8d7261699d1350a9e3"}, + {file = "certifi-2023.5.7-py3-none-any.whl", hash = "sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716"}, + {file = "certifi-2023.5.7.tar.gz", hash = "sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7"}, ] +[[package]] +name = "cffi" +version = "1.15.1" +description = "Foreign Function Interface for Python calling C code." +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, + {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, + {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, + {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, + {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, + {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, + {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, + {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, + {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, + {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, + {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, + {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, + {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, + {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, + {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, + {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, + {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, + {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, + {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, + {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, + {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, + {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, + {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, + {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, + {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, + {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, + {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, + {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, + {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, + {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, + {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, + {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, + {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, +] + +[package.dependencies] +pycparser = "*" + [[package]] name = "charset-normalizer" version = "3.1.0" @@ -490,6 +583,48 @@ files = [ [package.extras] toml = ["tomli"] +[[package]] +name = "cryptography" +version = "40.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +category = "dev" +optional = false +python-versions = ">=3.6" +files = [ + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_universal2.whl", hash = "sha256:8f79b5ff5ad9d3218afb1e7e20ea74da5f76943ee5edb7f76e56ec5161ec782b"}, + {file = "cryptography-40.0.2-cp36-abi3-macosx_10_12_x86_64.whl", hash = "sha256:05dc219433b14046c476f6f09d7636b92a1c3e5808b9a6536adf4932b3b2c440"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4df2af28d7bedc84fe45bd49bc35d710aede676e2a4cb7fc6d103a2adc8afe4d"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dcca15d3a19a66e63662dc8d30f8036b07be851a8680eda92d079868f106288"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a04386fb7bc85fab9cd51b6308633a3c271e3d0d3eae917eebab2fac6219b6d2"}, + {file = "cryptography-40.0.2-cp36-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:adc0d980fd2760c9e5de537c28935cc32b9353baaf28e0814df417619c6c8c3b"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:d5a1bd0e9e2031465761dfa920c16b0065ad77321d8a8c1f5ee331021fda65e9"}, + {file = "cryptography-40.0.2-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a95f4802d49faa6a674242e25bfeea6fc2acd915b5e5e29ac90a32b1139cae1c"}, + {file = "cryptography-40.0.2-cp36-abi3-win32.whl", hash = "sha256:aecbb1592b0188e030cb01f82d12556cf72e218280f621deed7d806afd2113f9"}, + {file = "cryptography-40.0.2-cp36-abi3-win_amd64.whl", hash = "sha256:b12794f01d4cacfbd3177b9042198f3af1c856eedd0a98f10f141385c809a14b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:142bae539ef28a1c76794cca7f49729e7c54423f615cfd9b0b1fa90ebe53244b"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:956ba8701b4ffe91ba59665ed170a2ebbdc6fc0e40de5f6059195d9f2b33ca0e"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4f01c9863da784558165f5d4d916093737a75203a5c5286fde60e503e4276c7a"}, + {file = "cryptography-40.0.2-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:3daf9b114213f8ba460b829a02896789751626a2a4e7a43a28ee77c04b5e4958"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48f388d0d153350f378c7f7b41497a54ff1513c816bcbbcafe5b829e59b9ce5b"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c0764e72b36a3dc065c155e5b22f93df465da9c39af65516fe04ed3c68c92636"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:cbaba590180cba88cb99a5f76f90808a624f18b169b90a4abb40c1fd8c19420e"}, + {file = "cryptography-40.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:7a38250f433cd41df7fcb763caa3ee9362777fdb4dc642b9a349721d2bf47404"}, + {file = "cryptography-40.0.2.tar.gz", hash = "sha256:c33c0d32b8594fa647d2e01dbccc303478e16fdd7cf98652d5b3ed11aa5e5c99"}, +] + +[package.dependencies] +cffi = ">=1.12" + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] +docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +pep8test = ["black", "check-manifest", "mypy", "ruff"] +sdist = ["setuptools-rust (>=0.11.4)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["iso8601", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-shard (>=0.1.2)", "pytest-subtests", "pytest-xdist"] +test-randomorder = ["pytest-randomly"] +tox = ["tox"] + [[package]] name = "exceptiongroup" version = "1.1.1" @@ -860,6 +995,54 @@ files = [ {file = "multidict-6.0.4.tar.gz", hash = "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49"}, ] +[[package]] +name = "mypy" +version = "1.3.0" +description = "Optional static typing for Python" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "mypy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c1eb485cea53f4f5284e5baf92902cd0088b24984f4209e25981cc359d64448d"}, + {file = "mypy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4c99c3ecf223cf2952638da9cd82793d8f3c0c5fa8b6ae2b2d9ed1e1ff51ba85"}, + {file = "mypy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:550a8b3a19bb6589679a7c3c31f64312e7ff482a816c96e0cecec9ad3a7564dd"}, + {file = "mypy-1.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cbc07246253b9e3d7d74c9ff948cd0fd7a71afcc2b77c7f0a59c26e9395cb152"}, + {file = "mypy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:a22435632710a4fcf8acf86cbd0d69f68ac389a3892cb23fbad176d1cddaf228"}, + {file = "mypy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e33bb8b2613614a33dff70565f4c803f889ebd2f859466e42b46e1df76018dd"}, + {file = "mypy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7d23370d2a6b7a71dc65d1266f9a34e4cde9e8e21511322415db4b26f46f6b8c"}, + {file = "mypy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:658fe7b674769a0770d4b26cb4d6f005e88a442fe82446f020be8e5f5efb2fae"}, + {file = "mypy-1.3.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6e42d29e324cdda61daaec2336c42512e59c7c375340bd202efa1fe0f7b8f8ca"}, + {file = "mypy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:d0b6c62206e04061e27009481cb0ec966f7d6172b5b936f3ead3d74f29fe3dcf"}, + {file = "mypy-1.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:76ec771e2342f1b558c36d49900dfe81d140361dd0d2df6cd71b3db1be155409"}, + {file = "mypy-1.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ebc95f8386314272bbc817026f8ce8f4f0d2ef7ae44f947c4664efac9adec929"}, + {file = "mypy-1.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:faff86aa10c1aa4a10e1a301de160f3d8fc8703b88c7e98de46b531ff1276a9a"}, + {file = "mypy-1.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:8c5979d0deb27e0f4479bee18ea0f83732a893e81b78e62e2dda3e7e518c92ee"}, + {file = "mypy-1.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c5d2cc54175bab47011b09688b418db71403aefad07cbcd62d44010543fc143f"}, + {file = "mypy-1.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:87df44954c31d86df96c8bd6e80dfcd773473e877ac6176a8e29898bfb3501cb"}, + {file = "mypy-1.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:473117e310febe632ddf10e745a355714e771ffe534f06db40702775056614c4"}, + {file = "mypy-1.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:74bc9b6e0e79808bf8678d7678b2ae3736ea72d56eede3820bd3849823e7f305"}, + {file = "mypy-1.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:44797d031a41516fcf5cbfa652265bb994e53e51994c1bd649ffcd0c3a7eccbf"}, + {file = "mypy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ddae0f39ca146972ff6bb4399f3b2943884a774b8771ea0a8f50e971f5ea5ba8"}, + {file = "mypy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c4c42c60a8103ead4c1c060ac3cdd3ff01e18fddce6f1016e08939647a0e703"}, + {file = "mypy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e86c2c6852f62f8f2b24cb7a613ebe8e0c7dc1402c61d36a609174f63e0ff017"}, + {file = "mypy-1.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:f9dca1e257d4cc129517779226753dbefb4f2266c4eaad610fc15c6a7e14283e"}, + {file = "mypy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:95d8d31a7713510685b05fbb18d6ac287a56c8f6554d88c19e73f724a445448a"}, + {file = "mypy-1.3.0-py3-none-any.whl", hash = "sha256:a8763e72d5d9574d45ce5881962bc8e9046bf7b375b0abf031f3e6811732a897"}, + {file = "mypy-1.3.0.tar.gz", hash = "sha256:e1f4d16e296f5135624b34e8fb741eb0eadedca90862405b1f1fde2040b9bd11"}, +] + +[package.dependencies] +mypy-extensions = ">=1.0.0" +tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} +typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} +typing-extensions = ">=3.10" + +[package.extras] +dmypy = ["psutil (>=4.0)"] +install-types = ["pip"] +python2 = ["typed-ast (>=1.4.0,<2)"] +reports = ["lxml"] + [[package]] name = "mypy-extensions" version = "1.0.0" @@ -872,6 +1055,21 @@ files = [ {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"}, ] +[[package]] +name = "nodeenv" +version = "1.7.0" +description = "Node.js virtual environment builder" +category = "dev" +optional = false +python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" +files = [ + {file = "nodeenv-1.7.0-py2.py3-none-any.whl", hash = "sha256:27083a7b96a25f2f5e1d8cb4b6317ee8aeda3bdd121394e5ac54e498028a042e"}, + {file = "nodeenv-1.7.0.tar.gz", hash = "sha256:e0e7f7dfb85fc5394c6fe1e8fa98131a2473e04311a45afb6508f7cf1836fa2b"}, +] + +[package.dependencies] +setuptools = "*" + [[package]] name = "packaging" version = "23.1" @@ -981,6 +1179,18 @@ files = [ {file = "pycodestyle-2.9.1.tar.gz", hash = "sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785"}, ] +[[package]] +name = "pycparser" +version = "2.21" +description = "C parser in Python" +category = "dev" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +files = [ + {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, + {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, +] + [[package]] name = "pydantic" version = "1.10.7" @@ -1046,6 +1256,26 @@ files = [ {file = "pyflakes-2.5.0.tar.gz", hash = "sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3"}, ] +[[package]] +name = "pyright" +version = "1.1.307" +description = "Command line wrapper for pyright" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "pyright-1.1.307-py3-none-any.whl", hash = "sha256:6b360d2e018311bdf8acea73ef1f21bf0b5b502345aa94bc6763cf197b2e75b3"}, + {file = "pyright-1.1.307.tar.gz", hash = "sha256:b7a8734fad4a2438b8bb0dfbe462f529c9d4eb31947bdae85b9b4e7a97ff6a49"}, +] + +[package.dependencies] +nodeenv = ">=1.6.0" +typing-extensions = {version = ">=3.7", markers = "python_version < \"3.8\""} + +[package.extras] +all = ["twine (>=3.4.1)"] +dev = ["twine (>=3.4.1)"] + [[package]] name = "pytest" version = "7.3.1" @@ -1099,18 +1329,18 @@ files = [ [[package]] name = "redis" -version = "4.5.4" +version = "4.5.5" description = "Python client for Redis database and key-value store" category = "main" optional = true python-versions = ">=3.7" files = [ - {file = "redis-4.5.4-py3-none-any.whl", hash = "sha256:2c19e6767c474f2e85167909061d525ed65bea9301c0770bb151e041b7ac89a2"}, - {file = "redis-4.5.4.tar.gz", hash = "sha256:73ec35da4da267d6847e47f68730fdd5f62e2ca69e3ef5885c6a78a9374c3893"}, + {file = "redis-4.5.5-py3-none-any.whl", hash = "sha256:77929bc7f5dab9adf3acba2d3bb7d7658f1e0c2f1cafe7eb36434e751c471119"}, + {file = "redis-4.5.5.tar.gz", hash = "sha256:dc87a0bdef6c8bfe1ef1e1c40be7034390c2ae02d92dcd0c7ca1729443899880"}, ] [package.dependencies] -async-timeout = {version = ">=4.0.2", markers = "python_version <= \"3.11.2\""} +async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} typing-extensions = {version = "*", markers = "python_version < \"3.8\""} @@ -1120,26 +1350,43 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" [[package]] name = "requests" -version = "2.29.0" +version = "2.30.0" description = "Python HTTP for Humans." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "requests-2.29.0-py3-none-any.whl", hash = "sha256:e8f3c9be120d3333921d213eef078af392fba3933ab7ed2d1cba3b56f2568c3b"}, - {file = "requests-2.29.0.tar.gz", hash = "sha256:f2e34a75f4749019bb0e3effb66683630e4ffeaf75819fb51bebef1bf5aef059"}, + {file = "requests-2.30.0-py3-none-any.whl", hash = "sha256:10e94cc4f3121ee6da529d358cdaeaff2f1c409cd377dbc72b825852f2f7e294"}, + {file = "requests-2.30.0.tar.gz", hash = "sha256:239d7d4458afcb28a692cdd298d87542235f4ca8d36d03a15bfc128a6559a2f4"}, ] [package.dependencies] certifi = ">=2017.4.17" charset-normalizer = ">=2,<4" idna = ">=2.5,<4" -urllib3 = ">=1.21.1,<1.27" +urllib3 = ">=1.21.1,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] +[[package]] +name = "setuptools" +version = "67.7.2" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "setuptools-67.7.2-py3-none-any.whl", hash = "sha256:23aaf86b85ca52ceb801d32703f12d77517b2556af839621c641fca11287952b"}, + {file = "setuptools-67.7.2.tar.gz", hash = "sha256:f104fa03692a2602fa0fec6c6a9e63b6c8a968de13e17c026957dd1f53d80990"}, +] + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8 (<5)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pip-run (>=8.8)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] + [[package]] name = "six" version = "1.16.0" @@ -1229,6 +1476,426 @@ files = [ {file = "typed_ast-1.5.4.tar.gz", hash = "sha256:39e21ceb7388e4bb37f4c679d72707ed46c2fbf2a5609b8b8ebc4b067d977df2"}, ] +[[package]] +name = "types-aiobotocore" +version = "2.5.0.post2" +description = "Type annotations for aiobotocore 2.5.0 generated with mypy-boto3-builder 7.14.5" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "types-aiobotocore-2.5.0.post2.tar.gz", hash = "sha256:e0e46a6834841db86083ce0dad3d5efbaebe0a43c18f783b0e8c95ea1f7e80c5"}, + {file = "types_aiobotocore-2.5.0.post2-py3-none-any.whl", hash = "sha256:75ddccdaf5cdf080a1a62cb74346f2704187a53b9ff1a8d63428c2e1de4e05f7"}, +] + +[package.dependencies] +botocore-stubs = "*" +types-aiobotocore-dynamodb = {version = ">=2.5.0,<2.6.0", optional = true, markers = "extra == \"dynamodb\""} +typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.9\""} + +[package.extras] +accessanalyzer = ["types-aiobotocore-accessanalyzer (>=2.5.0,<2.6.0)"] +account = ["types-aiobotocore-account (>=2.5.0,<2.6.0)"] +acm = ["types-aiobotocore-acm (>=2.5.0,<2.6.0)"] +acm-pca = ["types-aiobotocore-acm-pca (>=2.5.0,<2.6.0)"] +aiobotocore = ["aiobotocore (==2.5.0)", "botocore (==1.29.76)"] +alexaforbusiness = ["types-aiobotocore-alexaforbusiness (>=2.5.0,<2.6.0)"] +all = ["types-aiobotocore-accessanalyzer (>=2.5.0,<2.6.0)", "types-aiobotocore-account (>=2.5.0,<2.6.0)", "types-aiobotocore-acm (>=2.5.0,<2.6.0)", "types-aiobotocore-acm-pca (>=2.5.0,<2.6.0)", "types-aiobotocore-alexaforbusiness (>=2.5.0,<2.6.0)", "types-aiobotocore-amp (>=2.5.0,<2.6.0)", "types-aiobotocore-amplify (>=2.5.0,<2.6.0)", "types-aiobotocore-amplifybackend (>=2.5.0,<2.6.0)", "types-aiobotocore-amplifyuibuilder (>=2.5.0,<2.6.0)", "types-aiobotocore-apigateway (>=2.5.0,<2.6.0)", "types-aiobotocore-apigatewaymanagementapi (>=2.5.0,<2.6.0)", "types-aiobotocore-apigatewayv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-appconfig (>=2.5.0,<2.6.0)", "types-aiobotocore-appconfigdata (>=2.5.0,<2.6.0)", "types-aiobotocore-appflow (>=2.5.0,<2.6.0)", "types-aiobotocore-appintegrations (>=2.5.0,<2.6.0)", "types-aiobotocore-application-autoscaling (>=2.5.0,<2.6.0)", "types-aiobotocore-application-insights (>=2.5.0,<2.6.0)", "types-aiobotocore-applicationcostprofiler (>=2.5.0,<2.6.0)", "types-aiobotocore-appmesh (>=2.5.0,<2.6.0)", "types-aiobotocore-apprunner (>=2.5.0,<2.6.0)", "types-aiobotocore-appstream (>=2.5.0,<2.6.0)", "types-aiobotocore-appsync (>=2.5.0,<2.6.0)", "types-aiobotocore-arc-zonal-shift (>=2.5.0,<2.6.0)", "types-aiobotocore-athena (>=2.5.0,<2.6.0)", "types-aiobotocore-auditmanager (>=2.5.0,<2.6.0)", "types-aiobotocore-autoscaling (>=2.5.0,<2.6.0)", "types-aiobotocore-autoscaling-plans (>=2.5.0,<2.6.0)", "types-aiobotocore-backup (>=2.5.0,<2.6.0)", "types-aiobotocore-backup-gateway (>=2.5.0,<2.6.0)", "types-aiobotocore-backupstorage (>=2.5.0,<2.6.0)", "types-aiobotocore-batch (>=2.5.0,<2.6.0)", "types-aiobotocore-billingconductor (>=2.5.0,<2.6.0)", "types-aiobotocore-braket (>=2.5.0,<2.6.0)", "types-aiobotocore-budgets (>=2.5.0,<2.6.0)", "types-aiobotocore-ce (>=2.5.0,<2.6.0)", "types-aiobotocore-chime (>=2.5.0,<2.6.0)", "types-aiobotocore-chime-sdk-identity (>=2.5.0,<2.6.0)", "types-aiobotocore-chime-sdk-media-pipelines (>=2.5.0,<2.6.0)", "types-aiobotocore-chime-sdk-meetings (>=2.5.0,<2.6.0)", "types-aiobotocore-chime-sdk-messaging (>=2.5.0,<2.6.0)", "types-aiobotocore-chime-sdk-voice (>=2.5.0,<2.6.0)", "types-aiobotocore-cleanrooms (>=2.5.0,<2.6.0)", "types-aiobotocore-cloud9 (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudcontrol (>=2.5.0,<2.6.0)", "types-aiobotocore-clouddirectory (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudformation (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudfront (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudhsm (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudhsmv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudsearch (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudsearchdomain (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudtrail (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudtrail-data (>=2.5.0,<2.6.0)", "types-aiobotocore-cloudwatch (>=2.5.0,<2.6.0)", "types-aiobotocore-codeartifact (>=2.5.0,<2.6.0)", "types-aiobotocore-codebuild (>=2.5.0,<2.6.0)", "types-aiobotocore-codecatalyst (>=2.5.0,<2.6.0)", "types-aiobotocore-codecommit (>=2.5.0,<2.6.0)", "types-aiobotocore-codedeploy (>=2.5.0,<2.6.0)", "types-aiobotocore-codeguru-reviewer (>=2.5.0,<2.6.0)", "types-aiobotocore-codeguruprofiler (>=2.5.0,<2.6.0)", "types-aiobotocore-codepipeline (>=2.5.0,<2.6.0)", "types-aiobotocore-codestar (>=2.5.0,<2.6.0)", "types-aiobotocore-codestar-connections (>=2.5.0,<2.6.0)", "types-aiobotocore-codestar-notifications (>=2.5.0,<2.6.0)", "types-aiobotocore-cognito-identity (>=2.5.0,<2.6.0)", "types-aiobotocore-cognito-idp (>=2.5.0,<2.6.0)", "types-aiobotocore-cognito-sync (>=2.5.0,<2.6.0)", "types-aiobotocore-comprehend (>=2.5.0,<2.6.0)", "types-aiobotocore-comprehendmedical (>=2.5.0,<2.6.0)", "types-aiobotocore-compute-optimizer (>=2.5.0,<2.6.0)", "types-aiobotocore-config (>=2.5.0,<2.6.0)", "types-aiobotocore-connect (>=2.5.0,<2.6.0)", "types-aiobotocore-connect-contact-lens (>=2.5.0,<2.6.0)", "types-aiobotocore-connectcampaigns (>=2.5.0,<2.6.0)", "types-aiobotocore-connectcases (>=2.5.0,<2.6.0)", "types-aiobotocore-connectparticipant (>=2.5.0,<2.6.0)", "types-aiobotocore-controltower (>=2.5.0,<2.6.0)", "types-aiobotocore-cur (>=2.5.0,<2.6.0)", "types-aiobotocore-customer-profiles (>=2.5.0,<2.6.0)", "types-aiobotocore-databrew (>=2.5.0,<2.6.0)", "types-aiobotocore-dataexchange (>=2.5.0,<2.6.0)", "types-aiobotocore-datapipeline (>=2.5.0,<2.6.0)", "types-aiobotocore-datasync (>=2.5.0,<2.6.0)", "types-aiobotocore-dax (>=2.5.0,<2.6.0)", "types-aiobotocore-detective (>=2.5.0,<2.6.0)", "types-aiobotocore-devicefarm (>=2.5.0,<2.6.0)", "types-aiobotocore-devops-guru (>=2.5.0,<2.6.0)", "types-aiobotocore-directconnect (>=2.5.0,<2.6.0)", "types-aiobotocore-discovery (>=2.5.0,<2.6.0)", "types-aiobotocore-dlm (>=2.5.0,<2.6.0)", "types-aiobotocore-dms (>=2.5.0,<2.6.0)", "types-aiobotocore-docdb (>=2.5.0,<2.6.0)", "types-aiobotocore-docdb-elastic (>=2.5.0,<2.6.0)", "types-aiobotocore-drs (>=2.5.0,<2.6.0)", "types-aiobotocore-ds (>=2.5.0,<2.6.0)", "types-aiobotocore-dynamodb (>=2.5.0,<2.6.0)", "types-aiobotocore-dynamodbstreams (>=2.5.0,<2.6.0)", "types-aiobotocore-ebs (>=2.5.0,<2.6.0)", "types-aiobotocore-ec2 (>=2.5.0,<2.6.0)", "types-aiobotocore-ec2-instance-connect (>=2.5.0,<2.6.0)", "types-aiobotocore-ecr (>=2.5.0,<2.6.0)", "types-aiobotocore-ecr-public (>=2.5.0,<2.6.0)", "types-aiobotocore-ecs (>=2.5.0,<2.6.0)", "types-aiobotocore-efs (>=2.5.0,<2.6.0)", "types-aiobotocore-eks (>=2.5.0,<2.6.0)", "types-aiobotocore-elastic-inference (>=2.5.0,<2.6.0)", "types-aiobotocore-elasticache (>=2.5.0,<2.6.0)", "types-aiobotocore-elasticbeanstalk (>=2.5.0,<2.6.0)", "types-aiobotocore-elastictranscoder (>=2.5.0,<2.6.0)", "types-aiobotocore-elb (>=2.5.0,<2.6.0)", "types-aiobotocore-elbv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-emr (>=2.5.0,<2.6.0)", "types-aiobotocore-emr-containers (>=2.5.0,<2.6.0)", "types-aiobotocore-emr-serverless (>=2.5.0,<2.6.0)", "types-aiobotocore-es (>=2.5.0,<2.6.0)", "types-aiobotocore-events (>=2.5.0,<2.6.0)", "types-aiobotocore-evidently (>=2.5.0,<2.6.0)", "types-aiobotocore-finspace (>=2.5.0,<2.6.0)", "types-aiobotocore-finspace-data (>=2.5.0,<2.6.0)", "types-aiobotocore-firehose (>=2.5.0,<2.6.0)", "types-aiobotocore-fis (>=2.5.0,<2.6.0)", "types-aiobotocore-fms (>=2.5.0,<2.6.0)", "types-aiobotocore-forecast (>=2.5.0,<2.6.0)", "types-aiobotocore-forecastquery (>=2.5.0,<2.6.0)", "types-aiobotocore-frauddetector (>=2.5.0,<2.6.0)", "types-aiobotocore-fsx (>=2.5.0,<2.6.0)", "types-aiobotocore-gamelift (>=2.5.0,<2.6.0)", "types-aiobotocore-gamesparks (>=2.5.0,<2.6.0)", "types-aiobotocore-glacier (>=2.5.0,<2.6.0)", "types-aiobotocore-globalaccelerator (>=2.5.0,<2.6.0)", "types-aiobotocore-glue (>=2.5.0,<2.6.0)", "types-aiobotocore-grafana (>=2.5.0,<2.6.0)", "types-aiobotocore-greengrass (>=2.5.0,<2.6.0)", "types-aiobotocore-greengrassv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-groundstation (>=2.5.0,<2.6.0)", "types-aiobotocore-guardduty (>=2.5.0,<2.6.0)", "types-aiobotocore-health (>=2.5.0,<2.6.0)", "types-aiobotocore-healthlake (>=2.5.0,<2.6.0)", "types-aiobotocore-honeycode (>=2.5.0,<2.6.0)", "types-aiobotocore-iam (>=2.5.0,<2.6.0)", "types-aiobotocore-identitystore (>=2.5.0,<2.6.0)", "types-aiobotocore-imagebuilder (>=2.5.0,<2.6.0)", "types-aiobotocore-importexport (>=2.5.0,<2.6.0)", "types-aiobotocore-inspector (>=2.5.0,<2.6.0)", "types-aiobotocore-inspector2 (>=2.5.0,<2.6.0)", "types-aiobotocore-iot (>=2.5.0,<2.6.0)", "types-aiobotocore-iot-data (>=2.5.0,<2.6.0)", "types-aiobotocore-iot-jobs-data (>=2.5.0,<2.6.0)", "types-aiobotocore-iot-roborunner (>=2.5.0,<2.6.0)", "types-aiobotocore-iot1click-devices (>=2.5.0,<2.6.0)", "types-aiobotocore-iot1click-projects (>=2.5.0,<2.6.0)", "types-aiobotocore-iotanalytics (>=2.5.0,<2.6.0)", "types-aiobotocore-iotdeviceadvisor (>=2.5.0,<2.6.0)", "types-aiobotocore-iotevents (>=2.5.0,<2.6.0)", "types-aiobotocore-iotevents-data (>=2.5.0,<2.6.0)", "types-aiobotocore-iotfleethub (>=2.5.0,<2.6.0)", "types-aiobotocore-iotfleetwise (>=2.5.0,<2.6.0)", "types-aiobotocore-iotsecuretunneling (>=2.5.0,<2.6.0)", "types-aiobotocore-iotsitewise (>=2.5.0,<2.6.0)", "types-aiobotocore-iotthingsgraph (>=2.5.0,<2.6.0)", "types-aiobotocore-iottwinmaker (>=2.5.0,<2.6.0)", "types-aiobotocore-iotwireless (>=2.5.0,<2.6.0)", "types-aiobotocore-ivs (>=2.5.0,<2.6.0)", "types-aiobotocore-ivschat (>=2.5.0,<2.6.0)", "types-aiobotocore-kafka (>=2.5.0,<2.6.0)", "types-aiobotocore-kafkaconnect (>=2.5.0,<2.6.0)", "types-aiobotocore-kendra (>=2.5.0,<2.6.0)", "types-aiobotocore-kendra-ranking (>=2.5.0,<2.6.0)", "types-aiobotocore-keyspaces (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesis (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesis-video-archived-media (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesis-video-media (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesis-video-signaling (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesis-video-webrtc-storage (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesisanalytics (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesisanalyticsv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-kinesisvideo (>=2.5.0,<2.6.0)", "types-aiobotocore-kms (>=2.5.0,<2.6.0)", "types-aiobotocore-lakeformation (>=2.5.0,<2.6.0)", "types-aiobotocore-lambda (>=2.5.0,<2.6.0)", "types-aiobotocore-lex-models (>=2.5.0,<2.6.0)", "types-aiobotocore-lex-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-lexv2-models (>=2.5.0,<2.6.0)", "types-aiobotocore-lexv2-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-license-manager (>=2.5.0,<2.6.0)", "types-aiobotocore-license-manager-linux-subscriptions (>=2.5.0,<2.6.0)", "types-aiobotocore-license-manager-user-subscriptions (>=2.5.0,<2.6.0)", "types-aiobotocore-lightsail (>=2.5.0,<2.6.0)", "types-aiobotocore-location (>=2.5.0,<2.6.0)", "types-aiobotocore-logs (>=2.5.0,<2.6.0)", "types-aiobotocore-lookoutequipment (>=2.5.0,<2.6.0)", "types-aiobotocore-lookoutmetrics (>=2.5.0,<2.6.0)", "types-aiobotocore-lookoutvision (>=2.5.0,<2.6.0)", "types-aiobotocore-m2 (>=2.5.0,<2.6.0)", "types-aiobotocore-machinelearning (>=2.5.0,<2.6.0)", "types-aiobotocore-macie (>=2.5.0,<2.6.0)", "types-aiobotocore-macie2 (>=2.5.0,<2.6.0)", "types-aiobotocore-managedblockchain (>=2.5.0,<2.6.0)", "types-aiobotocore-marketplace-catalog (>=2.5.0,<2.6.0)", "types-aiobotocore-marketplace-entitlement (>=2.5.0,<2.6.0)", "types-aiobotocore-marketplacecommerceanalytics (>=2.5.0,<2.6.0)", "types-aiobotocore-mediaconnect (>=2.5.0,<2.6.0)", "types-aiobotocore-mediaconvert (>=2.5.0,<2.6.0)", "types-aiobotocore-medialive (>=2.5.0,<2.6.0)", "types-aiobotocore-mediapackage (>=2.5.0,<2.6.0)", "types-aiobotocore-mediapackage-vod (>=2.5.0,<2.6.0)", "types-aiobotocore-mediastore (>=2.5.0,<2.6.0)", "types-aiobotocore-mediastore-data (>=2.5.0,<2.6.0)", "types-aiobotocore-mediatailor (>=2.5.0,<2.6.0)", "types-aiobotocore-memorydb (>=2.5.0,<2.6.0)", "types-aiobotocore-meteringmarketplace (>=2.5.0,<2.6.0)", "types-aiobotocore-mgh (>=2.5.0,<2.6.0)", "types-aiobotocore-mgn (>=2.5.0,<2.6.0)", "types-aiobotocore-migration-hub-refactor-spaces (>=2.5.0,<2.6.0)", "types-aiobotocore-migrationhub-config (>=2.5.0,<2.6.0)", "types-aiobotocore-migrationhuborchestrator (>=2.5.0,<2.6.0)", "types-aiobotocore-migrationhubstrategy (>=2.5.0,<2.6.0)", "types-aiobotocore-mobile (>=2.5.0,<2.6.0)", "types-aiobotocore-mq (>=2.5.0,<2.6.0)", "types-aiobotocore-mturk (>=2.5.0,<2.6.0)", "types-aiobotocore-mwaa (>=2.5.0,<2.6.0)", "types-aiobotocore-neptune (>=2.5.0,<2.6.0)", "types-aiobotocore-network-firewall (>=2.5.0,<2.6.0)", "types-aiobotocore-networkmanager (>=2.5.0,<2.6.0)", "types-aiobotocore-nimble (>=2.5.0,<2.6.0)", "types-aiobotocore-oam (>=2.5.0,<2.6.0)", "types-aiobotocore-omics (>=2.5.0,<2.6.0)", "types-aiobotocore-opensearch (>=2.5.0,<2.6.0)", "types-aiobotocore-opensearchserverless (>=2.5.0,<2.6.0)", "types-aiobotocore-opsworks (>=2.5.0,<2.6.0)", "types-aiobotocore-opsworkscm (>=2.5.0,<2.6.0)", "types-aiobotocore-organizations (>=2.5.0,<2.6.0)", "types-aiobotocore-outposts (>=2.5.0,<2.6.0)", "types-aiobotocore-panorama (>=2.5.0,<2.6.0)", "types-aiobotocore-personalize (>=2.5.0,<2.6.0)", "types-aiobotocore-personalize-events (>=2.5.0,<2.6.0)", "types-aiobotocore-personalize-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-pi (>=2.5.0,<2.6.0)", "types-aiobotocore-pinpoint (>=2.5.0,<2.6.0)", "types-aiobotocore-pinpoint-email (>=2.5.0,<2.6.0)", "types-aiobotocore-pinpoint-sms-voice (>=2.5.0,<2.6.0)", "types-aiobotocore-pinpoint-sms-voice-v2 (>=2.5.0,<2.6.0)", "types-aiobotocore-pipes (>=2.5.0,<2.6.0)", "types-aiobotocore-polly (>=2.5.0,<2.6.0)", "types-aiobotocore-pricing (>=2.5.0,<2.6.0)", "types-aiobotocore-privatenetworks (>=2.5.0,<2.6.0)", "types-aiobotocore-proton (>=2.5.0,<2.6.0)", "types-aiobotocore-qldb (>=2.5.0,<2.6.0)", "types-aiobotocore-qldb-session (>=2.5.0,<2.6.0)", "types-aiobotocore-quicksight (>=2.5.0,<2.6.0)", "types-aiobotocore-ram (>=2.5.0,<2.6.0)", "types-aiobotocore-rbin (>=2.5.0,<2.6.0)", "types-aiobotocore-rds (>=2.5.0,<2.6.0)", "types-aiobotocore-rds-data (>=2.5.0,<2.6.0)", "types-aiobotocore-redshift (>=2.5.0,<2.6.0)", "types-aiobotocore-redshift-data (>=2.5.0,<2.6.0)", "types-aiobotocore-redshift-serverless (>=2.5.0,<2.6.0)", "types-aiobotocore-rekognition (>=2.5.0,<2.6.0)", "types-aiobotocore-resiliencehub (>=2.5.0,<2.6.0)", "types-aiobotocore-resource-explorer-2 (>=2.5.0,<2.6.0)", "types-aiobotocore-resource-groups (>=2.5.0,<2.6.0)", "types-aiobotocore-resourcegroupstaggingapi (>=2.5.0,<2.6.0)", "types-aiobotocore-robomaker (>=2.5.0,<2.6.0)", "types-aiobotocore-rolesanywhere (>=2.5.0,<2.6.0)", "types-aiobotocore-route53 (>=2.5.0,<2.6.0)", "types-aiobotocore-route53-recovery-cluster (>=2.5.0,<2.6.0)", "types-aiobotocore-route53-recovery-control-config (>=2.5.0,<2.6.0)", "types-aiobotocore-route53-recovery-readiness (>=2.5.0,<2.6.0)", "types-aiobotocore-route53domains (>=2.5.0,<2.6.0)", "types-aiobotocore-route53resolver (>=2.5.0,<2.6.0)", "types-aiobotocore-rum (>=2.5.0,<2.6.0)", "types-aiobotocore-s3 (>=2.5.0,<2.6.0)", "types-aiobotocore-s3control (>=2.5.0,<2.6.0)", "types-aiobotocore-s3outposts (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-a2i-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-edge (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-featurestore-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-geospatial (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-metrics (>=2.5.0,<2.6.0)", "types-aiobotocore-sagemaker-runtime (>=2.5.0,<2.6.0)", "types-aiobotocore-savingsplans (>=2.5.0,<2.6.0)", "types-aiobotocore-scheduler (>=2.5.0,<2.6.0)", "types-aiobotocore-schemas (>=2.5.0,<2.6.0)", "types-aiobotocore-sdb (>=2.5.0,<2.6.0)", "types-aiobotocore-secretsmanager (>=2.5.0,<2.6.0)", "types-aiobotocore-securityhub (>=2.5.0,<2.6.0)", "types-aiobotocore-securitylake (>=2.5.0,<2.6.0)", "types-aiobotocore-serverlessrepo (>=2.5.0,<2.6.0)", "types-aiobotocore-service-quotas (>=2.5.0,<2.6.0)", "types-aiobotocore-servicecatalog (>=2.5.0,<2.6.0)", "types-aiobotocore-servicecatalog-appregistry (>=2.5.0,<2.6.0)", "types-aiobotocore-servicediscovery (>=2.5.0,<2.6.0)", "types-aiobotocore-ses (>=2.5.0,<2.6.0)", "types-aiobotocore-sesv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-shield (>=2.5.0,<2.6.0)", "types-aiobotocore-signer (>=2.5.0,<2.6.0)", "types-aiobotocore-simspaceweaver (>=2.5.0,<2.6.0)", "types-aiobotocore-sms (>=2.5.0,<2.6.0)", "types-aiobotocore-sms-voice (>=2.5.0,<2.6.0)", "types-aiobotocore-snow-device-management (>=2.5.0,<2.6.0)", "types-aiobotocore-snowball (>=2.5.0,<2.6.0)", "types-aiobotocore-sns (>=2.5.0,<2.6.0)", "types-aiobotocore-sqs (>=2.5.0,<2.6.0)", "types-aiobotocore-ssm (>=2.5.0,<2.6.0)", "types-aiobotocore-ssm-contacts (>=2.5.0,<2.6.0)", "types-aiobotocore-ssm-incidents (>=2.5.0,<2.6.0)", "types-aiobotocore-ssm-sap (>=2.5.0,<2.6.0)", "types-aiobotocore-sso (>=2.5.0,<2.6.0)", "types-aiobotocore-sso-admin (>=2.5.0,<2.6.0)", "types-aiobotocore-sso-oidc (>=2.5.0,<2.6.0)", "types-aiobotocore-stepfunctions (>=2.5.0,<2.6.0)", "types-aiobotocore-storagegateway (>=2.5.0,<2.6.0)", "types-aiobotocore-sts (>=2.5.0,<2.6.0)", "types-aiobotocore-support (>=2.5.0,<2.6.0)", "types-aiobotocore-support-app (>=2.5.0,<2.6.0)", "types-aiobotocore-swf (>=2.5.0,<2.6.0)", "types-aiobotocore-synthetics (>=2.5.0,<2.6.0)", "types-aiobotocore-textract (>=2.5.0,<2.6.0)", "types-aiobotocore-timestream-query (>=2.5.0,<2.6.0)", "types-aiobotocore-timestream-write (>=2.5.0,<2.6.0)", "types-aiobotocore-tnb (>=2.5.0,<2.6.0)", "types-aiobotocore-transcribe (>=2.5.0,<2.6.0)", "types-aiobotocore-transfer (>=2.5.0,<2.6.0)", "types-aiobotocore-translate (>=2.5.0,<2.6.0)", "types-aiobotocore-voice-id (>=2.5.0,<2.6.0)", "types-aiobotocore-waf (>=2.5.0,<2.6.0)", "types-aiobotocore-waf-regional (>=2.5.0,<2.6.0)", "types-aiobotocore-wafv2 (>=2.5.0,<2.6.0)", "types-aiobotocore-wellarchitected (>=2.5.0,<2.6.0)", "types-aiobotocore-wisdom (>=2.5.0,<2.6.0)", "types-aiobotocore-workdocs (>=2.5.0,<2.6.0)", "types-aiobotocore-worklink (>=2.5.0,<2.6.0)", "types-aiobotocore-workmail (>=2.5.0,<2.6.0)", "types-aiobotocore-workmailmessageflow (>=2.5.0,<2.6.0)", "types-aiobotocore-workspaces (>=2.5.0,<2.6.0)", "types-aiobotocore-workspaces-web (>=2.5.0,<2.6.0)", "types-aiobotocore-xray (>=2.5.0,<2.6.0)"] +amp = ["types-aiobotocore-amp (>=2.5.0,<2.6.0)"] +amplify = ["types-aiobotocore-amplify (>=2.5.0,<2.6.0)"] +amplifybackend = ["types-aiobotocore-amplifybackend (>=2.5.0,<2.6.0)"] +amplifyuibuilder = ["types-aiobotocore-amplifyuibuilder (>=2.5.0,<2.6.0)"] +apigateway = ["types-aiobotocore-apigateway (>=2.5.0,<2.6.0)"] +apigatewaymanagementapi = ["types-aiobotocore-apigatewaymanagementapi (>=2.5.0,<2.6.0)"] +apigatewayv2 = ["types-aiobotocore-apigatewayv2 (>=2.5.0,<2.6.0)"] +appconfig = ["types-aiobotocore-appconfig (>=2.5.0,<2.6.0)"] +appconfigdata = ["types-aiobotocore-appconfigdata (>=2.5.0,<2.6.0)"] +appflow = ["types-aiobotocore-appflow (>=2.5.0,<2.6.0)"] +appintegrations = ["types-aiobotocore-appintegrations (>=2.5.0,<2.6.0)"] +application-autoscaling = ["types-aiobotocore-application-autoscaling (>=2.5.0,<2.6.0)"] +application-insights = ["types-aiobotocore-application-insights (>=2.5.0,<2.6.0)"] +applicationcostprofiler = ["types-aiobotocore-applicationcostprofiler (>=2.5.0,<2.6.0)"] +appmesh = ["types-aiobotocore-appmesh (>=2.5.0,<2.6.0)"] +apprunner = ["types-aiobotocore-apprunner (>=2.5.0,<2.6.0)"] +appstream = ["types-aiobotocore-appstream (>=2.5.0,<2.6.0)"] +appsync = ["types-aiobotocore-appsync (>=2.5.0,<2.6.0)"] +arc-zonal-shift = ["types-aiobotocore-arc-zonal-shift (>=2.5.0,<2.6.0)"] +athena = ["types-aiobotocore-athena (>=2.5.0,<2.6.0)"] +auditmanager = ["types-aiobotocore-auditmanager (>=2.5.0,<2.6.0)"] +autoscaling = ["types-aiobotocore-autoscaling (>=2.5.0,<2.6.0)"] +autoscaling-plans = ["types-aiobotocore-autoscaling-plans (>=2.5.0,<2.6.0)"] +backup = ["types-aiobotocore-backup (>=2.5.0,<2.6.0)"] +backup-gateway = ["types-aiobotocore-backup-gateway (>=2.5.0,<2.6.0)"] +backupstorage = ["types-aiobotocore-backupstorage (>=2.5.0,<2.6.0)"] +batch = ["types-aiobotocore-batch (>=2.5.0,<2.6.0)"] +billingconductor = ["types-aiobotocore-billingconductor (>=2.5.0,<2.6.0)"] +braket = ["types-aiobotocore-braket (>=2.5.0,<2.6.0)"] +budgets = ["types-aiobotocore-budgets (>=2.5.0,<2.6.0)"] +ce = ["types-aiobotocore-ce (>=2.5.0,<2.6.0)"] +chime = ["types-aiobotocore-chime (>=2.5.0,<2.6.0)"] +chime-sdk-identity = ["types-aiobotocore-chime-sdk-identity (>=2.5.0,<2.6.0)"] +chime-sdk-media-pipelines = ["types-aiobotocore-chime-sdk-media-pipelines (>=2.5.0,<2.6.0)"] +chime-sdk-meetings = ["types-aiobotocore-chime-sdk-meetings (>=2.5.0,<2.6.0)"] +chime-sdk-messaging = ["types-aiobotocore-chime-sdk-messaging (>=2.5.0,<2.6.0)"] +chime-sdk-voice = ["types-aiobotocore-chime-sdk-voice (>=2.5.0,<2.6.0)"] +cleanrooms = ["types-aiobotocore-cleanrooms (>=2.5.0,<2.6.0)"] +cloud9 = ["types-aiobotocore-cloud9 (>=2.5.0,<2.6.0)"] +cloudcontrol = ["types-aiobotocore-cloudcontrol (>=2.5.0,<2.6.0)"] +clouddirectory = ["types-aiobotocore-clouddirectory (>=2.5.0,<2.6.0)"] +cloudformation = ["types-aiobotocore-cloudformation (>=2.5.0,<2.6.0)"] +cloudfront = ["types-aiobotocore-cloudfront (>=2.5.0,<2.6.0)"] +cloudhsm = ["types-aiobotocore-cloudhsm (>=2.5.0,<2.6.0)"] +cloudhsmv2 = ["types-aiobotocore-cloudhsmv2 (>=2.5.0,<2.6.0)"] +cloudsearch = ["types-aiobotocore-cloudsearch (>=2.5.0,<2.6.0)"] +cloudsearchdomain = ["types-aiobotocore-cloudsearchdomain (>=2.5.0,<2.6.0)"] +cloudtrail = ["types-aiobotocore-cloudtrail (>=2.5.0,<2.6.0)"] +cloudtrail-data = ["types-aiobotocore-cloudtrail-data (>=2.5.0,<2.6.0)"] +cloudwatch = ["types-aiobotocore-cloudwatch (>=2.5.0,<2.6.0)"] +codeartifact = ["types-aiobotocore-codeartifact (>=2.5.0,<2.6.0)"] +codebuild = ["types-aiobotocore-codebuild (>=2.5.0,<2.6.0)"] +codecatalyst = ["types-aiobotocore-codecatalyst (>=2.5.0,<2.6.0)"] +codecommit = ["types-aiobotocore-codecommit (>=2.5.0,<2.6.0)"] +codedeploy = ["types-aiobotocore-codedeploy (>=2.5.0,<2.6.0)"] +codeguru-reviewer = ["types-aiobotocore-codeguru-reviewer (>=2.5.0,<2.6.0)"] +codeguruprofiler = ["types-aiobotocore-codeguruprofiler (>=2.5.0,<2.6.0)"] +codepipeline = ["types-aiobotocore-codepipeline (>=2.5.0,<2.6.0)"] +codestar = ["types-aiobotocore-codestar (>=2.5.0,<2.6.0)"] +codestar-connections = ["types-aiobotocore-codestar-connections (>=2.5.0,<2.6.0)"] +codestar-notifications = ["types-aiobotocore-codestar-notifications (>=2.5.0,<2.6.0)"] +cognito-identity = ["types-aiobotocore-cognito-identity (>=2.5.0,<2.6.0)"] +cognito-idp = ["types-aiobotocore-cognito-idp (>=2.5.0,<2.6.0)"] +cognito-sync = ["types-aiobotocore-cognito-sync (>=2.5.0,<2.6.0)"] +comprehend = ["types-aiobotocore-comprehend (>=2.5.0,<2.6.0)"] +comprehendmedical = ["types-aiobotocore-comprehendmedical (>=2.5.0,<2.6.0)"] +compute-optimizer = ["types-aiobotocore-compute-optimizer (>=2.5.0,<2.6.0)"] +config = ["types-aiobotocore-config (>=2.5.0,<2.6.0)"] +connect = ["types-aiobotocore-connect (>=2.5.0,<2.6.0)"] +connect-contact-lens = ["types-aiobotocore-connect-contact-lens (>=2.5.0,<2.6.0)"] +connectcampaigns = ["types-aiobotocore-connectcampaigns (>=2.5.0,<2.6.0)"] +connectcases = ["types-aiobotocore-connectcases (>=2.5.0,<2.6.0)"] +connectparticipant = ["types-aiobotocore-connectparticipant (>=2.5.0,<2.6.0)"] +controltower = ["types-aiobotocore-controltower (>=2.5.0,<2.6.0)"] +cur = ["types-aiobotocore-cur (>=2.5.0,<2.6.0)"] +customer-profiles = ["types-aiobotocore-customer-profiles (>=2.5.0,<2.6.0)"] +databrew = ["types-aiobotocore-databrew (>=2.5.0,<2.6.0)"] +dataexchange = ["types-aiobotocore-dataexchange (>=2.5.0,<2.6.0)"] +datapipeline = ["types-aiobotocore-datapipeline (>=2.5.0,<2.6.0)"] +datasync = ["types-aiobotocore-datasync (>=2.5.0,<2.6.0)"] +dax = ["types-aiobotocore-dax (>=2.5.0,<2.6.0)"] +detective = ["types-aiobotocore-detective (>=2.5.0,<2.6.0)"] +devicefarm = ["types-aiobotocore-devicefarm (>=2.5.0,<2.6.0)"] +devops-guru = ["types-aiobotocore-devops-guru (>=2.5.0,<2.6.0)"] +directconnect = ["types-aiobotocore-directconnect (>=2.5.0,<2.6.0)"] +discovery = ["types-aiobotocore-discovery (>=2.5.0,<2.6.0)"] +dlm = ["types-aiobotocore-dlm (>=2.5.0,<2.6.0)"] +dms = ["types-aiobotocore-dms (>=2.5.0,<2.6.0)"] +docdb = ["types-aiobotocore-docdb (>=2.5.0,<2.6.0)"] +docdb-elastic = ["types-aiobotocore-docdb-elastic (>=2.5.0,<2.6.0)"] +drs = ["types-aiobotocore-drs (>=2.5.0,<2.6.0)"] +ds = ["types-aiobotocore-ds (>=2.5.0,<2.6.0)"] +dynamodb = ["types-aiobotocore-dynamodb (>=2.5.0,<2.6.0)"] +dynamodbstreams = ["types-aiobotocore-dynamodbstreams (>=2.5.0,<2.6.0)"] +ebs = ["types-aiobotocore-ebs (>=2.5.0,<2.6.0)"] +ec2 = ["types-aiobotocore-ec2 (>=2.5.0,<2.6.0)"] +ec2-instance-connect = ["types-aiobotocore-ec2-instance-connect (>=2.5.0,<2.6.0)"] +ecr = ["types-aiobotocore-ecr (>=2.5.0,<2.6.0)"] +ecr-public = ["types-aiobotocore-ecr-public (>=2.5.0,<2.6.0)"] +ecs = ["types-aiobotocore-ecs (>=2.5.0,<2.6.0)"] +efs = ["types-aiobotocore-efs (>=2.5.0,<2.6.0)"] +eks = ["types-aiobotocore-eks (>=2.5.0,<2.6.0)"] +elastic-inference = ["types-aiobotocore-elastic-inference (>=2.5.0,<2.6.0)"] +elasticache = ["types-aiobotocore-elasticache (>=2.5.0,<2.6.0)"] +elasticbeanstalk = ["types-aiobotocore-elasticbeanstalk (>=2.5.0,<2.6.0)"] +elastictranscoder = ["types-aiobotocore-elastictranscoder (>=2.5.0,<2.6.0)"] +elb = ["types-aiobotocore-elb (>=2.5.0,<2.6.0)"] +elbv2 = ["types-aiobotocore-elbv2 (>=2.5.0,<2.6.0)"] +emr = ["types-aiobotocore-emr (>=2.5.0,<2.6.0)"] +emr-containers = ["types-aiobotocore-emr-containers (>=2.5.0,<2.6.0)"] +emr-serverless = ["types-aiobotocore-emr-serverless (>=2.5.0,<2.6.0)"] +es = ["types-aiobotocore-es (>=2.5.0,<2.6.0)"] +essential = ["types-aiobotocore-cloudformation (>=2.5.0,<2.6.0)", "types-aiobotocore-dynamodb (>=2.5.0,<2.6.0)", "types-aiobotocore-ec2 (>=2.5.0,<2.6.0)", "types-aiobotocore-lambda (>=2.5.0,<2.6.0)", "types-aiobotocore-rds (>=2.5.0,<2.6.0)", "types-aiobotocore-s3 (>=2.5.0,<2.6.0)", "types-aiobotocore-sqs (>=2.5.0,<2.6.0)"] +events = ["types-aiobotocore-events (>=2.5.0,<2.6.0)"] +evidently = ["types-aiobotocore-evidently (>=2.5.0,<2.6.0)"] +finspace = ["types-aiobotocore-finspace (>=2.5.0,<2.6.0)"] +finspace-data = ["types-aiobotocore-finspace-data (>=2.5.0,<2.6.0)"] +firehose = ["types-aiobotocore-firehose (>=2.5.0,<2.6.0)"] +fis = ["types-aiobotocore-fis (>=2.5.0,<2.6.0)"] +fms = ["types-aiobotocore-fms (>=2.5.0,<2.6.0)"] +forecast = ["types-aiobotocore-forecast (>=2.5.0,<2.6.0)"] +forecastquery = ["types-aiobotocore-forecastquery (>=2.5.0,<2.6.0)"] +frauddetector = ["types-aiobotocore-frauddetector (>=2.5.0,<2.6.0)"] +fsx = ["types-aiobotocore-fsx (>=2.5.0,<2.6.0)"] +gamelift = ["types-aiobotocore-gamelift (>=2.5.0,<2.6.0)"] +gamesparks = ["types-aiobotocore-gamesparks (>=2.5.0,<2.6.0)"] +glacier = ["types-aiobotocore-glacier (>=2.5.0,<2.6.0)"] +globalaccelerator = ["types-aiobotocore-globalaccelerator (>=2.5.0,<2.6.0)"] +glue = ["types-aiobotocore-glue (>=2.5.0,<2.6.0)"] +grafana = ["types-aiobotocore-grafana (>=2.5.0,<2.6.0)"] +greengrass = ["types-aiobotocore-greengrass (>=2.5.0,<2.6.0)"] +greengrassv2 = ["types-aiobotocore-greengrassv2 (>=2.5.0,<2.6.0)"] +groundstation = ["types-aiobotocore-groundstation (>=2.5.0,<2.6.0)"] +guardduty = ["types-aiobotocore-guardduty (>=2.5.0,<2.6.0)"] +health = ["types-aiobotocore-health (>=2.5.0,<2.6.0)"] +healthlake = ["types-aiobotocore-healthlake (>=2.5.0,<2.6.0)"] +honeycode = ["types-aiobotocore-honeycode (>=2.5.0,<2.6.0)"] +iam = ["types-aiobotocore-iam (>=2.5.0,<2.6.0)"] +identitystore = ["types-aiobotocore-identitystore (>=2.5.0,<2.6.0)"] +imagebuilder = ["types-aiobotocore-imagebuilder (>=2.5.0,<2.6.0)"] +importexport = ["types-aiobotocore-importexport (>=2.5.0,<2.6.0)"] +inspector = ["types-aiobotocore-inspector (>=2.5.0,<2.6.0)"] +inspector2 = ["types-aiobotocore-inspector2 (>=2.5.0,<2.6.0)"] +iot = ["types-aiobotocore-iot (>=2.5.0,<2.6.0)"] +iot-data = ["types-aiobotocore-iot-data (>=2.5.0,<2.6.0)"] +iot-jobs-data = ["types-aiobotocore-iot-jobs-data (>=2.5.0,<2.6.0)"] +iot-roborunner = ["types-aiobotocore-iot-roborunner (>=2.5.0,<2.6.0)"] +iot1click-devices = ["types-aiobotocore-iot1click-devices (>=2.5.0,<2.6.0)"] +iot1click-projects = ["types-aiobotocore-iot1click-projects (>=2.5.0,<2.6.0)"] +iotanalytics = ["types-aiobotocore-iotanalytics (>=2.5.0,<2.6.0)"] +iotdeviceadvisor = ["types-aiobotocore-iotdeviceadvisor (>=2.5.0,<2.6.0)"] +iotevents = ["types-aiobotocore-iotevents (>=2.5.0,<2.6.0)"] +iotevents-data = ["types-aiobotocore-iotevents-data (>=2.5.0,<2.6.0)"] +iotfleethub = ["types-aiobotocore-iotfleethub (>=2.5.0,<2.6.0)"] +iotfleetwise = ["types-aiobotocore-iotfleetwise (>=2.5.0,<2.6.0)"] +iotsecuretunneling = ["types-aiobotocore-iotsecuretunneling (>=2.5.0,<2.6.0)"] +iotsitewise = ["types-aiobotocore-iotsitewise (>=2.5.0,<2.6.0)"] +iotthingsgraph = ["types-aiobotocore-iotthingsgraph (>=2.5.0,<2.6.0)"] +iottwinmaker = ["types-aiobotocore-iottwinmaker (>=2.5.0,<2.6.0)"] +iotwireless = ["types-aiobotocore-iotwireless (>=2.5.0,<2.6.0)"] +ivs = ["types-aiobotocore-ivs (>=2.5.0,<2.6.0)"] +ivschat = ["types-aiobotocore-ivschat (>=2.5.0,<2.6.0)"] +kafka = ["types-aiobotocore-kafka (>=2.5.0,<2.6.0)"] +kafkaconnect = ["types-aiobotocore-kafkaconnect (>=2.5.0,<2.6.0)"] +kendra = ["types-aiobotocore-kendra (>=2.5.0,<2.6.0)"] +kendra-ranking = ["types-aiobotocore-kendra-ranking (>=2.5.0,<2.6.0)"] +keyspaces = ["types-aiobotocore-keyspaces (>=2.5.0,<2.6.0)"] +kinesis = ["types-aiobotocore-kinesis (>=2.5.0,<2.6.0)"] +kinesis-video-archived-media = ["types-aiobotocore-kinesis-video-archived-media (>=2.5.0,<2.6.0)"] +kinesis-video-media = ["types-aiobotocore-kinesis-video-media (>=2.5.0,<2.6.0)"] +kinesis-video-signaling = ["types-aiobotocore-kinesis-video-signaling (>=2.5.0,<2.6.0)"] +kinesis-video-webrtc-storage = ["types-aiobotocore-kinesis-video-webrtc-storage (>=2.5.0,<2.6.0)"] +kinesisanalytics = ["types-aiobotocore-kinesisanalytics (>=2.5.0,<2.6.0)"] +kinesisanalyticsv2 = ["types-aiobotocore-kinesisanalyticsv2 (>=2.5.0,<2.6.0)"] +kinesisvideo = ["types-aiobotocore-kinesisvideo (>=2.5.0,<2.6.0)"] +kms = ["types-aiobotocore-kms (>=2.5.0,<2.6.0)"] +lakeformation = ["types-aiobotocore-lakeformation (>=2.5.0,<2.6.0)"] +lambda = ["types-aiobotocore-lambda (>=2.5.0,<2.6.0)"] +lex-models = ["types-aiobotocore-lex-models (>=2.5.0,<2.6.0)"] +lex-runtime = ["types-aiobotocore-lex-runtime (>=2.5.0,<2.6.0)"] +lexv2-models = ["types-aiobotocore-lexv2-models (>=2.5.0,<2.6.0)"] +lexv2-runtime = ["types-aiobotocore-lexv2-runtime (>=2.5.0,<2.6.0)"] +license-manager = ["types-aiobotocore-license-manager (>=2.5.0,<2.6.0)"] +license-manager-linux-subscriptions = ["types-aiobotocore-license-manager-linux-subscriptions (>=2.5.0,<2.6.0)"] +license-manager-user-subscriptions = ["types-aiobotocore-license-manager-user-subscriptions (>=2.5.0,<2.6.0)"] +lightsail = ["types-aiobotocore-lightsail (>=2.5.0,<2.6.0)"] +location = ["types-aiobotocore-location (>=2.5.0,<2.6.0)"] +logs = ["types-aiobotocore-logs (>=2.5.0,<2.6.0)"] +lookoutequipment = ["types-aiobotocore-lookoutequipment (>=2.5.0,<2.6.0)"] +lookoutmetrics = ["types-aiobotocore-lookoutmetrics (>=2.5.0,<2.6.0)"] +lookoutvision = ["types-aiobotocore-lookoutvision (>=2.5.0,<2.6.0)"] +m2 = ["types-aiobotocore-m2 (>=2.5.0,<2.6.0)"] +machinelearning = ["types-aiobotocore-machinelearning (>=2.5.0,<2.6.0)"] +macie = ["types-aiobotocore-macie (>=2.5.0,<2.6.0)"] +macie2 = ["types-aiobotocore-macie2 (>=2.5.0,<2.6.0)"] +managedblockchain = ["types-aiobotocore-managedblockchain (>=2.5.0,<2.6.0)"] +marketplace-catalog = ["types-aiobotocore-marketplace-catalog (>=2.5.0,<2.6.0)"] +marketplace-entitlement = ["types-aiobotocore-marketplace-entitlement (>=2.5.0,<2.6.0)"] +marketplacecommerceanalytics = ["types-aiobotocore-marketplacecommerceanalytics (>=2.5.0,<2.6.0)"] +mediaconnect = ["types-aiobotocore-mediaconnect (>=2.5.0,<2.6.0)"] +mediaconvert = ["types-aiobotocore-mediaconvert (>=2.5.0,<2.6.0)"] +medialive = ["types-aiobotocore-medialive (>=2.5.0,<2.6.0)"] +mediapackage = ["types-aiobotocore-mediapackage (>=2.5.0,<2.6.0)"] +mediapackage-vod = ["types-aiobotocore-mediapackage-vod (>=2.5.0,<2.6.0)"] +mediastore = ["types-aiobotocore-mediastore (>=2.5.0,<2.6.0)"] +mediastore-data = ["types-aiobotocore-mediastore-data (>=2.5.0,<2.6.0)"] +mediatailor = ["types-aiobotocore-mediatailor (>=2.5.0,<2.6.0)"] +memorydb = ["types-aiobotocore-memorydb (>=2.5.0,<2.6.0)"] +meteringmarketplace = ["types-aiobotocore-meteringmarketplace (>=2.5.0,<2.6.0)"] +mgh = ["types-aiobotocore-mgh (>=2.5.0,<2.6.0)"] +mgn = ["types-aiobotocore-mgn (>=2.5.0,<2.6.0)"] +migration-hub-refactor-spaces = ["types-aiobotocore-migration-hub-refactor-spaces (>=2.5.0,<2.6.0)"] +migrationhub-config = ["types-aiobotocore-migrationhub-config (>=2.5.0,<2.6.0)"] +migrationhuborchestrator = ["types-aiobotocore-migrationhuborchestrator (>=2.5.0,<2.6.0)"] +migrationhubstrategy = ["types-aiobotocore-migrationhubstrategy (>=2.5.0,<2.6.0)"] +mobile = ["types-aiobotocore-mobile (>=2.5.0,<2.6.0)"] +mq = ["types-aiobotocore-mq (>=2.5.0,<2.6.0)"] +mturk = ["types-aiobotocore-mturk (>=2.5.0,<2.6.0)"] +mwaa = ["types-aiobotocore-mwaa (>=2.5.0,<2.6.0)"] +neptune = ["types-aiobotocore-neptune (>=2.5.0,<2.6.0)"] +network-firewall = ["types-aiobotocore-network-firewall (>=2.5.0,<2.6.0)"] +networkmanager = ["types-aiobotocore-networkmanager (>=2.5.0,<2.6.0)"] +nimble = ["types-aiobotocore-nimble (>=2.5.0,<2.6.0)"] +oam = ["types-aiobotocore-oam (>=2.5.0,<2.6.0)"] +omics = ["types-aiobotocore-omics (>=2.5.0,<2.6.0)"] +opensearch = ["types-aiobotocore-opensearch (>=2.5.0,<2.6.0)"] +opensearchserverless = ["types-aiobotocore-opensearchserverless (>=2.5.0,<2.6.0)"] +opsworks = ["types-aiobotocore-opsworks (>=2.5.0,<2.6.0)"] +opsworkscm = ["types-aiobotocore-opsworkscm (>=2.5.0,<2.6.0)"] +organizations = ["types-aiobotocore-organizations (>=2.5.0,<2.6.0)"] +outposts = ["types-aiobotocore-outposts (>=2.5.0,<2.6.0)"] +panorama = ["types-aiobotocore-panorama (>=2.5.0,<2.6.0)"] +personalize = ["types-aiobotocore-personalize (>=2.5.0,<2.6.0)"] +personalize-events = ["types-aiobotocore-personalize-events (>=2.5.0,<2.6.0)"] +personalize-runtime = ["types-aiobotocore-personalize-runtime (>=2.5.0,<2.6.0)"] +pi = ["types-aiobotocore-pi (>=2.5.0,<2.6.0)"] +pinpoint = ["types-aiobotocore-pinpoint (>=2.5.0,<2.6.0)"] +pinpoint-email = ["types-aiobotocore-pinpoint-email (>=2.5.0,<2.6.0)"] +pinpoint-sms-voice = ["types-aiobotocore-pinpoint-sms-voice (>=2.5.0,<2.6.0)"] +pinpoint-sms-voice-v2 = ["types-aiobotocore-pinpoint-sms-voice-v2 (>=2.5.0,<2.6.0)"] +pipes = ["types-aiobotocore-pipes (>=2.5.0,<2.6.0)"] +polly = ["types-aiobotocore-polly (>=2.5.0,<2.6.0)"] +pricing = ["types-aiobotocore-pricing (>=2.5.0,<2.6.0)"] +privatenetworks = ["types-aiobotocore-privatenetworks (>=2.5.0,<2.6.0)"] +proton = ["types-aiobotocore-proton (>=2.5.0,<2.6.0)"] +qldb = ["types-aiobotocore-qldb (>=2.5.0,<2.6.0)"] +qldb-session = ["types-aiobotocore-qldb-session (>=2.5.0,<2.6.0)"] +quicksight = ["types-aiobotocore-quicksight (>=2.5.0,<2.6.0)"] +ram = ["types-aiobotocore-ram (>=2.5.0,<2.6.0)"] +rbin = ["types-aiobotocore-rbin (>=2.5.0,<2.6.0)"] +rds = ["types-aiobotocore-rds (>=2.5.0,<2.6.0)"] +rds-data = ["types-aiobotocore-rds-data (>=2.5.0,<2.6.0)"] +redshift = ["types-aiobotocore-redshift (>=2.5.0,<2.6.0)"] +redshift-data = ["types-aiobotocore-redshift-data (>=2.5.0,<2.6.0)"] +redshift-serverless = ["types-aiobotocore-redshift-serverless (>=2.5.0,<2.6.0)"] +rekognition = ["types-aiobotocore-rekognition (>=2.5.0,<2.6.0)"] +resiliencehub = ["types-aiobotocore-resiliencehub (>=2.5.0,<2.6.0)"] +resource-explorer-2 = ["types-aiobotocore-resource-explorer-2 (>=2.5.0,<2.6.0)"] +resource-groups = ["types-aiobotocore-resource-groups (>=2.5.0,<2.6.0)"] +resourcegroupstaggingapi = ["types-aiobotocore-resourcegroupstaggingapi (>=2.5.0,<2.6.0)"] +robomaker = ["types-aiobotocore-robomaker (>=2.5.0,<2.6.0)"] +rolesanywhere = ["types-aiobotocore-rolesanywhere (>=2.5.0,<2.6.0)"] +route53 = ["types-aiobotocore-route53 (>=2.5.0,<2.6.0)"] +route53-recovery-cluster = ["types-aiobotocore-route53-recovery-cluster (>=2.5.0,<2.6.0)"] +route53-recovery-control-config = ["types-aiobotocore-route53-recovery-control-config (>=2.5.0,<2.6.0)"] +route53-recovery-readiness = ["types-aiobotocore-route53-recovery-readiness (>=2.5.0,<2.6.0)"] +route53domains = ["types-aiobotocore-route53domains (>=2.5.0,<2.6.0)"] +route53resolver = ["types-aiobotocore-route53resolver (>=2.5.0,<2.6.0)"] +rum = ["types-aiobotocore-rum (>=2.5.0,<2.6.0)"] +s3 = ["types-aiobotocore-s3 (>=2.5.0,<2.6.0)"] +s3control = ["types-aiobotocore-s3control (>=2.5.0,<2.6.0)"] +s3outposts = ["types-aiobotocore-s3outposts (>=2.5.0,<2.6.0)"] +sagemaker = ["types-aiobotocore-sagemaker (>=2.5.0,<2.6.0)"] +sagemaker-a2i-runtime = ["types-aiobotocore-sagemaker-a2i-runtime (>=2.5.0,<2.6.0)"] +sagemaker-edge = ["types-aiobotocore-sagemaker-edge (>=2.5.0,<2.6.0)"] +sagemaker-featurestore-runtime = ["types-aiobotocore-sagemaker-featurestore-runtime (>=2.5.0,<2.6.0)"] +sagemaker-geospatial = ["types-aiobotocore-sagemaker-geospatial (>=2.5.0,<2.6.0)"] +sagemaker-metrics = ["types-aiobotocore-sagemaker-metrics (>=2.5.0,<2.6.0)"] +sagemaker-runtime = ["types-aiobotocore-sagemaker-runtime (>=2.5.0,<2.6.0)"] +savingsplans = ["types-aiobotocore-savingsplans (>=2.5.0,<2.6.0)"] +scheduler = ["types-aiobotocore-scheduler (>=2.5.0,<2.6.0)"] +schemas = ["types-aiobotocore-schemas (>=2.5.0,<2.6.0)"] +sdb = ["types-aiobotocore-sdb (>=2.5.0,<2.6.0)"] +secretsmanager = ["types-aiobotocore-secretsmanager (>=2.5.0,<2.6.0)"] +securityhub = ["types-aiobotocore-securityhub (>=2.5.0,<2.6.0)"] +securitylake = ["types-aiobotocore-securitylake (>=2.5.0,<2.6.0)"] +serverlessrepo = ["types-aiobotocore-serverlessrepo (>=2.5.0,<2.6.0)"] +service-quotas = ["types-aiobotocore-service-quotas (>=2.5.0,<2.6.0)"] +servicecatalog = ["types-aiobotocore-servicecatalog (>=2.5.0,<2.6.0)"] +servicecatalog-appregistry = ["types-aiobotocore-servicecatalog-appregistry (>=2.5.0,<2.6.0)"] +servicediscovery = ["types-aiobotocore-servicediscovery (>=2.5.0,<2.6.0)"] +ses = ["types-aiobotocore-ses (>=2.5.0,<2.6.0)"] +sesv2 = ["types-aiobotocore-sesv2 (>=2.5.0,<2.6.0)"] +shield = ["types-aiobotocore-shield (>=2.5.0,<2.6.0)"] +signer = ["types-aiobotocore-signer (>=2.5.0,<2.6.0)"] +simspaceweaver = ["types-aiobotocore-simspaceweaver (>=2.5.0,<2.6.0)"] +sms = ["types-aiobotocore-sms (>=2.5.0,<2.6.0)"] +sms-voice = ["types-aiobotocore-sms-voice (>=2.5.0,<2.6.0)"] +snow-device-management = ["types-aiobotocore-snow-device-management (>=2.5.0,<2.6.0)"] +snowball = ["types-aiobotocore-snowball (>=2.5.0,<2.6.0)"] +sns = ["types-aiobotocore-sns (>=2.5.0,<2.6.0)"] +sqs = ["types-aiobotocore-sqs (>=2.5.0,<2.6.0)"] +ssm = ["types-aiobotocore-ssm (>=2.5.0,<2.6.0)"] +ssm-contacts = ["types-aiobotocore-ssm-contacts (>=2.5.0,<2.6.0)"] +ssm-incidents = ["types-aiobotocore-ssm-incidents (>=2.5.0,<2.6.0)"] +ssm-sap = ["types-aiobotocore-ssm-sap (>=2.5.0,<2.6.0)"] +sso = ["types-aiobotocore-sso (>=2.5.0,<2.6.0)"] +sso-admin = ["types-aiobotocore-sso-admin (>=2.5.0,<2.6.0)"] +sso-oidc = ["types-aiobotocore-sso-oidc (>=2.5.0,<2.6.0)"] +stepfunctions = ["types-aiobotocore-stepfunctions (>=2.5.0,<2.6.0)"] +storagegateway = ["types-aiobotocore-storagegateway (>=2.5.0,<2.6.0)"] +sts = ["types-aiobotocore-sts (>=2.5.0,<2.6.0)"] +support = ["types-aiobotocore-support (>=2.5.0,<2.6.0)"] +support-app = ["types-aiobotocore-support-app (>=2.5.0,<2.6.0)"] +swf = ["types-aiobotocore-swf (>=2.5.0,<2.6.0)"] +synthetics = ["types-aiobotocore-synthetics (>=2.5.0,<2.6.0)"] +textract = ["types-aiobotocore-textract (>=2.5.0,<2.6.0)"] +timestream-query = ["types-aiobotocore-timestream-query (>=2.5.0,<2.6.0)"] +timestream-write = ["types-aiobotocore-timestream-write (>=2.5.0,<2.6.0)"] +tnb = ["types-aiobotocore-tnb (>=2.5.0,<2.6.0)"] +transcribe = ["types-aiobotocore-transcribe (>=2.5.0,<2.6.0)"] +transfer = ["types-aiobotocore-transfer (>=2.5.0,<2.6.0)"] +translate = ["types-aiobotocore-translate (>=2.5.0,<2.6.0)"] +voice-id = ["types-aiobotocore-voice-id (>=2.5.0,<2.6.0)"] +waf = ["types-aiobotocore-waf (>=2.5.0,<2.6.0)"] +waf-regional = ["types-aiobotocore-waf-regional (>=2.5.0,<2.6.0)"] +wafv2 = ["types-aiobotocore-wafv2 (>=2.5.0,<2.6.0)"] +wellarchitected = ["types-aiobotocore-wellarchitected (>=2.5.0,<2.6.0)"] +wisdom = ["types-aiobotocore-wisdom (>=2.5.0,<2.6.0)"] +workdocs = ["types-aiobotocore-workdocs (>=2.5.0,<2.6.0)"] +worklink = ["types-aiobotocore-worklink (>=2.5.0,<2.6.0)"] +workmail = ["types-aiobotocore-workmail (>=2.5.0,<2.6.0)"] +workmailmessageflow = ["types-aiobotocore-workmailmessageflow (>=2.5.0,<2.6.0)"] +workspaces = ["types-aiobotocore-workspaces (>=2.5.0,<2.6.0)"] +workspaces-web = ["types-aiobotocore-workspaces-web (>=2.5.0,<2.6.0)"] +xray = ["types-aiobotocore-xray (>=2.5.0,<2.6.0)"] + +[[package]] +name = "types-aiobotocore-dynamodb" +version = "2.5.0.post1" +description = "Type annotations for aiobotocore.DynamoDB 2.5.0 service generated with mypy-boto3-builder 7.13.0" +category = "dev" +optional = false +python-versions = ">=3.7" +files = [ + {file = "types-aiobotocore-dynamodb-2.5.0.post1.tar.gz", hash = "sha256:21ed5a55c6aa4e7ac3660b8b1af7b85a88294b292e4232afea4c771d794ebc84"}, + {file = "types_aiobotocore_dynamodb-2.5.0.post1-py3-none-any.whl", hash = "sha256:2ba30ac2984b169b713d30765a50f775013c17cfbc50dc0e2f9b1649f6f1bbcf"}, +] + +[package.dependencies] +typing-extensions = ">=4.1.0" + +[[package]] +name = "types-awscrt" +version = "0.16.17" +description = "Type annotations and code completion for awscrt" +category = "dev" +optional = false +python-versions = ">=3.7,<4.0" +files = [ + {file = "types_awscrt-0.16.17-py3-none-any.whl", hash = "sha256:e28fb3f20568ce9e96e33e01e0b87b891822f36b8f368adb582553b016d4aa08"}, + {file = "types_awscrt-0.16.17.tar.gz", hash = "sha256:9e447df3ad46767887d14fa9c856df94f80e8a0a7f0169577ab23b52ee37bcdf"}, +] + +[[package]] +name = "types-pyopenssl" +version = "23.1.0.3" +description = "Typing stubs for pyOpenSSL" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-pyOpenSSL-23.1.0.3.tar.gz", hash = "sha256:e7211088eff3e20d359888dedecb0994f7181d5cce0f26354dd47ca0484dc8a6"}, + {file = "types_pyOpenSSL-23.1.0.3-py3-none-any.whl", hash = "sha256:ad024b07a1f4bffbca44699543c71efd04733a6c22781fa9673a971e410a3086"}, +] + +[package.dependencies] +cryptography = ">=35.0.0" + +[[package]] +name = "types-redis" +version = "4.5.5.1" +description = "Typing stubs for redis" +category = "dev" +optional = false +python-versions = "*" +files = [ + {file = "types-redis-4.5.5.1.tar.gz", hash = "sha256:0193d0522cccd6d46e9e17b811c30fc407e1800e0381da0e95f5c9239bdca58b"}, + {file = "types_redis-4.5.5.1-py3-none-any.whl", hash = "sha256:569b9795618c95d5f8fad2156dceb622614162761b4382892b99c519c378f776"}, +] + +[package.dependencies] +cryptography = ">=35.0.0" +types-pyOpenSSL = "*" + [[package]] name = "typing-extensions" version = "4.5.0" @@ -1476,4 +2143,4 @@ redis = ["redis"] [metadata] lock-version = "2.0" python-versions = "^3.7" -content-hash = "4325f045144b309e8378c02465b4e66544d28fc74751883f9a50ff391df08dbe" +content-hash = "3ccacd20507af6c47bf9895f36104fb39abf32b686ff00882fb131668fc9d167" diff --git a/pyproject.toml b/pyproject.toml index de4e11f..0fd4078 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,7 +22,7 @@ redis = { version = "^4.2.0rc1", optional = true } aiomcache = { version = "*", optional = true } pendulum = "*" aiobotocore = { version = "^1.4.1", optional = true } -typing-extensions = { version = ">=4.1.0", markers = "python_version < \"3.10\"" } +typing-extensions = { version = ">=4.1.0" } aiohttp = { version = ">=3.8.3", markers = "python_version >= \"3.11\"" } [tool.poetry.group.dev.dependencies] @@ -33,6 +33,10 @@ pytest = "*" requests = "*" coverage = "^6.5.0" httpx = "*" +mypy = "^1.2.0" +types-redis = "^4.5.4.2" +pyright = "^1.1.306" +types-aiobotocore = { extras = ["dynamodb"], version = "^2.5.0.post2" } [build-system] requires = ["poetry>=0.12"] @@ -47,3 +51,31 @@ all = ["redis", "aiomcache", "aiobotocore"] [tool.black] line-length = 100 target-version = ['py36', 'py37', 'py38', 'py39'] + +[tool.mypy] +files = ["fastapi_cache", "examples", "tests"] +python_version = "3.7" +# equivalent of --strict +warn_unused_configs = true +disallow_any_generics = true +disallow_subclassing_any = true +disallow_untyped_calls = true +disallow_untyped_defs = true +disallow_incomplete_defs = true +check_untyped_defs = true +disallow_untyped_decorators = true +warn_redundant_casts = true +warn_unused_ignores = true +warn_return_any = true +no_implicit_reexport = true +strict_equality = true +strict_concatenate = true + +[[tool.mypy.overrides]] +module = "examples.*.main" +ignore_errors = true + +[tool.pyright] +include = ["fastapi_cache", "tests", "examples"] +strict = ["fastapi_cache", "tests"] +pythonVersion = "3.7" diff --git a/tests/test_codecs.py b/tests/test_codecs.py index ff1dc23..1a4ea71 100644 --- a/tests/test_codecs.py +++ b/tests/test_codecs.py @@ -1,5 +1,5 @@ from dataclasses import dataclass -from typing import Any, Optional +from typing import Any, Optional, Tuple, Type import pytest from pydantic import BaseModel, ValidationError @@ -46,14 +46,14 @@ def test_pickle_coder(value: Any) -> None: [ (1, None), ("some_string", None), - ((1, 2), tuple[int, int]), + ((1, 2), Tuple[int, int]), ([1, 2, 3], None), ({"some_key": 1, "other_key": 2}, None), (DCItem(name="foo", price=42.0, description="some dataclass item", tax=0.2), DCItem), (PDItem(name="foo", price=42.0, description="some pydantic item", tax=0.2), PDItem), ], ) -def test_json_coder(value: Any, return_type) -> None: +def test_json_coder(value: Any, return_type: Type[Any]) -> None: encoded_value = JsonCoder.encode(value) assert isinstance(encoded_value, bytes) decoded_value = JsonCoder.decode_as_type(encoded_value, type_=return_type) diff --git a/tests/test_decorator.py b/tests/test_decorator.py index fc89960..5d3c472 100644 --- a/tests/test_decorator.py +++ b/tests/test_decorator.py @@ -1,5 +1,5 @@ import time -from typing import Generator +from typing import Generator, Any import pendulum import pytest @@ -11,7 +11,7 @@ from fastapi_cache.backends.inmemory import InMemoryBackend @pytest.fixture(autouse=True) -def init_cache() -> Generator: +def init_cache() -> Generator[Any, Any, None]: FastAPICache.init(InMemoryBackend()) yield FastAPICache.reset() @@ -21,34 +21,34 @@ def test_datetime() -> None: with TestClient(app) as client: response = client.get("/datetime") now = response.json().get("now") - now_ = pendulum.now().replace(microsecond=0) - assert pendulum.parse(now).replace(microsecond=0) == now_ + now_ = pendulum.now().replace(microsecond=0) # type: ignore[no-untyped-call] + assert pendulum.parse(now).replace(microsecond=0) == now_ # type: ignore[attr-defined] response = client.get("/datetime") now = response.json().get("now") - assert pendulum.parse(now).replace(microsecond=0) == now_ + assert pendulum.parse(now).replace(microsecond=0) == now_ # type: ignore[attr-defined] time.sleep(3) response = client.get("/datetime") now = response.json().get("now") - now = pendulum.parse(now).replace(microsecond=0) + now = pendulum.parse(now).replace(microsecond=0) # type: ignore[attr-defined] assert now != now_ - assert now == pendulum.now().replace(microsecond=0) + assert now == pendulum.now().replace(microsecond=0) # type: ignore[no-untyped-call] def test_date() -> None: """Test path function without request or response arguments.""" with TestClient(app) as client: response = client.get("/date") - assert pendulum.parse(response.json()) == pendulum.today() + assert pendulum.parse(response.json()) == pendulum.today() # type: ignore[attr-defined] # do it again to test cache response = client.get("/date") - assert pendulum.parse(response.json()) == pendulum.today() + assert pendulum.parse(response.json()) == pendulum.today() # type: ignore[attr-defined] # now test with cache disabled, as that's a separate code path - FastAPICache._enable = False + FastAPICache._enable = False # pyright: ignore[reportPrivateUsage] response = client.get("/date") - assert pendulum.parse(response.json()) == pendulum.today() - FastAPICache._enable = True + assert pendulum.parse(response.json()) == pendulum.today() # type: ignore[attr-defined] + FastAPICache._enable = True # pyright: ignore[reportPrivateUsage] def test_sync() -> None: