diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 11f11a7ce..f2f13ad63 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -32,7 +32,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: ["3.10", "3.11", "3.12", "3.13"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] poetry-version: ["1.8.2"] steps: diff --git a/aws_advanced_python_wrapper/__init__.py b/aws_advanced_python_wrapper/__init__.py index 459a67fab..3f66527f4 100644 --- a/aws_advanced_python_wrapper/__init__.py +++ b/aws_advanced_python_wrapper/__init__.py @@ -12,47 +12,31 @@ # See the License for the specific language governing permissions and # limitations under the License. +import sys from logging import DEBUG, getLogger -from aws_advanced_python_wrapper.pep249 import (DatabaseError, DataError, - Error, IntegrityError, - InterfaceError, InternalError, - NotSupportedError, - OperationalError, - ProgrammingError) -from .cleanup import release_resources -from .driver_info import DriverInfo -from .utils.utils import LogUtils -from .wrapper import AwsWrapperConnection - -# PEP249 compliance -connect = AwsWrapperConnection.connect -apilevel = "2.0" -threadsafety = 2 -paramstyle = "pyformat" - -# Public API -__all__ = [ - 'connect', - 'AwsWrapperConnection', - 'release_resources', - 'set_logger', - 'apilevel', - 'threadsafety', - 'paramstyle', - 'Error', - 'InterfaceError', - 'DatabaseError', - 'DataError', - 'OperationalError', - 'IntegrityError', - 'InternalError', - 'ProgrammingError', - 'NotSupportedError' -] +from aws_advanced_python_wrapper import _dbapi +from aws_advanced_python_wrapper.cleanup import release_resources +from aws_advanced_python_wrapper.driver_info import DriverInfo +from aws_advanced_python_wrapper.utils.utils import LogUtils +from aws_advanced_python_wrapper.wrapper import AwsWrapperConnection + +# Populate the full PEP 249 module surface (exceptions, type ctors/singletons, +# apilevel/threadsafety/paramstyle). `connect` stays bound to +# AwsWrapperConnection.connect for back-compat with existing callers. +_dbapi.install(sys.modules[__name__].__dict__, connect=AwsWrapperConnection.connect) __version__ = DriverInfo.DRIVER_VERSION -def set_logger(name='aws_advanced_python_wrapper', level=DEBUG, format_string=None): +def set_logger(name="aws_advanced_python_wrapper", level=DEBUG, format_string=None): LogUtils.setup_logger(getLogger(name), level, format_string) + + +__all__ = ( + "AwsWrapperConnection", + "release_resources", + "set_logger", + *_dbapi._PEP249_NAMES, + "connect", +) diff --git a/aws_advanced_python_wrapper/_dbapi.py b/aws_advanced_python_wrapper/_dbapi.py new file mode 100644 index 000000000..847d1dcb8 --- /dev/null +++ b/aws_advanced_python_wrapper/_dbapi.py @@ -0,0 +1,135 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Canonical PEP 249 module surface shared by the top-level wrapper module +and the per-driver DBAPI submodules (`aws_advanced_python_wrapper.psycopg`, +`aws_advanced_python_wrapper.mysql_connector`). + +Consumers should NOT import from this module directly. The public DBAPI +module surface lives on the top-level module and the per-driver submodules, +populated via `install()`. +""" + +from __future__ import annotations + +from datetime import date as Date # noqa: N812 +from datetime import datetime as Timestamp # noqa: N812 +from datetime import time as Time # noqa: N812 +from time import localtime +from typing import Callable, Optional + +from aws_advanced_python_wrapper.pep249 import DatabaseError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import DataError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import Error # noqa: F401 +from aws_advanced_python_wrapper.pep249 import IntegrityError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import InterfaceError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import InternalError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import NotSupportedError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import OperationalError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import ProgrammingError # noqa: F401 +from aws_advanced_python_wrapper.pep249 import Warning # noqa: F401 + +apilevel = "2.0" +threadsafety = 2 +paramstyle = "pyformat" + + +def Binary(data: bytes) -> bytes: # noqa: N802 + return bytes(data) + + +def DateFromTicks(ticks: float) -> Date: # noqa: N802 + return Date(*localtime(ticks)[:3]) + + +def TimeFromTicks(ticks: float) -> Time: # noqa: N802 + return Time(*localtime(ticks)[3:6]) + + +def TimestampFromTicks(ticks: float) -> Timestamp: # noqa: N802 + return Timestamp(*localtime(ticks)[:6]) + + +class _DBAPISet(frozenset): + """Type-object singleton per PEP 249: compares equal to any contained type code.""" + + def __eq__(self, other: object) -> bool: + if isinstance(other, (int, str)): + return other in self + return super().__eq__(other) + + def __ne__(self, other: object) -> bool: + return not self.__eq__(other) + + def __hash__(self) -> int: + return super().__hash__() + + +# Type-code sources: +# PG: psycopg.postgres.types (OIDs) +# MySQL: mysql.connector.FieldType (ints) +# Union both into each singleton. + +# PG text-like OIDs: text(25), varchar(1043), bpchar(1042), char(18), +# name(19), json(114), jsonb(3802) +# MySQL FieldType string-like: VAR_STRING(253), STRING(254), VARCHAR(15) +STRING = _DBAPISet([25, 1043, 1042, 18, 19, 114, 3802, 253, 254, 15]) + +# PG binary: bytea(17) +# MySQL FieldType BLOB family: TINY_BLOB(249), MEDIUM_BLOB(250), +# LONG_BLOB(251), BLOB(252) +BINARY = _DBAPISet([17, 249, 250, 251, 252]) + +# PG numeric: int2(21), int4(23), int8(20), float4(700), float8(701), +# numeric(1700), money(790) +# MySQL FieldType numeric: DECIMAL(0), TINY(1), SHORT(2), LONG(3), +# FLOAT(4), DOUBLE(5), LONGLONG(8), INT24(9), +# NEWDECIMAL(246) +NUMBER = _DBAPISet([21, 23, 20, 700, 701, 1700, 790, 0, 1, 2, 3, 4, 5, 8, 9, 246]) + +# PG datetime: date(1082), time(1083), timestamp(1114), timestamptz(1184), +# timetz(1266), interval(1186) +# MySQL FieldType datetime: DATE(10), TIME(11), DATETIME(12), YEAR(13), +# NEWDATE(14), TIMESTAMP(7) +DATETIME = _DBAPISet([1082, 1083, 1114, 1184, 1266, 1186, 10, 11, 12, 13, 14, 7]) + +# PG rowid: oid(26). MySQL has no ROWID equivalent; left PG-only. +ROWID = _DBAPISet([26]) + + +_PEP249_NAMES = ( + "Warning", "Error", "InterfaceError", "DatabaseError", + "DataError", "OperationalError", "IntegrityError", + "InternalError", "ProgrammingError", "NotSupportedError", + "Date", "Time", "Timestamp", + "DateFromTicks", "TimeFromTicks", "TimestampFromTicks", + "Binary", "STRING", "BINARY", "NUMBER", "DATETIME", "ROWID", + "apilevel", "threadsafety", "paramstyle", +) + + +def install(module_ns: dict, connect: Optional[Callable] = None) -> None: + """Populate `module_ns` with the PEP 249 module surface. + + If `connect` is provided, `module_ns['connect']` is set to it and 'connect' + is added to `module_ns['__all__']`. + """ + source = globals() + for name in _PEP249_NAMES: + module_ns[name] = source[name] + if connect is not None: + module_ns["connect"] = connect + module_ns["__all__"] = (*_PEP249_NAMES, "connect") + else: + module_ns["__all__"] = tuple(_PEP249_NAMES) diff --git a/aws_advanced_python_wrapper/driver_dialect.py b/aws_advanced_python_wrapper/driver_dialect.py index 47476fe77..fc800cd45 100644 --- a/aws_advanced_python_wrapper/driver_dialect.py +++ b/aws_advanced_python_wrapper/driver_dialect.py @@ -129,6 +129,7 @@ def execute( exec_func: Callable, *args: Any, exec_timeout: Optional[float] = None, + conn: Optional[Connection] = None, **kwargs: Any) -> Cursor: if DbApiMethod.ALL.method_name not in self.network_bound_methods and method_name not in self.network_bound_methods: return exec_func() @@ -138,7 +139,11 @@ def execute( if exec_timeout > 0: try: - execute_with_timeout = timeout(self._thread_pool, exec_timeout)(exec_func) + # Pass conn so that, on timeout, the abandoned operation's socket is + # shut down and its worker thread is awaited before we propagate -- + # otherwise a later close/reuse of conn races the still-running + # operation (cross-thread use-after-free in the driver, env-4 SIGSEGV). + execute_with_timeout = timeout(self._thread_pool, exec_timeout, conn)(exec_func) return execute_with_timeout() except TimeoutError as e: raise QueryTimeoutError(Messages.get_formatted("DriverDialect.ExecuteTimeout", method_name)) from e @@ -161,7 +166,7 @@ def ping(self, conn: Connection) -> bool: try: with conn.cursor() as cursor: query = DriverDialect._QUERY - self.execute(DbApiMethod.CURSOR_EXECUTE.method_name, lambda: cursor.execute(query), query, exec_timeout=10) + self.execute(DbApiMethod.CURSOR_EXECUTE.method_name, lambda: cursor.execute(query), query, exec_timeout=10, conn=conn) cursor.fetchone() return True except Exception: diff --git a/aws_advanced_python_wrapper/errors.py b/aws_advanced_python_wrapper/errors.py index 9cc6bc22b..873ed7f80 100644 --- a/aws_advanced_python_wrapper/errors.py +++ b/aws_advanced_python_wrapper/errors.py @@ -14,7 +14,7 @@ from typing import Optional -from .pep249 import Error +from .pep249 import Error, InterfaceError, NotSupportedError, OperationalError class AwsWrapperError(Error): @@ -30,15 +30,15 @@ def __init__(self, message: str = "", original_error: Optional[Exception] = None self.driver_error = original_error -class UnsupportedOperationError(AwsWrapperError): +class UnsupportedOperationError(AwsWrapperError, NotSupportedError): __module__ = "aws_advanced_python_wrapper" -class QueryTimeoutError(AwsWrapperError): +class QueryTimeoutError(AwsWrapperError, OperationalError): __module__ = "aws_advanced_python_wrapper" -class FailoverError(Error): +class FailoverError(OperationalError): __module__ = "aws_advanced_python_wrapper" @@ -51,12 +51,23 @@ class FailoverFailedError(FailoverError): class FailoverSuccessError(FailoverError): + # SA classification is handled at the dialect boundary by + # ``sqlalchemy_dialects._exception_handling._FailoverSuccessRewrapMixin``, + # which catches FailoverSuccessError in ``do_execute`` / + # ``do_executemany`` and re-raises as the dialect's native + # OperationalError. Do NOT add driver-native OperationalError classes + # (psycopg / mysql.connector) as bases here: Django's + # ``wrap_database_errors`` walks ``issubclass`` against the driver's + # own error module and would swallow FailoverSuccessError before any + # user ``except FailoverSuccessError:`` handler could see it + # (regression seen in tests/integration/container/django/ + # test_django_plugins.py::test_django_failover_during_query). __module__ = "aws_advanced_python_wrapper" -class ReadWriteSplittingError(AwsWrapperError): +class ReadWriteSplittingError(AwsWrapperError, InterfaceError): __module__ = "aws_advanced_python_wrapper" -class AwsConnectError(AwsWrapperError): +class AwsConnectError(AwsWrapperError, OperationalError): __module__ = "aws_advanced_python_wrapper" diff --git a/aws_advanced_python_wrapper/exception_handling.py b/aws_advanced_python_wrapper/exception_handling.py index 69485571b..8c7a93546 100644 --- a/aws_advanced_python_wrapper/exception_handling.py +++ b/aws_advanced_python_wrapper/exception_handling.py @@ -35,6 +35,17 @@ def is_network_exception(self, error: Optional[Exception] = None, sql_state: Opt def is_login_exception(self, error: Optional[Exception] = None, sql_state: Optional[str] = None) -> bool: """ Checks whether the given error is caused by failing to authenticate the user. + + Note for subclassers: some callers (notably ``HostMonitor`` in + ``cluster_topology_monitor`` since commit ``724de17``) treat a + ``True`` result as **bounded transient** — they retry on Aurora's + PAM-service-restart window during writer promotion before giving up. + If you override this method and intend a fast-fail "credentials are + permanently bad" signal, be aware your override may be retried up + to ~5 seconds before propagating. Callers that need fail-fast + semantics should classify those errors elsewhere (e.g. as a + dedicated non-network non-login exception). + :param error: The error raised by the target driver. :param sql_state: The SQL State associated with the error. :return: True if the error is caused by a login issue, False otherwise. diff --git a/aws_advanced_python_wrapper/mysql_connector.py b/aws_advanced_python_wrapper/mysql_connector.py new file mode 100644 index 000000000..b6fbc04f5 --- /dev/null +++ b/aws_advanced_python_wrapper/mysql_connector.py @@ -0,0 +1,66 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""PEP 249 DBAPI module bound to mysql-connector-python. + +Enables SQLAlchemy's creator-pattern: + + from sqlalchemy import create_engine + from aws_advanced_python_wrapper.mysql_connector import connect + + engine = create_engine( + "mysql+mysqlconnector://", + creator=lambda: connect( + "host=... user=... database=...", + wrapper_dialect="aurora-mysql", + ), + ) +""" + +from __future__ import annotations + +import sys +from typing import Any + +import mysql.connector as _mysql_connector +from mysql.connector import connect as _mysql_connect + +from aws_advanced_python_wrapper import _dbapi +from aws_advanced_python_wrapper.wrapper import AwsWrapperConnection + + +def __getattr__(name: str) -> Any: + """Forward missing attributes to the underlying mysql.connector module. + + See ``aws_advanced_python_wrapper/psycopg.py`` for the rationale. + """ + try: + return getattr(_mysql_connector, name) + except AttributeError: + raise AttributeError( + f"module 'aws_advanced_python_wrapper.mysql_connector' has no attribute {name!r}" + ) from None + + +def connect(conninfo: str = "", **kwargs: Any) -> AwsWrapperConnection: + """PEP 249 `connect`, target-driver-bound to mysql-connector-python. + + Equivalent to:: + + AwsWrapperConnection.connect(mysql.connector.connect, conninfo, **kwargs) + """ + return AwsWrapperConnection.connect(_mysql_connect, conninfo, **kwargs) + + +_dbapi.install(sys.modules[__name__].__dict__, connect=connect) diff --git a/aws_advanced_python_wrapper/mysql_driver_dialect.py b/aws_advanced_python_wrapper/mysql_driver_dialect.py index 132025f7a..9b65c3546 100644 --- a/aws_advanced_python_wrapper/mysql_driver_dialect.py +++ b/aws_advanced_python_wrapper/mysql_driver_dialect.py @@ -14,20 +14,18 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, ClassVar, Set +from typing import TYPE_CHECKING, Any, Callable, ClassVar, Optional, Set if TYPE_CHECKING: from aws_advanced_python_wrapper.hostinfo import HostInfo from aws_advanced_python_wrapper.pep249 import Connection -from concurrent.futures import TimeoutError from inspect import signature from aws_advanced_python_wrapper.driver_dialect import DriverDialect from aws_advanced_python_wrapper.driver_dialect_codes import DriverDialectCodes from aws_advanced_python_wrapper.errors import UnsupportedOperationError from aws_advanced_python_wrapper.pep249_methods import DbApiMethod -from aws_advanced_python_wrapper.utils.decorators import timeout from aws_advanced_python_wrapper.utils.messages import Messages from aws_advanced_python_wrapper.utils.properties import (Properties, PropertiesUtils, @@ -95,27 +93,62 @@ def is_closed(self, conn: Connection) -> bool: if self.can_execute_query(conn): socket_timeout = WrapperProperties.SOCKET_TIMEOUT_SEC.get_float(self._props) timeout_sec = socket_timeout if socket_timeout > 0 else MySQLDriverDialect.IS_CLOSED_TIMEOUT_SEC - is_connected_with_timeout = timeout( - self._thread_pool, timeout_sec)(conn.is_connected) # type: ignore - + # Run the liveness ping on the CALLING thread, never a worker + # thread. mysql.connector connections are not safe for concurrent + # use. The previous implementation offloaded conn.is_connected() + # (a COM_PING == SSL I/O) to a thread pool and, on timeout, + # abandoned the still-running ping on the pool thread while the + # caller went on to use/close the same connection -- two threads + # doing SSL read/write on one socket, a use-after-free in + # OpenSSL/libmysqlclient that crashes the process with SIGSEGV. + # Bound the ping with a temporary socket read timeout instead so + # it cannot hang, and never touch the connection from a second + # thread. + restore_timeout = MySQLDriverDialect._set_socket_timeout(conn, timeout_sec) try: - return not is_connected_with_timeout() - except TimeoutError: - return False + return not conn.is_connected() # type: ignore[attr-defined] + finally: + if restore_timeout is not None: + restore_timeout() return False raise UnsupportedOperationError(Messages.get_formatted("DriverDialect.UnsupportedOperationError", self._driver_name, "is_connected")) + @staticmethod + def _set_socket_timeout(conn: Connection, timeout_sec: float) -> Optional[Callable[[], None]]: + """Temporarily set a read timeout on the connection's underlying socket so + that a liveness ping issued on the calling thread cannot block forever. + + Returns a callable that restores the previous timeout, or None when the + socket is not reachable (e.g. the C-extension connection, whose ping is + instead bounded by its connect-time read_timeout).""" + sock = getattr(getattr(conn, "_socket", None), "sock", None) + if sock is None: + return None + try: + previous = sock.gettimeout() + sock.settimeout(timeout_sec) + except OSError: + return None + + def _restore() -> None: + try: + sock.settimeout(previous) + except OSError: + pass + + return _restore + def get_autocommit(self, conn: Connection) -> bool: if MySQLDriverDialect._is_mysql_connection(conn): - return conn.autocommit # type: ignore + return conn.autocommit # type: ignore[attr-defined] raise UnsupportedOperationError( Messages.get_formatted("DriverDialect.UnsupportedOperationError", self._driver_name, "autocommit")) def set_autocommit(self, conn: Connection, autocommit: bool): if MySQLDriverDialect._is_mysql_connection(conn): - conn.autocommit = autocommit # type: ignore + conn.autocommit = autocommit # type: ignore[attr-defined] return raise UnsupportedOperationError( @@ -134,13 +167,13 @@ def abort_connection(self, conn: Connection): def can_execute_query(self, conn: Connection) -> bool: if MySQLDriverDialect._is_mysql_connection(conn): - if conn.unread_result: # type: ignore - return conn.can_consume_results # type: ignore + if conn.unread_result: # type: ignore[attr-defined] + return conn.can_consume_results # type: ignore[attr-defined] return True def is_in_transaction(self, conn: Connection) -> bool: if MySQLDriverDialect._is_mysql_connection(conn): - return bool(conn.in_transaction) # type: ignore + return bool(conn.in_transaction) # type: ignore[attr-defined] raise UnsupportedOperationError( Messages.get_formatted("DriverDialect.UnsupportedOperationError", self._driver_name, @@ -178,7 +211,7 @@ def get_connection_from_obj(self, obj: object) -> Any: def transfer_session_state(self, from_conn: Connection, to_conn: Connection): if MySQLDriverDialect._is_mysql_connection(from_conn) and MySQLDriverDialect._is_mysql_connection(to_conn): - to_conn.autocommit = from_conn.autocommit # type: ignore + to_conn.autocommit = from_conn.autocommit # type: ignore[attr-defined] def ping(self, conn: Connection) -> bool: return not self.is_closed(conn) diff --git a/aws_advanced_python_wrapper/pg_driver_dialect.py b/aws_advanced_python_wrapper/pg_driver_dialect.py index 42366831e..269e3ff2c 100644 --- a/aws_advanced_python_wrapper/pg_driver_dialect.py +++ b/aws_advanced_python_wrapper/pg_driver_dialect.py @@ -14,6 +14,7 @@ from __future__ import annotations +import socket from typing import TYPE_CHECKING, Any, Callable, Set import psycopg @@ -28,11 +29,14 @@ from aws_advanced_python_wrapper.driver_dialect_codes import DriverDialectCodes from aws_advanced_python_wrapper.errors import UnsupportedOperationError from aws_advanced_python_wrapper.pep249_methods import DbApiMethod +from aws_advanced_python_wrapper.utils.log import Logger from aws_advanced_python_wrapper.utils.messages import Messages from aws_advanced_python_wrapper.utils.properties import (Properties, PropertiesUtils, WrapperProperties) +logger = Logger(__name__) + class PgDriverDialect(DriverDialect): _driver_name: str = "Psycopg" @@ -73,10 +77,51 @@ def is_closed(self, conn: Connection) -> bool: def abort_connection(self, conn: Connection): if isinstance(conn, psycopg.Connection): - conn.close() + # abort_connection is invoked from the host-monitoring (EFM) monitor + # thread to interrupt an in-flight operation when the host becomes + # unreachable, so the owning thread's blocked recv returns promptly. + # + # It must NOT call close(): psycopg close() is PQfinish, which frees + # the libpq connection struct and tears down the SSL session + # (SSL_free) with no lock. Freeing that struct while the owning thread + # is mid-SSL-op on the same connection races a use-after-free in + # libpq/OpenSSL and crashes the whole process with SIGSEGV. + # + # cancel()/cancel_safe() avoids the crash but cannot interrupt a query + # when the host is unreachable (the CancelRequest can't be delivered), + # which defeats the EFM's purpose on exactly the network-failure case + # it exists for. + # + # Shutting the underlying socket down is the thread-safe equivalent of + # JDBC's Connection.abort(): it unblocks the owning thread's recv + # immediately (even on a dead host) WITHOUT freeing any struct, so + # there is no SSL_free to race. The owning thread observes the broken + # connection and closes it on its own thread (the only safe place for + # PQfinish). + if conn.closed: + return + try: + fd = conn.fileno() + except Exception: + return + if fd is None or fd < 0: + return + try: + sock = socket.socket(fileno=fd) + except OSError as e: + logger.debug("PgDriverDialect.AbortConnectionShutdownFailed", e) + return + try: + sock.shutdown(socket.SHUT_RDWR) + except OSError as e: + logger.debug("PgDriverDialect.AbortConnectionShutdownFailed", e) + finally: + # release the fd WITHOUT closing it; the connection still owns it + # and will PQfinish on its owning thread. + sock.detach() return raise UnsupportedOperationError( - Messages.get_formatted("DriverDialect.UnsupportedOperationError", self._driver_name, "cancel")) + Messages.get_formatted("DriverDialect.UnsupportedOperationError", self._driver_name, "abort_connection")) def is_in_transaction(self, conn: Connection) -> bool: if isinstance(conn, psycopg.Connection): diff --git a/aws_advanced_python_wrapper/psycopg.py b/aws_advanced_python_wrapper/psycopg.py new file mode 100644 index 000000000..332b5b494 --- /dev/null +++ b/aws_advanced_python_wrapper/psycopg.py @@ -0,0 +1,72 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""PEP 249 DBAPI module bound to psycopg v3. + +Enables SQLAlchemy's creator-pattern: + + from sqlalchemy import create_engine + from aws_advanced_python_wrapper.psycopg import connect + + engine = create_engine( + "postgresql+psycopg://", + creator=lambda: connect( + "host=... user=... dbname=...", + wrapper_dialect="aurora-pg", + ), + ) +""" + +from __future__ import annotations + +import sys +from typing import Any + +import psycopg as _psycopg +from psycopg import Connection as _PGConnection + +from aws_advanced_python_wrapper import _dbapi +from aws_advanced_python_wrapper.wrapper import AwsWrapperConnection + + +def __getattr__(name: str) -> Any: + """Forward missing attributes to the underlying psycopg module. + + PEP 562 module-level __getattr__. Only fires for names NOT defined here + (including not populated by ``_dbapi.install()``), so our PEP 249 exports + (`connect`, `Error`, `Date`, `STRING`, ...) and our own definitions take + precedence. SQLAlchemy's PGDialect_psycopg probes the DBAPI module for + psycopg-specific state (``adapters``, ``__version__``, ``pq``, ...); + forwarding lets it see the real driver for those reads while keeping our + wrapper's `connect` for the connection path. + """ + try: + return getattr(_psycopg, name) + except AttributeError: + raise AttributeError( + f"module 'aws_advanced_python_wrapper.psycopg' has no attribute {name!r}" + ) from None + + +def connect(conninfo: str = "", **kwargs: Any) -> AwsWrapperConnection: + """PEP 249 `connect`, target-driver-bound to psycopg v3. + + Equivalent to:: + + AwsWrapperConnection.connect(psycopg.Connection.connect, conninfo, **kwargs) + """ + return AwsWrapperConnection.connect(_PGConnection.connect, conninfo, **kwargs) + + +_dbapi.install(sys.modules[__name__].__dict__, connect=connect) diff --git a/aws_advanced_python_wrapper/sql_alchemy_connection_provider.py b/aws_advanced_python_wrapper/sql_alchemy_connection_provider.py index 904e49411..768764d1c 100644 --- a/aws_advanced_python_wrapper/sql_alchemy_connection_provider.py +++ b/aws_advanced_python_wrapper/sql_alchemy_connection_provider.py @@ -14,14 +14,16 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Callable, ClassVar, Dict, Optional, Tuple +import time +from typing import (TYPE_CHECKING, Any, Callable, ClassVar, Dict, Optional, + Tuple) if TYPE_CHECKING: from aws_advanced_python_wrapper.database_dialect import DatabaseDialect from aws_advanced_python_wrapper.hostinfo import HostInfo, HostRole from aws_advanced_python_wrapper.driver_dialect import DriverDialect -from sqlalchemy import QueuePool, pool # type: ignore +from sqlalchemy import QueuePool, pool from aws_advanced_python_wrapper.connection_provider import ConnectionProvider from aws_advanced_python_wrapper.errors import AwsWrapperError @@ -29,6 +31,7 @@ HighestWeightHostSelector, HostSelector, RandomHostSelector, RoundRobinHostSelector, WeightedRandomHostSelector) from aws_advanced_python_wrapper.plugin import CanReleaseResources +from aws_advanced_python_wrapper.utils import transient_connect from aws_advanced_python_wrapper.utils.messages import Messages from aws_advanced_python_wrapper.utils.properties import (Properties, WrapperProperties) @@ -140,8 +143,8 @@ def connect( raise AwsWrapperError(Messages.get_formatted("SqlAlchemyPooledConnectionProvider.PoolNone", host_info.url)) queue_pool, creator_props = db_pool - - # Update the password in the creator's captured properties so new pooled connections use the latest credentials + # Refresh the password held by the pool's creator closure so subsequent new + # connections use the latest credential (e.g. a freshly minted IAM token). password = WrapperProperties.PASSWORD.get(props) if password is not None: creator_props[WrapperProperties.PASSWORD.name] = password @@ -173,8 +176,38 @@ def _create_pool( kwargs["creator"] = self._get_connection_func(target_func, prepared_properties) return self._create_sql_alchemy_pool(**kwargs), prepared_properties + # SA's pool refill goes straight through ``target_connect_func`` and + # bypasses the wrapper's plugin chain, so this layer needs its own + # transient-retry. Classification and backoff are centralised in + # ``utils.transient_connect`` so all retry sites (sync pool, Django + # backend) stay in sync. The budget itself is + # configurable via ``WrapperProperties.CONNECTION_RETRY_MAX_ATTEMPTS`` + # and ``CONNECTION_RETRY_MAX_BACKOFF_S`` — defaults match + # ``transient_connect.DEFAULT_*`` for backwards compatibility. + _TRANSIENT_CONNECT_MAX_ATTEMPTS: ClassVar[int] = transient_connect.DEFAULT_MAX_ATTEMPTS + def _get_connection_func(self, target_connect_func: Callable, props: Properties): - return lambda: target_connect_func(**props) + max_attempts = WrapperProperties.CONNECTION_RETRY_MAX_ATTEMPTS.get_int(props) + max_backoff = WrapperProperties.CONNECTION_RETRY_MAX_BACKOFF_S.get_float(props) + + def _connect_with_transient_retry() -> Any: + last_exc: Optional[BaseException] = None + for attempt in range(max_attempts): + try: + return target_connect_func(**props) + except Exception as exc: + last_exc = exc + if transient_connect.is_transient_connect_error(exc) \ + and attempt < max_attempts - 1: + time.sleep(transient_connect.compute_backoff( + attempt, max_backoff=max_backoff)) + continue + raise + # Defensive: loop exits via return or raise above; this is + # unreachable but keeps mypy from inferring an implicit None. + assert last_exc is not None + raise last_exc + return _connect_with_transient_retry def _create_sql_alchemy_pool(self, **kwargs): return pool.QueuePool(**kwargs) diff --git a/aws_advanced_python_wrapper/sqlalchemy/mysql_orm_dialect.py b/aws_advanced_python_wrapper/sqlalchemy/mysql_orm_dialect.py deleted file mode 100644 index 3d6ffaa53..000000000 --- a/aws_advanced_python_wrapper/sqlalchemy/mysql_orm_dialect.py +++ /dev/null @@ -1,198 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"). -# You may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from __future__ import annotations - -from typing import TYPE_CHECKING, Optional - -import mysql.connector -from mysql.connector import CMySQLConnection -from mysql.connector.errors import Error -from sqlalchemy.dialects.mysql.mysqlconnector import \ - MySQLDialect_mysqlconnector -from sqlalchemy.engine import default - -from aws_advanced_python_wrapper import AwsWrapperConnection -from aws_advanced_python_wrapper.errors import AwsWrapperError - -if TYPE_CHECKING: - from sqlalchemy import Connection - - -class SqlAlchemyOrmMysqlDialect(MySQLDialect_mysqlconnector): - supports_statement_cache = True - - """ - SQLAlchemy dialect for AWS Advanced Python Wrapper with mysqlconnector. Extends the SQLAlchemy MySQL mysqlconnector dialect. - This dialect is not related to the DriverDialect or DatabaseDialect classes used by our driver. Instead, it is used - directly by SQLAlchemy. This dialect is registered in pyproject.toml and is selected by prefixing the connection - string passed to create_engine with "mysql+aws_wrapper_mysqlconnector://" ("[name]+[driver]"). - """ - - name = 'mysql' - driver = 'aws_wrapper_mysqlconnector' - - @classmethod - def import_dbapi(cls): - """ - Return the DB-API 2.0 module. - SQLAlchemy calls this to get the driver module. - """ - import aws_advanced_python_wrapper - return aws_advanced_python_wrapper - - def create_connect_args(self, url): - """ - Transform SQLAlchemy URL into connection arguments. - Must include the 'target' parameter for our wrapper driver. - """ - # Extract standard connection parameters - opts = url.translate_connect_args(username='user') - - # Add query string parameters - opts.update(url.query) - - # Add the required 'target' parameter for our wrapper - if 'target' not in opts: - opts['target'] = mysql.connector.Connect - if 'wrapper_plugins' not in opts: - opts['plugins'] = "aurora_connection_tracker,failover_v2" - else: - opts['plugins'] = opts['wrapper_plugins'] - opts.pop('wrapper_plugins', None) - if 'connect_timeout' in opts: - opts['connect_timeout'] = int(opts['connect_timeout']) - - # Return empty args list and kwargs dict - return [], opts - - def do_ping(self, dbapi_connection) -> bool: - """ - Liveness check for SQLAlchemy's pool_pre_ping. - The parent pings dbapi_connection directly, but AwsWrapperConnection - has no ping(), so ping the wrapped driver connection instead. - Return False on the native error so the pool invalidates and reconnects; - SQLAlchemy cannot classify it because import_dbapi reports the wrapper as the DBAPI. - """ - try: - dbapi_connection.target_connection.ping(reconnect=False) - return True - except Error: - return False - - def _detect_charset(self, connection: Connection) -> str: - if isinstance(connection, CMySQLConnection): - return connection.charset - else: - raise Exception("Could not detect charset because connection was not a CMySQLConnection.") - - def _extract_error_code(self, exception: BaseException) -> int: - if isinstance(exception, AwsWrapperError): - err = exception.driver_error - if err and isinstance(err, Error): - return err.errno - else: - raise Exception("Could not extract error code because driver_error was not a BaseException.") - else: - raise Exception("Could not extract error code because exception was not an AwsWrapperError.") - - def initialize(self, connection): - """ - Override initialization to handle type introspection. - The parent class tries to use TypeInfo.fetch() which requires - a native SQLAlchemy connection, not AwsWrapperConnection. - """ - - # Unwrap SQLAlchemy's connection object - wrapper_conn, wrapper_parent = self._get_wrapper_connection_and_parent(connection) - - # this is driver-based, does not need server version info - # and is fairly critical for even basic SQL operations - self._connection_charset: Optional[str] = self._detect_charset( - wrapper_conn.target_connection - ) - - # call super().initialize() because we need to have - # server_version_info set up. in 1.4 under python 2 only this does the - # "check unicode returns" thing, which is the one area that some - # SQL gets compiled within initialize() currently - default.DefaultDialect.initialize(self, connection) - - self._detect_sql_mode(connection) - self._detect_ansiquotes(connection) # depends on sql mode - self._detect_casing(connection) - if self._server_ansiquotes: - # if ansiquotes == True, build a new IdentifierPreparer - # with the new setting - self.identifier_preparer = self.preparer( - self, server_ansiquotes=self._server_ansiquotes - ) - - self.supports_sequences = ( - self.is_mariadb and self.server_version_info >= (10, 3) - ) - - self.supports_for_update_of = ( - self._is_mysql and self.server_version_info >= (8,) - ) - - self.use_mysql_for_share = ( - self._is_mysql and self.server_version_info >= (8, 0, 1) - ) - - self._needs_correct_for_88718_96365 = ( - not self.is_mariadb and self.server_version_info >= (8,) - ) - - self.delete_returning = ( - self.is_mariadb and self.server_version_info >= (10, 0, 5) - ) - - self.insert_returning = ( - self.is_mariadb and self.server_version_info >= (10, 5) - ) - - self._requires_alias_for_on_duplicate_key = ( - self._is_mysql and self.server_version_info >= (8, 0, 20) - ) - - self._warn_for_known_db_issues() - - def _get_wrapper_connection_and_parent(self, connection): - """ - Traverse the connection chain to find AwsWrapperConnection and its parent connection. - - Args: - connection: SQLAlchemy Connection object - - Returns: - AwsWrapperConnection instance or None, parent connection of AwsWrapperConnection or None - """ - # Start with the DBAPI connection - parent = connection - child = connection.connection - - # Traverse up to 5 levels deep (reasonable limit) - for _ in range(5): - if isinstance(child, AwsWrapperConnection): - return child, parent - - # Try to go deeper if there's a .connection attribute - if hasattr(child, 'connection'): - parent = child - child = child.connection - else: - break - - return None diff --git a/aws_advanced_python_wrapper/sqlalchemy_dialects/__init__.py b/aws_advanced_python_wrapper/sqlalchemy_dialects/__init__.py new file mode 100644 index 000000000..fdc815f16 --- /dev/null +++ b/aws_advanced_python_wrapper/sqlalchemy_dialects/__init__.py @@ -0,0 +1,21 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Custom SQLAlchemy dialects that swap the DBAPI module to the +AWS Advanced Python Wrapper. + +Users should prefer the SA dialect registry +(``create_engine("postgresql+aws_wrapper_psycopg://...")``) over importing +these classes directly. +""" diff --git a/aws_advanced_python_wrapper/sqlalchemy_dialects/_exception_handling.py b/aws_advanced_python_wrapper/sqlalchemy_dialects/_exception_handling.py new file mode 100644 index 000000000..0dc1f32f8 --- /dev/null +++ b/aws_advanced_python_wrapper/sqlalchemy_dialects/_exception_handling.py @@ -0,0 +1,165 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Shared exception-handling helpers for the wrapper's SA dialects. + +SQLAlchemy classifies DBAPI exceptions in ``Connection._handle_dbapi_exception`` +by walking ``dialect.loaded_dbapi.`` and wrapping into +``sqlalchemy.exc.``. SA's classifier needs the raised exception +to be an instance of the **driver-native** ``OperationalError`` class +(e.g. ``psycopg.OperationalError``), not the wrapper's PEP-249 +``OperationalError``. Wrapper-internal exceptions like +``FailoverSuccessError`` are single-inherit from ``FailoverError`` (the +driver-native multi-inheritance was reverted in commit ``d994d02`` because +it caused Django's ``wrap_database_errors`` to swallow the failover signal +on MySQL), so SA's classifier lets them escape raw and any user-written +``except sqlalchemy.exc.OperationalError:`` retry loop never fires. + +The mixin below sidesteps that by intercepting ``FailoverSuccessError`` at +the ``do_execute`` / ``do_executemany`` boundary and re-raising it as the +driver-native ``OperationalError`` class — which SA's classifier DOES +reclassify reliably to ``sqlalchemy.exc.OperationalError``. The original +wrapper exception is preserved via ``__cause__`` so callers that need the +exact wrapper type can ``isinstance(exc.__cause__, FailoverSuccessError)``. + +Each concrete dialect declares its target class via +``_failover_success_target_cls``; the mixin wraps the dialect's +``do_execute`` / ``do_executemany`` calls. + +Scope: only ``do_execute`` and ``do_executemany`` are wrapped. If +``FailoverSuccessError`` ever surfaces from ``do_commit`` / ``do_rollback`` +/ ``do_begin_twophase`` / etc., it will escape raw — extend the mixin then. +""" + +from __future__ import annotations + +from typing import ClassVar, Optional, Type + +from aws_advanced_python_wrapper.errors import FailoverSuccessError + + +def _normalize_driver_error(e, driver_error_module): + """Translate a raw driver-native DBAPI error into the wrapper's PEP-249 + equivalent so SQLAlchemy's classifier recognizes it. + + SA wraps an exception into ``sqlalchemy.exc.DBAPIError`` (enabling + ``has_table`` / ``is_disconnect`` / retry handling) only when + ``isinstance(e, dialect.dbapi.Error)`` -- and ``dialect.dbapi.Error`` is the + wrapper's PEP-249 ``Error``. Plugin chains that re-wrap driver errors as + ``AwsWrapperError`` (e.g. failover) are already recognized, but auth-only + chains (``iam`` / ``aws_secrets_manager`` / no plugins) let the raw driver + error (``mysql.connector.errors.*``, ``psycopg.*``, ``pymysql.*``) escape -- + which SA cannot classify, so e.g. ``has_table`` never catches a 1146 + "table doesn't exist" and ``create_all`` fails. + + Returns an equivalent wrapper PEP-249 error (same PEP-249 subtype matched by + name; ``errno`` / ``sqlstate`` / ``pgcode`` preserved so the dialect's + ``_extract_error_code`` still reads the numeric code; original chained via + ``__cause__``), or ``None`` if ``e`` is already a wrapper error or not a + recognizable driver error (caller should re-raise the original). + """ + from aws_advanced_python_wrapper import pep249 + if isinstance(e, pep249.Error): + return None # already a wrapper PEP-249 error (incl. AwsWrapperError) + if driver_error_module is None: + return None + base = getattr(driver_error_module, "Error", None) + if base is None or not isinstance(e, base): + return None # not a driver-native DBAPI error -- leave it alone + target_cls = pep249.Error + # Most-specific PEP-249 subtype first; DatabaseError (the common parent) + # last so e.g. a ProgrammingError isn't mis-mapped to it. + for name in ("DataError", "IntegrityError", "InternalError", + "NotSupportedError", "OperationalError", "ProgrammingError", + "InterfaceError", "DatabaseError"): + drv_cls = getattr(driver_error_module, name, None) + if drv_cls is not None and isinstance(e, drv_cls): + target_cls = getattr(pep249, name, pep249.Error) + break + wrapped = target_cls(str(e)) + for attr in ("errno", "sqlstate", "pgcode"): + val = getattr(e, attr, None) + if val is not None: + try: + setattr(wrapped, attr, val) + except Exception: # noqa: BLE001 - best-effort metadata copy + pass + return wrapped + + +class _FailoverSuccessRewrapMixin: + """Re-raise ``FailoverSuccessError`` as the driver-native OperationalError. + + Concrete dialect subclasses set ``_failover_success_target_cls`` to the + driver's own ``OperationalError`` class (e.g. ``psycopg.OperationalError``, + ``mysql.connector.errors.OperationalError``). + The mixin's ``do_execute`` wraps the parent's call: on + ``FailoverSuccessError``, it raises the target class with the same message, + chaining the original via ``__cause__``. SA's classifier reliably maps + driver-native ``OperationalError`` -> ``sqlalchemy.exc.OperationalError``, + so user retry loops (``except sqlalchemy.exc.OperationalError:``) fire. + + Other ``FailoverError`` subclasses (``FailoverFailedError``, + ``TransactionResolutionUnknownError``) are NOT rewrapped: failed failover + is a hard error the user should see, and transaction-resolution-unknown + has its own semantics distinct from a generic OperationalError. + """ + + # Subclasses MUST set this to the driver-native OperationalError class. + _failover_success_target_cls: ClassVar[Optional[Type[BaseException]]] = None + + def _driver_error_module(self): + """Driver-native DBAPI exception namespace (module exposing PEP-249 + error classes: ``Error``, ``OperationalError``, ``ProgrammingError``, + ...). Concrete dialects override to enable normalizing raw driver + errors into wrapper PEP-249 errors (see :func:`_normalize_driver_error`) + so SA's classifier works on plugin chains that don't re-wrap driver + errors (iam / secrets / no-plugins). Default ``None`` => no-op. + """ + return None + + def do_execute( # type: ignore[no-untyped-def] + self, cursor, statement, parameters, context=None): + try: + super().do_execute( # type: ignore[misc] + cursor, statement, parameters, context) + except FailoverSuccessError as e: + target = self._failover_success_target_cls + if target is None: + raise # mis-configured dialect; surface the raw error + raise target(str(e)) from e + except Exception as e: + normalized = _normalize_driver_error(e, self._driver_error_module()) + if normalized is not None: + raise normalized from e + raise + + def do_executemany( # type: ignore[no-untyped-def] + self, cursor, statement, parameters, context=None): + try: + super().do_executemany( # type: ignore[misc] + cursor, statement, parameters, context) + except FailoverSuccessError as e: + target = self._failover_success_target_cls + if target is None: + raise + raise target(str(e)) from e + except Exception as e: + normalized = _normalize_driver_error(e, self._driver_error_module()) + if normalized is not None: + raise normalized from e + raise + + +__all__ = ["_FailoverSuccessRewrapMixin"] diff --git a/aws_advanced_python_wrapper/sqlalchemy_dialects/mysql.py b/aws_advanced_python_wrapper/sqlalchemy_dialects/mysql.py new file mode 100644 index 000000000..200451ccd --- /dev/null +++ b/aws_advanced_python_wrapper/sqlalchemy_dialects/mysql.py @@ -0,0 +1,150 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""MySQL SQLAlchemy dialect bound to the AWS Advanced Python Wrapper. + +Registered as ``mysql.aws_wrapper_mysqlconnector`` via a pyproject +entry-point (URL ``mysql+aws_wrapper_mysqlconnector://``). Subclasses SA's +standard MySQLDialect_mysqlconnector and only swaps the DBAPI module to +:mod:`aws_advanced_python_wrapper.mysql_connector`, which routes connect() +through the wrapper's plugin pipeline. +""" + +from __future__ import annotations + +from sqlalchemy.dialects.mysql.mysqlconnector import \ + MySQLDialect_mysqlconnector + +from aws_advanced_python_wrapper.pep249 import \ + OperationalError as _PEP249OperationalError +from aws_advanced_python_wrapper.sqlalchemy_dialects._exception_handling import \ + _FailoverSuccessRewrapMixin + + +class AwsWrapperMySQLConnectorDialect( + _FailoverSuccessRewrapMixin, MySQLDialect_mysqlconnector): + """SQLAlchemy dialect that uses the AWS Advanced Python Wrapper as its DBAPI.""" + + driver = "aws_wrapper_mysqlconnector" + supports_statement_cache = True + + # See _FailoverSuccessRewrapMixin / sqlalchemy_dialects/pg.py for the + # full rationale. The shim's ``dialect.dbapi.OperationalError`` resolves + # to the wrapper's PEP-249 ``OperationalError`` via ``_dbapi.install``, + # so the rewrap target must be that class for SA's classifier to wrap + # us to ``sqlalchemy.exc.OperationalError``. + _failover_success_target_cls = _PEP249OperationalError + + @classmethod + def import_dbapi(cls): + import aws_advanced_python_wrapper.mysql_connector as dbapi + return dbapi + + def create_connect_args(self, url): + # See aws_advanced_python_wrapper/sqlalchemy_dialects/pg.py for the + # `wrapper_plugins` → `plugins` translation rationale. + args, kwargs = super().create_connect_args(url) + wrapper_plugins = kwargs.pop("wrapper_plugins", None) + if wrapper_plugins is not None: + kwargs["plugins"] = wrapper_plugins + return args, kwargs + + def _extract_error_code(self, exception: BaseException) -> int: + # Plugins such as failover re-raise the underlying driver error + # wrapped in an ``AwsWrapperError``, which hides the numeric MySQL + # error code that SA's ``has_table`` / ``is_disconnect`` logic keys + # off. In particular ``has_table`` must see 1146 ("table doesn't + # exist") to return False so ``create_all`` can proceed -- otherwise + # the wrapped error propagates and ORM table setup fails. Unwrap to + # the underlying mysql-connector error so the stock classifier can + # read ``.errno``. Restores the override that main's + # SqlAlchemyOrmMysqlDialect carried before it was dropped in the merge. + from aws_advanced_python_wrapper.errors import AwsWrapperError + if isinstance(exception, AwsWrapperError) and exception.driver_error is not None: + exception = exception.driver_error + return super()._extract_error_code(exception) + + def _driver_error_module(self): + # mysql-connector-python's PEP-249 exception namespace; lets + # _normalize_driver_error translate a raw mysql.connector error into the + # wrapper's PEP-249 type so SA classifies it (see _exception_handling). + import mysql.connector.errors as _err + return _err + + def _detect_charset(self, connection): + # SA's MySQLDialect_mysqlconnector._detect_charset does + # ``return connection.connection.charset``. That ``.charset`` walks + # _AdhocProxiedConnection.__getattr__ → dbapi_connection, landing + # on AwsWrapperConnection which (in the sync wrapper) has no + # generic attribute passthrough. Reach the underlying mysql- + # connector connection through the wrapper's explicit + # ``target_connection`` accessor. + proxied = connection.connection + dbapi = getattr(proxied, "dbapi_connection", proxied) + inner = getattr(dbapi, "target_connection", dbapi) + return inner.charset + + def is_disconnect(self, e, connection, cursor): + # Two goals: + # 1. Prevent the upstream MySQLDialect_mysqlconnector.is_disconnect + # from probing ``e.errno`` on FailoverError subclasses (they + # don't carry the mysql-connector errno attribute, so upstream + # would crash with AttributeError before classifying). + # 2. Return the right value for each kind of failover signal: + # - FailoverSuccessError: the wrapper successfully reconnected + # to a new writer; ``AwsWrapperConnection.target_connection`` + # is auto-rebound via ``plugin_service.current_connection`` + # to the new endpoint. The pool slot IS still valid -- if + # SA invalidates it, the creator lambda re-fires with the + # original (now-demoted) instance hostname and lands on the + # old reader. Returning False keeps the same wrapper, which + # is now on the new writer. (PG passes naturally because + # psycopg's upstream is_disconnect returns False for this.) + # - FailoverFailedError: the wrapper has no working connection; + # pool slot really is dead. Return True so SA invalidates. + # _FailoverSuccessRewrapMixin still handles the do_execute path; + # this method handles the cursor-creation path which runs before + # do_execute reaches the mixin. + from aws_advanced_python_wrapper.errors import (FailoverError, + FailoverFailedError) + + # Catch the whole FailoverError family (FailoverSuccessError, + # FailoverFailedError, AND TransactionResolutionUnknownError) before the + # upstream is_disconnect probes ``e.errno`` -- none of them carry the + # mysql-connector errno attribute, so falling through raises + # ``AttributeError: 'TransactionResolutionUnknownError' object has no + # attribute 'errno'`` (seen on mid-transaction failover, env-3/env-4). + # Only FailoverFailedError means there is no usable connection -> True + # (SA invalidates the slot). FailoverSuccessError and + # TransactionResolutionUnknownError both mean the wrapper reconnected to + # a new writer and the pool slot's wrapper is valid -> False. + if isinstance(e, FailoverError): + return isinstance(e, FailoverFailedError) + return super().is_disconnect(e, connection, cursor) + + def do_ping(self, dbapi_connection) -> bool: + # Support SQLAlchemy ``pool_pre_ping``. SA's + # MySQLDialect_mysqlconnector.do_ping calls + # ``dbapi_connection.ping(False)``, but AwsWrapperConnection does NOT + # expose ``.ping()`` -- so without this override pool_pre_ping raises + # AttributeError. Reach the underlying mysql-connector connection via + # the wrapper's ``target_connection`` accessor and ping there; a driver + # error means the connection is dead -> return False so SA's pool + # recycles it. Adopts AWS PR #1245, generalized to our dialect family. + target = getattr(dbapi_connection, "target_connection", dbapi_connection) + try: + target.ping(reconnect=False) + return True + except Exception: + return False diff --git a/aws_advanced_python_wrapper/sqlalchemy_dialects/pg.py b/aws_advanced_python_wrapper/sqlalchemy_dialects/pg.py new file mode 100644 index 000000000..6403e2313 --- /dev/null +++ b/aws_advanced_python_wrapper/sqlalchemy_dialects/pg.py @@ -0,0 +1,167 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""PostgreSQL SQLAlchemy dialect bound to the AWS Advanced Python Wrapper. + +Registered as ``postgresql.aws_wrapper_psycopg`` via a pyproject entry-point +(URL ``postgresql+aws_wrapper_psycopg://``). Subclasses SA's standard +PGDialect_psycopg and only swaps the DBAPI module to +:mod:`aws_advanced_python_wrapper.psycopg`, which routes connect() through +the wrapper's plugin pipeline. +""" + +from __future__ import annotations + +from typing import Any + +from sqlalchemy.dialects.postgresql.psycopg import PGDialect_psycopg + +from aws_advanced_python_wrapper.pep249 import \ + OperationalError as _PEP249OperationalError +from aws_advanced_python_wrapper.sqlalchemy_dialects._exception_handling import \ + _FailoverSuccessRewrapMixin + + +class AwsWrapperPGPsycopgDialect(_FailoverSuccessRewrapMixin, PGDialect_psycopg): + """SQLAlchemy dialect that uses the AWS Advanced Python Wrapper as its DBAPI. + + Wrapper-specific override pattern + --------------------------------- + The wrapper interposes on DBAPI-level calls -- SA drives those + through our plugin pipeline. But SA's psycopg dialect also calls + into psycopg internals directly (``psycopg.types.TypeInfo.fetch`` + and friends), passing a ``driver_connection``. Those helpers do a + strict ``isinstance`` check against ``psycopg.Connection``; our + proxy is not a subclass, so they raise TypeError. + + Wherever SA reaches the raw driver connection, we override the + method here to unwrap to the native psycopg connection via + ``AwsWrapperConnection.target_connection`` before handing it to + psycopg. Current overrides: ``_type_info_fetch``. + """ + + driver = "aws_wrapper_psycopg" + supports_statement_cache = True + + # See _FailoverSuccessRewrapMixin. SA's classifier checks + # ``isinstance(exc, dialect.dbapi.OperationalError)``; for our shim + # ``dialect.dbapi.OperationalError`` resolves to the wrapper's PEP-249 + # ``OperationalError`` (installed via ``_dbapi.install``), NOT psycopg's + # native one. The target class must therefore be the wrapper's PEP-249 + # class so SA's classifier matches and wraps to + # ``sqlalchemy.exc.OperationalError``. (psycopg.OperationalError would + # only work if SA's dbapi attribute pointed at the real psycopg module, + # which it doesn't here because ``import_dbapi`` returns our shim.) + _failover_success_target_cls = _PEP249OperationalError + + @classmethod + def import_dbapi(cls): + import aws_advanced_python_wrapper.psycopg as dbapi + return dbapi + + def create_connect_args(self, url): + # SQLAlchemy's `create_engine` intercepts `plugins=` in the URL query + # to load SA engine plugins, stripping it before the dialect sees it. + # The wrapper's own `plugins` connection property would therefore be + # swallowed. Allow users to spell it as `wrapper_plugins=` in the URL + # and rename it to `plugins=` before handing kwargs to the DBAPI. + args, kwargs = super().create_connect_args(url) + wrapper_plugins = kwargs.pop("wrapper_plugins", None) + if wrapper_plugins is not None: + kwargs["plugins"] = wrapper_plugins + return args, kwargs + + def _driver_error_module(self): + # psycopg exposes PEP-249 error classes at top level; lets + # _normalize_driver_error translate a raw psycopg error into the + # wrapper's PEP-249 type so SA classifies it (see _exception_handling). + import psycopg + return psycopg + + def is_disconnect(self, e, connection, cursor): + # Mirror sync mysql.py for explicit, defensive symmetry. Upstream + # PGDialect_psycopg.is_disconnect happens to return False for our + # FailoverSuccessError today (it checks ``connection.closed`` / + # ``broken`` rather than probing errno), which is why PG passes + # naturally. Make that behavior explicit here so it doesn't drift + # if upstream changes: + # - FailoverSuccessError → False (pool slot's wrapper is now + # bound to the new writer via plugin_service.current_connection; + # SA should reuse it, not invalidate). + # - FailoverFailedError → True (no usable connection; invalidate). + from aws_advanced_python_wrapper.errors import (FailoverError, + FailoverFailedError) + + # Catch the whole FailoverError family -- including + # TransactionResolutionUnknownError -- before the upstream is_disconnect + # probes attributes the wrapper errors don't carry. Only + # FailoverFailedError means there's no usable connection (-> True, SA + # invalidates); FailoverSuccessError and TransactionResolutionUnknownError + # both mean the wrapper reconnected to a new writer (-> False). + if isinstance(e, FailoverError): + return isinstance(e, FailoverFailedError) + return super().is_disconnect(e, connection, cursor) + + def _type_info_fetch(self, connection: Any, name: str) -> Any: + """Unwrap to native psycopg.Connection before TypeInfo.fetch. + + SA native (``sqlalchemy/dialects/postgresql/psycopg.py:462``): + return TypeInfo.fetch(connection.connection.driver_connection, name) + + In SA's sync psycopg dialect, ``connection.connection`` is the + DBAPI-level connection and ``driver_connection`` is the native + psycopg.Connection (SA's ``AdaptedConnection`` base class + implements ``driver_connection`` as a property returning + ``self._connection``). When our wrapper is the DBAPI connection, + ``driver_connection`` returns our wrapper proxy. + + ``psycopg.TypeInfo.fetch`` rejects the proxy with + ``TypeError: expected Connection or AsyncConnection, got ...`` + (psycopg/_typeinfo.py:90). Reach the underlying native via + ``target_connection`` (exposed on our wrapper at + ``wrapper.py:84``) and pass it directly. + """ + from psycopg.types import TypeInfo + + # connection.connection may BE our wrapper (SA hands us the + # DBAPI conn directly on the sync path) or SA's adapter + # wrapping us. Support both shapes: prefer ``driver_connection`` + # when present, else fall back to the conn itself. + dbapi_conn = connection.connection + candidate = getattr(dbapi_conn, "driver_connection", dbapi_conn) + native = getattr(candidate, "target_connection", candidate) + return TypeInfo.fetch(native, name) + + def do_ping(self, dbapi_connection) -> bool: + # Support SQLAlchemy ``pool_pre_ping``. psycopg3 has no ``.ping()``; + # SA's _psycopg_common.do_ping runs ``SELECT 1`` via the DBAPI + # connection's cursor with an autocommit toggle. Run that liveness + # query against the native psycopg connection (reached via the + # wrapper's ``target_connection``) so it works regardless of which + # psycopg surface the wrapper proxies. A failure -> return False so + # SA's pool recycles the connection. Mirrors AWS PR #1245's + # pool_pre_ping support, generalized to PostgreSQL. + target = getattr(dbapi_connection, "target_connection", dbapi_connection) + try: + before_autocommit = target.autocommit + if not before_autocommit: + target.autocommit = True + try: + target.execute("SELECT 1") + finally: + if not before_autocommit and not target.closed: + target.autocommit = before_autocommit + return True + except Exception: + return False diff --git a/aws_advanced_python_wrapper/utils/decorators.py b/aws_advanced_python_wrapper/utils/decorators.py index 7f76fb984..7eb42de8a 100644 --- a/aws_advanced_python_wrapper/utils/decorators.py +++ b/aws_advanced_python_wrapper/utils/decorators.py @@ -15,7 +15,9 @@ from __future__ import annotations import functools -from typing import TYPE_CHECKING +import socket +from concurrent.futures import TimeoutError as FuturesTimeoutError +from typing import TYPE_CHECKING, Optional if TYPE_CHECKING: from concurrent.futures import Executor @@ -24,6 +26,49 @@ from aws_advanced_python_wrapper.pep249 import Connection +def _shutdown_connection_socket(conn) -> None: + """Shut down the connection's underlying socket so a query blocked on it in + another thread returns immediately, WITHOUT freeing the connection. + + These timeout decorators run a query on a worker thread and give up on it via + ``future.result(timeout=...)``. The query keeps running on the worker thread + after the timeout; if the caller then closes or reuses the connection (e.g. + the topology monitor reconnecting after a failover), the abandoned query is + left reading a connection another thread freed -- a cross-thread use-after- + free in libpq/libmysqlclient that crashes the process (env-4 SIGSEGV). + Shutting the socket down (a thread-safe syscall that frees nothing) makes the + abandoned query's recv return EOF and unwind, so we can wait for the worker + thread before letting the caller touch the connection again. + """ + # mysql.connector (pure) exposes the raw socket here. + sock = getattr(getattr(conn, "_socket", None), "sock", None) + if sock is not None and hasattr(sock, "shutdown"): + try: + sock.shutdown(socket.SHUT_RDWR) + except OSError: + pass + return + # psycopg exposes the libpq fd via fileno(). + fd = None + fileno = getattr(conn, "fileno", None) + if callable(fileno): + try: + fd = fileno() + except Exception: # noqa: BLE001 + fd = None + if fd is not None and fd >= 0: + try: + s = socket.socket(fileno=fd) + except OSError: + return + try: + s.shutdown(socket.SHUT_RDWR) + except OSError: + pass + finally: + s.detach() # release the fd without closing it; the connection owns it + + def preserve_transaction_status_with_timeout(executor: Executor, timeout_sec, driver_dialect: DriverDialect, conn: Connection): """ Timeout decorator, timeout in seconds @@ -37,8 +82,20 @@ def func_wrapper(*args, **kwargs): future = executor.submit(func, *args, **kwargs) - # raises TimeoutError on timeout - result = future.result(timeout=timeout_sec) + try: + result = future.result(timeout=timeout_sec) + except FuturesTimeoutError: + # The query is still running on the worker thread. Interrupt its + # socket so it unwinds, then WAIT for the worker to finish before + # propagating -- otherwise the caller may close/reuse this + # connection while the worker is still reading it, a cross-thread + # use-after-free in the driver (env-4 SIGSEGV). + _shutdown_connection_socket(conn) + try: + future.result(timeout=timeout_sec) + except Exception: # noqa: BLE001 - already timing out; just drain it + pass + raise if not initial_transaction_status and driver_dialect.is_in_transaction(conn): # this condition is True when autocommit is False and the query started a new transaction. @@ -51,9 +108,17 @@ def func_wrapper(*args, **kwargs): return preserve_transaction_status_with_timeout_decorator -def timeout(executor: Executor, timeout_sec): +def timeout(executor: Executor, timeout_sec, conn: Optional[Connection] = None): """ - Timeout decorator, timeout in seconds + Timeout decorator, timeout in seconds. + + ``conn`` is the connection the offloaded operation runs on. When given and the + operation times out, its socket is shut down and the worker thread is awaited + before the timeout propagates -- otherwise the operation keeps running on the + worker thread and a subsequent close/reuse of ``conn`` (e.g. a failover handler + closing the old connection while an app/EFM query is still in flight on it) + races the abandoned operation: a cross-thread use-after-free in + libpq/libmysqlclient that crashes the process (env-4 SIGSEGV). """ def timeout_decorator(func): @@ -62,8 +127,17 @@ def func_wrapper(*args, **kwargs): future = executor.submit(func, *args, **kwargs) - # raises TimeoutError on timeout - return future.result(timeout=timeout_sec) + try: + # raises TimeoutError on timeout + return future.result(timeout=timeout_sec) + except FuturesTimeoutError: + if conn is not None: + _shutdown_connection_socket(conn) + try: + future.result(timeout=timeout_sec) + except Exception: # noqa: BLE001 - already timing out; just drain it + pass + raise return func_wrapper diff --git a/aws_advanced_python_wrapper/utils/properties.py b/aws_advanced_python_wrapper/utils/properties.py index baed31022..c2b332595 100644 --- a/aws_advanced_python_wrapper/utils/properties.py +++ b/aws_advanced_python_wrapper/utils/properties.py @@ -56,21 +56,26 @@ def get(self, props: Properties, return_default: bool = True) -> Optional[str]: return props.get(self.name) def get_type(self, props: Properties, type_class: Type[T]) -> T: + # Runtime dispatch by ``type_class``: mypy can't prove that the + # concrete returned value matches the generic T, so narrow each + # branch's suppression to [return-value] rather than a bare + # ``# type: ignore`` -- that way new type errors elsewhere in + # the function still get surfaced. value = props.get(self.name, self.default_value) if self.default_value else props.get(self.name) if value is None: if type_class == int: - return -1 # type: ignore + return -1 # type: ignore[return-value] elif type_class == float: - return -1.0 # type: ignore + return -1.0 # type: ignore[return-value] elif type_class == bool: - return False # type: ignore + return False # type: ignore[return-value] else: - return None # type: ignore + return None # type: ignore[return-value] if type_class == bool: if isinstance(value, bool): - return value # type: ignore - return value.lower() == "true" if isinstance(value, str) else bool(value) # type: ignore - return type_class(value) # type: ignore + return value # type: ignore[return-value] + return value.lower() == "true" if isinstance(value, str) else bool(value) # type: ignore[return-value] + return type_class(value) # type: ignore[call-arg] def get_int(self, props: Properties) -> int: return self.get_type(props, int) @@ -598,6 +603,19 @@ class WrapperProperties: 1000, ) + RWS_RECHECK_READER_ROLE = WrapperProperty( + "rws_recheck_reader_role", + "When the Read/Write Splitting Plugin picks a reader from topology, " + "query the freshly-opened connection's actual role via " + "``get_host_role``. If the live role does not match ``HostRole.READER`` " + "(e.g., Aurora's cluster topology lagged a recent failover and the " + "picked instance is actually the writer), close the connection, " + "force a topology refresh, and try another candidate. Defaults to " + "``True`` -- disable only if you're seeing the role-recheck query " + "show up as latency in your workload.", + True, + ) + # Simple Read/Write Splitting SRW_READ_ENDPOINT = WrapperProperty( "srw_read_endpoint", @@ -636,6 +654,26 @@ class WrapperProperties: 1000, ) + # Retry budget for connections opened at sites that bypass the wrapper's + # plugin chain (SQLAlchemy pool creator, Django MySQL backend). Aurora's + # promoted writer can spend 15-60s rejecting connects during post-failover + # boot; these knobs let consumers extend or shorten the retry window + # without forking. See ``utils/transient_connect.py``. + CONNECTION_RETRY_MAX_ATTEMPTS = WrapperProperty( + "connection_retry_max_attempts", + "Maximum number of attempts when opening a connection at the SQLAlchemy " + "pool / Django backend layer (paths that bypass the plugin chain). " + "Total budget = sum of compute_backoff(0..N-1). Set to 1 to disable retry.", + 10, + ) + + CONNECTION_RETRY_MAX_BACKOFF_S = WrapperProperty( + "connection_retry_max_backoff_s", + "Per-attempt backoff cap in seconds for the same retry path. Initial " + "backoff is 1.0s with a 1.5x multiplier; this caps the geometric growth.", + 30.0, + ) + # Global Database Read/Write Splitting GDB_RW_HOME_REGION = WrapperProperty( "gdb_rw_home_region", diff --git a/aws_advanced_python_wrapper/utils/retry_util.py b/aws_advanced_python_wrapper/utils/retry_util.py index e576f51c3..04bc96390 100644 --- a/aws_advanced_python_wrapper/utils/retry_util.py +++ b/aws_advanced_python_wrapper/utils/retry_util.py @@ -109,17 +109,28 @@ def get_allowed_connection( while remaining_hosts and time.time() < retry_end_time: candidate_host = None - try: - # The host selector requires a non-null role, so default to READER when - # no specific role needs to be verified. - candidate_host = plugin_service.get_host_info_by_strategy( - verify_role if verify_role is not None else HostRole.READER, - strategy, - remaining_hosts) - except Exception: - # Strategy can't get a host according to the requested conditions. - # Do nothing - pass + # When a specific role must be verified (writer failover), ask the + # selector for exactly that role. Otherwise -- the GDB *_OR_WRITER + # modes pass verify_role=None with an allowed list that already + # includes the writer -- the selector still requires a concrete + # role, so try a reader first (read-offload preference) then fall + # back to the writer. Right after a failover the newly elected + # writer can be the only reachable host; asking only for READER + # would spin until the deadline and fail with + # UnableToConnectToReader even though the writer is a valid target. + if verify_role is not None: + candidate_roles = [verify_role] + else: + candidate_roles = [HostRole.READER, HostRole.WRITER] + for candidate_role in candidate_roles: + try: + candidate_host = plugin_service.get_host_info_by_strategy( + candidate_role, strategy, remaining_hosts) + except Exception: + # Strategy can't get a host of this role; try the next. + candidate_host = None + if candidate_host is not None: + break if candidate_host is None: logger.debug("RetryUtil.CandidateNone", verify_role) @@ -164,7 +175,7 @@ def _available_copy(host: HostInfo) -> HostInfo: def close_connection(plugin_service: PluginService, conn: Connection) -> None: try: plugin_service.driver_dialect.execute( - DbApiMethod.CONNECTION_CLOSE.method_name, lambda: conn.close()) + DbApiMethod.CONNECTION_CLOSE.method_name, lambda: conn.close(), conn=conn) except Exception: pass diff --git a/aws_advanced_python_wrapper/utils/transient_connect.py b/aws_advanced_python_wrapper/utils/transient_connect.py new file mode 100644 index 000000000..5a4c4ac01 --- /dev/null +++ b/aws_advanced_python_wrapper/utils/transient_connect.py @@ -0,0 +1,193 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Per-driver classification of transient connect errors. + +Used by code paths that open a new DBAPI connection outside the wrapper's +plugin chain (SQLAlchemy pool creators, Django backends) and need their +own retry-with-backoff because the plugin-level retry doesn't fire there. + +The per-driver split mirrors :mod:`pg_exception_handler` / +:mod:`mysql_exception_handler`. Each driver block defines: + + * the SQLSTATEs / errnos / message prefixes that classify as transient + * which SQLSTATE *class prefixes* (e.g. ``"08"``) cover entire families + of network errors + +A single :func:`is_transient_connect_error` walks the union of all of +these so retry consumers don't need to know which driver they're talking +to at the retry site. +""" + +from __future__ import annotations + +import random +from typing import FrozenSet, Tuple + +# ───── PostgreSQL (psycopg) ──────────────────────────────────────────── +# Exact SQLSTATEs that are unambiguously transient. Notably we list +# 57P01/02/03 individually rather than a "57P" prefix because 57P04 is +# ``database_dropped`` (permanent) and would be wrong to retry on. +PG_TRANSIENT_CONNECT_SQLSTATES: FrozenSet[str] = frozenset({ + "57P01", # admin_shutdown + "57P02", # crash_shutdown + "57P03", # cannot_connect_now ("the database system is starting up") + "08006", # connection_failure (SQL-standard) +}) +# Class-08 (``connection_exception``) is uniformly transient per the SQL +# standard; psycopg emits the various sub-codes (08003, 08006, 08001…) +# during Aurora rotation. +PG_TRANSIENT_CONNECT_SQLSTATE_PREFIXES: Tuple[str, ...] = ("08",) +# libpq wire-level errors carry no SQLSTATE from the server. Mirrors +# :data:`pg_exception_handler.PgExceptionHandler._NETWORK_ERROR_MESSAGES`, +# plus the client-side connect-timeout message. psycopg raises +# ``ConnectionTimeout("connection timeout expired")`` when ``connect_timeout`` +# elapses before the server answers -- which is exactly what happens while +# Aurora is promoting a new writer (the endpoint accepts the TCP connection +# but the backend hasn't finished booting, so the libpq handshake stalls). +# That is transient: the next attempt, once promotion completes, succeeds. +# It carries no SQLSTATE (the server never replied), so only the message +# prefix can classify it. +PG_TRANSIENT_CONNECT_MESSAGE_PREFIXES: Tuple[str, ...] = ( + "connection failed", + "consuming input failed", + "connection socket closed", + "the connection is closed", + "connection timeout expired", +) + +# ───── MySQL Connector (sync) ────────────────────────────────────────── +# mysql-connector-python primarily classifies connection errors by +# ``errno`` (integer). SQLSTATEs are mostly ``HY000`` (general error) +# with the actual signal in the errno. Mirrors +# :data:`mysql_exception_handler.MysqlExceptionHandler._NETWORK_ERRORS`. +MYSQL_TRANSIENT_CONNECT_ERRNOS: FrozenSet[int] = frozenset({ + 2001, # Can't create UNIX socket + 2002, # Can't connect to local MySQL server through socket + 2003, # Can't connect to MySQL server + 2004, # Can't create TCP/IP socket + 2006, # MySQL server has gone away + 2012, # Error in server handshake + 2013, # Lost connection to MySQL server during query + 2026, # SSL connection error + 2055, # Lost connection to MySQL server (read failure) +}) +# ``08`` (standard connection class) and ``HY`` (driver-level "general +# error" used by mysql-connector when it doesn't have a specific SQLSTATE) +# are both treated as network. Matches mysql_exception_handler.py:71. +MYSQL_TRANSIENT_CONNECT_SQLSTATE_PREFIXES: Tuple[str, ...] = ("08", "HY") +MYSQL_TRANSIENT_CONNECT_MESSAGE_PREFIXES: Tuple[str, ...] = ( + "MySQL Connection not available", +) + +# ───── Combined views (driver-agnostic retry consumers use these) ───── +_ALL_SQLSTATES: FrozenSet[str] = PG_TRANSIENT_CONNECT_SQLSTATES +_ALL_ERRNOS: FrozenSet[int] = MYSQL_TRANSIENT_CONNECT_ERRNOS +_ALL_SQLSTATE_PREFIXES: Tuple[str, ...] = ( + PG_TRANSIENT_CONNECT_SQLSTATE_PREFIXES + + MYSQL_TRANSIENT_CONNECT_SQLSTATE_PREFIXES +) +_ALL_MESSAGE_PREFIXES: Tuple[str, ...] = ( + PG_TRANSIENT_CONNECT_MESSAGE_PREFIXES + + MYSQL_TRANSIENT_CONNECT_MESSAGE_PREFIXES +) + +# ───── Retry budget defaults ─────────────────────────────────────────── +# Exponential backoff with cap, plus equal-jitter to spread retries +# from concurrent callers (multiple pool connections reconnecting after +# the same Aurora failover would otherwise stampede on identical +# wall-clock intervals). +# +# With these defaults the per-attempt schedule (max-jitter values) is: +# 1, 1.5, 2.25, 3.4, 5.1, 7.6, 11.4, 17.1, 25.6, 30 (cap) +# Mean total budget across all 10 attempts is ~79s; worst-case is ~105s. +# This comfortably covers Aurora's documented 30-60s post-failover +# window plus outliers (multi-region promotions, slow boots) without +# growing the cap unnecessarily. +DEFAULT_MAX_ATTEMPTS: int = 10 +DEFAULT_INITIAL_BACKOFF_S: float = 1.0 +DEFAULT_BACKOFF_MULTIPLIER: float = 1.5 +DEFAULT_MAX_BACKOFF_S: float = 30.0 + + +def compute_backoff( + attempt: int, + initial: float = DEFAULT_INITIAL_BACKOFF_S, + multiplier: float = DEFAULT_BACKOFF_MULTIPLIER, + max_backoff: float = DEFAULT_MAX_BACKOFF_S, + jitter: bool = True, +) -> float: + """Exponential backoff with cap and equal-jitter. ``attempt`` is 0-indexed. + + With defaults and jitter enabled, the per-attempt sleep falls in the + range ``[base/2, base]`` where ``base = min(initial * multiplier**attempt, + max_backoff)``:: + + attempt 0 → 0.5s … 1.0s + attempt 1 → 1.0s … 2.0s + attempt 2 → 2.0s … 4.0s + attempt 3 → 4.0s … 8.0s + attempt 4 → 8.0s … 16.0s + attempt 5 → 15.0s … 30.0s (capped at max_backoff) + + Equal-jitter (``base/2 + random.uniform(0, base/2)``) per AWS + Architecture Blog "Exponential Backoff And Jitter" — guarantees a + minimum wait equal to half of the deterministic backoff while + spreading concurrent retries over the upper half of each window. + + Pass ``jitter=False`` for tests or for callers that need deterministic + sleep durations. + """ + if attempt < 0: + attempt = 0 + base = min(initial * (multiplier ** attempt), max_backoff) + if not jitter: + return base + return base / 2 + random.uniform(0, base / 2) + + +def is_transient_connect_error(exc: BaseException) -> bool: + """Return ``True`` if ``exc`` looks like a transient connect failure + that should trigger retry-with-backoff at the call site. + + Checks in this order (cheapest first): + + 1. ``errno`` (MySQL-style numeric error code) + 2. exact-match SQLSTATE (PG-specific codes) + 3. SQLSTATE class prefix (covers both PG ``"08"`` and MySQL ``"HY"``) + 4. message-prefix matching for libpq/connector wire errors that + arrive without a SQLSTATE + + Note on psycopg: ``psycopg.Error`` exceptions sometimes carry + ``args == ()`` and place the useful info on ``.diag`` / ``.sqlstate`` / + ``.pgcode``. The SQLSTATE branch (#2/#3) handles that case — do NOT + add an ``args[0]``-only check above it, that would skip the SQLSTATE + match for psycopg and miscount the transient-error class. + """ + # 1) errno (mysql-connector) + errno = getattr(exc, "errno", None) + if isinstance(errno, int) and errno in _ALL_ERRNOS: + return True + + # 2-3) SQLSTATE (psycopg uses ``sqlstate``; some libraries set ``pgcode``) + sqlstate = getattr(exc, "sqlstate", None) or getattr(exc, "pgcode", None) + if sqlstate is not None: + if sqlstate in _ALL_SQLSTATES: + return True + if any(sqlstate.startswith(p) for p in _ALL_SQLSTATE_PREFIXES): + return True + + # 4) message-prefix match + msg = str(exc.args[0]) if exc.args else str(exc) + return any(msg.startswith(p) for p in _ALL_MESSAGE_PREFIXES) diff --git a/docs/examples/MySQLSQLAlchemyFailover.py b/docs/examples/MySQLSQLAlchemyFailover.py index 5a7a60701..a4e2327ef 100644 --- a/docs/examples/MySQLSQLAlchemyFailover.py +++ b/docs/examples/MySQLSQLAlchemyFailover.py @@ -12,211 +12,50 @@ # See the License for the specific language governing permissions and # limitations under the License. -from sqlalchemy import Column, Integer, String, create_engine -from sqlalchemy.exc import DBAPIError -from sqlalchemy.orm import DeclarativeBase, sessionmaker +"""SQLAlchemy + AWS Advanced Python Wrapper: failover on Aurora MySQL.""" -from aws_advanced_python_wrapper import release_resources -from aws_advanced_python_wrapper.errors import ( - FailoverFailedError, FailoverSuccessError, - TransactionResolutionUnknownError) - -""" -SQLAlchemy ORM Failover Example with AWS Advanced Python Wrapper - -This example demonstrates how to handle failover events when using SQLAlchemy ORM -with the AWS Advanced Python Wrapper. - -""" - - -class Base(DeclarativeBase): - pass - - -class BankAccount(Base): - """Example model for demonstrating failover handling.""" - __tablename__ = 'bank_test' - - id = Column(Integer, primary_key=True) - name = Column(String(50)) - account_balance = Column(Integer) - - def __str__(self) -> str: - return f"{self.name}: ${self.account_balance}" - - -def execute_query_with_failover_handling(query_func): - """ - Execute a SQLAlchemy ORM query with failover error handling. - - Args: - query_func: A callable that executes the desired query - - Returns: - The result of the query function - """ - try: - return query_func() - - except DBAPIError as dbapi_err: - e = dbapi_err.orig - if isinstance(e, FailoverSuccessError): - # Query execution failed and AWS Advanced Python Wrapper successfully failed over to an available instance. - # https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/using-the-python-driver/using-plugins/UsingTheFailoverPlugin.md#failoversuccesserror - - # The connection has been re-established. Retry the query. - print("Failover successful! Retrying query...") - - # Retry the query - return query_func() - - elif isinstance(e, FailoverFailedError): - # Failover failed. The application should open a new connection, - # check the results of the failed transaction and re-run it if needed. - # https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/using-the-python-driver/using-plugins/UsingTheFailoverPlugin.md#failoverfailederror - print(f"Failover failed: {e}") - print("Application should open a new connection and retry the transaction.") - raise e - - elif isinstance(e, TransactionResolutionUnknownError): - # The transaction state is unknown. The application should check the status - # of the failed transaction and restart it if needed. - # https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/using-the-python-driver/using-plugins/UsingTheFailoverPlugin.md#transactionresolutionunknownerror - print(f"Transaction resolution unknown: {e}") - print("Application should check transaction status and retry if needed.") - raise e - - -def create_table(engine): - """Create the database table with failover handling.""" - def _create(): - Base.metadata.create_all(engine) - print("Table created successfully") - - execute_query_with_failover_handling(_create) - - -def drop_table(engine): - """Drop the database table with failover handling.""" - def _drop(): - Base.metadata.drop_all(engine) - print("Table dropped successfully") - - execute_query_with_failover_handling(_drop) - - -def insert_records(session): - """Insert records with failover handling.""" - print("\n--- Inserting Records ---") - - def _insert1(): - account = BankAccount(name='Jane Doe', account_balance=200) - session.add(account) - session.commit() # Explicit commit required - print(f"Inserted: {account}") - return account - - def _insert2(): - account = BankAccount(name='John Smith', account_balance=200) - session.add(account) - session.commit() - print(f"Inserted: {account}") - return account - - execute_query_with_failover_handling(_insert1) - execute_query_with_failover_handling(_insert2) +from sqlalchemy import create_engine, text +from sqlalchemy.exc import OperationalError - -def query_records(session): - """Query records with failover handling.""" - print("\n--- Querying Records ---") - - def _query(): - accounts = session.query(BankAccount).all() - for account in accounts: - print(f" {account}") - return accounts - - return execute_query_with_failover_handling(_query) - - -def update_record(session): - """Update a record with failover handling.""" - print("\n--- Updating Record ---") - - def _update(): - account = session.query(BankAccount).filter(BankAccount.name == "Jane Doe").first() - if account: - account.account_balance = 300 - session.commit() - print(f"Updated: {account}") - return account - - return execute_query_with_failover_handling(_update) - - -def filter_records(session): - """Filter records with failover handling.""" - print("\n--- Filtering Records ---") - - def _filter(): - accounts = session.query(BankAccount).filter(BankAccount.account_balance >= 250).all() - print(f"Found {len(accounts)} accounts with balance >= $250:") - for account in accounts: - print(f" {account}") - return accounts - - return execute_query_with_failover_handling(_filter) - - -if __name__ == "__main__": +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.mysql_connector import connect + +CLUSTER_ENDPOINT = "database.cluster-xyz.us-east-1.rds.amazonaws.com" +DB_NAME = "mysql" +USER = "john" +PASSWORD = "pwd" + + +def build_engine(): + return create_engine( + "mysql+mysqlconnector://", + creator=lambda: connect( + f"host={CLUSTER_ENDPOINT} database={DB_NAME} user={USER} password={PASSWORD}", + wrapper_dialect="aurora-mysql", + plugins="failover", + use_pure=True, + ), + ) + + +def run_workload(engine, iterations: int = 20) -> None: + for i in range(iterations): + try: + with engine.connect() as conn: + row = conn.execute(text("SELECT @@aurora_server_id")).one() + print(f"iter {i}: connected to instance {row[0]}") + except OperationalError as exc: + print(f"iter {i}: operational error ({type(exc.orig).__name__}); retrying") + + +def main() -> None: + engine = build_engine() try: - print("SQLAlchemy ORM Failover Example with AWS Advanced Python Wrapper") - print("=" * 60) - - engine = create_engine( - 'mysql+aws_wrapper_mysqlconnector://admin:pwd@' - 'database.cluster-xyz.us-east-1.rds.amazonaws.com:3306/mysql?' - 'wrapper_plugins=failover_v2' - ) - - # Create table - create_table(engine) - - Session = sessionmaker(bind=engine) - with Session() as session: - # Insert records - insert_records(session) - - # Query records - query_records(session) - - # Update a record - update_record(session) - - # Query again to see the update - query_records(session) - - # Filter records - filter_records(session) - - session.close() - - # Cleanup - print("\n--- Cleanup ---") - drop_table(engine) - - print("\n" + "=" * 60) - print("Example completed successfully!") - + run_workload(engine) + finally: engine.dispose() + release_resources() - except Exception as e: - print(f"Error: {e}") - import traceback - traceback.print_exc() - finally: - # Clean up AWS Advanced Python Wrapper resources - release_resources() +if __name__ == "__main__": + main() diff --git a/docs/examples/MySQLSQLAlchemyReadWriteSplitting.py b/docs/examples/MySQLSQLAlchemyReadWriteSplitting.py new file mode 100644 index 000000000..059d2ebb7 --- /dev/null +++ b/docs/examples/MySQLSQLAlchemyReadWriteSplitting.py @@ -0,0 +1,64 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""SQLAlchemy + AWS Advanced Python Wrapper: read/write splitting on Aurora MySQL.""" + +from sqlalchemy import create_engine, text + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.mysql_connector import connect + +CLUSTER_ENDPOINT = "database.cluster-xyz.us-east-1.rds.amazonaws.com" +DB_NAME = "mysql" +USER = "john" +PASSWORD = "pwd" + + +def build_engine(): + return create_engine( + "mysql+mysqlconnector://", + creator=lambda: connect( + f"host={CLUSTER_ENDPOINT} database={DB_NAME} user={USER} password={PASSWORD}", + wrapper_dialect="aurora-mysql", + plugins="readWriteSplitting", + use_pure=True, + ), + ) + + +def instance_id(conn) -> str: + return conn.execute(text("SELECT @@aurora_server_id")).scalar_one() + + +def main() -> None: + engine = build_engine() + try: + with engine.connect() as conn: + print(f"writer: {instance_id(conn)}") + conn.commit() + + with engine.connect().execution_options(mysql_readonly=True) as conn: + print(f"reader: {instance_id(conn)}") + conn.commit() + + with engine.connect() as conn: + print(f"writer again: {instance_id(conn)}") + conn.commit() + finally: + engine.dispose() + release_resources() + + +if __name__ == "__main__": + main() diff --git a/docs/examples/PGSQLAlchemyFailover.py b/docs/examples/PGSQLAlchemyFailover.py new file mode 100644 index 000000000..21258cb83 --- /dev/null +++ b/docs/examples/PGSQLAlchemyFailover.py @@ -0,0 +1,71 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""SQLAlchemy + AWS Advanced Python Wrapper: failover on Aurora PostgreSQL. + +This example shows how to build an SQLAlchemy Engine that routes through the +AWS Advanced Python Wrapper's failover plugin, then perform a workload that +survives an Aurora failover event by catching sqlalchemy.exc.OperationalError +and retrying the unit of work. +""" + +from sqlalchemy import create_engine, text +from sqlalchemy.exc import OperationalError + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.psycopg import connect + +CLUSTER_ENDPOINT = "database.cluster-xyz.us-east-1.rds.amazonaws.com" +DB_NAME = "postgres" +USER = "john" +PASSWORD = "pwd" + + +def build_engine(): + return create_engine( + "postgresql+psycopg://", + creator=lambda: connect( + f"host={CLUSTER_ENDPOINT} dbname={DB_NAME} user={USER} password={PASSWORD}", + wrapper_dialect="aurora-pg", + plugins="failover,host_monitoring_v2", + ), + ) + + +def run_workload(engine, iterations: int = 20) -> None: + for i in range(iterations): + try: + with engine.connect() as conn: + row = conn.execute( + text("SELECT pg_catalog.aurora_db_instance_identifier()") + ).one() + print(f"iter {i}: connected to instance {row[0]}") + except OperationalError as exc: + # FailoverSuccessError is reclassified as OperationalError by the + # wrapper; SA wraps it here. The correct response is to retry the + # unit of work against the new writer. + print(f"iter {i}: operational error ({type(exc.orig).__name__}); retrying") + + +def main() -> None: + engine = build_engine() + try: + run_workload(engine) + finally: + engine.dispose() + release_resources() + + +if __name__ == "__main__": + main() diff --git a/docs/examples/PGSQLAlchemyReadWriteSplitting.py b/docs/examples/PGSQLAlchemyReadWriteSplitting.py new file mode 100644 index 000000000..ffff08368 --- /dev/null +++ b/docs/examples/PGSQLAlchemyReadWriteSplitting.py @@ -0,0 +1,72 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""SQLAlchemy + AWS Advanced Python Wrapper: read/write splitting on Aurora PostgreSQL. + +Demonstrates routing read-only transactions to Aurora replicas via the +readWriteSplitting plugin, by flipping SQLAlchemy's read_only execution option. +""" + +from sqlalchemy import create_engine, text + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.psycopg import connect + +CLUSTER_ENDPOINT = "database.cluster-xyz.us-east-1.rds.amazonaws.com" +DB_NAME = "postgres" +USER = "john" +PASSWORD = "pwd" + + +def build_engine(): + return create_engine( + "postgresql+psycopg://", + creator=lambda: connect( + f"host={CLUSTER_ENDPOINT} dbname={DB_NAME} user={USER} password={PASSWORD}", + wrapper_dialect="aurora-pg", + plugins="readWriteSplitting", + ), + ) + + +def instance_id(conn) -> str: + return conn.execute( + text("SELECT pg_catalog.aurora_db_instance_identifier()") + ).scalar_one() + + +def main() -> None: + engine = build_engine() + try: + # Writer by default. + with engine.connect() as conn: + print(f"writer: {instance_id(conn)}") + conn.commit() + + # Read-only transaction -> router switches to a reader. + with engine.connect().execution_options(postgresql_readonly=True) as conn: + print(f"reader: {instance_id(conn)}") + conn.commit() + + # Back to writer on the next non-read-only connection. + with engine.connect() as conn: + print(f"writer again: {instance_id(conn)}") + conn.commit() + finally: + engine.dispose() + release_resources() + + +if __name__ == "__main__": + main() diff --git a/docs/using-the-python-wrapper/SqlAlchemySupport.md b/docs/using-the-python-wrapper/SqlAlchemySupport.md index 2913acaa3..17ae2abdf 100644 --- a/docs/using-the-python-wrapper/SqlAlchemySupport.md +++ b/docs/using-the-python-wrapper/SqlAlchemySupport.md @@ -1,88 +1,161 @@ -# SQLAlchemy ORM Support +# SQLAlchemy Support -> [!IMPORTANT] -> SQLAlchemy ORM support is currently only available for **MySQL databases**. - -The AWS Advanced Python Wrapper provides a custom SQLAlchemy database backend that enables SQLAlchemy applications to leverage AWS and Aurora functionalities such as failover handling and IAM authentication. +The AWS Advanced Python Wrapper can be used as a PEP 249 DBAPI module with SQLAlchemy's `create_engine` via the `creator=` factory pattern, for both PostgreSQL (via psycopg v3) and MySQL (via mysql-connector-python). ## Prerequisites -- SQLAlchemy 2.0.0+ +- Python 3.10 – 3.14 (inclusive) +- SQLAlchemy 2.x +- One of: + - [psycopg v3](https://www.psycopg.org/psycopg3/) for PostgreSQL + - [mysql-connector-python](https://dev.mysql.com/doc/connector-python/en/) for MySQL + +## Using the wrapper with SQLAlchemy (PostgreSQL) -## Basic Configuration +```python +from sqlalchemy import create_engine, text + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.psycopg import connect + +engine = create_engine( + "postgresql+psycopg://", + creator=lambda: connect( + "host=database.cluster-xyz.us-east-1.rds.amazonaws.com " + "dbname=db user=john password=pwd", + wrapper_dialect="aurora-pg", + plugins="failover,host_monitoring_v2", + ), +) + +try: + with engine.connect() as conn: + row = conn.execute(text("SELECT pg_catalog.aurora_db_instance_identifier()")).one() + print(row) +finally: + engine.dispose() + release_resources() +``` -To use the AWS Advanced Python Wrapper with SQLAlchemy, call the `create_engine` function with your database URL with the configuration settings appended: +The wrapper's connection options (`wrapper_dialect`, `plugins`, etc.) are passed as kwargs to `connect`; the `postgresql+psycopg://` URL tells SQLAlchemy which SQL compiler and type system to use. + +## Using the wrapper with SQLAlchemy (MySQL) + +```python +from sqlalchemy import create_engine, text + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.mysql_connector import connect + +engine = create_engine( + "mysql+mysqlconnector://", + creator=lambda: connect( + "host=database.cluster-xyz.us-east-1.rds.amazonaws.com " + "database=db user=john password=pwd", + wrapper_dialect="aurora-mysql", + plugins="failover,host_monitoring_v2", + use_pure=True, + ), +) + +try: + with engine.connect() as conn: + row = conn.execute(text("SELECT @@aurora_server_id")).one() + print(row) +finally: + engine.dispose() + release_resources() +``` + +> **Note — `use_pure` + IAM authentication:** For Aurora MySQL, we recommend `use_pure=True` because the C extension's `is_connected` can block indefinitely on network failure. However, the [IAM Authentication Plugin](using-plugins/UsingTheIamAuthenticationPlugin.md) is incompatible with `use_pure=True` (the pure-Python driver truncates passwords at 255 chars; IAM tokens are longer). See the README's "Known Limitations" section for details. + +## Using the custom SQLAlchemy dialects (URL-based) + +The wrapper registers two SQLAlchemy dialects via entry-points so `create_engine` can be driven by URL alone — no `creator=` lambda needed. This is the idiomatic path for Alembic, 12-factor `DATABASE_URL` configs, and framework starters that expect a URL string. + +PostgreSQL: ```python from sqlalchemy import create_engine -create_engine("mysql+aws_wrapper_mysqlconnector://your_username:your_password@your-cluster-endpoint.cluster-xyz.us-east-1.rds.amazonaws.com:your_port/your_database_name?connect_timeout=10&wrapper_plugins=aurora_connection_tracker%2Cfailover_v2") +engine = create_engine( + "postgresql+aws_wrapper_psycopg://john:pwd@" + "database.cluster-xyz.us-east-1.rds.amazonaws.com:5432/db" + "?wrapper_dialect=aurora-pg&wrapper_plugins=failover,host_monitoring_v2" +) ``` -See [the SQLALchemy official documentation](https://docs.sqlalchemy.org/en/20/core/engines.html) for more information on engine configuration. +MySQL: -### Supported Engines +```python +from sqlalchemy import create_engine -| Driver | Database Dialect | -|-------------------|------------------| -| `aws_wrapper_mysqlconnector` | `mysql` | +engine = create_engine( + "mysql+aws_wrapper_mysqlconnector://john:pwd@" + "database.cluster-xyz.us-east-1.rds.amazonaws.com:3306/db" + "?wrapper_dialect=aurora-mysql&wrapper_plugins=failover&use_pure=True" +) +``` -Ensure what is passed to create_engine always starts with `"mysql+aws_wrapper_mysqlconnector:..."`. Further setting of the database dialect within the wrapper can be done with the `wrapper_dialect` parameter, for more details see: [Database Dialects](https://github.com/aws/aws-advanced-python-wrapper/blob/main/docs/using-the-python-wrapper/DatabaseDialects.md). +### Naming -## Using Plugins with SQLAlchemy +The wrapper registers as a **driver under SQLAlchemy's existing dialects**, following SA's `+` URL convention (the same shape as stock `postgresql+psycopg`, `mysql+mysqlconnector`): -The AWS Advanced Python Wrapper supports a variety of plugins that enhance your SQLAlchemy application with features like failover handling, IAM authentication, and more. Most plugins can be enabled simply by adding them to the `wrapper_plugins` parameter in your database URL. +| Engine | URL | +|--------|-----| +| PostgreSQL | `postgresql+aws_wrapper_psycopg://` | +| MySQL | `mysql+aws_wrapper_mysqlconnector://` | -> [!NOTE] -> SQLAlchemy reserves the `plugins` connection parameter for its own engine, pool, and dialect event listeners. -> When using SQLAlchemy, enable AWS Advanced Python Wrapper plugins (such as the Aurora Initial Connection Strategy plugin) via `wrapper_plugins`. Otherwise, use `plugins` as usual. +This keeps the dialect identity correct (`engine.dialect.name == "postgresql"` / `"mysql"`), so dialect-specific type compilation, reserved-word handling, and any third-party `if dialect.name == ...` checks behave as expected. -For a complete list of available plugins, see the [Plugin Compatibility](#plugin-compatibility). +### URL parameter `wrapper_plugins` (not `plugins`) +SQLAlchemy's `create_engine` reserves the query-string `plugins=` key for its own engine-plugin loader and strips it from the URL before the dialect sees it. To pass the wrapper's `plugins` connection property via URL, spell it **`wrapper_plugins=`** — the dialect translates it back to `plugins=` before calling the wrapper's `connect()`. In the creator-pattern path (where you call `connect()` directly in Python), continue to use the normal `plugins=` kwarg; the `wrapper_plugins` alias is URL-only. -### Failover Plugin +All other wrapper connection options (`wrapper_dialect`, plugin-specific parameters like `failover_timeout_sec`, auth parameters like `iam_region`, etc.) pass through the URL query string unchanged as kwargs to the underlying wrapper's `connect()`. -The Failover Plugin provides automatic failover handling for Aurora clusters. When a database instance becomes unavailable, the plugin automatically connects to a healthy instance in the cluster. +Both the creator-pattern (shown above) and the URL-based path remain supported. Use whichever fits your configuration surface. -For more information about the Failover Plugin, see the [Failover Plugin documentation](./using-plugins/UsingTheFailover2Plugin.md). +## Error handling -#### Handling Failover Events +Wrapper errors are classified so SQLAlchemy maps them to the correct `sqlalchemy.exc.*` subclass: -During a failover event, the driver will throw a `DBAPIError` exception after successfully connecting to a new instance. Your application should catch this exception, check which type of [failover error](./using-plugins/UsingTheFailoverPlugin.md#failover-errors) occurred, and retry the failed query: +| Wrapper error | SQLAlchemy error | +|---|---| +| `AwsConnectError` | `sqlalchemy.exc.OperationalError` | +| `FailoverError`, `FailoverSuccessError`, `FailoverFailedError`, `TransactionResolutionUnknownError` | `sqlalchemy.exc.OperationalError` | +| `QueryTimeoutError` | `sqlalchemy.exc.OperationalError` | +| `ReadWriteSplittingError` | `sqlalchemy.exc.InterfaceError` | +| `UnsupportedOperationError` | `sqlalchemy.exc.NotSupportedError` | +| `AwsWrapperError` (generic) | `sqlalchemy.exc.DBAPIError` | -```python -from aws_advanced_python_wrapper.errors import FailoverSuccessError - -def execute_query_with_failover_handling(query_func): - try: - return query_func() - except DBAPIError as dbapi_err: - err = dbapi_err.orig - if isinstance(err, FailoverSuccessError): - # Failover successful, retry the query - return query_func() -``` +Applications writing SA retry loops can `except sqlalchemy.exc.OperationalError` and catch failover events naturally. Target-driver exceptions (e.g., `psycopg.errors.*`, `mysql.connector.errors.*`) are not remapped and flow through SA's dialect-specific classification unchanged. + +## Resource cleanup + +Two things must be torn down at shutdown, in this order: + +1. `engine.dispose()` — drains SQLAlchemy's `QueuePool` and closes all pooled DBAPI connections. +2. `aws_advanced_python_wrapper.release_resources()` — tears down the wrapper's own background threads (topology monitor, host monitoring, internal pool cleanup). + +They are complementary: `engine.dispose()` does not reach the wrapper's background machinery, and `release_resources()` does not close SA's pool. + +## Combining with plugins + +Plugins are configured identically to non-SA usage — via the `plugins` connection property and any plugin-specific options. See: + +- [Failover Plugin](using-plugins/UsingTheFailoverPlugin.md) / [Failover v2 Plugin](using-plugins/UsingTheFailover2Plugin.md) +- [Read/Write Splitting Plugin](using-plugins/UsingTheReadWriteSplittingPlugin.md) +- [Host Monitoring Plugin (EFM)](using-plugins/UsingTheHostMonitoringPlugin.md) +- [IAM Authentication Plugin](using-plugins/UsingTheIamAuthenticationPlugin.md) +- [AWS Secrets Manager Plugin](using-plugins/UsingTheAwsSecretsManagerPlugin.md) + +## See also -For a complete example, see [MySQLSQLAlchemyFailover.py](../examples/MySQLSQLAlchemyFailover.py). - -### Plugin Compatibility - -| Plugin name | Plugin Code | Supported? | -|-------------------------------------------------------------------------------------------------|-------------------------------------------|-----| -| [Failover Plugin](./using-plugins/UsingTheFailoverPlugin.md) | `failover` | | -| [Failover Plugin v2](./using-plugins/UsingTheFailover2Plugin.md) | `failover_v2` | | -| [Host Monitoring Plugin](./using-plugins/UsingTheHostMonitoringPlugin.md) | `host_monitoring_v2` or `host_monitoring` | | -| [IAM Authentication Plugin](./using-plugins/UsingTheIamAuthenticationPlugin.md) | `iam` | | -| [AWS Secrets Manager Plugin](./using-plugins/UsingTheAwsSecretsManagerPlugin.md) | `aws_secrets_manager` | | -| [Federated Authentication Plugin](./using-plugins/UsingTheFederatedAuthenticationPlugin.md) | `federated_auth` | | -| [Okta Authentication Plugin](./using-plugins/UsingTheOktaAuthenticationPlugin.md) | `okta` | | -| [Custom Endpoint Plugin](./using-plugins/UsingTheCustomEndpointPlugin.md) | `custom_endpoint` | | -| Aurora Stale DNS Plugin | `stale_dns` | | -| [Aurora Connection Tracker Plugin](./using-plugins/UsingTheAuroraConnectionTrackerPlugin.md) | `aurora_connection_tracker` | | -| [Fastest Response Strategy Plugin](./using-plugins/UsingTheFastestResponseStrategyPlugin.md) | `fastest_response_strategy` | | -| [Blue/Green Deployment Plugin](./using-plugins/UsingTheBlueGreenPlugin.md) | `bg` | | -| [Limitless Plugin](./using-plugins/UsingTheLimitlessPlugin.md) | `limitless` | | -| [Read Write Splitting Plugin](./using-plugins/UsingTheReadWriteSplittingPlugin.md) | `read_write_splitting` | | -| [Simple Read Write Splitting Plugin](./using-plugins/UsingTheSimpleReadWriteSplittingPlugin.md) | `srw` | | - -For Read Write Splitting, SQLAlchemy provides session binding. See the [official SQLAlchemy documentation on the Session API](https://docs.sqlalchemy.org/en/20/orm/session_api.html) for more information on session binds. +- [Django Support](DjangoSupport.md) +- [Using the AWS Python Wrapper](UsingThePythonWrapper.md) +- Example scripts: + - [`PGSQLAlchemyFailover.py`](../examples/PGSQLAlchemyFailover.py) + - [`MySQLSQLAlchemyFailover.py`](../examples/MySQLSQLAlchemyFailover.py) + - [`PGSQLAlchemyReadWriteSplitting.py`](../examples/PGSQLAlchemyReadWriteSplitting.py) + - [`MySQLSQLAlchemyReadWriteSplitting.py`](../examples/MySQLSQLAlchemyReadWriteSplitting.py) diff --git a/mypy.ini b/mypy.ini index a756a6a07..9167741ce 100644 --- a/mypy.ini +++ b/mypy.ini @@ -11,11 +11,18 @@ exclude = (?x)( | PGInternalConnectionPoolPasswordWarning\.py | PGReadWriteSplitting\.py | PGSecretsManager\.py + | PGSQLAlchemyFailover\.py + | MySQLSQLAlchemyFailover\.py + | PGSQLAlchemyReadWriteSplitting\.py + | MySQLSQLAlchemyReadWriteSplitting\.py ) [mypy-mysql] ignore_missing_imports = True +[mypy-pymysql] +ignore_missing_imports = True + [mypy-parameterized] ignore_missing_imports = True diff --git a/poetry.lock b/poetry.lock index 6cb9e8576..0b3baaa0d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.3.3 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.4.1 and should not be changed by hand. [[package]] name = "asgiref" @@ -58,34 +58,34 @@ lxml = ["lxml"] [[package]] name = "boto3" -version = "1.42.74" +version = "1.43.32" description = "The AWS SDK for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "boto3-1.42.74-py3-none-any.whl", hash = "sha256:4bf89c044d618fe4435af854ab820f09dd43569c0df15d7beb0398f50b9aa970"}, - {file = "boto3-1.42.74.tar.gz", hash = "sha256:dbacd808cf2a3dadbf35f3dbd8de97b94dc9f78b1ebd439f38f552e0f9753577"}, + {file = "boto3-1.43.32-py3-none-any.whl", hash = "sha256:a3d7d7a9489c18cc9c806aca9be689677779d17ddbf919fe300146576c1bdee2"}, + {file = "boto3-1.43.32.tar.gz", hash = "sha256:15544d42af8aa8f775ea636f77c9c97fbc90ff28c0e5a0d1d47c8acd9f5b1982"}, ] [package.dependencies] -botocore = ">=1.42.74,<1.43.0" +botocore = ">=1.43.32,<1.44.0" jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.16.0,<0.17.0" +s3transfer = ">=0.19.0,<0.20.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "boto3-stubs" -version = "1.42.74" -description = "Type annotations for boto3 1.42.74 generated with mypy-boto3-builder 8.12.0" +version = "1.43.32" +description = "Type annotations for boto3 1.43.32 generated with mypy-boto3-builder 8.12.0" optional = false python-versions = ">=3.9" groups = ["main"] files = [ - {file = "boto3_stubs-1.42.74-py3-none-any.whl", hash = "sha256:63b7ba180b3fe361dcae0a50dd57e1ac676149cf0c90be420fa067189bafa7c6"}, - {file = "boto3_stubs-1.42.74.tar.gz", hash = "sha256:781078235e61c78000035ece0a92befaaf846762b6a91becf6b2887331fd010d"}, + {file = "boto3_stubs-1.43.32-py3-none-any.whl", hash = "sha256:7d4528dba959c9e2158904c857c0aeb54b0dcdfd95d2fc54a8e97b916cfe04a8"}, + {file = "boto3_stubs-1.43.32.tar.gz", hash = "sha256:d63a679b19c124226988b1dba269cb58280175ac7435673212c10904fcffaee8"}, ] [package.dependencies] @@ -94,446 +94,455 @@ types-s3transfer = "*" typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [package.extras] -accessanalyzer = ["mypy-boto3-accessanalyzer (>=1.42.0,<1.43.0)"] -account = ["mypy-boto3-account (>=1.42.0,<1.43.0)"] -acm = ["mypy-boto3-acm (>=1.42.0,<1.43.0)"] -acm-pca = ["mypy-boto3-acm-pca (>=1.42.0,<1.43.0)"] -aiops = ["mypy-boto3-aiops (>=1.42.0,<1.43.0)"] -all = ["mypy-boto3-accessanalyzer (>=1.42.0,<1.43.0)", "mypy-boto3-account (>=1.42.0,<1.43.0)", "mypy-boto3-acm (>=1.42.0,<1.43.0)", "mypy-boto3-acm-pca (>=1.42.0,<1.43.0)", "mypy-boto3-aiops (>=1.42.0,<1.43.0)", "mypy-boto3-amp (>=1.42.0,<1.43.0)", "mypy-boto3-amplify (>=1.42.0,<1.43.0)", "mypy-boto3-amplifybackend (>=1.42.0,<1.43.0)", "mypy-boto3-amplifyuibuilder (>=1.42.0,<1.43.0)", "mypy-boto3-apigateway (>=1.42.0,<1.43.0)", "mypy-boto3-apigatewaymanagementapi (>=1.42.0,<1.43.0)", "mypy-boto3-apigatewayv2 (>=1.42.0,<1.43.0)", "mypy-boto3-appconfig (>=1.42.0,<1.43.0)", "mypy-boto3-appconfigdata (>=1.42.0,<1.43.0)", "mypy-boto3-appfabric (>=1.42.0,<1.43.0)", "mypy-boto3-appflow (>=1.42.0,<1.43.0)", "mypy-boto3-appintegrations (>=1.42.0,<1.43.0)", "mypy-boto3-application-autoscaling (>=1.42.0,<1.43.0)", "mypy-boto3-application-insights (>=1.42.0,<1.43.0)", "mypy-boto3-application-signals (>=1.42.0,<1.43.0)", "mypy-boto3-applicationcostprofiler (>=1.42.0,<1.43.0)", "mypy-boto3-appmesh (>=1.42.0,<1.43.0)", "mypy-boto3-apprunner (>=1.42.0,<1.43.0)", "mypy-boto3-appstream (>=1.42.0,<1.43.0)", "mypy-boto3-appsync (>=1.42.0,<1.43.0)", "mypy-boto3-arc-region-switch (>=1.42.0,<1.43.0)", "mypy-boto3-arc-zonal-shift (>=1.42.0,<1.43.0)", "mypy-boto3-artifact (>=1.42.0,<1.43.0)", "mypy-boto3-athena (>=1.42.0,<1.43.0)", "mypy-boto3-auditmanager (>=1.42.0,<1.43.0)", "mypy-boto3-autoscaling (>=1.42.0,<1.43.0)", "mypy-boto3-autoscaling-plans (>=1.42.0,<1.43.0)", "mypy-boto3-b2bi (>=1.42.0,<1.43.0)", "mypy-boto3-backup (>=1.42.0,<1.43.0)", "mypy-boto3-backup-gateway (>=1.42.0,<1.43.0)", "mypy-boto3-backupsearch (>=1.42.0,<1.43.0)", "mypy-boto3-batch (>=1.42.0,<1.43.0)", "mypy-boto3-bcm-dashboards (>=1.42.0,<1.43.0)", "mypy-boto3-bcm-data-exports (>=1.42.0,<1.43.0)", "mypy-boto3-bcm-pricing-calculator (>=1.42.0,<1.43.0)", "mypy-boto3-bcm-recommended-actions (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-agent (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-agent-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-agentcore (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-agentcore-control (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-data-automation (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-data-automation-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-bedrock-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-billing (>=1.42.0,<1.43.0)", "mypy-boto3-billingconductor (>=1.42.0,<1.43.0)", "mypy-boto3-braket (>=1.42.0,<1.43.0)", "mypy-boto3-budgets (>=1.42.0,<1.43.0)", "mypy-boto3-ce (>=1.42.0,<1.43.0)", "mypy-boto3-chatbot (>=1.42.0,<1.43.0)", "mypy-boto3-chime (>=1.42.0,<1.43.0)", "mypy-boto3-chime-sdk-identity (>=1.42.0,<1.43.0)", "mypy-boto3-chime-sdk-media-pipelines (>=1.42.0,<1.43.0)", "mypy-boto3-chime-sdk-meetings (>=1.42.0,<1.43.0)", "mypy-boto3-chime-sdk-messaging (>=1.42.0,<1.43.0)", "mypy-boto3-chime-sdk-voice (>=1.42.0,<1.43.0)", "mypy-boto3-cleanrooms (>=1.42.0,<1.43.0)", "mypy-boto3-cleanroomsml (>=1.42.0,<1.43.0)", "mypy-boto3-cloud9 (>=1.42.0,<1.43.0)", "mypy-boto3-cloudcontrol (>=1.42.0,<1.43.0)", "mypy-boto3-clouddirectory (>=1.42.0,<1.43.0)", "mypy-boto3-cloudformation (>=1.42.0,<1.43.0)", "mypy-boto3-cloudfront (>=1.42.0,<1.43.0)", "mypy-boto3-cloudfront-keyvaluestore (>=1.42.0,<1.43.0)", "mypy-boto3-cloudhsm (>=1.42.0,<1.43.0)", "mypy-boto3-cloudhsmv2 (>=1.42.0,<1.43.0)", "mypy-boto3-cloudsearch (>=1.42.0,<1.43.0)", "mypy-boto3-cloudsearchdomain (>=1.42.0,<1.43.0)", "mypy-boto3-cloudtrail (>=1.42.0,<1.43.0)", "mypy-boto3-cloudtrail-data (>=1.42.0,<1.43.0)", "mypy-boto3-cloudwatch (>=1.42.0,<1.43.0)", "mypy-boto3-codeartifact (>=1.42.0,<1.43.0)", "mypy-boto3-codebuild (>=1.42.0,<1.43.0)", "mypy-boto3-codecatalyst (>=1.42.0,<1.43.0)", "mypy-boto3-codecommit (>=1.42.0,<1.43.0)", "mypy-boto3-codeconnections (>=1.42.0,<1.43.0)", "mypy-boto3-codedeploy (>=1.42.0,<1.43.0)", "mypy-boto3-codeguru-reviewer (>=1.42.0,<1.43.0)", "mypy-boto3-codeguru-security (>=1.42.0,<1.43.0)", "mypy-boto3-codeguruprofiler (>=1.42.0,<1.43.0)", "mypy-boto3-codepipeline (>=1.42.0,<1.43.0)", "mypy-boto3-codestar-connections (>=1.42.0,<1.43.0)", "mypy-boto3-codestar-notifications (>=1.42.0,<1.43.0)", "mypy-boto3-cognito-identity (>=1.42.0,<1.43.0)", "mypy-boto3-cognito-idp (>=1.42.0,<1.43.0)", "mypy-boto3-cognito-sync (>=1.42.0,<1.43.0)", "mypy-boto3-comprehend (>=1.42.0,<1.43.0)", "mypy-boto3-comprehendmedical (>=1.42.0,<1.43.0)", "mypy-boto3-compute-optimizer (>=1.42.0,<1.43.0)", "mypy-boto3-compute-optimizer-automation (>=1.42.0,<1.43.0)", "mypy-boto3-config (>=1.42.0,<1.43.0)", "mypy-boto3-connect (>=1.42.0,<1.43.0)", "mypy-boto3-connect-contact-lens (>=1.42.0,<1.43.0)", "mypy-boto3-connectcampaigns (>=1.42.0,<1.43.0)", "mypy-boto3-connectcampaignsv2 (>=1.42.0,<1.43.0)", "mypy-boto3-connectcases (>=1.42.0,<1.43.0)", "mypy-boto3-connecthealth (>=1.42.0,<1.43.0)", "mypy-boto3-connectparticipant (>=1.42.0,<1.43.0)", "mypy-boto3-controlcatalog (>=1.42.0,<1.43.0)", "mypy-boto3-controltower (>=1.42.0,<1.43.0)", "mypy-boto3-cost-optimization-hub (>=1.42.0,<1.43.0)", "mypy-boto3-cur (>=1.42.0,<1.43.0)", "mypy-boto3-customer-profiles (>=1.42.0,<1.43.0)", "mypy-boto3-databrew (>=1.42.0,<1.43.0)", "mypy-boto3-dataexchange (>=1.42.0,<1.43.0)", "mypy-boto3-datapipeline (>=1.42.0,<1.43.0)", "mypy-boto3-datasync (>=1.42.0,<1.43.0)", "mypy-boto3-datazone (>=1.42.0,<1.43.0)", "mypy-boto3-dax (>=1.42.0,<1.43.0)", "mypy-boto3-deadline (>=1.42.0,<1.43.0)", "mypy-boto3-detective (>=1.42.0,<1.43.0)", "mypy-boto3-devicefarm (>=1.42.0,<1.43.0)", "mypy-boto3-devops-guru (>=1.42.0,<1.43.0)", "mypy-boto3-directconnect (>=1.42.0,<1.43.0)", "mypy-boto3-discovery (>=1.42.0,<1.43.0)", "mypy-boto3-dlm (>=1.42.0,<1.43.0)", "mypy-boto3-dms (>=1.42.0,<1.43.0)", "mypy-boto3-docdb (>=1.42.0,<1.43.0)", "mypy-boto3-docdb-elastic (>=1.42.0,<1.43.0)", "mypy-boto3-drs (>=1.42.0,<1.43.0)", "mypy-boto3-ds (>=1.42.0,<1.43.0)", "mypy-boto3-ds-data (>=1.42.0,<1.43.0)", "mypy-boto3-dsql (>=1.42.0,<1.43.0)", "mypy-boto3-dynamodb (>=1.42.0,<1.43.0)", "mypy-boto3-dynamodbstreams (>=1.42.0,<1.43.0)", "mypy-boto3-ebs (>=1.42.0,<1.43.0)", "mypy-boto3-ec2 (>=1.42.0,<1.43.0)", "mypy-boto3-ec2-instance-connect (>=1.42.0,<1.43.0)", "mypy-boto3-ecr (>=1.42.0,<1.43.0)", "mypy-boto3-ecr-public (>=1.42.0,<1.43.0)", "mypy-boto3-ecs (>=1.42.0,<1.43.0)", "mypy-boto3-efs (>=1.42.0,<1.43.0)", "mypy-boto3-eks (>=1.42.0,<1.43.0)", "mypy-boto3-eks-auth (>=1.42.0,<1.43.0)", "mypy-boto3-elasticache (>=1.42.0,<1.43.0)", "mypy-boto3-elasticbeanstalk (>=1.42.0,<1.43.0)", "mypy-boto3-elb (>=1.42.0,<1.43.0)", "mypy-boto3-elbv2 (>=1.42.0,<1.43.0)", "mypy-boto3-elementalinference (>=1.42.0,<1.43.0)", "mypy-boto3-emr (>=1.42.0,<1.43.0)", "mypy-boto3-emr-containers (>=1.42.0,<1.43.0)", "mypy-boto3-emr-serverless (>=1.42.0,<1.43.0)", "mypy-boto3-entityresolution (>=1.42.0,<1.43.0)", "mypy-boto3-es (>=1.42.0,<1.43.0)", "mypy-boto3-events (>=1.42.0,<1.43.0)", "mypy-boto3-evs (>=1.42.0,<1.43.0)", "mypy-boto3-finspace (>=1.42.0,<1.43.0)", "mypy-boto3-finspace-data (>=1.42.0,<1.43.0)", "mypy-boto3-firehose (>=1.42.0,<1.43.0)", "mypy-boto3-fis (>=1.42.0,<1.43.0)", "mypy-boto3-fms (>=1.42.0,<1.43.0)", "mypy-boto3-forecast (>=1.42.0,<1.43.0)", "mypy-boto3-forecastquery (>=1.42.0,<1.43.0)", "mypy-boto3-frauddetector (>=1.42.0,<1.43.0)", "mypy-boto3-freetier (>=1.42.0,<1.43.0)", "mypy-boto3-fsx (>=1.42.0,<1.43.0)", "mypy-boto3-gamelift (>=1.42.0,<1.43.0)", "mypy-boto3-gameliftstreams (>=1.42.0,<1.43.0)", "mypy-boto3-geo-maps (>=1.42.0,<1.43.0)", "mypy-boto3-geo-places (>=1.42.0,<1.43.0)", "mypy-boto3-geo-routes (>=1.42.0,<1.43.0)", "mypy-boto3-glacier (>=1.42.0,<1.43.0)", "mypy-boto3-globalaccelerator (>=1.42.0,<1.43.0)", "mypy-boto3-glue (>=1.42.0,<1.43.0)", "mypy-boto3-grafana (>=1.42.0,<1.43.0)", "mypy-boto3-greengrass (>=1.42.0,<1.43.0)", "mypy-boto3-greengrassv2 (>=1.42.0,<1.43.0)", "mypy-boto3-groundstation (>=1.42.0,<1.43.0)", "mypy-boto3-guardduty (>=1.42.0,<1.43.0)", "mypy-boto3-health (>=1.42.0,<1.43.0)", "mypy-boto3-healthlake (>=1.42.0,<1.43.0)", "mypy-boto3-iam (>=1.42.0,<1.43.0)", "mypy-boto3-identitystore (>=1.42.0,<1.43.0)", "mypy-boto3-imagebuilder (>=1.42.0,<1.43.0)", "mypy-boto3-importexport (>=1.42.0,<1.43.0)", "mypy-boto3-inspector (>=1.42.0,<1.43.0)", "mypy-boto3-inspector-scan (>=1.42.0,<1.43.0)", "mypy-boto3-inspector2 (>=1.42.0,<1.43.0)", "mypy-boto3-internetmonitor (>=1.42.0,<1.43.0)", "mypy-boto3-invoicing (>=1.42.0,<1.43.0)", "mypy-boto3-iot (>=1.42.0,<1.43.0)", "mypy-boto3-iot-data (>=1.42.0,<1.43.0)", "mypy-boto3-iot-jobs-data (>=1.42.0,<1.43.0)", "mypy-boto3-iot-managed-integrations (>=1.42.0,<1.43.0)", "mypy-boto3-iotdeviceadvisor (>=1.42.0,<1.43.0)", "mypy-boto3-iotevents (>=1.42.0,<1.43.0)", "mypy-boto3-iotevents-data (>=1.42.0,<1.43.0)", "mypy-boto3-iotfleetwise (>=1.42.0,<1.43.0)", "mypy-boto3-iotsecuretunneling (>=1.42.0,<1.43.0)", "mypy-boto3-iotsitewise (>=1.42.0,<1.43.0)", "mypy-boto3-iotthingsgraph (>=1.42.0,<1.43.0)", "mypy-boto3-iottwinmaker (>=1.42.0,<1.43.0)", "mypy-boto3-iotwireless (>=1.42.0,<1.43.0)", "mypy-boto3-ivs (>=1.42.0,<1.43.0)", "mypy-boto3-ivs-realtime (>=1.42.0,<1.43.0)", "mypy-boto3-ivschat (>=1.42.0,<1.43.0)", "mypy-boto3-kafka (>=1.42.0,<1.43.0)", "mypy-boto3-kafkaconnect (>=1.42.0,<1.43.0)", "mypy-boto3-kendra (>=1.42.0,<1.43.0)", "mypy-boto3-kendra-ranking (>=1.42.0,<1.43.0)", "mypy-boto3-keyspaces (>=1.42.0,<1.43.0)", "mypy-boto3-keyspacesstreams (>=1.42.0,<1.43.0)", "mypy-boto3-kinesis (>=1.42.0,<1.43.0)", "mypy-boto3-kinesis-video-archived-media (>=1.42.0,<1.43.0)", "mypy-boto3-kinesis-video-media (>=1.42.0,<1.43.0)", "mypy-boto3-kinesis-video-signaling (>=1.42.0,<1.43.0)", "mypy-boto3-kinesis-video-webrtc-storage (>=1.42.0,<1.43.0)", "mypy-boto3-kinesisanalytics (>=1.42.0,<1.43.0)", "mypy-boto3-kinesisanalyticsv2 (>=1.42.0,<1.43.0)", "mypy-boto3-kinesisvideo (>=1.42.0,<1.43.0)", "mypy-boto3-kms (>=1.42.0,<1.43.0)", "mypy-boto3-lakeformation (>=1.42.0,<1.43.0)", "mypy-boto3-lambda (>=1.42.0,<1.43.0)", "mypy-boto3-launch-wizard (>=1.42.0,<1.43.0)", "mypy-boto3-lex-models (>=1.42.0,<1.43.0)", "mypy-boto3-lex-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-lexv2-models (>=1.42.0,<1.43.0)", "mypy-boto3-lexv2-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-license-manager (>=1.42.0,<1.43.0)", "mypy-boto3-license-manager-linux-subscriptions (>=1.42.0,<1.43.0)", "mypy-boto3-license-manager-user-subscriptions (>=1.42.0,<1.43.0)", "mypy-boto3-lightsail (>=1.42.0,<1.43.0)", "mypy-boto3-location (>=1.42.0,<1.43.0)", "mypy-boto3-logs (>=1.42.0,<1.43.0)", "mypy-boto3-lookoutequipment (>=1.42.0,<1.43.0)", "mypy-boto3-m2 (>=1.42.0,<1.43.0)", "mypy-boto3-machinelearning (>=1.42.0,<1.43.0)", "mypy-boto3-macie2 (>=1.42.0,<1.43.0)", "mypy-boto3-mailmanager (>=1.42.0,<1.43.0)", "mypy-boto3-managedblockchain (>=1.42.0,<1.43.0)", "mypy-boto3-managedblockchain-query (>=1.42.0,<1.43.0)", "mypy-boto3-marketplace-agreement (>=1.42.0,<1.43.0)", "mypy-boto3-marketplace-catalog (>=1.42.0,<1.43.0)", "mypy-boto3-marketplace-deployment (>=1.42.0,<1.43.0)", "mypy-boto3-marketplace-entitlement (>=1.42.0,<1.43.0)", "mypy-boto3-marketplace-reporting (>=1.42.0,<1.43.0)", "mypy-boto3-marketplacecommerceanalytics (>=1.42.0,<1.43.0)", "mypy-boto3-mediaconnect (>=1.42.0,<1.43.0)", "mypy-boto3-mediaconvert (>=1.42.0,<1.43.0)", "mypy-boto3-medialive (>=1.42.0,<1.43.0)", "mypy-boto3-mediapackage (>=1.42.0,<1.43.0)", "mypy-boto3-mediapackage-vod (>=1.42.0,<1.43.0)", "mypy-boto3-mediapackagev2 (>=1.42.0,<1.43.0)", "mypy-boto3-mediastore (>=1.42.0,<1.43.0)", "mypy-boto3-mediastore-data (>=1.42.0,<1.43.0)", "mypy-boto3-mediatailor (>=1.42.0,<1.43.0)", "mypy-boto3-medical-imaging (>=1.42.0,<1.43.0)", "mypy-boto3-memorydb (>=1.42.0,<1.43.0)", "mypy-boto3-meteringmarketplace (>=1.42.0,<1.43.0)", "mypy-boto3-mgh (>=1.42.0,<1.43.0)", "mypy-boto3-mgn (>=1.42.0,<1.43.0)", "mypy-boto3-migration-hub-refactor-spaces (>=1.42.0,<1.43.0)", "mypy-boto3-migrationhub-config (>=1.42.0,<1.43.0)", "mypy-boto3-migrationhuborchestrator (>=1.42.0,<1.43.0)", "mypy-boto3-migrationhubstrategy (>=1.42.0,<1.43.0)", "mypy-boto3-mpa (>=1.42.0,<1.43.0)", "mypy-boto3-mq (>=1.42.0,<1.43.0)", "mypy-boto3-mturk (>=1.42.0,<1.43.0)", "mypy-boto3-mwaa (>=1.42.0,<1.43.0)", "mypy-boto3-mwaa-serverless (>=1.42.0,<1.43.0)", "mypy-boto3-neptune (>=1.42.0,<1.43.0)", "mypy-boto3-neptune-graph (>=1.42.0,<1.43.0)", "mypy-boto3-neptunedata (>=1.42.0,<1.43.0)", "mypy-boto3-network-firewall (>=1.42.0,<1.43.0)", "mypy-boto3-networkflowmonitor (>=1.42.0,<1.43.0)", "mypy-boto3-networkmanager (>=1.42.0,<1.43.0)", "mypy-boto3-networkmonitor (>=1.42.0,<1.43.0)", "mypy-boto3-notifications (>=1.42.0,<1.43.0)", "mypy-boto3-notificationscontacts (>=1.42.0,<1.43.0)", "mypy-boto3-nova-act (>=1.42.0,<1.43.0)", "mypy-boto3-oam (>=1.42.0,<1.43.0)", "mypy-boto3-observabilityadmin (>=1.42.0,<1.43.0)", "mypy-boto3-odb (>=1.42.0,<1.43.0)", "mypy-boto3-omics (>=1.42.0,<1.43.0)", "mypy-boto3-opensearch (>=1.42.0,<1.43.0)", "mypy-boto3-opensearchserverless (>=1.42.0,<1.43.0)", "mypy-boto3-organizations (>=1.42.0,<1.43.0)", "mypy-boto3-osis (>=1.42.0,<1.43.0)", "mypy-boto3-outposts (>=1.42.0,<1.43.0)", "mypy-boto3-panorama (>=1.42.0,<1.43.0)", "mypy-boto3-partnercentral-account (>=1.42.0,<1.43.0)", "mypy-boto3-partnercentral-benefits (>=1.42.0,<1.43.0)", "mypy-boto3-partnercentral-channel (>=1.42.0,<1.43.0)", "mypy-boto3-partnercentral-selling (>=1.42.0,<1.43.0)", "mypy-boto3-payment-cryptography (>=1.42.0,<1.43.0)", "mypy-boto3-payment-cryptography-data (>=1.42.0,<1.43.0)", "mypy-boto3-pca-connector-ad (>=1.42.0,<1.43.0)", "mypy-boto3-pca-connector-scep (>=1.42.0,<1.43.0)", "mypy-boto3-pcs (>=1.42.0,<1.43.0)", "mypy-boto3-personalize (>=1.42.0,<1.43.0)", "mypy-boto3-personalize-events (>=1.42.0,<1.43.0)", "mypy-boto3-personalize-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-pi (>=1.42.0,<1.43.0)", "mypy-boto3-pinpoint (>=1.42.0,<1.43.0)", "mypy-boto3-pinpoint-email (>=1.42.0,<1.43.0)", "mypy-boto3-pinpoint-sms-voice (>=1.42.0,<1.43.0)", "mypy-boto3-pinpoint-sms-voice-v2 (>=1.42.0,<1.43.0)", "mypy-boto3-pipes (>=1.42.0,<1.43.0)", "mypy-boto3-polly (>=1.42.0,<1.43.0)", "mypy-boto3-pricing (>=1.42.0,<1.43.0)", "mypy-boto3-proton (>=1.42.0,<1.43.0)", "mypy-boto3-qapps (>=1.42.0,<1.43.0)", "mypy-boto3-qbusiness (>=1.42.0,<1.43.0)", "mypy-boto3-qconnect (>=1.42.0,<1.43.0)", "mypy-boto3-quicksight (>=1.42.0,<1.43.0)", "mypy-boto3-ram (>=1.42.0,<1.43.0)", "mypy-boto3-rbin (>=1.42.0,<1.43.0)", "mypy-boto3-rds (>=1.42.0,<1.43.0)", "mypy-boto3-rds-data (>=1.42.0,<1.43.0)", "mypy-boto3-redshift (>=1.42.0,<1.43.0)", "mypy-boto3-redshift-data (>=1.42.0,<1.43.0)", "mypy-boto3-redshift-serverless (>=1.42.0,<1.43.0)", "mypy-boto3-rekognition (>=1.42.0,<1.43.0)", "mypy-boto3-repostspace (>=1.42.0,<1.43.0)", "mypy-boto3-resiliencehub (>=1.42.0,<1.43.0)", "mypy-boto3-resource-explorer-2 (>=1.42.0,<1.43.0)", "mypy-boto3-resource-groups (>=1.42.0,<1.43.0)", "mypy-boto3-resourcegroupstaggingapi (>=1.42.0,<1.43.0)", "mypy-boto3-rolesanywhere (>=1.42.0,<1.43.0)", "mypy-boto3-route53 (>=1.42.0,<1.43.0)", "mypy-boto3-route53-recovery-cluster (>=1.42.0,<1.43.0)", "mypy-boto3-route53-recovery-control-config (>=1.42.0,<1.43.0)", "mypy-boto3-route53-recovery-readiness (>=1.42.0,<1.43.0)", "mypy-boto3-route53domains (>=1.42.0,<1.43.0)", "mypy-boto3-route53globalresolver (>=1.42.0,<1.43.0)", "mypy-boto3-route53profiles (>=1.42.0,<1.43.0)", "mypy-boto3-route53resolver (>=1.42.0,<1.43.0)", "mypy-boto3-rtbfabric (>=1.42.0,<1.43.0)", "mypy-boto3-rum (>=1.42.0,<1.43.0)", "mypy-boto3-s3 (>=1.42.0,<1.43.0)", "mypy-boto3-s3control (>=1.42.0,<1.43.0)", "mypy-boto3-s3outposts (>=1.42.0,<1.43.0)", "mypy-boto3-s3tables (>=1.42.0,<1.43.0)", "mypy-boto3-s3vectors (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-a2i-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-edge (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-featurestore-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-geospatial (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-metrics (>=1.42.0,<1.43.0)", "mypy-boto3-sagemaker-runtime (>=1.42.0,<1.43.0)", "mypy-boto3-savingsplans (>=1.42.0,<1.43.0)", "mypy-boto3-scheduler (>=1.42.0,<1.43.0)", "mypy-boto3-schemas (>=1.42.0,<1.43.0)", "mypy-boto3-sdb (>=1.42.0,<1.43.0)", "mypy-boto3-secretsmanager (>=1.42.0,<1.43.0)", "mypy-boto3-security-ir (>=1.42.0,<1.43.0)", "mypy-boto3-securityhub (>=1.42.0,<1.43.0)", "mypy-boto3-securitylake (>=1.42.0,<1.43.0)", "mypy-boto3-serverlessrepo (>=1.42.0,<1.43.0)", "mypy-boto3-service-quotas (>=1.42.0,<1.43.0)", "mypy-boto3-servicecatalog (>=1.42.0,<1.43.0)", "mypy-boto3-servicecatalog-appregistry (>=1.42.0,<1.43.0)", "mypy-boto3-servicediscovery (>=1.42.0,<1.43.0)", "mypy-boto3-ses (>=1.42.0,<1.43.0)", "mypy-boto3-sesv2 (>=1.42.0,<1.43.0)", "mypy-boto3-shield (>=1.42.0,<1.43.0)", "mypy-boto3-signer (>=1.42.0,<1.43.0)", "mypy-boto3-signer-data (>=1.42.0,<1.43.0)", "mypy-boto3-signin (>=1.42.0,<1.43.0)", "mypy-boto3-simpledbv2 (>=1.42.0,<1.43.0)", "mypy-boto3-simspaceweaver (>=1.42.0,<1.43.0)", "mypy-boto3-snow-device-management (>=1.42.0,<1.43.0)", "mypy-boto3-snowball (>=1.42.0,<1.43.0)", "mypy-boto3-sns (>=1.42.0,<1.43.0)", "mypy-boto3-socialmessaging (>=1.42.0,<1.43.0)", "mypy-boto3-sqs (>=1.42.0,<1.43.0)", "mypy-boto3-ssm (>=1.42.0,<1.43.0)", "mypy-boto3-ssm-contacts (>=1.42.0,<1.43.0)", "mypy-boto3-ssm-guiconnect (>=1.42.0,<1.43.0)", "mypy-boto3-ssm-incidents (>=1.42.0,<1.43.0)", "mypy-boto3-ssm-quicksetup (>=1.42.0,<1.43.0)", "mypy-boto3-ssm-sap (>=1.42.0,<1.43.0)", "mypy-boto3-sso (>=1.42.0,<1.43.0)", "mypy-boto3-sso-admin (>=1.42.0,<1.43.0)", "mypy-boto3-sso-oidc (>=1.42.0,<1.43.0)", "mypy-boto3-stepfunctions (>=1.42.0,<1.43.0)", "mypy-boto3-storagegateway (>=1.42.0,<1.43.0)", "mypy-boto3-sts (>=1.42.0,<1.43.0)", "mypy-boto3-supplychain (>=1.42.0,<1.43.0)", "mypy-boto3-support (>=1.42.0,<1.43.0)", "mypy-boto3-support-app (>=1.42.0,<1.43.0)", "mypy-boto3-swf (>=1.42.0,<1.43.0)", "mypy-boto3-synthetics (>=1.42.0,<1.43.0)", "mypy-boto3-taxsettings (>=1.42.0,<1.43.0)", "mypy-boto3-textract (>=1.42.0,<1.43.0)", "mypy-boto3-timestream-influxdb (>=1.42.0,<1.43.0)", "mypy-boto3-timestream-query (>=1.42.0,<1.43.0)", "mypy-boto3-timestream-write (>=1.42.0,<1.43.0)", "mypy-boto3-tnb (>=1.42.0,<1.43.0)", "mypy-boto3-transcribe (>=1.42.0,<1.43.0)", "mypy-boto3-transfer (>=1.42.0,<1.43.0)", "mypy-boto3-translate (>=1.42.0,<1.43.0)", "mypy-boto3-trustedadvisor (>=1.42.0,<1.43.0)", "mypy-boto3-verifiedpermissions (>=1.42.0,<1.43.0)", "mypy-boto3-voice-id (>=1.42.0,<1.43.0)", "mypy-boto3-vpc-lattice (>=1.42.0,<1.43.0)", "mypy-boto3-waf (>=1.42.0,<1.43.0)", "mypy-boto3-waf-regional (>=1.42.0,<1.43.0)", "mypy-boto3-wafv2 (>=1.42.0,<1.43.0)", "mypy-boto3-wellarchitected (>=1.42.0,<1.43.0)", "mypy-boto3-wickr (>=1.42.0,<1.43.0)", "mypy-boto3-wisdom (>=1.42.0,<1.43.0)", "mypy-boto3-workdocs (>=1.42.0,<1.43.0)", "mypy-boto3-workmail (>=1.42.0,<1.43.0)", "mypy-boto3-workmailmessageflow (>=1.42.0,<1.43.0)", "mypy-boto3-workspaces (>=1.42.0,<1.43.0)", "mypy-boto3-workspaces-instances (>=1.42.0,<1.43.0)", "mypy-boto3-workspaces-thin-client (>=1.42.0,<1.43.0)", "mypy-boto3-workspaces-web (>=1.42.0,<1.43.0)", "mypy-boto3-xray (>=1.42.0,<1.43.0)"] -amp = ["mypy-boto3-amp (>=1.42.0,<1.43.0)"] -amplify = ["mypy-boto3-amplify (>=1.42.0,<1.43.0)"] -amplifybackend = ["mypy-boto3-amplifybackend (>=1.42.0,<1.43.0)"] -amplifyuibuilder = ["mypy-boto3-amplifyuibuilder (>=1.42.0,<1.43.0)"] -apigateway = ["mypy-boto3-apigateway (>=1.42.0,<1.43.0)"] -apigatewaymanagementapi = ["mypy-boto3-apigatewaymanagementapi (>=1.42.0,<1.43.0)"] -apigatewayv2 = ["mypy-boto3-apigatewayv2 (>=1.42.0,<1.43.0)"] -appconfig = ["mypy-boto3-appconfig (>=1.42.0,<1.43.0)"] -appconfigdata = ["mypy-boto3-appconfigdata (>=1.42.0,<1.43.0)"] -appfabric = ["mypy-boto3-appfabric (>=1.42.0,<1.43.0)"] -appflow = ["mypy-boto3-appflow (>=1.42.0,<1.43.0)"] -appintegrations = ["mypy-boto3-appintegrations (>=1.42.0,<1.43.0)"] -application-autoscaling = ["mypy-boto3-application-autoscaling (>=1.42.0,<1.43.0)"] -application-insights = ["mypy-boto3-application-insights (>=1.42.0,<1.43.0)"] -application-signals = ["mypy-boto3-application-signals (>=1.42.0,<1.43.0)"] -applicationcostprofiler = ["mypy-boto3-applicationcostprofiler (>=1.42.0,<1.43.0)"] -appmesh = ["mypy-boto3-appmesh (>=1.42.0,<1.43.0)"] -apprunner = ["mypy-boto3-apprunner (>=1.42.0,<1.43.0)"] -appstream = ["mypy-boto3-appstream (>=1.42.0,<1.43.0)"] -appsync = ["mypy-boto3-appsync (>=1.42.0,<1.43.0)"] -arc-region-switch = ["mypy-boto3-arc-region-switch (>=1.42.0,<1.43.0)"] -arc-zonal-shift = ["mypy-boto3-arc-zonal-shift (>=1.42.0,<1.43.0)"] -artifact = ["mypy-boto3-artifact (>=1.42.0,<1.43.0)"] -athena = ["mypy-boto3-athena (>=1.42.0,<1.43.0)"] -auditmanager = ["mypy-boto3-auditmanager (>=1.42.0,<1.43.0)"] -autoscaling = ["mypy-boto3-autoscaling (>=1.42.0,<1.43.0)"] -autoscaling-plans = ["mypy-boto3-autoscaling-plans (>=1.42.0,<1.43.0)"] -b2bi = ["mypy-boto3-b2bi (>=1.42.0,<1.43.0)"] -backup = ["mypy-boto3-backup (>=1.42.0,<1.43.0)"] -backup-gateway = ["mypy-boto3-backup-gateway (>=1.42.0,<1.43.0)"] -backupsearch = ["mypy-boto3-backupsearch (>=1.42.0,<1.43.0)"] -batch = ["mypy-boto3-batch (>=1.42.0,<1.43.0)"] -bcm-dashboards = ["mypy-boto3-bcm-dashboards (>=1.42.0,<1.43.0)"] -bcm-data-exports = ["mypy-boto3-bcm-data-exports (>=1.42.0,<1.43.0)"] -bcm-pricing-calculator = ["mypy-boto3-bcm-pricing-calculator (>=1.42.0,<1.43.0)"] -bcm-recommended-actions = ["mypy-boto3-bcm-recommended-actions (>=1.42.0,<1.43.0)"] -bedrock = ["mypy-boto3-bedrock (>=1.42.0,<1.43.0)"] -bedrock-agent = ["mypy-boto3-bedrock-agent (>=1.42.0,<1.43.0)"] -bedrock-agent-runtime = ["mypy-boto3-bedrock-agent-runtime (>=1.42.0,<1.43.0)"] -bedrock-agentcore = ["mypy-boto3-bedrock-agentcore (>=1.42.0,<1.43.0)"] -bedrock-agentcore-control = ["mypy-boto3-bedrock-agentcore-control (>=1.42.0,<1.43.0)"] -bedrock-data-automation = ["mypy-boto3-bedrock-data-automation (>=1.42.0,<1.43.0)"] -bedrock-data-automation-runtime = ["mypy-boto3-bedrock-data-automation-runtime (>=1.42.0,<1.43.0)"] -bedrock-runtime = ["mypy-boto3-bedrock-runtime (>=1.42.0,<1.43.0)"] -billing = ["mypy-boto3-billing (>=1.42.0,<1.43.0)"] -billingconductor = ["mypy-boto3-billingconductor (>=1.42.0,<1.43.0)"] -boto3 = ["boto3 (==1.42.74)"] -braket = ["mypy-boto3-braket (>=1.42.0,<1.43.0)"] -budgets = ["mypy-boto3-budgets (>=1.42.0,<1.43.0)"] -ce = ["mypy-boto3-ce (>=1.42.0,<1.43.0)"] -chatbot = ["mypy-boto3-chatbot (>=1.42.0,<1.43.0)"] -chime = ["mypy-boto3-chime (>=1.42.0,<1.43.0)"] -chime-sdk-identity = ["mypy-boto3-chime-sdk-identity (>=1.42.0,<1.43.0)"] -chime-sdk-media-pipelines = ["mypy-boto3-chime-sdk-media-pipelines (>=1.42.0,<1.43.0)"] -chime-sdk-meetings = ["mypy-boto3-chime-sdk-meetings (>=1.42.0,<1.43.0)"] -chime-sdk-messaging = ["mypy-boto3-chime-sdk-messaging (>=1.42.0,<1.43.0)"] -chime-sdk-voice = ["mypy-boto3-chime-sdk-voice (>=1.42.0,<1.43.0)"] -cleanrooms = ["mypy-boto3-cleanrooms (>=1.42.0,<1.43.0)"] -cleanroomsml = ["mypy-boto3-cleanroomsml (>=1.42.0,<1.43.0)"] -cloud9 = ["mypy-boto3-cloud9 (>=1.42.0,<1.43.0)"] -cloudcontrol = ["mypy-boto3-cloudcontrol (>=1.42.0,<1.43.0)"] -clouddirectory = ["mypy-boto3-clouddirectory (>=1.42.0,<1.43.0)"] -cloudformation = ["mypy-boto3-cloudformation (>=1.42.0,<1.43.0)"] -cloudfront = ["mypy-boto3-cloudfront (>=1.42.0,<1.43.0)"] -cloudfront-keyvaluestore = ["mypy-boto3-cloudfront-keyvaluestore (>=1.42.0,<1.43.0)"] -cloudhsm = ["mypy-boto3-cloudhsm (>=1.42.0,<1.43.0)"] -cloudhsmv2 = ["mypy-boto3-cloudhsmv2 (>=1.42.0,<1.43.0)"] -cloudsearch = ["mypy-boto3-cloudsearch (>=1.42.0,<1.43.0)"] -cloudsearchdomain = ["mypy-boto3-cloudsearchdomain (>=1.42.0,<1.43.0)"] -cloudtrail = ["mypy-boto3-cloudtrail (>=1.42.0,<1.43.0)"] -cloudtrail-data = ["mypy-boto3-cloudtrail-data (>=1.42.0,<1.43.0)"] -cloudwatch = ["mypy-boto3-cloudwatch (>=1.42.0,<1.43.0)"] -codeartifact = ["mypy-boto3-codeartifact (>=1.42.0,<1.43.0)"] -codebuild = ["mypy-boto3-codebuild (>=1.42.0,<1.43.0)"] -codecatalyst = ["mypy-boto3-codecatalyst (>=1.42.0,<1.43.0)"] -codecommit = ["mypy-boto3-codecommit (>=1.42.0,<1.43.0)"] -codeconnections = ["mypy-boto3-codeconnections (>=1.42.0,<1.43.0)"] -codedeploy = ["mypy-boto3-codedeploy (>=1.42.0,<1.43.0)"] -codeguru-reviewer = ["mypy-boto3-codeguru-reviewer (>=1.42.0,<1.43.0)"] -codeguru-security = ["mypy-boto3-codeguru-security (>=1.42.0,<1.43.0)"] -codeguruprofiler = ["mypy-boto3-codeguruprofiler (>=1.42.0,<1.43.0)"] -codepipeline = ["mypy-boto3-codepipeline (>=1.42.0,<1.43.0)"] -codestar-connections = ["mypy-boto3-codestar-connections (>=1.42.0,<1.43.0)"] -codestar-notifications = ["mypy-boto3-codestar-notifications (>=1.42.0,<1.43.0)"] -cognito-identity = ["mypy-boto3-cognito-identity (>=1.42.0,<1.43.0)"] -cognito-idp = ["mypy-boto3-cognito-idp (>=1.42.0,<1.43.0)"] -cognito-sync = ["mypy-boto3-cognito-sync (>=1.42.0,<1.43.0)"] -comprehend = ["mypy-boto3-comprehend (>=1.42.0,<1.43.0)"] -comprehendmedical = ["mypy-boto3-comprehendmedical (>=1.42.0,<1.43.0)"] -compute-optimizer = ["mypy-boto3-compute-optimizer (>=1.42.0,<1.43.0)"] -compute-optimizer-automation = ["mypy-boto3-compute-optimizer-automation (>=1.42.0,<1.43.0)"] -config = ["mypy-boto3-config (>=1.42.0,<1.43.0)"] -connect = ["mypy-boto3-connect (>=1.42.0,<1.43.0)"] -connect-contact-lens = ["mypy-boto3-connect-contact-lens (>=1.42.0,<1.43.0)"] -connectcampaigns = ["mypy-boto3-connectcampaigns (>=1.42.0,<1.43.0)"] -connectcampaignsv2 = ["mypy-boto3-connectcampaignsv2 (>=1.42.0,<1.43.0)"] -connectcases = ["mypy-boto3-connectcases (>=1.42.0,<1.43.0)"] -connecthealth = ["mypy-boto3-connecthealth (>=1.42.0,<1.43.0)"] -connectparticipant = ["mypy-boto3-connectparticipant (>=1.42.0,<1.43.0)"] -controlcatalog = ["mypy-boto3-controlcatalog (>=1.42.0,<1.43.0)"] -controltower = ["mypy-boto3-controltower (>=1.42.0,<1.43.0)"] -cost-optimization-hub = ["mypy-boto3-cost-optimization-hub (>=1.42.0,<1.43.0)"] -cur = ["mypy-boto3-cur (>=1.42.0,<1.43.0)"] -customer-profiles = ["mypy-boto3-customer-profiles (>=1.42.0,<1.43.0)"] -databrew = ["mypy-boto3-databrew (>=1.42.0,<1.43.0)"] -dataexchange = ["mypy-boto3-dataexchange (>=1.42.0,<1.43.0)"] -datapipeline = ["mypy-boto3-datapipeline (>=1.42.0,<1.43.0)"] -datasync = ["mypy-boto3-datasync (>=1.42.0,<1.43.0)"] -datazone = ["mypy-boto3-datazone (>=1.42.0,<1.43.0)"] -dax = ["mypy-boto3-dax (>=1.42.0,<1.43.0)"] -deadline = ["mypy-boto3-deadline (>=1.42.0,<1.43.0)"] -detective = ["mypy-boto3-detective (>=1.42.0,<1.43.0)"] -devicefarm = ["mypy-boto3-devicefarm (>=1.42.0,<1.43.0)"] -devops-guru = ["mypy-boto3-devops-guru (>=1.42.0,<1.43.0)"] -directconnect = ["mypy-boto3-directconnect (>=1.42.0,<1.43.0)"] -discovery = ["mypy-boto3-discovery (>=1.42.0,<1.43.0)"] -dlm = ["mypy-boto3-dlm (>=1.42.0,<1.43.0)"] -dms = ["mypy-boto3-dms (>=1.42.0,<1.43.0)"] -docdb = ["mypy-boto3-docdb (>=1.42.0,<1.43.0)"] -docdb-elastic = ["mypy-boto3-docdb-elastic (>=1.42.0,<1.43.0)"] -drs = ["mypy-boto3-drs (>=1.42.0,<1.43.0)"] -ds = ["mypy-boto3-ds (>=1.42.0,<1.43.0)"] -ds-data = ["mypy-boto3-ds-data (>=1.42.0,<1.43.0)"] -dsql = ["mypy-boto3-dsql (>=1.42.0,<1.43.0)"] -dynamodb = ["mypy-boto3-dynamodb (>=1.42.0,<1.43.0)"] -dynamodbstreams = ["mypy-boto3-dynamodbstreams (>=1.42.0,<1.43.0)"] -ebs = ["mypy-boto3-ebs (>=1.42.0,<1.43.0)"] -ec2 = ["mypy-boto3-ec2 (>=1.42.0,<1.43.0)"] -ec2-instance-connect = ["mypy-boto3-ec2-instance-connect (>=1.42.0,<1.43.0)"] -ecr = ["mypy-boto3-ecr (>=1.42.0,<1.43.0)"] -ecr-public = ["mypy-boto3-ecr-public (>=1.42.0,<1.43.0)"] -ecs = ["mypy-boto3-ecs (>=1.42.0,<1.43.0)"] -efs = ["mypy-boto3-efs (>=1.42.0,<1.43.0)"] -eks = ["mypy-boto3-eks (>=1.42.0,<1.43.0)"] -eks-auth = ["mypy-boto3-eks-auth (>=1.42.0,<1.43.0)"] -elasticache = ["mypy-boto3-elasticache (>=1.42.0,<1.43.0)"] -elasticbeanstalk = ["mypy-boto3-elasticbeanstalk (>=1.42.0,<1.43.0)"] -elb = ["mypy-boto3-elb (>=1.42.0,<1.43.0)"] -elbv2 = ["mypy-boto3-elbv2 (>=1.42.0,<1.43.0)"] -elementalinference = ["mypy-boto3-elementalinference (>=1.42.0,<1.43.0)"] -emr = ["mypy-boto3-emr (>=1.42.0,<1.43.0)"] -emr-containers = ["mypy-boto3-emr-containers (>=1.42.0,<1.43.0)"] -emr-serverless = ["mypy-boto3-emr-serverless (>=1.42.0,<1.43.0)"] -entityresolution = ["mypy-boto3-entityresolution (>=1.42.0,<1.43.0)"] -es = ["mypy-boto3-es (>=1.42.0,<1.43.0)"] -essential = ["mypy-boto3-cloudformation (>=1.42.0,<1.43.0)", "mypy-boto3-dynamodb (>=1.42.0,<1.43.0)", "mypy-boto3-ec2 (>=1.42.0,<1.43.0)", "mypy-boto3-lambda (>=1.42.0,<1.43.0)", "mypy-boto3-rds (>=1.42.0,<1.43.0)", "mypy-boto3-s3 (>=1.42.0,<1.43.0)", "mypy-boto3-sqs (>=1.42.0,<1.43.0)"] -events = ["mypy-boto3-events (>=1.42.0,<1.43.0)"] -evs = ["mypy-boto3-evs (>=1.42.0,<1.43.0)"] -finspace = ["mypy-boto3-finspace (>=1.42.0,<1.43.0)"] -finspace-data = ["mypy-boto3-finspace-data (>=1.42.0,<1.43.0)"] -firehose = ["mypy-boto3-firehose (>=1.42.0,<1.43.0)"] -fis = ["mypy-boto3-fis (>=1.42.0,<1.43.0)"] -fms = ["mypy-boto3-fms (>=1.42.0,<1.43.0)"] -forecast = ["mypy-boto3-forecast (>=1.42.0,<1.43.0)"] -forecastquery = ["mypy-boto3-forecastquery (>=1.42.0,<1.43.0)"] -frauddetector = ["mypy-boto3-frauddetector (>=1.42.0,<1.43.0)"] -freetier = ["mypy-boto3-freetier (>=1.42.0,<1.43.0)"] -fsx = ["mypy-boto3-fsx (>=1.42.0,<1.43.0)"] -full = ["boto3-stubs-full (>=1.42.0,<1.43.0)"] -gamelift = ["mypy-boto3-gamelift (>=1.42.0,<1.43.0)"] -gameliftstreams = ["mypy-boto3-gameliftstreams (>=1.42.0,<1.43.0)"] -geo-maps = ["mypy-boto3-geo-maps (>=1.42.0,<1.43.0)"] -geo-places = ["mypy-boto3-geo-places (>=1.42.0,<1.43.0)"] -geo-routes = ["mypy-boto3-geo-routes (>=1.42.0,<1.43.0)"] -glacier = ["mypy-boto3-glacier (>=1.42.0,<1.43.0)"] -globalaccelerator = ["mypy-boto3-globalaccelerator (>=1.42.0,<1.43.0)"] -glue = ["mypy-boto3-glue (>=1.42.0,<1.43.0)"] -grafana = ["mypy-boto3-grafana (>=1.42.0,<1.43.0)"] -greengrass = ["mypy-boto3-greengrass (>=1.42.0,<1.43.0)"] -greengrassv2 = ["mypy-boto3-greengrassv2 (>=1.42.0,<1.43.0)"] -groundstation = ["mypy-boto3-groundstation (>=1.42.0,<1.43.0)"] -guardduty = ["mypy-boto3-guardduty (>=1.42.0,<1.43.0)"] -health = ["mypy-boto3-health (>=1.42.0,<1.43.0)"] -healthlake = ["mypy-boto3-healthlake (>=1.42.0,<1.43.0)"] -iam = ["mypy-boto3-iam (>=1.42.0,<1.43.0)"] -identitystore = ["mypy-boto3-identitystore (>=1.42.0,<1.43.0)"] -imagebuilder = ["mypy-boto3-imagebuilder (>=1.42.0,<1.43.0)"] -importexport = ["mypy-boto3-importexport (>=1.42.0,<1.43.0)"] -inspector = ["mypy-boto3-inspector (>=1.42.0,<1.43.0)"] -inspector-scan = ["mypy-boto3-inspector-scan (>=1.42.0,<1.43.0)"] -inspector2 = ["mypy-boto3-inspector2 (>=1.42.0,<1.43.0)"] -internetmonitor = ["mypy-boto3-internetmonitor (>=1.42.0,<1.43.0)"] -invoicing = ["mypy-boto3-invoicing (>=1.42.0,<1.43.0)"] -iot = ["mypy-boto3-iot (>=1.42.0,<1.43.0)"] -iot-data = ["mypy-boto3-iot-data (>=1.42.0,<1.43.0)"] -iot-jobs-data = ["mypy-boto3-iot-jobs-data (>=1.42.0,<1.43.0)"] -iot-managed-integrations = ["mypy-boto3-iot-managed-integrations (>=1.42.0,<1.43.0)"] -iotdeviceadvisor = ["mypy-boto3-iotdeviceadvisor (>=1.42.0,<1.43.0)"] -iotevents = ["mypy-boto3-iotevents (>=1.42.0,<1.43.0)"] -iotevents-data = ["mypy-boto3-iotevents-data (>=1.42.0,<1.43.0)"] -iotfleetwise = ["mypy-boto3-iotfleetwise (>=1.42.0,<1.43.0)"] -iotsecuretunneling = ["mypy-boto3-iotsecuretunneling (>=1.42.0,<1.43.0)"] -iotsitewise = ["mypy-boto3-iotsitewise (>=1.42.0,<1.43.0)"] -iotthingsgraph = ["mypy-boto3-iotthingsgraph (>=1.42.0,<1.43.0)"] -iottwinmaker = ["mypy-boto3-iottwinmaker (>=1.42.0,<1.43.0)"] -iotwireless = ["mypy-boto3-iotwireless (>=1.42.0,<1.43.0)"] -ivs = ["mypy-boto3-ivs (>=1.42.0,<1.43.0)"] -ivs-realtime = ["mypy-boto3-ivs-realtime (>=1.42.0,<1.43.0)"] -ivschat = ["mypy-boto3-ivschat (>=1.42.0,<1.43.0)"] -kafka = ["mypy-boto3-kafka (>=1.42.0,<1.43.0)"] -kafkaconnect = ["mypy-boto3-kafkaconnect (>=1.42.0,<1.43.0)"] -kendra = ["mypy-boto3-kendra (>=1.42.0,<1.43.0)"] -kendra-ranking = ["mypy-boto3-kendra-ranking (>=1.42.0,<1.43.0)"] -keyspaces = ["mypy-boto3-keyspaces (>=1.42.0,<1.43.0)"] -keyspacesstreams = ["mypy-boto3-keyspacesstreams (>=1.42.0,<1.43.0)"] -kinesis = ["mypy-boto3-kinesis (>=1.42.0,<1.43.0)"] -kinesis-video-archived-media = ["mypy-boto3-kinesis-video-archived-media (>=1.42.0,<1.43.0)"] -kinesis-video-media = ["mypy-boto3-kinesis-video-media (>=1.42.0,<1.43.0)"] -kinesis-video-signaling = ["mypy-boto3-kinesis-video-signaling (>=1.42.0,<1.43.0)"] -kinesis-video-webrtc-storage = ["mypy-boto3-kinesis-video-webrtc-storage (>=1.42.0,<1.43.0)"] -kinesisanalytics = ["mypy-boto3-kinesisanalytics (>=1.42.0,<1.43.0)"] -kinesisanalyticsv2 = ["mypy-boto3-kinesisanalyticsv2 (>=1.42.0,<1.43.0)"] -kinesisvideo = ["mypy-boto3-kinesisvideo (>=1.42.0,<1.43.0)"] -kms = ["mypy-boto3-kms (>=1.42.0,<1.43.0)"] -lakeformation = ["mypy-boto3-lakeformation (>=1.42.0,<1.43.0)"] -lambda = ["mypy-boto3-lambda (>=1.42.0,<1.43.0)"] -launch-wizard = ["mypy-boto3-launch-wizard (>=1.42.0,<1.43.0)"] -lex-models = ["mypy-boto3-lex-models (>=1.42.0,<1.43.0)"] -lex-runtime = ["mypy-boto3-lex-runtime (>=1.42.0,<1.43.0)"] -lexv2-models = ["mypy-boto3-lexv2-models (>=1.42.0,<1.43.0)"] -lexv2-runtime = ["mypy-boto3-lexv2-runtime (>=1.42.0,<1.43.0)"] -license-manager = ["mypy-boto3-license-manager (>=1.42.0,<1.43.0)"] -license-manager-linux-subscriptions = ["mypy-boto3-license-manager-linux-subscriptions (>=1.42.0,<1.43.0)"] -license-manager-user-subscriptions = ["mypy-boto3-license-manager-user-subscriptions (>=1.42.0,<1.43.0)"] -lightsail = ["mypy-boto3-lightsail (>=1.42.0,<1.43.0)"] -location = ["mypy-boto3-location (>=1.42.0,<1.43.0)"] -logs = ["mypy-boto3-logs (>=1.42.0,<1.43.0)"] -lookoutequipment = ["mypy-boto3-lookoutequipment (>=1.42.0,<1.43.0)"] -m2 = ["mypy-boto3-m2 (>=1.42.0,<1.43.0)"] -machinelearning = ["mypy-boto3-machinelearning (>=1.42.0,<1.43.0)"] -macie2 = ["mypy-boto3-macie2 (>=1.42.0,<1.43.0)"] -mailmanager = ["mypy-boto3-mailmanager (>=1.42.0,<1.43.0)"] -managedblockchain = ["mypy-boto3-managedblockchain (>=1.42.0,<1.43.0)"] -managedblockchain-query = ["mypy-boto3-managedblockchain-query (>=1.42.0,<1.43.0)"] -marketplace-agreement = ["mypy-boto3-marketplace-agreement (>=1.42.0,<1.43.0)"] -marketplace-catalog = ["mypy-boto3-marketplace-catalog (>=1.42.0,<1.43.0)"] -marketplace-deployment = ["mypy-boto3-marketplace-deployment (>=1.42.0,<1.43.0)"] -marketplace-entitlement = ["mypy-boto3-marketplace-entitlement (>=1.42.0,<1.43.0)"] -marketplace-reporting = ["mypy-boto3-marketplace-reporting (>=1.42.0,<1.43.0)"] -marketplacecommerceanalytics = ["mypy-boto3-marketplacecommerceanalytics (>=1.42.0,<1.43.0)"] -mediaconnect = ["mypy-boto3-mediaconnect (>=1.42.0,<1.43.0)"] -mediaconvert = ["mypy-boto3-mediaconvert (>=1.42.0,<1.43.0)"] -medialive = ["mypy-boto3-medialive (>=1.42.0,<1.43.0)"] -mediapackage = ["mypy-boto3-mediapackage (>=1.42.0,<1.43.0)"] -mediapackage-vod = ["mypy-boto3-mediapackage-vod (>=1.42.0,<1.43.0)"] -mediapackagev2 = ["mypy-boto3-mediapackagev2 (>=1.42.0,<1.43.0)"] -mediastore = ["mypy-boto3-mediastore (>=1.42.0,<1.43.0)"] -mediastore-data = ["mypy-boto3-mediastore-data (>=1.42.0,<1.43.0)"] -mediatailor = ["mypy-boto3-mediatailor (>=1.42.0,<1.43.0)"] -medical-imaging = ["mypy-boto3-medical-imaging (>=1.42.0,<1.43.0)"] -memorydb = ["mypy-boto3-memorydb (>=1.42.0,<1.43.0)"] -meteringmarketplace = ["mypy-boto3-meteringmarketplace (>=1.42.0,<1.43.0)"] -mgh = ["mypy-boto3-mgh (>=1.42.0,<1.43.0)"] -mgn = ["mypy-boto3-mgn (>=1.42.0,<1.43.0)"] -migration-hub-refactor-spaces = ["mypy-boto3-migration-hub-refactor-spaces (>=1.42.0,<1.43.0)"] -migrationhub-config = ["mypy-boto3-migrationhub-config (>=1.42.0,<1.43.0)"] -migrationhuborchestrator = ["mypy-boto3-migrationhuborchestrator (>=1.42.0,<1.43.0)"] -migrationhubstrategy = ["mypy-boto3-migrationhubstrategy (>=1.42.0,<1.43.0)"] -mpa = ["mypy-boto3-mpa (>=1.42.0,<1.43.0)"] -mq = ["mypy-boto3-mq (>=1.42.0,<1.43.0)"] -mturk = ["mypy-boto3-mturk (>=1.42.0,<1.43.0)"] -mwaa = ["mypy-boto3-mwaa (>=1.42.0,<1.43.0)"] -mwaa-serverless = ["mypy-boto3-mwaa-serverless (>=1.42.0,<1.43.0)"] -neptune = ["mypy-boto3-neptune (>=1.42.0,<1.43.0)"] -neptune-graph = ["mypy-boto3-neptune-graph (>=1.42.0,<1.43.0)"] -neptunedata = ["mypy-boto3-neptunedata (>=1.42.0,<1.43.0)"] -network-firewall = ["mypy-boto3-network-firewall (>=1.42.0,<1.43.0)"] -networkflowmonitor = ["mypy-boto3-networkflowmonitor (>=1.42.0,<1.43.0)"] -networkmanager = ["mypy-boto3-networkmanager (>=1.42.0,<1.43.0)"] -networkmonitor = ["mypy-boto3-networkmonitor (>=1.42.0,<1.43.0)"] -notifications = ["mypy-boto3-notifications (>=1.42.0,<1.43.0)"] -notificationscontacts = ["mypy-boto3-notificationscontacts (>=1.42.0,<1.43.0)"] -nova-act = ["mypy-boto3-nova-act (>=1.42.0,<1.43.0)"] -oam = ["mypy-boto3-oam (>=1.42.0,<1.43.0)"] -observabilityadmin = ["mypy-boto3-observabilityadmin (>=1.42.0,<1.43.0)"] -odb = ["mypy-boto3-odb (>=1.42.0,<1.43.0)"] -omics = ["mypy-boto3-omics (>=1.42.0,<1.43.0)"] -opensearch = ["mypy-boto3-opensearch (>=1.42.0,<1.43.0)"] -opensearchserverless = ["mypy-boto3-opensearchserverless (>=1.42.0,<1.43.0)"] -organizations = ["mypy-boto3-organizations (>=1.42.0,<1.43.0)"] -osis = ["mypy-boto3-osis (>=1.42.0,<1.43.0)"] -outposts = ["mypy-boto3-outposts (>=1.42.0,<1.43.0)"] -panorama = ["mypy-boto3-panorama (>=1.42.0,<1.43.0)"] -partnercentral-account = ["mypy-boto3-partnercentral-account (>=1.42.0,<1.43.0)"] -partnercentral-benefits = ["mypy-boto3-partnercentral-benefits (>=1.42.0,<1.43.0)"] -partnercentral-channel = ["mypy-boto3-partnercentral-channel (>=1.42.0,<1.43.0)"] -partnercentral-selling = ["mypy-boto3-partnercentral-selling (>=1.42.0,<1.43.0)"] -payment-cryptography = ["mypy-boto3-payment-cryptography (>=1.42.0,<1.43.0)"] -payment-cryptography-data = ["mypy-boto3-payment-cryptography-data (>=1.42.0,<1.43.0)"] -pca-connector-ad = ["mypy-boto3-pca-connector-ad (>=1.42.0,<1.43.0)"] -pca-connector-scep = ["mypy-boto3-pca-connector-scep (>=1.42.0,<1.43.0)"] -pcs = ["mypy-boto3-pcs (>=1.42.0,<1.43.0)"] -personalize = ["mypy-boto3-personalize (>=1.42.0,<1.43.0)"] -personalize-events = ["mypy-boto3-personalize-events (>=1.42.0,<1.43.0)"] -personalize-runtime = ["mypy-boto3-personalize-runtime (>=1.42.0,<1.43.0)"] -pi = ["mypy-boto3-pi (>=1.42.0,<1.43.0)"] -pinpoint = ["mypy-boto3-pinpoint (>=1.42.0,<1.43.0)"] -pinpoint-email = ["mypy-boto3-pinpoint-email (>=1.42.0,<1.43.0)"] -pinpoint-sms-voice = ["mypy-boto3-pinpoint-sms-voice (>=1.42.0,<1.43.0)"] -pinpoint-sms-voice-v2 = ["mypy-boto3-pinpoint-sms-voice-v2 (>=1.42.0,<1.43.0)"] -pipes = ["mypy-boto3-pipes (>=1.42.0,<1.43.0)"] -polly = ["mypy-boto3-polly (>=1.42.0,<1.43.0)"] -pricing = ["mypy-boto3-pricing (>=1.42.0,<1.43.0)"] -proton = ["mypy-boto3-proton (>=1.42.0,<1.43.0)"] -qapps = ["mypy-boto3-qapps (>=1.42.0,<1.43.0)"] -qbusiness = ["mypy-boto3-qbusiness (>=1.42.0,<1.43.0)"] -qconnect = ["mypy-boto3-qconnect (>=1.42.0,<1.43.0)"] -quicksight = ["mypy-boto3-quicksight (>=1.42.0,<1.43.0)"] -ram = ["mypy-boto3-ram (>=1.42.0,<1.43.0)"] -rbin = ["mypy-boto3-rbin (>=1.42.0,<1.43.0)"] -rds = ["mypy-boto3-rds (>=1.42.0,<1.43.0)"] -rds-data = ["mypy-boto3-rds-data (>=1.42.0,<1.43.0)"] -redshift = ["mypy-boto3-redshift (>=1.42.0,<1.43.0)"] -redshift-data = ["mypy-boto3-redshift-data (>=1.42.0,<1.43.0)"] -redshift-serverless = ["mypy-boto3-redshift-serverless (>=1.42.0,<1.43.0)"] -rekognition = ["mypy-boto3-rekognition (>=1.42.0,<1.43.0)"] -repostspace = ["mypy-boto3-repostspace (>=1.42.0,<1.43.0)"] -resiliencehub = ["mypy-boto3-resiliencehub (>=1.42.0,<1.43.0)"] -resource-explorer-2 = ["mypy-boto3-resource-explorer-2 (>=1.42.0,<1.43.0)"] -resource-groups = ["mypy-boto3-resource-groups (>=1.42.0,<1.43.0)"] -resourcegroupstaggingapi = ["mypy-boto3-resourcegroupstaggingapi (>=1.42.0,<1.43.0)"] -rolesanywhere = ["mypy-boto3-rolesanywhere (>=1.42.0,<1.43.0)"] -route53 = ["mypy-boto3-route53 (>=1.42.0,<1.43.0)"] -route53-recovery-cluster = ["mypy-boto3-route53-recovery-cluster (>=1.42.0,<1.43.0)"] -route53-recovery-control-config = ["mypy-boto3-route53-recovery-control-config (>=1.42.0,<1.43.0)"] -route53-recovery-readiness = ["mypy-boto3-route53-recovery-readiness (>=1.42.0,<1.43.0)"] -route53domains = ["mypy-boto3-route53domains (>=1.42.0,<1.43.0)"] -route53globalresolver = ["mypy-boto3-route53globalresolver (>=1.42.0,<1.43.0)"] -route53profiles = ["mypy-boto3-route53profiles (>=1.42.0,<1.43.0)"] -route53resolver = ["mypy-boto3-route53resolver (>=1.42.0,<1.43.0)"] -rtbfabric = ["mypy-boto3-rtbfabric (>=1.42.0,<1.43.0)"] -rum = ["mypy-boto3-rum (>=1.42.0,<1.43.0)"] -s3 = ["mypy-boto3-s3 (>=1.42.0,<1.43.0)"] -s3control = ["mypy-boto3-s3control (>=1.42.0,<1.43.0)"] -s3outposts = ["mypy-boto3-s3outposts (>=1.42.0,<1.43.0)"] -s3tables = ["mypy-boto3-s3tables (>=1.42.0,<1.43.0)"] -s3vectors = ["mypy-boto3-s3vectors (>=1.42.0,<1.43.0)"] -sagemaker = ["mypy-boto3-sagemaker (>=1.42.0,<1.43.0)"] -sagemaker-a2i-runtime = ["mypy-boto3-sagemaker-a2i-runtime (>=1.42.0,<1.43.0)"] -sagemaker-edge = ["mypy-boto3-sagemaker-edge (>=1.42.0,<1.43.0)"] -sagemaker-featurestore-runtime = ["mypy-boto3-sagemaker-featurestore-runtime (>=1.42.0,<1.43.0)"] -sagemaker-geospatial = ["mypy-boto3-sagemaker-geospatial (>=1.42.0,<1.43.0)"] -sagemaker-metrics = ["mypy-boto3-sagemaker-metrics (>=1.42.0,<1.43.0)"] -sagemaker-runtime = ["mypy-boto3-sagemaker-runtime (>=1.42.0,<1.43.0)"] -savingsplans = ["mypy-boto3-savingsplans (>=1.42.0,<1.43.0)"] -scheduler = ["mypy-boto3-scheduler (>=1.42.0,<1.43.0)"] -schemas = ["mypy-boto3-schemas (>=1.42.0,<1.43.0)"] -sdb = ["mypy-boto3-sdb (>=1.42.0,<1.43.0)"] -secretsmanager = ["mypy-boto3-secretsmanager (>=1.42.0,<1.43.0)"] -security-ir = ["mypy-boto3-security-ir (>=1.42.0,<1.43.0)"] -securityhub = ["mypy-boto3-securityhub (>=1.42.0,<1.43.0)"] -securitylake = ["mypy-boto3-securitylake (>=1.42.0,<1.43.0)"] -serverlessrepo = ["mypy-boto3-serverlessrepo (>=1.42.0,<1.43.0)"] -service-quotas = ["mypy-boto3-service-quotas (>=1.42.0,<1.43.0)"] -servicecatalog = ["mypy-boto3-servicecatalog (>=1.42.0,<1.43.0)"] -servicecatalog-appregistry = ["mypy-boto3-servicecatalog-appregistry (>=1.42.0,<1.43.0)"] -servicediscovery = ["mypy-boto3-servicediscovery (>=1.42.0,<1.43.0)"] -ses = ["mypy-boto3-ses (>=1.42.0,<1.43.0)"] -sesv2 = ["mypy-boto3-sesv2 (>=1.42.0,<1.43.0)"] -shield = ["mypy-boto3-shield (>=1.42.0,<1.43.0)"] -signer = ["mypy-boto3-signer (>=1.42.0,<1.43.0)"] -signer-data = ["mypy-boto3-signer-data (>=1.42.0,<1.43.0)"] -signin = ["mypy-boto3-signin (>=1.42.0,<1.43.0)"] -simpledbv2 = ["mypy-boto3-simpledbv2 (>=1.42.0,<1.43.0)"] -simspaceweaver = ["mypy-boto3-simspaceweaver (>=1.42.0,<1.43.0)"] -snow-device-management = ["mypy-boto3-snow-device-management (>=1.42.0,<1.43.0)"] -snowball = ["mypy-boto3-snowball (>=1.42.0,<1.43.0)"] -sns = ["mypy-boto3-sns (>=1.42.0,<1.43.0)"] -socialmessaging = ["mypy-boto3-socialmessaging (>=1.42.0,<1.43.0)"] -sqs = ["mypy-boto3-sqs (>=1.42.0,<1.43.0)"] -ssm = ["mypy-boto3-ssm (>=1.42.0,<1.43.0)"] -ssm-contacts = ["mypy-boto3-ssm-contacts (>=1.42.0,<1.43.0)"] -ssm-guiconnect = ["mypy-boto3-ssm-guiconnect (>=1.42.0,<1.43.0)"] -ssm-incidents = ["mypy-boto3-ssm-incidents (>=1.42.0,<1.43.0)"] -ssm-quicksetup = ["mypy-boto3-ssm-quicksetup (>=1.42.0,<1.43.0)"] -ssm-sap = ["mypy-boto3-ssm-sap (>=1.42.0,<1.43.0)"] -sso = ["mypy-boto3-sso (>=1.42.0,<1.43.0)"] -sso-admin = ["mypy-boto3-sso-admin (>=1.42.0,<1.43.0)"] -sso-oidc = ["mypy-boto3-sso-oidc (>=1.42.0,<1.43.0)"] -stepfunctions = ["mypy-boto3-stepfunctions (>=1.42.0,<1.43.0)"] -storagegateway = ["mypy-boto3-storagegateway (>=1.42.0,<1.43.0)"] -sts = ["mypy-boto3-sts (>=1.42.0,<1.43.0)"] -supplychain = ["mypy-boto3-supplychain (>=1.42.0,<1.43.0)"] -support = ["mypy-boto3-support (>=1.42.0,<1.43.0)"] -support-app = ["mypy-boto3-support-app (>=1.42.0,<1.43.0)"] -swf = ["mypy-boto3-swf (>=1.42.0,<1.43.0)"] -synthetics = ["mypy-boto3-synthetics (>=1.42.0,<1.43.0)"] -taxsettings = ["mypy-boto3-taxsettings (>=1.42.0,<1.43.0)"] -textract = ["mypy-boto3-textract (>=1.42.0,<1.43.0)"] -timestream-influxdb = ["mypy-boto3-timestream-influxdb (>=1.42.0,<1.43.0)"] -timestream-query = ["mypy-boto3-timestream-query (>=1.42.0,<1.43.0)"] -timestream-write = ["mypy-boto3-timestream-write (>=1.42.0,<1.43.0)"] -tnb = ["mypy-boto3-tnb (>=1.42.0,<1.43.0)"] -transcribe = ["mypy-boto3-transcribe (>=1.42.0,<1.43.0)"] -transfer = ["mypy-boto3-transfer (>=1.42.0,<1.43.0)"] -translate = ["mypy-boto3-translate (>=1.42.0,<1.43.0)"] -trustedadvisor = ["mypy-boto3-trustedadvisor (>=1.42.0,<1.43.0)"] -verifiedpermissions = ["mypy-boto3-verifiedpermissions (>=1.42.0,<1.43.0)"] -voice-id = ["mypy-boto3-voice-id (>=1.42.0,<1.43.0)"] -vpc-lattice = ["mypy-boto3-vpc-lattice (>=1.42.0,<1.43.0)"] -waf = ["mypy-boto3-waf (>=1.42.0,<1.43.0)"] -waf-regional = ["mypy-boto3-waf-regional (>=1.42.0,<1.43.0)"] -wafv2 = ["mypy-boto3-wafv2 (>=1.42.0,<1.43.0)"] -wellarchitected = ["mypy-boto3-wellarchitected (>=1.42.0,<1.43.0)"] -wickr = ["mypy-boto3-wickr (>=1.42.0,<1.43.0)"] -wisdom = ["mypy-boto3-wisdom (>=1.42.0,<1.43.0)"] -workdocs = ["mypy-boto3-workdocs (>=1.42.0,<1.43.0)"] -workmail = ["mypy-boto3-workmail (>=1.42.0,<1.43.0)"] -workmailmessageflow = ["mypy-boto3-workmailmessageflow (>=1.42.0,<1.43.0)"] -workspaces = ["mypy-boto3-workspaces (>=1.42.0,<1.43.0)"] -workspaces-instances = ["mypy-boto3-workspaces-instances (>=1.42.0,<1.43.0)"] -workspaces-thin-client = ["mypy-boto3-workspaces-thin-client (>=1.42.0,<1.43.0)"] -workspaces-web = ["mypy-boto3-workspaces-web (>=1.42.0,<1.43.0)"] -xray = ["mypy-boto3-xray (>=1.42.0,<1.43.0)"] +accessanalyzer = ["mypy-boto3-accessanalyzer (>=1.43.0,<1.44.0)"] +account = ["mypy-boto3-account (>=1.43.0,<1.44.0)"] +acm = ["mypy-boto3-acm (>=1.43.0,<1.44.0)"] +acm-pca = ["mypy-boto3-acm-pca (>=1.43.0,<1.44.0)"] +aiops = ["mypy-boto3-aiops (>=1.43.0,<1.44.0)"] +all = ["mypy-boto3-accessanalyzer (>=1.43.0,<1.44.0)", "mypy-boto3-account (>=1.43.0,<1.44.0)", "mypy-boto3-acm (>=1.43.0,<1.44.0)", "mypy-boto3-acm-pca (>=1.43.0,<1.44.0)", "mypy-boto3-aiops (>=1.43.0,<1.44.0)", "mypy-boto3-amp (>=1.43.0,<1.44.0)", "mypy-boto3-amplify (>=1.43.0,<1.44.0)", "mypy-boto3-amplifybackend (>=1.43.0,<1.44.0)", "mypy-boto3-amplifyuibuilder (>=1.43.0,<1.44.0)", "mypy-boto3-apigateway (>=1.43.0,<1.44.0)", "mypy-boto3-apigatewaymanagementapi (>=1.43.0,<1.44.0)", "mypy-boto3-apigatewayv2 (>=1.43.0,<1.44.0)", "mypy-boto3-appconfig (>=1.43.0,<1.44.0)", "mypy-boto3-appconfigdata (>=1.43.0,<1.44.0)", "mypy-boto3-appfabric (>=1.43.0,<1.44.0)", "mypy-boto3-appflow (>=1.43.0,<1.44.0)", "mypy-boto3-appintegrations (>=1.43.0,<1.44.0)", "mypy-boto3-application-autoscaling (>=1.43.0,<1.44.0)", "mypy-boto3-application-insights (>=1.43.0,<1.44.0)", "mypy-boto3-application-signals (>=1.43.0,<1.44.0)", "mypy-boto3-applicationcostprofiler (>=1.43.0,<1.44.0)", "mypy-boto3-appmesh (>=1.43.0,<1.44.0)", "mypy-boto3-apprunner (>=1.43.0,<1.44.0)", "mypy-boto3-appstream (>=1.43.0,<1.44.0)", "mypy-boto3-appsync (>=1.43.0,<1.44.0)", "mypy-boto3-arc-region-switch (>=1.43.0,<1.44.0)", "mypy-boto3-arc-zonal-shift (>=1.43.0,<1.44.0)", "mypy-boto3-artifact (>=1.43.0,<1.44.0)", "mypy-boto3-athena (>=1.43.0,<1.44.0)", "mypy-boto3-auditmanager (>=1.43.0,<1.44.0)", "mypy-boto3-autoscaling (>=1.43.0,<1.44.0)", "mypy-boto3-autoscaling-plans (>=1.43.0,<1.44.0)", "mypy-boto3-b2bi (>=1.43.0,<1.44.0)", "mypy-boto3-backup (>=1.43.0,<1.44.0)", "mypy-boto3-backup-gateway (>=1.43.0,<1.44.0)", "mypy-boto3-backupsearch (>=1.43.0,<1.44.0)", "mypy-boto3-batch (>=1.43.0,<1.44.0)", "mypy-boto3-bcm-dashboards (>=1.43.0,<1.44.0)", "mypy-boto3-bcm-data-exports (>=1.43.0,<1.44.0)", "mypy-boto3-bcm-pricing-calculator (>=1.43.0,<1.44.0)", "mypy-boto3-bcm-recommended-actions (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-agent (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-agent-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-agentcore (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-agentcore-control (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-data-automation (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-data-automation-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-bedrock-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-billing (>=1.43.0,<1.44.0)", "mypy-boto3-billingconductor (>=1.43.0,<1.44.0)", "mypy-boto3-braket (>=1.43.0,<1.44.0)", "mypy-boto3-budgets (>=1.43.0,<1.44.0)", "mypy-boto3-ce (>=1.43.0,<1.44.0)", "mypy-boto3-chatbot (>=1.43.0,<1.44.0)", "mypy-boto3-chime (>=1.43.0,<1.44.0)", "mypy-boto3-chime-sdk-identity (>=1.43.0,<1.44.0)", "mypy-boto3-chime-sdk-media-pipelines (>=1.43.0,<1.44.0)", "mypy-boto3-chime-sdk-meetings (>=1.43.0,<1.44.0)", "mypy-boto3-chime-sdk-messaging (>=1.43.0,<1.44.0)", "mypy-boto3-chime-sdk-voice (>=1.43.0,<1.44.0)", "mypy-boto3-cleanrooms (>=1.43.0,<1.44.0)", "mypy-boto3-cleanroomsml (>=1.43.0,<1.44.0)", "mypy-boto3-cloud9 (>=1.43.0,<1.44.0)", "mypy-boto3-cloudcontrol (>=1.43.0,<1.44.0)", "mypy-boto3-clouddirectory (>=1.43.0,<1.44.0)", "mypy-boto3-cloudformation (>=1.43.0,<1.44.0)", "mypy-boto3-cloudfront (>=1.43.0,<1.44.0)", "mypy-boto3-cloudfront-keyvaluestore (>=1.43.0,<1.44.0)", "mypy-boto3-cloudhsm (>=1.43.0,<1.44.0)", "mypy-boto3-cloudhsmv2 (>=1.43.0,<1.44.0)", "mypy-boto3-cloudsearch (>=1.43.0,<1.44.0)", "mypy-boto3-cloudsearchdomain (>=1.43.0,<1.44.0)", "mypy-boto3-cloudtrail (>=1.43.0,<1.44.0)", "mypy-boto3-cloudtrail-data (>=1.43.0,<1.44.0)", "mypy-boto3-cloudwatch (>=1.43.0,<1.44.0)", "mypy-boto3-codeartifact (>=1.43.0,<1.44.0)", "mypy-boto3-codebuild (>=1.43.0,<1.44.0)", "mypy-boto3-codecatalyst (>=1.43.0,<1.44.0)", "mypy-boto3-codecommit (>=1.43.0,<1.44.0)", "mypy-boto3-codeconnections (>=1.43.0,<1.44.0)", "mypy-boto3-codedeploy (>=1.43.0,<1.44.0)", "mypy-boto3-codeguru-reviewer (>=1.43.0,<1.44.0)", "mypy-boto3-codeguru-security (>=1.43.0,<1.44.0)", "mypy-boto3-codeguruprofiler (>=1.43.0,<1.44.0)", "mypy-boto3-codepipeline (>=1.43.0,<1.44.0)", "mypy-boto3-codestar-connections (>=1.43.0,<1.44.0)", "mypy-boto3-codestar-notifications (>=1.43.0,<1.44.0)", "mypy-boto3-cognito-identity (>=1.43.0,<1.44.0)", "mypy-boto3-cognito-idp (>=1.43.0,<1.44.0)", "mypy-boto3-cognito-sync (>=1.43.0,<1.44.0)", "mypy-boto3-comprehend (>=1.43.0,<1.44.0)", "mypy-boto3-comprehendmedical (>=1.43.0,<1.44.0)", "mypy-boto3-compute-optimizer (>=1.43.0,<1.44.0)", "mypy-boto3-compute-optimizer-automation (>=1.43.0,<1.44.0)", "mypy-boto3-config (>=1.43.0,<1.44.0)", "mypy-boto3-connect (>=1.43.0,<1.44.0)", "mypy-boto3-connect-contact-lens (>=1.43.0,<1.44.0)", "mypy-boto3-connectcampaigns (>=1.43.0,<1.44.0)", "mypy-boto3-connectcampaignsv2 (>=1.43.0,<1.44.0)", "mypy-boto3-connectcases (>=1.43.0,<1.44.0)", "mypy-boto3-connecthealth (>=1.43.0,<1.44.0)", "mypy-boto3-connectparticipant (>=1.43.0,<1.44.0)", "mypy-boto3-controlcatalog (>=1.43.0,<1.44.0)", "mypy-boto3-controltower (>=1.43.0,<1.44.0)", "mypy-boto3-cost-optimization-hub (>=1.43.0,<1.44.0)", "mypy-boto3-cur (>=1.43.0,<1.44.0)", "mypy-boto3-customer-profiles (>=1.43.0,<1.44.0)", "mypy-boto3-databrew (>=1.43.0,<1.44.0)", "mypy-boto3-dataexchange (>=1.43.0,<1.44.0)", "mypy-boto3-datapipeline (>=1.43.0,<1.44.0)", "mypy-boto3-datasync (>=1.43.0,<1.44.0)", "mypy-boto3-datazone (>=1.43.0,<1.44.0)", "mypy-boto3-dax (>=1.43.0,<1.44.0)", "mypy-boto3-deadline (>=1.43.0,<1.44.0)", "mypy-boto3-detective (>=1.43.0,<1.44.0)", "mypy-boto3-devicefarm (>=1.43.0,<1.44.0)", "mypy-boto3-devops-agent (>=1.43.0,<1.44.0)", "mypy-boto3-devops-guru (>=1.43.0,<1.44.0)", "mypy-boto3-directconnect (>=1.43.0,<1.44.0)", "mypy-boto3-discovery (>=1.43.0,<1.44.0)", "mypy-boto3-dlm (>=1.43.0,<1.44.0)", "mypy-boto3-dms (>=1.43.0,<1.44.0)", "mypy-boto3-docdb (>=1.43.0,<1.44.0)", "mypy-boto3-docdb-elastic (>=1.43.0,<1.44.0)", "mypy-boto3-drs (>=1.43.0,<1.44.0)", "mypy-boto3-ds (>=1.43.0,<1.44.0)", "mypy-boto3-ds-data (>=1.43.0,<1.44.0)", "mypy-boto3-dsql (>=1.43.0,<1.44.0)", "mypy-boto3-dynamodb (>=1.43.0,<1.44.0)", "mypy-boto3-dynamodbstreams (>=1.43.0,<1.44.0)", "mypy-boto3-ebs (>=1.43.0,<1.44.0)", "mypy-boto3-ec2 (>=1.43.0,<1.44.0)", "mypy-boto3-ec2-instance-connect (>=1.43.0,<1.44.0)", "mypy-boto3-ecr (>=1.43.0,<1.44.0)", "mypy-boto3-ecr-public (>=1.43.0,<1.44.0)", "mypy-boto3-ecs (>=1.43.0,<1.44.0)", "mypy-boto3-efs (>=1.43.0,<1.44.0)", "mypy-boto3-eks (>=1.43.0,<1.44.0)", "mypy-boto3-eks-auth (>=1.43.0,<1.44.0)", "mypy-boto3-elasticache (>=1.43.0,<1.44.0)", "mypy-boto3-elasticbeanstalk (>=1.43.0,<1.44.0)", "mypy-boto3-elb (>=1.43.0,<1.44.0)", "mypy-boto3-elbv2 (>=1.43.0,<1.44.0)", "mypy-boto3-elementalinference (>=1.43.0,<1.44.0)", "mypy-boto3-emr (>=1.43.0,<1.44.0)", "mypy-boto3-emr-containers (>=1.43.0,<1.44.0)", "mypy-boto3-emr-serverless (>=1.43.0,<1.44.0)", "mypy-boto3-entityresolution (>=1.43.0,<1.44.0)", "mypy-boto3-es (>=1.43.0,<1.44.0)", "mypy-boto3-events (>=1.43.0,<1.44.0)", "mypy-boto3-evs (>=1.43.0,<1.44.0)", "mypy-boto3-finspace (>=1.43.0,<1.44.0)", "mypy-boto3-finspace-data (>=1.43.0,<1.44.0)", "mypy-boto3-firehose (>=1.43.0,<1.44.0)", "mypy-boto3-fis (>=1.43.0,<1.44.0)", "mypy-boto3-fms (>=1.43.0,<1.44.0)", "mypy-boto3-forecast (>=1.43.0,<1.44.0)", "mypy-boto3-forecastquery (>=1.43.0,<1.44.0)", "mypy-boto3-frauddetector (>=1.43.0,<1.44.0)", "mypy-boto3-freetier (>=1.43.0,<1.44.0)", "mypy-boto3-fsx (>=1.43.0,<1.44.0)", "mypy-boto3-gamelift (>=1.43.0,<1.44.0)", "mypy-boto3-gameliftstreams (>=1.43.0,<1.44.0)", "mypy-boto3-geo-maps (>=1.43.0,<1.44.0)", "mypy-boto3-geo-places (>=1.43.0,<1.44.0)", "mypy-boto3-geo-routes (>=1.43.0,<1.44.0)", "mypy-boto3-glacier (>=1.43.0,<1.44.0)", "mypy-boto3-globalaccelerator (>=1.43.0,<1.44.0)", "mypy-boto3-glue (>=1.43.0,<1.44.0)", "mypy-boto3-grafana (>=1.43.0,<1.44.0)", "mypy-boto3-greengrass (>=1.43.0,<1.44.0)", "mypy-boto3-greengrassv2 (>=1.43.0,<1.44.0)", "mypy-boto3-groundstation (>=1.43.0,<1.44.0)", "mypy-boto3-guardduty (>=1.43.0,<1.44.0)", "mypy-boto3-health (>=1.43.0,<1.44.0)", "mypy-boto3-healthlake (>=1.43.0,<1.44.0)", "mypy-boto3-iam (>=1.43.0,<1.44.0)", "mypy-boto3-identitystore (>=1.43.0,<1.44.0)", "mypy-boto3-imagebuilder (>=1.43.0,<1.44.0)", "mypy-boto3-importexport (>=1.43.0,<1.44.0)", "mypy-boto3-inspector (>=1.43.0,<1.44.0)", "mypy-boto3-inspector-scan (>=1.43.0,<1.44.0)", "mypy-boto3-inspector2 (>=1.43.0,<1.44.0)", "mypy-boto3-interconnect (>=1.43.0,<1.44.0)", "mypy-boto3-internetmonitor (>=1.43.0,<1.44.0)", "mypy-boto3-invoicing (>=1.43.0,<1.44.0)", "mypy-boto3-iot (>=1.43.0,<1.44.0)", "mypy-boto3-iot-data (>=1.43.0,<1.44.0)", "mypy-boto3-iot-jobs-data (>=1.43.0,<1.44.0)", "mypy-boto3-iot-managed-integrations (>=1.43.0,<1.44.0)", "mypy-boto3-iotdeviceadvisor (>=1.43.0,<1.44.0)", "mypy-boto3-iotevents (>=1.43.0,<1.44.0)", "mypy-boto3-iotevents-data (>=1.43.0,<1.44.0)", "mypy-boto3-iotfleetwise (>=1.43.0,<1.44.0)", "mypy-boto3-iotsecuretunneling (>=1.43.0,<1.44.0)", "mypy-boto3-iotsitewise (>=1.43.0,<1.44.0)", "mypy-boto3-iotthingsgraph (>=1.43.0,<1.44.0)", "mypy-boto3-iottwinmaker (>=1.43.0,<1.44.0)", "mypy-boto3-iotwireless (>=1.43.0,<1.44.0)", "mypy-boto3-ivs (>=1.43.0,<1.44.0)", "mypy-boto3-ivs-realtime (>=1.43.0,<1.44.0)", "mypy-boto3-ivschat (>=1.43.0,<1.44.0)", "mypy-boto3-kafka (>=1.43.0,<1.44.0)", "mypy-boto3-kafkaconnect (>=1.43.0,<1.44.0)", "mypy-boto3-kendra (>=1.43.0,<1.44.0)", "mypy-boto3-kendra-ranking (>=1.43.0,<1.44.0)", "mypy-boto3-keyspaces (>=1.43.0,<1.44.0)", "mypy-boto3-keyspacesstreams (>=1.43.0,<1.44.0)", "mypy-boto3-kinesis (>=1.43.0,<1.44.0)", "mypy-boto3-kinesis-video-archived-media (>=1.43.0,<1.44.0)", "mypy-boto3-kinesis-video-media (>=1.43.0,<1.44.0)", "mypy-boto3-kinesis-video-signaling (>=1.43.0,<1.44.0)", "mypy-boto3-kinesis-video-webrtc-storage (>=1.43.0,<1.44.0)", "mypy-boto3-kinesisanalytics (>=1.43.0,<1.44.0)", "mypy-boto3-kinesisanalyticsv2 (>=1.43.0,<1.44.0)", "mypy-boto3-kinesisvideo (>=1.43.0,<1.44.0)", "mypy-boto3-kms (>=1.43.0,<1.44.0)", "mypy-boto3-lakeformation (>=1.43.0,<1.44.0)", "mypy-boto3-lambda (>=1.43.0,<1.44.0)", "mypy-boto3-launch-wizard (>=1.43.0,<1.44.0)", "mypy-boto3-lex-models (>=1.43.0,<1.44.0)", "mypy-boto3-lex-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-lexv2-models (>=1.43.0,<1.44.0)", "mypy-boto3-lexv2-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-license-manager (>=1.43.0,<1.44.0)", "mypy-boto3-license-manager-linux-subscriptions (>=1.43.0,<1.44.0)", "mypy-boto3-license-manager-user-subscriptions (>=1.43.0,<1.44.0)", "mypy-boto3-lightsail (>=1.43.0,<1.44.0)", "mypy-boto3-location (>=1.43.0,<1.44.0)", "mypy-boto3-logs (>=1.43.0,<1.44.0)", "mypy-boto3-lookoutequipment (>=1.43.0,<1.44.0)", "mypy-boto3-m2 (>=1.43.0,<1.44.0)", "mypy-boto3-machinelearning (>=1.43.0,<1.44.0)", "mypy-boto3-macie2 (>=1.43.0,<1.44.0)", "mypy-boto3-mailmanager (>=1.43.0,<1.44.0)", "mypy-boto3-managedblockchain (>=1.43.0,<1.44.0)", "mypy-boto3-managedblockchain-query (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-agreement (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-catalog (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-deployment (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-discovery (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-entitlement (>=1.43.0,<1.44.0)", "mypy-boto3-marketplace-reporting (>=1.43.0,<1.44.0)", "mypy-boto3-marketplacecommerceanalytics (>=1.43.0,<1.44.0)", "mypy-boto3-mediaconnect (>=1.43.0,<1.44.0)", "mypy-boto3-mediaconvert (>=1.43.0,<1.44.0)", "mypy-boto3-medialive (>=1.43.0,<1.44.0)", "mypy-boto3-mediapackage (>=1.43.0,<1.44.0)", "mypy-boto3-mediapackage-vod (>=1.43.0,<1.44.0)", "mypy-boto3-mediapackagev2 (>=1.43.0,<1.44.0)", "mypy-boto3-mediastore (>=1.43.0,<1.44.0)", "mypy-boto3-mediastore-data (>=1.43.0,<1.44.0)", "mypy-boto3-mediatailor (>=1.43.0,<1.44.0)", "mypy-boto3-medical-imaging (>=1.43.0,<1.44.0)", "mypy-boto3-memorydb (>=1.43.0,<1.44.0)", "mypy-boto3-meteringmarketplace (>=1.43.0,<1.44.0)", "mypy-boto3-mgh (>=1.43.0,<1.44.0)", "mypy-boto3-mgn (>=1.43.0,<1.44.0)", "mypy-boto3-migration-hub-refactor-spaces (>=1.43.0,<1.44.0)", "mypy-boto3-migrationhub-config (>=1.43.0,<1.44.0)", "mypy-boto3-migrationhuborchestrator (>=1.43.0,<1.44.0)", "mypy-boto3-migrationhubstrategy (>=1.43.0,<1.44.0)", "mypy-boto3-mpa (>=1.43.0,<1.44.0)", "mypy-boto3-mq (>=1.43.0,<1.44.0)", "mypy-boto3-mturk (>=1.43.0,<1.44.0)", "mypy-boto3-mwaa (>=1.43.0,<1.44.0)", "mypy-boto3-mwaa-serverless (>=1.43.0,<1.44.0)", "mypy-boto3-neptune (>=1.43.0,<1.44.0)", "mypy-boto3-neptune-graph (>=1.43.0,<1.44.0)", "mypy-boto3-neptunedata (>=1.43.0,<1.44.0)", "mypy-boto3-network-firewall (>=1.43.0,<1.44.0)", "mypy-boto3-networkflowmonitor (>=1.43.0,<1.44.0)", "mypy-boto3-networkmanager (>=1.43.0,<1.44.0)", "mypy-boto3-networkmonitor (>=1.43.0,<1.44.0)", "mypy-boto3-notifications (>=1.43.0,<1.44.0)", "mypy-boto3-notificationscontacts (>=1.43.0,<1.44.0)", "mypy-boto3-nova-act (>=1.43.0,<1.44.0)", "mypy-boto3-oam (>=1.43.0,<1.44.0)", "mypy-boto3-observabilityadmin (>=1.43.0,<1.44.0)", "mypy-boto3-odb (>=1.43.0,<1.44.0)", "mypy-boto3-omics (>=1.43.0,<1.44.0)", "mypy-boto3-opensearch (>=1.43.0,<1.44.0)", "mypy-boto3-opensearchserverless (>=1.43.0,<1.44.0)", "mypy-boto3-organizations (>=1.43.0,<1.44.0)", "mypy-boto3-osis (>=1.43.0,<1.44.0)", "mypy-boto3-outposts (>=1.43.0,<1.44.0)", "mypy-boto3-panorama (>=1.43.0,<1.44.0)", "mypy-boto3-partnercentral-account (>=1.43.0,<1.44.0)", "mypy-boto3-partnercentral-benefits (>=1.43.0,<1.44.0)", "mypy-boto3-partnercentral-channel (>=1.43.0,<1.44.0)", "mypy-boto3-partnercentral-selling (>=1.43.0,<1.44.0)", "mypy-boto3-payment-cryptography (>=1.43.0,<1.44.0)", "mypy-boto3-payment-cryptography-data (>=1.43.0,<1.44.0)", "mypy-boto3-pca-connector-ad (>=1.43.0,<1.44.0)", "mypy-boto3-pca-connector-scep (>=1.43.0,<1.44.0)", "mypy-boto3-pcs (>=1.43.0,<1.44.0)", "mypy-boto3-personalize (>=1.43.0,<1.44.0)", "mypy-boto3-personalize-events (>=1.43.0,<1.44.0)", "mypy-boto3-personalize-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-pi (>=1.43.0,<1.44.0)", "mypy-boto3-pinpoint (>=1.43.0,<1.44.0)", "mypy-boto3-pinpoint-email (>=1.43.0,<1.44.0)", "mypy-boto3-pinpoint-sms-voice (>=1.43.0,<1.44.0)", "mypy-boto3-pinpoint-sms-voice-v2 (>=1.43.0,<1.44.0)", "mypy-boto3-pipes (>=1.43.0,<1.44.0)", "mypy-boto3-polly (>=1.43.0,<1.44.0)", "mypy-boto3-pricing (>=1.43.0,<1.44.0)", "mypy-boto3-proton (>=1.43.0,<1.44.0)", "mypy-boto3-qapps (>=1.43.0,<1.44.0)", "mypy-boto3-qbusiness (>=1.43.0,<1.44.0)", "mypy-boto3-qconnect (>=1.43.0,<1.44.0)", "mypy-boto3-quicksight (>=1.43.0,<1.44.0)", "mypy-boto3-ram (>=1.43.0,<1.44.0)", "mypy-boto3-rbin (>=1.43.0,<1.44.0)", "mypy-boto3-rds (>=1.43.0,<1.44.0)", "mypy-boto3-rds-data (>=1.43.0,<1.44.0)", "mypy-boto3-redshift (>=1.43.0,<1.44.0)", "mypy-boto3-redshift-data (>=1.43.0,<1.44.0)", "mypy-boto3-redshift-serverless (>=1.43.0,<1.44.0)", "mypy-boto3-rekognition (>=1.43.0,<1.44.0)", "mypy-boto3-repostspace (>=1.43.0,<1.44.0)", "mypy-boto3-resiliencehub (>=1.43.0,<1.44.0)", "mypy-boto3-resiliencehubv2 (>=1.43.0,<1.44.0)", "mypy-boto3-resource-explorer-2 (>=1.43.0,<1.44.0)", "mypy-boto3-resource-groups (>=1.43.0,<1.44.0)", "mypy-boto3-resourcegroupstaggingapi (>=1.43.0,<1.44.0)", "mypy-boto3-rolesanywhere (>=1.43.0,<1.44.0)", "mypy-boto3-route53 (>=1.43.0,<1.44.0)", "mypy-boto3-route53-recovery-cluster (>=1.43.0,<1.44.0)", "mypy-boto3-route53-recovery-control-config (>=1.43.0,<1.44.0)", "mypy-boto3-route53-recovery-readiness (>=1.43.0,<1.44.0)", "mypy-boto3-route53domains (>=1.43.0,<1.44.0)", "mypy-boto3-route53globalresolver (>=1.43.0,<1.44.0)", "mypy-boto3-route53profiles (>=1.43.0,<1.44.0)", "mypy-boto3-route53resolver (>=1.43.0,<1.44.0)", "mypy-boto3-rtbfabric (>=1.43.0,<1.44.0)", "mypy-boto3-rum (>=1.43.0,<1.44.0)", "mypy-boto3-s3 (>=1.43.0,<1.44.0)", "mypy-boto3-s3control (>=1.43.0,<1.44.0)", "mypy-boto3-s3files (>=1.43.0,<1.44.0)", "mypy-boto3-s3outposts (>=1.43.0,<1.44.0)", "mypy-boto3-s3tables (>=1.43.0,<1.44.0)", "mypy-boto3-s3vectors (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-a2i-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-edge (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-featurestore-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-geospatial (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-metrics (>=1.43.0,<1.44.0)", "mypy-boto3-sagemaker-runtime (>=1.43.0,<1.44.0)", "mypy-boto3-sagemakerjobruntime (>=1.43.0,<1.44.0)", "mypy-boto3-savingsplans (>=1.43.0,<1.44.0)", "mypy-boto3-scheduler (>=1.43.0,<1.44.0)", "mypy-boto3-schemas (>=1.43.0,<1.44.0)", "mypy-boto3-sdb (>=1.43.0,<1.44.0)", "mypy-boto3-secretsmanager (>=1.43.0,<1.44.0)", "mypy-boto3-security-ir (>=1.43.0,<1.44.0)", "mypy-boto3-securityagent (>=1.43.0,<1.44.0)", "mypy-boto3-securityhub (>=1.43.0,<1.44.0)", "mypy-boto3-securitylake (>=1.43.0,<1.44.0)", "mypy-boto3-serverlessrepo (>=1.43.0,<1.44.0)", "mypy-boto3-service-quotas (>=1.43.0,<1.44.0)", "mypy-boto3-servicecatalog (>=1.43.0,<1.44.0)", "mypy-boto3-servicecatalog-appregistry (>=1.43.0,<1.44.0)", "mypy-boto3-servicediscovery (>=1.43.0,<1.44.0)", "mypy-boto3-ses (>=1.43.0,<1.44.0)", "mypy-boto3-sesv2 (>=1.43.0,<1.44.0)", "mypy-boto3-shield (>=1.43.0,<1.44.0)", "mypy-boto3-signer (>=1.43.0,<1.44.0)", "mypy-boto3-signer-data (>=1.43.0,<1.44.0)", "mypy-boto3-signin (>=1.43.0,<1.44.0)", "mypy-boto3-simpledbv2 (>=1.43.0,<1.44.0)", "mypy-boto3-simspaceweaver (>=1.43.0,<1.44.0)", "mypy-boto3-snow-device-management (>=1.43.0,<1.44.0)", "mypy-boto3-snowball (>=1.43.0,<1.44.0)", "mypy-boto3-sns (>=1.43.0,<1.44.0)", "mypy-boto3-socialmessaging (>=1.43.0,<1.44.0)", "mypy-boto3-sqs (>=1.43.0,<1.44.0)", "mypy-boto3-ssm (>=1.43.0,<1.44.0)", "mypy-boto3-ssm-contacts (>=1.43.0,<1.44.0)", "mypy-boto3-ssm-guiconnect (>=1.43.0,<1.44.0)", "mypy-boto3-ssm-incidents (>=1.43.0,<1.44.0)", "mypy-boto3-ssm-quicksetup (>=1.43.0,<1.44.0)", "mypy-boto3-ssm-sap (>=1.43.0,<1.44.0)", "mypy-boto3-sso (>=1.43.0,<1.44.0)", "mypy-boto3-sso-admin (>=1.43.0,<1.44.0)", "mypy-boto3-sso-oidc (>=1.43.0,<1.44.0)", "mypy-boto3-stepfunctions (>=1.43.0,<1.44.0)", "mypy-boto3-storagegateway (>=1.43.0,<1.44.0)", "mypy-boto3-sts (>=1.43.0,<1.44.0)", "mypy-boto3-supplychain (>=1.43.0,<1.44.0)", "mypy-boto3-support (>=1.43.0,<1.44.0)", "mypy-boto3-support-app (>=1.43.0,<1.44.0)", "mypy-boto3-sustainability (>=1.43.0,<1.44.0)", "mypy-boto3-swf (>=1.43.0,<1.44.0)", "mypy-boto3-synthetics (>=1.43.0,<1.44.0)", "mypy-boto3-taxsettings (>=1.43.0,<1.44.0)", "mypy-boto3-textract (>=1.43.0,<1.44.0)", "mypy-boto3-timestream-influxdb (>=1.43.0,<1.44.0)", "mypy-boto3-timestream-query (>=1.43.0,<1.44.0)", "mypy-boto3-timestream-write (>=1.43.0,<1.44.0)", "mypy-boto3-tnb (>=1.43.0,<1.44.0)", "mypy-boto3-transcribe (>=1.43.0,<1.44.0)", "mypy-boto3-transfer (>=1.43.0,<1.44.0)", "mypy-boto3-translate (>=1.43.0,<1.44.0)", "mypy-boto3-trustedadvisor (>=1.43.0,<1.44.0)", "mypy-boto3-uxc (>=1.43.0,<1.44.0)", "mypy-boto3-verifiedpermissions (>=1.43.0,<1.44.0)", "mypy-boto3-voice-id (>=1.43.0,<1.44.0)", "mypy-boto3-vpc-lattice (>=1.43.0,<1.44.0)", "mypy-boto3-waf (>=1.43.0,<1.44.0)", "mypy-boto3-waf-regional (>=1.43.0,<1.44.0)", "mypy-boto3-wafv2 (>=1.43.0,<1.44.0)", "mypy-boto3-wellarchitected (>=1.43.0,<1.44.0)", "mypy-boto3-wickr (>=1.43.0,<1.44.0)", "mypy-boto3-wisdom (>=1.43.0,<1.44.0)", "mypy-boto3-workdocs (>=1.43.0,<1.44.0)", "mypy-boto3-workmail (>=1.43.0,<1.44.0)", "mypy-boto3-workmailmessageflow (>=1.43.0,<1.44.0)", "mypy-boto3-workspaces (>=1.43.0,<1.44.0)", "mypy-boto3-workspaces-instances (>=1.43.0,<1.44.0)", "mypy-boto3-workspaces-thin-client (>=1.43.0,<1.44.0)", "mypy-boto3-workspaces-web (>=1.43.0,<1.44.0)", "mypy-boto3-xray (>=1.43.0,<1.44.0)"] +amp = ["mypy-boto3-amp (>=1.43.0,<1.44.0)"] +amplify = ["mypy-boto3-amplify (>=1.43.0,<1.44.0)"] +amplifybackend = ["mypy-boto3-amplifybackend (>=1.43.0,<1.44.0)"] +amplifyuibuilder = ["mypy-boto3-amplifyuibuilder (>=1.43.0,<1.44.0)"] +apigateway = ["mypy-boto3-apigateway (>=1.43.0,<1.44.0)"] +apigatewaymanagementapi = ["mypy-boto3-apigatewaymanagementapi (>=1.43.0,<1.44.0)"] +apigatewayv2 = ["mypy-boto3-apigatewayv2 (>=1.43.0,<1.44.0)"] +appconfig = ["mypy-boto3-appconfig (>=1.43.0,<1.44.0)"] +appconfigdata = ["mypy-boto3-appconfigdata (>=1.43.0,<1.44.0)"] +appfabric = ["mypy-boto3-appfabric (>=1.43.0,<1.44.0)"] +appflow = ["mypy-boto3-appflow (>=1.43.0,<1.44.0)"] +appintegrations = ["mypy-boto3-appintegrations (>=1.43.0,<1.44.0)"] +application-autoscaling = ["mypy-boto3-application-autoscaling (>=1.43.0,<1.44.0)"] +application-insights = ["mypy-boto3-application-insights (>=1.43.0,<1.44.0)"] +application-signals = ["mypy-boto3-application-signals (>=1.43.0,<1.44.0)"] +applicationcostprofiler = ["mypy-boto3-applicationcostprofiler (>=1.43.0,<1.44.0)"] +appmesh = ["mypy-boto3-appmesh (>=1.43.0,<1.44.0)"] +apprunner = ["mypy-boto3-apprunner (>=1.43.0,<1.44.0)"] +appstream = ["mypy-boto3-appstream (>=1.43.0,<1.44.0)"] +appsync = ["mypy-boto3-appsync (>=1.43.0,<1.44.0)"] +arc-region-switch = ["mypy-boto3-arc-region-switch (>=1.43.0,<1.44.0)"] +arc-zonal-shift = ["mypy-boto3-arc-zonal-shift (>=1.43.0,<1.44.0)"] +artifact = ["mypy-boto3-artifact (>=1.43.0,<1.44.0)"] +athena = ["mypy-boto3-athena (>=1.43.0,<1.44.0)"] +auditmanager = ["mypy-boto3-auditmanager (>=1.43.0,<1.44.0)"] +autoscaling = ["mypy-boto3-autoscaling (>=1.43.0,<1.44.0)"] +autoscaling-plans = ["mypy-boto3-autoscaling-plans (>=1.43.0,<1.44.0)"] +b2bi = ["mypy-boto3-b2bi (>=1.43.0,<1.44.0)"] +backup = ["mypy-boto3-backup (>=1.43.0,<1.44.0)"] +backup-gateway = ["mypy-boto3-backup-gateway (>=1.43.0,<1.44.0)"] +backupsearch = ["mypy-boto3-backupsearch (>=1.43.0,<1.44.0)"] +batch = ["mypy-boto3-batch (>=1.43.0,<1.44.0)"] +bcm-dashboards = ["mypy-boto3-bcm-dashboards (>=1.43.0,<1.44.0)"] +bcm-data-exports = ["mypy-boto3-bcm-data-exports (>=1.43.0,<1.44.0)"] +bcm-pricing-calculator = ["mypy-boto3-bcm-pricing-calculator (>=1.43.0,<1.44.0)"] +bcm-recommended-actions = ["mypy-boto3-bcm-recommended-actions (>=1.43.0,<1.44.0)"] +bedrock = ["mypy-boto3-bedrock (>=1.43.0,<1.44.0)"] +bedrock-agent = ["mypy-boto3-bedrock-agent (>=1.43.0,<1.44.0)"] +bedrock-agent-runtime = ["mypy-boto3-bedrock-agent-runtime (>=1.43.0,<1.44.0)"] +bedrock-agentcore = ["mypy-boto3-bedrock-agentcore (>=1.43.0,<1.44.0)"] +bedrock-agentcore-control = ["mypy-boto3-bedrock-agentcore-control (>=1.43.0,<1.44.0)"] +bedrock-data-automation = ["mypy-boto3-bedrock-data-automation (>=1.43.0,<1.44.0)"] +bedrock-data-automation-runtime = ["mypy-boto3-bedrock-data-automation-runtime (>=1.43.0,<1.44.0)"] +bedrock-runtime = ["mypy-boto3-bedrock-runtime (>=1.43.0,<1.44.0)"] +billing = ["mypy-boto3-billing (>=1.43.0,<1.44.0)"] +billingconductor = ["mypy-boto3-billingconductor (>=1.43.0,<1.44.0)"] +boto3 = ["boto3 (==1.43.32)"] +braket = ["mypy-boto3-braket (>=1.43.0,<1.44.0)"] +budgets = ["mypy-boto3-budgets (>=1.43.0,<1.44.0)"] +ce = ["mypy-boto3-ce (>=1.43.0,<1.44.0)"] +chatbot = ["mypy-boto3-chatbot (>=1.43.0,<1.44.0)"] +chime = ["mypy-boto3-chime (>=1.43.0,<1.44.0)"] +chime-sdk-identity = ["mypy-boto3-chime-sdk-identity (>=1.43.0,<1.44.0)"] +chime-sdk-media-pipelines = ["mypy-boto3-chime-sdk-media-pipelines (>=1.43.0,<1.44.0)"] +chime-sdk-meetings = ["mypy-boto3-chime-sdk-meetings (>=1.43.0,<1.44.0)"] +chime-sdk-messaging = ["mypy-boto3-chime-sdk-messaging (>=1.43.0,<1.44.0)"] +chime-sdk-voice = ["mypy-boto3-chime-sdk-voice (>=1.43.0,<1.44.0)"] +cleanrooms = ["mypy-boto3-cleanrooms (>=1.43.0,<1.44.0)"] +cleanroomsml = ["mypy-boto3-cleanroomsml (>=1.43.0,<1.44.0)"] +cloud9 = ["mypy-boto3-cloud9 (>=1.43.0,<1.44.0)"] +cloudcontrol = ["mypy-boto3-cloudcontrol (>=1.43.0,<1.44.0)"] +clouddirectory = ["mypy-boto3-clouddirectory (>=1.43.0,<1.44.0)"] +cloudformation = ["mypy-boto3-cloudformation (>=1.43.0,<1.44.0)"] +cloudfront = ["mypy-boto3-cloudfront (>=1.43.0,<1.44.0)"] +cloudfront-keyvaluestore = ["mypy-boto3-cloudfront-keyvaluestore (>=1.43.0,<1.44.0)"] +cloudhsm = ["mypy-boto3-cloudhsm (>=1.43.0,<1.44.0)"] +cloudhsmv2 = ["mypy-boto3-cloudhsmv2 (>=1.43.0,<1.44.0)"] +cloudsearch = ["mypy-boto3-cloudsearch (>=1.43.0,<1.44.0)"] +cloudsearchdomain = ["mypy-boto3-cloudsearchdomain (>=1.43.0,<1.44.0)"] +cloudtrail = ["mypy-boto3-cloudtrail (>=1.43.0,<1.44.0)"] +cloudtrail-data = ["mypy-boto3-cloudtrail-data (>=1.43.0,<1.44.0)"] +cloudwatch = ["mypy-boto3-cloudwatch (>=1.43.0,<1.44.0)"] +codeartifact = ["mypy-boto3-codeartifact (>=1.43.0,<1.44.0)"] +codebuild = ["mypy-boto3-codebuild (>=1.43.0,<1.44.0)"] +codecatalyst = ["mypy-boto3-codecatalyst (>=1.43.0,<1.44.0)"] +codecommit = ["mypy-boto3-codecommit (>=1.43.0,<1.44.0)"] +codeconnections = ["mypy-boto3-codeconnections (>=1.43.0,<1.44.0)"] +codedeploy = ["mypy-boto3-codedeploy (>=1.43.0,<1.44.0)"] +codeguru-reviewer = ["mypy-boto3-codeguru-reviewer (>=1.43.0,<1.44.0)"] +codeguru-security = ["mypy-boto3-codeguru-security (>=1.43.0,<1.44.0)"] +codeguruprofiler = ["mypy-boto3-codeguruprofiler (>=1.43.0,<1.44.0)"] +codepipeline = ["mypy-boto3-codepipeline (>=1.43.0,<1.44.0)"] +codestar-connections = ["mypy-boto3-codestar-connections (>=1.43.0,<1.44.0)"] +codestar-notifications = ["mypy-boto3-codestar-notifications (>=1.43.0,<1.44.0)"] +cognito-identity = ["mypy-boto3-cognito-identity (>=1.43.0,<1.44.0)"] +cognito-idp = ["mypy-boto3-cognito-idp (>=1.43.0,<1.44.0)"] +cognito-sync = ["mypy-boto3-cognito-sync (>=1.43.0,<1.44.0)"] +comprehend = ["mypy-boto3-comprehend (>=1.43.0,<1.44.0)"] +comprehendmedical = ["mypy-boto3-comprehendmedical (>=1.43.0,<1.44.0)"] +compute-optimizer = ["mypy-boto3-compute-optimizer (>=1.43.0,<1.44.0)"] +compute-optimizer-automation = ["mypy-boto3-compute-optimizer-automation (>=1.43.0,<1.44.0)"] +config = ["mypy-boto3-config (>=1.43.0,<1.44.0)"] +connect = ["mypy-boto3-connect (>=1.43.0,<1.44.0)"] +connect-contact-lens = ["mypy-boto3-connect-contact-lens (>=1.43.0,<1.44.0)"] +connectcampaigns = ["mypy-boto3-connectcampaigns (>=1.43.0,<1.44.0)"] +connectcampaignsv2 = ["mypy-boto3-connectcampaignsv2 (>=1.43.0,<1.44.0)"] +connectcases = ["mypy-boto3-connectcases (>=1.43.0,<1.44.0)"] +connecthealth = ["mypy-boto3-connecthealth (>=1.43.0,<1.44.0)"] +connectparticipant = ["mypy-boto3-connectparticipant (>=1.43.0,<1.44.0)"] +controlcatalog = ["mypy-boto3-controlcatalog (>=1.43.0,<1.44.0)"] +controltower = ["mypy-boto3-controltower (>=1.43.0,<1.44.0)"] +cost-optimization-hub = ["mypy-boto3-cost-optimization-hub (>=1.43.0,<1.44.0)"] +cur = ["mypy-boto3-cur (>=1.43.0,<1.44.0)"] +customer-profiles = ["mypy-boto3-customer-profiles (>=1.43.0,<1.44.0)"] +databrew = ["mypy-boto3-databrew (>=1.43.0,<1.44.0)"] +dataexchange = ["mypy-boto3-dataexchange (>=1.43.0,<1.44.0)"] +datapipeline = ["mypy-boto3-datapipeline (>=1.43.0,<1.44.0)"] +datasync = ["mypy-boto3-datasync (>=1.43.0,<1.44.0)"] +datazone = ["mypy-boto3-datazone (>=1.43.0,<1.44.0)"] +dax = ["mypy-boto3-dax (>=1.43.0,<1.44.0)"] +deadline = ["mypy-boto3-deadline (>=1.43.0,<1.44.0)"] +detective = ["mypy-boto3-detective (>=1.43.0,<1.44.0)"] +devicefarm = ["mypy-boto3-devicefarm (>=1.43.0,<1.44.0)"] +devops-agent = ["mypy-boto3-devops-agent (>=1.43.0,<1.44.0)"] +devops-guru = ["mypy-boto3-devops-guru (>=1.43.0,<1.44.0)"] +directconnect = ["mypy-boto3-directconnect (>=1.43.0,<1.44.0)"] +discovery = ["mypy-boto3-discovery (>=1.43.0,<1.44.0)"] +dlm = ["mypy-boto3-dlm (>=1.43.0,<1.44.0)"] +dms = ["mypy-boto3-dms (>=1.43.0,<1.44.0)"] +docdb = ["mypy-boto3-docdb (>=1.43.0,<1.44.0)"] +docdb-elastic = ["mypy-boto3-docdb-elastic (>=1.43.0,<1.44.0)"] +drs = ["mypy-boto3-drs (>=1.43.0,<1.44.0)"] +ds = ["mypy-boto3-ds (>=1.43.0,<1.44.0)"] +ds-data = ["mypy-boto3-ds-data (>=1.43.0,<1.44.0)"] +dsql = ["mypy-boto3-dsql (>=1.43.0,<1.44.0)"] +dynamodb = ["mypy-boto3-dynamodb (>=1.43.0,<1.44.0)"] +dynamodbstreams = ["mypy-boto3-dynamodbstreams (>=1.43.0,<1.44.0)"] +ebs = ["mypy-boto3-ebs (>=1.43.0,<1.44.0)"] +ec2 = ["mypy-boto3-ec2 (>=1.43.0,<1.44.0)"] +ec2-instance-connect = ["mypy-boto3-ec2-instance-connect (>=1.43.0,<1.44.0)"] +ecr = ["mypy-boto3-ecr (>=1.43.0,<1.44.0)"] +ecr-public = ["mypy-boto3-ecr-public (>=1.43.0,<1.44.0)"] +ecs = ["mypy-boto3-ecs (>=1.43.0,<1.44.0)"] +efs = ["mypy-boto3-efs (>=1.43.0,<1.44.0)"] +eks = ["mypy-boto3-eks (>=1.43.0,<1.44.0)"] +eks-auth = ["mypy-boto3-eks-auth (>=1.43.0,<1.44.0)"] +elasticache = ["mypy-boto3-elasticache (>=1.43.0,<1.44.0)"] +elasticbeanstalk = ["mypy-boto3-elasticbeanstalk (>=1.43.0,<1.44.0)"] +elb = ["mypy-boto3-elb (>=1.43.0,<1.44.0)"] +elbv2 = ["mypy-boto3-elbv2 (>=1.43.0,<1.44.0)"] +elementalinference = ["mypy-boto3-elementalinference (>=1.43.0,<1.44.0)"] +emr = ["mypy-boto3-emr (>=1.43.0,<1.44.0)"] +emr-containers = ["mypy-boto3-emr-containers (>=1.43.0,<1.44.0)"] +emr-serverless = ["mypy-boto3-emr-serverless (>=1.43.0,<1.44.0)"] +entityresolution = ["mypy-boto3-entityresolution (>=1.43.0,<1.44.0)"] +es = ["mypy-boto3-es (>=1.43.0,<1.44.0)"] +essential = ["mypy-boto3-cloudformation (>=1.43.0,<1.44.0)", "mypy-boto3-dynamodb (>=1.43.0,<1.44.0)", "mypy-boto3-ec2 (>=1.43.0,<1.44.0)", "mypy-boto3-lambda (>=1.43.0,<1.44.0)", "mypy-boto3-rds (>=1.43.0,<1.44.0)", "mypy-boto3-s3 (>=1.43.0,<1.44.0)", "mypy-boto3-sqs (>=1.43.0,<1.44.0)"] +events = ["mypy-boto3-events (>=1.43.0,<1.44.0)"] +evs = ["mypy-boto3-evs (>=1.43.0,<1.44.0)"] +finspace = ["mypy-boto3-finspace (>=1.43.0,<1.44.0)"] +finspace-data = ["mypy-boto3-finspace-data (>=1.43.0,<1.44.0)"] +firehose = ["mypy-boto3-firehose (>=1.43.0,<1.44.0)"] +fis = ["mypy-boto3-fis (>=1.43.0,<1.44.0)"] +fms = ["mypy-boto3-fms (>=1.43.0,<1.44.0)"] +forecast = ["mypy-boto3-forecast (>=1.43.0,<1.44.0)"] +forecastquery = ["mypy-boto3-forecastquery (>=1.43.0,<1.44.0)"] +frauddetector = ["mypy-boto3-frauddetector (>=1.43.0,<1.44.0)"] +freetier = ["mypy-boto3-freetier (>=1.43.0,<1.44.0)"] +fsx = ["mypy-boto3-fsx (>=1.43.0,<1.44.0)"] +full = ["boto3-stubs-full (>=1.43.0,<1.44.0)"] +gamelift = ["mypy-boto3-gamelift (>=1.43.0,<1.44.0)"] +gameliftstreams = ["mypy-boto3-gameliftstreams (>=1.43.0,<1.44.0)"] +geo-maps = ["mypy-boto3-geo-maps (>=1.43.0,<1.44.0)"] +geo-places = ["mypy-boto3-geo-places (>=1.43.0,<1.44.0)"] +geo-routes = ["mypy-boto3-geo-routes (>=1.43.0,<1.44.0)"] +glacier = ["mypy-boto3-glacier (>=1.43.0,<1.44.0)"] +globalaccelerator = ["mypy-boto3-globalaccelerator (>=1.43.0,<1.44.0)"] +glue = ["mypy-boto3-glue (>=1.43.0,<1.44.0)"] +grafana = ["mypy-boto3-grafana (>=1.43.0,<1.44.0)"] +greengrass = ["mypy-boto3-greengrass (>=1.43.0,<1.44.0)"] +greengrassv2 = ["mypy-boto3-greengrassv2 (>=1.43.0,<1.44.0)"] +groundstation = ["mypy-boto3-groundstation (>=1.43.0,<1.44.0)"] +guardduty = ["mypy-boto3-guardduty (>=1.43.0,<1.44.0)"] +health = ["mypy-boto3-health (>=1.43.0,<1.44.0)"] +healthlake = ["mypy-boto3-healthlake (>=1.43.0,<1.44.0)"] +iam = ["mypy-boto3-iam (>=1.43.0,<1.44.0)"] +identitystore = ["mypy-boto3-identitystore (>=1.43.0,<1.44.0)"] +imagebuilder = ["mypy-boto3-imagebuilder (>=1.43.0,<1.44.0)"] +importexport = ["mypy-boto3-importexport (>=1.43.0,<1.44.0)"] +inspector = ["mypy-boto3-inspector (>=1.43.0,<1.44.0)"] +inspector-scan = ["mypy-boto3-inspector-scan (>=1.43.0,<1.44.0)"] +inspector2 = ["mypy-boto3-inspector2 (>=1.43.0,<1.44.0)"] +interconnect = ["mypy-boto3-interconnect (>=1.43.0,<1.44.0)"] +internetmonitor = ["mypy-boto3-internetmonitor (>=1.43.0,<1.44.0)"] +invoicing = ["mypy-boto3-invoicing (>=1.43.0,<1.44.0)"] +iot = ["mypy-boto3-iot (>=1.43.0,<1.44.0)"] +iot-data = ["mypy-boto3-iot-data (>=1.43.0,<1.44.0)"] +iot-jobs-data = ["mypy-boto3-iot-jobs-data (>=1.43.0,<1.44.0)"] +iot-managed-integrations = ["mypy-boto3-iot-managed-integrations (>=1.43.0,<1.44.0)"] +iotdeviceadvisor = ["mypy-boto3-iotdeviceadvisor (>=1.43.0,<1.44.0)"] +iotevents = ["mypy-boto3-iotevents (>=1.43.0,<1.44.0)"] +iotevents-data = ["mypy-boto3-iotevents-data (>=1.43.0,<1.44.0)"] +iotfleetwise = ["mypy-boto3-iotfleetwise (>=1.43.0,<1.44.0)"] +iotsecuretunneling = ["mypy-boto3-iotsecuretunneling (>=1.43.0,<1.44.0)"] +iotsitewise = ["mypy-boto3-iotsitewise (>=1.43.0,<1.44.0)"] +iotthingsgraph = ["mypy-boto3-iotthingsgraph (>=1.43.0,<1.44.0)"] +iottwinmaker = ["mypy-boto3-iottwinmaker (>=1.43.0,<1.44.0)"] +iotwireless = ["mypy-boto3-iotwireless (>=1.43.0,<1.44.0)"] +ivs = ["mypy-boto3-ivs (>=1.43.0,<1.44.0)"] +ivs-realtime = ["mypy-boto3-ivs-realtime (>=1.43.0,<1.44.0)"] +ivschat = ["mypy-boto3-ivschat (>=1.43.0,<1.44.0)"] +kafka = ["mypy-boto3-kafka (>=1.43.0,<1.44.0)"] +kafkaconnect = ["mypy-boto3-kafkaconnect (>=1.43.0,<1.44.0)"] +kendra = ["mypy-boto3-kendra (>=1.43.0,<1.44.0)"] +kendra-ranking = ["mypy-boto3-kendra-ranking (>=1.43.0,<1.44.0)"] +keyspaces = ["mypy-boto3-keyspaces (>=1.43.0,<1.44.0)"] +keyspacesstreams = ["mypy-boto3-keyspacesstreams (>=1.43.0,<1.44.0)"] +kinesis = ["mypy-boto3-kinesis (>=1.43.0,<1.44.0)"] +kinesis-video-archived-media = ["mypy-boto3-kinesis-video-archived-media (>=1.43.0,<1.44.0)"] +kinesis-video-media = ["mypy-boto3-kinesis-video-media (>=1.43.0,<1.44.0)"] +kinesis-video-signaling = ["mypy-boto3-kinesis-video-signaling (>=1.43.0,<1.44.0)"] +kinesis-video-webrtc-storage = ["mypy-boto3-kinesis-video-webrtc-storage (>=1.43.0,<1.44.0)"] +kinesisanalytics = ["mypy-boto3-kinesisanalytics (>=1.43.0,<1.44.0)"] +kinesisanalyticsv2 = ["mypy-boto3-kinesisanalyticsv2 (>=1.43.0,<1.44.0)"] +kinesisvideo = ["mypy-boto3-kinesisvideo (>=1.43.0,<1.44.0)"] +kms = ["mypy-boto3-kms (>=1.43.0,<1.44.0)"] +lakeformation = ["mypy-boto3-lakeformation (>=1.43.0,<1.44.0)"] +lambda = ["mypy-boto3-lambda (>=1.43.0,<1.44.0)"] +launch-wizard = ["mypy-boto3-launch-wizard (>=1.43.0,<1.44.0)"] +lex-models = ["mypy-boto3-lex-models (>=1.43.0,<1.44.0)"] +lex-runtime = ["mypy-boto3-lex-runtime (>=1.43.0,<1.44.0)"] +lexv2-models = ["mypy-boto3-lexv2-models (>=1.43.0,<1.44.0)"] +lexv2-runtime = ["mypy-boto3-lexv2-runtime (>=1.43.0,<1.44.0)"] +license-manager = ["mypy-boto3-license-manager (>=1.43.0,<1.44.0)"] +license-manager-linux-subscriptions = ["mypy-boto3-license-manager-linux-subscriptions (>=1.43.0,<1.44.0)"] +license-manager-user-subscriptions = ["mypy-boto3-license-manager-user-subscriptions (>=1.43.0,<1.44.0)"] +lightsail = ["mypy-boto3-lightsail (>=1.43.0,<1.44.0)"] +location = ["mypy-boto3-location (>=1.43.0,<1.44.0)"] +logs = ["mypy-boto3-logs (>=1.43.0,<1.44.0)"] +lookoutequipment = ["mypy-boto3-lookoutequipment (>=1.43.0,<1.44.0)"] +m2 = ["mypy-boto3-m2 (>=1.43.0,<1.44.0)"] +machinelearning = ["mypy-boto3-machinelearning (>=1.43.0,<1.44.0)"] +macie2 = ["mypy-boto3-macie2 (>=1.43.0,<1.44.0)"] +mailmanager = ["mypy-boto3-mailmanager (>=1.43.0,<1.44.0)"] +managedblockchain = ["mypy-boto3-managedblockchain (>=1.43.0,<1.44.0)"] +managedblockchain-query = ["mypy-boto3-managedblockchain-query (>=1.43.0,<1.44.0)"] +marketplace-agreement = ["mypy-boto3-marketplace-agreement (>=1.43.0,<1.44.0)"] +marketplace-catalog = ["mypy-boto3-marketplace-catalog (>=1.43.0,<1.44.0)"] +marketplace-deployment = ["mypy-boto3-marketplace-deployment (>=1.43.0,<1.44.0)"] +marketplace-discovery = ["mypy-boto3-marketplace-discovery (>=1.43.0,<1.44.0)"] +marketplace-entitlement = ["mypy-boto3-marketplace-entitlement (>=1.43.0,<1.44.0)"] +marketplace-reporting = ["mypy-boto3-marketplace-reporting (>=1.43.0,<1.44.0)"] +marketplacecommerceanalytics = ["mypy-boto3-marketplacecommerceanalytics (>=1.43.0,<1.44.0)"] +mediaconnect = ["mypy-boto3-mediaconnect (>=1.43.0,<1.44.0)"] +mediaconvert = ["mypy-boto3-mediaconvert (>=1.43.0,<1.44.0)"] +medialive = ["mypy-boto3-medialive (>=1.43.0,<1.44.0)"] +mediapackage = ["mypy-boto3-mediapackage (>=1.43.0,<1.44.0)"] +mediapackage-vod = ["mypy-boto3-mediapackage-vod (>=1.43.0,<1.44.0)"] +mediapackagev2 = ["mypy-boto3-mediapackagev2 (>=1.43.0,<1.44.0)"] +mediastore = ["mypy-boto3-mediastore (>=1.43.0,<1.44.0)"] +mediastore-data = ["mypy-boto3-mediastore-data (>=1.43.0,<1.44.0)"] +mediatailor = ["mypy-boto3-mediatailor (>=1.43.0,<1.44.0)"] +medical-imaging = ["mypy-boto3-medical-imaging (>=1.43.0,<1.44.0)"] +memorydb = ["mypy-boto3-memorydb (>=1.43.0,<1.44.0)"] +meteringmarketplace = ["mypy-boto3-meteringmarketplace (>=1.43.0,<1.44.0)"] +mgh = ["mypy-boto3-mgh (>=1.43.0,<1.44.0)"] +mgn = ["mypy-boto3-mgn (>=1.43.0,<1.44.0)"] +migration-hub-refactor-spaces = ["mypy-boto3-migration-hub-refactor-spaces (>=1.43.0,<1.44.0)"] +migrationhub-config = ["mypy-boto3-migrationhub-config (>=1.43.0,<1.44.0)"] +migrationhuborchestrator = ["mypy-boto3-migrationhuborchestrator (>=1.43.0,<1.44.0)"] +migrationhubstrategy = ["mypy-boto3-migrationhubstrategy (>=1.43.0,<1.44.0)"] +mpa = ["mypy-boto3-mpa (>=1.43.0,<1.44.0)"] +mq = ["mypy-boto3-mq (>=1.43.0,<1.44.0)"] +mturk = ["mypy-boto3-mturk (>=1.43.0,<1.44.0)"] +mwaa = ["mypy-boto3-mwaa (>=1.43.0,<1.44.0)"] +mwaa-serverless = ["mypy-boto3-mwaa-serverless (>=1.43.0,<1.44.0)"] +neptune = ["mypy-boto3-neptune (>=1.43.0,<1.44.0)"] +neptune-graph = ["mypy-boto3-neptune-graph (>=1.43.0,<1.44.0)"] +neptunedata = ["mypy-boto3-neptunedata (>=1.43.0,<1.44.0)"] +network-firewall = ["mypy-boto3-network-firewall (>=1.43.0,<1.44.0)"] +networkflowmonitor = ["mypy-boto3-networkflowmonitor (>=1.43.0,<1.44.0)"] +networkmanager = ["mypy-boto3-networkmanager (>=1.43.0,<1.44.0)"] +networkmonitor = ["mypy-boto3-networkmonitor (>=1.43.0,<1.44.0)"] +notifications = ["mypy-boto3-notifications (>=1.43.0,<1.44.0)"] +notificationscontacts = ["mypy-boto3-notificationscontacts (>=1.43.0,<1.44.0)"] +nova-act = ["mypy-boto3-nova-act (>=1.43.0,<1.44.0)"] +oam = ["mypy-boto3-oam (>=1.43.0,<1.44.0)"] +observabilityadmin = ["mypy-boto3-observabilityadmin (>=1.43.0,<1.44.0)"] +odb = ["mypy-boto3-odb (>=1.43.0,<1.44.0)"] +omics = ["mypy-boto3-omics (>=1.43.0,<1.44.0)"] +opensearch = ["mypy-boto3-opensearch (>=1.43.0,<1.44.0)"] +opensearchserverless = ["mypy-boto3-opensearchserverless (>=1.43.0,<1.44.0)"] +organizations = ["mypy-boto3-organizations (>=1.43.0,<1.44.0)"] +osis = ["mypy-boto3-osis (>=1.43.0,<1.44.0)"] +outposts = ["mypy-boto3-outposts (>=1.43.0,<1.44.0)"] +panorama = ["mypy-boto3-panorama (>=1.43.0,<1.44.0)"] +partnercentral-account = ["mypy-boto3-partnercentral-account (>=1.43.0,<1.44.0)"] +partnercentral-benefits = ["mypy-boto3-partnercentral-benefits (>=1.43.0,<1.44.0)"] +partnercentral-channel = ["mypy-boto3-partnercentral-channel (>=1.43.0,<1.44.0)"] +partnercentral-selling = ["mypy-boto3-partnercentral-selling (>=1.43.0,<1.44.0)"] +payment-cryptography = ["mypy-boto3-payment-cryptography (>=1.43.0,<1.44.0)"] +payment-cryptography-data = ["mypy-boto3-payment-cryptography-data (>=1.43.0,<1.44.0)"] +pca-connector-ad = ["mypy-boto3-pca-connector-ad (>=1.43.0,<1.44.0)"] +pca-connector-scep = ["mypy-boto3-pca-connector-scep (>=1.43.0,<1.44.0)"] +pcs = ["mypy-boto3-pcs (>=1.43.0,<1.44.0)"] +personalize = ["mypy-boto3-personalize (>=1.43.0,<1.44.0)"] +personalize-events = ["mypy-boto3-personalize-events (>=1.43.0,<1.44.0)"] +personalize-runtime = ["mypy-boto3-personalize-runtime (>=1.43.0,<1.44.0)"] +pi = ["mypy-boto3-pi (>=1.43.0,<1.44.0)"] +pinpoint = ["mypy-boto3-pinpoint (>=1.43.0,<1.44.0)"] +pinpoint-email = ["mypy-boto3-pinpoint-email (>=1.43.0,<1.44.0)"] +pinpoint-sms-voice = ["mypy-boto3-pinpoint-sms-voice (>=1.43.0,<1.44.0)"] +pinpoint-sms-voice-v2 = ["mypy-boto3-pinpoint-sms-voice-v2 (>=1.43.0,<1.44.0)"] +pipes = ["mypy-boto3-pipes (>=1.43.0,<1.44.0)"] +polly = ["mypy-boto3-polly (>=1.43.0,<1.44.0)"] +pricing = ["mypy-boto3-pricing (>=1.43.0,<1.44.0)"] +proton = ["mypy-boto3-proton (>=1.43.0,<1.44.0)"] +qapps = ["mypy-boto3-qapps (>=1.43.0,<1.44.0)"] +qbusiness = ["mypy-boto3-qbusiness (>=1.43.0,<1.44.0)"] +qconnect = ["mypy-boto3-qconnect (>=1.43.0,<1.44.0)"] +quicksight = ["mypy-boto3-quicksight (>=1.43.0,<1.44.0)"] +ram = ["mypy-boto3-ram (>=1.43.0,<1.44.0)"] +rbin = ["mypy-boto3-rbin (>=1.43.0,<1.44.0)"] +rds = ["mypy-boto3-rds (>=1.43.0,<1.44.0)"] +rds-data = ["mypy-boto3-rds-data (>=1.43.0,<1.44.0)"] +redshift = ["mypy-boto3-redshift (>=1.43.0,<1.44.0)"] +redshift-data = ["mypy-boto3-redshift-data (>=1.43.0,<1.44.0)"] +redshift-serverless = ["mypy-boto3-redshift-serverless (>=1.43.0,<1.44.0)"] +rekognition = ["mypy-boto3-rekognition (>=1.43.0,<1.44.0)"] +repostspace = ["mypy-boto3-repostspace (>=1.43.0,<1.44.0)"] +resiliencehub = ["mypy-boto3-resiliencehub (>=1.43.0,<1.44.0)"] +resiliencehubv2 = ["mypy-boto3-resiliencehubv2 (>=1.43.0,<1.44.0)"] +resource-explorer-2 = ["mypy-boto3-resource-explorer-2 (>=1.43.0,<1.44.0)"] +resource-groups = ["mypy-boto3-resource-groups (>=1.43.0,<1.44.0)"] +resourcegroupstaggingapi = ["mypy-boto3-resourcegroupstaggingapi (>=1.43.0,<1.44.0)"] +rolesanywhere = ["mypy-boto3-rolesanywhere (>=1.43.0,<1.44.0)"] +route53 = ["mypy-boto3-route53 (>=1.43.0,<1.44.0)"] +route53-recovery-cluster = ["mypy-boto3-route53-recovery-cluster (>=1.43.0,<1.44.0)"] +route53-recovery-control-config = ["mypy-boto3-route53-recovery-control-config (>=1.43.0,<1.44.0)"] +route53-recovery-readiness = ["mypy-boto3-route53-recovery-readiness (>=1.43.0,<1.44.0)"] +route53domains = ["mypy-boto3-route53domains (>=1.43.0,<1.44.0)"] +route53globalresolver = ["mypy-boto3-route53globalresolver (>=1.43.0,<1.44.0)"] +route53profiles = ["mypy-boto3-route53profiles (>=1.43.0,<1.44.0)"] +route53resolver = ["mypy-boto3-route53resolver (>=1.43.0,<1.44.0)"] +rtbfabric = ["mypy-boto3-rtbfabric (>=1.43.0,<1.44.0)"] +rum = ["mypy-boto3-rum (>=1.43.0,<1.44.0)"] +s3 = ["mypy-boto3-s3 (>=1.43.0,<1.44.0)"] +s3control = ["mypy-boto3-s3control (>=1.43.0,<1.44.0)"] +s3files = ["mypy-boto3-s3files (>=1.43.0,<1.44.0)"] +s3outposts = ["mypy-boto3-s3outposts (>=1.43.0,<1.44.0)"] +s3tables = ["mypy-boto3-s3tables (>=1.43.0,<1.44.0)"] +s3vectors = ["mypy-boto3-s3vectors (>=1.43.0,<1.44.0)"] +sagemaker = ["mypy-boto3-sagemaker (>=1.43.0,<1.44.0)"] +sagemaker-a2i-runtime = ["mypy-boto3-sagemaker-a2i-runtime (>=1.43.0,<1.44.0)"] +sagemaker-edge = ["mypy-boto3-sagemaker-edge (>=1.43.0,<1.44.0)"] +sagemaker-featurestore-runtime = ["mypy-boto3-sagemaker-featurestore-runtime (>=1.43.0,<1.44.0)"] +sagemaker-geospatial = ["mypy-boto3-sagemaker-geospatial (>=1.43.0,<1.44.0)"] +sagemaker-metrics = ["mypy-boto3-sagemaker-metrics (>=1.43.0,<1.44.0)"] +sagemaker-runtime = ["mypy-boto3-sagemaker-runtime (>=1.43.0,<1.44.0)"] +sagemakerjobruntime = ["mypy-boto3-sagemakerjobruntime (>=1.43.0,<1.44.0)"] +savingsplans = ["mypy-boto3-savingsplans (>=1.43.0,<1.44.0)"] +scheduler = ["mypy-boto3-scheduler (>=1.43.0,<1.44.0)"] +schemas = ["mypy-boto3-schemas (>=1.43.0,<1.44.0)"] +sdb = ["mypy-boto3-sdb (>=1.43.0,<1.44.0)"] +secretsmanager = ["mypy-boto3-secretsmanager (>=1.43.0,<1.44.0)"] +security-ir = ["mypy-boto3-security-ir (>=1.43.0,<1.44.0)"] +securityagent = ["mypy-boto3-securityagent (>=1.43.0,<1.44.0)"] +securityhub = ["mypy-boto3-securityhub (>=1.43.0,<1.44.0)"] +securitylake = ["mypy-boto3-securitylake (>=1.43.0,<1.44.0)"] +serverlessrepo = ["mypy-boto3-serverlessrepo (>=1.43.0,<1.44.0)"] +service-quotas = ["mypy-boto3-service-quotas (>=1.43.0,<1.44.0)"] +servicecatalog = ["mypy-boto3-servicecatalog (>=1.43.0,<1.44.0)"] +servicecatalog-appregistry = ["mypy-boto3-servicecatalog-appregistry (>=1.43.0,<1.44.0)"] +servicediscovery = ["mypy-boto3-servicediscovery (>=1.43.0,<1.44.0)"] +ses = ["mypy-boto3-ses (>=1.43.0,<1.44.0)"] +sesv2 = ["mypy-boto3-sesv2 (>=1.43.0,<1.44.0)"] +shield = ["mypy-boto3-shield (>=1.43.0,<1.44.0)"] +signer = ["mypy-boto3-signer (>=1.43.0,<1.44.0)"] +signer-data = ["mypy-boto3-signer-data (>=1.43.0,<1.44.0)"] +signin = ["mypy-boto3-signin (>=1.43.0,<1.44.0)"] +simpledbv2 = ["mypy-boto3-simpledbv2 (>=1.43.0,<1.44.0)"] +simspaceweaver = ["mypy-boto3-simspaceweaver (>=1.43.0,<1.44.0)"] +snow-device-management = ["mypy-boto3-snow-device-management (>=1.43.0,<1.44.0)"] +snowball = ["mypy-boto3-snowball (>=1.43.0,<1.44.0)"] +sns = ["mypy-boto3-sns (>=1.43.0,<1.44.0)"] +socialmessaging = ["mypy-boto3-socialmessaging (>=1.43.0,<1.44.0)"] +sqs = ["mypy-boto3-sqs (>=1.43.0,<1.44.0)"] +ssm = ["mypy-boto3-ssm (>=1.43.0,<1.44.0)"] +ssm-contacts = ["mypy-boto3-ssm-contacts (>=1.43.0,<1.44.0)"] +ssm-guiconnect = ["mypy-boto3-ssm-guiconnect (>=1.43.0,<1.44.0)"] +ssm-incidents = ["mypy-boto3-ssm-incidents (>=1.43.0,<1.44.0)"] +ssm-quicksetup = ["mypy-boto3-ssm-quicksetup (>=1.43.0,<1.44.0)"] +ssm-sap = ["mypy-boto3-ssm-sap (>=1.43.0,<1.44.0)"] +sso = ["mypy-boto3-sso (>=1.43.0,<1.44.0)"] +sso-admin = ["mypy-boto3-sso-admin (>=1.43.0,<1.44.0)"] +sso-oidc = ["mypy-boto3-sso-oidc (>=1.43.0,<1.44.0)"] +stepfunctions = ["mypy-boto3-stepfunctions (>=1.43.0,<1.44.0)"] +storagegateway = ["mypy-boto3-storagegateway (>=1.43.0,<1.44.0)"] +sts = ["mypy-boto3-sts (>=1.43.0,<1.44.0)"] +supplychain = ["mypy-boto3-supplychain (>=1.43.0,<1.44.0)"] +support = ["mypy-boto3-support (>=1.43.0,<1.44.0)"] +support-app = ["mypy-boto3-support-app (>=1.43.0,<1.44.0)"] +sustainability = ["mypy-boto3-sustainability (>=1.43.0,<1.44.0)"] +swf = ["mypy-boto3-swf (>=1.43.0,<1.44.0)"] +synthetics = ["mypy-boto3-synthetics (>=1.43.0,<1.44.0)"] +taxsettings = ["mypy-boto3-taxsettings (>=1.43.0,<1.44.0)"] +textract = ["mypy-boto3-textract (>=1.43.0,<1.44.0)"] +timestream-influxdb = ["mypy-boto3-timestream-influxdb (>=1.43.0,<1.44.0)"] +timestream-query = ["mypy-boto3-timestream-query (>=1.43.0,<1.44.0)"] +timestream-write = ["mypy-boto3-timestream-write (>=1.43.0,<1.44.0)"] +tnb = ["mypy-boto3-tnb (>=1.43.0,<1.44.0)"] +transcribe = ["mypy-boto3-transcribe (>=1.43.0,<1.44.0)"] +transfer = ["mypy-boto3-transfer (>=1.43.0,<1.44.0)"] +translate = ["mypy-boto3-translate (>=1.43.0,<1.44.0)"] +trustedadvisor = ["mypy-boto3-trustedadvisor (>=1.43.0,<1.44.0)"] +uxc = ["mypy-boto3-uxc (>=1.43.0,<1.44.0)"] +verifiedpermissions = ["mypy-boto3-verifiedpermissions (>=1.43.0,<1.44.0)"] +voice-id = ["mypy-boto3-voice-id (>=1.43.0,<1.44.0)"] +vpc-lattice = ["mypy-boto3-vpc-lattice (>=1.43.0,<1.44.0)"] +waf = ["mypy-boto3-waf (>=1.43.0,<1.44.0)"] +waf-regional = ["mypy-boto3-waf-regional (>=1.43.0,<1.44.0)"] +wafv2 = ["mypy-boto3-wafv2 (>=1.43.0,<1.44.0)"] +wellarchitected = ["mypy-boto3-wellarchitected (>=1.43.0,<1.44.0)"] +wickr = ["mypy-boto3-wickr (>=1.43.0,<1.44.0)"] +wisdom = ["mypy-boto3-wisdom (>=1.43.0,<1.44.0)"] +workdocs = ["mypy-boto3-workdocs (>=1.43.0,<1.44.0)"] +workmail = ["mypy-boto3-workmail (>=1.43.0,<1.44.0)"] +workmailmessageflow = ["mypy-boto3-workmailmessageflow (>=1.43.0,<1.44.0)"] +workspaces = ["mypy-boto3-workspaces (>=1.43.0,<1.44.0)"] +workspaces-instances = ["mypy-boto3-workspaces-instances (>=1.43.0,<1.44.0)"] +workspaces-thin-client = ["mypy-boto3-workspaces-thin-client (>=1.43.0,<1.44.0)"] +workspaces-web = ["mypy-boto3-workspaces-web (>=1.43.0,<1.44.0)"] +xray = ["mypy-boto3-xray (>=1.43.0,<1.44.0)"] [[package]] name = "botocore" -version = "1.42.74" +version = "1.43.32" description = "Low-level, data-driven core of boto 3." optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "botocore-1.42.74-py3-none-any.whl", hash = "sha256:3a76a8af08b5de82e51a0ae132394e226e15dbf21c8146ac3f7c1f881517a7a7"}, - {file = "botocore-1.42.74.tar.gz", hash = "sha256:9cf5cdffc6c90ed87b0fe184676806182588be0d0df9b363e9fe3e2923ac8e80"}, + {file = "botocore-1.43.32-py3-none-any.whl", hash = "sha256:429796537fde1301df90d394808985d88cd51b36a6e769e5c12f6a6877605428"}, + {file = "botocore-1.43.32.tar.gz", hash = "sha256:88ed52268b8f7e8ff8f9df5adbbf61e5bbb5dc618ee50de4346cabe93a482792"}, ] [package.dependencies] jmespath = ">=0.7.1,<2.0.0" python-dateutil = ">=2.1,<3.0.0" -urllib3 = {version = ">=1.25.4,<2.2.0 || >2.2.0,<3", markers = "python_version >= \"3.10\""} +urllib3 = ">=1.25.4,<2.2.0 || >2.2.0,<3" [package.extras] -crt = ["awscrt (==0.31.2)"] +crt = ["awscrt (==0.32.2)"] [[package]] name = "botocore-stubs" @@ -864,24 +873,6 @@ files = [ {file = "debugpy-1.8.20.tar.gz", hash = "sha256:55bc8701714969f1ab89a6d5f2f3d40c36f91b2cbe2f65d98bf8196f6a6a2c33"}, ] -[[package]] -name = "deprecated" -version = "1.2.14" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" -groups = ["main", "test"] -files = [ - {file = "Deprecated-1.2.14-py2.py3-none-any.whl", hash = "sha256:6fac8b097794a90302bdbb17b9b815e732d3c4720583ff1b198499d78470466c"}, - {file = "Deprecated-1.2.14.tar.gz", hash = "sha256:e5323eb936458dccc2582dc6f9c322c852a775a27065ff2b0c4970b9d53d01b3"}, -] - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] - [[package]] name = "django" version = "5.2.14" @@ -1024,159 +1015,164 @@ grpc = ["grpcio (>=1.44.0,<2.0.0.dev0)"] [[package]] name = "greenlet" -version = "3.1.1" +version = "3.5.2" description = "Lightweight in-process concurrent programming" optional = false -python-versions = ">=3.7" +python-versions = ">=3.10" groups = ["dev"] markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" files = [ - {file = "greenlet-3.1.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:0bbae94a29c9e5c7e4a2b7f0aae5c17e8e90acbfd3bf6270eeba60c39fce3563"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fde093fb93f35ca72a556cf72c92ea3ebfda3d79fc35bb19fbe685853869a83"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36b89d13c49216cadb828db8dfa6ce86bbbc476a82d3a6c397f0efae0525bdd0"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94b6150a85e1b33b40b1464a3f9988dcc5251d6ed06842abff82e42632fac120"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:93147c513fac16385d1036b7e5b102c7fbbdb163d556b791f0f11eada7ba65dc"}, - {file = "greenlet-3.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:da7a9bff22ce038e19bf62c4dd1ec8391062878710ded0a845bcf47cc0200617"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:b2795058c23988728eec1f36a4e5e4ebad22f8320c85f3587b539b9ac84128d7"}, - {file = "greenlet-3.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ed10eac5830befbdd0c32f83e8aa6288361597550ba669b04c48f0f9a2c843c6"}, - {file = "greenlet-3.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:77c386de38a60d1dfb8e55b8c1101d68c79dfdd25c7095d51fec2dd800892b80"}, - {file = "greenlet-3.1.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:e4d333e558953648ca09d64f13e6d8f0523fa705f51cae3f03b5983489958c70"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:09fc016b73c94e98e29af67ab7b9a879c307c6731a2c9da0db5a7d9b7edd1159"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d5e975ca70269d66d17dd995dafc06f1b06e8cb1ec1e9ed54c1d1e4a7c4cf26e"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b2813dc3de8c1ee3f924e4d4227999285fd335d1bcc0d2be6dc3f1f6a318ec1"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e347b3bfcf985a05e8c0b7d462ba6f15b1ee1c909e2dcad795e49e91b152c383"}, - {file = "greenlet-3.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e8f8c9cb53cdac7ba9793c276acd90168f416b9ce36799b9b885790f8ad6c0a"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:62ee94988d6b4722ce0028644418d93a52429e977d742ca2ccbe1c4f4a792511"}, - {file = "greenlet-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1776fd7f989fc6b8d8c8cb8da1f6b82c5814957264d1f6cf818d475ec2bf6395"}, - {file = "greenlet-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:48ca08c771c268a768087b408658e216133aecd835c0ded47ce955381105ba39"}, - {file = "greenlet-3.1.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:4afe7ea89de619adc868e087b4d2359282058479d7cfb94970adf4b55284574d"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f406b22b7c9a9b4f8aa9d2ab13d6ae0ac3e85c9a809bd590ad53fed2bf70dc79"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c3a701fe5a9695b238503ce5bbe8218e03c3bcccf7e204e455e7462d770268aa"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2846930c65b47d70b9d178e89c7e1a69c95c1f68ea5aa0a58646b7a96df12441"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99cfaa2110534e2cf3ba31a7abcac9d328d1d9f1b95beede58294a60348fba36"}, - {file = "greenlet-3.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1443279c19fca463fc33e65ef2a935a5b09bb90f978beab37729e1c3c6c25fe9"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b7cede291382a78f7bb5f04a529cb18e068dd29e0fb27376074b6d0317bf4dd0"}, - {file = "greenlet-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:23f20bb60ae298d7d8656c6ec6db134bca379ecefadb0b19ce6f19d1f232a942"}, - {file = "greenlet-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:7124e16b4c55d417577c2077be379514321916d5790fa287c9ed6f23bd2ffd01"}, - {file = "greenlet-3.1.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:05175c27cb459dcfc05d026c4232f9de8913ed006d42713cb8a5137bd49375f1"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:935e943ec47c4afab8965954bf49bfa639c05d4ccf9ef6e924188f762145c0ff"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:667a9706c970cb552ede35aee17339a18e8f2a87a51fba2ed39ceeeb1004798a"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b8a678974d1f3aa55f6cc34dc480169d58f2e6d8958895d68845fa4ab566509e"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:efc0f674aa41b92da8c49e0346318c6075d734994c3c4e4430b1c3f853e498e4"}, - {file = "greenlet-3.1.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0153404a4bb921f0ff1abeb5ce8a5131da56b953eda6e14b88dc6bbc04d2049e"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:275f72decf9932639c1c6dd1013a1bc266438eb32710016a1c742df5da6e60a1"}, - {file = "greenlet-3.1.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c4aab7f6381f38a4b42f269057aee279ab0fc7bf2e929e3d4abfae97b682a12c"}, - {file = "greenlet-3.1.1-cp313-cp313-win_amd64.whl", hash = "sha256:b42703b1cf69f2aa1df7d1030b9d77d3e584a70755674d60e710f0af570f3761"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f1695e76146579f8c06c1509c7ce4dfe0706f49c6831a817ac04eebb2fd02011"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7876452af029456b3f3549b696bb36a06db7c90747740c5302f74a9e9fa14b13"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4ead44c85f8ab905852d3de8d86f6f8baf77109f9da589cb4fa142bd3b57b475"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8320f64b777d00dd7ccdade271eaf0cad6636343293a25074cc5566160e4de7b"}, - {file = "greenlet-3.1.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6510bf84a6b643dabba74d3049ead221257603a253d0a9873f55f6a59a65f822"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:04b013dc07c96f83134b1e99888e7a79979f1a247e2a9f59697fa14b5862ed01"}, - {file = "greenlet-3.1.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:411f015496fec93c1c8cd4e5238da364e1da7a124bcb293f085bf2860c32c6f6"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47da355d8687fd65240c364c90a31569a133b7b60de111c255ef5b606f2ae291"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:98884ecf2ffb7d7fe6bd517e8eb99d31ff7855a840fa6d0d63cd07c037f6a981"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1d4aeb8891338e60d1ab6127af1fe45def5259def8094b9c7e34690c8858803"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db32b5348615a04b82240cc67983cb315309e88d444a288934ee6ceaebcad6cc"}, - {file = "greenlet-3.1.1-cp37-cp37m-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dcc62f31eae24de7f8dce72134c8651c58000d3b1868e01392baea7c32c247de"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1d3755bcb2e02de341c55b4fca7a745a24a9e7212ac953f6b3a48d117d7257aa"}, - {file = "greenlet-3.1.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:b8da394b34370874b4572676f36acabac172602abf054cbc4ac910219f3340af"}, - {file = "greenlet-3.1.1-cp37-cp37m-win32.whl", hash = "sha256:a0dfc6c143b519113354e780a50381508139b07d2177cb6ad6a08278ec655798"}, - {file = "greenlet-3.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:54558ea205654b50c438029505def3834e80f0869a70fb15b871c29b4575ddef"}, - {file = "greenlet-3.1.1-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:346bed03fe47414091be4ad44786d1bd8bef0c3fcad6ed3dee074a032ab408a9"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dfc59d69fc48664bc693842bd57acfdd490acafda1ab52c7836e3fc75c90a111"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d21e10da6ec19b457b82636209cbe2331ff4306b54d06fa04b7c138ba18c8a81"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:37b9de5a96111fc15418819ab4c4432e4f3c2ede61e660b1e33971eba26ef9ba"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ef9ea3f137e5711f0dbe5f9263e8c009b7069d8a1acea822bd5e9dae0ae49c8"}, - {file = "greenlet-3.1.1-cp38-cp38-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:85f3ff71e2e60bd4b4932a043fbbe0f499e263c628390b285cb599154a3b03b1"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:95ffcf719966dd7c453f908e208e14cde192e09fde6c7186c8f1896ef778d8cd"}, - {file = "greenlet-3.1.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:03a088b9de532cbfe2ba2034b2b85e82df37874681e8c470d6fb2f8c04d7e4b7"}, - {file = "greenlet-3.1.1-cp38-cp38-win32.whl", hash = "sha256:8b8b36671f10ba80e159378df9c4f15c14098c4fd73a36b9ad715f057272fbef"}, - {file = "greenlet-3.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:7017b2be767b9d43cc31416aba48aab0d2309ee31b4dbf10a1d38fb7972bdf9d"}, - {file = "greenlet-3.1.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:396979749bd95f018296af156201d6211240e7a23090f50a8d5d18c370084dc3"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9d0ff5ad43e785350894d97e13633a66e2b50000e8a183a50a88d834752d42"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f6ff3b14f2df4c41660a7dec01045a045653998784bf8cfcb5a525bdffffbc8f"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:94ebba31df2aa506d7b14866fed00ac141a867e63143fe5bca82a8e503b36437"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73aaad12ac0ff500f62cebed98d8789198ea0e6f233421059fa68a5aa7220145"}, - {file = "greenlet-3.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:63e4844797b975b9af3a3fb8f7866ff08775f5426925e1e0bbcfe7932059a12c"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:7939aa3ca7d2a1593596e7ac6d59391ff30281ef280d8632fa03d81f7c5f955e"}, - {file = "greenlet-3.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d0028e725ee18175c6e422797c407874da24381ce0690d6b9396c204c7f7276e"}, - {file = "greenlet-3.1.1-cp39-cp39-win32.whl", hash = "sha256:5e06afd14cbaf9e00899fae69b24a32f2196c19de08fcb9f4779dd4f004e5e7c"}, - {file = "greenlet-3.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:3319aa75e0e0639bc15ff54ca327e8dc7a6fe404003496e3c6925cd3142e0e22"}, - {file = "greenlet-3.1.1.tar.gz", hash = "sha256:4ce3ac6cdb6adf7946475d7ef31777c26d94bccc377e070a7986bd2d5c515467"}, + {file = "greenlet-3.5.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:9df9daae96848508450011d0d86ed7c95f8829a354ce438284a77b24896fd1f8"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:01e32e9d2b1714a2b06184cb3071ff2a2fd9bc7d065e39198ab21f7253dad421"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:0488ca77c94da5e09d1d9958f98b58cebba1b8fd9664c24898499133de927574"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bc18b8d33e6976804b9b792fe11cb3b1fee8b646e8a9e20bf521a429ddf73520"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d9e19257794e28821c9ebd5e23f86d7c267cd9d390089374f068d2049f949e3"}, + {file = "greenlet-3.5.2-cp310-cp310-manylinux_2_39_riscv64.whl", hash = "sha256:2c6d6bfa4fdd7c39a0dbf112cdf28edbd19c517c810eefb6e4e71b0d55933a4c"}, + {file = "greenlet-3.5.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:bf493b3c1c0a2324c49b0472e2280ba4665f3510d8115f6f807759a6163b15f7"}, + {file = "greenlet-3.5.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:561dd919c02236a613fbf226791cbd77ee5002cbd5cb7e838869aa3ac7a71e16"}, + {file = "greenlet-3.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:049827baab63dda8ab8ec5a6d07fc6eb0f418319cfc757fc8737a605e99ca1ad"}, + {file = "greenlet-3.5.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:d7792398872f89466c6671d5d193537eff163ecf7fac78d82e6ddc25017fb4f5"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:711028c953cd6ce5dc01bbb5a1747e3ad6bd8b2f7ded73778bb936e8dab9e3b6"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5eba55076d79e8a5176e6925295cfb901ebc95dae493342ede22230f75d8bee2"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:1724499fc08388208408681c53c5062e9803c334e5a0bdaeb616228ba882aac8"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c1c1e5ad80f1f38ea479b83b39dccb20874cfe9ad5e52f87225fa294ba4d39a1"}, + {file = "greenlet-3.5.2-cp311-cp311-manylinux_2_39_riscv64.whl", hash = "sha256:e976f9f6941f57d87a194c91868622c8b22a142a741d2fde31655c319133ade6"}, + {file = "greenlet-3.5.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9e194b996aa1b89d933cfe136e5eb39b22a8b72ba59d376ef39a55bca4dbf47f"}, + {file = "greenlet-3.5.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4e554809538bd4867f24421b43abde170f9c9b8192149b30df5e164bcac6124f"}, + {file = "greenlet-3.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:e063263ce9047878480d7e536012fc8b7c8e1922989eb5f03b9ab998a2ee7b7e"}, + {file = "greenlet-3.5.2-cp311-cp311-win_arm64.whl", hash = "sha256:a3f76a94e2d6e1fee8f302265679d8cc47d71a203936dd03c6e2ace0f9cfd46d"}, + {file = "greenlet-3.5.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:76dae33e97b52743a19210931ee3e78a88fe1438bc2fc4ee5e7512d289bfad4f"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30252d191d6959df1d040b559a38fc017139606c5ecc2ad00416557c0355d742"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1adc23c50f22b0f5979521909a8360ab4a3d3bef8b641ce633a04cf1b1c967ea"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:87359c23eb4e8f1b16da68faad29bf5aeb80e3628d7d8e4aa2e41c36879ddedd"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1f052fff492c52fdfa99bd3b3c1389a53de37dae76a0562741417f0d018f02b3"}, + {file = "greenlet-3.5.2-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:f4d67c1684db3f9782c37ee4bade3f86f5a23a8fcf3f8359224106018ca40728"}, + {file = "greenlet-3.5.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:120b77c2a18ebf629c3a7886f68c6d01e065654844ad468f15bb93ace66f2094"}, + {file = "greenlet-3.5.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a850f6224088ef7dcc70f1a545cb6b3d119c35d6dca63b925b9f35da0635cdad"}, + {file = "greenlet-3.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:89da99ee8345b458ea2f16831dad31c88ddcdec454b48704d569a0b8fb28f146"}, + {file = "greenlet-3.5.2-cp312-cp312-win_arm64.whl", hash = "sha256:ca92411942154023c65851e6077d8ca0d00f19de5fa80bb2c6f196ff6c920ba9"}, + {file = "greenlet-3.5.2-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:0629377725977252159de1ebd3c6e49c170a63856e585446797bb3d66d4d9c34"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2ddf9eddc617681108dd071b3feabf3f4a4cd64846254aec4d4ceda098b639a"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f41feb9f2b59e2e61ac9bea4e344ddd9396bf3cacb2583f73a3595ed7df6f8e7"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9dc23f0e5ad76415457212a4b947d22ebe4dc80baf02adf7dd5647a90f38bb4e"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:09201fa698768db245920b00fdc86ee3e73540f01ca6db162be9632642e1a473"}, + {file = "greenlet-3.5.2-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:423167363c510a75b649f5cd58d873c29498ea03598b9e4b1c3b73e0f899f3d5"}, + {file = "greenlet-3.5.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a1759fa4f14c398508cf20dc8037de55cc23ae8bd14c185c2718257837195ca5"}, + {file = "greenlet-3.5.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b9318cdeb9abdbfdd8bc8464ee4a06dffde2c7846e1def138365a6240ab2c9a5"}, + {file = "greenlet-3.5.2-cp313-cp313-win_amd64.whl", hash = "sha256:2c3b3311af72b3d3b03cc0f1ffd11f072e834be5d0444105cf715fc44434e39c"}, + {file = "greenlet-3.5.2-cp313-cp313-win_arm64.whl", hash = "sha256:f9bbd6216c45a563c2a61e478e038b439d9f248bde44f775ea37d339da643af4"}, + {file = "greenlet-3.5.2-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:1c31219badba285858ba8ed117f403dea7fafee6bade9a1991875aae530c3ceb"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6f96ed6f4adc1066954ae95f45717657cb67468ef3b89e9a3632e14a625a8f39"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5795e883e915333c0d5648faaa691857fbc7180136883edc377f50f0d509c2a8"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6e9e49d732ee92a189bb7035e293029244aeba648297a9b856dc733d17ca7f0d"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:26aed8d9503ca78889141a9739d71b383efea5f472a7c522b5410f7eb2a1b163"}, + {file = "greenlet-3.5.2-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:537c5c4f30395020bb9f48f53146070e3b997c3c75da14011ab732aaa19ce3ef"}, + {file = "greenlet-3.5.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:dbebc038fcdda8f8f21cce985fd04e34e0f42007e7fc7ab7ad285caf77974b95"}, + {file = "greenlet-3.5.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a207023f1cf8695fd82580b8099c09c5809be18bc2282362cdfb965dd884a317"}, + {file = "greenlet-3.5.2-cp314-cp314-win_amd64.whl", hash = "sha256:c674a1dd4fe41f6a93febe7ab366ceabf15080ea31a9307811c56dac5f435f73"}, + {file = "greenlet-3.5.2-cp314-cp314-win_arm64.whl", hash = "sha256:3c417cd6c593bbbef6f7aa31a79f37d3db7d18832fc56b694a2150130bde784e"}, + {file = "greenlet-3.5.2-cp314-cp314t-macosx_11_0_universal2.whl", hash = "sha256:a96457a30384de52d9c5d2fd33abf6c1daae3db392cd556738f408b1a79a1cf0"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4af5d4961818ab651d09c1448a03b1ba2a1726a076266ebb62330bab9f3238c"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a1789a6244ea1ba61fd4386c9a6a31873e9b0234762103364be98ef87dcb19f3"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2ee6288f1933d698b4f098127ed17bda2910a75d2807915bd16294a972055d6c"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3be00501fb4a8c37f6b4b3c4773808ceb26ea65c7ea64fd5735d0f330b3786de"}, + {file = "greenlet-3.5.2-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:b4cad42662c796334c2d24607c411e3ed82481c1fb4e1e8ec3a5a8416060092e"}, + {file = "greenlet-3.5.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1d554cd96841a68d464d75a3736f8e87408a7b02b1930a75fa32feb408ad62f8"}, + {file = "greenlet-3.5.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3dff6cd3aac35f6cd3fc23460105acf576f5faf6c378de0bc088bf37c913864a"}, + {file = "greenlet-3.5.2-cp314-cp314t-win_amd64.whl", hash = "sha256:36cfea2aa075d544617176b2e84450480f0797070ad8799a8c41ada2fe449d32"}, + {file = "greenlet-3.5.2-cp315-cp315-macosx_11_0_universal2.whl", hash = "sha256:a0314aa832c94633355dc6f3ee54f195159533355a323f26926fc63b98b2ccbb"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24c59cb7db9d5c694cb8fd0c76eef8e456b2123afdfa7e4b8f2a67a0860d7682"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7bb811753703739ad318112f16eccfaabdac050037b6d092debaa8b23566b4ce"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2debcd0ef9455b7d4879589903efc8e497d4b8fb8c0ae772309e44d1ca5e957f"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6d78b5c1c178dad90447f1b8452262709d3eef4c98f825569e74c9d0b2260ac9"}, + {file = "greenlet-3.5.2-cp315-cp315-manylinux_2_39_riscv64.whl", hash = "sha256:9558cae989faeab6fbb425cd98a0cfa4190a47fba6443973fbee0a1eb0b0b6c3"}, + {file = "greenlet-3.5.2-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:0977af2df83136f81c1f76e76d4e2fe7d0dc56ea9c101a86af26a95190b9ca32"}, + {file = "greenlet-3.5.2-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:f9ed777c6891d8253e54468576f55e27f8fc1a662a664f946a191003574c0a74"}, + {file = "greenlet-3.5.2-cp315-cp315-win_amd64.whl", hash = "sha256:c0ea4eb3de23f0bac1d75205e10ccfa9b418b17b01a2d7bf19e3b69dda08900a"}, + {file = "greenlet-3.5.2-cp315-cp315-win_arm64.whl", hash = "sha256:7a7bfc200be40d04961d7e80e8337d726c0c1a50777e588123c3ed8ba731dcb9"}, + {file = "greenlet-3.5.2-cp315-cp315t-macosx_11_0_universal2.whl", hash = "sha256:98a52d6a50d4deaba304331d83ee3e10ebbdc1517fcca40b2715d1de4534065c"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1587ff8b58fdf806993ed1490a06ac19c22d47b219c68b30954380029045d8d4"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:feb721811d2754bfd16b48de151dd6b1f222c048e625151f2ca44cfdfd69f59c"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a9476cbead736dc48ce89e3cd97acff95ecc48cbf21273603a438f9870c4a014"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7fe6062b1f35534e1e8fb28dfed406cf4eeff3e0bca3a0d9f8ff69f20a4abb00"}, + {file = "greenlet-3.5.2-cp315-cp315t-manylinux_2_39_riscv64.whl", hash = "sha256:5930d3946ecae99fa7fc0e3f3ae515426ad85058ebd9bfc6c00cca8016e6206b"}, + {file = "greenlet-3.5.2-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b4ac902af825cbac8e9b2fccab8122236fd2ba6c8b71a080116d2c2ec72671b1"}, + {file = "greenlet-3.5.2-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:6f1e473c06ae8be00c9034c2bb10fa277b08a93287e3111c395b839f01d27e1f"}, + {file = "greenlet-3.5.2-cp315-cp315t-win_amd64.whl", hash = "sha256:3c2315045f9983e2e50d7e89d95405c21bddb8745f2da4487bc080ab3525f904"}, + {file = "greenlet-3.5.2-cp315-cp315t-win_arm64.whl", hash = "sha256:db548d5ab6c2a8ead82c013f875090d79b5d7d2b67fc513934ce6cf66492ad7f"}, + {file = "greenlet-3.5.2.tar.gz", hash = "sha256:c1b906220d83c140361cdd12eef970fb5881a168b98ee58a43786426173da14c"}, ] [package.extras] docs = ["Sphinx", "furo"] -test = ["objgraph", "psutil"] +test = ["objgraph", "psutil", "setuptools"] [[package]] name = "grpcio" -version = "1.67.0" +version = "1.81.1" description = "HTTP/2-based RPC framework" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "grpcio-1.67.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:bd79929b3bb96b54df1296cd3bf4d2b770bd1df6c2bdf549b49bab286b925cdc"}, - {file = "grpcio-1.67.0-cp310-cp310-macosx_12_0_universal2.whl", hash = "sha256:16724ffc956ea42967f5758c2f043faef43cb7e48a51948ab593570570d1e68b"}, - {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:2b7183c80b602b0ad816315d66f2fb7887614ead950416d60913a9a71c12560d"}, - {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:efe32b45dd6d118f5ea2e5deaed417d8a14976325c93812dd831908522b402c9"}, - {file = "grpcio-1.67.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe89295219b9c9e47780a0f1c75ca44211e706d1c598242249fe717af3385ec8"}, - {file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa8d025fae1595a207b4e47c2e087cb88d47008494db258ac561c00877d4c8f8"}, - {file = "grpcio-1.67.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f95e15db43e75a534420e04822df91f645664bf4ad21dfaad7d51773c80e6bb4"}, - {file = "grpcio-1.67.0-cp310-cp310-win32.whl", hash = "sha256:a6b9a5c18863fd4b6624a42e2712103fb0f57799a3b29651c0e5b8119a519d65"}, - {file = "grpcio-1.67.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6eb68493a05d38b426604e1dc93bfc0137c4157f7ab4fac5771fd9a104bbaa6"}, - {file = "grpcio-1.67.0-cp311-cp311-linux_armv7l.whl", hash = "sha256:e91d154689639932305b6ea6f45c6e46bb51ecc8ea77c10ef25aa77f75443ad4"}, - {file = "grpcio-1.67.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cb204a742997277da678611a809a8409657b1398aaeebf73b3d9563b7d154c13"}, - {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_aarch64.whl", hash = "sha256:ae6de510f670137e755eb2a74b04d1041e7210af2444103c8c95f193340d17ee"}, - {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:74b900566bdf68241118f2918d312d3bf554b2ce0b12b90178091ea7d0a17b3d"}, - {file = "grpcio-1.67.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a4e95e43447a02aa603abcc6b5e727d093d161a869c83b073f50b9390ecf0fa8"}, - {file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0bb94e66cd8f0baf29bd3184b6aa09aeb1a660f9ec3d85da615c5003154bc2bf"}, - {file = "grpcio-1.67.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:82e5bd4b67b17c8c597273663794a6a46a45e44165b960517fe6d8a2f7f16d23"}, - {file = "grpcio-1.67.0-cp311-cp311-win32.whl", hash = "sha256:7fc1d2b9fd549264ae585026b266ac2db53735510a207381be509c315b4af4e8"}, - {file = "grpcio-1.67.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac11ecb34a86b831239cc38245403a8de25037b448464f95c3315819e7519772"}, - {file = "grpcio-1.67.0-cp312-cp312-linux_armv7l.whl", hash = "sha256:227316b5631260e0bef8a3ce04fa7db4cc81756fea1258b007950b6efc90c05d"}, - {file = "grpcio-1.67.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:d90cfdafcf4b45a7a076e3e2a58e7bc3d59c698c4f6470b0bb13a4d869cf2273"}, - {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_aarch64.whl", hash = "sha256:77196216d5dd6f99af1c51e235af2dd339159f657280e65ce7e12c1a8feffd1d"}, - {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15c05a26a0f7047f720da41dc49406b395c1470eef44ff7e2c506a47ac2c0591"}, - {file = "grpcio-1.67.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3840994689cc8cbb73d60485c594424ad8adb56c71a30d8948d6453083624b52"}, - {file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:5a1e03c3102b6451028d5dc9f8591131d6ab3c8a0e023d94c28cb930ed4b5f81"}, - {file = "grpcio-1.67.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:682968427a63d898759474e3b3178d42546e878fdce034fd7474ef75143b64e3"}, - {file = "grpcio-1.67.0-cp312-cp312-win32.whl", hash = "sha256:d01793653248f49cf47e5695e0a79805b1d9d4eacef85b310118ba1dfcd1b955"}, - {file = "grpcio-1.67.0-cp312-cp312-win_amd64.whl", hash = "sha256:985b2686f786f3e20326c4367eebdaed3e7aa65848260ff0c6644f817042cb15"}, - {file = "grpcio-1.67.0-cp313-cp313-linux_armv7l.whl", hash = "sha256:8c9a35b8bc50db35ab8e3e02a4f2a35cfba46c8705c3911c34ce343bd777813a"}, - {file = "grpcio-1.67.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:42199e704095b62688998c2d84c89e59a26a7d5d32eed86d43dc90e7a3bd04aa"}, - {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_aarch64.whl", hash = "sha256:c4c425f440fb81f8d0237c07b9322fc0fb6ee2b29fbef5f62a322ff8fcce240d"}, - {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:323741b6699cd2b04a71cb38f502db98f90532e8a40cb675393d248126a268af"}, - {file = "grpcio-1.67.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:662c8e105c5e5cee0317d500eb186ed7a93229586e431c1bf0c9236c2407352c"}, - {file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:f6bd2ab135c64a4d1e9e44679a616c9bc944547357c830fafea5c3caa3de5153"}, - {file = "grpcio-1.67.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:2f55c1e0e2ae9bdd23b3c63459ee4c06d223b68aeb1961d83c48fb63dc29bc03"}, - {file = "grpcio-1.67.0-cp313-cp313-win32.whl", hash = "sha256:fd6bc27861e460fe28e94226e3673d46e294ca4673d46b224428d197c5935e69"}, - {file = "grpcio-1.67.0-cp313-cp313-win_amd64.whl", hash = "sha256:cf51d28063338608cd8d3cd64677e922134837902b70ce00dad7f116e3998210"}, - {file = "grpcio-1.67.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:7f200aca719c1c5dc72ab68be3479b9dafccdf03df530d137632c534bb6f1ee3"}, - {file = "grpcio-1.67.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:0892dd200ece4822d72dd0952f7112c542a487fc48fe77568deaaa399c1e717d"}, - {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:f4d613fbf868b2e2444f490d18af472ccb47660ea3df52f068c9c8801e1f3e85"}, - {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0c69bf11894cad9da00047f46584d5758d6ebc9b5950c0dc96fec7e0bce5cde9"}, - {file = "grpcio-1.67.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9bca3ca0c5e74dea44bf57d27e15a3a3996ce7e5780d61b7c72386356d231db"}, - {file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:014dfc020e28a0d9be7e93a91f85ff9f4a87158b7df9952fe23cc42d29d31e1e"}, - {file = "grpcio-1.67.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d4ea4509d42c6797539e9ec7496c15473177ce9abc89bc5c71e7abe50fc25737"}, - {file = "grpcio-1.67.0-cp38-cp38-win32.whl", hash = "sha256:9d75641a2fca9ae1ae86454fd25d4c298ea8cc195dbc962852234d54a07060ad"}, - {file = "grpcio-1.67.0-cp38-cp38-win_amd64.whl", hash = "sha256:cff8e54d6a463883cda2fab94d2062aad2f5edd7f06ae3ed030f2a74756db365"}, - {file = "grpcio-1.67.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:62492bd534979e6d7127b8a6b29093161a742dee3875873e01964049d5250a74"}, - {file = "grpcio-1.67.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eef1dce9d1a46119fd09f9a992cf6ab9d9178b696382439446ca5f399d7b96fe"}, - {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:f623c57a5321461c84498a99dddf9d13dac0e40ee056d884d6ec4ebcab647a78"}, - {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:54d16383044e681f8beb50f905249e4e7261dd169d4aaf6e52eab67b01cbbbe2"}, - {file = "grpcio-1.67.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b2a44e572fb762c668e4812156b81835f7aba8a721b027e2d4bb29fb50ff4d33"}, - {file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:391df8b0faac84d42f5b8dfc65f5152c48ed914e13c522fd05f2aca211f8bfad"}, - {file = "grpcio-1.67.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:cfd9306511fdfc623a1ba1dc3bc07fbd24e6cfbe3c28b4d1e05177baa2f99617"}, - {file = "grpcio-1.67.0-cp39-cp39-win32.whl", hash = "sha256:30d47dbacfd20cbd0c8be9bfa52fdb833b395d4ec32fe5cff7220afc05d08571"}, - {file = "grpcio-1.67.0-cp39-cp39-win_amd64.whl", hash = "sha256:f55f077685f61f0fbd06ea355142b71e47e4a26d2d678b3ba27248abfe67163a"}, - {file = "grpcio-1.67.0.tar.gz", hash = "sha256:e090b2553e0da1c875449c8e75073dd4415dd71c9bde6a406240fdf4c0ee467c"}, + {file = "grpcio-1.81.1-cp310-cp310-linux_armv7l.whl", hash = "sha256:6f9a0c9c1cc15c112d1c053064fd032b64917062292c3d70aea280e02ae10b77"}, + {file = "grpcio-1.81.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:69ef28e54fc85397f91b8c19592b8ef3d81952080366914823bd8572a2958120"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:15641444eca4a29358107b3dceb74c1c6305c55c822fd199b458aaea4068a7fb"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:d4b2dddfc219f54f956ccd53cf76a1d338ffe68fc7f2849ec9c7feb9927ff692"}, + {file = "grpcio-1.81.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ca1cc11d82677b9662082e5478b7528e2b7db7beaa6bdff42bd62789d81be399"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa2ba7d2ad6df4d80127cea65e5b8d5e2c3adbf153ff4804452836328aca7c54"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:592b5fee597faa91cce2dd294dd7d9a1c83d76c4dbf877e33ec1adb866b2fbed"}, + {file = "grpcio-1.81.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:62481553b1793a27e9b9c3cf9e5bd483ef045ca72462592074b46d42b0c4d9b9"}, + {file = "grpcio-1.81.1-cp310-cp310-win32.whl", hash = "sha256:bb693b1e3d9a2f3fd228e2110daf4b5aeedb36761ca1e4282f74725f6d89f611"}, + {file = "grpcio-1.81.1-cp310-cp310-win_amd64.whl", hash = "sha256:88268ca418cacea64cecb0d1d600d3c6b3a8038fcba02e1e205178c5b1f47661"}, + {file = "grpcio-1.81.1-cp311-cp311-linux_armv7l.whl", hash = "sha256:d71d30f2d92f67d944631c523713934fee37292469e182ebcd2c1dd8a64ce53f"}, + {file = "grpcio-1.81.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:b137f4bf3ada9dc44d411478decc6ff09a79ed30b306cd2abaa98408c3588137"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a3acb384427816dd5d470f47e62137b87f74da694faa8a50147012cf40df276a"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:f9a0ebbe45c29b5e5866593c12b78bd9035f0f0f0d4bc8361680cd580d99db49"}, + {file = "grpcio-1.81.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0a37165cc80b1a368384b383e63a4c38116a10467ae44c904d2d7468c4470ec2"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6282caffb41ec326d4cb67ca9cf53b739d1b2f975a2acb498c7418e9f7d9a416"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a35009284d0d3d5c2c9601c164a911b8b4331608d98a9a66d47d97bb2f522b70"}, + {file = "grpcio-1.81.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1b22c80559854b789a01fd89e8929b3798a156c0829b5282a8939f33ad4115ad"}, + {file = "grpcio-1.81.1-cp311-cp311-win32.whl", hash = "sha256:428bec0161b48d8cf583c068591bc0016d0d9cfff52462b72b3884861ea768c5"}, + {file = "grpcio-1.81.1-cp311-cp311-win_amd64.whl", hash = "sha256:30e825f6848d9f18bba350ed6c75c1b02a0b5184474a31db9a32b1fa66fd8c79"}, + {file = "grpcio-1.81.1-cp312-cp312-linux_armv7l.whl", hash = "sha256:8b39472beafc0bdcafc4c8c73ad082ebfdb449d566897a61e7acb4fa88089115"}, + {file = "grpcio-1.81.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:12b7524c88d4026d3dcb7b0ebe16b6714f3b4af402ddd0f0639ab064a00c87c3"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:1e123f9b37edb8375fd74130d1f69c944bbf0a7b06761ae7211154b8759e94d2"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:2c2e2ae6867c2966b8daccc836d54a13218e0007e9a490aeb81dd05be64d22d7"}, + {file = "grpcio-1.81.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:766bc7c9a9c340342f4c864ccbda8e78111e4751f13b895812b9c148fb79e9d0"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b259a04a737cb3496be0901328eb8b7552ed8df4865d8c8f1cf1bffcfc0776a3"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:85b10a45b8993d195c4f3ff57025b8d1e11834909ee475c403bfa60cb4caefaf"}, + {file = "grpcio-1.81.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8ea1936c26b99999b27479853039a7f34713f56c49375ad52b38535ec93a796c"}, + {file = "grpcio-1.81.1-cp312-cp312-win32.whl", hash = "sha256:a185a04039df6cae8648bc8ab6d6fde7bf94f7188ecf7828e76ac52eef1e41d6"}, + {file = "grpcio-1.81.1-cp312-cp312-win_amd64.whl", hash = "sha256:3ad74f8bb1a18963914c5452d289422830b39459e8776ebbcd207be1fbfb1d94"}, + {file = "grpcio-1.81.1-cp313-cp313-linux_armv7l.whl", hash = "sha256:b10e1ff4756ed27d5a29d7fc79cfce7ef1ff56ad20025b89bac7cf79e09abbbe"}, + {file = "grpcio-1.81.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:819edbdcb42ab8598b494bcf0222684bbb7a3c772bd1b1f0be7e029a6063c28e"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c5bf2dc311127d91230cc79b92188c082634a06cf66c5234db49a43b910183b0"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:e8ca6a1fcdb2943c9cbc1804a1baf3acb6071d72a471591678ded84218006e14"}, + {file = "grpcio-1.81.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e64dd101d380a115cc5a0c7856788adb535f1a4e21fc543775602f8be95180ae"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:98a07f9bf591e3a8919797bee1c53f026ba4acd587e5a4404c8e57c9ec36b2a5"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c261d74b1a945cf895a9d6eccd1685a8e837531beaab782da4d630a8d12deffb"}, + {file = "grpcio-1.81.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:58ad1131c300d3c9b933802b3cc4dc69d380822935ba50b28703156ea826fbf7"}, + {file = "grpcio-1.81.1-cp313-cp313-win32.whl", hash = "sha256:78e29211f26da2fdd0e9c6d2b79f489476140cf7029b6a64808ade7ca4156a42"}, + {file = "grpcio-1.81.1-cp313-cp313-win_amd64.whl", hash = "sha256:edb59506291b647a30884b1d51a599d605f40b20af4a7dc3d33786a47a31de60"}, + {file = "grpcio-1.81.1-cp314-cp314-linux_armv7l.whl", hash = "sha256:506f48f2f9c29b143fca3dad7b0d518c188b6c9648c75a2ae6e2d9f2c13a060b"}, + {file = "grpcio-1.81.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d865db4a6318e1c1bea83292e0ed231090538fc4ca45425b0f0480eb338bbc6e"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e2aa72e3ce1770317ef534f63d397b55e130725f5149bd36077c3b539019db27"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:0490c30c261eded63f3f354979f9dc4502a9fb944cccb60cd9dc85f5a7349854"}, + {file = "grpcio-1.81.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:410482da976329fe5f4067270401b12cf2bd552ff8020f054ecfaddb5475f9d6"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e3657301562ac3cb8018d30d0d3ebfa39932239f7b5703422057ef14b69949f5"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:24c8e57504c8f45b237e40b99262d181071e5099a07053695b75d97bb53053a0"}, + {file = "grpcio-1.81.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b427c19380991a4eaab2f6144b64b99b412043314c6bf4ab544f97bb31ee4190"}, + {file = "grpcio-1.81.1-cp314-cp314-win32.whl", hash = "sha256:61233fe8951e5c85dff81c2458b6528624760166946b5b47ea150a589168411f"}, + {file = "grpcio-1.81.1-cp314-cp314-win_amd64.whl", hash = "sha256:3768a5ff1b2125e6f552e561b6b2dca0e64982d8949689b4df145cf8b98d7821"}, + {file = "grpcio-1.81.1.tar.gz", hash = "sha256:6fa10a767143a5e82e8eaab53918af0cd8909a57a27f8cb2288b80a613ac671b"}, ] +[package.dependencies] +typing-extensions = ">=4.12,<5.0" + [package.extras] -protobuf = ["grpcio-tools (>=1.67.0)"] +protobuf = ["grpcio-tools (>=1.81.1)"] [[package]] name = "idna" @@ -1193,26 +1189,6 @@ files = [ [package.extras] all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] -[[package]] -name = "importlib-metadata" -version = "8.4.0" -description = "Read metadata from Python packages" -optional = false -python-versions = ">=3.8" -groups = ["main", "test"] -files = [ - {file = "importlib_metadata-8.4.0-py3-none-any.whl", hash = "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1"}, - {file = "importlib_metadata-8.4.0.tar.gz", hash = "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5"}, -] - -[package.dependencies] -zipp = ">=0.5" - -[package.extras] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -perf = ["ipython"] -test = ["flufl.flake8", "importlib-resources (>=1.3) ; python_version < \"3.9\"", "jaraco.test (>=5.4)", "packaging", "pyfakefs", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-perf (>=0.9.2)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] - [[package]] name = "iniconfig" version = "2.0.0" @@ -1272,89 +1248,103 @@ files = [ [[package]] name = "librt" -version = "0.7.8" +version = "0.11.0" description = "Mypyc runtime library" optional = false python-versions = ">=3.9" groups = ["dev"] markers = "platform_python_implementation != \"PyPy\"" files = [ - {file = "librt-0.7.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b45306a1fc5f53c9330fbee134d8b3227fe5da2ab09813b892790400aa49352d"}, - {file = "librt-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:864c4b7083eeee250ed55135d2127b260d7eb4b5e953a9e5df09c852e327961b"}, - {file = "librt-0.7.8-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6938cc2de153bc927ed8d71c7d2f2ae01b4e96359126c602721340eb7ce1a92d"}, - {file = "librt-0.7.8-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66daa6ac5de4288a5bbfbe55b4caa7bf0cd26b3269c7a476ffe8ce45f837f87d"}, - {file = "librt-0.7.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4864045f49dc9c974dadb942ac56a74cd0479a2aafa51ce272c490a82322ea3c"}, - {file = "librt-0.7.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a36515b1328dc5b3ffce79fe204985ca8572525452eacabee2166f44bb387b2c"}, - {file = "librt-0.7.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b7e7f140c5169798f90b80d6e607ed2ba5059784968a004107c88ad61fb3641d"}, - {file = "librt-0.7.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff71447cb778a4f772ddc4ce360e6ba9c95527ed84a52096bd1bbf9fee2ec7c0"}, - {file = "librt-0.7.8-cp310-cp310-win32.whl", hash = "sha256:047164e5f68b7a8ebdf9fae91a3c2161d3192418aadd61ddd3a86a56cbe3dc85"}, - {file = "librt-0.7.8-cp310-cp310-win_amd64.whl", hash = "sha256:d6f254d096d84156a46a84861183c183d30734e52383602443292644d895047c"}, - {file = "librt-0.7.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ff3e9c11aa260c31493d4b3197d1e28dd07768594a4f92bec4506849d736248f"}, - {file = "librt-0.7.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddb52499d0b3ed4aa88746aaf6f36a08314677d5c346234c3987ddc506404eac"}, - {file = "librt-0.7.8-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e9c0afebbe6ce177ae8edba0c7c4d626f2a0fc12c33bb993d163817c41a7a05c"}, - {file = "librt-0.7.8-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:631599598e2c76ded400c0a8722dec09217c89ff64dc54b060f598ed68e7d2a8"}, - {file = "librt-0.7.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c1ba843ae20db09b9d5c80475376168feb2640ce91cd9906414f23cc267a1ff"}, - {file = "librt-0.7.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b5b007bb22ea4b255d3ee39dfd06d12534de2fcc3438567d9f48cdaf67ae1ae3"}, - {file = "librt-0.7.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbd79caaf77a3f590cbe32dc2447f718772d6eea59656a7dcb9311161b10fa75"}, - {file = "librt-0.7.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:87808a8d1e0bd62a01cafc41f0fd6818b5a5d0ca0d8a55326a81643cdda8f873"}, - {file = "librt-0.7.8-cp311-cp311-win32.whl", hash = "sha256:31724b93baa91512bd0a376e7cf0b59d8b631ee17923b1218a65456fa9bda2e7"}, - {file = "librt-0.7.8-cp311-cp311-win_amd64.whl", hash = "sha256:978e8b5f13e52cf23a9e80f3286d7546baa70bc4ef35b51d97a709d0b28e537c"}, - {file = "librt-0.7.8-cp311-cp311-win_arm64.whl", hash = "sha256:20e3946863d872f7cabf7f77c6c9d370b8b3d74333d3a32471c50d3a86c0a232"}, - {file = "librt-0.7.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9b6943885b2d49c48d0cff23b16be830ba46b0152d98f62de49e735c6e655a63"}, - {file = "librt-0.7.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46ef1f4b9b6cc364b11eea0ecc0897314447a66029ee1e55859acb3dd8757c93"}, - {file = "librt-0.7.8-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:907ad09cfab21e3c86e8f1f87858f7049d1097f77196959c033612f532b4e592"}, - {file = "librt-0.7.8-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2991b6c3775383752b3ca0204842743256f3ad3deeb1d0adc227d56b78a9a850"}, - {file = "librt-0.7.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03679b9856932b8c8f674e87aa3c55ea11c9274301f76ae8dc4d281bda55cf62"}, - {file = "librt-0.7.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3968762fec1b2ad34ce57458b6de25dbb4142713e9ca6279a0d352fa4e9f452b"}, - {file = "librt-0.7.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bb7a7807523a31f03061288cc4ffc065d684c39db7644c676b47d89553c0d714"}, - {file = "librt-0.7.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad64a14b1e56e702e19b24aae108f18ad1bf7777f3af5fcd39f87d0c5a814449"}, - {file = "librt-0.7.8-cp312-cp312-win32.whl", hash = "sha256:0241a6ed65e6666236ea78203a73d800dbed896cf12ae25d026d75dc1fcd1dac"}, - {file = "librt-0.7.8-cp312-cp312-win_amd64.whl", hash = "sha256:6db5faf064b5bab9675c32a873436b31e01d66ca6984c6f7f92621656033a708"}, - {file = "librt-0.7.8-cp312-cp312-win_arm64.whl", hash = "sha256:57175aa93f804d2c08d2edb7213e09276bd49097611aefc37e3fa38d1fb99ad0"}, - {file = "librt-0.7.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4c3995abbbb60b3c129490fa985dfe6cac11d88fc3c36eeb4fb1449efbbb04fc"}, - {file = "librt-0.7.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:44e0c2cbc9bebd074cf2cdbe472ca185e824be4e74b1c63a8e934cea674bebf2"}, - {file = "librt-0.7.8-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4d2f1e492cae964b3463a03dc77a7fe8742f7855d7258c7643f0ee32b6651dd3"}, - {file = "librt-0.7.8-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:451e7ffcef8f785831fdb791bd69211f47e95dc4c6ddff68e589058806f044c6"}, - {file = "librt-0.7.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3469e1af9f1380e093ae06bedcbdd11e407ac0b303a56bbe9afb1d6824d4982d"}, - {file = "librt-0.7.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f11b300027ce19a34f6d24ebb0a25fd0e24a9d53353225a5c1e6cadbf2916b2e"}, - {file = "librt-0.7.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4adc73614f0d3c97874f02f2c7fd2a27854e7e24ad532ea6b965459c5b757eca"}, - {file = "librt-0.7.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60c299e555f87e4c01b2eca085dfccda1dde87f5a604bb45c2906b8305819a93"}, - {file = "librt-0.7.8-cp313-cp313-win32.whl", hash = "sha256:b09c52ed43a461994716082ee7d87618096851319bf695d57ec123f2ab708951"}, - {file = "librt-0.7.8-cp313-cp313-win_amd64.whl", hash = "sha256:f8f4a901a3fa28969d6e4519deceab56c55a09d691ea7b12ca830e2fa3461e34"}, - {file = "librt-0.7.8-cp313-cp313-win_arm64.whl", hash = "sha256:43d4e71b50763fcdcf64725ac680d8cfa1706c928b844794a7aa0fa9ac8e5f09"}, - {file = "librt-0.7.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:be927c3c94c74b05128089a955fba86501c3b544d1d300282cc1b4bd370cb418"}, - {file = "librt-0.7.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7b0803e9008c62a7ef79058233db7ff6f37a9933b8f2573c05b07ddafa226611"}, - {file = "librt-0.7.8-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:79feb4d00b2a4e0e05c9c56df707934f41fcb5fe53fd9efb7549068d0495b758"}, - {file = "librt-0.7.8-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9122094e3f24aa759c38f46bd8863433820654927370250f460ae75488b66ea"}, - {file = "librt-0.7.8-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e03bea66af33c95ce3addf87a9bf1fcad8d33e757bc479957ddbc0e4f7207ac"}, - {file = "librt-0.7.8-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f1ade7f31675db00b514b98f9ab9a7698c7282dad4be7492589109471852d398"}, - {file = "librt-0.7.8-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a14229ac62adcf1b90a15992f1ab9c69ae8b99ffb23cb64a90878a6e8a2f5b81"}, - {file = "librt-0.7.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5bcaaf624fd24e6a0cb14beac37677f90793a96864c67c064a91458611446e83"}, - {file = "librt-0.7.8-cp314-cp314-win32.whl", hash = "sha256:7aa7d5457b6c542ecaed79cec4ad98534373c9757383973e638ccced0f11f46d"}, - {file = "librt-0.7.8-cp314-cp314-win_amd64.whl", hash = "sha256:3d1322800771bee4a91f3b4bd4e49abc7d35e65166821086e5afd1e6c0d9be44"}, - {file = "librt-0.7.8-cp314-cp314-win_arm64.whl", hash = "sha256:5363427bc6a8c3b1719f8f3845ea53553d301382928a86e8fab7984426949bce"}, - {file = "librt-0.7.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ca916919793a77e4a98d4a1701e345d337ce53be4a16620f063191f7322ac80f"}, - {file = "librt-0.7.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:54feb7b4f2f6706bb82325e836a01be805770443e2400f706e824e91f6441dde"}, - {file = "librt-0.7.8-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:39a4c76fee41007070f872b648cc2f711f9abf9a13d0c7162478043377b52c8e"}, - {file = "librt-0.7.8-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac9c8a458245c7de80bc1b9765b177055efff5803f08e548dd4bb9ab9a8d789b"}, - {file = "librt-0.7.8-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95b67aa7eff150f075fda09d11f6bfb26edffd300f6ab1666759547581e8f666"}, - {file = "librt-0.7.8-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:535929b6eff670c593c34ff435d5440c3096f20fa72d63444608a5aef64dd581"}, - {file = "librt-0.7.8-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:63937bd0f4d1cb56653dc7ae900d6c52c41f0015e25aaf9902481ee79943b33a"}, - {file = "librt-0.7.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf243da9e42d914036fd362ac3fa77d80a41cadcd11ad789b1b5eec4daaf67ca"}, - {file = "librt-0.7.8-cp314-cp314t-win32.whl", hash = "sha256:171ca3a0a06c643bd0a2f62a8944e1902c94aa8e5da4db1ea9a8daf872685365"}, - {file = "librt-0.7.8-cp314-cp314t-win_amd64.whl", hash = "sha256:445b7304145e24c60288a2f172b5ce2ca35c0f81605f5299f3fa567e189d2e32"}, - {file = "librt-0.7.8-cp314-cp314t-win_arm64.whl", hash = "sha256:8766ece9de08527deabcd7cb1b4f1a967a385d26e33e536d6d8913db6ef74f06"}, - {file = "librt-0.7.8-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c7e8f88f79308d86d8f39c491773cbb533d6cb7fa6476f35d711076ee04fceb6"}, - {file = "librt-0.7.8-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:389bd25a0db916e1d6bcb014f11aa9676cedaa485e9ec3752dfe19f196fd377b"}, - {file = "librt-0.7.8-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:73fd300f501a052f2ba52ede721232212f3b06503fa12665408ecfc9d8fd149c"}, - {file = "librt-0.7.8-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d772edc6a5f7835635c7562f6688e031f0b97e31d538412a852c49c9a6c92d5"}, - {file = "librt-0.7.8-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bfde8a130bd0f239e45503ab39fab239ace094d63ee1d6b67c25a63d741c0f71"}, - {file = "librt-0.7.8-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fdec6e2368ae4f796fc72fad7fd4bd1753715187e6d870932b0904609e7c878e"}, - {file = "librt-0.7.8-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:00105e7d541a8f2ee5be52caacea98a005e0478cfe78c8080fbb7b5d2b340c63"}, - {file = "librt-0.7.8-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c6f8947d3dfd7f91066c5b4385812c18be26c9d5a99ca56667547f2c39149d94"}, - {file = "librt-0.7.8-cp39-cp39-win32.whl", hash = "sha256:41d7bb1e07916aeb12ae4a44e3025db3691c4149ab788d0315781b4d29b86afb"}, - {file = "librt-0.7.8-cp39-cp39-win_amd64.whl", hash = "sha256:e90a8e237753c83b8e484d478d9a996dc5e39fd5bd4c6ce32563bc8123f132be"}, - {file = "librt-0.7.8.tar.gz", hash = "sha256:1a4ede613941d9c3470b0368be851df6bb78ab218635512d0370b27a277a0862"}, + {file = "librt-0.11.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6e94ebfcfa2d5e9926d6c3b9aa4617ffc42a845b4321fb84021b872358c82a0f"}, + {file = "librt-0.11.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ae627397a2f351560440d872d6f7c8dbb4072e57868e7b2fc5b8b430fe489d45"}, + {file = "librt-0.11.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc329359321b67d24efdf4bc69012b0597001649544db662c001db5a0184794c"}, + {file = "librt-0.11.0-cp310-cp310-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:7e82e642ab0f7608ce2fe53d76ca2280a9ee33a1b06556142c7c6fe80a86fc33"}, + {file = "librt-0.11.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:88145c15c67731d54283d135b03244028c750cc9edc334a96a4f5950ebdb2884"}, + {file = "librt-0.11.0-cp310-cp310-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9d36a51b3d93320b686588e27123f4995804dbf1bce81df78c02fc3c6eea9280"}, + {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d00f3ac06a2a8b246327f11e186a53a100a4d5c7ed52346367e5ec751d51586c"}, + {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:461bbceede621f1ffb8839755f8663e886087ee7af16294cab7fb4d782c62eeb"}, + {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:0cad8a4d6a8ff03c9b76f9414caccd78e7cfbc8a2e12fa334d8e1d9932753783"}, + {file = "librt-0.11.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:f37aa505b3cf60701562eddb32df74b12a9e380c207fd8b06dd157a943ac7ea0"}, + {file = "librt-0.11.0-cp310-cp310-win32.whl", hash = "sha256:94663a21534637f0e787ec2a2a756022df6e5b7b2335a5cdd7d8e33d68a2af89"}, + {file = "librt-0.11.0-cp310-cp310-win_amd64.whl", hash = "sha256:dec7db73758c2b54953fd8b7fe348c45188fe26b39ee18446196edd08453a5d4"}, + {file = "librt-0.11.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:93d95bd45b7d58343d8b90d904450a545144eec19a002511163426f8ab1fae29"}, + {file = "librt-0.11.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ee278c769a713638cdacd4c0436d72156e75df3ebc0166ab2b9dc43acc386c9"}, + {file = "librt-0.11.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f230cb1cbc9faaa616f9a678f530ebcf186e414b6bcbd88b960e4ba1b92428d5"}, + {file = "librt-0.11.0-cp311-cp311-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:5d63c855d86938d9de93e265c9bd8c705b51ec494de5738340ee93767a686e4b"}, + {file = "librt-0.11.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:993f028be9e96a08d31df3479ac80d99be374d17f3b78e4796b3fd3c913d4e89"}, + {file = "librt-0.11.0-cp311-cp311-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:258d73a0aa66a055e65b2e4d1b8cdb23b9d132c5bb915d9547d804fcaed116cc"}, + {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0827efe7854718f04aaddf6496e96960a956e676fe1d0f04eb41511fd8ad06d5"}, + {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7753e57d6e12d019c0d8786f1c09c709f4c3fcc57c3887b24e36e6c06ec938b7"}, + {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:11bd19822431cc21af9f27374e7ae2e58103c7d98bda823536a6c47f6bb2bb3d"}, + {file = "librt-0.11.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:22bdf239b219d3993761a148ffa134b19e52e9989c84f845d5d7b71d70a17412"}, + {file = "librt-0.11.0-cp311-cp311-win32.whl", hash = "sha256:46c60b61e308eb535fbd6fa622b1ee1bb2815691c1ad9c98bf7b84952ec3bc8d"}, + {file = "librt-0.11.0-cp311-cp311-win_amd64.whl", hash = "sha256:902e546ff044f579ff1c953ff5fce97b636fe9e3943996b2177710c6ef076f73"}, + {file = "librt-0.11.0-cp311-cp311-win_arm64.whl", hash = "sha256:65ac3bc20f78aa0ee5ae84baa68917f89fef4af63e941084dd019a0d0e749f0c"}, + {file = "librt-0.11.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b87504f1690a23b9a2cca841191a04f83895d4fc2dd04df91d82b1a04ca2ad46"}, + {file = "librt-0.11.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40071fc5fe0ce8daa6de616702314a01e1250711682b0523d6ab8d4525910cb3"}, + {file = "librt-0.11.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:137e79445c896a0ea7b265f52d23954e05b64222ee1af69e2cb34219067cbb67"}, + {file = "librt-0.11.0-cp312-cp312-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:cca6644054e78746d8d4ef238681f9c34ff8b584fe6b988ecebb8db3b15e622a"}, + {file = "librt-0.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d5b0eea49f5562861ee8d757a32ef7d559c1d35be2aaaa1ec28941d74c9ffc8a"}, + {file = "librt-0.11.0-cp312-cp312-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0d1029d7e1ae1a7e647ed6fb5df8c4ce2dffefb7a9f5fd1376a4554d96dac09f"}, + {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:bc3ce6b33c5828d9e80592011a5c584cb2ce86edbc4088405f70da47dc1d1b3b"}, + {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:936c5995f3514a42111f20099397d8177c79b4d7e70961e396c6f5a0a3566766"}, + {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:9bc0ca6ad9381cbe8e4aa6e5726e4c80c78115a6e9723c599ed1d73e092bc49d"}, + {file = "librt-0.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:070aa8c26c0a74774317a72df8851facc7f0f012a5b406557ac56992d92e1ec8"}, + {file = "librt-0.11.0-cp312-cp312-win32.whl", hash = "sha256:6bf14feb84b05ae945277395451998c89c54d0def4070eb5c08de544930b245a"}, + {file = "librt-0.11.0-cp312-cp312-win_amd64.whl", hash = "sha256:75672f0bc524ede266287d532d7923dbce94c7514ad07627bac3d0c6d92cc4d9"}, + {file = "librt-0.11.0-cp312-cp312-win_arm64.whl", hash = "sha256:2f10cf143e4a9bb0f4f5af568a00df94a2d69ef41c2579584454bb0fe5cc642c"}, + {file = "librt-0.11.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:78dc31f7fdfe9c9d0eb0e8f42d139db230e826415bbcabd9f0e9faaaee909894"}, + {file = "librt-0.11.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:fa475675db22290c3158e1d42326d0f5a65f04f44a0e68c3630a25b53560fb9c"}, + {file = "librt-0.11.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:621db29691044bdeda22e789e482e1b0f3a985d90e3426c9c6d17606416205ea"}, + {file = "librt-0.11.0-cp313-cp313-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:a9010e2ed5b3a9e158c5fd966b3ab7e834bb3d3aacc8f66c91dd4b57a3799230"}, + {file = "librt-0.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7c39513d8b7477a2e1ed8c43fc21c524e8d5a0f8d4e8b7b074dbdbe7820a08e2"}, + {file = "librt-0.11.0-cp313-cp313-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7aef3cf1d5af86e770ab04bfd993dfc4ae8b8c17f66fb77dd4a7d50de7bbb1a3"}, + {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:557183ddc36babe46b27dd60facbd5adb4492181a5be887587d57cda6e092f21"}, + {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:83d3e1f72bd42f6c5c0b7daec530c3f829bd02db42c70b8ddf0c2d90a2459930"}, + {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:4ce1f21fbe589bc1afd7872dece84fb0e1144f794a288e58a10d2c54a55c43be"}, + {file = "librt-0.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:970b09f7044ea2b64c9da42fd3d335666518cfd1c6e8a182c95da73d0214b41e"}, + {file = "librt-0.11.0-cp313-cp313-win32.whl", hash = "sha256:78fddc31cd4d3caa897ad5d31f856b1faadc9474021ad6cb182b9018793e254e"}, + {file = "librt-0.11.0-cp313-cp313-win_amd64.whl", hash = "sha256:8ca8aa88751a775870b764e93bad5135385f563cb8dcee399abf034ea4d3cb47"}, + {file = "librt-0.11.0-cp313-cp313-win_arm64.whl", hash = "sha256:96f044bb325fd9cf1a723015638c219e9143f0dfbc0ca54c565df2b7fc748b44"}, + {file = "librt-0.11.0-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:4a017a95e5837dc15a8c5661d60e05daa96b90908b1aa6b7acdf443cd25c8ebd"}, + {file = "librt-0.11.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:b1ecbd9819deccc39b7542bf4d2a740d8a620694d39989e58661d3763458f8d4"}, + {file = "librt-0.11.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7da327dacd7be8f8ec36547373550744a3cc0e536d54665cd83f8bcd961200e8"}, + {file = "librt-0.11.0-cp314-cp314-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:0dc56b1f8d06e60db362cc3fdae206681817f86ce4725d34511473487f12a34b"}, + {file = "librt-0.11.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05fb8fb2ab90e21c8d12ea240d744ad514da9baf381ebfa70d91d20d21713175"}, + {file = "librt-0.11.0-cp314-cp314-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cae74872be221df4374d10fec61f93ed1513b9546ea84f2c0bf73ab3e9bd0b03"}, + {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:32bcc918c0148eb7e3d57385125bac7e5f9e4359d05f07448b09f6f778c2f31c"}, + {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f9743fc99135d5f78d2454435615f6dec0473ca507c26ce9d92b10b562a280d3"}, + {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:5ba067f4aadae8fda802d91d2124c90c42195ff32d9161d3549e6d05cfe26f96"}, + {file = "librt-0.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:de3bf945454d032f9e390b85c4072e0a0570bf825421c8be0e71209fa65e1abe"}, + {file = "librt-0.11.0-cp314-cp314-win32.whl", hash = "sha256:d2277a05f6dcb9fd13db9566aac4fabd68c3ea1ea46ee5567d4eef8efa495a2f"}, + {file = "librt-0.11.0-cp314-cp314-win_amd64.whl", hash = "sha256:ab73e8db5e3f564d812c1f5c3a175930a5f9bc96ccb5e3b22a34d7858b401cf7"}, + {file = "librt-0.11.0-cp314-cp314-win_arm64.whl", hash = "sha256:aea3caa317752e3a466fa8af45d91ee0ea8c7fdd96e42b0a8dd9b76a7931eba1"}, + {file = "librt-0.11.0-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:d1b36540d7aaf9b9101b3a6f376c8d8e9f7a9aec93ed05918f2c69d493ffef72"}, + {file = "librt-0.11.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:efbb343ab2ce3540f4ecbe6315d677ed70f37cd9a72b1e58066c918ca83acbaa"}, + {file = "librt-0.11.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aa0dd688aab3f7914d3e6e5e3554978e0383312fb8e771d84be008a35b9ee548"}, + {file = "librt-0.11.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:f5fb36b8c6c63fdcbb1d526d94c0d1331610d43f4118cc1beb4efef4f3faacb2"}, + {file = "librt-0.11.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4a9a237d13addb93715b6fee74023d5ee3469b53fce527626c0e088aa585805f"}, + {file = "librt-0.11.0-cp314-cp314t-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5ddd17bd87b2c56ddd60e546a7984a2e64c4e8eab92fb4cf3830a48ad5469d51"}, + {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd43992b4473d42f12ff9e68326079f0696d9d4e6000e8f39a0238d482ba6ee2"}, + {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:f8e3e8056dd674e279741485e2e512d6e9a751c7455809d0114e6ebf8d781085"}, + {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:c1f708d8ae9c56cf38a903c44297243d2ec83fd82b396b977e0144a3e76217e3"}, + {file = "librt-0.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:0add982e0e7b9fc14cf4b33789d5f13f66581889b88c2f58099f6ce8f92617bd"}, + {file = "librt-0.11.0-cp314-cp314t-win32.whl", hash = "sha256:2b481d846ac894c4e8403c5fd0e87c5d11d6499e404b474602508a224ff531c8"}, + {file = "librt-0.11.0-cp314-cp314t-win_amd64.whl", hash = "sha256:28edb433edde181112a908c78907af28f964eabc15f4dd16c9d66c834302677c"}, + {file = "librt-0.11.0-cp314-cp314t-win_arm64.whl", hash = "sha256:dee008f20b542e3cd162ba338a7f9ec0f6d23d395f66fe8aeeec3c9d067ea253"}, + {file = "librt-0.11.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6bd72d903911d995ab666dbd1871f8b1e80925a699af8063fbf50053329fb05f"}, + {file = "librt-0.11.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0ef69ac715f3cd8e5cd252cb2aebfa72c015492aacc339d5d7bf8fef3c62c677"}, + {file = "librt-0.11.0-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:624a40c4a4ad7773315c287276cd024509b2c66ff5904f504bfc08d2c70293ab"}, + {file = "librt-0.11.0-cp39-cp39-manylinux2014_i686.manylinux_2_17_i686.manylinux_2_28_i686.whl", hash = "sha256:41dc19fe150b69716c8ece4f76773a9e8813fe3e35e032a58b4d46423fb8d7c0"}, + {file = "librt-0.11.0-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4e8bd98ea9c47ae90b319a087ab28dac493f1ffbc1ecd1f28fcdbf3b7e1108d1"}, + {file = "librt-0.11.0-cp39-cp39-manylinux_2_34_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:84308fc49423ce6475d1c5d1985cd69a8ca9f0325fc7d5f81bb690a3f3625d4e"}, + {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ff0fbaf5f44a21beeb0110f2ab64f45135a9536a834b79c0d1ef018f2786bbfa"}, + {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:9c028a9442a18e266955d364ce42259136e79a7ba14d773e0d778d5f70cd56f1"}, + {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:9f1692105a02bcf853f355032a5fdc5494358ef83d8fd22d16de375c85cec3f5"}, + {file = "librt-0.11.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7a80a71e1fda83cc752a9141e87aae7fef279538597564d670e9ce513f286192"}, + {file = "librt-0.11.0-cp39-cp39-win32.whl", hash = "sha256:140695816ddf3c86eb972981a26f35efd871c44b0c3aed44c8cd01749386617f"}, + {file = "librt-0.11.0-cp39-cp39-win_amd64.whl", hash = "sha256:92f7ff819c197fc30473190a12c2856f325ac90aabfccbeb2072d28cc2e234e3"}, + {file = "librt-0.11.0.tar.gz", hash = "sha256:075dc3ef4458a278e0195cbf6ac9d38808d9b906c5a6c7f7f79c3888276a3fb1"}, ] [[package]] @@ -1441,64 +1431,74 @@ files = [ [[package]] name = "mypy" -version = "1.19.1" +version = "1.20.2" description = "Optional static typing for Python" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["dev"] files = [ - {file = "mypy-1.19.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f05aa3d375b385734388e844bc01733bd33c644ab48e9684faa54e5389775ec"}, - {file = "mypy-1.19.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:022ea7279374af1a5d78dfcab853fe6a536eebfda4b59deab53cd21f6cd9f00b"}, - {file = "mypy-1.19.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee4c11e460685c3e0c64a4c5de82ae143622410950d6be863303a1c4ba0e36d6"}, - {file = "mypy-1.19.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de759aafbae8763283b2ee5869c7255391fbc4de3ff171f8f030b5ec48381b74"}, - {file = "mypy-1.19.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ab43590f9cd5108f41aacf9fca31841142c786827a74ab7cc8a2eacb634e09a1"}, - {file = "mypy-1.19.1-cp310-cp310-win_amd64.whl", hash = "sha256:2899753e2f61e571b3971747e302d5f420c3fd09650e1951e99f823bc3089dac"}, - {file = "mypy-1.19.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d8dfc6ab58ca7dda47d9237349157500468e404b17213d44fc1cb77bce532288"}, - {file = "mypy-1.19.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e3f276d8493c3c97930e354b2595a44a21348b320d859fb4a2b9f66da9ed27ab"}, - {file = "mypy-1.19.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2abb24cf3f17864770d18d673c85235ba52456b36a06b6afc1e07c1fdcd3d0e6"}, - {file = "mypy-1.19.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a009ffa5a621762d0c926a078c2d639104becab69e79538a494bcccb62cc0331"}, - {file = "mypy-1.19.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f7cee03c9a2e2ee26ec07479f38ea9c884e301d42c6d43a19d20fb014e3ba925"}, - {file = "mypy-1.19.1-cp311-cp311-win_amd64.whl", hash = "sha256:4b84a7a18f41e167f7995200a1d07a4a6810e89d29859df936f1c3923d263042"}, - {file = "mypy-1.19.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a8174a03289288c1f6c46d55cef02379b478bfbc8e358e02047487cad44c6ca1"}, - {file = "mypy-1.19.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ffcebe56eb09ff0c0885e750036a095e23793ba6c2e894e7e63f6d89ad51f22e"}, - {file = "mypy-1.19.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b64d987153888790bcdb03a6473d321820597ab8dd9243b27a92153c4fa50fd2"}, - {file = "mypy-1.19.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c35d298c2c4bba75feb2195655dfea8124d855dfd7343bf8b8c055421eaf0cf8"}, - {file = "mypy-1.19.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34c81968774648ab5ac09c29a375fdede03ba253f8f8287847bd480782f73a6a"}, - {file = "mypy-1.19.1-cp312-cp312-win_amd64.whl", hash = "sha256:b10e7c2cd7870ba4ad9b2d8a6102eb5ffc1f16ca35e3de6bfa390c1113029d13"}, - {file = "mypy-1.19.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e3157c7594ff2ef1634ee058aafc56a82db665c9438fd41b390f3bde1ab12250"}, - {file = "mypy-1.19.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bdb12f69bcc02700c2b47e070238f42cb87f18c0bc1fc4cdb4fb2bc5fd7a3b8b"}, - {file = "mypy-1.19.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f859fb09d9583a985be9a493d5cfc5515b56b08f7447759a0c5deaf68d80506e"}, - {file = "mypy-1.19.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c9a6538e0415310aad77cb94004ca6482330fece18036b5f360b62c45814c4ef"}, - {file = "mypy-1.19.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:da4869fc5e7f62a88f3fe0b5c919d1d9f7ea3cef92d3689de2823fd27e40aa75"}, - {file = "mypy-1.19.1-cp313-cp313-win_amd64.whl", hash = "sha256:016f2246209095e8eda7538944daa1d60e1e8134d98983b9fc1e92c1fc0cb8dd"}, - {file = "mypy-1.19.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:06e6170bd5836770e8104c8fdd58e5e725cfeb309f0a6c681a811f557e97eac1"}, - {file = "mypy-1.19.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:804bd67b8054a85447c8954215a906d6eff9cabeabe493fb6334b24f4bfff718"}, - {file = "mypy-1.19.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21761006a7f497cb0d4de3d8ef4ca70532256688b0523eee02baf9eec895e27b"}, - {file = "mypy-1.19.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28902ee51f12e0f19e1e16fbe2f8f06b6637f482c459dd393efddd0ec7f82045"}, - {file = "mypy-1.19.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:481daf36a4c443332e2ae9c137dfee878fcea781a2e3f895d54bd3002a900957"}, - {file = "mypy-1.19.1-cp314-cp314-win_amd64.whl", hash = "sha256:8bb5c6f6d043655e055be9b542aa5f3bdd30e4f3589163e85f93f3640060509f"}, - {file = "mypy-1.19.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7bcfc336a03a1aaa26dfce9fff3e287a3ba99872a157561cbfcebe67c13308e3"}, - {file = "mypy-1.19.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7951a701c07ea584c4fe327834b92a30825514c868b1f69c30445093fdd9d5a"}, - {file = "mypy-1.19.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b13cfdd6c87fc3efb69ea4ec18ef79c74c3f98b4e5498ca9b85ab3b2c2329a67"}, - {file = "mypy-1.19.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f28f99c824ecebcdaa2e55d82953e38ff60ee5ec938476796636b86afa3956e"}, - {file = "mypy-1.19.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c608937067d2fc5a4dd1a5ce92fd9e1398691b8c5d012d66e1ddd430e9244376"}, - {file = "mypy-1.19.1-cp39-cp39-win_amd64.whl", hash = "sha256:409088884802d511ee52ca067707b90c883426bd95514e8cfda8281dc2effe24"}, - {file = "mypy-1.19.1-py3-none-any.whl", hash = "sha256:f1235f5ea01b7db5468d53ece6aaddf1ad0b88d9e7462b86ef96fe04995d7247"}, - {file = "mypy-1.19.1.tar.gz", hash = "sha256:19d88bb05303fe63f71dd2c6270daca27cb9401c4ca8255fe50d1d920e0eb9ba"}, + {file = "mypy-1.20.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cf5a4db6dca263010e2c7bff081c89383c72d187ba2cf4c44759aac970e2f0c4"}, + {file = "mypy-1.20.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7b0e817b518bff7facd7f85ea05b643ad8bdcce684cf29784987b0a7c8e1f997"}, + {file = "mypy-1.20.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:97d7b9a485b40f8ca425460e89bf1da2814625b2da627c0dcc6aa46c92631d14"}, + {file = "mypy-1.20.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e1c12f6d2db3d78b909b5f77513c11eb7f2dd2782b96a3ab6dffc7d44575c99"}, + {file = "mypy-1.20.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:89dce27e142d25ffbc154c1819383b69f2e9234dc4ed4766f42e0e8cb264ab5c"}, + {file = "mypy-1.20.2-cp310-cp310-win_amd64.whl", hash = "sha256:f376e37f9bf2a946872fc5fd1199c99310748e3c26c7a26683f13f8bdb756cbd"}, + {file = "mypy-1.20.2-cp310-cp310-win_arm64.whl", hash = "sha256:6e2b469efd811707bc530fd1effef0f5d6eebcb7fe376affae69025da4b979a2"}, + {file = "mypy-1.20.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4077797a273e56e8843d001e9dfe4ba10e33323d6ade647ff260e5cd97d9758c"}, + {file = "mypy-1.20.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cdecf62abcc4292500d7858aeae87a1f8f1150f4c4dd08fb0b336ee79b2a6df3"}, + {file = "mypy-1.20.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c566c3a88b6ece59b3d70f65bedef17304f48eb52ff040a6a18214e1917b3254"}, + {file = "mypy-1.20.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0deb80d062b2479f2c87ae568f89845afc71d11bc41b04179e58165fd9f31e98"}, + {file = "mypy-1.20.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bba9ad231e92a3e424b3e56b65aa17704993425bba97e302c832f9466bb85bac"}, + {file = "mypy-1.20.2-cp311-cp311-win_amd64.whl", hash = "sha256:baf593f2765fa3a6b1ef95807dbaa3d25b594f6a52adcc506a6b9cb115e1be67"}, + {file = "mypy-1.20.2-cp311-cp311-win_arm64.whl", hash = "sha256:20175a1c0f49863946ec20b7f63255768058ac4f07d2b9ded6a6b46cfb5a9100"}, + {file = "mypy-1.20.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4dbfcf869f6b0517f70cf0030ba6ea1d6645e132337a7d5204a18d8d5636c02b"}, + {file = "mypy-1.20.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b6481b228d072315b053210b01ac320e1be243dc17f9e5887ef167f23f5fae4"}, + {file = "mypy-1.20.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:34397cdced6b90b836e38182076049fdb41424322e0b0728c946b0939ebdf9f6"}, + {file = "mypy-1.20.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a5da6976f20cae27059ea8d0c86e7cef3de720e04c4bb9ee18e3690fdb792066"}, + {file = "mypy-1.20.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:56908d7e08318d39f85b1f0c6cfd47b0cac1a130da677630dac0de3e0623e102"}, + {file = "mypy-1.20.2-cp312-cp312-win_amd64.whl", hash = "sha256:d52ad8d78522da1d308789df651ee5379088e77c76cb1994858d40a426b343b9"}, + {file = "mypy-1.20.2-cp312-cp312-win_arm64.whl", hash = "sha256:785b08db19c9f214dc37d65f7c165d19a30fcecb48abfa30f31b01b5acaabb58"}, + {file = "mypy-1.20.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:edfbfca868cdd6bd8d974a60f8a3682f5565d3f5c99b327640cedd24c4264026"}, + {file = "mypy-1.20.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e2877a02380adfcdbc69071a0f74d6e9dbbf593c0dc9d174e1f223ffd5281943"}, + {file = "mypy-1.20.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7488448de6007cd5177c6cea0517ac33b4c0f5ee9b5e9f2be51ce75511a85517"}, + {file = "mypy-1.20.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb9c2fa06887e21d6a3a868762acb82aec34e2c6fd0174064f27c93ede68ad15"}, + {file = "mypy-1.20.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d56a78b646f2e3daa865bc70cd5ec5a46c50045801ca8ff17a0c43abc97e3ee"}, + {file = "mypy-1.20.2-cp313-cp313-win_amd64.whl", hash = "sha256:2a4102b03bb7481d9a91a6da8d174740c9c8c4401024684b9ca3b7cc5e49852f"}, + {file = "mypy-1.20.2-cp313-cp313-win_arm64.whl", hash = "sha256:a95a9248b0c6fd933a442c03c3b113c3b61320086b88e2c444676d3fd1ca3330"}, + {file = "mypy-1.20.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:419413398fe250aae057fd2fe50166b61077083c9b82754c341cf4fd73038f30"}, + {file = "mypy-1.20.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e73c07f23009962885c197ccb9b41356a30cc0e5a1d0c2ea8fd8fb1362d7f924"}, + {file = "mypy-1.20.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c64e5973df366b747646fc98da921f9d6eba9716d57d1db94a83c026a08e0fb"}, + {file = "mypy-1.20.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a65aa591af023864fd08a97da9974e919452cfe19cb146c8a5dc692626445dc"}, + {file = "mypy-1.20.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:4fef51b01e638974a6e69885687e9bd40c8d1e09a6cd291cca0619625cf1f558"}, + {file = "mypy-1.20.2-cp314-cp314-win_amd64.whl", hash = "sha256:913485a03f1bcf5d279409a9d2b9ed565c151f61c09f29991e5faa14033da4c8"}, + {file = "mypy-1.20.2-cp314-cp314-win_arm64.whl", hash = "sha256:c3bae4f855d965b5453784300c12ffc63a548304ac7f99e55d4dc7c898673aa3"}, + {file = "mypy-1.20.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:2de3dcea53babc1c3237a19002bc3d228ce1833278f093b8d619e06e7cc79609"}, + {file = "mypy-1.20.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:52b176444e2e5054dfcbcb8c75b0b719865c96247b37407184bbfca5c353f2c2"}, + {file = "mypy-1.20.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:688c3312e5dadb573a2c69c82af3a298d43ecf9e6d264e0f95df960b5f6ac19c"}, + {file = "mypy-1.20.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:29752dbbf8cc53f89f6ac096d363314333045c257c9c75cbd189ca2de0455744"}, + {file = "mypy-1.20.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:803203d2b6ea644982c644895c2f78b28d0e208bba7b27d9b921e0ec5eb207c6"}, + {file = "mypy-1.20.2-cp314-cp314t-win_amd64.whl", hash = "sha256:9bcb8aa397ff0093c824182fd76a935a9ba7ad097fcbef80ae89bf6c1731d8ec"}, + {file = "mypy-1.20.2-cp314-cp314t-win_arm64.whl", hash = "sha256:e061b58443f1736f8a37c48978d7ab581636d6ab03e3d4f99e3fa90463bb9382"}, + {file = "mypy-1.20.2-py3-none-any.whl", hash = "sha256:a94c5a76ab46c5e6257c7972b6c8cff0574201ca7dc05647e33e795d78680563"}, + {file = "mypy-1.20.2.tar.gz", hash = "sha256:e8222c26daaafd9e8626dec58ae36029f82585890589576f769a650dd20fd665"}, ] [package.dependencies] -librt = {version = ">=0.6.2", markers = "platform_python_implementation != \"PyPy\""} +librt = {version = ">=0.8.0", markers = "platform_python_implementation != \"PyPy\""} mypy_extensions = ">=1.0.0" -pathspec = ">=0.9.0" +pathspec = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing_extensions = ">=4.6.0" +typing_extensions = [ + {version = ">=4.6.0", markers = "python_version < \"3.15\""}, + {version = ">=4.14.0", markers = "python_version >= \"3.15\""}, +] [package.extras] dmypy = ["psutil (>=4.0)"] faster-cache = ["orjson"] install-types = ["pip"] mypyc = ["setuptools (>=50)"] +native-parser = ["ast-serialize (>=0.1.1,<1.0.0)"] reports = ["lxml"] [[package]] @@ -1515,39 +1515,38 @@ files = [ [[package]] name = "mysql-connector-python" -version = "9.6.0" +version = "9.7.0" description = "A self-contained Python driver for communicating with MySQL servers, using an API that is compliant with the Python Database API Specification v2.0 (PEP 249)." optional = false python-versions = ">=3.10" groups = ["dev", "test"] files = [ - {file = "mysql_connector_python-9.6.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:478e035ebcf734b3a1497bfd3eb72ce3632da6384545b08cf6329471b3849b6e"}, - {file = "mysql_connector_python-9.6.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:228000bb951810dad724821d04000174ffcc7fa94b4dcef884b17a3cdae07283"}, - {file = "mysql_connector_python-9.6.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:477e86182aefbf693b71ff8bda7679ab4487af64c027759af831a70080aaaeac"}, - {file = "mysql_connector_python-9.6.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:4bf932724a2702d8b9cde4bf764b843a35e85c59479a870997d37a2a68a5632d"}, - {file = "mysql_connector_python-9.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:b507372c060eb39e2a10ebcb3eb1b12e1778b0120808062fc23e3856268cd2d9"}, - {file = "mysql_connector_python-9.6.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:011931f7392a1087e10d305b0303f2a20cc1af2c1c8a15cd5691609aa95dfcbd"}, - {file = "mysql_connector_python-9.6.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:b5212372aff6833473d2560ac87d3df9fb2498d0faacb7ebf231d947175fa36a"}, - {file = "mysql_connector_python-9.6.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:61deca6e243fafbb3cf08ae27bd0c83d0f8188de8456e46aeba0d3db15bb7230"}, - {file = "mysql_connector_python-9.6.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:adabbc5e1475cdf5fb6f1902a25edc3bd1e0726fa45f01ab1b8f479ff43b3337"}, - {file = "mysql_connector_python-9.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:8732ca0b7417b45238bcbfc7e64d9c4d62c759672207c6284f0921c366efddc7"}, - {file = "mysql_connector_python-9.6.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9664e217c72dd6fb700f4c8512af90261f72d2f5d7c00c4e13e4c1e09bfa3d5e"}, - {file = "mysql_connector_python-9.6.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:1ed4b5c4761e5333035293e746683890e4ef2e818e515d14023fd80293bc31fa"}, - {file = "mysql_connector_python-9.6.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:5095758dcb89a6bce2379f349da336c268c407129002b595c5dba82ce387e2a5"}, - {file = "mysql_connector_python-9.6.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:4ae4e7780fad950a4f267dea5851048d160f5b71314a342cdbf30b154f1c74f7"}, - {file = "mysql_connector_python-9.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:c180e0b4100d7402e03993bfac5c97d18e01d7ca9d198d742fffc245077f8ffe"}, - {file = "mysql_connector_python-9.6.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e86e45a7b540ca09af8a18ecfa761e0cdeccfdb62818331614ec030ae44bfd26"}, - {file = "mysql_connector_python-9.6.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:8d3e9252384e1b7f95b07020664f2673d9c29c5e95eeda2e048b3331e190b9d4"}, - {file = "mysql_connector_python-9.6.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:0fa18ead33cb699ea92005695077cef09aa494eebf51164ee30c891c3eaea90c"}, - {file = "mysql_connector_python-9.6.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:a26490cb029bf7b18a1d2093101105b3526a1036b51ad01553d30138f5beb8d2"}, - {file = "mysql_connector_python-9.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:3460ed976e1b88b7284335d9397a3c519dff56d71580ca1f76ff1c0c7714c813"}, - {file = "mysql_connector_python-9.6.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e2cc13cd3dcdb845d636e52c4e7a9509b63da09bec6ce1b3696be53a79847e2d"}, - {file = "mysql_connector_python-9.6.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:a08c2149d4b52a010c4353f18c84716d18114a4ecd00b466ea34138de2c640f2"}, - {file = "mysql_connector_python-9.6.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:b00228b985edd208b20f45c5e684c54e08e31e01bc1d8c3c18a36641c3be5bf7"}, - {file = "mysql_connector_python-9.6.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:4617ef5216da7ca32dd46afda61a1552807762434127413bba46fbe4379f59d4"}, - {file = "mysql_connector_python-9.6.0-cp314-cp314-win_amd64.whl", hash = "sha256:bc782f64ca00b6b933d4c6a35568f1349d115cc4434c849b5b9edc015bee3e62"}, - {file = "mysql_connector_python-9.6.0-py2.py3-none-any.whl", hash = "sha256:44b0fb57207ebc6ae05b5b21b7968a9ed33b29187fe87b38951bad2a334d75d5"}, - {file = "mysql_connector_python-9.6.0.tar.gz", hash = "sha256:c453bb55347174d87504b534246fb10c589daf5d057515bf615627198a3c7ef1"}, + {file = "mysql_connector_python-9.7.0-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:ee90c5f44f706f012be17f03f6ad158ff96e7f2dcc077896fe4537d3d28b3cf4"}, + {file = "mysql_connector_python-9.7.0-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:a2f371ab69d65c61136c51ad7026017400166cef3c959cab7a9fb668c7acbfba"}, + {file = "mysql_connector_python-9.7.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:9bdfc2d4c4444cd1cc79cc6487c047b28fe2b26d0327b27eb9f5737bb553cb5c"}, + {file = "mysql_connector_python-9.7.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:6546e0b60c275409a5add9e3308c3897fcf478d1338cd845b1664c1a8946f72f"}, + {file = "mysql_connector_python-9.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:c51be697bfdfdf63bb71c5ecc51f7c6faf4aaa3d14a0136fa16e97cc37df1185"}, + {file = "mysql_connector_python-9.7.0-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:b5cb8a3ba42b539f79cd13e4c8376d28506f3180f7079c9b04ea7bfd0424fb03"}, + {file = "mysql_connector_python-9.7.0-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:5492d57a6a0e5127a928290737fbb91b66b46d31dac8de3e7604e550bf3b3a6e"}, + {file = "mysql_connector_python-9.7.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:daf70f7da64a2e7c17e6dfd1fc98d2deb653fd955d0bd0b1fef246356e682b0f"}, + {file = "mysql_connector_python-9.7.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:b8d3d6f32b95ae1d0a2f29d1a2b4e628849bcf7e84a70dc56c85b4929361d86b"}, + {file = "mysql_connector_python-9.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:079ce68d617250ef5cefffd5243056dc9f87c6034c804235fd6f45a0daf5a6ae"}, + {file = "mysql_connector_python-9.7.0-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:2eae45230b5cbd783d68bdfe8b05ad9b4ebd06799f8d302a6169d7f025572baf"}, + {file = "mysql_connector_python-9.7.0-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:15106ed73d74487f86de6b1859ff7f362efca7c7f9c494497ccb7439d3139fe6"}, + {file = "mysql_connector_python-9.7.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:45491d4ce56722cb335e6d0bde2d4f4a98b7073421bd02a04ad5e6220d69e499"}, + {file = "mysql_connector_python-9.7.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:d5924a76b530159c02f2fe8da4d3c6377ce1f5e195827e8ecbd36124673651d3"}, + {file = "mysql_connector_python-9.7.0-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:e3842ecd62391a28c1dda5eb817f40418715e68482a8c146b3c478ac8bb7a23f"}, + {file = "mysql_connector_python-9.7.0-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:9da73e212bb08e4df286506ffbda943063bbce448375a7db29748bb367f4e0af"}, + {file = "mysql_connector_python-9.7.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:39bf31cdbe920eae08801eb829584dc27f70dadbdb3a5c3b78402f54cea87ab0"}, + {file = "mysql_connector_python-9.7.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:236a4b8abfac8217517ce9e9edc735decf55282ada3890b3cd33770009f33d68"}, + {file = "mysql_connector_python-9.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:229ffce2333b88b59f8f034881e12dc85b309615338be9f843ed63923db99d52"}, + {file = "mysql_connector_python-9.7.0-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:9e17ceb79c1c4c137a5994f8ca8c6a1ce8ebf83eda3ccc21dd67f2c1398680f0"}, + {file = "mysql_connector_python-9.7.0-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:272c4e8263f6a514e4ae65e9553ed214fc9d4cf1f0f6bedca30def20c2ae1d52"}, + {file = "mysql_connector_python-9.7.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:9549a2974353407427b574f005c92f03972e303182b4c3b4a272bf4ca10855ed"}, + {file = "mysql_connector_python-9.7.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:ea4e05ab864ab8b0b5066d885d89ca51e5ba1320dba520c20a6f9388a8eca022"}, + {file = "mysql_connector_python-9.7.0-cp314-cp314-win_amd64.whl", hash = "sha256:5a5abbc152bc28cb2e64a04605ecd9941eff6b0dc5f9528cb84adb873e9a1e49"}, + {file = "mysql_connector_python-9.7.0-py2.py3-none-any.whl", hash = "sha256:af80b1e7179d5c2d983cf62470ad9b134a7e9ef05cf31108ae587f15873530cc"}, + {file = "mysql_connector_python-9.7.0.tar.gz", hash = "sha256:933887e71c871b6e9d8908459fe8303ebcf8feb5cc1e1c49caa6490e525cf78e"}, ] [package.extras] @@ -1558,124 +1557,136 @@ webauthn = ["fido2 (==1.1.2)"] [[package]] name = "opentelemetry-api" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Python API" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "opentelemetry_api-1.27.0-py3-none-any.whl", hash = "sha256:953d5871815e7c30c81b56d910c707588000fff7a3ca1c73e6531911d53065e7"}, - {file = "opentelemetry_api-1.27.0.tar.gz", hash = "sha256:ed673583eaa5f81b5ce5e86ef7cdaf622f88ef65f0b9aab40b843dcae5bef342"}, + {file = "opentelemetry_api-1.42.1-py3-none-any.whl", hash = "sha256:51a69edacadbc03a8950ace1c4c21099cacc538820ac2c9e36277e78cebba714"}, + {file = "opentelemetry_api-1.42.1.tar.gz", hash = "sha256:56c63bea9f77b62856be8c47600474acad853b2924b99b1687c4cb6297166716"}, ] [package.dependencies] -deprecated = ">=1.2.6" -importlib-metadata = ">=6.0,<=8.4.0" +typing-extensions = ">=4.5.0" [[package]] name = "opentelemetry-exporter-otlp" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Collector Exporters" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "opentelemetry_exporter_otlp-1.27.0-py3-none-any.whl", hash = "sha256:7688791cbdd951d71eb6445951d1cfbb7b6b2d7ee5948fac805d404802931145"}, - {file = "opentelemetry_exporter_otlp-1.27.0.tar.gz", hash = "sha256:4a599459e623868cc95d933c301199c2367e530f089750e115599fccd67cb2a1"}, + {file = "opentelemetry_exporter_otlp-1.42.1-py3-none-any.whl", hash = "sha256:aedd54545bb0587cd45210abdc8be545af9c01413f3307786e276df1e3c83bee"}, + {file = "opentelemetry_exporter_otlp-1.42.1.tar.gz", hash = "sha256:2d9ebaed714377a67d224d46795ddcc11d2c877fa5de35fda70b6f3b010729a9"}, ] [package.dependencies] -opentelemetry-exporter-otlp-proto-grpc = "1.27.0" -opentelemetry-exporter-otlp-proto-http = "1.27.0" +opentelemetry-exporter-otlp-proto-grpc = "1.42.1" +opentelemetry-exporter-otlp-proto-http = "1.42.1" [[package]] name = "opentelemetry-exporter-otlp-proto-common" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Protobuf encoding" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "opentelemetry_exporter_otlp_proto_common-1.27.0-py3-none-any.whl", hash = "sha256:675db7fffcb60946f3a5c43e17d1168a3307a94a930ecf8d2ea1f286f3d4f79a"}, - {file = "opentelemetry_exporter_otlp_proto_common-1.27.0.tar.gz", hash = "sha256:159d27cf49f359e3798c4c3eb8da6ef4020e292571bd8c5604a2a573231dd5c8"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.42.1-py3-none-any.whl", hash = "sha256:f48d395ab815b444da118868977e9798ea354c25737d5cf39578ae894011c140"}, + {file = "opentelemetry_exporter_otlp_proto_common-1.42.1.tar.gz", hash = "sha256:04f1f01fb597c4249dfcd7f8b861c902c2102369d376d9d346ff38de4469a2ee"}, ] [package.dependencies] -opentelemetry-proto = "1.27.0" +opentelemetry-proto = "1.42.1" [[package]] name = "opentelemetry-exporter-otlp-proto-grpc" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Collector Protobuf over gRPC Exporter" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "opentelemetry_exporter_otlp_proto_grpc-1.27.0-py3-none-any.whl", hash = "sha256:56b5bbd5d61aab05e300d9d62a6b3c134827bbd28d0b12f2649c2da368006c9e"}, - {file = "opentelemetry_exporter_otlp_proto_grpc-1.27.0.tar.gz", hash = "sha256:af6f72f76bcf425dfb5ad11c1a6d6eca2863b91e63575f89bb7b4b55099d968f"}, + {file = "opentelemetry_exporter_otlp_proto_grpc-1.42.1-py3-none-any.whl", hash = "sha256:0ae1177e2038b18a929b3098215243631ef91136cba26b7e2b12790ceb7e87cc"}, + {file = "opentelemetry_exporter_otlp_proto_grpc-1.42.1.tar.gz", hash = "sha256:975c4461f167dd8ed8857d68d3b6b25f3d272eab896f6a9470d0f5b90e2faf15"}, ] [package.dependencies] -deprecated = ">=1.2.6" -googleapis-common-protos = ">=1.52,<2.0" -grpcio = ">=1.0.0,<2.0.0" +googleapis-common-protos = ">=1.57,<2.0" +grpcio = [ + {version = ">=1.63.2,<2.0.0", markers = "python_version < \"3.13\""}, + {version = ">=1.66.2,<2.0.0", markers = "python_version == \"3.13\""}, + {version = ">=1.75.1,<2.0.0", markers = "python_version >= \"3.14\""}, +] opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.27.0" -opentelemetry-proto = "1.27.0" -opentelemetry-sdk = ">=1.27.0,<1.28.0" +opentelemetry-exporter-otlp-proto-common = "1.42.1" +opentelemetry-proto = "1.42.1" +opentelemetry-sdk = ">=1.42.1,<1.43.0" +typing-extensions = ">=4.6.0" + +[package.extras] +gcp-auth = ["opentelemetry-exporter-credential-provider-gcp (>=0.59b0)"] [[package]] name = "opentelemetry-exporter-otlp-proto-http" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Collector Protobuf over HTTP Exporter" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "opentelemetry_exporter_otlp_proto_http-1.27.0-py3-none-any.whl", hash = "sha256:688027575c9da42e179a69fe17e2d1eba9b14d81de8d13553a21d3114f3b4d75"}, - {file = "opentelemetry_exporter_otlp_proto_http-1.27.0.tar.gz", hash = "sha256:2103479092d8eb18f61f3fbff084f67cc7f2d4a7d37e75304b8b56c1d09ebef5"}, + {file = "opentelemetry_exporter_otlp_proto_http-1.42.1-py3-none-any.whl", hash = "sha256:00a16da1b312a1d6c7233d600d557c91df71125af73020f3b9a7765bd699d59d"}, + {file = "opentelemetry_exporter_otlp_proto_http-1.42.1.tar.gz", hash = "sha256:bf142a21035d7571ac3a09cb2e5639f49886f243972883cfe777ed3bf02b734d"}, ] [package.dependencies] -deprecated = ">=1.2.6" googleapis-common-protos = ">=1.52,<2.0" opentelemetry-api = ">=1.15,<2.0" -opentelemetry-exporter-otlp-proto-common = "1.27.0" -opentelemetry-proto = "1.27.0" -opentelemetry-sdk = ">=1.27.0,<1.28.0" +opentelemetry-exporter-otlp-proto-common = "1.42.1" +opentelemetry-proto = "1.42.1" +opentelemetry-sdk = ">=1.42.1,<1.43.0" requests = ">=2.7,<3.0" +typing-extensions = ">=4.5.0" + +[package.extras] +gcp-auth = ["opentelemetry-exporter-credential-provider-gcp (>=0.59b0)"] [[package]] name = "opentelemetry-proto" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Python Proto" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["test"] files = [ - {file = "opentelemetry_proto-1.27.0-py3-none-any.whl", hash = "sha256:b133873de5581a50063e1e4b29cdcf0c5e253a8c2d8dc1229add20a4c3830ace"}, - {file = "opentelemetry_proto-1.27.0.tar.gz", hash = "sha256:33c9345d91dafd8a74fc3d7576c5a38f18b7fdf8d02983ac67485386132aedd6"}, + {file = "opentelemetry_proto-1.42.1-py3-none-any.whl", hash = "sha256:dedb74cba2886c59c7789b227a7a670613025a07489040050aedff6e5c0fb43c"}, + {file = "opentelemetry_proto-1.42.1.tar.gz", hash = "sha256:c6a51e6b4f05ae63565f3a113217f3d2bfaec68f78c02d7a6c85f9010d1cfca6"}, ] [package.dependencies] -protobuf = ">=3.19,<5.0" +protobuf = ">=5.0,<7.0" [[package]] name = "opentelemetry-sdk" -version = "1.27.0" +version = "1.42.1" description = "OpenTelemetry Python SDK" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "opentelemetry_sdk-1.27.0-py3-none-any.whl", hash = "sha256:365f5e32f920faf0fd9e14fdfd92c086e317eaa5f860edba9cdc17a380d9197d"}, - {file = "opentelemetry_sdk-1.27.0.tar.gz", hash = "sha256:d525017dea0ccce9ba4e0245100ec46ecdc043f2d7b8315d56b19aff0904fa6f"}, + {file = "opentelemetry_sdk-1.42.1-py3-none-any.whl", hash = "sha256:083cd4bbfaa5aa7b5a9e552430d9951219967cfb27aa61feb13a77aba1fc839d"}, + {file = "opentelemetry_sdk-1.42.1.tar.gz", hash = "sha256:8c834e8f8c9ba4171d4ec843d0cb8a67e4c7394d3f9e9297e582cbd9456ddbf7"}, ] [package.dependencies] -opentelemetry-api = "1.27.0" -opentelemetry-semantic-conventions = "0.48b0" -typing-extensions = ">=3.7.4" +opentelemetry-api = "1.42.1" +opentelemetry-semantic-conventions = "0.63b1" +typing-extensions = ">=4.5.0" + +[package.extras] +file-configuration = ["jsonschema (>=4.0)", "pyyaml (>=6.0)"] [[package]] name = "opentelemetry-sdk-extension-aws" @@ -1694,19 +1705,19 @@ opentelemetry-sdk = ">=1.12,<2.0" [[package]] name = "opentelemetry-semantic-conventions" -version = "0.48b0" +version = "0.63b1" description = "OpenTelemetry Semantic Conventions" optional = false -python-versions = ">=3.8" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "opentelemetry_semantic_conventions-0.48b0-py3-none-any.whl", hash = "sha256:a0de9f45c413a8669788a38569c7e0a11ce6ce97861a628cca785deecdc32a1f"}, - {file = "opentelemetry_semantic_conventions-0.48b0.tar.gz", hash = "sha256:12d74983783b6878162208be57c9effcb89dc88691c64992d70bb89dc00daa1a"}, + {file = "opentelemetry_semantic_conventions-0.63b1-py3-none-any.whl", hash = "sha256:dfe5ef4dee82586b746f522b818ceb298d00b3d59f660042bd79404bff8d0682"}, + {file = "opentelemetry_semantic_conventions-0.63b1.tar.gz", hash = "sha256:3daf963611334b365e98a57438183eb012d3bfb40b2d931a9af613476b8701a9"}, ] [package.dependencies] -deprecated = ">=1.2.6" -opentelemetry-api = "1.27.0" +opentelemetry-api = "1.42.1" +typing-extensions = ">=4.5.0" [[package]] name = "packaging" @@ -1786,23 +1797,23 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "protobuf" -version = "4.25.8" +version = "5.29.6" description = "" optional = false python-versions = ">=3.8" groups = ["test"] files = [ - {file = "protobuf-4.25.8-cp310-abi3-win32.whl", hash = "sha256:504435d831565f7cfac9f0714440028907f1975e4bed228e58e72ecfff58a1e0"}, - {file = "protobuf-4.25.8-cp310-abi3-win_amd64.whl", hash = "sha256:bd551eb1fe1d7e92c1af1d75bdfa572eff1ab0e5bf1736716814cdccdb2360f9"}, - {file = "protobuf-4.25.8-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:ca809b42f4444f144f2115c4c1a747b9a404d590f18f37e9402422033e464e0f"}, - {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:9ad7ef62d92baf5a8654fbb88dac7fa5594cfa70fd3440488a5ca3bfc6d795a7"}, - {file = "protobuf-4.25.8-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:83e6e54e93d2b696a92cad6e6efc924f3850f82b52e1563778dfab8b355101b0"}, - {file = "protobuf-4.25.8-cp38-cp38-win32.whl", hash = "sha256:27d498ffd1f21fb81d987a041c32d07857d1d107909f5134ba3350e1ce80a4af"}, - {file = "protobuf-4.25.8-cp38-cp38-win_amd64.whl", hash = "sha256:d552c53d0415449c8d17ced5c341caba0d89dbf433698e1436c8fa0aae7808a3"}, - {file = "protobuf-4.25.8-cp39-cp39-win32.whl", hash = "sha256:077ff8badf2acf8bc474406706ad890466274191a48d0abd3bd6987107c9cde5"}, - {file = "protobuf-4.25.8-cp39-cp39-win_amd64.whl", hash = "sha256:f4510b93a3bec6eba8fd8f1093e9d7fb0d4a24d1a81377c10c0e5bbfe9e4ed24"}, - {file = "protobuf-4.25.8-py3-none-any.whl", hash = "sha256:15a0af558aa3b13efef102ae6e4f3efac06f1eea11afb3a57db2901447d9fb59"}, - {file = "protobuf-4.25.8.tar.gz", hash = "sha256:6135cf8affe1fc6f76cced2641e4ea8d3e59518d1f24ae41ba97bcad82d397cd"}, + {file = "protobuf-5.29.6-cp310-abi3-win32.whl", hash = "sha256:62e8a3114992c7c647bce37dcc93647575fc52d50e48de30c6fcb28a6a291eb1"}, + {file = "protobuf-5.29.6-cp310-abi3-win_amd64.whl", hash = "sha256:7e6ad413275be172f67fdee0f43484b6de5a904cc1c3ea9804cb6fe2ff366eda"}, + {file = "protobuf-5.29.6-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:b5a169e664b4057183a34bdc424540e86eea47560f3c123a0d64de4e137f9269"}, + {file = "protobuf-5.29.6-cp38-abi3-manylinux2014_aarch64.whl", hash = "sha256:a8866b2cff111f0f863c1b3b9e7572dc7eaea23a7fae27f6fc613304046483e6"}, + {file = "protobuf-5.29.6-cp38-abi3-manylinux2014_x86_64.whl", hash = "sha256:e3387f44798ac1106af0233c04fb8abf543772ff241169946f698b3a9a3d3ab9"}, + {file = "protobuf-5.29.6-cp38-cp38-win32.whl", hash = "sha256:36ade6ff88212e91aef4e687a971a11d7d24d6948a66751abc1b3238648f5d05"}, + {file = "protobuf-5.29.6-cp38-cp38-win_amd64.whl", hash = "sha256:831e2da16b6cc9d8f1654c041dd594eda43391affd3c03a91bea7f7f6da106d6"}, + {file = "protobuf-5.29.6-cp39-cp39-win32.whl", hash = "sha256:cb4c86de9cd8a7f3a256b9744220d87b847371c6b2f10bde87768918ef33ba49"}, + {file = "protobuf-5.29.6-cp39-cp39-win_amd64.whl", hash = "sha256:76e07e6567f8baf827137e8d5b8204b6c7b6488bbbff1bf0a72b383f77999c18"}, + {file = "protobuf-5.29.6-py3-none-any.whl", hash = "sha256:6b9edb641441b2da9fa8f428760fc136a49cf97a52076010cf22a2ff73438a86"}, + {file = "protobuf-5.29.6.tar.gz", hash = "sha256:da9ee6a5424b6b30fd5e45c5ea663aef540ca95f9ad99d1e887e819cdf9b8723"}, ] [[package]] @@ -2072,14 +2083,14 @@ six = ">=1.5" [[package]] name = "requests" -version = "2.33.0" +version = "2.34.2" description = "Python HTTP for Humans." optional = false python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "requests-2.33.0-py3-none-any.whl", hash = "sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b"}, - {file = "requests-2.33.0.tar.gz", hash = "sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652"}, + {file = "requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0"}, + {file = "requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed"}, ] [package.dependencies] @@ -2090,7 +2101,6 @@ urllib3 = ">=1.26,<3" [package.extras] socks = ["PySocks (>=1.5.6,!=1.5.7)"] -test = ["PySocks (>=1.5.6,!=1.5.7)", "pytest (>=3)", "pytest-cov", "pytest-httpbin (==2.1.0)", "pytest-mock", "pytest-xdist"] use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"] [[package]] @@ -2107,14 +2117,14 @@ files = [ [[package]] name = "s3transfer" -version = "0.16.0" +version = "0.19.0" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">=3.9" +python-versions = ">=3.10" groups = ["main", "test"] files = [ - {file = "s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe"}, - {file = "s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920"}, + {file = "s3transfer-0.19.0-py3-none-any.whl", hash = "sha256:777cc2415536f1debadb5c2ef7779275d0fc0fe0e042411cdd6caebeb2685262"}, + {file = "s3transfer-0.19.0.tar.gz", hash = "sha256:ce436931687addc4c1712d52d40b32f53e88315723f107ffa20ba82b05a0f685"}, ] [package.dependencies] @@ -2149,75 +2159,70 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.48" +version = "2.0.51" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" groups = ["dev"] files = [ - {file = "sqlalchemy-2.0.48-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7001dc9d5f6bb4deb756d5928eaefe1930f6f4179da3924cbd95ee0e9f4dce89"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1a89ce07ad2d4b8cfc30bd5889ec40613e028ed80ef47da7d9dd2ce969ad30e0"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10853a53a4a00417a00913d270dddda75815fcb80675874285f41051c094d7dd"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:fac0fa4e4f55f118fd87177dacb1c6522fe39c28d498d259014020fec9164c29"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3713e21ea67bca727eecd4a24bf68bcd414c403faae4989442be60994301ded0"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-win32.whl", hash = "sha256:d404dc897ce10e565d647795861762aa2d06ca3f4a728c5e9a835096c7059018"}, - {file = "sqlalchemy-2.0.48-cp310-cp310-win_amd64.whl", hash = "sha256:841a94c66577661c1f088ac958cd767d7c9bf507698f45afffe7a4017049de76"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b4c575df7368b3b13e0cebf01d4679f9a28ed2ae6c1cd0b1d5beffb6b2007dc"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e83e3f959aaa1c9df95c22c528096d94848a1bc819f5d0ebf7ee3df0ca63db6c"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f7b7243850edd0b8b97043f04748f31de50cf426e939def5c16bedb540698f7"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:82745b03b4043e04600a6b665cb98697c4339b24e34d74b0a2ac0a2488b6f94d"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e5e088bf43f6ee6fec7dbf1ef7ff7774a616c236b5c0cb3e00662dd71a56b571"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-win32.whl", hash = "sha256:9c7d0a77e36b5f4b01ca398482230ab792061d243d715299b44a0b55c89fe617"}, - {file = "sqlalchemy-2.0.48-cp311-cp311-win_amd64.whl", hash = "sha256:583849c743e0e3c9bb7446f5b5addeacedc168d657a69b418063dfdb2d90081c"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:348174f228b99f33ca1f773e85510e08927620caa59ffe7803b37170df30332b"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:53667b5f668991e279d21f94ccfa6e45b4e3f4500e7591ae59a8012d0f010dcb"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:34634e196f620c7a61d18d5cf7dc841ca6daa7961aed75d532b7e58b309ac894"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:546572a1793cc35857a2ffa1fe0e58571af1779bcc1ffa7c9fb0839885ed69a9"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:07edba08061bc277bfdc772dd2a1a43978f5a45994dd3ede26391b405c15221e"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-win32.whl", hash = "sha256:908a3fa6908716f803b86896a09a2c4dde5f5ce2bb07aacc71ffebb57986ce99"}, - {file = "sqlalchemy-2.0.48-cp312-cp312-win_amd64.whl", hash = "sha256:68549c403f79a8e25984376480959975212a670405e3913830614432b5daa07a"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e3070c03701037aa418b55d36532ecb8f8446ed0135acb71c678dbdf12f5b6e4"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2645b7d8a738763b664a12a1542c89c940daa55196e8d73e55b169cc5c99f65f"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b19151e76620a412c2ac1c6f977ab1b9fa7ad43140178345136456d5265b32ed"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5b193a7e29fd9fa56e502920dca47dffe60f97c863494946bd698c6058a55658"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:36ac4ddc3d33e852da9cb00ffb08cea62ca05c39711dc67062ca2bb1fae35fd8"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-win32.whl", hash = "sha256:389b984139278f97757ea9b08993e7b9d1142912e046ab7d82b3fbaeb0209131"}, - {file = "sqlalchemy-2.0.48-cp313-cp313-win_amd64.whl", hash = "sha256:d612c976cbc2d17edfcc4c006874b764e85e990c29ce9bd411f926bbfb02b9a2"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:69f5bc24904d3bc3640961cddd2523e361257ef68585d6e364166dfbe8c78fae"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd08b90d211c086181caed76931ecfa2bdfc83eea3cfccdb0f82abc6c4b876cb"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:1ccd42229aaac2df431562117ac7e667d702e8e44afdb6cf0e50fa3f18160f0b"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f0dcbc588cd5b725162c076eb9119342f6579c7f7f55057bb7e3c6ff27e13121"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-win32.whl", hash = "sha256:9764014ef5e58aab76220c5664abb5d47d5bc858d9debf821e55cfdd0f128485"}, - {file = "sqlalchemy-2.0.48-cp313-cp313t-win_amd64.whl", hash = "sha256:e2f35b4cccd9ed286ad62e0a3c3ac21e06c02abc60e20aa51a3e305a30f5fa79"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e2d0d88686e3d35a76f3e15a34e8c12d73fc94c1dea1cd55782e695cc14086dd"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49b7bddc1eebf011ea5ab722fdbe67a401caa34a350d278cc7733c0e88fecb1f"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:426c5ca86415d9b8945c7073597e10de9644802e2ff502b8e1f11a7a2642856b"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:288937433bd44e3990e7da2402fabc44a3c6c25d3704da066b85b89a85474ae0"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:8183dc57ae7d9edc1346e007e840a9f3d6aa7b7f165203a99e16f447150140d2"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-win32.whl", hash = "sha256:1182437cb2d97988cfea04cf6cdc0b0bb9c74f4d56ec3d08b81e23d621a28cc6"}, - {file = "sqlalchemy-2.0.48-cp314-cp314-win_amd64.whl", hash = "sha256:144921da96c08feb9e2b052c5c5c1d0d151a292c6135623c6b2c041f2a45f9e0"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5aee45fd2c6c0f2b9cdddf48c48535e7471e42d6fb81adfde801da0bd5b93241"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7cddca31edf8b0653090cbb54562ca027c421c58ddde2c0685f49ff56a1690e0"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7a936f1bb23d370b7c8cc079d5fce4c7d18da87a33c6744e51a93b0f9e97e9b3"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e004aa9248e8cb0a5f9b96d003ca7c1c0a5da8decd1066e7b53f59eb8ce7c62b"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-win32.whl", hash = "sha256:b8438ec5594980d405251451c5b7ea9aa58dda38eb7ac35fb7e4c696712ee24f"}, - {file = "sqlalchemy-2.0.48-cp314-cp314t-win_amd64.whl", hash = "sha256:d854b3970067297f3a7fbd7a4683587134aa9b3877ee15aa29eea478dc68f933"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:f8649a14caa5f8a243628b1d61cf530ad9ae4578814ba726816adb1121fc493e"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6bb85c546591569558571aa1b06aba711b26ae62f111e15e56136d69920e1616"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a6b764fb312bd35e47797ad2e63f0d323792837a6ac785a4ca967019357d2bc7"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:7c998f2ace8bf76b453b75dbcca500d4f4b9dd3908c13e89b86289b37784848b"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:d64177f443594c8697369c10e4bbcac70ef558e0f7921a1de7e4a3d1734bcf67"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-win32.whl", hash = "sha256:01f6bbd4308b23240cf7d3ef117557c8fd097ec9549d5d8a52977544e35b40ad"}, - {file = "sqlalchemy-2.0.48-cp38-cp38-win_amd64.whl", hash = "sha256:858e433f12b0e5b3ed2f8da917433b634f4937d0e8793e5cb33c54a1a01df565"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4599a95f9430ae0de82b52ff0d27304fe898c17cb5f4099f7438a51b9998ac77"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f27f9da0a7d22b9f981108fd4b62f8b5743423388915a563e651c20d06c1f457"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d8fcccbbc0c13c13702c471da398b8cd72ba740dca5859f148ae8e0e8e0d3e7e"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:a5b429eb84339f9f05e06083f119ad814e6d85e27ecbdf9c551dfdbb128eaf8a"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:bcb8ebbf2e2c36cfe01a94f2438012c6a9d494cf80f129d9753bcdf33bfc35a6"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-win32.whl", hash = "sha256:e214d546c8ecb5fc22d6e6011746082abf13a9cf46eefb45769c7b31407c97b5"}, - {file = "sqlalchemy-2.0.48-cp39-cp39-win_amd64.whl", hash = "sha256:b8fc3454b4f3bd0a368001d0e968852dad45a873f8b4babd41bc302ec851a099"}, - {file = "sqlalchemy-2.0.48-py3-none-any.whl", hash = "sha256:a66fe406437dd65cacd96a72689a3aaaecaebbcd62d81c5ac1c0fdbeac835096"}, - {file = "sqlalchemy-2.0.48.tar.gz", hash = "sha256:5ca74f37f3369b45e1f6b7b06afb182af1fd5dde009e4ffd831830d98cbe5fe7"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e8203d2fbd5c6254692ef0a72c740d75b2f3c7ca345404f4c1a4604813c77c0"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1af05726b3d0cdba1c55284bf408fd3b792e690fe2399bfb8304565551cda652"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e54ff2dd657f2e3e0fbf2b097db1182f7bfea263eca4353f00065bae2a67c3d"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:1e47b1199c2e832e325eacabc8d32d2487f58c9358f97e9a00f5eb93c5680d84"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c68568f3facf8f66fa76c60e0ced69b67666ffa9941d1d0a3756fda196049080"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-win32.whl", hash = "sha256:0592bdadf86ddcabfd72d9ab66ea8a5d8d2cc6be1cc51fa7e66c03868ac5eac1"}, + {file = "sqlalchemy-2.0.51-cp310-cp310-win_amd64.whl", hash = "sha256:740cf6f35351b1ac3d82369152acf1d51d37e3dcf85d4dc0a22ca01410eabe2a"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1aa10c0daee6705294d181daadaa793221e1a59ed55000a3fab1d42b088ce4ba"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a5b2ed6d828f1f09bd812861f4f59ca3bc3803f9df871f4555187f0faf018604"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:436728ce18a80f6951a1e11cc6112c2ede9faf20766f1a26195a7c441ca12dbd"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:dc261707bf5739aea8a541593f3cc1d463c2701fb05fbcbba0ce031b69a21260"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a6d26094615306d116dd5e4a51b0304c99dd2356fc569eed6922a80a6bd3b265"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-win32.whl", hash = "sha256:ca8435d13829b92f4a97362d91975154a4015db3a2634154e1754e9a915e6b86"}, + {file = "sqlalchemy-2.0.51-cp311-cp311-win_amd64.whl", hash = "sha256:4a011ea4510683319ce4ed274b56ee05194b39b6da9d09ca7a39388f0fa84dcc"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d78702b26ba1c18b2d0fb2ea940ba7f17a9581b42e8361ff93920ebbee1235a"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581921d849d6e6f994d560389192955e80e2950e18fcdfe2ccea863e01158e6e"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d21ce524ab86c23046e992a5b81cb54c21079c6df6e78b8fc77d77cac70a6b9"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c5d98a2709840027f5a347c3af0a7c3d5f6c1ff93af2ca1c54494e23cba8f389"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1181256e0f16479691b5616d36375dc2620ad8332b25978763c3d206ad3f3f1d"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-win32.whl", hash = "sha256:9f380393be5abeb6815f68fd39271b95127173511b6706b0a630a9995d53f8f5"}, + {file = "sqlalchemy-2.0.51-cp312-cp312-win_amd64.whl", hash = "sha256:2cf39aabdf48e87c1c2c2ed6d20d33ffa0733b3071ce9c5f66357947dd009080"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7c2056838b6685b72fdb36c99996cf862753461a62f2e84f4196371d3b2d6a07"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483b11bd46bf35fc14c52faf338b04300c9e6ce554bce9b11be85bfec3bc3195"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bed1ee8b01da6088210aa9412023326fb98a599ba502e6118308601dcbef77f"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:72ca54c952107ba5cd58854b67a5a6268631289d21651a1235396f3b98b47400"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e693d15533a45cd5906f0589f9c35090bef6ef45bf1e8195c424aa0ae06a8d"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-win32.whl", hash = "sha256:b93ab07b5292dbe7e6b8da89475275e7042744283921344b56105f3eeb0f828b"}, + {file = "sqlalchemy-2.0.51-cp313-cp313-win_amd64.whl", hash = "sha256:0f053118c30e53161857a953e4de667d90e274980dccbe5dd3829bbbeece72a5"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:6ea306caaae6bd5afd0a46050003c88f6bf33227377a49298c498c3cb88ff491"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c45a496d6bc05dec41dcd4c3a2b183723f47473255c159cd80b503c8f246424d"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4004ada0aafe8ae1991b2cd1d99c6d9146126e123bd6f883c260d974aa012e54"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f6bcad487aee1c638d707235682fc96f741de00663619881ab235400d03289e"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:39a76529db6305693d8d4affa58ad5b5e2e18edd62daea628b29b97930b3513d"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-win32.whl", hash = "sha256:08a204d8b5638717c26a24df18fcf40af45a6b22e35b70b1d62f0113c2e278e8"}, + {file = "sqlalchemy-2.0.51-cp314-cp314-win_amd64.whl", hash = "sha256:96747bfbadb055466e5b46d572618170046b45ce5a4879167f50d70a5319a499"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1a213be1fcd5e49d9904c3b9939211ded90bc2a64e93f4c01963474285de"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c6b36ed71f41942bdcd2ad2522be46bfce09d5705be5640ecf19bbc7660e4b7"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c2c62877097e1a0db401fba5cb4debee33265e5b2a55c4ccb489c02c53b4f72"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0378d055e9e8cd6ce4d8dff683bdd3d7d413533c4ee51d67a2b1e0f9eacc0f23"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e46fc36029eff666391e0531e5387b62ce6c4f1d8e50b3fb3099eaca1b42522"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-win32.whl", hash = "sha256:9161cfc9efce70d1715f47d6ff40f79c6778c00d53be4fbc09d70301e4b83ba7"}, + {file = "sqlalchemy-2.0.51-cp314-cp314t-win_amd64.whl", hash = "sha256:159bb6ba32059f57ad7375a8f50d844dd2f19d14954ecf820cd33e20debd46b2"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bb1f5062f98b0b3290e72b707747fdd7e0f22d6956b236ba7ca7f5c9971d2da2"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:247acaa29ccef6250dfd6a3eedf8f94ddf23564180a39fe362e32ae9dbdbde46"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c95ef01f53233a305a874a44a63fbfb1d81cd79b49de0f8529b3548cde437e37"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:fa268106c8987639a17a18514cfe0cd9bf17420ab887e1e1bf486da8836135b1"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b7f08588854bbb724041d9ae9d980d40040c922382e1d9a2ecb390edc4fd5032"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-win32.whl", hash = "sha256:6b588fd681ddf0c196b8df1ea49a8913514894b2b8f945a9511b4b48871f99c8"}, + {file = "sqlalchemy-2.0.51-cp38-cp38-win_amd64.whl", hash = "sha256:ca216e8af5c05e326efc7e28716ac2381a7cf9791749f5ee1849dccdc99c9b00"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:aa18ae738b5170e253ad0bb6c4b0f07585081e8a6e50893e4d911d47b39a0904"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:59cab3686b1bc039dd9cded2f8d0c08a246e84e76bd4ab5b4f18c7cdae293825"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:111604e637da87031255ddc26c7d7bc22bc6af6f5d459ccff3af1b4660233a85"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ad30ae663711786303fbcd46a47516302d201ee49a877cb3fac61f672895110a"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b21f0e7efc7a5c509e953784e9d1575ebb8b4318960e7e7d7a93bb803626cf64"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-win32.whl", hash = "sha256:a42ad6afcbaaa777241e347aa2e29155993045a0d6b7db74da61053ffe875fe0"}, + {file = "sqlalchemy-2.0.51-cp39-cp39-win_amd64.whl", hash = "sha256:2a97eaad21c84b4ef8010b11eeba9fe6153eb0b3df3ff8b6abc309df1b978ef7"}, + {file = "sqlalchemy-2.0.51-py3-none-any.whl", hash = "sha256:bb024d8b621d0be75f4f44ecc7c950450026e76d66dc8f791bb5331d7fed59d5"}, + {file = "sqlalchemy-2.0.51.tar.gz", hash = "sha256:804dccd8a4a6242c4e30ad961e540e18a588f6527202f2d6791b01845d59fdc9"}, ] [package.dependencies] @@ -2347,14 +2352,14 @@ files = [ [[package]] name = "types-boto3" -version = "1.42.74" -description = "Type annotations for boto3 1.42.74 generated with mypy-boto3-builder 8.12.0" +version = "1.43.32" +description = "Type annotations for boto3 1.43.32 generated with mypy-boto3-builder 8.12.0" optional = false python-versions = ">=3.9" groups = ["test"] files = [ - {file = "types_boto3-1.42.74-py3-none-any.whl", hash = "sha256:3791c49c694b5c6d980e38994032eff4ed90ab4f7b1ad4fb34f3501b7fc60d02"}, - {file = "types_boto3-1.42.74.tar.gz", hash = "sha256:8013a2dfc1ba398217d2d2dc6b54b37494df65cbae363f9430af4824697cb655"}, + {file = "types_boto3-1.43.32-py3-none-any.whl", hash = "sha256:febd8ac45968b29010323cbb2057afe7b7e2a3fc8cf42a1c86516b42bd2a3354"}, + {file = "types_boto3-1.43.32.tar.gz", hash = "sha256:2a41a59b2aac7565fd2545a7442a1c9cdf05d595b0a7721bce03d87635a43e3d"}, ] [package.dependencies] @@ -2363,426 +2368,435 @@ types-s3transfer = "*" typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [package.extras] -accessanalyzer = ["types-boto3-accessanalyzer (>=1.42.0,<1.43.0)"] -account = ["types-boto3-account (>=1.42.0,<1.43.0)"] -acm = ["types-boto3-acm (>=1.42.0,<1.43.0)"] -acm-pca = ["types-boto3-acm-pca (>=1.42.0,<1.43.0)"] -aiops = ["types-boto3-aiops (>=1.42.0,<1.43.0)"] -all = ["types-boto3-accessanalyzer (>=1.42.0,<1.43.0)", "types-boto3-account (>=1.42.0,<1.43.0)", "types-boto3-acm (>=1.42.0,<1.43.0)", "types-boto3-acm-pca (>=1.42.0,<1.43.0)", "types-boto3-aiops (>=1.42.0,<1.43.0)", "types-boto3-amp (>=1.42.0,<1.43.0)", "types-boto3-amplify (>=1.42.0,<1.43.0)", "types-boto3-amplifybackend (>=1.42.0,<1.43.0)", "types-boto3-amplifyuibuilder (>=1.42.0,<1.43.0)", "types-boto3-apigateway (>=1.42.0,<1.43.0)", "types-boto3-apigatewaymanagementapi (>=1.42.0,<1.43.0)", "types-boto3-apigatewayv2 (>=1.42.0,<1.43.0)", "types-boto3-appconfig (>=1.42.0,<1.43.0)", "types-boto3-appconfigdata (>=1.42.0,<1.43.0)", "types-boto3-appfabric (>=1.42.0,<1.43.0)", "types-boto3-appflow (>=1.42.0,<1.43.0)", "types-boto3-appintegrations (>=1.42.0,<1.43.0)", "types-boto3-application-autoscaling (>=1.42.0,<1.43.0)", "types-boto3-application-insights (>=1.42.0,<1.43.0)", "types-boto3-application-signals (>=1.42.0,<1.43.0)", "types-boto3-applicationcostprofiler (>=1.42.0,<1.43.0)", "types-boto3-appmesh (>=1.42.0,<1.43.0)", "types-boto3-apprunner (>=1.42.0,<1.43.0)", "types-boto3-appstream (>=1.42.0,<1.43.0)", "types-boto3-appsync (>=1.42.0,<1.43.0)", "types-boto3-arc-region-switch (>=1.42.0,<1.43.0)", "types-boto3-arc-zonal-shift (>=1.42.0,<1.43.0)", "types-boto3-artifact (>=1.42.0,<1.43.0)", "types-boto3-athena (>=1.42.0,<1.43.0)", "types-boto3-auditmanager (>=1.42.0,<1.43.0)", "types-boto3-autoscaling (>=1.42.0,<1.43.0)", "types-boto3-autoscaling-plans (>=1.42.0,<1.43.0)", "types-boto3-b2bi (>=1.42.0,<1.43.0)", "types-boto3-backup (>=1.42.0,<1.43.0)", "types-boto3-backup-gateway (>=1.42.0,<1.43.0)", "types-boto3-backupsearch (>=1.42.0,<1.43.0)", "types-boto3-batch (>=1.42.0,<1.43.0)", "types-boto3-bcm-dashboards (>=1.42.0,<1.43.0)", "types-boto3-bcm-data-exports (>=1.42.0,<1.43.0)", "types-boto3-bcm-pricing-calculator (>=1.42.0,<1.43.0)", "types-boto3-bcm-recommended-actions (>=1.42.0,<1.43.0)", "types-boto3-bedrock (>=1.42.0,<1.43.0)", "types-boto3-bedrock-agent (>=1.42.0,<1.43.0)", "types-boto3-bedrock-agent-runtime (>=1.42.0,<1.43.0)", "types-boto3-bedrock-agentcore (>=1.42.0,<1.43.0)", "types-boto3-bedrock-agentcore-control (>=1.42.0,<1.43.0)", "types-boto3-bedrock-data-automation (>=1.42.0,<1.43.0)", "types-boto3-bedrock-data-automation-runtime (>=1.42.0,<1.43.0)", "types-boto3-bedrock-runtime (>=1.42.0,<1.43.0)", "types-boto3-billing (>=1.42.0,<1.43.0)", "types-boto3-billingconductor (>=1.42.0,<1.43.0)", "types-boto3-braket (>=1.42.0,<1.43.0)", "types-boto3-budgets (>=1.42.0,<1.43.0)", "types-boto3-ce (>=1.42.0,<1.43.0)", "types-boto3-chatbot (>=1.42.0,<1.43.0)", "types-boto3-chime (>=1.42.0,<1.43.0)", "types-boto3-chime-sdk-identity (>=1.42.0,<1.43.0)", "types-boto3-chime-sdk-media-pipelines (>=1.42.0,<1.43.0)", "types-boto3-chime-sdk-meetings (>=1.42.0,<1.43.0)", "types-boto3-chime-sdk-messaging (>=1.42.0,<1.43.0)", "types-boto3-chime-sdk-voice (>=1.42.0,<1.43.0)", "types-boto3-cleanrooms (>=1.42.0,<1.43.0)", "types-boto3-cleanroomsml (>=1.42.0,<1.43.0)", "types-boto3-cloud9 (>=1.42.0,<1.43.0)", "types-boto3-cloudcontrol (>=1.42.0,<1.43.0)", "types-boto3-clouddirectory (>=1.42.0,<1.43.0)", "types-boto3-cloudformation (>=1.42.0,<1.43.0)", "types-boto3-cloudfront (>=1.42.0,<1.43.0)", "types-boto3-cloudfront-keyvaluestore (>=1.42.0,<1.43.0)", "types-boto3-cloudhsm (>=1.42.0,<1.43.0)", "types-boto3-cloudhsmv2 (>=1.42.0,<1.43.0)", "types-boto3-cloudsearch (>=1.42.0,<1.43.0)", "types-boto3-cloudsearchdomain (>=1.42.0,<1.43.0)", "types-boto3-cloudtrail (>=1.42.0,<1.43.0)", "types-boto3-cloudtrail-data (>=1.42.0,<1.43.0)", "types-boto3-cloudwatch (>=1.42.0,<1.43.0)", "types-boto3-codeartifact (>=1.42.0,<1.43.0)", "types-boto3-codebuild (>=1.42.0,<1.43.0)", "types-boto3-codecatalyst (>=1.42.0,<1.43.0)", "types-boto3-codecommit (>=1.42.0,<1.43.0)", "types-boto3-codeconnections (>=1.42.0,<1.43.0)", "types-boto3-codedeploy (>=1.42.0,<1.43.0)", "types-boto3-codeguru-reviewer (>=1.42.0,<1.43.0)", "types-boto3-codeguru-security (>=1.42.0,<1.43.0)", "types-boto3-codeguruprofiler (>=1.42.0,<1.43.0)", "types-boto3-codepipeline (>=1.42.0,<1.43.0)", "types-boto3-codestar-connections (>=1.42.0,<1.43.0)", "types-boto3-codestar-notifications (>=1.42.0,<1.43.0)", "types-boto3-cognito-identity (>=1.42.0,<1.43.0)", "types-boto3-cognito-idp (>=1.42.0,<1.43.0)", "types-boto3-cognito-sync (>=1.42.0,<1.43.0)", "types-boto3-comprehend (>=1.42.0,<1.43.0)", "types-boto3-comprehendmedical (>=1.42.0,<1.43.0)", "types-boto3-compute-optimizer (>=1.42.0,<1.43.0)", "types-boto3-compute-optimizer-automation (>=1.42.0,<1.43.0)", "types-boto3-config (>=1.42.0,<1.43.0)", "types-boto3-connect (>=1.42.0,<1.43.0)", "types-boto3-connect-contact-lens (>=1.42.0,<1.43.0)", "types-boto3-connectcampaigns (>=1.42.0,<1.43.0)", "types-boto3-connectcampaignsv2 (>=1.42.0,<1.43.0)", "types-boto3-connectcases (>=1.42.0,<1.43.0)", "types-boto3-connecthealth (>=1.42.0,<1.43.0)", "types-boto3-connectparticipant (>=1.42.0,<1.43.0)", "types-boto3-controlcatalog (>=1.42.0,<1.43.0)", "types-boto3-controltower (>=1.42.0,<1.43.0)", "types-boto3-cost-optimization-hub (>=1.42.0,<1.43.0)", "types-boto3-cur (>=1.42.0,<1.43.0)", "types-boto3-customer-profiles (>=1.42.0,<1.43.0)", "types-boto3-databrew (>=1.42.0,<1.43.0)", "types-boto3-dataexchange (>=1.42.0,<1.43.0)", "types-boto3-datapipeline (>=1.42.0,<1.43.0)", "types-boto3-datasync (>=1.42.0,<1.43.0)", "types-boto3-datazone (>=1.42.0,<1.43.0)", "types-boto3-dax (>=1.42.0,<1.43.0)", "types-boto3-deadline (>=1.42.0,<1.43.0)", "types-boto3-detective (>=1.42.0,<1.43.0)", "types-boto3-devicefarm (>=1.42.0,<1.43.0)", "types-boto3-devops-guru (>=1.42.0,<1.43.0)", "types-boto3-directconnect (>=1.42.0,<1.43.0)", "types-boto3-discovery (>=1.42.0,<1.43.0)", "types-boto3-dlm (>=1.42.0,<1.43.0)", "types-boto3-dms (>=1.42.0,<1.43.0)", "types-boto3-docdb (>=1.42.0,<1.43.0)", "types-boto3-docdb-elastic (>=1.42.0,<1.43.0)", "types-boto3-drs (>=1.42.0,<1.43.0)", "types-boto3-ds (>=1.42.0,<1.43.0)", "types-boto3-ds-data (>=1.42.0,<1.43.0)", "types-boto3-dsql (>=1.42.0,<1.43.0)", "types-boto3-dynamodb (>=1.42.0,<1.43.0)", "types-boto3-dynamodbstreams (>=1.42.0,<1.43.0)", "types-boto3-ebs (>=1.42.0,<1.43.0)", "types-boto3-ec2 (>=1.42.0,<1.43.0)", "types-boto3-ec2-instance-connect (>=1.42.0,<1.43.0)", "types-boto3-ecr (>=1.42.0,<1.43.0)", "types-boto3-ecr-public (>=1.42.0,<1.43.0)", "types-boto3-ecs (>=1.42.0,<1.43.0)", "types-boto3-efs (>=1.42.0,<1.43.0)", "types-boto3-eks (>=1.42.0,<1.43.0)", "types-boto3-eks-auth (>=1.42.0,<1.43.0)", "types-boto3-elasticache (>=1.42.0,<1.43.0)", "types-boto3-elasticbeanstalk (>=1.42.0,<1.43.0)", "types-boto3-elb (>=1.42.0,<1.43.0)", "types-boto3-elbv2 (>=1.42.0,<1.43.0)", "types-boto3-elementalinference (>=1.42.0,<1.43.0)", "types-boto3-emr (>=1.42.0,<1.43.0)", "types-boto3-emr-containers (>=1.42.0,<1.43.0)", "types-boto3-emr-serverless (>=1.42.0,<1.43.0)", "types-boto3-entityresolution (>=1.42.0,<1.43.0)", "types-boto3-es (>=1.42.0,<1.43.0)", "types-boto3-events (>=1.42.0,<1.43.0)", "types-boto3-evs (>=1.42.0,<1.43.0)", "types-boto3-finspace (>=1.42.0,<1.43.0)", "types-boto3-finspace-data (>=1.42.0,<1.43.0)", "types-boto3-firehose (>=1.42.0,<1.43.0)", "types-boto3-fis (>=1.42.0,<1.43.0)", "types-boto3-fms (>=1.42.0,<1.43.0)", "types-boto3-forecast (>=1.42.0,<1.43.0)", "types-boto3-forecastquery (>=1.42.0,<1.43.0)", "types-boto3-frauddetector (>=1.42.0,<1.43.0)", "types-boto3-freetier (>=1.42.0,<1.43.0)", "types-boto3-fsx (>=1.42.0,<1.43.0)", "types-boto3-gamelift (>=1.42.0,<1.43.0)", "types-boto3-gameliftstreams (>=1.42.0,<1.43.0)", "types-boto3-geo-maps (>=1.42.0,<1.43.0)", "types-boto3-geo-places (>=1.42.0,<1.43.0)", "types-boto3-geo-routes (>=1.42.0,<1.43.0)", "types-boto3-glacier (>=1.42.0,<1.43.0)", "types-boto3-globalaccelerator (>=1.42.0,<1.43.0)", "types-boto3-glue (>=1.42.0,<1.43.0)", "types-boto3-grafana (>=1.42.0,<1.43.0)", "types-boto3-greengrass (>=1.42.0,<1.43.0)", "types-boto3-greengrassv2 (>=1.42.0,<1.43.0)", "types-boto3-groundstation (>=1.42.0,<1.43.0)", "types-boto3-guardduty (>=1.42.0,<1.43.0)", "types-boto3-health (>=1.42.0,<1.43.0)", "types-boto3-healthlake (>=1.42.0,<1.43.0)", "types-boto3-iam (>=1.42.0,<1.43.0)", "types-boto3-identitystore (>=1.42.0,<1.43.0)", "types-boto3-imagebuilder (>=1.42.0,<1.43.0)", "types-boto3-importexport (>=1.42.0,<1.43.0)", "types-boto3-inspector (>=1.42.0,<1.43.0)", "types-boto3-inspector-scan (>=1.42.0,<1.43.0)", "types-boto3-inspector2 (>=1.42.0,<1.43.0)", "types-boto3-internetmonitor (>=1.42.0,<1.43.0)", "types-boto3-invoicing (>=1.42.0,<1.43.0)", "types-boto3-iot (>=1.42.0,<1.43.0)", "types-boto3-iot-data (>=1.42.0,<1.43.0)", "types-boto3-iot-jobs-data (>=1.42.0,<1.43.0)", "types-boto3-iot-managed-integrations (>=1.42.0,<1.43.0)", "types-boto3-iotdeviceadvisor (>=1.42.0,<1.43.0)", "types-boto3-iotevents (>=1.42.0,<1.43.0)", "types-boto3-iotevents-data (>=1.42.0,<1.43.0)", "types-boto3-iotfleetwise (>=1.42.0,<1.43.0)", "types-boto3-iotsecuretunneling (>=1.42.0,<1.43.0)", "types-boto3-iotsitewise (>=1.42.0,<1.43.0)", "types-boto3-iotthingsgraph (>=1.42.0,<1.43.0)", "types-boto3-iottwinmaker (>=1.42.0,<1.43.0)", "types-boto3-iotwireless (>=1.42.0,<1.43.0)", "types-boto3-ivs (>=1.42.0,<1.43.0)", "types-boto3-ivs-realtime (>=1.42.0,<1.43.0)", "types-boto3-ivschat (>=1.42.0,<1.43.0)", "types-boto3-kafka (>=1.42.0,<1.43.0)", "types-boto3-kafkaconnect (>=1.42.0,<1.43.0)", "types-boto3-kendra (>=1.42.0,<1.43.0)", "types-boto3-kendra-ranking (>=1.42.0,<1.43.0)", "types-boto3-keyspaces (>=1.42.0,<1.43.0)", "types-boto3-keyspacesstreams (>=1.42.0,<1.43.0)", "types-boto3-kinesis (>=1.42.0,<1.43.0)", "types-boto3-kinesis-video-archived-media (>=1.42.0,<1.43.0)", "types-boto3-kinesis-video-media (>=1.42.0,<1.43.0)", "types-boto3-kinesis-video-signaling (>=1.42.0,<1.43.0)", "types-boto3-kinesis-video-webrtc-storage (>=1.42.0,<1.43.0)", "types-boto3-kinesisanalytics (>=1.42.0,<1.43.0)", "types-boto3-kinesisanalyticsv2 (>=1.42.0,<1.43.0)", "types-boto3-kinesisvideo (>=1.42.0,<1.43.0)", "types-boto3-kms (>=1.42.0,<1.43.0)", "types-boto3-lakeformation (>=1.42.0,<1.43.0)", "types-boto3-lambda (>=1.42.0,<1.43.0)", "types-boto3-launch-wizard (>=1.42.0,<1.43.0)", "types-boto3-lex-models (>=1.42.0,<1.43.0)", "types-boto3-lex-runtime (>=1.42.0,<1.43.0)", "types-boto3-lexv2-models (>=1.42.0,<1.43.0)", "types-boto3-lexv2-runtime (>=1.42.0,<1.43.0)", "types-boto3-license-manager (>=1.42.0,<1.43.0)", "types-boto3-license-manager-linux-subscriptions (>=1.42.0,<1.43.0)", "types-boto3-license-manager-user-subscriptions (>=1.42.0,<1.43.0)", "types-boto3-lightsail (>=1.42.0,<1.43.0)", "types-boto3-location (>=1.42.0,<1.43.0)", "types-boto3-logs (>=1.42.0,<1.43.0)", "types-boto3-lookoutequipment (>=1.42.0,<1.43.0)", "types-boto3-m2 (>=1.42.0,<1.43.0)", "types-boto3-machinelearning (>=1.42.0,<1.43.0)", "types-boto3-macie2 (>=1.42.0,<1.43.0)", "types-boto3-mailmanager (>=1.42.0,<1.43.0)", "types-boto3-managedblockchain (>=1.42.0,<1.43.0)", "types-boto3-managedblockchain-query (>=1.42.0,<1.43.0)", "types-boto3-marketplace-agreement (>=1.42.0,<1.43.0)", "types-boto3-marketplace-catalog (>=1.42.0,<1.43.0)", "types-boto3-marketplace-deployment (>=1.42.0,<1.43.0)", "types-boto3-marketplace-entitlement (>=1.42.0,<1.43.0)", "types-boto3-marketplace-reporting (>=1.42.0,<1.43.0)", "types-boto3-marketplacecommerceanalytics (>=1.42.0,<1.43.0)", "types-boto3-mediaconnect (>=1.42.0,<1.43.0)", "types-boto3-mediaconvert (>=1.42.0,<1.43.0)", "types-boto3-medialive (>=1.42.0,<1.43.0)", "types-boto3-mediapackage (>=1.42.0,<1.43.0)", "types-boto3-mediapackage-vod (>=1.42.0,<1.43.0)", "types-boto3-mediapackagev2 (>=1.42.0,<1.43.0)", "types-boto3-mediastore (>=1.42.0,<1.43.0)", "types-boto3-mediastore-data (>=1.42.0,<1.43.0)", "types-boto3-mediatailor (>=1.42.0,<1.43.0)", "types-boto3-medical-imaging (>=1.42.0,<1.43.0)", "types-boto3-memorydb (>=1.42.0,<1.43.0)", "types-boto3-meteringmarketplace (>=1.42.0,<1.43.0)", "types-boto3-mgh (>=1.42.0,<1.43.0)", "types-boto3-mgn (>=1.42.0,<1.43.0)", "types-boto3-migration-hub-refactor-spaces (>=1.42.0,<1.43.0)", "types-boto3-migrationhub-config (>=1.42.0,<1.43.0)", "types-boto3-migrationhuborchestrator (>=1.42.0,<1.43.0)", "types-boto3-migrationhubstrategy (>=1.42.0,<1.43.0)", "types-boto3-mpa (>=1.42.0,<1.43.0)", "types-boto3-mq (>=1.42.0,<1.43.0)", "types-boto3-mturk (>=1.42.0,<1.43.0)", "types-boto3-mwaa (>=1.42.0,<1.43.0)", "types-boto3-mwaa-serverless (>=1.42.0,<1.43.0)", "types-boto3-neptune (>=1.42.0,<1.43.0)", "types-boto3-neptune-graph (>=1.42.0,<1.43.0)", "types-boto3-neptunedata (>=1.42.0,<1.43.0)", "types-boto3-network-firewall (>=1.42.0,<1.43.0)", "types-boto3-networkflowmonitor (>=1.42.0,<1.43.0)", "types-boto3-networkmanager (>=1.42.0,<1.43.0)", "types-boto3-networkmonitor (>=1.42.0,<1.43.0)", "types-boto3-notifications (>=1.42.0,<1.43.0)", "types-boto3-notificationscontacts (>=1.42.0,<1.43.0)", "types-boto3-nova-act (>=1.42.0,<1.43.0)", "types-boto3-oam (>=1.42.0,<1.43.0)", "types-boto3-observabilityadmin (>=1.42.0,<1.43.0)", "types-boto3-odb (>=1.42.0,<1.43.0)", "types-boto3-omics (>=1.42.0,<1.43.0)", "types-boto3-opensearch (>=1.42.0,<1.43.0)", "types-boto3-opensearchserverless (>=1.42.0,<1.43.0)", "types-boto3-organizations (>=1.42.0,<1.43.0)", "types-boto3-osis (>=1.42.0,<1.43.0)", "types-boto3-outposts (>=1.42.0,<1.43.0)", "types-boto3-panorama (>=1.42.0,<1.43.0)", "types-boto3-partnercentral-account (>=1.42.0,<1.43.0)", "types-boto3-partnercentral-benefits (>=1.42.0,<1.43.0)", "types-boto3-partnercentral-channel (>=1.42.0,<1.43.0)", "types-boto3-partnercentral-selling (>=1.42.0,<1.43.0)", "types-boto3-payment-cryptography (>=1.42.0,<1.43.0)", "types-boto3-payment-cryptography-data (>=1.42.0,<1.43.0)", "types-boto3-pca-connector-ad (>=1.42.0,<1.43.0)", "types-boto3-pca-connector-scep (>=1.42.0,<1.43.0)", "types-boto3-pcs (>=1.42.0,<1.43.0)", "types-boto3-personalize (>=1.42.0,<1.43.0)", "types-boto3-personalize-events (>=1.42.0,<1.43.0)", "types-boto3-personalize-runtime (>=1.42.0,<1.43.0)", "types-boto3-pi (>=1.42.0,<1.43.0)", "types-boto3-pinpoint (>=1.42.0,<1.43.0)", "types-boto3-pinpoint-email (>=1.42.0,<1.43.0)", "types-boto3-pinpoint-sms-voice (>=1.42.0,<1.43.0)", "types-boto3-pinpoint-sms-voice-v2 (>=1.42.0,<1.43.0)", "types-boto3-pipes (>=1.42.0,<1.43.0)", "types-boto3-polly (>=1.42.0,<1.43.0)", "types-boto3-pricing (>=1.42.0,<1.43.0)", "types-boto3-proton (>=1.42.0,<1.43.0)", "types-boto3-qapps (>=1.42.0,<1.43.0)", "types-boto3-qbusiness (>=1.42.0,<1.43.0)", "types-boto3-qconnect (>=1.42.0,<1.43.0)", "types-boto3-quicksight (>=1.42.0,<1.43.0)", "types-boto3-ram (>=1.42.0,<1.43.0)", "types-boto3-rbin (>=1.42.0,<1.43.0)", "types-boto3-rds (>=1.42.0,<1.43.0)", "types-boto3-rds-data (>=1.42.0,<1.43.0)", "types-boto3-redshift (>=1.42.0,<1.43.0)", "types-boto3-redshift-data (>=1.42.0,<1.43.0)", "types-boto3-redshift-serverless (>=1.42.0,<1.43.0)", "types-boto3-rekognition (>=1.42.0,<1.43.0)", "types-boto3-repostspace (>=1.42.0,<1.43.0)", "types-boto3-resiliencehub (>=1.42.0,<1.43.0)", "types-boto3-resource-explorer-2 (>=1.42.0,<1.43.0)", "types-boto3-resource-groups (>=1.42.0,<1.43.0)", "types-boto3-resourcegroupstaggingapi (>=1.42.0,<1.43.0)", "types-boto3-rolesanywhere (>=1.42.0,<1.43.0)", "types-boto3-route53 (>=1.42.0,<1.43.0)", "types-boto3-route53-recovery-cluster (>=1.42.0,<1.43.0)", "types-boto3-route53-recovery-control-config (>=1.42.0,<1.43.0)", "types-boto3-route53-recovery-readiness (>=1.42.0,<1.43.0)", "types-boto3-route53domains (>=1.42.0,<1.43.0)", "types-boto3-route53globalresolver (>=1.42.0,<1.43.0)", "types-boto3-route53profiles (>=1.42.0,<1.43.0)", "types-boto3-route53resolver (>=1.42.0,<1.43.0)", "types-boto3-rtbfabric (>=1.42.0,<1.43.0)", "types-boto3-rum (>=1.42.0,<1.43.0)", "types-boto3-s3 (>=1.42.0,<1.43.0)", "types-boto3-s3control (>=1.42.0,<1.43.0)", "types-boto3-s3outposts (>=1.42.0,<1.43.0)", "types-boto3-s3tables (>=1.42.0,<1.43.0)", "types-boto3-s3vectors (>=1.42.0,<1.43.0)", "types-boto3-sagemaker (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-a2i-runtime (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-edge (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-featurestore-runtime (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-geospatial (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-metrics (>=1.42.0,<1.43.0)", "types-boto3-sagemaker-runtime (>=1.42.0,<1.43.0)", "types-boto3-savingsplans (>=1.42.0,<1.43.0)", "types-boto3-scheduler (>=1.42.0,<1.43.0)", "types-boto3-schemas (>=1.42.0,<1.43.0)", "types-boto3-sdb (>=1.42.0,<1.43.0)", "types-boto3-secretsmanager (>=1.42.0,<1.43.0)", "types-boto3-security-ir (>=1.42.0,<1.43.0)", "types-boto3-securityhub (>=1.42.0,<1.43.0)", "types-boto3-securitylake (>=1.42.0,<1.43.0)", "types-boto3-serverlessrepo (>=1.42.0,<1.43.0)", "types-boto3-service-quotas (>=1.42.0,<1.43.0)", "types-boto3-servicecatalog (>=1.42.0,<1.43.0)", "types-boto3-servicecatalog-appregistry (>=1.42.0,<1.43.0)", "types-boto3-servicediscovery (>=1.42.0,<1.43.0)", "types-boto3-ses (>=1.42.0,<1.43.0)", "types-boto3-sesv2 (>=1.42.0,<1.43.0)", "types-boto3-shield (>=1.42.0,<1.43.0)", "types-boto3-signer (>=1.42.0,<1.43.0)", "types-boto3-signer-data (>=1.42.0,<1.43.0)", "types-boto3-signin (>=1.42.0,<1.43.0)", "types-boto3-simpledbv2 (>=1.42.0,<1.43.0)", "types-boto3-simspaceweaver (>=1.42.0,<1.43.0)", "types-boto3-snow-device-management (>=1.42.0,<1.43.0)", "types-boto3-snowball (>=1.42.0,<1.43.0)", "types-boto3-sns (>=1.42.0,<1.43.0)", "types-boto3-socialmessaging (>=1.42.0,<1.43.0)", "types-boto3-sqs (>=1.42.0,<1.43.0)", "types-boto3-ssm (>=1.42.0,<1.43.0)", "types-boto3-ssm-contacts (>=1.42.0,<1.43.0)", "types-boto3-ssm-guiconnect (>=1.42.0,<1.43.0)", "types-boto3-ssm-incidents (>=1.42.0,<1.43.0)", "types-boto3-ssm-quicksetup (>=1.42.0,<1.43.0)", "types-boto3-ssm-sap (>=1.42.0,<1.43.0)", "types-boto3-sso (>=1.42.0,<1.43.0)", "types-boto3-sso-admin (>=1.42.0,<1.43.0)", "types-boto3-sso-oidc (>=1.42.0,<1.43.0)", "types-boto3-stepfunctions (>=1.42.0,<1.43.0)", "types-boto3-storagegateway (>=1.42.0,<1.43.0)", "types-boto3-sts (>=1.42.0,<1.43.0)", "types-boto3-supplychain (>=1.42.0,<1.43.0)", "types-boto3-support (>=1.42.0,<1.43.0)", "types-boto3-support-app (>=1.42.0,<1.43.0)", "types-boto3-swf (>=1.42.0,<1.43.0)", "types-boto3-synthetics (>=1.42.0,<1.43.0)", "types-boto3-taxsettings (>=1.42.0,<1.43.0)", "types-boto3-textract (>=1.42.0,<1.43.0)", "types-boto3-timestream-influxdb (>=1.42.0,<1.43.0)", "types-boto3-timestream-query (>=1.42.0,<1.43.0)", "types-boto3-timestream-write (>=1.42.0,<1.43.0)", "types-boto3-tnb (>=1.42.0,<1.43.0)", "types-boto3-transcribe (>=1.42.0,<1.43.0)", "types-boto3-transfer (>=1.42.0,<1.43.0)", "types-boto3-translate (>=1.42.0,<1.43.0)", "types-boto3-trustedadvisor (>=1.42.0,<1.43.0)", "types-boto3-verifiedpermissions (>=1.42.0,<1.43.0)", "types-boto3-voice-id (>=1.42.0,<1.43.0)", "types-boto3-vpc-lattice (>=1.42.0,<1.43.0)", "types-boto3-waf (>=1.42.0,<1.43.0)", "types-boto3-waf-regional (>=1.42.0,<1.43.0)", "types-boto3-wafv2 (>=1.42.0,<1.43.0)", "types-boto3-wellarchitected (>=1.42.0,<1.43.0)", "types-boto3-wickr (>=1.42.0,<1.43.0)", "types-boto3-wisdom (>=1.42.0,<1.43.0)", "types-boto3-workdocs (>=1.42.0,<1.43.0)", "types-boto3-workmail (>=1.42.0,<1.43.0)", "types-boto3-workmailmessageflow (>=1.42.0,<1.43.0)", "types-boto3-workspaces (>=1.42.0,<1.43.0)", "types-boto3-workspaces-instances (>=1.42.0,<1.43.0)", "types-boto3-workspaces-thin-client (>=1.42.0,<1.43.0)", "types-boto3-workspaces-web (>=1.42.0,<1.43.0)", "types-boto3-xray (>=1.42.0,<1.43.0)"] -amp = ["types-boto3-amp (>=1.42.0,<1.43.0)"] -amplify = ["types-boto3-amplify (>=1.42.0,<1.43.0)"] -amplifybackend = ["types-boto3-amplifybackend (>=1.42.0,<1.43.0)"] -amplifyuibuilder = ["types-boto3-amplifyuibuilder (>=1.42.0,<1.43.0)"] -apigateway = ["types-boto3-apigateway (>=1.42.0,<1.43.0)"] -apigatewaymanagementapi = ["types-boto3-apigatewaymanagementapi (>=1.42.0,<1.43.0)"] -apigatewayv2 = ["types-boto3-apigatewayv2 (>=1.42.0,<1.43.0)"] -appconfig = ["types-boto3-appconfig (>=1.42.0,<1.43.0)"] -appconfigdata = ["types-boto3-appconfigdata (>=1.42.0,<1.43.0)"] -appfabric = ["types-boto3-appfabric (>=1.42.0,<1.43.0)"] -appflow = ["types-boto3-appflow (>=1.42.0,<1.43.0)"] -appintegrations = ["types-boto3-appintegrations (>=1.42.0,<1.43.0)"] -application-autoscaling = ["types-boto3-application-autoscaling (>=1.42.0,<1.43.0)"] -application-insights = ["types-boto3-application-insights (>=1.42.0,<1.43.0)"] -application-signals = ["types-boto3-application-signals (>=1.42.0,<1.43.0)"] -applicationcostprofiler = ["types-boto3-applicationcostprofiler (>=1.42.0,<1.43.0)"] -appmesh = ["types-boto3-appmesh (>=1.42.0,<1.43.0)"] -apprunner = ["types-boto3-apprunner (>=1.42.0,<1.43.0)"] -appstream = ["types-boto3-appstream (>=1.42.0,<1.43.0)"] -appsync = ["types-boto3-appsync (>=1.42.0,<1.43.0)"] -arc-region-switch = ["types-boto3-arc-region-switch (>=1.42.0,<1.43.0)"] -arc-zonal-shift = ["types-boto3-arc-zonal-shift (>=1.42.0,<1.43.0)"] -artifact = ["types-boto3-artifact (>=1.42.0,<1.43.0)"] -athena = ["types-boto3-athena (>=1.42.0,<1.43.0)"] -auditmanager = ["types-boto3-auditmanager (>=1.42.0,<1.43.0)"] -autoscaling = ["types-boto3-autoscaling (>=1.42.0,<1.43.0)"] -autoscaling-plans = ["types-boto3-autoscaling-plans (>=1.42.0,<1.43.0)"] -b2bi = ["types-boto3-b2bi (>=1.42.0,<1.43.0)"] -backup = ["types-boto3-backup (>=1.42.0,<1.43.0)"] -backup-gateway = ["types-boto3-backup-gateway (>=1.42.0,<1.43.0)"] -backupsearch = ["types-boto3-backupsearch (>=1.42.0,<1.43.0)"] -batch = ["types-boto3-batch (>=1.42.0,<1.43.0)"] -bcm-dashboards = ["types-boto3-bcm-dashboards (>=1.42.0,<1.43.0)"] -bcm-data-exports = ["types-boto3-bcm-data-exports (>=1.42.0,<1.43.0)"] -bcm-pricing-calculator = ["types-boto3-bcm-pricing-calculator (>=1.42.0,<1.43.0)"] -bcm-recommended-actions = ["types-boto3-bcm-recommended-actions (>=1.42.0,<1.43.0)"] -bedrock = ["types-boto3-bedrock (>=1.42.0,<1.43.0)"] -bedrock-agent = ["types-boto3-bedrock-agent (>=1.42.0,<1.43.0)"] -bedrock-agent-runtime = ["types-boto3-bedrock-agent-runtime (>=1.42.0,<1.43.0)"] -bedrock-agentcore = ["types-boto3-bedrock-agentcore (>=1.42.0,<1.43.0)"] -bedrock-agentcore-control = ["types-boto3-bedrock-agentcore-control (>=1.42.0,<1.43.0)"] -bedrock-data-automation = ["types-boto3-bedrock-data-automation (>=1.42.0,<1.43.0)"] -bedrock-data-automation-runtime = ["types-boto3-bedrock-data-automation-runtime (>=1.42.0,<1.43.0)"] -bedrock-runtime = ["types-boto3-bedrock-runtime (>=1.42.0,<1.43.0)"] -billing = ["types-boto3-billing (>=1.42.0,<1.43.0)"] -billingconductor = ["types-boto3-billingconductor (>=1.42.0,<1.43.0)"] -boto3 = ["boto3 (==1.42.74)"] -braket = ["types-boto3-braket (>=1.42.0,<1.43.0)"] -budgets = ["types-boto3-budgets (>=1.42.0,<1.43.0)"] -ce = ["types-boto3-ce (>=1.42.0,<1.43.0)"] -chatbot = ["types-boto3-chatbot (>=1.42.0,<1.43.0)"] -chime = ["types-boto3-chime (>=1.42.0,<1.43.0)"] -chime-sdk-identity = ["types-boto3-chime-sdk-identity (>=1.42.0,<1.43.0)"] -chime-sdk-media-pipelines = ["types-boto3-chime-sdk-media-pipelines (>=1.42.0,<1.43.0)"] -chime-sdk-meetings = ["types-boto3-chime-sdk-meetings (>=1.42.0,<1.43.0)"] -chime-sdk-messaging = ["types-boto3-chime-sdk-messaging (>=1.42.0,<1.43.0)"] -chime-sdk-voice = ["types-boto3-chime-sdk-voice (>=1.42.0,<1.43.0)"] -cleanrooms = ["types-boto3-cleanrooms (>=1.42.0,<1.43.0)"] -cleanroomsml = ["types-boto3-cleanroomsml (>=1.42.0,<1.43.0)"] -cloud9 = ["types-boto3-cloud9 (>=1.42.0,<1.43.0)"] -cloudcontrol = ["types-boto3-cloudcontrol (>=1.42.0,<1.43.0)"] -clouddirectory = ["types-boto3-clouddirectory (>=1.42.0,<1.43.0)"] -cloudformation = ["types-boto3-cloudformation (>=1.42.0,<1.43.0)"] -cloudfront = ["types-boto3-cloudfront (>=1.42.0,<1.43.0)"] -cloudfront-keyvaluestore = ["types-boto3-cloudfront-keyvaluestore (>=1.42.0,<1.43.0)"] -cloudhsm = ["types-boto3-cloudhsm (>=1.42.0,<1.43.0)"] -cloudhsmv2 = ["types-boto3-cloudhsmv2 (>=1.42.0,<1.43.0)"] -cloudsearch = ["types-boto3-cloudsearch (>=1.42.0,<1.43.0)"] -cloudsearchdomain = ["types-boto3-cloudsearchdomain (>=1.42.0,<1.43.0)"] -cloudtrail = ["types-boto3-cloudtrail (>=1.42.0,<1.43.0)"] -cloudtrail-data = ["types-boto3-cloudtrail-data (>=1.42.0,<1.43.0)"] -cloudwatch = ["types-boto3-cloudwatch (>=1.42.0,<1.43.0)"] -codeartifact = ["types-boto3-codeartifact (>=1.42.0,<1.43.0)"] -codebuild = ["types-boto3-codebuild (>=1.42.0,<1.43.0)"] -codecatalyst = ["types-boto3-codecatalyst (>=1.42.0,<1.43.0)"] -codecommit = ["types-boto3-codecommit (>=1.42.0,<1.43.0)"] -codeconnections = ["types-boto3-codeconnections (>=1.42.0,<1.43.0)"] -codedeploy = ["types-boto3-codedeploy (>=1.42.0,<1.43.0)"] -codeguru-reviewer = ["types-boto3-codeguru-reviewer (>=1.42.0,<1.43.0)"] -codeguru-security = ["types-boto3-codeguru-security (>=1.42.0,<1.43.0)"] -codeguruprofiler = ["types-boto3-codeguruprofiler (>=1.42.0,<1.43.0)"] -codepipeline = ["types-boto3-codepipeline (>=1.42.0,<1.43.0)"] -codestar-connections = ["types-boto3-codestar-connections (>=1.42.0,<1.43.0)"] -codestar-notifications = ["types-boto3-codestar-notifications (>=1.42.0,<1.43.0)"] -cognito-identity = ["types-boto3-cognito-identity (>=1.42.0,<1.43.0)"] -cognito-idp = ["types-boto3-cognito-idp (>=1.42.0,<1.43.0)"] -cognito-sync = ["types-boto3-cognito-sync (>=1.42.0,<1.43.0)"] -comprehend = ["types-boto3-comprehend (>=1.42.0,<1.43.0)"] -comprehendmedical = ["types-boto3-comprehendmedical (>=1.42.0,<1.43.0)"] -compute-optimizer = ["types-boto3-compute-optimizer (>=1.42.0,<1.43.0)"] -compute-optimizer-automation = ["types-boto3-compute-optimizer-automation (>=1.42.0,<1.43.0)"] -config = ["types-boto3-config (>=1.42.0,<1.43.0)"] -connect = ["types-boto3-connect (>=1.42.0,<1.43.0)"] -connect-contact-lens = ["types-boto3-connect-contact-lens (>=1.42.0,<1.43.0)"] -connectcampaigns = ["types-boto3-connectcampaigns (>=1.42.0,<1.43.0)"] -connectcampaignsv2 = ["types-boto3-connectcampaignsv2 (>=1.42.0,<1.43.0)"] -connectcases = ["types-boto3-connectcases (>=1.42.0,<1.43.0)"] -connecthealth = ["types-boto3-connecthealth (>=1.42.0,<1.43.0)"] -connectparticipant = ["types-boto3-connectparticipant (>=1.42.0,<1.43.0)"] -controlcatalog = ["types-boto3-controlcatalog (>=1.42.0,<1.43.0)"] -controltower = ["types-boto3-controltower (>=1.42.0,<1.43.0)"] -cost-optimization-hub = ["types-boto3-cost-optimization-hub (>=1.42.0,<1.43.0)"] -cur = ["types-boto3-cur (>=1.42.0,<1.43.0)"] -customer-profiles = ["types-boto3-customer-profiles (>=1.42.0,<1.43.0)"] -databrew = ["types-boto3-databrew (>=1.42.0,<1.43.0)"] -dataexchange = ["types-boto3-dataexchange (>=1.42.0,<1.43.0)"] -datapipeline = ["types-boto3-datapipeline (>=1.42.0,<1.43.0)"] -datasync = ["types-boto3-datasync (>=1.42.0,<1.43.0)"] -datazone = ["types-boto3-datazone (>=1.42.0,<1.43.0)"] -dax = ["types-boto3-dax (>=1.42.0,<1.43.0)"] -deadline = ["types-boto3-deadline (>=1.42.0,<1.43.0)"] -detective = ["types-boto3-detective (>=1.42.0,<1.43.0)"] -devicefarm = ["types-boto3-devicefarm (>=1.42.0,<1.43.0)"] -devops-guru = ["types-boto3-devops-guru (>=1.42.0,<1.43.0)"] -directconnect = ["types-boto3-directconnect (>=1.42.0,<1.43.0)"] -discovery = ["types-boto3-discovery (>=1.42.0,<1.43.0)"] -dlm = ["types-boto3-dlm (>=1.42.0,<1.43.0)"] -dms = ["types-boto3-dms (>=1.42.0,<1.43.0)"] -docdb = ["types-boto3-docdb (>=1.42.0,<1.43.0)"] -docdb-elastic = ["types-boto3-docdb-elastic (>=1.42.0,<1.43.0)"] -drs = ["types-boto3-drs (>=1.42.0,<1.43.0)"] -ds = ["types-boto3-ds (>=1.42.0,<1.43.0)"] -ds-data = ["types-boto3-ds-data (>=1.42.0,<1.43.0)"] -dsql = ["types-boto3-dsql (>=1.42.0,<1.43.0)"] -dynamodb = ["types-boto3-dynamodb (>=1.42.0,<1.43.0)"] -dynamodbstreams = ["types-boto3-dynamodbstreams (>=1.42.0,<1.43.0)"] -ebs = ["types-boto3-ebs (>=1.42.0,<1.43.0)"] -ec2 = ["types-boto3-ec2 (>=1.42.0,<1.43.0)"] -ec2-instance-connect = ["types-boto3-ec2-instance-connect (>=1.42.0,<1.43.0)"] -ecr = ["types-boto3-ecr (>=1.42.0,<1.43.0)"] -ecr-public = ["types-boto3-ecr-public (>=1.42.0,<1.43.0)"] -ecs = ["types-boto3-ecs (>=1.42.0,<1.43.0)"] -efs = ["types-boto3-efs (>=1.42.0,<1.43.0)"] -eks = ["types-boto3-eks (>=1.42.0,<1.43.0)"] -eks-auth = ["types-boto3-eks-auth (>=1.42.0,<1.43.0)"] -elasticache = ["types-boto3-elasticache (>=1.42.0,<1.43.0)"] -elasticbeanstalk = ["types-boto3-elasticbeanstalk (>=1.42.0,<1.43.0)"] -elb = ["types-boto3-elb (>=1.42.0,<1.43.0)"] -elbv2 = ["types-boto3-elbv2 (>=1.42.0,<1.43.0)"] -elementalinference = ["types-boto3-elementalinference (>=1.42.0,<1.43.0)"] -emr = ["types-boto3-emr (>=1.42.0,<1.43.0)"] -emr-containers = ["types-boto3-emr-containers (>=1.42.0,<1.43.0)"] -emr-serverless = ["types-boto3-emr-serverless (>=1.42.0,<1.43.0)"] -entityresolution = ["types-boto3-entityresolution (>=1.42.0,<1.43.0)"] -es = ["types-boto3-es (>=1.42.0,<1.43.0)"] -essential = ["types-boto3-cloudformation (>=1.42.0,<1.43.0)", "types-boto3-dynamodb (>=1.42.0,<1.43.0)", "types-boto3-ec2 (>=1.42.0,<1.43.0)", "types-boto3-lambda (>=1.42.0,<1.43.0)", "types-boto3-rds (>=1.42.0,<1.43.0)", "types-boto3-s3 (>=1.42.0,<1.43.0)", "types-boto3-sqs (>=1.42.0,<1.43.0)"] -events = ["types-boto3-events (>=1.42.0,<1.43.0)"] -evs = ["types-boto3-evs (>=1.42.0,<1.43.0)"] -finspace = ["types-boto3-finspace (>=1.42.0,<1.43.0)"] -finspace-data = ["types-boto3-finspace-data (>=1.42.0,<1.43.0)"] -firehose = ["types-boto3-firehose (>=1.42.0,<1.43.0)"] -fis = ["types-boto3-fis (>=1.42.0,<1.43.0)"] -fms = ["types-boto3-fms (>=1.42.0,<1.43.0)"] -forecast = ["types-boto3-forecast (>=1.42.0,<1.43.0)"] -forecastquery = ["types-boto3-forecastquery (>=1.42.0,<1.43.0)"] -frauddetector = ["types-boto3-frauddetector (>=1.42.0,<1.43.0)"] -freetier = ["types-boto3-freetier (>=1.42.0,<1.43.0)"] -fsx = ["types-boto3-fsx (>=1.42.0,<1.43.0)"] -full = ["types-boto3-full (>=1.42.0,<1.43.0)"] -gamelift = ["types-boto3-gamelift (>=1.42.0,<1.43.0)"] -gameliftstreams = ["types-boto3-gameliftstreams (>=1.42.0,<1.43.0)"] -geo-maps = ["types-boto3-geo-maps (>=1.42.0,<1.43.0)"] -geo-places = ["types-boto3-geo-places (>=1.42.0,<1.43.0)"] -geo-routes = ["types-boto3-geo-routes (>=1.42.0,<1.43.0)"] -glacier = ["types-boto3-glacier (>=1.42.0,<1.43.0)"] -globalaccelerator = ["types-boto3-globalaccelerator (>=1.42.0,<1.43.0)"] -glue = ["types-boto3-glue (>=1.42.0,<1.43.0)"] -grafana = ["types-boto3-grafana (>=1.42.0,<1.43.0)"] -greengrass = ["types-boto3-greengrass (>=1.42.0,<1.43.0)"] -greengrassv2 = ["types-boto3-greengrassv2 (>=1.42.0,<1.43.0)"] -groundstation = ["types-boto3-groundstation (>=1.42.0,<1.43.0)"] -guardduty = ["types-boto3-guardduty (>=1.42.0,<1.43.0)"] -health = ["types-boto3-health (>=1.42.0,<1.43.0)"] -healthlake = ["types-boto3-healthlake (>=1.42.0,<1.43.0)"] -iam = ["types-boto3-iam (>=1.42.0,<1.43.0)"] -identitystore = ["types-boto3-identitystore (>=1.42.0,<1.43.0)"] -imagebuilder = ["types-boto3-imagebuilder (>=1.42.0,<1.43.0)"] -importexport = ["types-boto3-importexport (>=1.42.0,<1.43.0)"] -inspector = ["types-boto3-inspector (>=1.42.0,<1.43.0)"] -inspector-scan = ["types-boto3-inspector-scan (>=1.42.0,<1.43.0)"] -inspector2 = ["types-boto3-inspector2 (>=1.42.0,<1.43.0)"] -internetmonitor = ["types-boto3-internetmonitor (>=1.42.0,<1.43.0)"] -invoicing = ["types-boto3-invoicing (>=1.42.0,<1.43.0)"] -iot = ["types-boto3-iot (>=1.42.0,<1.43.0)"] -iot-data = ["types-boto3-iot-data (>=1.42.0,<1.43.0)"] -iot-jobs-data = ["types-boto3-iot-jobs-data (>=1.42.0,<1.43.0)"] -iot-managed-integrations = ["types-boto3-iot-managed-integrations (>=1.42.0,<1.43.0)"] -iotdeviceadvisor = ["types-boto3-iotdeviceadvisor (>=1.42.0,<1.43.0)"] -iotevents = ["types-boto3-iotevents (>=1.42.0,<1.43.0)"] -iotevents-data = ["types-boto3-iotevents-data (>=1.42.0,<1.43.0)"] -iotfleetwise = ["types-boto3-iotfleetwise (>=1.42.0,<1.43.0)"] -iotsecuretunneling = ["types-boto3-iotsecuretunneling (>=1.42.0,<1.43.0)"] -iotsitewise = ["types-boto3-iotsitewise (>=1.42.0,<1.43.0)"] -iotthingsgraph = ["types-boto3-iotthingsgraph (>=1.42.0,<1.43.0)"] -iottwinmaker = ["types-boto3-iottwinmaker (>=1.42.0,<1.43.0)"] -iotwireless = ["types-boto3-iotwireless (>=1.42.0,<1.43.0)"] -ivs = ["types-boto3-ivs (>=1.42.0,<1.43.0)"] -ivs-realtime = ["types-boto3-ivs-realtime (>=1.42.0,<1.43.0)"] -ivschat = ["types-boto3-ivschat (>=1.42.0,<1.43.0)"] -kafka = ["types-boto3-kafka (>=1.42.0,<1.43.0)"] -kafkaconnect = ["types-boto3-kafkaconnect (>=1.42.0,<1.43.0)"] -kendra = ["types-boto3-kendra (>=1.42.0,<1.43.0)"] -kendra-ranking = ["types-boto3-kendra-ranking (>=1.42.0,<1.43.0)"] -keyspaces = ["types-boto3-keyspaces (>=1.42.0,<1.43.0)"] -keyspacesstreams = ["types-boto3-keyspacesstreams (>=1.42.0,<1.43.0)"] -kinesis = ["types-boto3-kinesis (>=1.42.0,<1.43.0)"] -kinesis-video-archived-media = ["types-boto3-kinesis-video-archived-media (>=1.42.0,<1.43.0)"] -kinesis-video-media = ["types-boto3-kinesis-video-media (>=1.42.0,<1.43.0)"] -kinesis-video-signaling = ["types-boto3-kinesis-video-signaling (>=1.42.0,<1.43.0)"] -kinesis-video-webrtc-storage = ["types-boto3-kinesis-video-webrtc-storage (>=1.42.0,<1.43.0)"] -kinesisanalytics = ["types-boto3-kinesisanalytics (>=1.42.0,<1.43.0)"] -kinesisanalyticsv2 = ["types-boto3-kinesisanalyticsv2 (>=1.42.0,<1.43.0)"] -kinesisvideo = ["types-boto3-kinesisvideo (>=1.42.0,<1.43.0)"] -kms = ["types-boto3-kms (>=1.42.0,<1.43.0)"] -lakeformation = ["types-boto3-lakeformation (>=1.42.0,<1.43.0)"] -lambda = ["types-boto3-lambda (>=1.42.0,<1.43.0)"] -launch-wizard = ["types-boto3-launch-wizard (>=1.42.0,<1.43.0)"] -lex-models = ["types-boto3-lex-models (>=1.42.0,<1.43.0)"] -lex-runtime = ["types-boto3-lex-runtime (>=1.42.0,<1.43.0)"] -lexv2-models = ["types-boto3-lexv2-models (>=1.42.0,<1.43.0)"] -lexv2-runtime = ["types-boto3-lexv2-runtime (>=1.42.0,<1.43.0)"] -license-manager = ["types-boto3-license-manager (>=1.42.0,<1.43.0)"] -license-manager-linux-subscriptions = ["types-boto3-license-manager-linux-subscriptions (>=1.42.0,<1.43.0)"] -license-manager-user-subscriptions = ["types-boto3-license-manager-user-subscriptions (>=1.42.0,<1.43.0)"] -lightsail = ["types-boto3-lightsail (>=1.42.0,<1.43.0)"] -location = ["types-boto3-location (>=1.42.0,<1.43.0)"] -logs = ["types-boto3-logs (>=1.42.0,<1.43.0)"] -lookoutequipment = ["types-boto3-lookoutequipment (>=1.42.0,<1.43.0)"] -m2 = ["types-boto3-m2 (>=1.42.0,<1.43.0)"] -machinelearning = ["types-boto3-machinelearning (>=1.42.0,<1.43.0)"] -macie2 = ["types-boto3-macie2 (>=1.42.0,<1.43.0)"] -mailmanager = ["types-boto3-mailmanager (>=1.42.0,<1.43.0)"] -managedblockchain = ["types-boto3-managedblockchain (>=1.42.0,<1.43.0)"] -managedblockchain-query = ["types-boto3-managedblockchain-query (>=1.42.0,<1.43.0)"] -marketplace-agreement = ["types-boto3-marketplace-agreement (>=1.42.0,<1.43.0)"] -marketplace-catalog = ["types-boto3-marketplace-catalog (>=1.42.0,<1.43.0)"] -marketplace-deployment = ["types-boto3-marketplace-deployment (>=1.42.0,<1.43.0)"] -marketplace-entitlement = ["types-boto3-marketplace-entitlement (>=1.42.0,<1.43.0)"] -marketplace-reporting = ["types-boto3-marketplace-reporting (>=1.42.0,<1.43.0)"] -marketplacecommerceanalytics = ["types-boto3-marketplacecommerceanalytics (>=1.42.0,<1.43.0)"] -mediaconnect = ["types-boto3-mediaconnect (>=1.42.0,<1.43.0)"] -mediaconvert = ["types-boto3-mediaconvert (>=1.42.0,<1.43.0)"] -medialive = ["types-boto3-medialive (>=1.42.0,<1.43.0)"] -mediapackage = ["types-boto3-mediapackage (>=1.42.0,<1.43.0)"] -mediapackage-vod = ["types-boto3-mediapackage-vod (>=1.42.0,<1.43.0)"] -mediapackagev2 = ["types-boto3-mediapackagev2 (>=1.42.0,<1.43.0)"] -mediastore = ["types-boto3-mediastore (>=1.42.0,<1.43.0)"] -mediastore-data = ["types-boto3-mediastore-data (>=1.42.0,<1.43.0)"] -mediatailor = ["types-boto3-mediatailor (>=1.42.0,<1.43.0)"] -medical-imaging = ["types-boto3-medical-imaging (>=1.42.0,<1.43.0)"] -memorydb = ["types-boto3-memorydb (>=1.42.0,<1.43.0)"] -meteringmarketplace = ["types-boto3-meteringmarketplace (>=1.42.0,<1.43.0)"] -mgh = ["types-boto3-mgh (>=1.42.0,<1.43.0)"] -mgn = ["types-boto3-mgn (>=1.42.0,<1.43.0)"] -migration-hub-refactor-spaces = ["types-boto3-migration-hub-refactor-spaces (>=1.42.0,<1.43.0)"] -migrationhub-config = ["types-boto3-migrationhub-config (>=1.42.0,<1.43.0)"] -migrationhuborchestrator = ["types-boto3-migrationhuborchestrator (>=1.42.0,<1.43.0)"] -migrationhubstrategy = ["types-boto3-migrationhubstrategy (>=1.42.0,<1.43.0)"] -mpa = ["types-boto3-mpa (>=1.42.0,<1.43.0)"] -mq = ["types-boto3-mq (>=1.42.0,<1.43.0)"] -mturk = ["types-boto3-mturk (>=1.42.0,<1.43.0)"] -mwaa = ["types-boto3-mwaa (>=1.42.0,<1.43.0)"] -mwaa-serverless = ["types-boto3-mwaa-serverless (>=1.42.0,<1.43.0)"] -neptune = ["types-boto3-neptune (>=1.42.0,<1.43.0)"] -neptune-graph = ["types-boto3-neptune-graph (>=1.42.0,<1.43.0)"] -neptunedata = ["types-boto3-neptunedata (>=1.42.0,<1.43.0)"] -network-firewall = ["types-boto3-network-firewall (>=1.42.0,<1.43.0)"] -networkflowmonitor = ["types-boto3-networkflowmonitor (>=1.42.0,<1.43.0)"] -networkmanager = ["types-boto3-networkmanager (>=1.42.0,<1.43.0)"] -networkmonitor = ["types-boto3-networkmonitor (>=1.42.0,<1.43.0)"] -notifications = ["types-boto3-notifications (>=1.42.0,<1.43.0)"] -notificationscontacts = ["types-boto3-notificationscontacts (>=1.42.0,<1.43.0)"] -nova-act = ["types-boto3-nova-act (>=1.42.0,<1.43.0)"] -oam = ["types-boto3-oam (>=1.42.0,<1.43.0)"] -observabilityadmin = ["types-boto3-observabilityadmin (>=1.42.0,<1.43.0)"] -odb = ["types-boto3-odb (>=1.42.0,<1.43.0)"] -omics = ["types-boto3-omics (>=1.42.0,<1.43.0)"] -opensearch = ["types-boto3-opensearch (>=1.42.0,<1.43.0)"] -opensearchserverless = ["types-boto3-opensearchserverless (>=1.42.0,<1.43.0)"] -organizations = ["types-boto3-organizations (>=1.42.0,<1.43.0)"] -osis = ["types-boto3-osis (>=1.42.0,<1.43.0)"] -outposts = ["types-boto3-outposts (>=1.42.0,<1.43.0)"] -panorama = ["types-boto3-panorama (>=1.42.0,<1.43.0)"] -partnercentral-account = ["types-boto3-partnercentral-account (>=1.42.0,<1.43.0)"] -partnercentral-benefits = ["types-boto3-partnercentral-benefits (>=1.42.0,<1.43.0)"] -partnercentral-channel = ["types-boto3-partnercentral-channel (>=1.42.0,<1.43.0)"] -partnercentral-selling = ["types-boto3-partnercentral-selling (>=1.42.0,<1.43.0)"] -payment-cryptography = ["types-boto3-payment-cryptography (>=1.42.0,<1.43.0)"] -payment-cryptography-data = ["types-boto3-payment-cryptography-data (>=1.42.0,<1.43.0)"] -pca-connector-ad = ["types-boto3-pca-connector-ad (>=1.42.0,<1.43.0)"] -pca-connector-scep = ["types-boto3-pca-connector-scep (>=1.42.0,<1.43.0)"] -pcs = ["types-boto3-pcs (>=1.42.0,<1.43.0)"] -personalize = ["types-boto3-personalize (>=1.42.0,<1.43.0)"] -personalize-events = ["types-boto3-personalize-events (>=1.42.0,<1.43.0)"] -personalize-runtime = ["types-boto3-personalize-runtime (>=1.42.0,<1.43.0)"] -pi = ["types-boto3-pi (>=1.42.0,<1.43.0)"] -pinpoint = ["types-boto3-pinpoint (>=1.42.0,<1.43.0)"] -pinpoint-email = ["types-boto3-pinpoint-email (>=1.42.0,<1.43.0)"] -pinpoint-sms-voice = ["types-boto3-pinpoint-sms-voice (>=1.42.0,<1.43.0)"] -pinpoint-sms-voice-v2 = ["types-boto3-pinpoint-sms-voice-v2 (>=1.42.0,<1.43.0)"] -pipes = ["types-boto3-pipes (>=1.42.0,<1.43.0)"] -polly = ["types-boto3-polly (>=1.42.0,<1.43.0)"] -pricing = ["types-boto3-pricing (>=1.42.0,<1.43.0)"] -proton = ["types-boto3-proton (>=1.42.0,<1.43.0)"] -qapps = ["types-boto3-qapps (>=1.42.0,<1.43.0)"] -qbusiness = ["types-boto3-qbusiness (>=1.42.0,<1.43.0)"] -qconnect = ["types-boto3-qconnect (>=1.42.0,<1.43.0)"] -quicksight = ["types-boto3-quicksight (>=1.42.0,<1.43.0)"] -ram = ["types-boto3-ram (>=1.42.0,<1.43.0)"] -rbin = ["types-boto3-rbin (>=1.42.0,<1.43.0)"] -rds = ["types-boto3-rds (>=1.42.0,<1.43.0)"] -rds-data = ["types-boto3-rds-data (>=1.42.0,<1.43.0)"] -redshift = ["types-boto3-redshift (>=1.42.0,<1.43.0)"] -redshift-data = ["types-boto3-redshift-data (>=1.42.0,<1.43.0)"] -redshift-serverless = ["types-boto3-redshift-serverless (>=1.42.0,<1.43.0)"] -rekognition = ["types-boto3-rekognition (>=1.42.0,<1.43.0)"] -repostspace = ["types-boto3-repostspace (>=1.42.0,<1.43.0)"] -resiliencehub = ["types-boto3-resiliencehub (>=1.42.0,<1.43.0)"] -resource-explorer-2 = ["types-boto3-resource-explorer-2 (>=1.42.0,<1.43.0)"] -resource-groups = ["types-boto3-resource-groups (>=1.42.0,<1.43.0)"] -resourcegroupstaggingapi = ["types-boto3-resourcegroupstaggingapi (>=1.42.0,<1.43.0)"] -rolesanywhere = ["types-boto3-rolesanywhere (>=1.42.0,<1.43.0)"] -route53 = ["types-boto3-route53 (>=1.42.0,<1.43.0)"] -route53-recovery-cluster = ["types-boto3-route53-recovery-cluster (>=1.42.0,<1.43.0)"] -route53-recovery-control-config = ["types-boto3-route53-recovery-control-config (>=1.42.0,<1.43.0)"] -route53-recovery-readiness = ["types-boto3-route53-recovery-readiness (>=1.42.0,<1.43.0)"] -route53domains = ["types-boto3-route53domains (>=1.42.0,<1.43.0)"] -route53globalresolver = ["types-boto3-route53globalresolver (>=1.42.0,<1.43.0)"] -route53profiles = ["types-boto3-route53profiles (>=1.42.0,<1.43.0)"] -route53resolver = ["types-boto3-route53resolver (>=1.42.0,<1.43.0)"] -rtbfabric = ["types-boto3-rtbfabric (>=1.42.0,<1.43.0)"] -rum = ["types-boto3-rum (>=1.42.0,<1.43.0)"] -s3 = ["types-boto3-s3 (>=1.42.0,<1.43.0)"] -s3control = ["types-boto3-s3control (>=1.42.0,<1.43.0)"] -s3outposts = ["types-boto3-s3outposts (>=1.42.0,<1.43.0)"] -s3tables = ["types-boto3-s3tables (>=1.42.0,<1.43.0)"] -s3vectors = ["types-boto3-s3vectors (>=1.42.0,<1.43.0)"] -sagemaker = ["types-boto3-sagemaker (>=1.42.0,<1.43.0)"] -sagemaker-a2i-runtime = ["types-boto3-sagemaker-a2i-runtime (>=1.42.0,<1.43.0)"] -sagemaker-edge = ["types-boto3-sagemaker-edge (>=1.42.0,<1.43.0)"] -sagemaker-featurestore-runtime = ["types-boto3-sagemaker-featurestore-runtime (>=1.42.0,<1.43.0)"] -sagemaker-geospatial = ["types-boto3-sagemaker-geospatial (>=1.42.0,<1.43.0)"] -sagemaker-metrics = ["types-boto3-sagemaker-metrics (>=1.42.0,<1.43.0)"] -sagemaker-runtime = ["types-boto3-sagemaker-runtime (>=1.42.0,<1.43.0)"] -savingsplans = ["types-boto3-savingsplans (>=1.42.0,<1.43.0)"] -scheduler = ["types-boto3-scheduler (>=1.42.0,<1.43.0)"] -schemas = ["types-boto3-schemas (>=1.42.0,<1.43.0)"] -sdb = ["types-boto3-sdb (>=1.42.0,<1.43.0)"] -secretsmanager = ["types-boto3-secretsmanager (>=1.42.0,<1.43.0)"] -security-ir = ["types-boto3-security-ir (>=1.42.0,<1.43.0)"] -securityhub = ["types-boto3-securityhub (>=1.42.0,<1.43.0)"] -securitylake = ["types-boto3-securitylake (>=1.42.0,<1.43.0)"] -serverlessrepo = ["types-boto3-serverlessrepo (>=1.42.0,<1.43.0)"] -service-quotas = ["types-boto3-service-quotas (>=1.42.0,<1.43.0)"] -servicecatalog = ["types-boto3-servicecatalog (>=1.42.0,<1.43.0)"] -servicecatalog-appregistry = ["types-boto3-servicecatalog-appregistry (>=1.42.0,<1.43.0)"] -servicediscovery = ["types-boto3-servicediscovery (>=1.42.0,<1.43.0)"] -ses = ["types-boto3-ses (>=1.42.0,<1.43.0)"] -sesv2 = ["types-boto3-sesv2 (>=1.42.0,<1.43.0)"] -shield = ["types-boto3-shield (>=1.42.0,<1.43.0)"] -signer = ["types-boto3-signer (>=1.42.0,<1.43.0)"] -signer-data = ["types-boto3-signer-data (>=1.42.0,<1.43.0)"] -signin = ["types-boto3-signin (>=1.42.0,<1.43.0)"] -simpledbv2 = ["types-boto3-simpledbv2 (>=1.42.0,<1.43.0)"] -simspaceweaver = ["types-boto3-simspaceweaver (>=1.42.0,<1.43.0)"] -snow-device-management = ["types-boto3-snow-device-management (>=1.42.0,<1.43.0)"] -snowball = ["types-boto3-snowball (>=1.42.0,<1.43.0)"] -sns = ["types-boto3-sns (>=1.42.0,<1.43.0)"] -socialmessaging = ["types-boto3-socialmessaging (>=1.42.0,<1.43.0)"] -sqs = ["types-boto3-sqs (>=1.42.0,<1.43.0)"] -ssm = ["types-boto3-ssm (>=1.42.0,<1.43.0)"] -ssm-contacts = ["types-boto3-ssm-contacts (>=1.42.0,<1.43.0)"] -ssm-guiconnect = ["types-boto3-ssm-guiconnect (>=1.42.0,<1.43.0)"] -ssm-incidents = ["types-boto3-ssm-incidents (>=1.42.0,<1.43.0)"] -ssm-quicksetup = ["types-boto3-ssm-quicksetup (>=1.42.0,<1.43.0)"] -ssm-sap = ["types-boto3-ssm-sap (>=1.42.0,<1.43.0)"] -sso = ["types-boto3-sso (>=1.42.0,<1.43.0)"] -sso-admin = ["types-boto3-sso-admin (>=1.42.0,<1.43.0)"] -sso-oidc = ["types-boto3-sso-oidc (>=1.42.0,<1.43.0)"] -stepfunctions = ["types-boto3-stepfunctions (>=1.42.0,<1.43.0)"] -storagegateway = ["types-boto3-storagegateway (>=1.42.0,<1.43.0)"] -sts = ["types-boto3-sts (>=1.42.0,<1.43.0)"] -supplychain = ["types-boto3-supplychain (>=1.42.0,<1.43.0)"] -support = ["types-boto3-support (>=1.42.0,<1.43.0)"] -support-app = ["types-boto3-support-app (>=1.42.0,<1.43.0)"] -swf = ["types-boto3-swf (>=1.42.0,<1.43.0)"] -synthetics = ["types-boto3-synthetics (>=1.42.0,<1.43.0)"] -taxsettings = ["types-boto3-taxsettings (>=1.42.0,<1.43.0)"] -textract = ["types-boto3-textract (>=1.42.0,<1.43.0)"] -timestream-influxdb = ["types-boto3-timestream-influxdb (>=1.42.0,<1.43.0)"] -timestream-query = ["types-boto3-timestream-query (>=1.42.0,<1.43.0)"] -timestream-write = ["types-boto3-timestream-write (>=1.42.0,<1.43.0)"] -tnb = ["types-boto3-tnb (>=1.42.0,<1.43.0)"] -transcribe = ["types-boto3-transcribe (>=1.42.0,<1.43.0)"] -transfer = ["types-boto3-transfer (>=1.42.0,<1.43.0)"] -translate = ["types-boto3-translate (>=1.42.0,<1.43.0)"] -trustedadvisor = ["types-boto3-trustedadvisor (>=1.42.0,<1.43.0)"] -verifiedpermissions = ["types-boto3-verifiedpermissions (>=1.42.0,<1.43.0)"] -voice-id = ["types-boto3-voice-id (>=1.42.0,<1.43.0)"] -vpc-lattice = ["types-boto3-vpc-lattice (>=1.42.0,<1.43.0)"] -waf = ["types-boto3-waf (>=1.42.0,<1.43.0)"] -waf-regional = ["types-boto3-waf-regional (>=1.42.0,<1.43.0)"] -wafv2 = ["types-boto3-wafv2 (>=1.42.0,<1.43.0)"] -wellarchitected = ["types-boto3-wellarchitected (>=1.42.0,<1.43.0)"] -wickr = ["types-boto3-wickr (>=1.42.0,<1.43.0)"] -wisdom = ["types-boto3-wisdom (>=1.42.0,<1.43.0)"] -workdocs = ["types-boto3-workdocs (>=1.42.0,<1.43.0)"] -workmail = ["types-boto3-workmail (>=1.42.0,<1.43.0)"] -workmailmessageflow = ["types-boto3-workmailmessageflow (>=1.42.0,<1.43.0)"] -workspaces = ["types-boto3-workspaces (>=1.42.0,<1.43.0)"] -workspaces-instances = ["types-boto3-workspaces-instances (>=1.42.0,<1.43.0)"] -workspaces-thin-client = ["types-boto3-workspaces-thin-client (>=1.42.0,<1.43.0)"] -workspaces-web = ["types-boto3-workspaces-web (>=1.42.0,<1.43.0)"] -xray = ["types-boto3-xray (>=1.42.0,<1.43.0)"] +accessanalyzer = ["types-boto3-accessanalyzer (>=1.43.0,<1.44.0)"] +account = ["types-boto3-account (>=1.43.0,<1.44.0)"] +acm = ["types-boto3-acm (>=1.43.0,<1.44.0)"] +acm-pca = ["types-boto3-acm-pca (>=1.43.0,<1.44.0)"] +aiops = ["types-boto3-aiops (>=1.43.0,<1.44.0)"] +all = ["types-boto3-accessanalyzer (>=1.43.0,<1.44.0)", "types-boto3-account (>=1.43.0,<1.44.0)", "types-boto3-acm (>=1.43.0,<1.44.0)", "types-boto3-acm-pca (>=1.43.0,<1.44.0)", "types-boto3-aiops (>=1.43.0,<1.44.0)", "types-boto3-amp (>=1.43.0,<1.44.0)", "types-boto3-amplify (>=1.43.0,<1.44.0)", "types-boto3-amplifybackend (>=1.43.0,<1.44.0)", "types-boto3-amplifyuibuilder (>=1.43.0,<1.44.0)", "types-boto3-apigateway (>=1.43.0,<1.44.0)", "types-boto3-apigatewaymanagementapi (>=1.43.0,<1.44.0)", "types-boto3-apigatewayv2 (>=1.43.0,<1.44.0)", "types-boto3-appconfig (>=1.43.0,<1.44.0)", "types-boto3-appconfigdata (>=1.43.0,<1.44.0)", "types-boto3-appfabric (>=1.43.0,<1.44.0)", "types-boto3-appflow (>=1.43.0,<1.44.0)", "types-boto3-appintegrations (>=1.43.0,<1.44.0)", "types-boto3-application-autoscaling (>=1.43.0,<1.44.0)", "types-boto3-application-insights (>=1.43.0,<1.44.0)", "types-boto3-application-signals (>=1.43.0,<1.44.0)", "types-boto3-applicationcostprofiler (>=1.43.0,<1.44.0)", "types-boto3-appmesh (>=1.43.0,<1.44.0)", "types-boto3-apprunner (>=1.43.0,<1.44.0)", "types-boto3-appstream (>=1.43.0,<1.44.0)", "types-boto3-appsync (>=1.43.0,<1.44.0)", "types-boto3-arc-region-switch (>=1.43.0,<1.44.0)", "types-boto3-arc-zonal-shift (>=1.43.0,<1.44.0)", "types-boto3-artifact (>=1.43.0,<1.44.0)", "types-boto3-athena (>=1.43.0,<1.44.0)", "types-boto3-auditmanager (>=1.43.0,<1.44.0)", "types-boto3-autoscaling (>=1.43.0,<1.44.0)", "types-boto3-autoscaling-plans (>=1.43.0,<1.44.0)", "types-boto3-b2bi (>=1.43.0,<1.44.0)", "types-boto3-backup (>=1.43.0,<1.44.0)", "types-boto3-backup-gateway (>=1.43.0,<1.44.0)", "types-boto3-backupsearch (>=1.43.0,<1.44.0)", "types-boto3-batch (>=1.43.0,<1.44.0)", "types-boto3-bcm-dashboards (>=1.43.0,<1.44.0)", "types-boto3-bcm-data-exports (>=1.43.0,<1.44.0)", "types-boto3-bcm-pricing-calculator (>=1.43.0,<1.44.0)", "types-boto3-bcm-recommended-actions (>=1.43.0,<1.44.0)", "types-boto3-bedrock (>=1.43.0,<1.44.0)", "types-boto3-bedrock-agent (>=1.43.0,<1.44.0)", "types-boto3-bedrock-agent-runtime (>=1.43.0,<1.44.0)", "types-boto3-bedrock-agentcore (>=1.43.0,<1.44.0)", "types-boto3-bedrock-agentcore-control (>=1.43.0,<1.44.0)", "types-boto3-bedrock-data-automation (>=1.43.0,<1.44.0)", "types-boto3-bedrock-data-automation-runtime (>=1.43.0,<1.44.0)", "types-boto3-bedrock-runtime (>=1.43.0,<1.44.0)", "types-boto3-billing (>=1.43.0,<1.44.0)", "types-boto3-billingconductor (>=1.43.0,<1.44.0)", "types-boto3-braket (>=1.43.0,<1.44.0)", "types-boto3-budgets (>=1.43.0,<1.44.0)", "types-boto3-ce (>=1.43.0,<1.44.0)", "types-boto3-chatbot (>=1.43.0,<1.44.0)", "types-boto3-chime (>=1.43.0,<1.44.0)", "types-boto3-chime-sdk-identity (>=1.43.0,<1.44.0)", "types-boto3-chime-sdk-media-pipelines (>=1.43.0,<1.44.0)", "types-boto3-chime-sdk-meetings (>=1.43.0,<1.44.0)", "types-boto3-chime-sdk-messaging (>=1.43.0,<1.44.0)", "types-boto3-chime-sdk-voice (>=1.43.0,<1.44.0)", "types-boto3-cleanrooms (>=1.43.0,<1.44.0)", "types-boto3-cleanroomsml (>=1.43.0,<1.44.0)", "types-boto3-cloud9 (>=1.43.0,<1.44.0)", "types-boto3-cloudcontrol (>=1.43.0,<1.44.0)", "types-boto3-clouddirectory (>=1.43.0,<1.44.0)", "types-boto3-cloudformation (>=1.43.0,<1.44.0)", "types-boto3-cloudfront (>=1.43.0,<1.44.0)", "types-boto3-cloudfront-keyvaluestore (>=1.43.0,<1.44.0)", "types-boto3-cloudhsm (>=1.43.0,<1.44.0)", "types-boto3-cloudhsmv2 (>=1.43.0,<1.44.0)", "types-boto3-cloudsearch (>=1.43.0,<1.44.0)", "types-boto3-cloudsearchdomain (>=1.43.0,<1.44.0)", "types-boto3-cloudtrail (>=1.43.0,<1.44.0)", "types-boto3-cloudtrail-data (>=1.43.0,<1.44.0)", "types-boto3-cloudwatch (>=1.43.0,<1.44.0)", "types-boto3-codeartifact (>=1.43.0,<1.44.0)", "types-boto3-codebuild (>=1.43.0,<1.44.0)", "types-boto3-codecatalyst (>=1.43.0,<1.44.0)", "types-boto3-codecommit (>=1.43.0,<1.44.0)", "types-boto3-codeconnections (>=1.43.0,<1.44.0)", "types-boto3-codedeploy (>=1.43.0,<1.44.0)", "types-boto3-codeguru-reviewer (>=1.43.0,<1.44.0)", "types-boto3-codeguru-security (>=1.43.0,<1.44.0)", "types-boto3-codeguruprofiler (>=1.43.0,<1.44.0)", "types-boto3-codepipeline (>=1.43.0,<1.44.0)", "types-boto3-codestar-connections (>=1.43.0,<1.44.0)", "types-boto3-codestar-notifications (>=1.43.0,<1.44.0)", "types-boto3-cognito-identity (>=1.43.0,<1.44.0)", "types-boto3-cognito-idp (>=1.43.0,<1.44.0)", "types-boto3-cognito-sync (>=1.43.0,<1.44.0)", "types-boto3-comprehend (>=1.43.0,<1.44.0)", "types-boto3-comprehendmedical (>=1.43.0,<1.44.0)", "types-boto3-compute-optimizer (>=1.43.0,<1.44.0)", "types-boto3-compute-optimizer-automation (>=1.43.0,<1.44.0)", "types-boto3-config (>=1.43.0,<1.44.0)", "types-boto3-connect (>=1.43.0,<1.44.0)", "types-boto3-connect-contact-lens (>=1.43.0,<1.44.0)", "types-boto3-connectcampaigns (>=1.43.0,<1.44.0)", "types-boto3-connectcampaignsv2 (>=1.43.0,<1.44.0)", "types-boto3-connectcases (>=1.43.0,<1.44.0)", "types-boto3-connecthealth (>=1.43.0,<1.44.0)", "types-boto3-connectparticipant (>=1.43.0,<1.44.0)", "types-boto3-controlcatalog (>=1.43.0,<1.44.0)", "types-boto3-controltower (>=1.43.0,<1.44.0)", "types-boto3-cost-optimization-hub (>=1.43.0,<1.44.0)", "types-boto3-cur (>=1.43.0,<1.44.0)", "types-boto3-customer-profiles (>=1.43.0,<1.44.0)", "types-boto3-databrew (>=1.43.0,<1.44.0)", "types-boto3-dataexchange (>=1.43.0,<1.44.0)", "types-boto3-datapipeline (>=1.43.0,<1.44.0)", "types-boto3-datasync (>=1.43.0,<1.44.0)", "types-boto3-datazone (>=1.43.0,<1.44.0)", "types-boto3-dax (>=1.43.0,<1.44.0)", "types-boto3-deadline (>=1.43.0,<1.44.0)", "types-boto3-detective (>=1.43.0,<1.44.0)", "types-boto3-devicefarm (>=1.43.0,<1.44.0)", "types-boto3-devops-agent (>=1.43.0,<1.44.0)", "types-boto3-devops-guru (>=1.43.0,<1.44.0)", "types-boto3-directconnect (>=1.43.0,<1.44.0)", "types-boto3-discovery (>=1.43.0,<1.44.0)", "types-boto3-dlm (>=1.43.0,<1.44.0)", "types-boto3-dms (>=1.43.0,<1.44.0)", "types-boto3-docdb (>=1.43.0,<1.44.0)", "types-boto3-docdb-elastic (>=1.43.0,<1.44.0)", "types-boto3-drs (>=1.43.0,<1.44.0)", "types-boto3-ds (>=1.43.0,<1.44.0)", "types-boto3-ds-data (>=1.43.0,<1.44.0)", "types-boto3-dsql (>=1.43.0,<1.44.0)", "types-boto3-dynamodb (>=1.43.0,<1.44.0)", "types-boto3-dynamodbstreams (>=1.43.0,<1.44.0)", "types-boto3-ebs (>=1.43.0,<1.44.0)", "types-boto3-ec2 (>=1.43.0,<1.44.0)", "types-boto3-ec2-instance-connect (>=1.43.0,<1.44.0)", "types-boto3-ecr (>=1.43.0,<1.44.0)", "types-boto3-ecr-public (>=1.43.0,<1.44.0)", "types-boto3-ecs (>=1.43.0,<1.44.0)", "types-boto3-efs (>=1.43.0,<1.44.0)", "types-boto3-eks (>=1.43.0,<1.44.0)", "types-boto3-eks-auth (>=1.43.0,<1.44.0)", "types-boto3-elasticache (>=1.43.0,<1.44.0)", "types-boto3-elasticbeanstalk (>=1.43.0,<1.44.0)", "types-boto3-elb (>=1.43.0,<1.44.0)", "types-boto3-elbv2 (>=1.43.0,<1.44.0)", "types-boto3-elementalinference (>=1.43.0,<1.44.0)", "types-boto3-emr (>=1.43.0,<1.44.0)", "types-boto3-emr-containers (>=1.43.0,<1.44.0)", "types-boto3-emr-serverless (>=1.43.0,<1.44.0)", "types-boto3-entityresolution (>=1.43.0,<1.44.0)", "types-boto3-es (>=1.43.0,<1.44.0)", "types-boto3-events (>=1.43.0,<1.44.0)", "types-boto3-evs (>=1.43.0,<1.44.0)", "types-boto3-finspace (>=1.43.0,<1.44.0)", "types-boto3-finspace-data (>=1.43.0,<1.44.0)", "types-boto3-firehose (>=1.43.0,<1.44.0)", "types-boto3-fis (>=1.43.0,<1.44.0)", "types-boto3-fms (>=1.43.0,<1.44.0)", "types-boto3-forecast (>=1.43.0,<1.44.0)", "types-boto3-forecastquery (>=1.43.0,<1.44.0)", "types-boto3-frauddetector (>=1.43.0,<1.44.0)", "types-boto3-freetier (>=1.43.0,<1.44.0)", "types-boto3-fsx (>=1.43.0,<1.44.0)", "types-boto3-gamelift (>=1.43.0,<1.44.0)", "types-boto3-gameliftstreams (>=1.43.0,<1.44.0)", "types-boto3-geo-maps (>=1.43.0,<1.44.0)", "types-boto3-geo-places (>=1.43.0,<1.44.0)", "types-boto3-geo-routes (>=1.43.0,<1.44.0)", "types-boto3-glacier (>=1.43.0,<1.44.0)", "types-boto3-globalaccelerator (>=1.43.0,<1.44.0)", "types-boto3-glue (>=1.43.0,<1.44.0)", "types-boto3-grafana (>=1.43.0,<1.44.0)", "types-boto3-greengrass (>=1.43.0,<1.44.0)", "types-boto3-greengrassv2 (>=1.43.0,<1.44.0)", "types-boto3-groundstation (>=1.43.0,<1.44.0)", "types-boto3-guardduty (>=1.43.0,<1.44.0)", "types-boto3-health (>=1.43.0,<1.44.0)", "types-boto3-healthlake (>=1.43.0,<1.44.0)", "types-boto3-iam (>=1.43.0,<1.44.0)", "types-boto3-identitystore (>=1.43.0,<1.44.0)", "types-boto3-imagebuilder (>=1.43.0,<1.44.0)", "types-boto3-importexport (>=1.43.0,<1.44.0)", "types-boto3-inspector (>=1.43.0,<1.44.0)", "types-boto3-inspector-scan (>=1.43.0,<1.44.0)", "types-boto3-inspector2 (>=1.43.0,<1.44.0)", "types-boto3-interconnect (>=1.43.0,<1.44.0)", "types-boto3-internetmonitor (>=1.43.0,<1.44.0)", "types-boto3-invoicing (>=1.43.0,<1.44.0)", "types-boto3-iot (>=1.43.0,<1.44.0)", "types-boto3-iot-data (>=1.43.0,<1.44.0)", "types-boto3-iot-jobs-data (>=1.43.0,<1.44.0)", "types-boto3-iot-managed-integrations (>=1.43.0,<1.44.0)", "types-boto3-iotdeviceadvisor (>=1.43.0,<1.44.0)", "types-boto3-iotevents (>=1.43.0,<1.44.0)", "types-boto3-iotevents-data (>=1.43.0,<1.44.0)", "types-boto3-iotfleetwise (>=1.43.0,<1.44.0)", "types-boto3-iotsecuretunneling (>=1.43.0,<1.44.0)", "types-boto3-iotsitewise (>=1.43.0,<1.44.0)", "types-boto3-iotthingsgraph (>=1.43.0,<1.44.0)", "types-boto3-iottwinmaker (>=1.43.0,<1.44.0)", "types-boto3-iotwireless (>=1.43.0,<1.44.0)", "types-boto3-ivs (>=1.43.0,<1.44.0)", "types-boto3-ivs-realtime (>=1.43.0,<1.44.0)", "types-boto3-ivschat (>=1.43.0,<1.44.0)", "types-boto3-kafka (>=1.43.0,<1.44.0)", "types-boto3-kafkaconnect (>=1.43.0,<1.44.0)", "types-boto3-kendra (>=1.43.0,<1.44.0)", "types-boto3-kendra-ranking (>=1.43.0,<1.44.0)", "types-boto3-keyspaces (>=1.43.0,<1.44.0)", "types-boto3-keyspacesstreams (>=1.43.0,<1.44.0)", "types-boto3-kinesis (>=1.43.0,<1.44.0)", "types-boto3-kinesis-video-archived-media (>=1.43.0,<1.44.0)", "types-boto3-kinesis-video-media (>=1.43.0,<1.44.0)", "types-boto3-kinesis-video-signaling (>=1.43.0,<1.44.0)", "types-boto3-kinesis-video-webrtc-storage (>=1.43.0,<1.44.0)", "types-boto3-kinesisanalytics (>=1.43.0,<1.44.0)", "types-boto3-kinesisanalyticsv2 (>=1.43.0,<1.44.0)", "types-boto3-kinesisvideo (>=1.43.0,<1.44.0)", "types-boto3-kms (>=1.43.0,<1.44.0)", "types-boto3-lakeformation (>=1.43.0,<1.44.0)", "types-boto3-lambda (>=1.43.0,<1.44.0)", "types-boto3-launch-wizard (>=1.43.0,<1.44.0)", "types-boto3-lex-models (>=1.43.0,<1.44.0)", "types-boto3-lex-runtime (>=1.43.0,<1.44.0)", "types-boto3-lexv2-models (>=1.43.0,<1.44.0)", "types-boto3-lexv2-runtime (>=1.43.0,<1.44.0)", "types-boto3-license-manager (>=1.43.0,<1.44.0)", "types-boto3-license-manager-linux-subscriptions (>=1.43.0,<1.44.0)", "types-boto3-license-manager-user-subscriptions (>=1.43.0,<1.44.0)", "types-boto3-lightsail (>=1.43.0,<1.44.0)", "types-boto3-location (>=1.43.0,<1.44.0)", "types-boto3-logs (>=1.43.0,<1.44.0)", "types-boto3-lookoutequipment (>=1.43.0,<1.44.0)", "types-boto3-m2 (>=1.43.0,<1.44.0)", "types-boto3-machinelearning (>=1.43.0,<1.44.0)", "types-boto3-macie2 (>=1.43.0,<1.44.0)", "types-boto3-mailmanager (>=1.43.0,<1.44.0)", "types-boto3-managedblockchain (>=1.43.0,<1.44.0)", "types-boto3-managedblockchain-query (>=1.43.0,<1.44.0)", "types-boto3-marketplace-agreement (>=1.43.0,<1.44.0)", "types-boto3-marketplace-catalog (>=1.43.0,<1.44.0)", "types-boto3-marketplace-deployment (>=1.43.0,<1.44.0)", "types-boto3-marketplace-discovery (>=1.43.0,<1.44.0)", "types-boto3-marketplace-entitlement (>=1.43.0,<1.44.0)", "types-boto3-marketplace-reporting (>=1.43.0,<1.44.0)", "types-boto3-marketplacecommerceanalytics (>=1.43.0,<1.44.0)", "types-boto3-mediaconnect (>=1.43.0,<1.44.0)", "types-boto3-mediaconvert (>=1.43.0,<1.44.0)", "types-boto3-medialive (>=1.43.0,<1.44.0)", "types-boto3-mediapackage (>=1.43.0,<1.44.0)", "types-boto3-mediapackage-vod (>=1.43.0,<1.44.0)", "types-boto3-mediapackagev2 (>=1.43.0,<1.44.0)", "types-boto3-mediastore (>=1.43.0,<1.44.0)", "types-boto3-mediastore-data (>=1.43.0,<1.44.0)", "types-boto3-mediatailor (>=1.43.0,<1.44.0)", "types-boto3-medical-imaging (>=1.43.0,<1.44.0)", "types-boto3-memorydb (>=1.43.0,<1.44.0)", "types-boto3-meteringmarketplace (>=1.43.0,<1.44.0)", "types-boto3-mgh (>=1.43.0,<1.44.0)", "types-boto3-mgn (>=1.43.0,<1.44.0)", "types-boto3-migration-hub-refactor-spaces (>=1.43.0,<1.44.0)", "types-boto3-migrationhub-config (>=1.43.0,<1.44.0)", "types-boto3-migrationhuborchestrator (>=1.43.0,<1.44.0)", "types-boto3-migrationhubstrategy (>=1.43.0,<1.44.0)", "types-boto3-mpa (>=1.43.0,<1.44.0)", "types-boto3-mq (>=1.43.0,<1.44.0)", "types-boto3-mturk (>=1.43.0,<1.44.0)", "types-boto3-mwaa (>=1.43.0,<1.44.0)", "types-boto3-mwaa-serverless (>=1.43.0,<1.44.0)", "types-boto3-neptune (>=1.43.0,<1.44.0)", "types-boto3-neptune-graph (>=1.43.0,<1.44.0)", "types-boto3-neptunedata (>=1.43.0,<1.44.0)", "types-boto3-network-firewall (>=1.43.0,<1.44.0)", "types-boto3-networkflowmonitor (>=1.43.0,<1.44.0)", "types-boto3-networkmanager (>=1.43.0,<1.44.0)", "types-boto3-networkmonitor (>=1.43.0,<1.44.0)", "types-boto3-notifications (>=1.43.0,<1.44.0)", "types-boto3-notificationscontacts (>=1.43.0,<1.44.0)", "types-boto3-nova-act (>=1.43.0,<1.44.0)", "types-boto3-oam (>=1.43.0,<1.44.0)", "types-boto3-observabilityadmin (>=1.43.0,<1.44.0)", "types-boto3-odb (>=1.43.0,<1.44.0)", "types-boto3-omics (>=1.43.0,<1.44.0)", "types-boto3-opensearch (>=1.43.0,<1.44.0)", "types-boto3-opensearchserverless (>=1.43.0,<1.44.0)", "types-boto3-organizations (>=1.43.0,<1.44.0)", "types-boto3-osis (>=1.43.0,<1.44.0)", "types-boto3-outposts (>=1.43.0,<1.44.0)", "types-boto3-panorama (>=1.43.0,<1.44.0)", "types-boto3-partnercentral-account (>=1.43.0,<1.44.0)", "types-boto3-partnercentral-benefits (>=1.43.0,<1.44.0)", "types-boto3-partnercentral-channel (>=1.43.0,<1.44.0)", "types-boto3-partnercentral-selling (>=1.43.0,<1.44.0)", "types-boto3-payment-cryptography (>=1.43.0,<1.44.0)", "types-boto3-payment-cryptography-data (>=1.43.0,<1.44.0)", "types-boto3-pca-connector-ad (>=1.43.0,<1.44.0)", "types-boto3-pca-connector-scep (>=1.43.0,<1.44.0)", "types-boto3-pcs (>=1.43.0,<1.44.0)", "types-boto3-personalize (>=1.43.0,<1.44.0)", "types-boto3-personalize-events (>=1.43.0,<1.44.0)", "types-boto3-personalize-runtime (>=1.43.0,<1.44.0)", "types-boto3-pi (>=1.43.0,<1.44.0)", "types-boto3-pinpoint (>=1.43.0,<1.44.0)", "types-boto3-pinpoint-email (>=1.43.0,<1.44.0)", "types-boto3-pinpoint-sms-voice (>=1.43.0,<1.44.0)", "types-boto3-pinpoint-sms-voice-v2 (>=1.43.0,<1.44.0)", "types-boto3-pipes (>=1.43.0,<1.44.0)", "types-boto3-polly (>=1.43.0,<1.44.0)", "types-boto3-pricing (>=1.43.0,<1.44.0)", "types-boto3-proton (>=1.43.0,<1.44.0)", "types-boto3-qapps (>=1.43.0,<1.44.0)", "types-boto3-qbusiness (>=1.43.0,<1.44.0)", "types-boto3-qconnect (>=1.43.0,<1.44.0)", "types-boto3-quicksight (>=1.43.0,<1.44.0)", "types-boto3-ram (>=1.43.0,<1.44.0)", "types-boto3-rbin (>=1.43.0,<1.44.0)", "types-boto3-rds (>=1.43.0,<1.44.0)", "types-boto3-rds-data (>=1.43.0,<1.44.0)", "types-boto3-redshift (>=1.43.0,<1.44.0)", "types-boto3-redshift-data (>=1.43.0,<1.44.0)", "types-boto3-redshift-serverless (>=1.43.0,<1.44.0)", "types-boto3-rekognition (>=1.43.0,<1.44.0)", "types-boto3-repostspace (>=1.43.0,<1.44.0)", "types-boto3-resiliencehub (>=1.43.0,<1.44.0)", "types-boto3-resiliencehubv2 (>=1.43.0,<1.44.0)", "types-boto3-resource-explorer-2 (>=1.43.0,<1.44.0)", "types-boto3-resource-groups (>=1.43.0,<1.44.0)", "types-boto3-resourcegroupstaggingapi (>=1.43.0,<1.44.0)", "types-boto3-rolesanywhere (>=1.43.0,<1.44.0)", "types-boto3-route53 (>=1.43.0,<1.44.0)", "types-boto3-route53-recovery-cluster (>=1.43.0,<1.44.0)", "types-boto3-route53-recovery-control-config (>=1.43.0,<1.44.0)", "types-boto3-route53-recovery-readiness (>=1.43.0,<1.44.0)", "types-boto3-route53domains (>=1.43.0,<1.44.0)", "types-boto3-route53globalresolver (>=1.43.0,<1.44.0)", "types-boto3-route53profiles (>=1.43.0,<1.44.0)", "types-boto3-route53resolver (>=1.43.0,<1.44.0)", "types-boto3-rtbfabric (>=1.43.0,<1.44.0)", "types-boto3-rum (>=1.43.0,<1.44.0)", "types-boto3-s3 (>=1.43.0,<1.44.0)", "types-boto3-s3control (>=1.43.0,<1.44.0)", "types-boto3-s3files (>=1.43.0,<1.44.0)", "types-boto3-s3outposts (>=1.43.0,<1.44.0)", "types-boto3-s3tables (>=1.43.0,<1.44.0)", "types-boto3-s3vectors (>=1.43.0,<1.44.0)", "types-boto3-sagemaker (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-a2i-runtime (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-edge (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-featurestore-runtime (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-geospatial (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-metrics (>=1.43.0,<1.44.0)", "types-boto3-sagemaker-runtime (>=1.43.0,<1.44.0)", "types-boto3-sagemakerjobruntime (>=1.43.0,<1.44.0)", "types-boto3-savingsplans (>=1.43.0,<1.44.0)", "types-boto3-scheduler (>=1.43.0,<1.44.0)", "types-boto3-schemas (>=1.43.0,<1.44.0)", "types-boto3-sdb (>=1.43.0,<1.44.0)", "types-boto3-secretsmanager (>=1.43.0,<1.44.0)", "types-boto3-security-ir (>=1.43.0,<1.44.0)", "types-boto3-securityagent (>=1.43.0,<1.44.0)", "types-boto3-securityhub (>=1.43.0,<1.44.0)", "types-boto3-securitylake (>=1.43.0,<1.44.0)", "types-boto3-serverlessrepo (>=1.43.0,<1.44.0)", "types-boto3-service-quotas (>=1.43.0,<1.44.0)", "types-boto3-servicecatalog (>=1.43.0,<1.44.0)", "types-boto3-servicecatalog-appregistry (>=1.43.0,<1.44.0)", "types-boto3-servicediscovery (>=1.43.0,<1.44.0)", "types-boto3-ses (>=1.43.0,<1.44.0)", "types-boto3-sesv2 (>=1.43.0,<1.44.0)", "types-boto3-shield (>=1.43.0,<1.44.0)", "types-boto3-signer (>=1.43.0,<1.44.0)", "types-boto3-signer-data (>=1.43.0,<1.44.0)", "types-boto3-signin (>=1.43.0,<1.44.0)", "types-boto3-simpledbv2 (>=1.43.0,<1.44.0)", "types-boto3-simspaceweaver (>=1.43.0,<1.44.0)", "types-boto3-snow-device-management (>=1.43.0,<1.44.0)", "types-boto3-snowball (>=1.43.0,<1.44.0)", "types-boto3-sns (>=1.43.0,<1.44.0)", "types-boto3-socialmessaging (>=1.43.0,<1.44.0)", "types-boto3-sqs (>=1.43.0,<1.44.0)", "types-boto3-ssm (>=1.43.0,<1.44.0)", "types-boto3-ssm-contacts (>=1.43.0,<1.44.0)", "types-boto3-ssm-guiconnect (>=1.43.0,<1.44.0)", "types-boto3-ssm-incidents (>=1.43.0,<1.44.0)", "types-boto3-ssm-quicksetup (>=1.43.0,<1.44.0)", "types-boto3-ssm-sap (>=1.43.0,<1.44.0)", "types-boto3-sso (>=1.43.0,<1.44.0)", "types-boto3-sso-admin (>=1.43.0,<1.44.0)", "types-boto3-sso-oidc (>=1.43.0,<1.44.0)", "types-boto3-stepfunctions (>=1.43.0,<1.44.0)", "types-boto3-storagegateway (>=1.43.0,<1.44.0)", "types-boto3-sts (>=1.43.0,<1.44.0)", "types-boto3-supplychain (>=1.43.0,<1.44.0)", "types-boto3-support (>=1.43.0,<1.44.0)", "types-boto3-support-app (>=1.43.0,<1.44.0)", "types-boto3-sustainability (>=1.43.0,<1.44.0)", "types-boto3-swf (>=1.43.0,<1.44.0)", "types-boto3-synthetics (>=1.43.0,<1.44.0)", "types-boto3-taxsettings (>=1.43.0,<1.44.0)", "types-boto3-textract (>=1.43.0,<1.44.0)", "types-boto3-timestream-influxdb (>=1.43.0,<1.44.0)", "types-boto3-timestream-query (>=1.43.0,<1.44.0)", "types-boto3-timestream-write (>=1.43.0,<1.44.0)", "types-boto3-tnb (>=1.43.0,<1.44.0)", "types-boto3-transcribe (>=1.43.0,<1.44.0)", "types-boto3-transfer (>=1.43.0,<1.44.0)", "types-boto3-translate (>=1.43.0,<1.44.0)", "types-boto3-trustedadvisor (>=1.43.0,<1.44.0)", "types-boto3-uxc (>=1.43.0,<1.44.0)", "types-boto3-verifiedpermissions (>=1.43.0,<1.44.0)", "types-boto3-voice-id (>=1.43.0,<1.44.0)", "types-boto3-vpc-lattice (>=1.43.0,<1.44.0)", "types-boto3-waf (>=1.43.0,<1.44.0)", "types-boto3-waf-regional (>=1.43.0,<1.44.0)", "types-boto3-wafv2 (>=1.43.0,<1.44.0)", "types-boto3-wellarchitected (>=1.43.0,<1.44.0)", "types-boto3-wickr (>=1.43.0,<1.44.0)", "types-boto3-wisdom (>=1.43.0,<1.44.0)", "types-boto3-workdocs (>=1.43.0,<1.44.0)", "types-boto3-workmail (>=1.43.0,<1.44.0)", "types-boto3-workmailmessageflow (>=1.43.0,<1.44.0)", "types-boto3-workspaces (>=1.43.0,<1.44.0)", "types-boto3-workspaces-instances (>=1.43.0,<1.44.0)", "types-boto3-workspaces-thin-client (>=1.43.0,<1.44.0)", "types-boto3-workspaces-web (>=1.43.0,<1.44.0)", "types-boto3-xray (>=1.43.0,<1.44.0)"] +amp = ["types-boto3-amp (>=1.43.0,<1.44.0)"] +amplify = ["types-boto3-amplify (>=1.43.0,<1.44.0)"] +amplifybackend = ["types-boto3-amplifybackend (>=1.43.0,<1.44.0)"] +amplifyuibuilder = ["types-boto3-amplifyuibuilder (>=1.43.0,<1.44.0)"] +apigateway = ["types-boto3-apigateway (>=1.43.0,<1.44.0)"] +apigatewaymanagementapi = ["types-boto3-apigatewaymanagementapi (>=1.43.0,<1.44.0)"] +apigatewayv2 = ["types-boto3-apigatewayv2 (>=1.43.0,<1.44.0)"] +appconfig = ["types-boto3-appconfig (>=1.43.0,<1.44.0)"] +appconfigdata = ["types-boto3-appconfigdata (>=1.43.0,<1.44.0)"] +appfabric = ["types-boto3-appfabric (>=1.43.0,<1.44.0)"] +appflow = ["types-boto3-appflow (>=1.43.0,<1.44.0)"] +appintegrations = ["types-boto3-appintegrations (>=1.43.0,<1.44.0)"] +application-autoscaling = ["types-boto3-application-autoscaling (>=1.43.0,<1.44.0)"] +application-insights = ["types-boto3-application-insights (>=1.43.0,<1.44.0)"] +application-signals = ["types-boto3-application-signals (>=1.43.0,<1.44.0)"] +applicationcostprofiler = ["types-boto3-applicationcostprofiler (>=1.43.0,<1.44.0)"] +appmesh = ["types-boto3-appmesh (>=1.43.0,<1.44.0)"] +apprunner = ["types-boto3-apprunner (>=1.43.0,<1.44.0)"] +appstream = ["types-boto3-appstream (>=1.43.0,<1.44.0)"] +appsync = ["types-boto3-appsync (>=1.43.0,<1.44.0)"] +arc-region-switch = ["types-boto3-arc-region-switch (>=1.43.0,<1.44.0)"] +arc-zonal-shift = ["types-boto3-arc-zonal-shift (>=1.43.0,<1.44.0)"] +artifact = ["types-boto3-artifact (>=1.43.0,<1.44.0)"] +athena = ["types-boto3-athena (>=1.43.0,<1.44.0)"] +auditmanager = ["types-boto3-auditmanager (>=1.43.0,<1.44.0)"] +autoscaling = ["types-boto3-autoscaling (>=1.43.0,<1.44.0)"] +autoscaling-plans = ["types-boto3-autoscaling-plans (>=1.43.0,<1.44.0)"] +b2bi = ["types-boto3-b2bi (>=1.43.0,<1.44.0)"] +backup = ["types-boto3-backup (>=1.43.0,<1.44.0)"] +backup-gateway = ["types-boto3-backup-gateway (>=1.43.0,<1.44.0)"] +backupsearch = ["types-boto3-backupsearch (>=1.43.0,<1.44.0)"] +batch = ["types-boto3-batch (>=1.43.0,<1.44.0)"] +bcm-dashboards = ["types-boto3-bcm-dashboards (>=1.43.0,<1.44.0)"] +bcm-data-exports = ["types-boto3-bcm-data-exports (>=1.43.0,<1.44.0)"] +bcm-pricing-calculator = ["types-boto3-bcm-pricing-calculator (>=1.43.0,<1.44.0)"] +bcm-recommended-actions = ["types-boto3-bcm-recommended-actions (>=1.43.0,<1.44.0)"] +bedrock = ["types-boto3-bedrock (>=1.43.0,<1.44.0)"] +bedrock-agent = ["types-boto3-bedrock-agent (>=1.43.0,<1.44.0)"] +bedrock-agent-runtime = ["types-boto3-bedrock-agent-runtime (>=1.43.0,<1.44.0)"] +bedrock-agentcore = ["types-boto3-bedrock-agentcore (>=1.43.0,<1.44.0)"] +bedrock-agentcore-control = ["types-boto3-bedrock-agentcore-control (>=1.43.0,<1.44.0)"] +bedrock-data-automation = ["types-boto3-bedrock-data-automation (>=1.43.0,<1.44.0)"] +bedrock-data-automation-runtime = ["types-boto3-bedrock-data-automation-runtime (>=1.43.0,<1.44.0)"] +bedrock-runtime = ["types-boto3-bedrock-runtime (>=1.43.0,<1.44.0)"] +billing = ["types-boto3-billing (>=1.43.0,<1.44.0)"] +billingconductor = ["types-boto3-billingconductor (>=1.43.0,<1.44.0)"] +boto3 = ["boto3 (==1.43.32)"] +braket = ["types-boto3-braket (>=1.43.0,<1.44.0)"] +budgets = ["types-boto3-budgets (>=1.43.0,<1.44.0)"] +ce = ["types-boto3-ce (>=1.43.0,<1.44.0)"] +chatbot = ["types-boto3-chatbot (>=1.43.0,<1.44.0)"] +chime = ["types-boto3-chime (>=1.43.0,<1.44.0)"] +chime-sdk-identity = ["types-boto3-chime-sdk-identity (>=1.43.0,<1.44.0)"] +chime-sdk-media-pipelines = ["types-boto3-chime-sdk-media-pipelines (>=1.43.0,<1.44.0)"] +chime-sdk-meetings = ["types-boto3-chime-sdk-meetings (>=1.43.0,<1.44.0)"] +chime-sdk-messaging = ["types-boto3-chime-sdk-messaging (>=1.43.0,<1.44.0)"] +chime-sdk-voice = ["types-boto3-chime-sdk-voice (>=1.43.0,<1.44.0)"] +cleanrooms = ["types-boto3-cleanrooms (>=1.43.0,<1.44.0)"] +cleanroomsml = ["types-boto3-cleanroomsml (>=1.43.0,<1.44.0)"] +cloud9 = ["types-boto3-cloud9 (>=1.43.0,<1.44.0)"] +cloudcontrol = ["types-boto3-cloudcontrol (>=1.43.0,<1.44.0)"] +clouddirectory = ["types-boto3-clouddirectory (>=1.43.0,<1.44.0)"] +cloudformation = ["types-boto3-cloudformation (>=1.43.0,<1.44.0)"] +cloudfront = ["types-boto3-cloudfront (>=1.43.0,<1.44.0)"] +cloudfront-keyvaluestore = ["types-boto3-cloudfront-keyvaluestore (>=1.43.0,<1.44.0)"] +cloudhsm = ["types-boto3-cloudhsm (>=1.43.0,<1.44.0)"] +cloudhsmv2 = ["types-boto3-cloudhsmv2 (>=1.43.0,<1.44.0)"] +cloudsearch = ["types-boto3-cloudsearch (>=1.43.0,<1.44.0)"] +cloudsearchdomain = ["types-boto3-cloudsearchdomain (>=1.43.0,<1.44.0)"] +cloudtrail = ["types-boto3-cloudtrail (>=1.43.0,<1.44.0)"] +cloudtrail-data = ["types-boto3-cloudtrail-data (>=1.43.0,<1.44.0)"] +cloudwatch = ["types-boto3-cloudwatch (>=1.43.0,<1.44.0)"] +codeartifact = ["types-boto3-codeartifact (>=1.43.0,<1.44.0)"] +codebuild = ["types-boto3-codebuild (>=1.43.0,<1.44.0)"] +codecatalyst = ["types-boto3-codecatalyst (>=1.43.0,<1.44.0)"] +codecommit = ["types-boto3-codecommit (>=1.43.0,<1.44.0)"] +codeconnections = ["types-boto3-codeconnections (>=1.43.0,<1.44.0)"] +codedeploy = ["types-boto3-codedeploy (>=1.43.0,<1.44.0)"] +codeguru-reviewer = ["types-boto3-codeguru-reviewer (>=1.43.0,<1.44.0)"] +codeguru-security = ["types-boto3-codeguru-security (>=1.43.0,<1.44.0)"] +codeguruprofiler = ["types-boto3-codeguruprofiler (>=1.43.0,<1.44.0)"] +codepipeline = ["types-boto3-codepipeline (>=1.43.0,<1.44.0)"] +codestar-connections = ["types-boto3-codestar-connections (>=1.43.0,<1.44.0)"] +codestar-notifications = ["types-boto3-codestar-notifications (>=1.43.0,<1.44.0)"] +cognito-identity = ["types-boto3-cognito-identity (>=1.43.0,<1.44.0)"] +cognito-idp = ["types-boto3-cognito-idp (>=1.43.0,<1.44.0)"] +cognito-sync = ["types-boto3-cognito-sync (>=1.43.0,<1.44.0)"] +comprehend = ["types-boto3-comprehend (>=1.43.0,<1.44.0)"] +comprehendmedical = ["types-boto3-comprehendmedical (>=1.43.0,<1.44.0)"] +compute-optimizer = ["types-boto3-compute-optimizer (>=1.43.0,<1.44.0)"] +compute-optimizer-automation = ["types-boto3-compute-optimizer-automation (>=1.43.0,<1.44.0)"] +config = ["types-boto3-config (>=1.43.0,<1.44.0)"] +connect = ["types-boto3-connect (>=1.43.0,<1.44.0)"] +connect-contact-lens = ["types-boto3-connect-contact-lens (>=1.43.0,<1.44.0)"] +connectcampaigns = ["types-boto3-connectcampaigns (>=1.43.0,<1.44.0)"] +connectcampaignsv2 = ["types-boto3-connectcampaignsv2 (>=1.43.0,<1.44.0)"] +connectcases = ["types-boto3-connectcases (>=1.43.0,<1.44.0)"] +connecthealth = ["types-boto3-connecthealth (>=1.43.0,<1.44.0)"] +connectparticipant = ["types-boto3-connectparticipant (>=1.43.0,<1.44.0)"] +controlcatalog = ["types-boto3-controlcatalog (>=1.43.0,<1.44.0)"] +controltower = ["types-boto3-controltower (>=1.43.0,<1.44.0)"] +cost-optimization-hub = ["types-boto3-cost-optimization-hub (>=1.43.0,<1.44.0)"] +cur = ["types-boto3-cur (>=1.43.0,<1.44.0)"] +customer-profiles = ["types-boto3-customer-profiles (>=1.43.0,<1.44.0)"] +databrew = ["types-boto3-databrew (>=1.43.0,<1.44.0)"] +dataexchange = ["types-boto3-dataexchange (>=1.43.0,<1.44.0)"] +datapipeline = ["types-boto3-datapipeline (>=1.43.0,<1.44.0)"] +datasync = ["types-boto3-datasync (>=1.43.0,<1.44.0)"] +datazone = ["types-boto3-datazone (>=1.43.0,<1.44.0)"] +dax = ["types-boto3-dax (>=1.43.0,<1.44.0)"] +deadline = ["types-boto3-deadline (>=1.43.0,<1.44.0)"] +detective = ["types-boto3-detective (>=1.43.0,<1.44.0)"] +devicefarm = ["types-boto3-devicefarm (>=1.43.0,<1.44.0)"] +devops-agent = ["types-boto3-devops-agent (>=1.43.0,<1.44.0)"] +devops-guru = ["types-boto3-devops-guru (>=1.43.0,<1.44.0)"] +directconnect = ["types-boto3-directconnect (>=1.43.0,<1.44.0)"] +discovery = ["types-boto3-discovery (>=1.43.0,<1.44.0)"] +dlm = ["types-boto3-dlm (>=1.43.0,<1.44.0)"] +dms = ["types-boto3-dms (>=1.43.0,<1.44.0)"] +docdb = ["types-boto3-docdb (>=1.43.0,<1.44.0)"] +docdb-elastic = ["types-boto3-docdb-elastic (>=1.43.0,<1.44.0)"] +drs = ["types-boto3-drs (>=1.43.0,<1.44.0)"] +ds = ["types-boto3-ds (>=1.43.0,<1.44.0)"] +ds-data = ["types-boto3-ds-data (>=1.43.0,<1.44.0)"] +dsql = ["types-boto3-dsql (>=1.43.0,<1.44.0)"] +dynamodb = ["types-boto3-dynamodb (>=1.43.0,<1.44.0)"] +dynamodbstreams = ["types-boto3-dynamodbstreams (>=1.43.0,<1.44.0)"] +ebs = ["types-boto3-ebs (>=1.43.0,<1.44.0)"] +ec2 = ["types-boto3-ec2 (>=1.43.0,<1.44.0)"] +ec2-instance-connect = ["types-boto3-ec2-instance-connect (>=1.43.0,<1.44.0)"] +ecr = ["types-boto3-ecr (>=1.43.0,<1.44.0)"] +ecr-public = ["types-boto3-ecr-public (>=1.43.0,<1.44.0)"] +ecs = ["types-boto3-ecs (>=1.43.0,<1.44.0)"] +efs = ["types-boto3-efs (>=1.43.0,<1.44.0)"] +eks = ["types-boto3-eks (>=1.43.0,<1.44.0)"] +eks-auth = ["types-boto3-eks-auth (>=1.43.0,<1.44.0)"] +elasticache = ["types-boto3-elasticache (>=1.43.0,<1.44.0)"] +elasticbeanstalk = ["types-boto3-elasticbeanstalk (>=1.43.0,<1.44.0)"] +elb = ["types-boto3-elb (>=1.43.0,<1.44.0)"] +elbv2 = ["types-boto3-elbv2 (>=1.43.0,<1.44.0)"] +elementalinference = ["types-boto3-elementalinference (>=1.43.0,<1.44.0)"] +emr = ["types-boto3-emr (>=1.43.0,<1.44.0)"] +emr-containers = ["types-boto3-emr-containers (>=1.43.0,<1.44.0)"] +emr-serverless = ["types-boto3-emr-serverless (>=1.43.0,<1.44.0)"] +entityresolution = ["types-boto3-entityresolution (>=1.43.0,<1.44.0)"] +es = ["types-boto3-es (>=1.43.0,<1.44.0)"] +essential = ["types-boto3-cloudformation (>=1.43.0,<1.44.0)", "types-boto3-dynamodb (>=1.43.0,<1.44.0)", "types-boto3-ec2 (>=1.43.0,<1.44.0)", "types-boto3-lambda (>=1.43.0,<1.44.0)", "types-boto3-rds (>=1.43.0,<1.44.0)", "types-boto3-s3 (>=1.43.0,<1.44.0)", "types-boto3-sqs (>=1.43.0,<1.44.0)"] +events = ["types-boto3-events (>=1.43.0,<1.44.0)"] +evs = ["types-boto3-evs (>=1.43.0,<1.44.0)"] +finspace = ["types-boto3-finspace (>=1.43.0,<1.44.0)"] +finspace-data = ["types-boto3-finspace-data (>=1.43.0,<1.44.0)"] +firehose = ["types-boto3-firehose (>=1.43.0,<1.44.0)"] +fis = ["types-boto3-fis (>=1.43.0,<1.44.0)"] +fms = ["types-boto3-fms (>=1.43.0,<1.44.0)"] +forecast = ["types-boto3-forecast (>=1.43.0,<1.44.0)"] +forecastquery = ["types-boto3-forecastquery (>=1.43.0,<1.44.0)"] +frauddetector = ["types-boto3-frauddetector (>=1.43.0,<1.44.0)"] +freetier = ["types-boto3-freetier (>=1.43.0,<1.44.0)"] +fsx = ["types-boto3-fsx (>=1.43.0,<1.44.0)"] +full = ["types-boto3-full (>=1.43.0,<1.44.0)"] +gamelift = ["types-boto3-gamelift (>=1.43.0,<1.44.0)"] +gameliftstreams = ["types-boto3-gameliftstreams (>=1.43.0,<1.44.0)"] +geo-maps = ["types-boto3-geo-maps (>=1.43.0,<1.44.0)"] +geo-places = ["types-boto3-geo-places (>=1.43.0,<1.44.0)"] +geo-routes = ["types-boto3-geo-routes (>=1.43.0,<1.44.0)"] +glacier = ["types-boto3-glacier (>=1.43.0,<1.44.0)"] +globalaccelerator = ["types-boto3-globalaccelerator (>=1.43.0,<1.44.0)"] +glue = ["types-boto3-glue (>=1.43.0,<1.44.0)"] +grafana = ["types-boto3-grafana (>=1.43.0,<1.44.0)"] +greengrass = ["types-boto3-greengrass (>=1.43.0,<1.44.0)"] +greengrassv2 = ["types-boto3-greengrassv2 (>=1.43.0,<1.44.0)"] +groundstation = ["types-boto3-groundstation (>=1.43.0,<1.44.0)"] +guardduty = ["types-boto3-guardduty (>=1.43.0,<1.44.0)"] +health = ["types-boto3-health (>=1.43.0,<1.44.0)"] +healthlake = ["types-boto3-healthlake (>=1.43.0,<1.44.0)"] +iam = ["types-boto3-iam (>=1.43.0,<1.44.0)"] +identitystore = ["types-boto3-identitystore (>=1.43.0,<1.44.0)"] +imagebuilder = ["types-boto3-imagebuilder (>=1.43.0,<1.44.0)"] +importexport = ["types-boto3-importexport (>=1.43.0,<1.44.0)"] +inspector = ["types-boto3-inspector (>=1.43.0,<1.44.0)"] +inspector-scan = ["types-boto3-inspector-scan (>=1.43.0,<1.44.0)"] +inspector2 = ["types-boto3-inspector2 (>=1.43.0,<1.44.0)"] +interconnect = ["types-boto3-interconnect (>=1.43.0,<1.44.0)"] +internetmonitor = ["types-boto3-internetmonitor (>=1.43.0,<1.44.0)"] +invoicing = ["types-boto3-invoicing (>=1.43.0,<1.44.0)"] +iot = ["types-boto3-iot (>=1.43.0,<1.44.0)"] +iot-data = ["types-boto3-iot-data (>=1.43.0,<1.44.0)"] +iot-jobs-data = ["types-boto3-iot-jobs-data (>=1.43.0,<1.44.0)"] +iot-managed-integrations = ["types-boto3-iot-managed-integrations (>=1.43.0,<1.44.0)"] +iotdeviceadvisor = ["types-boto3-iotdeviceadvisor (>=1.43.0,<1.44.0)"] +iotevents = ["types-boto3-iotevents (>=1.43.0,<1.44.0)"] +iotevents-data = ["types-boto3-iotevents-data (>=1.43.0,<1.44.0)"] +iotfleetwise = ["types-boto3-iotfleetwise (>=1.43.0,<1.44.0)"] +iotsecuretunneling = ["types-boto3-iotsecuretunneling (>=1.43.0,<1.44.0)"] +iotsitewise = ["types-boto3-iotsitewise (>=1.43.0,<1.44.0)"] +iotthingsgraph = ["types-boto3-iotthingsgraph (>=1.43.0,<1.44.0)"] +iottwinmaker = ["types-boto3-iottwinmaker (>=1.43.0,<1.44.0)"] +iotwireless = ["types-boto3-iotwireless (>=1.43.0,<1.44.0)"] +ivs = ["types-boto3-ivs (>=1.43.0,<1.44.0)"] +ivs-realtime = ["types-boto3-ivs-realtime (>=1.43.0,<1.44.0)"] +ivschat = ["types-boto3-ivschat (>=1.43.0,<1.44.0)"] +kafka = ["types-boto3-kafka (>=1.43.0,<1.44.0)"] +kafkaconnect = ["types-boto3-kafkaconnect (>=1.43.0,<1.44.0)"] +kendra = ["types-boto3-kendra (>=1.43.0,<1.44.0)"] +kendra-ranking = ["types-boto3-kendra-ranking (>=1.43.0,<1.44.0)"] +keyspaces = ["types-boto3-keyspaces (>=1.43.0,<1.44.0)"] +keyspacesstreams = ["types-boto3-keyspacesstreams (>=1.43.0,<1.44.0)"] +kinesis = ["types-boto3-kinesis (>=1.43.0,<1.44.0)"] +kinesis-video-archived-media = ["types-boto3-kinesis-video-archived-media (>=1.43.0,<1.44.0)"] +kinesis-video-media = ["types-boto3-kinesis-video-media (>=1.43.0,<1.44.0)"] +kinesis-video-signaling = ["types-boto3-kinesis-video-signaling (>=1.43.0,<1.44.0)"] +kinesis-video-webrtc-storage = ["types-boto3-kinesis-video-webrtc-storage (>=1.43.0,<1.44.0)"] +kinesisanalytics = ["types-boto3-kinesisanalytics (>=1.43.0,<1.44.0)"] +kinesisanalyticsv2 = ["types-boto3-kinesisanalyticsv2 (>=1.43.0,<1.44.0)"] +kinesisvideo = ["types-boto3-kinesisvideo (>=1.43.0,<1.44.0)"] +kms = ["types-boto3-kms (>=1.43.0,<1.44.0)"] +lakeformation = ["types-boto3-lakeformation (>=1.43.0,<1.44.0)"] +lambda = ["types-boto3-lambda (>=1.43.0,<1.44.0)"] +launch-wizard = ["types-boto3-launch-wizard (>=1.43.0,<1.44.0)"] +lex-models = ["types-boto3-lex-models (>=1.43.0,<1.44.0)"] +lex-runtime = ["types-boto3-lex-runtime (>=1.43.0,<1.44.0)"] +lexv2-models = ["types-boto3-lexv2-models (>=1.43.0,<1.44.0)"] +lexv2-runtime = ["types-boto3-lexv2-runtime (>=1.43.0,<1.44.0)"] +license-manager = ["types-boto3-license-manager (>=1.43.0,<1.44.0)"] +license-manager-linux-subscriptions = ["types-boto3-license-manager-linux-subscriptions (>=1.43.0,<1.44.0)"] +license-manager-user-subscriptions = ["types-boto3-license-manager-user-subscriptions (>=1.43.0,<1.44.0)"] +lightsail = ["types-boto3-lightsail (>=1.43.0,<1.44.0)"] +location = ["types-boto3-location (>=1.43.0,<1.44.0)"] +logs = ["types-boto3-logs (>=1.43.0,<1.44.0)"] +lookoutequipment = ["types-boto3-lookoutequipment (>=1.43.0,<1.44.0)"] +m2 = ["types-boto3-m2 (>=1.43.0,<1.44.0)"] +machinelearning = ["types-boto3-machinelearning (>=1.43.0,<1.44.0)"] +macie2 = ["types-boto3-macie2 (>=1.43.0,<1.44.0)"] +mailmanager = ["types-boto3-mailmanager (>=1.43.0,<1.44.0)"] +managedblockchain = ["types-boto3-managedblockchain (>=1.43.0,<1.44.0)"] +managedblockchain-query = ["types-boto3-managedblockchain-query (>=1.43.0,<1.44.0)"] +marketplace-agreement = ["types-boto3-marketplace-agreement (>=1.43.0,<1.44.0)"] +marketplace-catalog = ["types-boto3-marketplace-catalog (>=1.43.0,<1.44.0)"] +marketplace-deployment = ["types-boto3-marketplace-deployment (>=1.43.0,<1.44.0)"] +marketplace-discovery = ["types-boto3-marketplace-discovery (>=1.43.0,<1.44.0)"] +marketplace-entitlement = ["types-boto3-marketplace-entitlement (>=1.43.0,<1.44.0)"] +marketplace-reporting = ["types-boto3-marketplace-reporting (>=1.43.0,<1.44.0)"] +marketplacecommerceanalytics = ["types-boto3-marketplacecommerceanalytics (>=1.43.0,<1.44.0)"] +mediaconnect = ["types-boto3-mediaconnect (>=1.43.0,<1.44.0)"] +mediaconvert = ["types-boto3-mediaconvert (>=1.43.0,<1.44.0)"] +medialive = ["types-boto3-medialive (>=1.43.0,<1.44.0)"] +mediapackage = ["types-boto3-mediapackage (>=1.43.0,<1.44.0)"] +mediapackage-vod = ["types-boto3-mediapackage-vod (>=1.43.0,<1.44.0)"] +mediapackagev2 = ["types-boto3-mediapackagev2 (>=1.43.0,<1.44.0)"] +mediastore = ["types-boto3-mediastore (>=1.43.0,<1.44.0)"] +mediastore-data = ["types-boto3-mediastore-data (>=1.43.0,<1.44.0)"] +mediatailor = ["types-boto3-mediatailor (>=1.43.0,<1.44.0)"] +medical-imaging = ["types-boto3-medical-imaging (>=1.43.0,<1.44.0)"] +memorydb = ["types-boto3-memorydb (>=1.43.0,<1.44.0)"] +meteringmarketplace = ["types-boto3-meteringmarketplace (>=1.43.0,<1.44.0)"] +mgh = ["types-boto3-mgh (>=1.43.0,<1.44.0)"] +mgn = ["types-boto3-mgn (>=1.43.0,<1.44.0)"] +migration-hub-refactor-spaces = ["types-boto3-migration-hub-refactor-spaces (>=1.43.0,<1.44.0)"] +migrationhub-config = ["types-boto3-migrationhub-config (>=1.43.0,<1.44.0)"] +migrationhuborchestrator = ["types-boto3-migrationhuborchestrator (>=1.43.0,<1.44.0)"] +migrationhubstrategy = ["types-boto3-migrationhubstrategy (>=1.43.0,<1.44.0)"] +mpa = ["types-boto3-mpa (>=1.43.0,<1.44.0)"] +mq = ["types-boto3-mq (>=1.43.0,<1.44.0)"] +mturk = ["types-boto3-mturk (>=1.43.0,<1.44.0)"] +mwaa = ["types-boto3-mwaa (>=1.43.0,<1.44.0)"] +mwaa-serverless = ["types-boto3-mwaa-serverless (>=1.43.0,<1.44.0)"] +neptune = ["types-boto3-neptune (>=1.43.0,<1.44.0)"] +neptune-graph = ["types-boto3-neptune-graph (>=1.43.0,<1.44.0)"] +neptunedata = ["types-boto3-neptunedata (>=1.43.0,<1.44.0)"] +network-firewall = ["types-boto3-network-firewall (>=1.43.0,<1.44.0)"] +networkflowmonitor = ["types-boto3-networkflowmonitor (>=1.43.0,<1.44.0)"] +networkmanager = ["types-boto3-networkmanager (>=1.43.0,<1.44.0)"] +networkmonitor = ["types-boto3-networkmonitor (>=1.43.0,<1.44.0)"] +notifications = ["types-boto3-notifications (>=1.43.0,<1.44.0)"] +notificationscontacts = ["types-boto3-notificationscontacts (>=1.43.0,<1.44.0)"] +nova-act = ["types-boto3-nova-act (>=1.43.0,<1.44.0)"] +oam = ["types-boto3-oam (>=1.43.0,<1.44.0)"] +observabilityadmin = ["types-boto3-observabilityadmin (>=1.43.0,<1.44.0)"] +odb = ["types-boto3-odb (>=1.43.0,<1.44.0)"] +omics = ["types-boto3-omics (>=1.43.0,<1.44.0)"] +opensearch = ["types-boto3-opensearch (>=1.43.0,<1.44.0)"] +opensearchserverless = ["types-boto3-opensearchserverless (>=1.43.0,<1.44.0)"] +organizations = ["types-boto3-organizations (>=1.43.0,<1.44.0)"] +osis = ["types-boto3-osis (>=1.43.0,<1.44.0)"] +outposts = ["types-boto3-outposts (>=1.43.0,<1.44.0)"] +panorama = ["types-boto3-panorama (>=1.43.0,<1.44.0)"] +partnercentral-account = ["types-boto3-partnercentral-account (>=1.43.0,<1.44.0)"] +partnercentral-benefits = ["types-boto3-partnercentral-benefits (>=1.43.0,<1.44.0)"] +partnercentral-channel = ["types-boto3-partnercentral-channel (>=1.43.0,<1.44.0)"] +partnercentral-selling = ["types-boto3-partnercentral-selling (>=1.43.0,<1.44.0)"] +payment-cryptography = ["types-boto3-payment-cryptography (>=1.43.0,<1.44.0)"] +payment-cryptography-data = ["types-boto3-payment-cryptography-data (>=1.43.0,<1.44.0)"] +pca-connector-ad = ["types-boto3-pca-connector-ad (>=1.43.0,<1.44.0)"] +pca-connector-scep = ["types-boto3-pca-connector-scep (>=1.43.0,<1.44.0)"] +pcs = ["types-boto3-pcs (>=1.43.0,<1.44.0)"] +personalize = ["types-boto3-personalize (>=1.43.0,<1.44.0)"] +personalize-events = ["types-boto3-personalize-events (>=1.43.0,<1.44.0)"] +personalize-runtime = ["types-boto3-personalize-runtime (>=1.43.0,<1.44.0)"] +pi = ["types-boto3-pi (>=1.43.0,<1.44.0)"] +pinpoint = ["types-boto3-pinpoint (>=1.43.0,<1.44.0)"] +pinpoint-email = ["types-boto3-pinpoint-email (>=1.43.0,<1.44.0)"] +pinpoint-sms-voice = ["types-boto3-pinpoint-sms-voice (>=1.43.0,<1.44.0)"] +pinpoint-sms-voice-v2 = ["types-boto3-pinpoint-sms-voice-v2 (>=1.43.0,<1.44.0)"] +pipes = ["types-boto3-pipes (>=1.43.0,<1.44.0)"] +polly = ["types-boto3-polly (>=1.43.0,<1.44.0)"] +pricing = ["types-boto3-pricing (>=1.43.0,<1.44.0)"] +proton = ["types-boto3-proton (>=1.43.0,<1.44.0)"] +qapps = ["types-boto3-qapps (>=1.43.0,<1.44.0)"] +qbusiness = ["types-boto3-qbusiness (>=1.43.0,<1.44.0)"] +qconnect = ["types-boto3-qconnect (>=1.43.0,<1.44.0)"] +quicksight = ["types-boto3-quicksight (>=1.43.0,<1.44.0)"] +ram = ["types-boto3-ram (>=1.43.0,<1.44.0)"] +rbin = ["types-boto3-rbin (>=1.43.0,<1.44.0)"] +rds = ["types-boto3-rds (>=1.43.0,<1.44.0)"] +rds-data = ["types-boto3-rds-data (>=1.43.0,<1.44.0)"] +redshift = ["types-boto3-redshift (>=1.43.0,<1.44.0)"] +redshift-data = ["types-boto3-redshift-data (>=1.43.0,<1.44.0)"] +redshift-serverless = ["types-boto3-redshift-serverless (>=1.43.0,<1.44.0)"] +rekognition = ["types-boto3-rekognition (>=1.43.0,<1.44.0)"] +repostspace = ["types-boto3-repostspace (>=1.43.0,<1.44.0)"] +resiliencehub = ["types-boto3-resiliencehub (>=1.43.0,<1.44.0)"] +resiliencehubv2 = ["types-boto3-resiliencehubv2 (>=1.43.0,<1.44.0)"] +resource-explorer-2 = ["types-boto3-resource-explorer-2 (>=1.43.0,<1.44.0)"] +resource-groups = ["types-boto3-resource-groups (>=1.43.0,<1.44.0)"] +resourcegroupstaggingapi = ["types-boto3-resourcegroupstaggingapi (>=1.43.0,<1.44.0)"] +rolesanywhere = ["types-boto3-rolesanywhere (>=1.43.0,<1.44.0)"] +route53 = ["types-boto3-route53 (>=1.43.0,<1.44.0)"] +route53-recovery-cluster = ["types-boto3-route53-recovery-cluster (>=1.43.0,<1.44.0)"] +route53-recovery-control-config = ["types-boto3-route53-recovery-control-config (>=1.43.0,<1.44.0)"] +route53-recovery-readiness = ["types-boto3-route53-recovery-readiness (>=1.43.0,<1.44.0)"] +route53domains = ["types-boto3-route53domains (>=1.43.0,<1.44.0)"] +route53globalresolver = ["types-boto3-route53globalresolver (>=1.43.0,<1.44.0)"] +route53profiles = ["types-boto3-route53profiles (>=1.43.0,<1.44.0)"] +route53resolver = ["types-boto3-route53resolver (>=1.43.0,<1.44.0)"] +rtbfabric = ["types-boto3-rtbfabric (>=1.43.0,<1.44.0)"] +rum = ["types-boto3-rum (>=1.43.0,<1.44.0)"] +s3 = ["types-boto3-s3 (>=1.43.0,<1.44.0)"] +s3control = ["types-boto3-s3control (>=1.43.0,<1.44.0)"] +s3files = ["types-boto3-s3files (>=1.43.0,<1.44.0)"] +s3outposts = ["types-boto3-s3outposts (>=1.43.0,<1.44.0)"] +s3tables = ["types-boto3-s3tables (>=1.43.0,<1.44.0)"] +s3vectors = ["types-boto3-s3vectors (>=1.43.0,<1.44.0)"] +sagemaker = ["types-boto3-sagemaker (>=1.43.0,<1.44.0)"] +sagemaker-a2i-runtime = ["types-boto3-sagemaker-a2i-runtime (>=1.43.0,<1.44.0)"] +sagemaker-edge = ["types-boto3-sagemaker-edge (>=1.43.0,<1.44.0)"] +sagemaker-featurestore-runtime = ["types-boto3-sagemaker-featurestore-runtime (>=1.43.0,<1.44.0)"] +sagemaker-geospatial = ["types-boto3-sagemaker-geospatial (>=1.43.0,<1.44.0)"] +sagemaker-metrics = ["types-boto3-sagemaker-metrics (>=1.43.0,<1.44.0)"] +sagemaker-runtime = ["types-boto3-sagemaker-runtime (>=1.43.0,<1.44.0)"] +sagemakerjobruntime = ["types-boto3-sagemakerjobruntime (>=1.43.0,<1.44.0)"] +savingsplans = ["types-boto3-savingsplans (>=1.43.0,<1.44.0)"] +scheduler = ["types-boto3-scheduler (>=1.43.0,<1.44.0)"] +schemas = ["types-boto3-schemas (>=1.43.0,<1.44.0)"] +sdb = ["types-boto3-sdb (>=1.43.0,<1.44.0)"] +secretsmanager = ["types-boto3-secretsmanager (>=1.43.0,<1.44.0)"] +security-ir = ["types-boto3-security-ir (>=1.43.0,<1.44.0)"] +securityagent = ["types-boto3-securityagent (>=1.43.0,<1.44.0)"] +securityhub = ["types-boto3-securityhub (>=1.43.0,<1.44.0)"] +securitylake = ["types-boto3-securitylake (>=1.43.0,<1.44.0)"] +serverlessrepo = ["types-boto3-serverlessrepo (>=1.43.0,<1.44.0)"] +service-quotas = ["types-boto3-service-quotas (>=1.43.0,<1.44.0)"] +servicecatalog = ["types-boto3-servicecatalog (>=1.43.0,<1.44.0)"] +servicecatalog-appregistry = ["types-boto3-servicecatalog-appregistry (>=1.43.0,<1.44.0)"] +servicediscovery = ["types-boto3-servicediscovery (>=1.43.0,<1.44.0)"] +ses = ["types-boto3-ses (>=1.43.0,<1.44.0)"] +sesv2 = ["types-boto3-sesv2 (>=1.43.0,<1.44.0)"] +shield = ["types-boto3-shield (>=1.43.0,<1.44.0)"] +signer = ["types-boto3-signer (>=1.43.0,<1.44.0)"] +signer-data = ["types-boto3-signer-data (>=1.43.0,<1.44.0)"] +signin = ["types-boto3-signin (>=1.43.0,<1.44.0)"] +simpledbv2 = ["types-boto3-simpledbv2 (>=1.43.0,<1.44.0)"] +simspaceweaver = ["types-boto3-simspaceweaver (>=1.43.0,<1.44.0)"] +snow-device-management = ["types-boto3-snow-device-management (>=1.43.0,<1.44.0)"] +snowball = ["types-boto3-snowball (>=1.43.0,<1.44.0)"] +sns = ["types-boto3-sns (>=1.43.0,<1.44.0)"] +socialmessaging = ["types-boto3-socialmessaging (>=1.43.0,<1.44.0)"] +sqs = ["types-boto3-sqs (>=1.43.0,<1.44.0)"] +ssm = ["types-boto3-ssm (>=1.43.0,<1.44.0)"] +ssm-contacts = ["types-boto3-ssm-contacts (>=1.43.0,<1.44.0)"] +ssm-guiconnect = ["types-boto3-ssm-guiconnect (>=1.43.0,<1.44.0)"] +ssm-incidents = ["types-boto3-ssm-incidents (>=1.43.0,<1.44.0)"] +ssm-quicksetup = ["types-boto3-ssm-quicksetup (>=1.43.0,<1.44.0)"] +ssm-sap = ["types-boto3-ssm-sap (>=1.43.0,<1.44.0)"] +sso = ["types-boto3-sso (>=1.43.0,<1.44.0)"] +sso-admin = ["types-boto3-sso-admin (>=1.43.0,<1.44.0)"] +sso-oidc = ["types-boto3-sso-oidc (>=1.43.0,<1.44.0)"] +stepfunctions = ["types-boto3-stepfunctions (>=1.43.0,<1.44.0)"] +storagegateway = ["types-boto3-storagegateway (>=1.43.0,<1.44.0)"] +sts = ["types-boto3-sts (>=1.43.0,<1.44.0)"] +supplychain = ["types-boto3-supplychain (>=1.43.0,<1.44.0)"] +support = ["types-boto3-support (>=1.43.0,<1.44.0)"] +support-app = ["types-boto3-support-app (>=1.43.0,<1.44.0)"] +sustainability = ["types-boto3-sustainability (>=1.43.0,<1.44.0)"] +swf = ["types-boto3-swf (>=1.43.0,<1.44.0)"] +synthetics = ["types-boto3-synthetics (>=1.43.0,<1.44.0)"] +taxsettings = ["types-boto3-taxsettings (>=1.43.0,<1.44.0)"] +textract = ["types-boto3-textract (>=1.43.0,<1.44.0)"] +timestream-influxdb = ["types-boto3-timestream-influxdb (>=1.43.0,<1.44.0)"] +timestream-query = ["types-boto3-timestream-query (>=1.43.0,<1.44.0)"] +timestream-write = ["types-boto3-timestream-write (>=1.43.0,<1.44.0)"] +tnb = ["types-boto3-tnb (>=1.43.0,<1.44.0)"] +transcribe = ["types-boto3-transcribe (>=1.43.0,<1.44.0)"] +transfer = ["types-boto3-transfer (>=1.43.0,<1.44.0)"] +translate = ["types-boto3-translate (>=1.43.0,<1.44.0)"] +trustedadvisor = ["types-boto3-trustedadvisor (>=1.43.0,<1.44.0)"] +uxc = ["types-boto3-uxc (>=1.43.0,<1.44.0)"] +verifiedpermissions = ["types-boto3-verifiedpermissions (>=1.43.0,<1.44.0)"] +voice-id = ["types-boto3-voice-id (>=1.43.0,<1.44.0)"] +vpc-lattice = ["types-boto3-vpc-lattice (>=1.43.0,<1.44.0)"] +waf = ["types-boto3-waf (>=1.43.0,<1.44.0)"] +waf-regional = ["types-boto3-waf-regional (>=1.43.0,<1.44.0)"] +wafv2 = ["types-boto3-wafv2 (>=1.43.0,<1.44.0)"] +wellarchitected = ["types-boto3-wellarchitected (>=1.43.0,<1.44.0)"] +wickr = ["types-boto3-wickr (>=1.43.0,<1.44.0)"] +wisdom = ["types-boto3-wisdom (>=1.43.0,<1.44.0)"] +workdocs = ["types-boto3-workdocs (>=1.43.0,<1.44.0)"] +workmail = ["types-boto3-workmail (>=1.43.0,<1.44.0)"] +workmailmessageflow = ["types-boto3-workmailmessageflow (>=1.43.0,<1.44.0)"] +workspaces = ["types-boto3-workspaces (>=1.43.0,<1.44.0)"] +workspaces-instances = ["types-boto3-workspaces-instances (>=1.43.0,<1.44.0)"] +workspaces-thin-client = ["types-boto3-workspaces-thin-client (>=1.43.0,<1.44.0)"] +workspaces-web = ["types-boto3-workspaces-web (>=1.43.0,<1.44.0)"] +xray = ["types-boto3-xray (>=1.43.0,<1.44.0)"] [[package]] name = "types-pyyaml" @@ -2810,14 +2824,14 @@ files = [ [[package]] name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" +version = "4.15.0" +description = "Backported and Experimental Type Hints for Python 3.9+" optional = false -python-versions = ">=3.8" +python-versions = ">=3.9" groups = ["main", "dev", "test"] files = [ - {file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"}, - {file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"}, + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] [[package]] @@ -2857,7 +2871,7 @@ version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." optional = false python-versions = ">=3.6" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, @@ -2931,27 +2945,7 @@ files = [ {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, ] -[[package]] -name = "zipp" -version = "3.20.2" -description = "Backport of pathlib-compatible object wrapper for zip files" -optional = false -python-versions = ">=3.8" -groups = ["main", "test"] -files = [ - {file = "zipp-3.20.2-py3-none-any.whl", hash = "sha256:a817ac80d6cf4b23bf7f2828b7cabf326f15a001bea8b1f9b49631780ba28350"}, - {file = "zipp-3.20.2.tar.gz", hash = "sha256:bc9eb26f4506fda01b81bcde0ca78103b6e62f991b381fec825435c836edbc29"}, -] - -[package.extras] -check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] -cover = ["pytest-cov"] -doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -enabler = ["pytest-enabler (>=2.2)"] -test = ["big-O", "importlib-resources ; python_version < \"3.9\"", "jaraco.functools", "jaraco.itertools", "jaraco.test", "more-itertools", "pytest (>=6,!=8.1.*)", "pytest-ignore-flaky"] -type = ["pytest-mypy"] - [metadata] lock-version = "2.1" python-versions = "^3.10.0" -content-hash = "3759fd70597c79048cebeb4fc0a1a1caa1d8a50bef0948a5a3dda1eaf13fddf5" +content-hash = "3a94d195ffb451a3a57239f3992c49a12a5a60949323e52813607ba40c73729c" diff --git a/pyproject.toml b/pyproject.toml index e8923de58..0bcad4670 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_advanced_python_wrapper" -version = "3.0.0" +version = "3.1.0" description = "Amazon Web Services (AWS) Advanced Python Wrapper" authors = ["Amazon Web Services"] readme = "README.md" @@ -20,54 +20,65 @@ classifiers = [ "Programming Language :: Python :: 3.11", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", + "Programming Language :: Python :: 3.14", ] +# SQLAlchemy dialect registration. Poetry exposes these as setuptools-style +# entry points under the ``sqlalchemy.dialects`` group, so the wrapper plugs in +# as a driver under SQLAlchemy's existing dialects (matching stock +# mysql+mysqlconnector / postgresql+psycopg) rather than as a parallel +# top-level dialect name: postgresql+aws_wrapper_psycopg and +# mysql+aws_wrapper_mysqlconnector. +[tool.poetry.plugins."sqlalchemy.dialects"] +"postgresql.aws_wrapper_psycopg" = "aws_advanced_python_wrapper.sqlalchemy_dialects.pg:AwsWrapperPGPsycopgDialect" +"mysql.aws_wrapper_mysqlconnector" = "aws_advanced_python_wrapper.sqlalchemy_dialects.mysql:AwsWrapperMySQLConnectorDialect" + [tool.poetry.dependencies] python = "^3.10.0" resourcebundle = "2.1.0" -boto3 = "^1.34.111" +boto3 = "^1.42.95" toml = "^0.10.2" -aws-xray-sdk = "^2.13.1" +aws-xray-sdk = "^2.15.0" types_aws_xray_sdk = "^2.13.0" -opentelemetry-api = "^1.22.0" -opentelemetry-sdk = "^1.22.0" -requests = "^2.32.2" -boto3-stubs = ">=1.37.38,<1.43.0" +opentelemetry-api = "^1.41.1" +opentelemetry-sdk = "^1.41.1" +requests = "^2.33.1" +boto3-stubs = ">=1.43.0,<1.44.0" [tool.poetry.group.dev.dependencies] -mypy = "^1.9.0" -flake8 = ">=6,<8" -flake8-type-checking = ">=2.9,<4.0" +mypy = "^1.20.2" +flake8 = ">=7.3.0,<8" +flake8-type-checking = ">=3.2.0,<4.0" isort = "^5.13.2" -pep8-naming = ">=0.14.1,<0.16.0" -SQLAlchemy = "^2.0.30" -psycopg = "^3.3.1" -psycopg-binary = "^3.3.1" -mysql-connector-python = "^9.5.0" -django = "^5.0" -django-stubs = "^5.2.8" +pep8-naming = ">=0.15.1,<0.16.0" +SQLAlchemy = "^2.0.49" +psycopg = "^3.3.3" +psycopg-binary = "^3.3.3" +mysql-connector-python = "^9.7.0" +django = "^5.2.13" +django-stubs = "^5.2.9" [tool.poetry.group.test.dependencies] -boto3 = "^1.34.111" -types-boto3 = "^1.34.111" -coverage = "^7.5.1" -debugpy = "^1.8.1" -pydevd-pycharm = "^233.13763.5" +boto3 = "^1.42.95" +types-boto3 = "^1.42.95" +coverage = "^7.13.5" +debugpy = "^1.8.20" +pydevd-pycharm = "^233.15619.17" pytest = "^7.4.4" -pytest-mock = "^3.14.0" -pytest-html = "^4.1.1" -pytest-html-merger = ">=0.0.10,<0.1.1" +pytest-mock = "^3.15.1" +pytest-html = "^4.2.0" +pytest-html-merger = ">=0.1.0,<0.1.1" toxiproxy-python = "^0.1.1" parameterized = "^0.9.0" -tabulate = ">=0.9,<0.11" -psycopg = "^3.3.1" -psycopg-binary = "^3.3.1" -mysql-connector-python = "^9.5.0" -opentelemetry-exporter-otlp = "^1.22.0" -opentelemetry-exporter-otlp-proto-grpc = "^1.22.0" -opentelemetry-sdk-extension-aws = "^2.0.1" -pytest-timeout = "^2.3.1" -pytest-repeat = "^0.9.3" +tabulate = ">=0.10.0,<0.11" +psycopg = "^3.3.3" +psycopg-binary = "^3.3.3" +mysql-connector-python = "^9.7.0" +opentelemetry-exporter-otlp = "^1.41.1" +opentelemetry-exporter-otlp-proto-grpc = "^1.41.1" +opentelemetry-sdk-extension-aws = "^2.1.0" +pytest-timeout = "^2.4.0" +pytest-repeat = "^0.9.4" [tool.isort] sections = "FUTURE,STDLIB,THIRDPARTY,FIRSTPARTY,LOCALFOLDER" @@ -83,7 +94,3 @@ filterwarnings = [ 'ignore:could not create cache path', 'ignore:Exception during reset or similar:pytest.PytestUnhandledThreadExceptionWarning' ] - -[tool.poetry.plugins."sqlalchemy.dialects"] -"postgresql.aws_wrapper_psycopg" = "aws_advanced_python_wrapper.sqlalchemy.pg_orm_dialect:SqlAlchemyOrmPgDialect" -"mysql.aws_wrapper_mysqlconnector" = "aws_advanced_python_wrapper.sqlalchemy.mysql_orm_dialect:SqlAlchemyOrmMysqlDialect" diff --git a/tests/integration/container/conftest.py b/tests/integration/container/conftest.py index 88e553119..619216229 100644 --- a/tests/integration/container/conftest.py +++ b/tests/integration/container/conftest.py @@ -17,7 +17,7 @@ import atexit from typing import TYPE_CHECKING, Optional -from aws_xray_sdk.core import xray_recorder # type: ignore +from aws_xray_sdk.core import xray_recorder from aws_advanced_python_wrapper.connection_provider import \ ConnectionProviderManager @@ -34,14 +34,15 @@ if TYPE_CHECKING: from .utils.test_driver import TestDriver - from aws_xray_sdk.core.models.segment import Segment # type: ignore + from aws_xray_sdk.core.models.segment import Segment import socket import timeit from time import sleep from typing import List -import pytest # type: ignore +import boto3 +import pytest from .utils.connection_utils import ConnectionUtils from .utils.database_engine_deployment import DatabaseEngineDeployment @@ -53,6 +54,37 @@ logger = Logger(__name__) +@pytest.fixture(scope="session", autouse=True) +def _prewarm_aws_pipeline(): + """Force boto3's lazy initialisation on the main thread before any test. + + boto3 defers a lot of lazy init (SSL context, urllib3 pool manager, + requests.Request construction, AWS credential-chain resolution) until the + first actual API call. When that first call happens on a worker thread + concurrently with libpq / psycopg activity during a multi-thread Aurora + failover, we have observed native-level concurrency races ending in a + SIGSEGV inside the OpenSSL / urllib3 / psycopg-binary stack. + + A single harmless ``describe_db_clusters`` here materialises all of it + once, on the main thread, before the first test body spawns any + failover-handler / topology-monitor worker thread. Implemented as a + session-scoped autouse fixture rather than a conftest import-time side + effect so it (a) does NOT fire during pure collection (``--collect-only``, + or running a single unrelated test) and (b) uses the **configured test + region** instead of a hardcoded one, exercising the same RDS endpoint the + tests will hit. Best-effort: a network-poor sandbox must not block the run. + """ + try: + info = TestEnvironment.get_current().get_info() + kwargs = {"service_name": "rds", "region_name": info.get_region()} + endpoint = info.get_rds_endpoint() + if endpoint: + kwargs["endpoint_url"] = endpoint + boto3.client(**kwargs).describe_db_clusters(MaxRecords=20) + except Exception as ex: # noqa: BLE001 -- best-effort, must not block tests + logger.debug(f"AWS pipeline prewarm failed (non-fatal): {ex}") + + @pytest.fixture(scope='module') def conn_utils(): return ConnectionUtils() @@ -156,7 +188,7 @@ def pytest_generate_tests(metafunc): environment = TestEnvironment.get_current() metafunc.parametrize("test_environment", [environment], ids=[repr(environment)]) if "test_driver" in metafunc.fixturenames: - allowed_drivers: List[TestDriver] = TestEnvironment.get_current().get_allowed_test_drivers() # type: ignore + allowed_drivers: List[TestDriver] = TestEnvironment.get_current().get_allowed_test_drivers() metafunc.parametrize("test_driver", allowed_drivers) diff --git a/tests/integration/container/sqlalchemy/test_sqlalchemy_basic.py b/tests/integration/container/sqlalchemy/test_sqlalchemy_basic.py index 00a84bcb9..162535a13 100644 --- a/tests/integration/container/sqlalchemy/test_sqlalchemy_basic.py +++ b/tests/integration/container/sqlalchemy/test_sqlalchemy_basic.py @@ -117,7 +117,15 @@ class Book(Base): class TestSqlAlchemy: @pytest.fixture(scope="function") def engine(self, conn_utils): - conn_str = f'mysql+aws_wrapper_mysqlconnector://{conn_utils.user}:{conn_utils.password}@{conn_utils.writer_cluster_host}:{conn_utils.port}/{conn_utils.dbname}' + # Pin an EFM-free plugin chain. MySQL cannot use host_monitoring / + # host_monitoring_v2: MySQLDriverDialect has no supports_abort_connection, + # and EFM V2 hard-raises (HostMonitoringV2Plugin.ConfigurationNotSupported) + # at construction without it. A bare URL would inherit the library + # DEFAULT_PLUGINS, which includes host_monitoring_v2, so we must specify + # the plugins explicitly here. + conn_str = (f'mysql+aws_wrapper_mysqlconnector://{conn_utils.user}:{conn_utils.password}' + f'@{conn_utils.writer_cluster_host}:{conn_utils.port}/{conn_utils.dbname}' + f'?wrapper_plugins=aurora_connection_tracker,failover_v2') engine = create_engine(conn_str) Base.metadata.create_all(engine) yield engine @@ -132,7 +140,7 @@ def session(self, engine): session.close() def test_sqlalchemy_backend_configuration(self, test_environment: TestEnvironment, session): - """Test SQLAlchemy backend configuration with empty plugins""" + """Test SQLAlchemy backend configuration with an EFM-free plugin chain""" # Verify that the connection is using the AWS wrapper assert session.connection().connection is not None diff --git a/tests/integration/container/sqlalchemy/test_sqlalchemy_plugins.py b/tests/integration/container/sqlalchemy/test_sqlalchemy_plugins.py index 513ab4116..72a896a74 100644 --- a/tests/integration/container/sqlalchemy/test_sqlalchemy_plugins.py +++ b/tests/integration/container/sqlalchemy/test_sqlalchemy_plugins.py @@ -14,6 +14,20 @@ # flake8: noqa: N806 +"""SQLAlchemy ORM + plugins integration tests. + +Salvaged from main's PR #1224 and now bound to the wrapper's own dialect via +the ``mysql+aws_wrapper_mysqlconnector://`` URL (see SqlAlchemySupport.md). + +Validated on real Aurora MySQL (EC2 run, 2026-06-15): these pass on +mysql-connector's default C extension -- including the failover variants +(failover_during_query, iam_plugin, secrets_manager) -- so ``use_pure=True`` +is NOT required here. The README's concern that the C extension's +``is_connected`` can block on network failure did not bite for these +ORM-level failover paths. (The MySQL SA dialect is separately exercised under +``use_pure=True`` in test_sqlalchemy.py.) +""" + from __future__ import annotations import json @@ -121,7 +135,12 @@ class Book(Base): def _build_url(user, password, host, port, dbname, wrapper_plugins=None, **extra_options): """Build a SQLAlchemy connection URL using the aws wrapper dialect.""" query_params = {} - if wrapper_plugins: + # ``is not None`` (not truthiness): an explicit empty string means "no + # plugins" and must be passed through as ``wrapper_plugins=`` so the + # wrapper loads zero plugins. Treating '' as falsy here would drop it and + # let the engine inherit DEFAULT_PLUGINS (which includes host_monitoring_v2, + # unsupported on MySQL) -- breaking test_sqlalchemy_with_no_plugins. + if wrapper_plugins is not None: query_params['wrapper_plugins'] = wrapper_plugins else: query_params['wrapper_plugins'] = '' diff --git a/tests/integration/container/test_sqlalchemy.py b/tests/integration/container/test_sqlalchemy.py new file mode 100644 index 000000000..ac7fb7ed3 --- /dev/null +++ b/tests/integration/container/test_sqlalchemy.py @@ -0,0 +1,269 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""SQLAlchemy creator-pattern integration tests for Aurora PG and Aurora MySQL. + +Proves: +- SA `create_engine(..., creator=lambda: aws_advanced_python_wrapper..connect(...))` + succeeds against real Aurora clusters for both drivers. +- Aurora failover surfaces as sqlalchemy.exc.OperationalError (via the + OperationalError-classified FailoverSuccessError) and a retry recovers. +- Read/Write Splitting's read_only flip routes to a reader and returns to a writer. + +Fixtures follow the existing test_read_write_splitting.py / test_aurora_failover.py +patterns (see conftest.py in this directory). +""" + +from __future__ import annotations + +import gc + +import pytest +from sqlalchemy import create_engine, text +from sqlalchemy.exc import OperationalError + +from aws_advanced_python_wrapper import release_resources +from aws_advanced_python_wrapper.mysql_connector import \ + connect as mysql_connect +from aws_advanced_python_wrapper.psycopg import connect as pg_connect +from aws_advanced_python_wrapper.utils.log import Logger +from .utils.conditions import (disable_on_features, enable_on_deployments, + enable_on_num_instances) +from .utils.database_engine import DatabaseEngine +from .utils.database_engine_deployment import DatabaseEngineDeployment +from .utils.rds_test_utility import RdsTestUtility +from .utils.test_driver import TestDriver +from .utils.test_environment import TestEnvironment +from .utils.test_environment_features import TestEnvironmentFeatures + +logger = Logger(__name__) + + +def _is_mysql(test_driver: TestDriver) -> bool: + return test_driver == TestDriver.MYSQL + + +def _sa_url(test_driver: TestDriver) -> str: + # Use the wrapper-aware SA dialects (registered via pyproject entry points) + # so SA's internal isinstance(...psycopg.Connection) checks see the native + # connection via the wrapper's _type_info_fetch override. The built-in + # ``postgresql+psycopg``/``mysql+mysqlconnector`` dialects do not unwrap + # AwsWrapperConnection and raise TypeError on lazy type fetches. + return "mysql+aws_wrapper_mysqlconnector://" if _is_mysql(test_driver) else "postgresql+aws_wrapper_psycopg://" + + +def _wrapper_dialect(test_driver: TestDriver) -> str: + return "aurora-mysql" if _is_mysql(test_driver) else "aurora-pg" + + +def _instance_id_sql(test_driver: TestDriver) -> str: + if _is_mysql(test_driver): + return "SELECT @@aurora_server_id" + return "SELECT pg_catalog.aurora_db_instance_identifier()" + + +def _is_reader_sql(test_driver: TestDriver) -> str: + # Data-plane "is this a reader?" check. After an Aurora failover this + # is authoritative on the connected instance, while the control-plane + # DescribeDBClusters.IsClusterWriter can lag the data plane by tens of + # seconds on multi-instance clusters (5-instance MULTI-5 is the worst). + if _is_mysql(test_driver): + return "SELECT @@innodb_read_only" + return "SELECT pg_catalog.pg_is_in_recovery()" + + +def _readonly_option(test_driver: TestDriver) -> dict: + return {"mysql_readonly": True} if _is_mysql(test_driver) else {"postgresql_readonly": True} + + +def _build_engine( + test_driver: TestDriver, + conninfo_kwargs: dict, + plugins: str, + **extra_props, +): + """Build a SQLAlchemy engine whose creator goes through the wrapper. + + ``**extra_props`` flows straight through to the wrapper's connect() + call as additional connection properties (e.g. ``topology_refresh_ms``, + ``failover_timeout_sec``). The wrapper picks these up via its + ``WrapperProperties`` registry just like the URL-query path does. + """ + if _is_mysql(test_driver): + # ``conninfo_kwargs`` (from ``DriverHelper.get_connect_params`` for MYSQL) + # already includes ``use_pure: True``; don't pass it again here, or + # mysql_connect() raises ``TypeError: got multiple values for 'use_pure'``. + creator = lambda: mysql_connect( # noqa: E731 + "", wrapper_dialect=_wrapper_dialect(test_driver), + plugins=plugins, **extra_props, **conninfo_kwargs, + ) + else: + creator = lambda: pg_connect( # noqa: E731 + "", wrapper_dialect=_wrapper_dialect(test_driver), + plugins=plugins, **extra_props, **conninfo_kwargs, + ) + return create_engine(_sa_url(test_driver), creator=creator) + + +@enable_on_num_instances(min_instances=2) +@enable_on_deployments([DatabaseEngineDeployment.AURORA]) +@disable_on_features([TestEnvironmentFeatures.RUN_AUTOSCALING_TESTS_ONLY, + TestEnvironmentFeatures.BLUE_GREEN_DEPLOYMENT, + TestEnvironmentFeatures.PERFORMANCE]) +class TestSqlAlchemy: + + @pytest.fixture(autouse=True) + def setup_method(self, request): + logger.info(f"Starting test: {request.node.name}") + yield + release_resources() + logger.info(f"Ending test: {request.node.name}") + release_resources() + gc.collect() + + @pytest.fixture(scope="class") + def aurora_utility(self): + region: str = TestEnvironment.get_current().get_info().get_region() + return RdsTestUtility(region) + + def test_sqlalchemy_creator_survives_aurora_failover( + self, test_driver: TestDriver, conn_utils, aurora_utility): + """SA engine recovers from Aurora failover via the OperationalError retry path.""" + # Failover test is PG+MySQL symmetric; skip on unsupported engines. + engine_kind = TestEnvironment.get_current().get_engine() + if engine_kind not in (DatabaseEngine.PG, DatabaseEngine.MYSQL): + pytest.skip(f"Unsupported engine: {engine_kind}") + + initial_writer_id = aurora_utility.get_cluster_writer_instance_id() + + # MySQL Connector/Python doesn't support thread-based connection abort, + # which BOTH host_monitoring plugins (v1 and v2) require. Per + # docs/using-the-python-wrapper/using-plugins/UsingTheHostMonitoringPlugin.md: + # "this plugin is incompatible with the MySQL Connector/Python driver." + # Drop EFM entirely on MySQL; PG keeps host_monitoring_v2. + plugins = "failover" if _is_mysql(test_driver) else "failover,host_monitoring_v2" + engine = _build_engine( + test_driver, conn_utils.get_connect_params(), plugins=plugins, + ) + try: + with engine.connect() as conn: + pre_failover_id = conn.execute(text(_instance_id_sql(test_driver))).scalar_one() + assert pre_failover_id == initial_writer_id + + # Trigger failover against the cluster. + aurora_utility.failover_cluster_and_wait_until_writer_changed() + + # First query after failover should raise sqlalchemy.exc.OperationalError + # because FailoverSuccessError is reclassified as OperationalError. + recovered = False + attempts_remaining = 10 + while attempts_remaining > 0 and not recovered: + try: + with engine.connect() as conn: + new_writer_id = conn.execute( + text(_instance_id_sql(test_driver)) + ).scalar_one() + assert new_writer_id != initial_writer_id + # Data-plane role check: pg_is_in_recovery / @@innodb_read_only + # on the connected instance is authoritative and race-free + # against the control plane (DescribeDBClusters), which can + # disagree with the data plane for tens of seconds on + # multi-instance Aurora clusters post-failover. + is_reader = conn.execute(text(_is_reader_sql(test_driver))).scalar_one() + assert is_reader in (0, False) + recovered = True + except OperationalError: + attempts_remaining -= 1 + + assert recovered, "SA did not recover from failover within 10 attempts" + finally: + engine.dispose() + release_resources() + + def test_sqlalchemy_creator_read_write_splitting( + self, test_driver: TestDriver, conn_utils, aurora_utility): + """R/W splitting routes read_only connections to a reader and returns to writer.""" + engine_kind = TestEnvironment.get_current().get_engine() + if engine_kind not in (DatabaseEngine.PG, DatabaseEngine.MYSQL): + pytest.skip(f"Unsupported engine: {engine_kind}") + + # Pair ``read_write_splitting`` with ``failover_v2`` (and, on PG, + # ``host_monitoring_v2``) per the canonical AWS samples: + # * docs/examples/MySQLReadWriteSplitting.py:87 ("…,failover") + # * docs/examples/PGReadWriteSplitting.py:87 ("…,failover,host_monitoring") + # * docs/using-the-python-wrapper/using-plugins/UsingTheReadWriteSplittingPlugin.md:11 + # ``failover_v2`` is the modern equivalent of ``failover`` and is + # in main's DEFAULT_PLUGINS. Its ``connect()`` calls + # ``plugin_service.refresh_host_list(conn)`` on the initial + # connection (failover_v2_plugin.py:178), which starts the + # cluster topology monitor thread; without that, the host list + # stays at {writer-only} and the read-only flip falls back to + # the writer. MySQL omits host_monitoring_v2 because mysql- + # connector-python doesn't support thread-based abort (see the + # EFM sweep elsewhere in this file and + # docs/.../UsingTheHostMonitoringPlugin.md:19). + plugins = ( + "read_write_splitting,failover_v2" + if _is_mysql(test_driver) + else "read_write_splitting,failover_v2,host_monitoring_v2" + ) + engine = _build_engine( + test_driver, conn_utils.get_connect_params(), + plugins=plugins, + ) + try: + with engine.connect() as conn: + writer_id = conn.execute(text(_instance_id_sql(test_driver))).scalar_one() + conn.commit() + + # SA's PG dialect registers ``postgresql_readonly`` via + # ``PGReadOnlyConnectionCharacteristic`` + # (sqlalchemy/dialects/postgresql/base.py:3263) which routes + # through ``dialect.set_readonly`` → the wrapper's + # ``AwsWrapperConnection.read_only`` property setter → + # ``CONNECTION_SET_READ_ONLY`` plugin dispatch. SA's MySQL + # dialect has no analogous characteristic — ``mysql_readonly`` + # passed to ``execution_options`` is silently ignored — so on + # MySQL we reach the wrapper's read_only setter directly via + # the DBAPI connection (mirrors what wrapper-aware MySQL users + # would do today). Reset to ``False`` before pool checkin so a + # later ``engine.connect()`` isn't stuck read-only. + if _is_mysql(test_driver): + with engine.connect() as conn: + raw = conn.connection.dbapi_connection + raw.read_only = True + try: + reader_id = conn.execute( + text(_instance_id_sql(test_driver)) + ).scalar_one() + conn.commit() + finally: + raw.read_only = False + else: + with engine.connect().execution_options(**_readonly_option(test_driver)) as conn: + reader_id = conn.execute(text(_instance_id_sql(test_driver))).scalar_one() + conn.commit() + + assert reader_id != writer_id, ( + f"read-only connection should route to a reader, got {reader_id}" + ) + + # Next non-read-only connection should return to the writer. + with engine.connect() as conn: + back_to_writer = conn.execute(text(_instance_id_sql(test_driver))).scalar_one() + conn.commit() + assert back_to_writer == writer_id + finally: + engine.dispose() + release_resources() diff --git a/tests/integration/container/utils/target_python_version.py b/tests/integration/container/utils/target_python_version.py index 624e6676f..267ac20e4 100644 --- a/tests/integration/container/utils/target_python_version.py +++ b/tests/integration/container/utils/target_python_version.py @@ -19,3 +19,4 @@ class TargetPythonVersion(Enum): PYTHON_3_11 = "PYTHON_3_11" PYTHON_3_12 = "PYTHON_3_12" PYTHON_3_13 = "PYTHON_3_13" + PYTHON_3_14 = "PYTHON_3_14" diff --git a/tests/integration/host/build.gradle.kts b/tests/integration/host/build.gradle.kts index c98afa215..aec208f5b 100644 --- a/tests/integration/host/build.gradle.kts +++ b/tests/integration/host/build.gradle.kts @@ -59,6 +59,17 @@ tasks.withType { reports.html.required.set(false) systemProperty("java.util.logging.config.file", "${project.buildDir}/resources/test/logging-test.properties") + + // Forward CLI -D system properties whose names start with "exclude-" to the + // forked Test task JVM. Without this, `gradle ... -Dexclude-python-3-11=true` + // sets the property only on the gradle process; TestEnvironmentConfiguration + // reads them inside the Test JVM and would see the defaults. + System.getProperties().forEach { k, v -> + val key = k.toString() + if (key.startsWith("exclude-")) { + systemProperty(key, v.toString()) + } + } } tasks.register("test-python-3.11-mysql") { @@ -68,6 +79,7 @@ tasks.register("test-python-3.11-mysql") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-12", "true") systemProperty("exclude-python-3-13", "true") + systemProperty("exclude-python-3-14", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-bg", "true") @@ -85,6 +97,7 @@ tasks.register("test-python-3.11-pg") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-12", "true") systemProperty("exclude-python-3-13", "true") + systemProperty("exclude-python-3-14", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-bg", "true") @@ -102,6 +115,7 @@ tasks.register("test-python-3.12-mysql") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-11", "true") systemProperty("exclude-python-3-13", "true") + systemProperty("exclude-python-3-14", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-traces-telemetry", "true") @@ -119,6 +133,7 @@ tasks.register("test-python-3.12-pg") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-11", "true") systemProperty("exclude-python-3-13", "true") + systemProperty("exclude-python-3-14", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-bg", "true") @@ -136,6 +151,7 @@ tasks.register("test-python-3.13-mysql") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-11", "true") systemProperty("exclude-python-3-12", "true") + systemProperty("exclude-python-3-14", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-bg", "true") @@ -153,6 +169,43 @@ tasks.register("test-python-3.13-pg") { systemProperty("exclude-performance", "true") systemProperty("exclude-python-3-11", "true") systemProperty("exclude-python-3-12", "true") + systemProperty("exclude-python-3-14", "true") + systemProperty("exclude-multi-az-cluster", "true") + systemProperty("exclude-multi-az-instance", "true") + systemProperty("exclude-bg", "true") + systemProperty("exclude-mysql-driver", "true") + systemProperty("exclude-mysql-engine", "true") + systemProperty("exclude-mariadb-driver", "true") + systemProperty("exclude-mariadb-engine", "true") + } +} + +tasks.register("test-python-3.14-mysql") { + group = "verification" + filter.includeTestsMatching("integration.host.TestRunner.runTests") + doFirst { + systemProperty("exclude-performance", "true") + systemProperty("exclude-python-3-11", "true") + systemProperty("exclude-python-3-12", "true") + systemProperty("exclude-python-3-13", "true") + systemProperty("exclude-multi-az-cluster", "true") + systemProperty("exclude-multi-az-instance", "true") + systemProperty("exclude-bg", "true") + systemProperty("exclude-traces-telemetry", "true") + systemProperty("exclude-metrics-telemetry", "true") + systemProperty("exclude-pg-driver", "true") + systemProperty("exclude-pg-engine", "true") + } +} + +tasks.register("test-python-3.14-pg") { + group = "verification" + filter.includeTestsMatching("integration.host.TestRunner.runTests") + doFirst { + systemProperty("exclude-performance", "true") + systemProperty("exclude-python-3-11", "true") + systemProperty("exclude-python-3-12", "true") + systemProperty("exclude-python-3-13", "true") systemProperty("exclude-multi-az-cluster", "true") systemProperty("exclude-multi-az-instance", "true") systemProperty("exclude-bg", "true") diff --git a/tests/integration/host/src/test/java/integration/TargetPythonVersion.java b/tests/integration/host/src/test/java/integration/TargetPythonVersion.java index 31e0edd77..259608cf2 100644 --- a/tests/integration/host/src/test/java/integration/TargetPythonVersion.java +++ b/tests/integration/host/src/test/java/integration/TargetPythonVersion.java @@ -19,5 +19,6 @@ public enum TargetPythonVersion { PYTHON_3_11, PYTHON_3_12, - PYTHON_3_13 + PYTHON_3_13, + PYTHON_3_14 } diff --git a/tests/unit/test_dialect.py b/tests/unit/test_dialect.py index 40b9ca5f4..5fdc7a1c1 100644 --- a/tests/unit/test_dialect.py +++ b/tests/unit/test_dialect.py @@ -14,8 +14,8 @@ from unittest.mock import patch -import psycopg # type: ignore -import pytest # type: ignore +import psycopg +import pytest from aws_advanced_python_wrapper.database_dialect import ( AuroraMysqlDialect, AuroraPgDialect, DatabaseDialectManager, DialectCode, diff --git a/tests/unit/test_error_hierarchy.py b/tests/unit/test_error_hierarchy.py new file mode 100644 index 000000000..c4b46505e --- /dev/null +++ b/tests/unit/test_error_hierarchy.py @@ -0,0 +1,87 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + +from aws_advanced_python_wrapper import errors, pep249 + + +def test_aws_wrapper_error_is_pep249_error(): + err = errors.AwsWrapperError("x") + assert isinstance(err, pep249.Error) + + +def test_aws_connect_error_is_operational_error(): + err = errors.AwsConnectError("x") + assert isinstance(err, errors.AwsWrapperError) + assert isinstance(err, pep249.OperationalError) + + +@pytest.mark.parametrize("cls", [ + errors.FailoverError, + errors.FailoverSuccessError, + errors.FailoverFailedError, + errors.TransactionResolutionUnknownError, +]) +def test_failover_errors_are_operational_errors(cls): + err = cls("x") + assert isinstance(err, pep249.OperationalError) + assert isinstance(err, pep249.Error) + + +def test_query_timeout_is_operational_error(): + err = errors.QueryTimeoutError("x") + assert isinstance(err, errors.AwsWrapperError) + assert isinstance(err, pep249.OperationalError) + + +def test_read_write_splitting_error_is_interface_error(): + err = errors.ReadWriteSplittingError("x") + assert isinstance(err, errors.AwsWrapperError) + assert isinstance(err, pep249.InterfaceError) + + +def test_unsupported_operation_is_not_supported_error(): + err = errors.UnsupportedOperationError("x") + assert isinstance(err, errors.AwsWrapperError) + assert isinstance(err, pep249.NotSupportedError) + + +def test_existing_except_awswrappererror_still_catches_children(): + for cls in (errors.AwsConnectError, errors.QueryTimeoutError, + errors.ReadWriteSplittingError, errors.UnsupportedOperationError): + try: + raise cls("x") + except errors.AwsWrapperError: + pass + else: + pytest.fail(f"{cls.__name__} should be caught by except AwsWrapperError") + + +def test_failover_errors_caught_by_except_error(): + for cls in (errors.FailoverError, errors.FailoverSuccessError, + errors.FailoverFailedError, errors.TransactionResolutionUnknownError): + try: + raise cls("x") + except pep249.Error: + pass + else: + pytest.fail(f"{cls.__name__} should be caught by except pep249.Error") + + +def test_mro_shape_has_single_error_ancestor(): + for cls in (errors.AwsConnectError, errors.QueryTimeoutError, + errors.ReadWriteSplittingError, errors.UnsupportedOperationError): + error_ancestors = [c for c in cls.__mro__ if c is pep249.Error] + assert len(error_ancestors) == 1, f"{cls.__name__} has >1 Error in MRO" diff --git a/tests/unit/test_failover_success_error_isolation.py b/tests/unit/test_failover_success_error_isolation.py new file mode 100644 index 000000000..078a824db --- /dev/null +++ b/tests/unit/test_failover_success_error_isolation.py @@ -0,0 +1,57 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Lock-in: FailoverSuccessError must not subclass any driver-native error +class. This is the contract that prevents Django's ``wrap_database_errors`` +from swallowing the wrapper's failover signal -- on MySQL today and on +PostgreSQL if/when a Django-PG backend ships in the wrapper. + +SA classification of FailoverSuccessError to ``sqlalchemy.exc.OperationalError`` +happens at the dialect boundary via +``aws_advanced_python_wrapper.sqlalchemy_dialects._exception_handling +._FailoverSuccessRewrapMixin``, which catches FailoverSuccessError in +``do_execute`` / ``do_executemany`` and re-raises as the dialect's native +``OperationalError``. That mechanism does NOT require the driver-native +multi-inheritance below; if someone re-introduces it, Django (and any +other consumer that walks ``issubclass`` against driver error modules) +will start wrapping failover signals. + +Regression these tests guard against: see +tests/integration/container/django/test_django_plugins.py:: +test_django_failover_during_query (commit d5ce856 introduced the +multi-inheritance and broke this test; the revert restores it). +""" + +import pytest + +from aws_advanced_python_wrapper.errors import FailoverSuccessError + + +def test_failover_success_error_is_not_psycopg_operational_error(): + psycopg = pytest.importorskip("psycopg") + assert not issubclass(FailoverSuccessError, psycopg.errors.OperationalError), ( + "FailoverSuccessError must not subclass psycopg.errors.OperationalError. " + "If it does, Django's wrap_database_errors will wrap it on a Django-PG " + "backend and block ``except FailoverSuccessError:`` handlers." + ) + + +def test_failover_success_error_is_not_mysqlconnector_operational_error(): + mc_errors = pytest.importorskip("mysql.connector.errors") + assert not issubclass(FailoverSuccessError, mc_errors.OperationalError), ( + "FailoverSuccessError must not subclass " + "mysql.connector.errors.OperationalError. If it does, Django's " + "wrap_database_errors wraps it on the MySQL Django backend " + "(test_django_failover_during_query regression)." + ) diff --git a/tests/unit/test_mysql_driver_dialect.py b/tests/unit/test_mysql_driver_dialect.py index e790788f3..0662fa4e3 100644 --- a/tests/unit/test_mysql_driver_dialect.py +++ b/tests/unit/test_mysql_driver_dialect.py @@ -40,13 +40,38 @@ def mock_invalid_conn(mocker): def test_is_closed(dialect, mock_conn, mock_invalid_conn): + mock_conn.unread_result = False mock_conn.is_connected.return_value = False assert dialect.is_closed(mock_conn) + mock_conn.is_connected.return_value = True + assert not dialect.is_closed(mock_conn) + with pytest.raises(AwsWrapperError): dialect.is_closed(mock_invalid_conn) +def test_is_closed_pings_on_calling_thread(dialect, mock_conn): + # Regression for the env-4 SIGSEGV: the liveness ping must run on the CALLING + # thread, never a worker/pool thread. mysql.connector connections are not safe + # for concurrent use; offloading is_connected() (a ping == SSL I/O) to a pool + # let an abandoned ping run concurrently with the caller's use of the same + # connection -> two threads on one SSLSocket -> OpenSSL use-after-free. + import threading + + mock_conn.unread_result = False + caller_tid = threading.get_ident() + seen = {} + + def record(): + seen["tid"] = threading.get_ident() + return True + + mock_conn.is_connected.side_effect = record + assert dialect.is_closed(mock_conn) is False # is_connected True -> not closed + assert seen["tid"] == caller_tid + + def test_is_in_transaction(dialect, mock_conn, mock_invalid_conn): mock_conn.in_transaction = True assert dialect.is_in_transaction(mock_conn) diff --git a/tests/unit/test_mysql_orm_dialect.py b/tests/unit/test_mysql_orm_dialect.py deleted file mode 100644 index 3c8696766..000000000 --- a/tests/unit/test_mysql_orm_dialect.py +++ /dev/null @@ -1,43 +0,0 @@ -# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"). -# You may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import pytest -from mysql.connector.errors import OperationalError - -from aws_advanced_python_wrapper import AwsWrapperConnection -from aws_advanced_python_wrapper.sqlalchemy.mysql_orm_dialect import \ - SqlAlchemyOrmMysqlDialect - - -@pytest.fixture -def dialect(): - # __init__ requires a live DBAPI, so bypass it to unit test do_ping in isolation. - return SqlAlchemyOrmMysqlDialect.__new__(SqlAlchemyOrmMysqlDialect) - - -@pytest.fixture -def dbapi_connection(mocker): - connection = mocker.MagicMock(spec=AwsWrapperConnection) - connection.target_connection = mocker.MagicMock() - return connection - - -def test_do_ping_pings_wrapped_target_connection(dialect, dbapi_connection): - assert dialect.do_ping(dbapi_connection) is True - dbapi_connection.target_connection.ping.assert_called_once_with(reconnect=False) - - -def test_do_ping_returns_false_on_dead_connection(dialect, dbapi_connection): - dbapi_connection.target_connection.ping.side_effect = OperationalError("MySQL server has gone away") - assert dialect.do_ping(dbapi_connection) is False diff --git a/tests/unit/test_pg_driver_dialect.py b/tests/unit/test_pg_driver_dialect.py index bc4a533aa..b19e99a5a 100644 --- a/tests/unit/test_pg_driver_dialect.py +++ b/tests/unit/test_pg_driver_dialect.py @@ -48,9 +48,33 @@ def dialect(): return PgDriverDialect(Properties()) -def test_abort_connection(dialect, mock_conn, mock_invalid_conn): +def test_abort_connection(dialect, mock_conn, mock_invalid_conn, mocker): + # abort_connection runs on the EFM monitor thread against a connection owned + # by another thread. It must NOT call close() (psycopg close() is PQfinish: + # it frees the libpq struct + tears down SSL with no lock, racing a + # use-after-free in libpq/OpenSSL -> SIGSEGV). It must shut the underlying + # socket down instead: that interrupts the owning thread's recv (even on an + # unreachable host) WITHOUT freeing the struct, and releases the fd without + # closing it (the connection still owns it). + mock_conn.closed = False + mock_conn.fileno.return_value = 7 + mock_sock = mocker.MagicMock() + socket_ctor = mocker.patch( + "aws_advanced_python_wrapper.pg_driver_dialect.socket.socket", return_value=mock_sock) + + dialect.abort_connection(mock_conn) + socket_ctor.assert_called_once_with(fileno=7) + mock_sock.shutdown.assert_called_once() + mock_sock.detach.assert_called_once() + mock_conn.close.assert_not_called() + + # already-closed connection: nothing to do + mock_conn.reset_mock() + socket_ctor.reset_mock() + mock_conn.closed = True dialect.abort_connection(mock_conn) - mock_conn.close.assert_called_once() + socket_ctor.assert_not_called() + mock_conn.close.assert_not_called() with pytest.raises(AwsWrapperError): dialect.abort_connection(mock_invalid_conn) diff --git a/tests/unit/test_retry_util.py b/tests/unit/test_retry_util.py new file mode 100644 index 000000000..60bfe3349 --- /dev/null +++ b/tests/unit/test_retry_util.py @@ -0,0 +1,95 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for the (sync) RetryUtil failover connection helper.""" + +import time +from unittest.mock import MagicMock + +from aws_advanced_python_wrapper.hostinfo import HostInfo, HostRole +from aws_advanced_python_wrapper.utils.retry_util import RetryUtil + +_W = HostInfo(host="writer.example.com", port=5432, role=HostRole.WRITER) +_R1 = HostInfo(host="r1.example.com", port=5432, role=HostRole.READER) + + +def _svc(*, all_hosts, role=HostRole.WRITER, conn=None): + """Build a MagicMock sync plugin_service for the retry helper.""" + svc = MagicMock() + svc.all_hosts = tuple(all_hosts) + svc.hosts = list(all_hosts) + svc.filter_hosts = MagicMock(side_effect=lambda hosts: list(hosts)) + svc.refresh_host_list = MagicMock() + svc.force_refresh_host_list = MagicMock() + svc.get_host_info_by_strategy = MagicMock( + side_effect=lambda role_, strat, hosts: hosts[0] if hosts else None) + svc.get_host_role = MagicMock(return_value=role) + c = conn or MagicMock(name="new_conn") + svc.connect = MagicMock(return_value=c) + svc.driver_dialect = MagicMock() + return svc, c + + +def _deadline(seconds=0.5): + return time.time() + seconds + + +def test_get_allowed_connection_falls_back_to_writer_when_no_reader(): + # Regression (#1246 GDB live-run bug): the + # *_OR_WRITER failover modes pass verify_role=None with an allowed list that + # includes the writer. Right after a writer failover the newly elected + # writer can be the only reachable host. The host selector requires a + # concrete role, so the helper must try READER then fall back to WRITER. The + # old code asked only for READER, so it could never select the writer and + # timed out with UnableToConnectToReader even though the writer was valid. + svc, conn = _svc(all_hosts=[_W], role=HostRole.WRITER) + + def _role_selector(role_, strat, hosts): + matches = [h for h in hosts if h.role == role_] + if not matches: + raise Exception("strategy can't get a host of the requested role") + return matches[0] + svc.get_host_info_by_strategy = MagicMock(side_effect=_role_selector) + + util = RetryUtil() + result = util.get_allowed_connection( + svc, MagicMock(), object(), + lambda: [_W], "random", None, _deadline()) + + assert result.connection is conn + assert result.host_info.host == _W.host + roles_asked = [call.args[0] for call in svc.get_host_info_by_strategy.call_args_list] + assert HostRole.WRITER in roles_asked # the fix's writer fallback fired + + +def test_get_allowed_connection_selects_reader_when_available(): + # When a reader IS reachable, the reader-first preference still holds + # (read-offload): a *_OR_WRITER mode should pick the reader, not the writer. + svc, conn = _svc(all_hosts=[_R1], role=HostRole.READER) + + def _role_selector(role_, strat, hosts): + matches = [h for h in hosts if h.role == role_] + if not matches: + raise Exception("no host for role") + return matches[0] + svc.get_host_info_by_strategy = MagicMock(side_effect=_role_selector) + + util = RetryUtil() + result = util.get_allowed_connection( + svc, MagicMock(), object(), + lambda: [_R1], "random", None, _deadline()) + + assert result.connection is conn + assert result.host_info.host == _R1.host + assert svc.get_host_info_by_strategy.call_args_list[0].args[0] == HostRole.READER diff --git a/tests/unit/test_sqlalchemy_dialects.py b/tests/unit/test_sqlalchemy_dialects.py new file mode 100644 index 000000000..4e20a2692 --- /dev/null +++ b/tests/unit/test_sqlalchemy_dialects.py @@ -0,0 +1,254 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest +from sqlalchemy import create_engine +from sqlalchemy.dialects import registry +from sqlalchemy.dialects.mysql.mysqlconnector import \ + MySQLDialect_mysqlconnector +from sqlalchemy.dialects.postgresql.psycopg import PGDialect_psycopg +from sqlalchemy.engine.url import make_url + +import aws_advanced_python_wrapper.mysql_connector as wrapper_mysql +import aws_advanced_python_wrapper.psycopg as wrapper_psycopg +from aws_advanced_python_wrapper.sqlalchemy_dialects.mysql import \ + AwsWrapperMySQLConnectorDialect +from aws_advanced_python_wrapper.sqlalchemy_dialects.pg import \ + AwsWrapperPGPsycopgDialect + + +def test_pg_dialect_subclasses_pgdialect_psycopg(): + assert issubclass(AwsWrapperPGPsycopgDialect, PGDialect_psycopg) + + +def test_pg_dialect_import_dbapi_returns_wrapper_submodule(): + assert AwsWrapperPGPsycopgDialect.import_dbapi() is wrapper_psycopg + + +def test_pg_dialect_driver_attr(): + assert AwsWrapperPGPsycopgDialect.driver == "aws_wrapper_psycopg" + + +def test_mysql_dialect_subclasses_mysqldialect_mysqlconnector(): + assert issubclass(AwsWrapperMySQLConnectorDialect, MySQLDialect_mysqlconnector) + + +def test_mysql_dialect_import_dbapi_returns_wrapper_submodule(): + assert AwsWrapperMySQLConnectorDialect.import_dbapi() is wrapper_mysql + + +def test_mysql_dialect_driver_attr(): + assert AwsWrapperMySQLConnectorDialect.driver == "aws_wrapper_mysqlconnector" + + +@pytest.mark.parametrize( + "dialect_cls", [AwsWrapperMySQLConnectorDialect, AwsWrapperPGPsycopgDialect]) +def test_is_disconnect_handles_full_failover_error_family(dialect_cls): + # Regression: is_disconnect must classify the ENTIRE FailoverError family + # without probing driver-specific attrs (errno/args[0]). A mid-transaction + # failover raises TransactionResolutionUnknownError, which carries no + # ``errno`` -- the old code only special-cased FailoverSuccessError / + # FailoverFailedError and fell through to the upstream errno probe, raising + # "AttributeError: 'TransactionResolutionUnknownError' object has no + # attribute 'errno'" (MySQL SQLAlchemy failover tests, env-3/env-4). + from aws_advanced_python_wrapper.errors import ( + FailoverFailedError, FailoverSuccessError, + TransactionResolutionUnknownError) + d = dialect_cls.__new__(dialect_cls) # avoid full dialect __init__/dbapi + # Reconnected-to-new-writer signals -> not a disconnect (slot still valid). + assert d.is_disconnect(FailoverSuccessError("x"), None, None) is False + assert d.is_disconnect( + TransactionResolutionUnknownError("x"), None, None) is False + # No usable connection -> disconnect (SA invalidates the slot). + assert d.is_disconnect(FailoverFailedError("x"), None, None) is True + + +# Registration uses the SA . convention: the wrapper plugs in +# as a driver under the stock ``postgresql`` / ``mysql`` dialects, so the URL is +# ``postgresql+aws_wrapper_psycopg`` / ``mysql+aws_wrapper_mysqlconnector``. +def test_registry_resolves_postgresql_aws_wrapper_psycopg(): + cls = registry.load("postgresql.aws_wrapper_psycopg") + assert cls is AwsWrapperPGPsycopgDialect + + +def test_registry_resolves_mysql_aws_wrapper_mysqlconnector(): + cls = registry.load("mysql.aws_wrapper_mysqlconnector") + assert cls is AwsWrapperMySQLConnectorDialect + + +def test_url_get_dialect_pg(): + url = make_url( + "postgresql+aws_wrapper_psycopg://u:p@h:5432/db?wrapper_dialect=aurora-pg" + ) + assert url.get_dialect() is AwsWrapperPGPsycopgDialect + + +def test_url_get_dialect_mysql(): + url = make_url( + "mysql+aws_wrapper_mysqlconnector://u:p@h:3306/db?wrapper_dialect=aurora-mysql" + ) + assert url.get_dialect() is AwsWrapperMySQLConnectorDialect + + +def test_url_query_args_flow_through_to_wrapper_connect(mocker): + """URL query args must become kwargs on AwsWrapperConnection.connect.""" + from aws_advanced_python_wrapper.wrapper import AwsWrapperConnection + mock_connect = mocker.patch.object( + AwsWrapperConnection, "connect", return_value=mocker.MagicMock(), + ) + # NOTE: URL uses `wrapper_plugins` instead of `plugins` because SA's + # create_engine intercepts `plugins` as its own engine-plugin loader. + # Our dialect's create_connect_args translates wrapper_plugins → plugins + # before handing kwargs to the DBAPI. + engine = create_engine( + "postgresql+aws_wrapper_psycopg://u:p@h:5432/db" + "?wrapper_dialect=aurora-pg&wrapper_plugins=failover,efm" + ) + try: + with engine.connect(): + pass + except Exception: + # The MagicMock connection may not satisfy SA's probes. + # We only care that AwsWrapperConnection.connect was invoked with the + # right kwargs. + pass + + assert mock_connect.called, "AwsWrapperConnection.connect was never invoked" + _args, kwargs = mock_connect.call_args + assert kwargs.get("wrapper_dialect") == "aurora-pg" + assert kwargs.get("plugins") == "failover,efm" + assert "wrapper_plugins" not in kwargs, ( + "dialect should have renamed wrapper_plugins → plugins before the connect call" + ) + + +# ---- _type_info_fetch unwrap (sync) ------------------------------------- + + +def test_pg_dialect_type_info_fetch_unwraps_target_connection(mocker): + """Regression guard for + + TypeError: expected Connection or AsyncConnection, + got AwsWrapperConnection + + at ``psycopg/_typeinfo.py:90``. ``psycopg.TypeInfo.fetch`` strictly + isinstance-checks its first argument -- our wrapper proxy is not a + subclass of ``psycopg.Connection``. The dialect override unwraps + to the native psycopg connection via ``target_connection`` before + calling into psycopg. + """ + from unittest.mock import MagicMock + native_conn = MagicMock(name="native_psycopg_connection") + wrapper = MagicMock(name="AwsWrapperConnection") + wrapper.target_connection = native_conn + # SA's sync path: connection.connection IS the DBAPI conn (our + # wrapper). No extra adapter layer between them. + sa_connection = MagicMock() + sa_connection.connection = wrapper + # Make the wrapper look like it has driver_connection too (mirrors + # AdaptedConnection contract added in d372b5f): + wrapper.driver_connection = wrapper + + # Patch TypeInfo.fetch so we can assert its first arg without + # needing a live Postgres. + fetch_mock = mocker.patch( + "psycopg.types.TypeInfo.fetch", return_value="type-info-sentinel") + + dialect = AwsWrapperPGPsycopgDialect() + result = dialect._type_info_fetch(sa_connection, "hstore") + + assert result == "type-info-sentinel" + fetch_mock.assert_called_once() + called_arg = fetch_mock.call_args.args[0] + assert called_arg is native_conn, ( + "TypeInfo.fetch must receive the native psycopg connection, " + "not our wrapper proxy") + + +def test_pg_dialect_type_info_fetch_falls_through_when_no_target_connection(mocker): + """If the DBAPI connection lacks ``target_connection`` (e.g., SA is + pointed at a real psycopg connection directly, no wrapper in the + middle), pass the connection through unchanged -- don't break + non-wrapper deployments.""" + from unittest.mock import MagicMock + + # spec= so attribute-lookup returns a real AttributeError for + # target_connection and we fall through to the conn itself. + class _NativeLike: + pass + native = _NativeLike() + sa_connection = MagicMock() + sa_connection.connection = native + + fetch_mock = mocker.patch( + "psycopg.types.TypeInfo.fetch", return_value="ok") + + dialect = AwsWrapperPGPsycopgDialect() + dialect._type_info_fetch(sa_connection, "hstore") + + called_arg = fetch_mock.call_args.args[0] + assert called_arg is native, ( + "no-wrapper deployments should pass the native conn through unchanged") + + +# --- do_ping / pool_pre_ping support (AWS PR #1245, ported to all dialects) --- + +def test_mysql_do_ping_pings_target_connection(): + """MySQL do_ping must ping the native mysql-connector connection (the + wrapper exposes no ``.ping()``), so pool_pre_ping works.""" + from unittest.mock import MagicMock + native = MagicMock(name="native_mysqlconnector") + wrapper = MagicMock(name="AwsWrapperConnection") + wrapper.target_connection = native + + dialect = AwsWrapperMySQLConnectorDialect() + assert dialect.do_ping(wrapper) is True + native.ping.assert_called_once_with(reconnect=False) + + +def test_mysql_do_ping_returns_false_on_dead_connection(): + from unittest.mock import MagicMock + native = MagicMock(name="native_mysqlconnector") + native.ping.side_effect = Exception("server has gone away") + wrapper = MagicMock(name="AwsWrapperConnection") + wrapper.target_connection = native + + dialect = AwsWrapperMySQLConnectorDialect() + assert dialect.do_ping(wrapper) is False + + +def test_pg_do_ping_runs_select_one_on_target_connection(): + """PG do_ping runs SELECT 1 on the native psycopg connection (psycopg3 + has no ``.ping()``).""" + from unittest.mock import MagicMock + native = MagicMock(name="native_psycopg") + native.autocommit = True # already autocommit -> no toggle + wrapper = MagicMock(name="AwsWrapperConnection") + wrapper.target_connection = native + + dialect = AwsWrapperPGPsycopgDialect() + assert dialect.do_ping(wrapper) is True + native.execute.assert_called_once_with("SELECT 1") + + +def test_pg_do_ping_returns_false_on_dead_connection(): + from unittest.mock import MagicMock + native = MagicMock(name="native_psycopg") + native.autocommit = True + native.execute.side_effect = Exception("connection is closed") + wrapper = MagicMock(name="AwsWrapperConnection") + wrapper.target_connection = native + + dialect = AwsWrapperPGPsycopgDialect() + assert dialect.do_ping(wrapper) is False diff --git a/tests/unit/test_transient_connect.py b/tests/unit/test_transient_connect.py new file mode 100644 index 000000000..68d860dbf --- /dev/null +++ b/tests/unit/test_transient_connect.py @@ -0,0 +1,93 @@ +# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). +# You may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Unit tests for transient connect-error classification.""" + +from __future__ import annotations + +import pytest + +from aws_advanced_python_wrapper.utils.transient_connect import \ + is_transient_connect_error + + +class _PgError(Exception): + """Mimics psycopg.Error's attribute shape (sqlstate may be None).""" + + def __init__(self, message: str, sqlstate=None): + super().__init__(message) + self.sqlstate = sqlstate + + +class _MysqlError(Exception): + """Mimics mysql-connector / pymysql error shape (errno + sqlstate).""" + + def __init__(self, message: str, errno=None, sqlstate=None): + super().__init__(message) + self.errno = errno + self.sqlstate = sqlstate + + +# ───── PostgreSQL ───────────────────────────────────────────────────── +@pytest.mark.parametrize("sqlstate", ["08006", "08001", "08003", "08P01"]) +def test_pg_class_08_is_transient(sqlstate): + assert is_transient_connect_error(_PgError("boom", sqlstate=sqlstate)) + + +@pytest.mark.parametrize("sqlstate", ["57P01", "57P02", "57P03"]) +def test_pg_admin_shutdown_codes_transient(sqlstate): + assert is_transient_connect_error(_PgError("starting up", sqlstate=sqlstate)) + + +def test_pg_database_dropped_not_transient(): + # 57P04 is database_dropped -- permanent, must NOT retry. + assert not is_transient_connect_error(_PgError("db dropped", sqlstate="57P04")) + + +@pytest.mark.parametrize("msg", [ + "connection failed: connection to server at \"10.0.0.1\" failed: " + "server closed the connection unexpectedly", + "consuming input failed: SSL error: unexpected eof while reading", + "the connection is closed", + "connection socket closed", +]) +def test_pg_wire_messages_transient(msg): + # libpq wire errors arrive with no SQLSTATE -- classified by message. + assert is_transient_connect_error(_PgError(msg, sqlstate=None)) + + +def test_pg_connect_timeout_is_transient(): + # Regression: psycopg raises ConnectionTimeout("connection timeout + # expired") with NO sqlstate while Aurora promotes a new writer. Must be + # transient so retry/poll loops keep waiting instead of bailing early. + assert is_transient_connect_error( + _PgError("connection timeout expired", sqlstate=None)) + + +def test_pg_auth_failure_not_transient(): + # Credential misconfiguration must fail fast (28P01 = invalid_password). + assert not is_transient_connect_error( + _PgError("password authentication failed for user", sqlstate="28P01")) + + +# ───── MySQL ────────────────────────────────────────────────────────── +@pytest.mark.parametrize("errno", [2002, 2003, 2006, 2013, 2055]) +def test_mysql_network_errnos_transient(errno): + assert is_transient_connect_error(_MysqlError("net", errno=errno)) + + +def test_mysql_access_denied_not_transient(): + # 1045 = ER_ACCESS_DENIED_ERROR -- a credential error, not transient. + assert not is_transient_connect_error( + _MysqlError("Access denied for user", errno=1045, sqlstate="28000"))