")
+ def get_user(user_id: str):
+ return {"id": user_id, "name": "John"}
+
+ def handler(event, context):
+ return app.resolve(event, context)
+ ```
+
+=== "functions/orders/handler.py"
+
+ ```python
+ from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/orders")
+ def list_orders():
+ return {"orders": []}
+
+ @app.post("/orders")
+ def create_order():
+ return {"id": "order-123"}
+
+ def handler(event, context):
+ return app.resolve(event, context)
+ ```
+
+To generate a unified OpenAPI schema, you have two options:
+
+=== "Option 1: CI/CD script"
+
+ Generate `openapi.json` at build time:
+
+ ```python
+ # scripts/generate_openapi.py
+ from pathlib import Path
+ from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+ merge = OpenAPIMerge(
+ title="My API",
+ version="1.0.0",
+ description="Unified API documentation",
+ )
+
+ merge.discover(
+ path="./functions",
+ pattern="handler.py",
+ exclude=["**/docs/**"], # Exclude the docs Lambda
+ recursive=True,
+ )
+
+ output = Path("openapi.json")
+ output.write_text(merge.get_openapi_json_schema())
+ print(f"Generated {output}")
+ ```
+
+=== "Option 2: Dedicated docs Lambda"
+
+ Serve Swagger UI from a dedicated Lambda:
+
+ ```python
+ # functions/docs/handler.py
+ from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+ app = APIGatewayRestResolver()
+
+ app.configure_openapi_merge(
+ path="../", # Parent directory containing other handlers
+ pattern="handler.py",
+ exclude=["**/docs/**"],
+ recursive=True,
+ title="My API",
+ version="1.0.0",
+ )
+
+ app.enable_swagger(path="/")
+
+ def handler(event, context):
+ return app.resolve(event, context)
+ ```
+
+### Standalone class
+
+Use `OpenAPIMerge` class to generate schemas. This is pure Python code where you control the paths and output.
+
+=== "openapi_merge_standalone.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_standalone.py"
+ ```
+
+=== "openapi_merge_with_exclusions.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_with_exclusions.py"
+ ```
+
+=== "openapi_merge_multiple_patterns.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_multiple_patterns.py"
+ ```
+
+### Resolver integration
+
+Use `configure_openapi_merge()` on any resolver to serve merged schemas via Swagger UI. This is useful when you want a dedicated Lambda to serve the unified documentation.
+
+=== "openapi_merge_resolver.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_resolver.py"
+ ```
+
+???+ warning "Routes from other Lambdas are documentation only"
+ The merged schema includes routes from all discovered handlers for documentation purposes. However, only routes defined in the current Lambda are actually executable. Other routes exist only in the OpenAPI spec - unless you configure API Gateway to route them to their respective Lambdas.
+
+### Shared resolver pattern
+
+In some architectures, instead of each handler file defining its own resolver, you have a central resolver file that is imported by multiple route files. Each route file registers its routes on the shared resolver instance.
+
+```text
+src/
+├── myapp/
+│ ├── resolver.py # Defines: app = APIGatewayRestResolver()
+│ ├── users_routes.py # Imports app, registers /users routes
+│ ├── orders_routes.py # Imports app, registers /orders routes
+│ └── payments_routes.py # Imports app, registers /payments routes
+```
+
+OpenAPI Merge automatically detects this pattern. When you point `discover()` to the resolver file, it finds all files that import from it and loads them to ensure all routes are registered before extracting the schema.
+
+=== "shared_resolver.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_shared_resolver.py"
+ ```
+
+=== "shared_users_routes.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_shared_users_routes.py"
+ ```
+
+=== "shared_orders_routes.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_shared_orders_routes.py"
+ ```
+
+=== "Discovery"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_shared_discovery.py"
+ ```
+
+### Conflict handling
+
+When the same path+method is defined in multiple handlers, use `on_conflict` to control behavior:
+
+| Strategy | Behavior |
+| -------- | -------- |
+| `warn` (default) | Log warning, keep first definition |
+| `error` | Raise `OpenAPIMergeError` |
+| `first` | Silently keep first definition |
+| `last` | Use last definition (override) |
+
+=== "openapi_merge_conflict.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_conflict.py"
+ ```
+
+### Full configuration
+
+=== "openapi_merge_full_config.py"
+
+ ```python
+ --8<-- "examples/event_handler_rest/src/openapi_merge_full_config.py"
+ ```
diff --git a/docs/includes/_layer_homepage_arm64.md b/docs/includes/_layer_homepage_arm64.md
index 8c6437a47ca..e40a04078ec 100644
--- a/docs/includes/_layer_homepage_arm64.md
+++ b/docs/includes/_layer_homepage_arm64.md
@@ -6,178 +6,168 @@
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-arm64:33**{: .copyMe} |
=== "Python 3.11"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-arm64:33**{: .copyMe} |
=== "Python 3.12"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33**{: .copyMe} |
=== "Python 3.13"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-arm64:33**{: .copyMe} |
=== "Python 3.14"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-arm64:33**{: .copyMe} |
diff --git a/docs/includes/_layer_homepage_x86.md b/docs/includes/_layer_homepage_x86.md
index 7160f26f385..907788332f7 100644
--- a/docs/includes/_layer_homepage_x86.md
+++ b/docs/includes/_layer_homepage_x86.md
@@ -5,183 +5,173 @@
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python310-x86_64:33**{: .copyMe} |
=== "Python 3.11"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python311-x86_64:33**{: .copyMe} |
=== "Python 3.12"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33**{: .copyMe} |
=== "Python 3.13"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33**{: .copyMe} |
=== "Python 3.14"
| Region | Layer ARN |
| -------------------- | --------------------------------------------------------------------------------------------------------- |
- | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
- | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:30**{: .copyMe} |
+ | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-5`** | **arn:aws:lambda:ap-southeast-5:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ap-southeast-7`** | **arn:aws:lambda:ap-southeast-7:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`mx-central-1`** | **arn:aws:lambda:mx-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
+ | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV3-python314-x86_64:33**{: .copyMe} |
diff --git a/docs/lambda-features/durable-functions.md b/docs/lambda-features/durable-functions.md
new file mode 100644
index 00000000000..9a2e6f9b831
--- /dev/null
+++ b/docs/lambda-features/durable-functions.md
@@ -0,0 +1,151 @@
+---
+title: Durable Functions
+description: Using Powertools for AWS Lambda (Python) with Lambda Durable Functions
+---
+
+
+
+[Lambda Durable Functions](https://docs.aws.amazon.com/lambda/latest/dg/durable-functions.html){target="_blank" rel="nofollow"} enable you to build resilient multi-step workflows that can execute for up to one year. They use checkpoints to track progress and automatically recover from failures through replay.
+
+## Key concepts
+
+| Concept | Description |
+| --------------------- | ------------------------------------------------------------------ |
+| **Durable execution** | Complete lifecycle of a durable function, from start to completion |
+| **Checkpoint** | Saved state that tracks progress through the workflow |
+| **Replay** | Re-execution from the beginning, skipping completed checkpoints |
+| **Step** | Business logic with built-in retries and progress tracking |
+| **Wait** | Suspend execution without incurring compute charges |
+
+## How it works
+
+Durable functions use a **checkpoint/replay mechanism**:
+
+1. Your code runs always from the beginning
+2. Completed operations are skipped using stored results
+3. Execution of new steps continues from where it left off
+4. State is automatically managed by the SDK
+
+## Powertools integration
+
+Powertools for AWS Lambda (Python) works seamlessly with Durable Functions. The [Durable Execution SDK](https://github.com/aws/aws-durable-execution-sdk-python){target="_blank" rel="nofollow"} has native integration with Logger via `context.set_logger()`.
+
+???+ note "Found an issue?"
+ If you encounter any issues using Powertools for AWS Lambda (Python) with Durable Functions, please [open an issue](https://github.com/aws-powertools/powertools-lambda-python/issues/new?template=bug_report.yml){target="_blank"}.
+
+### Logger
+
+The Durable Execution SDK provides a `context.logger` instance that automatically handles **log deduplication during replays**. You can integrate Logger to get structured JSON logging while keeping the deduplication benefits.
+
+For the best experience, set the Logger on the durable context. This gives you structured JSON logging with automatic log deduplication during replays:
+
+```python hl_lines="5 8 12 15" title="Integrating Logger with Durable Functions"
+--8<-- "examples/lambda_features/durable_functions/src/using_logger.py"
+```
+
+This gives you:
+
+- **JSON structured logging** from Powertools for AWS Lambda (Python)
+- **Log deduplication** during replays (logs from completed operations don't repeat)
+- **Automatic SDK enrichment** (execution_arn, parent_id, name, attempt)
+- **Lambda context injection** (request_id, function_name, etc.)
+
+???+ warning "Direct logger usage"
+ If you use the Logger directly (not through `context.logger`), logs will be emitted on every replay:
+
+ ```python
+ # Logs will duplicate during replays
+ logger.info("This appears on every replay")
+
+ # Use context.logger instead for deduplication
+ context.logger.info("This appears only once")
+ ```
+
+### Tracer
+
+Tracer works with Durable Functions. Each execution creates trace segments.
+
+???+ note "Trace continuity"
+ Due to the replay mechanism, traces may be interleaved. Each execution (including replays) creates separate trace segments. Use the `execution_arn` to correlate traces.
+
+```python hl_lines="5-6 9-10" title="Using Tracer with Durable Functions"
+--8<-- "examples/lambda_features/durable_functions/src/using_tracer.py"
+```
+
+### Metrics
+
+Metrics work with Durable Functions, but be aware that **metrics may be emitted multiple times** during replay if not handled carefully. Emit metrics at workflow completion rather than during intermediate steps to avoid counting replays as new executions.
+
+```python hl_lines="6 9 18 19 20 21" title="Using Metrics with Durable Functions"
+--8<-- "examples/lambda_features/durable_functions/src/best_practice_metrics.py"
+```
+
+### Idempotency
+
+The `@idempotent` decorator integrates with Durable Functions and is **replay-aware**. It's useful for protecting the Lambda handler entry point, especially for Event Source Mapping (ESM) invocations like SQS, Kinesis, or DynamoDB Streams.
+
+```python hl_lines="8 15" title="Using Idempotency with Durable Functions"
+--8<-- "examples/lambda_features/durable_functions/src/using_idempotency.py"
+```
+
+???+ warning "Decorator ordering matters"
+ The `@idempotent` decorator must be placed **above** `@durable_execution`. This ensures the idempotency check runs first, preventing duplicate executions before the durable workflow begins. Reversing the order would cause the durable execution to start before the idempotency check, defeating its purpose.
+
+**When to use Powertools Idempotency:**
+
+- Protecting the Lambda handler entry point from duplicate invocations
+- Methods you don't want to convert into steps but need idempotency guarantees
+- Event Source Mapping triggers (SQS, Kinesis, DynamoDB Streams)
+
+**When you don't need it:**
+
+- Steps within a durable function are already idempotent via the checkpoint mechanism
+
+### Parameters
+
+Parameters work normally with Durable Functions.
+
+```python hl_lines="13" title="Using Parameters with Durable Functions"
+--8<-- "examples/lambda_features/durable_functions/src/using_parameters.py"
+```
+
+???+ note "Parameter freshness"
+ If the replay or execution happens within the cache TTL on the same execution environment, the parameter value may come from cache. For long-running workflows (hours/days), parameters fetched at the start may become stale. Consider fetching parameters within steps that need the latest values, and customize the caching behavior with `max_age` to control freshness.
+
+## Best practices
+
+### Use Idempotency for ESM triggers
+
+When your durable function is triggered by Event Source Mappings (SQS, Kinesis, DynamoDB Streams), use the `@idempotent` decorator to protect against duplicate invocations.
+
+```python title="Idempotency for ESM"
+--8<-- "examples/lambda_features/durable_functions/src/best_practice_idempotency.py"
+```
+
+## FAQ
+
+### Do I need Idempotency utility with Durable Functions?
+
+It depends on your use case. Steps within a durable function are already idempotent via checkpoints. However, the `@idempotent` decorator is useful for protecting the Lambda handler entry point, especially for Event Source Mapping invocations (SQS, Kinesis, DynamoDB Streams) where the same event might trigger multiple invocations.
+
+### Why do I see duplicate logs?
+
+If you're using the logger directly instead of `context.logger`, logs will be emitted on every replay. Use `context.set_logger(logger)` and then `context.logger.info()` to get automatic log deduplication.
+
+### How do I correlate logs across replays?
+
+Use the `execution_arn` field that's automatically added to every log entry when using `context.logger`:
+
+```sql
+fields @timestamp, @message, execution_arn
+| filter execution_arn = "arn:aws:lambda:us-east-1:123456789012:function:my-function:execution-id"
+| sort @timestamp asc
+```
+
+### Can I use Tracer with Durable Functions?
+
+Yes, but be aware that each execution (including replays) creates separate trace segments. Use the `execution_arn` as a correlation identifier for end-to-end visibility.
+
+### How should I emit metrics without duplicates?
+
+Emit metrics at workflow completion rather than during intermediate steps. This ensures you count completed workflows, not replay attempts.
diff --git a/docs/lambda-features/index.md b/docs/lambda-features/index.md
new file mode 100644
index 00000000000..30d791c8601
--- /dev/null
+++ b/docs/lambda-features/index.md
@@ -0,0 +1,28 @@
+---
+title: Lambda Features
+description: Using Powertools with advanced Lambda features
+---
+
+
+
+This section covers how to use Powertools for AWS Lambda (Python) with advanced Lambda features like Lambda Managed Instances and Durable Functions.
+
+
+
+- :material-server:{ .lg .middle } __Lambda Managed Instances__
+
+ ---
+
+ Run Lambda functions on EC2 instances with multi-concurrent invocations
+
+ [:octicons-arrow-right-24: Getting started](./managed-instances.md)
+
+- :material-state-machine:{ .lg .middle } __Durable Functions__
+
+ ---
+
+ Build resilient multi-step workflows that can execute for up to one year
+
+ [:octicons-arrow-right-24: Getting started](./durable-functions.md)
+
+
diff --git a/docs/lambda-features/managed-instances.md b/docs/lambda-features/managed-instances.md
new file mode 100644
index 00000000000..38779673a7f
--- /dev/null
+++ b/docs/lambda-features/managed-instances.md
@@ -0,0 +1,102 @@
+---
+title: Lambda Managed Instances
+description: Using Powertools for AWS Lambda (Python) with Lambda Managed Instances
+---
+
+
+
+[Lambda Managed Instances](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html){target="_blank" rel="nofollow"} enables you to run Lambda functions on Amazon EC2 instances without managing infrastructure. It supports multi-concurrent invocations, EC2 pricing models, and specialized compute options like Graviton4.
+
+## Key differences from Lambda On Demand
+
+| Aspect | Lambda On Demand | Lambda Managed Instances |
+| ---------------- | ------------------------------------------- | ----------------------------------------------- |
+| **Concurrency** | Single invocation per execution environment | Multiple concurrent invocations per environment |
+| **Python model** | One process, one request | Multiple processes, one request each |
+| **Pricing** | Per-request duration | EC2-based with Savings Plans support |
+| **Scaling** | Scale on demand with cold starts | Async scaling based on CPU |
+| **Isolation** | Firecracker microVMs | Containers on EC2 Nitro |
+
+## How Lambda Python runtime handles concurrency
+
+The **Lambda Python runtime uses multiple processes** for concurrent requests. Each request runs in a separate process, which provides natural isolation between requests.
+
+This means:
+
+- **Each process has its own memory** - global variables are isolated per process
+- **`/tmp` directory is shared** across all processes - use caution with file operations
+
+For more details on the isolation model, see [Lambda Managed Instances documentation](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances.html){target="_blank" rel="nofollow"}.
+
+## Powertools integration
+
+Powertools for AWS Lambda (Python) works seamlessly with Lambda Managed Instances. All utilities are compatible with the multi-process concurrency model used by Python.
+
+### Logger, Tracer, and Metrics
+
+Core utilities work without any changes. Each process has its own instances, so correlation IDs and traces are naturally isolated per request.
+
+???+ note "VPC connectivity required"
+ Lambda Managed Instances run in your VPC. Ensure you have [network connectivity](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances-networking.html){target="_blank" rel="nofollow"} to send logs to CloudWatch, traces to X-Ray, and metrics to CloudWatch.
+
+```python hl_lines="5 6 7 10 11 12 20 25" title="Using Logger, Tracer, and Metrics with Managed Instances"
+--8<-- "examples/lambda_features/managed_instances/src/using_tracer.py"
+```
+
+### Parameters
+
+The Parameters utility works as expected, but be aware that **caching is per-process**.
+
+```python hl_lines="9" title="Using Parameters with Managed Instances"
+--8<-- "examples/lambda_features/managed_instances/src/using_parameters.py"
+```
+
+???+ tip "Cache behavior"
+ Since each process has its own cache, you might see more calls to SSM/Secrets Manager during initial warm-up. Once each process has cached the value, subsequent requests within that process use the cache. You can customize the caching behavior with `max_age` to control the TTL.
+
+### Idempotency
+
+Idempotency works without any changes. It uses DynamoDB for state management, which is external to the process.
+
+```python hl_lines="7 10" title="Using Idempotency with Managed Instances"
+--8<-- "examples/lambda_features/managed_instances/src/using_idempotency.py"
+```
+
+## VPC connectivity
+
+Lambda Managed Instances require VPC configuration for:
+
+- Sending logs to CloudWatch Logs
+- Sending traces to X-Ray
+- Accessing AWS services (SSM, Secrets Manager, DynamoDB, etc.)
+
+Configure connectivity using one of these options:
+
+1. **VPC Endpoints** - Private connectivity without internet access
+2. **NAT Gateway** - Internet access from private subnets
+3. **Public subnet with Internet Gateway** - Direct internet access
+4. **Egress-only Internet Gateway** - IPv6 outbound connectivity without inbound access ([learn more](https://docs.aws.amazon.com/vpc/latest/userguide/egress-only-internet-gateway.html){target="_blank" rel="nofollow"})
+
+See [Networking for Lambda Managed Instances](https://docs.aws.amazon.com/lambda/latest/dg/lambda-managed-instances-networking.html){target="_blank" rel="nofollow"} for detailed setup instructions.
+
+## FAQ
+
+### Does Powertools for AWS Lambda (Python) work with Lambda Managed Instances?
+
+Yes, all Powertools for AWS Lambda (Python) utilities work seamlessly with Lambda Managed Instances. The multi-process model in Python provides natural isolation between concurrent requests.
+
+### Is my code thread-safe?
+
+Lambda Managed Instances uses **multiple processes**, instead of threads. Each request runs in its own process with isolated memory. If you implement multi-threading within your handler, you are responsible for thread safety.
+
+### Why is my cache not shared between requests?
+
+Each process maintains its own cache (for Parameters, Feature Flags, etc.). This is expected behavior. The cache will warm up independently per process, which may result in slightly more calls to backend services during initial warm-up.
+
+### Can I use global variables?
+
+Yes, but remember they are **per-process**, not shared across concurrent requests. This is actually safer than shared state.
+
+### Do I need to change my existing Powertools for AWS Lambda (Python) code?
+
+No changes are required if you are running Powertools for AWS Lambda (Python) version **3.4.0** or later. Your existing code will work as-is with Lambda Managed Instances.
diff --git a/docs/requirements.txt b/docs/requirements.txt
index d1113254b7d..a7b731a7d5a 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -139,17 +139,17 @@ gitdb==4.0.12 \
--hash=sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571 \
--hash=sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf
# via gitpython
-gitpython==3.1.44 \
- --hash=sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110 \
- --hash=sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269
+gitpython==3.1.50 \
+ --hash=sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc \
+ --hash=sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9
# via mkdocs-git-revision-date-plugin
griffe==1.13.0 \
--hash=sha256:246ea436a5e78f7fbf5f24ca8a727bb4d2a4b442a2959052eea3d0bfe9a076e0 \
--hash=sha256:470fde5b735625ac0a36296cd194617f039e9e83e301fcbd493e2b58382d0559
# via mkdocstrings-python
-idna==3.10 \
- --hash=sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9 \
- --hash=sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3
+idna==3.15 \
+ --hash=sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8 \
+ --hash=sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc
# via requests
jinja2==3.1.6 \
--hash=sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d \
@@ -283,15 +283,15 @@ mkdocs-get-deps==0.2.0 \
# via mkdocs
mkdocs-git-revision-date-plugin==0.3.2 \
--hash=sha256:2e67956cb01823dd2418e2833f3623dee8604cdf223bddd005fe36226a56f6ef
- # via -r docs/requirements.in
+ # via -r requirements.in
mkdocs-llmstxt==0.5.0 \
--hash=sha256:753c699913d2d619a9072604b26b6dc9f5fb6d257d9b107857f80c8a0b787533 \
--hash=sha256:b2fa9e6d68df41d7467e948a4745725b6c99434a36b36204857dbd7bb3dfe041
- # via -r docs/requirements.in
+ # via -r requirements.in
mkdocs-material==9.7.6 \
--hash=sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69 \
--hash=sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba
- # via -r docs/requirements.in
+ # via -r requirements.in
mkdocs-material-extensions==1.3.1 \
--hash=sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443 \
--hash=sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31
@@ -303,7 +303,7 @@ mkdocstrings==0.30.0 \
mkdocstrings-python==1.19.0 \
--hash=sha256:395c1032af8f005234170575cc0c5d4d20980846623b623b35594281be4a3059 \
--hash=sha256:917aac66cf121243c11db5b89f66b0ded6c53ec0de5318ff5e22424eb2f2e57c
- # via -r docs/requirements.in
+ # via -r requirements.in
packaging==25.0 \
--hash=sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 \
--hash=sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f
@@ -324,9 +324,9 @@ pygments==2.19.2 \
--hash=sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887 \
--hash=sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b
# via mkdocs-material
-pymdown-extensions==10.16.1 \
- --hash=sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91 \
- --hash=sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d
+pymdown-extensions==10.21.3 \
+ --hash=sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354 \
+ --hash=sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6
# via
# mkdocs-material
# mkdocstrings
@@ -397,9 +397,9 @@ pyyaml-env-tag==1.1 \
--hash=sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04 \
--hash=sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff
# via mkdocs
-requests==2.32.4 \
- --hash=sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c \
- --hash=sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422
+requests==2.33.0 \
+ --hash=sha256:3324635456fa185245e24865e810cecec7b4caf933d7eb133dcde67d48cee69b \
+ --hash=sha256:c7ebc5e8b0f21837386ad0e1c8fe8b829fa5f544d8df3b2253bff14ef29d7652
# via mkdocs-material
six==1.17.0 \
--hash=sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274 \
@@ -415,64 +415,13 @@ soupsieve==2.7 \
--hash=sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4 \
--hash=sha256:ad282f9b6926286d2ead4750552c8a6142bc4c783fd66b0293547c8fe6ae126a
# via beautifulsoup4
-tomli==2.4.0 \
- --hash=sha256:0408e3de5ec77cc7f81960c362543cbbd91ef883e3138e81b729fc3eea5b9729 \
- --hash=sha256:0dc56fef0e2c1c470aeac5b6ca8cc7b640bb93e92d9803ddaf9ea03e198f5b0b \
- --hash=sha256:0e0fe8a0b8312acf3a88077a0802565cb09ee34107813bba1c7cd591fa6cfc8d \
- --hash=sha256:0f2e3955efea4d1cfbcb87bc321e00dc08d2bcb737fd1d5e398af111d86db5df \
- --hash=sha256:133e93646ec4300d651839d382d63edff11d8978be23da4cc106f5a18b7d0576 \
- --hash=sha256:1b168f2731796b045128c45982d3a4874057626da0e2ef1fdd722848b741361d \
- --hash=sha256:1c8a885b370751837c029ef9bc014f27d80840e48bac415f3412e6593bbc18c1 \
- --hash=sha256:1f776e7d669ebceb01dee46484485f43a4048746235e683bcdffacdf1fb4785a \
- --hash=sha256:1fb2945cbe303b1419e2706e711b7113da57b7db31ee378d08712d678a34e51e \
- --hash=sha256:20cedb4ee43278bc4f2fee6cb50daec836959aadaf948db5172e776dd3d993fc \
- --hash=sha256:20ffd184fb1df76a66e34bd1b36b4a4641bd2b82954befa32fe8163e79f1a702 \
- --hash=sha256:26ab906a1eb794cd4e103691daa23d95c6919cc2fa9160000ac02370cc9dd3f6 \
- --hash=sha256:2add28aacc7425117ff6364fe9e06a183bb0251b03f986df0e78e974047571fd \
- --hash=sha256:2b1e3b80e1d5e52e40e9b924ec43d81570f0e7d09d11081b797bc4692765a3d4 \
- --hash=sha256:31d556d079d72db7c584c0627ff3a24c5d3fb4f730221d3444f3efb1b2514776 \
- --hash=sha256:36b9d05b51e65b254ea6c2585b59d2c4cb91c8a3d91d0ed0f17591a29aaea54a \
- --hash=sha256:39b0b5d1b6dd03684b3fb276407ebed7090bbec989fa55838c98560c01113b66 \
- --hash=sha256:3cf226acb51d8f1c394c1b310e0e0e61fecdd7adcb78d01e294ac297dd2e7f87 \
- --hash=sha256:3d895d56bd3f82ddd6faaff993c275efc2ff38e52322ea264122d72729dca2b2 \
- --hash=sha256:413540dce94673591859c4c6f794dfeaa845e98bf35d72ed59636f869ef9f86f \
- --hash=sha256:43e685b9b2341681907759cf3a04e14d7104b3580f808cfde1dfdb60ada85475 \
- --hash=sha256:4cbcb367d44a1f0c2be408758b43e1ffb5308abe0ea222897d6bfc8e8281ef2f \
- --hash=sha256:551e321c6ba03b55676970b47cb1b73f14a0a4dce6a3e1a9458fd6d921d72e95 \
- --hash=sha256:5572e41282d5268eb09a697c89a7bee84fae66511f87533a6f88bd2f7b652da9 \
- --hash=sha256:5aa48d7c2356055feef06a43611fc401a07337d5b006be13a30f6c58f869e3c3 \
- --hash=sha256:5b5807f3999fb66776dbce568cc9a828544244a8eb84b84b9bafc080c99597b9 \
- --hash=sha256:5e3f639a7a8f10069d0e15408c0b96a2a828cfdec6fca05296ebcdcc28ca7c76 \
- --hash=sha256:685306e2cc7da35be4ee914fd34ab801a6acacb061b6a7abca922aaf9ad368da \
- --hash=sha256:75c2f8bbddf170e8effc98f5e9084a8751f8174ea6ccf4fca5398436e0320bc8 \
- --hash=sha256:7b438885858efd5be02a9a133caf5812b8776ee0c969fea02c45e8e3f296ba51 \
- --hash=sha256:7d49c66a7d5e56ac959cb6fc583aff0651094ec071ba9ad43df785abc2320d86 \
- --hash=sha256:7d6d9a4aee98fac3eab4952ad1d73aee87359452d1c086b5ceb43ed02ddb16b8 \
- --hash=sha256:84d081fbc252d1b6a982e1870660e7330fb8f90f676f6e78b052ad4e64714bf0 \
- --hash=sha256:8768715ffc41f0008abe25d808c20c3d990f42b6e2e58305d5da280ae7d1fa3b \
- --hash=sha256:920b1de295e72887bafa3ad9f7a792f811847d57ea6b1215154030cf131f16b1 \
- --hash=sha256:9a08144fa4cba33db5255f9b74f0b89888622109bd2776148f2597447f92a94e \
- --hash=sha256:a26d7ff68dfdb9f87a016ecfd1e1c2bacbe3108f4e0f8bcd2228ef9a766c787d \
- --hash=sha256:aa89c3f6c277dd275d8e243ad24f3b5e701491a860d5121f2cdd399fbb31fc9c \
- --hash=sha256:b5ef256a3fd497d4973c11bf142e9ed78b150d36f5773f1ca6088c230ffc5867 \
- --hash=sha256:b6c78bdf37764092d369722d9946cb65b8767bfa4110f902a1b2542d8d173c8a \
- --hash=sha256:bbb1b10aa643d973366dc2cb1ad94f99c1726a02343d43cbc011edbfac579e7c \
- --hash=sha256:c084ad935abe686bd9c898e62a02a19abfc9760b5a79bc29644463eaf2840cb0 \
- --hash=sha256:c73add4bb52a206fd0c0723432db123c0c75c280cbd67174dd9d2db228ebb1b4 \
- --hash=sha256:cae9c19ed12d4e8f3ebf46d1a75090e4c0dc16271c5bce1c833ac168f08fb614 \
- --hash=sha256:d20b797a5c1ad80c516e41bc1fb0443ddb5006e9aaa7bda2d71978346aeb9132 \
- --hash=sha256:d3d1654e11d724760cdb37a3d7691f0be9db5fbdaef59c9f532aabf87006dbaa \
- --hash=sha256:d878f2a6707cc9d53a1be1414bbb419e629c3d6e67f69230217bb663e76b5087
- # via mdformat
typing-extensions==4.14.0 \
--hash=sha256:8676b788e32f02ab42d9e7c61324048ae4c6d844a399eebace3d4979d75ceef4 \
--hash=sha256:a1514509136dd0b477638fc68d6a91497af5076466ad0fa6c338e44e359944af
- # via
- # beautifulsoup4
- # mkdocstrings-python
-urllib3==2.6.3 \
- --hash=sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed \
- --hash=sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4
+ # via beautifulsoup4
+urllib3==2.7.0 \
+ --hash=sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c \
+ --hash=sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897
# via requests
watchdog==6.0.0 \
--hash=sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a \
diff --git a/docs/utilities/metadata.md b/docs/utilities/metadata.md
index b1154d4cecd..4959d81d8c7 100644
--- a/docs/utilities/metadata.md
+++ b/docs/utilities/metadata.md
@@ -6,7 +6,7 @@ status: new
-The Metadata utility allows you to fetch data from the [AWS Lambda Metadata Endpoint (LMDS)](https://docs.aws.amazon.com/lambda/latest/dg/lambda-metadata-endpoint.html){target="_blank"}. This can be useful for retrieving information about the Lambda execution environment, such as the Availability Zone ID.
+The Metadata utility allows you to fetch data from the [AWS Lambda Metadata Endpoint (LMDS)](https://docs.aws.amazon.com/lambda/latest/dg/configuration-metadata-endpoint.html){target="_blank"}. This can be useful for retrieving information about the Lambda execution environment, such as the Availability Zone ID.
## Key features
diff --git a/docs/we_made_this.md b/docs/we_made_this.md
index db3dc8a23b1..07370d53d9e 100644
--- a/docs/we_made_this.md
+++ b/docs/we_made_this.md
@@ -35,29 +35,29 @@ GitHub: [https://github.com/serverless-dna/powertools-mcp](https://github.com/se
A collection of articles explaining in detail how Powertools for AWS Lambda helps with a Serverless adoption strategy and its challenges.
-* [Part 1 - Logging](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-elevate-your-handler-s-code-part-1-logging){target="_blank" rel="nofollow"}
+* [Part 1 - Logging](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-elevate-your-handler-s-code-part-1-logging/){target="_blank" rel="nofollow"}
-* [Part 2 - Observability: monitoring and tracing](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-elevate-your-handler-s-code-part-2-observability){target="_blank" rel="nofollow"}
+* [Part 2 - Observability: monitoring and tracing](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-elevate-your-handler-s-code-part-2-observability/){target="_blank" rel="nofollow"}
-* [Part 3 - Business Domain Observability](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-elevate-your-handler-s-code-part-3-business-domain-observability){target="_blank" rel="nofollow"}
+* [Part 3 - Business Domain Observability](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-elevate-your-handler-s-code-part-3-business-domain-observability/){target="_blank" rel="nofollow"}
-* [Part 4 - Environment Variables](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-environment-variables){target="_blank" rel="nofollow"}
+* [Part 4 - Environment Variables](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-environment-variables/){target="_blank" rel="nofollow"}
-* [Part 5 - Input Validation](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-elevate-your-handler-s-code-part-5-input-validation){target="_blank" rel="nofollow"}
+* [Part 5 - Input Validation](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-elevate-your-handler-s-code-part-5-input-validation/){target="_blank" rel="nofollow"}
-* [Part 6 - Configuration & Feature Flags](https://www.ranthebuilder.cloud/post/aws-lambda-cookbook-part-6-feature-flags-configuration-best-practices){target="_blank" rel="nofollow"}
+* [Part 6 - Configuration & Feature Flags](https://ranthebuilder.cloud/blog/aws-lambda-cookbook-part-6-feature-flags-configuration-best-practices/){target="_blank" rel="nofollow"}
-* [Serverless API Idempotency with AWS Powertools for AWS Lambda and CDK](https://www.ranthebuilder.cloud/post/serverless-api-idempotency-with-aws-lambda-powertools-and-cdk){target="_blank" rel="nofollow"}
+* [Serverless API Idempotency with AWS Powertools for AWS Lambda and CDK](https://ranthebuilder.cloud/blog/serverless-api-idempotency-with-aws-lambda-powertools-and-cdk/){target="_blank" rel="nofollow"}
-* [Effective Amazon SQS Batch Handling with Powertools for AWS Lambda (Python)](https://www.ranthebuilder.cloud/post/effective-amazon-sqs-batch-handling-with-aws-lambda-powertools){target="_blank" rel="nofollow"}
+* [Effective Amazon SQS Batch Handling with Powertools for AWS Lambda (Python)](https://ranthebuilder.cloud/blog/effective-amazon-sqs-batch-handling-with-aws-lambda-powertools/){target="_blank" rel="nofollow"}
-* [Serverless API Documentation with Powertools for AWS Lambda](https://www.ranthebuilder.cloud/post/serverless-open-api-documentation-with-aws-powertools){:target="_blank"}
+* [Serverless API Documentation with Powertools for AWS Lambda](https://ranthebuilder.cloud/blog/serverless-open-api-documentation-with-aws-powertools/){:target="_blank"}
* [Best practices for accelerating development with serverless blueprints](https://aws.amazon.com/blogs/infrastructure-and-automation/best-practices-for-accelerating-development-with-serverless-blueprints/){target="_blank" rel="nofollow"}
-* [Build a Chatbot with Amazon Bedrock: Automate API Calls Using Powertools for AWS Lambda and CDK](https://www.ranthebuilder.cloud/post/automating-api-calls-with-agents-for-amazon-bedrock-with-powertools){target="_blank" rel="nofollow"}
+* [Build a Chatbot with Amazon Bedrock: Automate API Calls Using Powertools for AWS Lambda and CDK](https://ranthebuilder.cloud/blog/automating-api-calls-with-agents-for-amazon-bedrock-with-powertools/){target="_blank" rel="nofollow"}
-* [Build Serverless WebSockets with AWS AppSync Events and Powertools for AWS Lambda](https://www.ranthebuilder.cloud/post/aws-appsync-events-and-powertools-for-aws-lambda){target="_blank" rel="nofollow"}
+* [Build Serverless WebSockets with AWS AppSync Events and Powertools for AWS Lambda](https://ranthebuilder.cloud/blog/aws-appsync-events-and-powertools-for-aws-lambda/){target="_blank" rel="nofollow"}
#### Lambda MCP Server Cookbook
@@ -138,7 +138,7 @@ This article will guide you through personalizing observability by integrating C
> **Author: [Nathan Hanks](https://www.linkedin.com/in/nathan-hanks-25151815/){target="_blank" rel="nofollow"}** :material-linkedin:
-[Creating a serverless API using Powertools for AWS Lambda and CDK](https://www.ranthebuilder.cloud/post/boost-app-engagement-with-aws-cloudwatch-metrics-powertools-for-aws){target="_blank" rel="nofollow"}
+[Creating a serverless API using Powertools for AWS Lambda and CDK](https://ranthebuilder.cloud/blog/boost-app-engagement-with-aws-cloudwatch-metrics-powertools-for-aws/){target="_blank" rel="nofollow"}
### Streaming data with AWS Lambda & Powertools for AWS Lambda
@@ -156,6 +156,14 @@ Learn to implement data masking in AWS Lambda with Powertools, protecting sensit
[Simplified Data Masking in AWS Lambda with Powertools](https://www.internetkatta.com/simplified-data-masking-in-aws-lambda-with-powertool){target="_blank" rel="nofollow"}
+### Stop writing Lambda boilerplate
+
+Introducing the [AWS Lambda Templates](https://github.com/amrabed/aws-lambda-templates){target="_blank"} repository — a collection of production-ready Python Lambda templates for Bedrock Agent, REST API, GraphQL, DynamoDB Stream, EventBridge, S3, and SQS scenarios, pre-wired with Powertools for AWS Lambda, AWS CDK, Pydantic, and a robust testing infrastructure.
+
+> **Author: [Amr Abed :material-linkedin:](https://www.linkedin.com/in/amrabed){target="_blank" rel="nofollow"}**
+
+[Stop Writing Lambda Boilerplate](https://builder.aws.com/content/3CDoe07m8JBNTQyzcrYWTWkfNPz/stop-writing-lambda-boilerplate){target="_blank" rel="nofollow"}
+
## Videos
#### Building a resilient input handling with Parser
@@ -192,7 +200,7 @@ Are you developing AWS Lambda functions with Python? Always looking for tools to
This session covers an opinionated approach to Python project setup, testing, profiling, deployments, and operations. Learn about many open source tools, including Powertools for AWS Lambda—a toolkit that can help you implement serverless best practices and increase developer velocity.
-Join to discover tools and patterns for effective serverless development with Python. To maximize your learning experience, the session includes a sample application that implements what’s described.
+Join to discover tools and patterns for effective serverless development with Python. To maximize your learning experience, the session includes a sample application that implements what's described.
diff --git a/examples/build_recipes/cdk/basic/app.py b/examples/build_recipes/cdk/basic/app.py
index f5d3d759ed8..6268d8e49c0 100644
--- a/examples/build_recipes/cdk/basic/app.py
+++ b/examples/build_recipes/cdk/basic/app.py
@@ -24,7 +24,7 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
powertools_layer = _lambda.LayerVersion.from_layer_version_arn(
self,
"PowertoolsLayer",
- layer_version_arn="arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30",
+ layer_version_arn="arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33",
)
# Lambda Function
diff --git a/examples/build_recipes/cdk/multi-stack/stacks/powertools_cdk_stack.py b/examples/build_recipes/cdk/multi-stack/stacks/powertools_cdk_stack.py
index 7bb1f3f578f..3c7a480adbe 100644
--- a/examples/build_recipes/cdk/multi-stack/stacks/powertools_cdk_stack.py
+++ b/examples/build_recipes/cdk/multi-stack/stacks/powertools_cdk_stack.py
@@ -47,7 +47,7 @@ def _create_powertools_layer(self) -> _lambda.ILayerVersion:
return _lambda.LayerVersion.from_layer_version_arn(
self,
"PowertoolsLayer",
- layer_version_arn="arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30",
+ layer_version_arn="arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33",
)
def _create_dynamodb_table(self) -> dynamodb.Table:
diff --git a/examples/build_recipes/sam/multi-env/template.yaml b/examples/build_recipes/sam/multi-env/template.yaml
index 636beea0d67..8babe94f382 100644
--- a/examples/build_recipes/sam/multi-env/template.yaml
+++ b/examples/build_recipes/sam/multi-env/template.yaml
@@ -61,7 +61,7 @@ Resources:
CodeUri: src/
Handler: app.lambda_handler
Layers:
- - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30
+ - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33
- !Ref DependenciesLayer
Events:
ApiEvent:
diff --git a/examples/build_recipes/sam/with-layers/template.yaml b/examples/build_recipes/sam/with-layers/template.yaml
index 9fac52a8127..fc9803b5a8a 100644
--- a/examples/build_recipes/sam/with-layers/template.yaml
+++ b/examples/build_recipes/sam/with-layers/template.yaml
@@ -31,7 +31,7 @@ Resources:
CodeUri: src/app/
Handler: app_sam_layer.lambda_handler
Layers:
- - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30
+ - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33
- !Ref DependenciesLayer
Events:
ApiEvent:
@@ -50,7 +50,7 @@ Resources:
CodeUri: src/worker/
Handler: worker_sam_layer.lambda_handler
Layers:
- - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:30
+ - arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python313-x86_64:33
- !Ref DependenciesLayer
Events:
SQSEvent:
diff --git a/examples/event_handler_graphql/src/requirements.txt b/examples/event_handler_graphql/src/requirements.txt
index 785ab54fc57..67f59e04d75 100644
--- a/examples/event_handler_graphql/src/requirements.txt
+++ b/examples/event_handler_graphql/src/requirements.txt
@@ -1,2 +1,2 @@
aws-lambda-powertools[tracer]
-requests>=2.32.0
+requests>=2.33.1
diff --git a/examples/event_handler_rest/src/async_resolve_all_resolvers.py b/examples/event_handler_rest/src/async_resolve_all_resolvers.py
new file mode 100644
index 00000000000..92149e1dc3c
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_all_resolvers.py
@@ -0,0 +1,31 @@
+import asyncio
+
+from aws_lambda_powertools.event_handler import (
+ ALBResolver,
+ APIGatewayHttpResolver,
+ APIGatewayRestResolver,
+)
+
+rest_app = APIGatewayRestResolver() # (1)!
+http_app = APIGatewayHttpResolver() # (2)!
+alb_app = ALBResolver() # (3)!
+
+
+@rest_app.get("/hello")
+@http_app.get("/hello")
+@alb_app.get("/hello")
+async def hello():
+ await asyncio.sleep(0)
+ return {"message": "hello from async"}
+
+
+def rest_handler(event, context):
+ return asyncio.run(rest_app.resolve_async(event, context))
+
+
+def http_handler(event, context):
+ return asyncio.run(http_app.resolve_async(event, context))
+
+
+def alb_handler(event, context):
+ return asyncio.run(alb_app.resolve_async(event, context))
diff --git a/examples/event_handler_rest/src/async_resolve_async_middleware.py b/examples/event_handler_rest/src/async_resolve_async_middleware.py
new file mode 100644
index 00000000000..e801a58b1f6
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_async_middleware.py
@@ -0,0 +1,29 @@
+import asyncio
+from collections.abc import Callable
+
+from aws_lambda_powertools import Logger
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response
+
+app = APIGatewayRestResolver()
+logger = Logger()
+
+
+async def async_inject_correlation_id(app: APIGatewayRestResolver, next_middleware: Callable) -> Response: # (1)!
+ request_id = app.current_event.request_context.request_id
+ app.append_context(correlation_id=request_id)
+ logger.set_correlation_id(request_id)
+
+ result = await next_middleware(app) # (2)!
+
+ result.headers["x-correlation-id"] = request_id
+ return result
+
+
+@app.get("/todos", middlewares=[async_inject_correlation_id])
+async def get_todos():
+ await asyncio.sleep(0)
+ return {"todos": []}
+
+
+def lambda_handler(event, context):
+ return asyncio.run(app.resolve_async(event, context))
diff --git a/examples/event_handler_rest/src/async_resolve_concurrent.py b/examples/event_handler_rest/src/async_resolve_concurrent.py
new file mode 100644
index 00000000000..868954d51c7
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_concurrent.py
@@ -0,0 +1,28 @@
+import asyncio
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+
+app = APIGatewayHttpResolver()
+
+
+async def fetch_profile(user_id: str) -> dict:
+ await asyncio.sleep(0) # simulate async I/O (e.g., DynamoDB, HTTP call)
+ return {"user_id": user_id, "name": "John"}
+
+
+async def fetch_orders(user_id: str) -> list:
+ await asyncio.sleep(0)
+ return [{"order_id": "123", "total": 99.99}]
+
+
+@app.get("/dashboard/")
+async def get_dashboard(user_id: str):
+ profile, orders = await asyncio.gather( # (1)!
+ fetch_profile(user_id),
+ fetch_orders(user_id),
+ )
+ return {"profile": profile, "orders": orders}
+
+
+def lambda_handler(event, context):
+ return asyncio.run(app.resolve_async(event, context))
diff --git a/examples/event_handler_rest/src/async_resolve_getting_started.py b/examples/event_handler_rest/src/async_resolve_getting_started.py
new file mode 100644
index 00000000000..40d9c2b9bec
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_getting_started.py
@@ -0,0 +1,21 @@
+import asyncio
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+
+app = APIGatewayHttpResolver()
+
+
+@app.get("/todos/")
+async def get_todo(todo_id: str): # (1)!
+ # Async handlers can use await for non-blocking I/O
+ await asyncio.sleep(0) # simulate async I/O
+ return {"todo_id": todo_id, "completed": False}
+
+
+@app.get("/health")
+def health(): # (2)!
+ return {"status": "ok"}
+
+
+def lambda_handler(event, context):
+ return asyncio.run(app.resolve_async(event, context)) # (3)!
diff --git a/examples/event_handler_rest/src/async_resolve_middleware.py b/examples/event_handler_rest/src/async_resolve_middleware.py
new file mode 100644
index 00000000000..7ace8762ff8
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_middleware.py
@@ -0,0 +1,29 @@
+import asyncio
+
+from aws_lambda_powertools import Logger
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response
+from aws_lambda_powertools.event_handler.middlewares import NextMiddleware
+
+app = APIGatewayRestResolver()
+logger = Logger()
+
+
+def inject_correlation_id(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response: # (1)!
+ request_id = app.current_event.request_context.request_id
+ app.append_context(correlation_id=request_id)
+ logger.set_correlation_id(request_id)
+
+ result = next_middleware(app)
+
+ result.headers["x-correlation-id"] = request_id
+ return result
+
+
+@app.get("/todos", middlewares=[inject_correlation_id])
+async def get_todos(): # (2)!
+ await asyncio.sleep(0)
+ return {"todos": []}
+
+
+def lambda_handler(event, context):
+ return asyncio.run(app.resolve_async(event, context))
diff --git a/examples/event_handler_rest/src/async_resolve_testing.py b/examples/event_handler_rest/src/async_resolve_testing.py
new file mode 100644
index 00000000000..8ce0aadeb13
--- /dev/null
+++ b/examples/event_handler_rest/src/async_resolve_testing.py
@@ -0,0 +1,26 @@
+import asyncio
+import json
+
+
+def test_async_handler():
+ from async_resolve_getting_started import app # (1)!
+
+ event = {
+ "httpMethod": "GET",
+ "path": "/todos/1",
+ "headers": {},
+ "queryStringParameters": None,
+ "pathParameters": {"todo_id": "1"},
+ "body": None,
+ "isBase64Encoded": False,
+ "requestContext": {"stage": "dev", "requestId": "test-id", "http": {"method": "GET", "path": "/todos/1"}},
+ "rawPath": "/todos/1",
+ "rawQueryString": "",
+ "routeKey": "GET /todos/{todo_id}",
+ "version": "2.0",
+ }
+
+ response = asyncio.run(app.resolve_async(event, {})) # (2)!
+
+ assert response["statusCode"] == 200 # (3)!
+ assert json.loads(response["body"]) == {"todo_id": "1", "completed": False}
diff --git a/examples/event_handler_rest/src/customizing_api_operations.py b/examples/event_handler_rest/src/customizing_api_operations.py
index e455fc7dadd..d7e9afeba6d 100644
--- a/examples/event_handler_rest/src/customizing_api_operations.py
+++ b/examples/event_handler_rest/src/customizing_api_operations.py
@@ -26,5 +26,17 @@ def get_todo_title(todo_id: int) -> str:
return todo.json()["title"]
+@app.post(
+ "/todos",
+ summary="Creates a new todo item",
+ description="Creates a new todo item and returns it",
+ response_description="The created todo object",
+ status_code=201,
+ tags=["Todos"],
+)
+def create_todo(title: str) -> dict:
+ return {"id": 1, "title": title}
+
+
def lambda_handler(event: dict, context: LambdaContext) -> dict:
return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/dependency_injection.py b/examples/event_handler_rest/src/dependency_injection.py
new file mode 100644
index 00000000000..664bc56951d
--- /dev/null
+++ b/examples/event_handler_rest/src/dependency_injection.py
@@ -0,0 +1,32 @@
+import os
+from typing import Any
+
+import boto3
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+from aws_lambda_powertools.event_handler.depends import Depends
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+app = APIGatewayHttpResolver()
+
+
+def get_dynamodb_table():
+ dynamodb = boto3.resource("dynamodb")
+ return dynamodb.Table(os.environ["TABLE_NAME"])
+
+
+@app.get("/orders")
+def list_orders(table: Annotated[Any, Depends(get_dynamodb_table)]):
+ return table.scan()["Items"]
+
+
+@app.post("/orders")
+def create_order(table: Annotated[Any, Depends(get_dynamodb_table)]):
+ order = app.current_event.json_body
+ table.put_item(Item=order)
+ return {"message": "Order created"}
+
+
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/dependency_injection_nested.py b/examples/event_handler_rest/src/dependency_injection_nested.py
new file mode 100644
index 00000000000..f8245439538
--- /dev/null
+++ b/examples/event_handler_rest/src/dependency_injection_nested.py
@@ -0,0 +1,38 @@
+import os
+from typing import Any
+
+import boto3
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+from aws_lambda_powertools.event_handler.depends import Depends
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+app = APIGatewayHttpResolver()
+
+
+def get_dynamodb_resource():
+ return boto3.resource("dynamodb")
+
+
+def get_orders_table(dynamodb: Annotated[Any, Depends(get_dynamodb_resource)]):
+ return dynamodb.Table(os.environ["ORDERS_TABLE"])
+
+
+def get_users_table(dynamodb: Annotated[Any, Depends(get_dynamodb_resource)]):
+ return dynamodb.Table(os.environ["USERS_TABLE"])
+
+
+@app.get("/orders/")
+def get_user_orders(
+ user_id: str,
+ orders_table: Annotated[Any, Depends(get_orders_table)],
+ users_table: Annotated[Any, Depends(get_users_table)],
+):
+ user = users_table.get_item(Key={"pk": user_id})["Item"]
+ orders = orders_table.query(KeyConditionExpression="pk = :uid", ExpressionAttributeValues={":uid": user_id})
+ return {"user": user["name"], "orders": orders["Items"]}
+
+
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/dependency_injection_testing.py b/examples/event_handler_rest/src/dependency_injection_testing.py
new file mode 100644
index 00000000000..3b9f41c5330
--- /dev/null
+++ b/examples/event_handler_rest/src/dependency_injection_testing.py
@@ -0,0 +1,26 @@
+from unittest.mock import MagicMock
+
+from dependency_injection import app, get_dynamodb_table
+
+
+def test_list_orders():
+ # Create a mock table
+ mock_table = MagicMock()
+ mock_table.scan.return_value = {"Items": [{"id": "order-1"}]}
+
+ # Override the dependency with a lambda that returns the mock
+ app.dependency_overrides[get_dynamodb_table] = lambda: mock_table
+
+ result = app(
+ {
+ "requestContext": {"http": {"method": "GET", "path": "/orders"}, "stage": "$default"},
+ "rawPath": "/orders",
+ "headers": {},
+ },
+ {},
+ )
+
+ assert result["statusCode"] == 200
+
+ # Clean up overrides after testing
+ app.dependency_overrides.clear()
diff --git a/examples/event_handler_rest/src/dependency_injection_with_middleware.py b/examples/event_handler_rest/src/dependency_injection_with_middleware.py
new file mode 100644
index 00000000000..63ee419c345
--- /dev/null
+++ b/examples/event_handler_rest/src/dependency_injection_with_middleware.py
@@ -0,0 +1,36 @@
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver, Response
+from aws_lambda_powertools.event_handler.depends import Depends
+from aws_lambda_powertools.event_handler.request import Request
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+app = APIGatewayHttpResolver()
+
+
+# Middleware handles auth — it can return HTTP responses (redirects, 401s)
+def auth_middleware(app, next_middleware):
+ token = app.current_event.headers.get("authorization", "")
+ if not token:
+ return Response(status_code=401, body="Unauthorized")
+
+ # Middleware writes to app.context
+ app.append_context(user={"id": "user-123", "role": "admin"})
+ return next_middleware(app)
+
+
+app.use(middlewares=[auth_middleware])
+
+
+# Depends() reads what middleware wrote via request.context — typed and testable
+def get_current_user(request: Request) -> dict:
+ return request.context["user"]
+
+
+@app.get("/admin/dashboard")
+def admin_dashboard(user: Annotated[dict, Depends(get_current_user)]):
+ return {"message": f"Welcome {user['id']}", "role": user["role"]}
+
+
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/dependency_injection_with_request.py b/examples/event_handler_rest/src/dependency_injection_with_request.py
new file mode 100644
index 00000000000..e8586294f32
--- /dev/null
+++ b/examples/event_handler_rest/src/dependency_injection_with_request.py
@@ -0,0 +1,26 @@
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+from aws_lambda_powertools.event_handler.depends import Depends
+from aws_lambda_powertools.event_handler.exceptions import UnauthorizedError
+from aws_lambda_powertools.event_handler.request import Request
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+app = APIGatewayHttpResolver()
+
+
+def get_authenticated_user(request: Request) -> str:
+ # Use resolved_event for full Powertools event access (cookies, request_context, path, etc.)
+ user_id = request.resolved_event.headers.get("x-user-id", "")
+ if not user_id:
+ raise UnauthorizedError("Missing authentication")
+ return user_id
+
+
+@app.get("/profile")
+def get_profile(user_id: Annotated[str, Depends(get_authenticated_user)]):
+ return {"user_id": user_id}
+
+
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/middleware_request_handler_injection.py b/examples/event_handler_rest/src/middleware_request_handler_injection.py
new file mode 100644
index 00000000000..9304fcb1021
--- /dev/null
+++ b/examples/event_handler_rest/src/middleware_request_handler_injection.py
@@ -0,0 +1,16 @@
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Request
+
+app = APIGatewayRestResolver()
+
+
+@app.get("/todos/")
+def get_todo(todo_id: str, request: Request): # (1)!
+ return {
+ "id": todo_id,
+ "route": request.route, # (2)!
+ "user_agent": request.headers.get("user-agent", ""),
+ }
+
+
+def lambda_handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/middleware_request_object.py b/examples/event_handler_rest/src/middleware_request_object.py
new file mode 100644
index 00000000000..9f58460888d
--- /dev/null
+++ b/examples/event_handler_rest/src/middleware_request_object.py
@@ -0,0 +1,30 @@
+from aws_lambda_powertools import Logger
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response
+from aws_lambda_powertools.event_handler.middlewares import NextMiddleware
+
+app = APIGatewayRestResolver()
+logger = Logger()
+
+
+def request_context_middleware(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ request = app.request # (1)!
+
+ logger.append_keys(
+ route=request.route, # (2)!
+ method=request.method,
+ path_parameters=request.path_parameters, # (3)!
+ )
+
+ response = next_middleware(app)
+
+ response.headers["x-route-pattern"] = request.route # (4)!
+ return response
+
+
+@app.get("/todos/", middlewares=[request_context_middleware])
+def get_todo(todo_id: str):
+ return {"id": todo_id}
+
+
+def lambda_handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/openapi_merge_conflict.py b/examples/event_handler_rest/src/openapi_merge_conflict.py
new file mode 100644
index 00000000000..f7b90c7a946
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_conflict.py
@@ -0,0 +1,9 @@
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+merge = OpenAPIMerge(
+ title="API",
+ version="1.0.0",
+ on_conflict="error", # Raise OpenAPIMergeError on conflicts
+)
+
+merge.discover(path="./src", pattern="**/handler.py")
diff --git a/examples/event_handler_rest/src/openapi_merge_full_config.py b/examples/event_handler_rest/src/openapi_merge_full_config.py
new file mode 100644
index 00000000000..a52549c6aab
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_full_config.py
@@ -0,0 +1,18 @@
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+from aws_lambda_powertools.event_handler.openapi.models import Contact, License, Server, Tag
+
+merge = OpenAPIMerge(
+ title="My API",
+ version="1.0.0",
+ summary="API summary",
+ description="Full API description",
+ terms_of_service="https://example.com/tos",
+ contact=Contact(name="Support", email="support@example.com"),
+ license_info=License(name="MIT"),
+ servers=[Server(url="https://api.example.com")],
+ tags=[Tag(name="users", description="User operations")],
+ on_conflict="warn",
+)
+
+merge.discover(path="./src", pattern="**/handler.py", recursive=True)
+schema = merge.get_openapi_json_schema()
diff --git a/examples/event_handler_rest/src/openapi_merge_multiple_patterns.py b/examples/event_handler_rest/src/openapi_merge_multiple_patterns.py
new file mode 100644
index 00000000000..9cf2a46fc8e
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_multiple_patterns.py
@@ -0,0 +1,9 @@
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+merge = OpenAPIMerge(title="API", version="1.0.0")
+
+merge.discover(
+ path="./src",
+ pattern=["handler.py", "api.py", "*_routes.py"],
+ recursive=True,
+)
diff --git a/examples/event_handler_rest/src/openapi_merge_resolver.py b/examples/event_handler_rest/src/openapi_merge_resolver.py
new file mode 100644
index 00000000000..cc8cccbf2a5
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_resolver.py
@@ -0,0 +1,18 @@
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+app = APIGatewayRestResolver()
+
+# Configure merge - discovers handlers but doesn't execute them
+app.configure_openapi_merge(
+ path="./functions",
+ pattern="**/handler.py",
+ title="My API",
+ version="1.0.0",
+)
+
+# Swagger UI will show the merged schema
+app.enable_swagger(path="/docs")
+
+
+def handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/openapi_merge_shared_discovery.py b/examples/event_handler_rest/src/openapi_merge_shared_discovery.py
new file mode 100644
index 00000000000..13cdfc3cef8
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_shared_discovery.py
@@ -0,0 +1,13 @@
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+merge = OpenAPIMerge(title="API", version="1.0.0")
+
+# Use project_root to resolve absolute imports like "from myapp.shared_resolver import app"
+merge.discover(
+ path="./src/myapp",
+ pattern="shared_resolver.py",
+ project_root="./src", # Root for import resolution
+)
+
+# Automatically finds users_routes.py and orders_routes.py
+# that import from shared_resolver.py
diff --git a/examples/event_handler_rest/src/openapi_merge_shared_orders_routes.py b/examples/event_handler_rest/src/openapi_merge_shared_orders_routes.py
new file mode 100644
index 00000000000..2682a9c6ab1
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_shared_orders_routes.py
@@ -0,0 +1,7 @@
+# Imports and registers routes on shared resolver - orders_routes.py
+from myapp.shared_resolver import app # type: ignore[import-not-found]
+
+
+@app.get("/orders")
+def get_orders():
+ return []
diff --git a/examples/event_handler_rest/src/openapi_merge_shared_resolver.py b/examples/event_handler_rest/src/openapi_merge_shared_resolver.py
new file mode 100644
index 00000000000..decaaa3c829
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_shared_resolver.py
@@ -0,0 +1,4 @@
+# Central resolver definition - shared_resolver.py
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+app = APIGatewayRestResolver()
diff --git a/examples/event_handler_rest/src/openapi_merge_shared_users_routes.py b/examples/event_handler_rest/src/openapi_merge_shared_users_routes.py
new file mode 100644
index 00000000000..de4c87069de
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_shared_users_routes.py
@@ -0,0 +1,12 @@
+# Imports and registers routes on shared resolver - users_routes.py
+from myapp.shared_resolver import app # type: ignore[import-not-found]
+
+
+@app.get("/users")
+def get_users():
+ return []
+
+
+@app.get("/users/")
+def get_user(user_id: str):
+ return {"id": user_id}
diff --git a/examples/event_handler_rest/src/openapi_merge_standalone.py b/examples/event_handler_rest/src/openapi_merge_standalone.py
new file mode 100644
index 00000000000..ef056974901
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_standalone.py
@@ -0,0 +1,23 @@
+from pathlib import Path
+
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+merge = OpenAPIMerge(
+ title="My Unified API",
+ version="1.0.0",
+ description="Consolidated API from multiple Lambda functions",
+)
+
+# Discover handlers
+merge.discover(
+ path="./src/functions",
+ pattern="*_handler.py",
+ recursive=True,
+)
+
+# Generate schema
+schema_json = merge.get_openapi_json_schema()
+
+# Write to file
+output = Path("openapi.json")
+output.write_text(schema_json)
diff --git a/examples/event_handler_rest/src/openapi_merge_with_exclusions.py b/examples/event_handler_rest/src/openapi_merge_with_exclusions.py
new file mode 100644
index 00000000000..b781857ddc5
--- /dev/null
+++ b/examples/event_handler_rest/src/openapi_merge_with_exclusions.py
@@ -0,0 +1,10 @@
+from aws_lambda_powertools.event_handler.openapi import OpenAPIMerge
+
+merge = OpenAPIMerge(title="API", version="1.0.0")
+
+merge.discover(
+ path="./src",
+ pattern="**/*_handler.py",
+ exclude=["**/tests/**", "**/legacy/**"],
+ recursive=True,
+)
diff --git a/examples/event_handler_rest/src/working_with_file_uploads.py b/examples/event_handler_rest/src/working_with_file_uploads.py
new file mode 100644
index 00000000000..bebf72939fe
--- /dev/null
+++ b/examples/event_handler_rest/src/working_with_file_uploads.py
@@ -0,0 +1,17 @@
+from typing import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+from aws_lambda_powertools.event_handler.openapi.params import File
+
+app = APIGatewayRestResolver(enable_validation=True)
+
+
+@app.post("/upload")
+def upload_file(
+ file_data: Annotated[bytes, File(description="File to upload")], # (1)!
+):
+ return {"file_size": len(file_data)}
+
+
+def lambda_handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/working_with_file_uploads_metadata.py b/examples/event_handler_rest/src/working_with_file_uploads_metadata.py
new file mode 100644
index 00000000000..07da798f350
--- /dev/null
+++ b/examples/event_handler_rest/src/working_with_file_uploads_metadata.py
@@ -0,0 +1,21 @@
+from typing import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+app = APIGatewayRestResolver(enable_validation=True)
+
+
+@app.post("/upload")
+def upload_file(
+ file_data: Annotated[UploadFile, File(description="File to upload")], # (1)!
+):
+ return {
+ "filename": file_data.filename, # (2)!
+ "content_type": file_data.content_type,
+ "file_size": len(file_data),
+ }
+
+
+def lambda_handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/event_handler_rest/src/working_with_file_uploads_mixed.py b/examples/event_handler_rest/src/working_with_file_uploads_mixed.py
new file mode 100644
index 00000000000..e0c3859c58e
--- /dev/null
+++ b/examples/event_handler_rest/src/working_with_file_uploads_mixed.py
@@ -0,0 +1,29 @@
+import csv
+import io
+from typing import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+from aws_lambda_powertools.event_handler.openapi.params import File, Form, UploadFile
+
+app = APIGatewayRestResolver(enable_validation=True)
+
+
+@app.post("/upload-csv")
+def upload_csv(
+ file_data: Annotated[UploadFile, File(description="CSV file to parse")], # (1)!
+ separator: Annotated[str, Form(description="CSV separator")] = ",", # (2)!
+):
+ text = file_data.content.decode("utf-8")
+ reader = csv.DictReader(io.StringIO(text), delimiter=separator)
+ rows = list(reader)
+
+ return {
+ "filename": file_data.filename,
+ "total_rows": len(rows),
+ "columns": list(rows[0].keys()) if rows else [],
+ "data": rows,
+ }
+
+
+def lambda_handler(event, context):
+ return app.resolve(event, context)
diff --git a/examples/homepage/install/arm64/amplify.txt b/examples/homepage/install/arm64/amplify.txt
index 4c426a23c01..8aadd5ecbba 100644
--- a/examples/homepage/install/arm64/amplify.txt
+++ b/examples/homepage/install/arm64/amplify.txt
@@ -6,7 +6,7 @@
? Do you want to configure advanced settings? Yes
...
? Do you want to enable Lambda layers for this function? Yes
-? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33
❯ amplify push -y
@@ -17,5 +17,5 @@ General information
- Name:
? Which setting do you want to update? Lambda layers configuration
? Do you want to enable Lambda layers for this function? Yes
-? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33
? Do you want to edit the local lambda function now? No
diff --git a/examples/homepage/install/arm64/cdk_arm64.py b/examples/homepage/install/arm64/cdk_arm64.py
index a9b6ed9d01f..2b7d084a199 100644
--- a/examples/homepage/install/arm64/cdk_arm64.py
+++ b/examples/homepage/install/arm64/cdk_arm64.py
@@ -9,7 +9,7 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
self,
id="lambda-powertools",
- layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30",
+ layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33",
)
aws_lambda.Function(
self,
diff --git a/examples/homepage/install/arm64/pulumi_arm64.py b/examples/homepage/install/arm64/pulumi_arm64.py
index 99115287ef0..1659d2362ad 100644
--- a/examples/homepage/install/arm64/pulumi_arm64.py
+++ b/examples/homepage/install/arm64/pulumi_arm64.py
@@ -22,7 +22,7 @@
pulumi.Output.concat(
"arn:aws:lambda:",
aws.get_region_output().name,
- ":017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30",
+ ":017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33",
),
],
tracing_config={"mode": "Active"},
diff --git a/examples/homepage/install/arm64/sam.yaml b/examples/homepage/install/arm64/sam.yaml
index fa1833c7be1..8d77abd0e02 100644
--- a/examples/homepage/install/arm64/sam.yaml
+++ b/examples/homepage/install/arm64/sam.yaml
@@ -9,4 +9,4 @@ Resources:
Runtime: python3.12
Handler: app.lambda_handler
Layers:
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33
diff --git a/examples/homepage/install/arm64/serverless.yml b/examples/homepage/install/arm64/serverless.yml
index 4ef384f4d99..c3812016a42 100644
--- a/examples/homepage/install/arm64/serverless.yml
+++ b/examples/homepage/install/arm64/serverless.yml
@@ -10,4 +10,4 @@ functions:
handler: lambda_function.lambda_handler
architecture: arm64
layers:
- - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30
+ - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33
diff --git a/examples/homepage/install/arm64/terraform.tf b/examples/homepage/install/arm64/terraform.tf
index 679c422939f..dc46db6df87 100644
--- a/examples/homepage/install/arm64/terraform.tf
+++ b/examples/homepage/install/arm64/terraform.tf
@@ -34,7 +34,7 @@ resource "aws_lambda_function" "test_lambda" {
role = aws_iam_role.iam_for_lambda.arn
handler = "index.test"
runtime = "python3.12"
- layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:30"]
+ layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-arm64:33"]
architectures = ["arm64"]
source_code_hash = filebase64sha256("lambda_function_payload.zip")
diff --git a/examples/homepage/install/x86_64/amplify.txt b/examples/homepage/install/x86_64/amplify.txt
index 63cdcc42b41..9a1223e9280 100644
--- a/examples/homepage/install/x86_64/amplify.txt
+++ b/examples/homepage/install/x86_64/amplify.txt
@@ -6,7 +6,7 @@
? Do you want to configure advanced settings? Yes
...
? Do you want to enable Lambda layers for this function? Yes
-? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
❯ amplify push -y
@@ -17,5 +17,5 @@ General information
- Name:
? Which setting do you want to update? Lambda layers configuration
? Do you want to enable Lambda layers for this function? Yes
-? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
? Do you want to edit the local lambda function now? No
diff --git a/examples/homepage/install/x86_64/cdk_x86.py b/examples/homepage/install/x86_64/cdk_x86.py
index b70637672c2..30d82a497dd 100644
--- a/examples/homepage/install/x86_64/cdk_x86.py
+++ b/examples/homepage/install/x86_64/cdk_x86.py
@@ -9,7 +9,7 @@ def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn(
self,
id="lambda-powertools",
- layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30",
+ layer_version_arn=f"arn:aws:lambda:{Aws.REGION}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33",
)
aws_lambda.Function(
self,
diff --git a/examples/homepage/install/x86_64/pulumi_x86.py b/examples/homepage/install/x86_64/pulumi_x86.py
index 067a6036ae7..1130c67b644 100644
--- a/examples/homepage/install/x86_64/pulumi_x86.py
+++ b/examples/homepage/install/x86_64/pulumi_x86.py
@@ -22,7 +22,7 @@
pulumi.Output.concat(
"arn:aws:lambda:",
aws.get_region_output().name,
- ":017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30",
+ ":017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33",
),
],
tracing_config={"mode": "Active"},
diff --git a/examples/homepage/install/x86_64/sam.yaml b/examples/homepage/install/x86_64/sam.yaml
index b26723ca830..d6beb66ea52 100644
--- a/examples/homepage/install/x86_64/sam.yaml
+++ b/examples/homepage/install/x86_64/sam.yaml
@@ -8,4 +8,4 @@ Resources:
Runtime: python3.12
Handler: app.lambda_handler
Layers:
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
diff --git a/examples/homepage/install/x86_64/serverless.yml b/examples/homepage/install/x86_64/serverless.yml
index d55c246c4c6..56deaf1b0fa 100644
--- a/examples/homepage/install/x86_64/serverless.yml
+++ b/examples/homepage/install/x86_64/serverless.yml
@@ -10,4 +10,4 @@ functions:
handler: lambda_function.lambda_handler
architecture: arm64
layers:
- - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
diff --git a/examples/homepage/install/x86_64/terraform.tf b/examples/homepage/install/x86_64/terraform.tf
index 53f7088f950..56e73fe45b6 100644
--- a/examples/homepage/install/x86_64/terraform.tf
+++ b/examples/homepage/install/x86_64/terraform.tf
@@ -34,7 +34,7 @@ resource "aws_lambda_function" "test_lambda" {
role = aws_iam_role.iam_for_lambda.arn
handler = "index.test"
runtime = "python3.12"
- layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30"]
+ layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33"]
source_code_hash = filebase64sha256("lambda_function_payload.zip")
}
diff --git a/examples/idempotency/src/getting_started_with_idempotency_redis_client.py b/examples/idempotency/src/getting_started_with_idempotency_redis_client.py
index ac2a20587e8..91b6f5b47c4 100644
--- a/examples/idempotency/src/getting_started_with_idempotency_redis_client.py
+++ b/examples/idempotency/src/getting_started_with_idempotency_redis_client.py
@@ -21,7 +21,7 @@
max_connections=1000,
)
-persistence_layer = CachePersistenceLayer(client=client)
+persistence_layer = CachePersistenceLayer(client=client) # type: ignore[arg-type]
@dataclass
diff --git a/examples/idempotency/src/using_redis_client_with_local_certs.py b/examples/idempotency/src/using_redis_client_with_local_certs.py
index 844f5b37e7d..b58571e3bbc 100644
--- a/examples/idempotency/src/using_redis_client_with_local_certs.py
+++ b/examples/idempotency/src/using_redis_client_with_local_certs.py
@@ -27,7 +27,7 @@
ssl_ca_certs=f"{abs_lambda_path()}/certs/cache_ca.pem", # (4)!
)
-persistence_layer = CachePersistenceLayer(client=redis_client)
+persistence_layer = CachePersistenceLayer(client=redis_client) # type: ignore[arg-type]
config = IdempotencyConfig(
expires_after_seconds=2 * 60, # 2 minutes
)
diff --git a/examples/lambda_features/__init__.py b/examples/lambda_features/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/lambda_features/durable_functions/__init__.py b/examples/lambda_features/durable_functions/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/lambda_features/durable_functions/src/__init__.py b/examples/lambda_features/durable_functions/src/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/lambda_features/durable_functions/src/best_practice_idempotency.py b/examples/lambda_features/durable_functions/src/best_practice_idempotency.py
new file mode 100644
index 00000000000..6d412b6127b
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/best_practice_idempotency.py
@@ -0,0 +1,21 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools.utilities.idempotency import (
+ DynamoDBPersistenceLayer,
+ idempotent,
+)
+
+persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
+
+
+@idempotent(persistence_store=persistence_layer)
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ # Protected against duplicate SQS/Kinesis/DynamoDB triggers
+
+ result: str = context.step(
+ lambda _: "processed",
+ name="process",
+ )
+
+ return result
diff --git a/examples/lambda_features/durable_functions/src/best_practice_metrics.py b/examples/lambda_features/durable_functions/src/best_practice_metrics.py
new file mode 100644
index 00000000000..59bd2c037ad
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/best_practice_metrics.py
@@ -0,0 +1,23 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools import Metrics
+from aws_lambda_powertools.metrics import MetricUnit
+
+metrics = Metrics()
+
+
+@metrics.log_metrics
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ result: str = context.step(
+ lambda _: "processed",
+ name="process",
+ )
+
+ # Emit metrics in a dedicated step to ensure they are only counted once
+ context.step(
+ lambda _: metrics.add_metric(name="WorkflowCompleted", unit=MetricUnit.Count, value=1),
+ name="emit_completion_metric",
+ )
+
+ return result
diff --git a/examples/lambda_features/durable_functions/src/using_idempotency.py b/examples/lambda_features/durable_functions/src/using_idempotency.py
new file mode 100644
index 00000000000..04654dd5c9d
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/using_idempotency.py
@@ -0,0 +1,26 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools.utilities.idempotency import (
+ DynamoDBPersistenceLayer,
+ idempotent,
+)
+
+persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
+
+
+def process_order(event: dict) -> str:
+ return f"processed-{event.get('order_id')}"
+
+
+@idempotent(persistence_store=persistence_layer)
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ # Idempotency protects against duplicate ESM invocations
+ # Steps within the workflow are already idempotent via checkpoints
+
+ result: str = context.step(
+ lambda _: process_order(event),
+ name="process_order",
+ )
+
+ return result
diff --git a/examples/lambda_features/durable_functions/src/using_logger.py b/examples/lambda_features/durable_functions/src/using_logger.py
new file mode 100644
index 00000000000..577a15eb583
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/using_logger.py
@@ -0,0 +1,25 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools import Logger
+
+logger = Logger(service="order-processing")
+
+
+@logger.inject_lambda_context
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ # Set Logger on the context for automatic deduplication
+ context.set_logger(logger)
+
+ # Logs via context.logger appear only once, even during replays
+ context.logger.info("Starting workflow", extra={"order_id": event.get("order_id")})
+
+ result: str = context.step(
+ lambda _: "processed",
+ name="process_order",
+ )
+
+ # This log won't repeat when the function replays after completing the step above
+ context.logger.info("Workflow completed", extra={"result": result})
+
+ return result
diff --git a/examples/lambda_features/durable_functions/src/using_parameters.py b/examples/lambda_features/durable_functions/src/using_parameters.py
new file mode 100644
index 00000000000..92f2c28256a
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/using_parameters.py
@@ -0,0 +1,20 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools.utilities import parameters
+
+
+def call_api(api_key: str) -> str:
+ return f"called-with-{api_key[:4]}..."
+
+
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ # Parameters may come from cache if replay hits the same execution environment within the TTL
+ api_key = parameters.get_secret("api-key")
+
+ result: str = context.step(
+ lambda _: call_api(api_key),
+ name="call_api",
+ )
+
+ return result
diff --git a/examples/lambda_features/durable_functions/src/using_tracer.py b/examples/lambda_features/durable_functions/src/using_tracer.py
new file mode 100644
index 00000000000..a70b6f46277
--- /dev/null
+++ b/examples/lambda_features/durable_functions/src/using_tracer.py
@@ -0,0 +1,27 @@
+from aws_durable_execution_sdk_python import DurableContext, durable_execution # type: ignore[import-not-found]
+
+from aws_lambda_powertools import Logger, Tracer
+
+tracer = Tracer()
+logger = Logger()
+
+
+@logger.inject_lambda_context
+@tracer.capture_lambda_handler
+@durable_execution
+def handler(event: dict, context: DurableContext) -> str:
+ context.set_logger(logger)
+
+ result: str = context.step(
+ lambda _: process_data(),
+ name="process_data",
+ )
+
+ return result
+
+
+@tracer.capture_method
+def process_data() -> str:
+ # This is traced on first execution
+ # On replay, the cached result is used
+ return "processed"
diff --git a/examples/lambda_features/managed_instances/__init__.py b/examples/lambda_features/managed_instances/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/lambda_features/managed_instances/src/__init__.py b/examples/lambda_features/managed_instances/src/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/examples/lambda_features/managed_instances/src/using_idempotency.py b/examples/lambda_features/managed_instances/src/using_idempotency.py
new file mode 100644
index 00000000000..e0e054d07f6
--- /dev/null
+++ b/examples/lambda_features/managed_instances/src/using_idempotency.py
@@ -0,0 +1,14 @@
+from aws_lambda_powertools.utilities.idempotency import (
+ DynamoDBPersistenceLayer,
+ idempotent,
+)
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
+
+
+@idempotent(persistence_store=persistence_layer)
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ # Idempotency is guaranteed across all concurrent requests
+ # DynamoDB handles the distributed locking
+ return {"statusCode": 200, "body": "Order processed"}
diff --git a/examples/lambda_features/managed_instances/src/using_parameters.py b/examples/lambda_features/managed_instances/src/using_parameters.py
new file mode 100644
index 00000000000..36ded9cc9c6
--- /dev/null
+++ b/examples/lambda_features/managed_instances/src/using_parameters.py
@@ -0,0 +1,11 @@
+from aws_lambda_powertools.utilities import parameters
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ # Cache is per-process, not shared across concurrent requests
+ # Each process maintains its own cache
+ # This is generally fine - cache will warm up per process
+ api_key = parameters.get_secret("my-api-key", max_age=300) # noqa: F841
+
+ return {"statusCode": 200}
diff --git a/examples/lambda_features/managed_instances/src/using_tracer.py b/examples/lambda_features/managed_instances/src/using_tracer.py
new file mode 100644
index 00000000000..3cb4ee6f7fd
--- /dev/null
+++ b/examples/lambda_features/managed_instances/src/using_tracer.py
@@ -0,0 +1,28 @@
+from aws_lambda_powertools import Logger, Metrics, Tracer
+from aws_lambda_powertools.metrics import MetricUnit
+from aws_lambda_powertools.utilities.typing import LambdaContext
+
+tracer = Tracer()
+logger = Logger()
+metrics = Metrics()
+
+
+@tracer.capture_lambda_handler
+@metrics.log_metrics
+@logger.inject_lambda_context
+def lambda_handler(event: dict, context: LambdaContext) -> dict:
+ order_id = event.get("order_id", "unknown")
+ logger.append_keys(order_id=order_id)
+
+ result = process_order(order_id)
+
+ # Metrics are flushed per request
+ metrics.add_metric(name="OrderProcessed", unit=MetricUnit.Count, value=1)
+
+ return {"statusCode": 200, "body": result}
+
+
+@tracer.capture_method
+def process_order(order_id: str) -> str:
+ logger.info("Processing order")
+ return f"Processed order {order_id}"
diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml
index 9fc1ee20500..092fb4166d3 100644
--- a/examples/logger/sam/template.yaml
+++ b/examples/logger/sam/template.yaml
@@ -14,7 +14,7 @@ Globals:
Layers:
# Find the latest Layer version in the official documentation
# https://docs.powertools.aws.dev/lambda/python/latest/#lambda-layer
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
Resources:
LoggerLambdaHandlerExample:
diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml
index 0e080111506..dc7d0258fee 100644
--- a/examples/metrics/sam/template.yaml
+++ b/examples/metrics/sam/template.yaml
@@ -16,7 +16,7 @@ Globals:
Layers:
# Find the latest Layer version in the official documentation
# https://docs.powertools.aws.dev/lambda/python/latest/#lambda-layer
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
Resources:
CaptureLambdaHandlerExample:
diff --git a/examples/metrics_datadog/sam/template.yaml b/examples/metrics_datadog/sam/template.yaml
index cc89c955374..d43669484f8 100644
--- a/examples/metrics_datadog/sam/template.yaml
+++ b/examples/metrics_datadog/sam/template.yaml
@@ -20,7 +20,7 @@ Globals:
Layers:
# Find the latest Layer version in the official documentation
# https://docs.powertools.aws.dev/lambda/python/latest/#lambda-layer
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
# Find the latest Layer version in the Datadog official documentation
# Datadog SDK
diff --git a/examples/parser/src/bring_your_own_envelope.py b/examples/parser/src/bring_your_own_envelope.py
index 1fb5dea0045..ae60ac58ee3 100644
--- a/examples/parser/src/bring_your_own_envelope.py
+++ b/examples/parser/src/bring_your_own_envelope.py
@@ -1,5 +1,7 @@
+from __future__ import annotations
+
import json
-from typing import Any, Dict, Optional, Type, TypeVar, Union
+from typing import Any, TypeVar
from pydantic import BaseModel
@@ -7,11 +9,11 @@
from aws_lambda_powertools.utilities.parser.models import EventBridgeModel
from aws_lambda_powertools.utilities.typing import LambdaContext
-Model = TypeVar("Model", bound=BaseModel)
+T = TypeVar("T")
class EventBridgeEnvelope(BaseEnvelope):
- def parse(self, data: Optional[Union[Dict[str, Any], Any]], model: Type[Model]) -> Optional[Model]:
+ def parse(self, data: dict[str, Any] | Any | None, model: type[T]) -> T | None:
if data is None:
return None
diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml
index 67a7e7ead41..465ac3e2507 100644
--- a/examples/tracer/sam/template.yaml
+++ b/examples/tracer/sam/template.yaml
@@ -13,7 +13,7 @@ Globals:
Layers:
# Find the latest Layer version in the official documentation
# https://docs.powertools.aws.dev/lambda/python/latest/#lambda-layer
- - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:30
+ - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV3-python312-x86_64:33
Resources:
CaptureLambdaHandlerExample:
diff --git a/layer_v3/app.py b/layer_v3/app.py
index 25ed2b116ce..b488f640324 100644
--- a/layer_v3/app.py
+++ b/layer_v3/app.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
import aws_cdk as cdk
-
from layer.canary_stack import CanaryStack
from layer.layer_stack import LayerStack
diff --git a/layer_v3/layer/canary/app.py b/layer_v3/layer/canary/app.py
index 667d8215636..135356ca730 100644
--- a/layer_v3/layer/canary/app.py
+++ b/layer_v3/layer/canary/app.py
@@ -66,7 +66,7 @@ def on_event(event, context):
def on_create(event):
props = event["ResourceProperties"]
- logger.info("create new resource with properties %s" % props)
+ logger.info(f"create new resource with properties {props}")
handler(event)
diff --git a/layer_v3/layer_constructors/layer_stack.py b/layer_v3/layer_constructors/layer_stack.py
index a718fba5e9a..66e03b82218 100644
--- a/layer_v3/layer_constructors/layer_stack.py
+++ b/layer_v3/layer_constructors/layer_stack.py
@@ -1,5 +1,6 @@
from __future__ import annotations
+# trigger CI: validate docker/setup-buildx-action v4 compatibility
from pathlib import Path
from typing import TYPE_CHECKING
diff --git a/layer_v3/poetry.lock b/layer_v3/poetry.lock
index 7ab9c82dc68..79d0e9ccd06 100644
--- a/layer_v3/poetry.lock
+++ b/layer_v3/poetry.lock
@@ -305,28 +305,44 @@ files = [
{file = "publication-0.0.3.tar.gz", hash = "sha256:68416a0de76dddcdd2930d1c8ef853a743cc96c82416c4e4d3b5d901c6276dc4"},
]
+[[package]]
+name = "pygments"
+version = "2.20.0"
+description = "Pygments is a syntax highlighting package written in Python."
+optional = false
+python-versions = ">=3.9"
+groups = ["dev"]
+files = [
+ {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
+ {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
+]
+
+[package.extras]
+windows-terminal = ["colorama (>=0.4.6)"]
+
[[package]]
name = "pytest"
-version = "7.4.4"
+version = "9.0.3"
description = "pytest: simple powerful testing with Python"
optional = false
-python-versions = ">=3.7"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"},
- {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"},
+ {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
+ {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
]
[package.dependencies]
-colorama = {version = "*", markers = "sys_platform == \"win32\""}
-exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
-iniconfig = "*"
-packaging = "*"
-pluggy = ">=0.12,<2.0"
-tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""}
+colorama = {version = ">=0.4", markers = "sys_platform == \"win32\""}
+exceptiongroup = {version = ">=1", markers = "python_version < \"3.11\""}
+iniconfig = ">=1.0.1"
+packaging = ">=22"
+pluggy = ">=1.5,<2"
+pygments = ">=2.7.2"
+tomli = {version = ">=1", markers = "python_version < \"3.11\""}
[package.extras]
-testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
+dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "requests", "setuptools", "xmlschema"]
[[package]]
name = "python-dateutil"
@@ -460,14 +476,14 @@ markers = {dev = "python_version == \"3.10\""}
[[package]]
name = "urllib3"
-version = "2.6.3"
+version = "2.7.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
- {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
+ {file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"},
+ {file = "urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c"},
]
[package.extras]
@@ -479,4 +495,4 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
[metadata]
lock-version = "2.1"
python-versions = "^3.10"
-content-hash = "3dc6a5fee955e5a822626957f89f37c55b1e0adc6fbf61267357edb26a944d7c"
+content-hash = "55e0062a4839c65fd80947421f94e712530dda1c9dd1aed9954d75a73b882fd9"
diff --git a/layer_v3/pyproject.toml b/layer_v3/pyproject.toml
index 5dffa424144..fd67c31419d 100644
--- a/layer_v3/pyproject.toml
+++ b/layer_v3/pyproject.toml
@@ -11,7 +11,7 @@ python = "^3.10"
aws-cdk-lib = "^2.223.0"
[tool.poetry.group.dev.dependencies]
-pytest = "^7.1.2"
+pytest = ">=7.1.2,<10.0.0"
boto3 = "^1.24.46"
urllib3 = ">=1.25.4,!=2.2.0,<3"
diff --git a/mkdocs.yml b/mkdocs.yml
index cc51089fab0..6bea356bac6 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -21,6 +21,7 @@ nav:
- Datadog: core/metrics/datadog.md
- Event Handler:
- core/event_handler/api_gateway.md
+ - core/event_handler/openapi.md
- core/event_handler/appsync.md
- core/event_handler/appsync_events.md
- core/event_handler/bedrock_agents.md
@@ -39,6 +40,10 @@ nav:
- utilities/middleware_factory.md
- utilities/jmespath_functions.md
- CloudFormation Custom Resources: https://github.com/aws-cloudformation/custom-resource-helper" target="_blank
+ - Lambda Features:
+ - lambda-features/index.md
+ - lambda-features/managed-instances.md
+ - lambda-features/durable-functions.md
- Build recipes:
- build_recipes/index.md
- Getting started: build_recipes/getting-started.md
diff --git a/package-lock.json b/package-lock.json
index dfaf20a09cb..3ef587c3ca1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,13 +8,13 @@
"name": "aws-lambda-powertools-python-e2e",
"version": "1.0.0",
"devDependencies": {
- "aws-cdk": "^2.1111.0"
+ "aws-cdk": "^2.1124.1"
}
},
"node_modules/aws-cdk": {
- "version": "2.1111.0",
- "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1111.0.tgz",
- "integrity": "sha512-69AVF04cxbAhYzmeJYtUF5bs6ruNnH05EQZJfjadk5Lpg+HVaJY2NjG/2qgsMmKrfRgvLet73Ir8ehVlAaaGng==",
+ "version": "2.1124.1",
+ "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.1124.1.tgz",
+ "integrity": "sha512-sRYdPMdkX+02EHaT946AFV0w0CMfbHKWpLZPv525xTCkaVu1eYu6DzHFuTdimxdSN0uGQ2D4LHrD1sr94tRhow==",
"dev": true,
"license": "Apache-2.0",
"bin": {
diff --git a/package.json b/package.json
index 3bccdebc669..e862df39fb7 100644
--- a/package.json
+++ b/package.json
@@ -2,6 +2,6 @@
"name": "aws-lambda-powertools-python-e2e",
"version": "1.0.0",
"devDependencies": {
- "aws-cdk": "^2.1111.0"
+ "aws-cdk": "^2.1124.1"
}
}
diff --git a/parallel_run_e2e.py b/parallel_run_e2e.py
index 1146f66931e..7a56c885705 100755
--- a/parallel_run_e2e.py
+++ b/parallel_run_e2e.py
@@ -1,4 +1,5 @@
-""" Calculate how many parallel workers are needed to complete E2E infrastructure jobs across available CPU Cores """
+"""Calculate how many parallel workers are needed to complete E2E infrastructure jobs across available CPU Cores"""
+
import subprocess
import sys
from pathlib import Path
@@ -9,7 +10,7 @@ def main():
workers = len(list(features)) - 1
command = f"poetry run pytest -n {workers} -o log_cli=true tests/e2e"
- result = subprocess.run(command.split(), shell=False)
+ result = subprocess.run(command.split(), shell=False, check=False)
sys.exit(result.returncode)
diff --git a/poetry.lock b/poetry.lock
index 242e8d71083..fdc75dcbcac 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 2.2.1 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 = "annotated-types"
@@ -49,6 +49,49 @@ files = [
[package.extras]
test = ["coverage", "mypy", "pexpect", "ruff", "wheel"]
+[[package]]
+name = "ast-serialize"
+version = "0.5.0"
+description = "Python bindings for mypy AST serialization"
+optional = false
+python-versions = ">=3.7"
+groups = ["dev"]
+files = [
+ {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_10_12_x86_64.whl", hash = "sha256:8f5c14f169eb0972c0c21bada5358b23d6047c76583b005234f865b11f1fa00a"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7d1a2de9de5be04652f0ed60738356ef94f66db37924a9499fffe98dc491aa0b"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:be5173fb66f9b49026d9d5a2ff0fc7c7009077107c0eb285b2d60fdf1fe10bd1"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f8015cd071ac1339924ee2b8098c93e00e155f30a16f40ec9816fcf84f4753f6"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5499e8797edff2a9186aa313ed382c6b422e798e9332d9953badcee6e69a88f2"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6848f2a093fb5548751a9a09bff8fcd229e2bbeb0e3331f391b6ae6d26cd9903"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:832d4c998e0b091fd60a6d6bceee535483c4d490de9ba85003af835225719261"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:16db7c62ec0b8efe1d7afd283a388d8f74f2605d56032e5a37747d2de8dba027"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:baf5eb061eb5bccade4128ad42da33787d72f6013809cd1b590376ece8b3c937"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:104e4a35bd7c124173c41760ef9aaea17ddb3f86c65cb643671d59afbe3ee94c"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:36be371028fc1675acb38a331bde160dbab7ff907fdf00b67eb6911aa106951b"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:061ee58bdb52341c8201a6df41182a977736bae3b7ded87ca7176ca25a8a47ab"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:b15219e9cdc9f53f6f4cb51c009203507228226148c05c5e8fe451c28b435eb3"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-win32.whl", hash = "sha256:842d1c004bb466c7df036f95fabef789570541922b10976b12f5592a69cf0b38"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b0c06d760909b095cc466356dfccd05a1c7233a6ca191c020dca2c6a6f16c24c"},
+ {file = "ast_serialize-0.5.0-cp314-cp314t-win_arm64.whl", hash = "sha256:787baedb0262cc49e8ce37cc15c00ae818e46a165a3b36f5e21ed174998104cb"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-macosx_10_12_x86_64.whl", hash = "sha256:0668aa9459cfa8c9c49ddd2163ebcf43088ba045ef7492af6fe22e0098303101"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:bf683d6363edf2b39eed6b6d4fe22d34b6203867a67e27134d9e2a2680c4bc4a"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc22cf0c9be65e71cf88fda130af60d61eb4a79370ad4cfe7900d48a4aa2211"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f66173891548c9f2726bf27957b41cabce12fa679dc6da505ddbde4d4b3b31cf"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e42d729ef2be96a14efbad355093284739e3670ece3e534f82cc8832790911d9"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b725026bafa801dbd7310eb13a75f0a2e370e7e51b2cb225f9d21fcfadf919ee"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b54f60c1d78767a53b67eaa663f0dfac3afe606aa07f1301572f588b73d64809"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_31_riscv64.whl", hash = "sha256:27d51654fc240a1e87e742d353d98eb45b75f62f129086b3596ab53df2ac2a43"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2782c36237c46dd1674542f2109740ea5ea485a169bf1431939ada0434e17934"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1943db345233cc7194a470f13afa9c59772c0b123dea0c9414c4d4ca54369759"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:df1c00022cbbcb064bfaa505aa9c9295362443ce5dacb459d1331d3da353f887"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_i686.whl", hash = "sha256:cae65289fc456fde04af979a2be09302ef5d8ab92ef23e596d6746dc267ada27"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:239a4c354e8d676e9d94631d1d4a64edc6b266f86ff3a5a80aedd344f342c01d"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-win32.whl", hash = "sha256:143a4ef63285a075871908fda3672dc21864b83a8ec3ee12304aa3e4c5387b9a"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-win_amd64.whl", hash = "sha256:cf25572c526add400f26a4750dc6ce0c3bb93fc1f75e7ae0cad4ce4f2cd5c590"},
+ {file = "ast_serialize-0.5.0-cp39-abi3-win_arm64.whl", hash = "sha256:92a31c9c20d25a076edaeec76b128a3535d74a24f340b9a8a7e96c9b86dc9642"},
+ {file = "ast_serialize-0.5.0.tar.gz", hash = "sha256:5880091bfe6f4f986f22866375c2e884843e7a0b6343ae41aeea659613d879b6"},
+]
+
[[package]]
name = "async-timeout"
version = "5.0.1"
@@ -86,6 +129,7 @@ files = [
{file = "avro-1.12.1-py2.py3-none-any.whl", hash = "sha256:970475dd6457924533966fe761be607c759d5a48390cc8fbed472f7c9a8868f2"},
{file = "avro-1.12.1.tar.gz", hash = "sha256:c5b8dd2dd4c10816f0dc127cc29cfd43b5e405cf7e6840e89460a024bf3d098d"},
]
+markers = {main = "extra == \"kafka-consumer-avro\""}
[package.extras]
snappy = ["python-snappy"]
@@ -93,18 +137,18 @@ zstandard = ["zstandard"]
[[package]]
name = "aws-cdk-asset-awscli-v1"
-version = "2.2.263"
+version = "2.2.273"
description = "A library that contains the AWS CLI for use in Lambda Layers"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "aws_cdk_asset_awscli_v1-2.2.263-py3-none-any.whl", hash = "sha256:185150757d4216ea982d7b35596de5b3d767776be00cd78cacce02eaa08f8851"},
- {file = "aws_cdk_asset_awscli_v1-2.2.263.tar.gz", hash = "sha256:657605260ace055fac4ae30a6fb84a80504a6e24ce0b1d278913d4db4bafa266"},
+ {file = "aws_cdk_asset_awscli_v1-2.2.273-py3-none-any.whl", hash = "sha256:1a0994afa7b48f63b580603be64c7a99d19ed6777bdf81d3c2435d8b43cf0d71"},
+ {file = "aws_cdk_asset_awscli_v1-2.2.273.tar.gz", hash = "sha256:6580dad3416e53712db434f81add6fb4a314e1a80f9c57cc42606df1f64c8e0f"},
]
[package.dependencies]
-jsii = ">=1.125.0,<2.0.0"
+jsii = ">=1.127.0,<2.0.0"
publication = ">=0.0.3"
typeguard = "2.13.3"
@@ -157,7 +201,7 @@ files = [
]
[package.dependencies]
-"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1.a0"
+"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1a0"
aws-cdk-lib = ">=2.114.1,<3.0.0"
constructs = ">=10.0.0,<11.0.0"
jsii = ">=1.92.0,<2.0.0"
@@ -177,7 +221,7 @@ files = [
]
[package.dependencies]
-"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1.a0"
+"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1a0"
aws-cdk-lib = ">=2.114.1,<3.0.0"
constructs = ">=10.0.0,<11.0.0"
jsii = ">=1.92.0,<2.0.0"
@@ -205,18 +249,18 @@ typeguard = ">=2.13.3,<2.14.0"
[[package]]
name = "aws-cdk-aws-lambda-python-alpha"
-version = "2.243.0a0"
+version = "2.251.0a0"
description = "The CDK Construct Library for AWS Lambda in Python"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "aws_cdk_aws_lambda_python_alpha-2.243.0a0-py3-none-any.whl", hash = "sha256:96f9d7281dd84f1bff3cc8b8e0d403589f957845c6ba2a34a570dd8d7b776e0e"},
- {file = "aws_cdk_aws_lambda_python_alpha-2.243.0a0.tar.gz", hash = "sha256:d97718daedab795f9652ab7799ac3d206a6dd33efa5e622b60c8fa5cc6a526d2"},
+ {file = "aws_cdk_aws_lambda_python_alpha-2.251.0a0-py3-none-any.whl", hash = "sha256:c5780e06890582166932269ef594f4f2050961c2a1431429821ea45ea7a338fc"},
+ {file = "aws_cdk_aws_lambda_python_alpha-2.251.0a0.tar.gz", hash = "sha256:04f2b8edb36cb2eb3494169100d3eaad54f7acb577bd870a5343f6d95a5480da"},
]
[package.dependencies]
-aws-cdk-lib = ">=2.243.0,<3.0.0"
+aws-cdk-lib = ">=2.251.0,<3.0.0"
constructs = ">=10.5.0,<11.0.0"
jsii = ">=1.127.0,<2.0.0"
publication = ">=0.0.3"
@@ -224,53 +268,53 @@ typeguard = "2.13.3"
[[package]]
name = "aws-cdk-cloud-assembly-schema"
-version = "52.2.0"
+version = "53.24.0"
description = "Schema for the protocol between CDK framework and CDK CLI"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "aws_cdk_cloud_assembly_schema-52.2.0-py3-none-any.whl", hash = "sha256:87b918589f7d627f45e330726f592ec0b39056e1403558f3a1ba8a2134dacd6f"},
- {file = "aws_cdk_cloud_assembly_schema-52.2.0.tar.gz", hash = "sha256:737309e2c7c7e4b46bd669cb9fe8799a36424c9a174523b54833cf1cd12b5e3f"},
+ {file = "aws_cdk_cloud_assembly_schema-53.24.0-py3-none-any.whl", hash = "sha256:360c4804f3073601ac320d1773432bc45b34201d7c8fb85aff7ed536801efb0c"},
+ {file = "aws_cdk_cloud_assembly_schema-53.24.0.tar.gz", hash = "sha256:f999f4c777deaca6631c61993bf5583022ff57c3a94a65930e2fc6b68cb7c407"},
]
[package.dependencies]
-jsii = ">=1.121.0,<2.0.0"
+jsii = ">=1.129.0,<2.0.0"
publication = ">=0.0.3"
typeguard = "2.13.3"
[[package]]
name = "aws-cdk-lib"
-version = "2.243.0"
+version = "2.254.0"
description = "Version 2 of the AWS Cloud Development Kit library"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "aws_cdk_lib-2.243.0-py3-none-any.whl", hash = "sha256:9de49529fbca82680c7e4fa28040bf3895efd4250a32c812d31133c2274708b5"},
- {file = "aws_cdk_lib-2.243.0.tar.gz", hash = "sha256:ae39b90d0eef422293d22c6f2c67c5e1edfbfce7a5135a463f29e7c23538318c"},
+ {file = "aws_cdk_lib-2.254.0-py3-none-any.whl", hash = "sha256:626095eaa742e0b9d894c3a1bf06a6e7d1245a986165a72408871d41886c6d07"},
+ {file = "aws_cdk_lib-2.254.0.tar.gz", hash = "sha256:ddbef134cad91f8985444f77f052f0337af5f132101ad7aea2215b4775ff7828"},
]
[package.dependencies]
-"aws-cdk.asset-awscli-v1" = "2.2.263"
+"aws-cdk.asset-awscli-v1" = "2.2.273"
"aws-cdk.asset-node-proxy-agent-v6" = ">=2.1.1,<3.0.0"
-"aws-cdk.cloud-assembly-schema" = ">=52.1.0,<53.0.0"
+"aws-cdk.cloud-assembly-schema" = ">=53.21.0,<54.0.0"
constructs = ">=10.5.0,<11.0.0"
-jsii = ">=1.127.0,<2.0.0"
+jsii = ">=1.129.0,<2.0.0"
publication = ">=0.0.3"
typeguard = "2.13.3"
[[package]]
name = "aws-encryption-sdk"
-version = "4.0.4"
+version = "4.0.5"
description = "AWS Encryption SDK implementation for Python"
optional = true
python-versions = "*"
groups = ["main"]
markers = "extra == \"all\" or extra == \"datamasking\""
files = [
- {file = "aws_encryption_sdk-4.0.4-py2.py3-none-any.whl", hash = "sha256:29e7ec00aa6f27bb6e4f4f17e51abf3fc58a7fc17882c0e375ee09c97ab84585"},
- {file = "aws_encryption_sdk-4.0.4.tar.gz", hash = "sha256:60b69f19f72fa568d7e69e9d3966fe10e541c9c83b1af5a83724f8a1fe184d43"},
+ {file = "aws_encryption_sdk-4.0.5-py2.py3-none-any.whl", hash = "sha256:3e6b76afb94c28730487dee71fa1bfc217fcdbab061733c220ff87b88630e40e"},
+ {file = "aws_encryption_sdk-4.0.5.tar.gz", hash = "sha256:a36136181a4d63cbf0d7347d29786c80a4d74a07c79c88a8799e27b27a9c3fc1"},
]
[package.dependencies]
@@ -299,14 +343,14 @@ requests = ">=0.14.0"
[[package]]
name = "aws-sam-translator"
-version = "1.107.0"
+version = "1.108.0"
description = "AWS SAM Translator is a library that transform SAM templates into AWS CloudFormation templates"
optional = false
python-versions = "!=4.0,<=4.0,>=3.8"
groups = ["dev"]
files = [
- {file = "aws_sam_translator-1.107.0-py3-none-any.whl", hash = "sha256:95b2a03a87fb61d9a9e9e431a18e6221c4780b32792eed4b239e72ef7366d63b"},
- {file = "aws_sam_translator-1.107.0.tar.gz", hash = "sha256:e6462c85309a4cabcc9559edf12f164c67a74a1208feb6350ab8aa1b620c9365"},
+ {file = "aws_sam_translator-1.108.0-py3-none-any.whl", hash = "sha256:03130421e641bb57ba7978e7db9e49acb32ecb09a87777dca3c28e44b3ea49db"},
+ {file = "aws_sam_translator-1.108.0.tar.gz", hash = "sha256:8a21be119caaa64cf85e01b5e0fde804abe117b36fcce934bc1b74f3ccdc2488"},
]
[package.dependencies]
@@ -316,7 +360,7 @@ pydantic = {version = ">=2.12.5,<2.13.0", markers = "python_version >= \"3.9\""}
typing_extensions = ">=4.4"
[package.extras]
-dev = ["black (==24.3.0)", "boto3 (>=1.34.0,<2.0.0)", "boto3-stubs[appconfig,serverlessrepo] (>=1.34.0,<2.0.0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.10.1,<1.11.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (>=0.4.5,<0.5.0)", "tenacity (>=9.0,<10.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"]
+dev = ["black (==24.3.0)", "boto3 (>=1.34.0,<2.0.0)", "boto3-stubs[appconfig,serverlessrepo] (>=1.34.0,<2.0.0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.10.1,<1.11.0)", "parameterized (>=0.7,<1.0)", "pytest (>=6.2,<8)", "pytest-cov (>=2.10,<5)", "pytest-env (>=0.6,<1)", "pytest-rerunfailures (>=9.1,<12)", "pytest-xdist (>=2.5,<4)", "pyyaml (>=6.0,<7.0)", "requests (>=2.28,<3.0)", "ruamel.yaml (==0.17.21)", "ruff (>=0.4.5,<0.5.0)", "tenacity (>=9.0,<10.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)", "types-requests (>=2.28,<3.0)"]
[[package]]
name = "aws-xray-sdk"
@@ -442,6 +486,7 @@ files = [
{file = "boto3-1.42.67-py3-none-any.whl", hash = "sha256:aa900216bdc48bbd0115ed7128a4baed5548c6a60673160a38df8a8566df57cd"},
{file = "boto3-1.42.67.tar.gz", hash = "sha256:d4123ceb3be36c5cb7ddccc7a7c43701e1fb6af612ef46e3b5d667daf5447d4b"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\""}
[package.dependencies]
botocore = ">=1.42.67,<1.43.0"
@@ -453,453 +498,460 @@ 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.3"
+description = "Type annotations for boto3 1.43.3 generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
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.3-py3-none-any.whl", hash = "sha256:dd43fb68fe1d6db450588609a96013a9baf86d1cfc45bbbee7fd97bac971a3c0"},
+ {file = "boto3_stubs-1.43.3.tar.gz", hash = "sha256:1c17fb4003c8d3ac324385f1d7a366721436eab3b6dc7838239dea53137ba9de"},
]
[package.dependencies]
botocore-stubs = "*"
-mypy-boto3-appconfig = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"appconfig\""}
-mypy-boto3-appconfigdata = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"appconfigdata\""}
-mypy-boto3-cloudformation = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"cloudformation\""}
-mypy-boto3-cloudwatch = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"cloudwatch\""}
-mypy-boto3-dynamodb = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"dynamodb\""}
-mypy-boto3-lambda = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"lambda\""}
-mypy-boto3-logs = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"logs\""}
-mypy-boto3-s3 = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"s3\""}
-mypy-boto3-secretsmanager = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"secretsmanager\""}
-mypy-boto3-ssm = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"ssm\""}
-mypy-boto3-xray = {version = ">=1.42.0,<1.43.0", optional = true, markers = "extra == \"xray\""}
+mypy-boto3-appconfig = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"appconfig\""}
+mypy-boto3-appconfigdata = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"appconfigdata\""}
+mypy-boto3-cloudformation = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"cloudformation\""}
+mypy-boto3-cloudwatch = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"cloudwatch\""}
+mypy-boto3-dynamodb = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"dynamodb\""}
+mypy-boto3-lambda = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"lambda\""}
+mypy-boto3-logs = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"logs\""}
+mypy-boto3-s3 = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"s3\""}
+mypy-boto3-secretsmanager = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"secretsmanager\""}
+mypy-boto3-ssm = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"ssm\""}
+mypy-boto3-xray = {version = ">=1.43.0,<1.44.0", optional = true, markers = "extra == \"xray\""}
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-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-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.3)"]
+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)"]
+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)"]
+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"
@@ -912,6 +964,7 @@ files = [
{file = "botocore-1.42.67-py3-none-any.whl", hash = "sha256:a94317d2ce83deae230964beb2729639455de65595d0154f285b0ccfd29780cd"},
{file = "botocore-1.42.67.tar.gz", hash = "sha256:ee307f30fcb798d244fb35a87847b274e1e1f72cd5f7f2e31bd1826df0c45295"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\" or extra == \"tracer\""}
[package.dependencies]
jmespath = ">=0.7.1,<2.0.0"
@@ -981,40 +1034,40 @@ ujson = ["ujson (>=5.10.0)"]
[[package]]
name = "cdk-nag"
-version = "2.37.55"
+version = "2.38.2"
description = "Check CDK v2 applications for best practices using a combination on available rule packs."
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "cdk_nag-2.37.55-py3-none-any.whl", hash = "sha256:bf83bcdeb98ac20bb813cac291af121d91c5a296fa815e01f93886b4f8b38845"},
- {file = "cdk_nag-2.37.55.tar.gz", hash = "sha256:e9dc517070ef5a19deef95e79731e5624bd86cd07b56d210380408ea1314e47b"},
+ {file = "cdk_nag-2.38.2-py3-none-any.whl", hash = "sha256:d37f18ae9450f401bcc55d5d82138beee561486806579849cb9be25ff7565904"},
+ {file = "cdk_nag-2.38.2.tar.gz", hash = "sha256:a4d419062ea4d64c2892942214b9184b124eb2bc36d087982007b3455e1ac443"},
]
[package.dependencies]
aws-cdk-lib = ">=2.176.0,<3.0.0"
-constructs = ">=10.0.5,<11.0.0"
-jsii = ">=1.116.0,<2.0.0"
+constructs = ">=10.5.1,<11.0.0"
+jsii = ">=1.128.0,<2.0.0"
publication = ">=0.0.3"
-typeguard = ">=2.13.3,<4.3.0"
+typeguard = "2.13.3"
[[package]]
name = "cdklabs-generative-ai-cdk-constructs"
-version = "0.1.316"
+version = "0.1.317"
description = "AWS Generative AI CDK Constructs is a library for well-architected generative AI patterns."
optional = false
-python-versions = "~=3.9"
+python-versions = "~=3.10"
groups = ["dev"]
files = [
- {file = "cdklabs_generative_ai_cdk_constructs-0.1.316-py3-none-any.whl", hash = "sha256:925926882b2978156918536460bbfa03ab1ed0b7641ff0982d7370c8a3f81f83"},
- {file = "cdklabs_generative_ai_cdk_constructs-0.1.316.tar.gz", hash = "sha256:8347018014753f5c99a14f93ea05756ded83f05286eef6fc712b492364fe173b"},
+ {file = "cdklabs_generative_ai_cdk_constructs-0.1.317-py3-none-any.whl", hash = "sha256:86359377bbb56c946a460b0b7244ad5f9b8be3ab290201ad2e197fc7a6628dfb"},
+ {file = "cdklabs_generative_ai_cdk_constructs-0.1.317.tar.gz", hash = "sha256:e04ed66168736f65cc4d13449a719dbb8d84c7ffb054d22a034865918315d157"},
]
[package.dependencies]
-aws-cdk-lib = ">=2.233.0,<3.0.0"
-cdk-nag = ">=2.37.55,<3.0.0"
-constructs = ">=10.3.0,<11.0.0"
-jsii = ">=1.127.0,<2.0.0"
+aws-cdk-lib = ">=2.254.0,<3.0.0"
+cdk-nag = ">=2.38.2,<3.0.0"
+constructs = ">=10.6.0,<11.0.0"
+jsii = ">=1.130.0,<2.0.0"
publication = ">=0.0.3"
typeguard = "2.13.3"
@@ -1029,6 +1082,7 @@ files = [
{file = "certifi-2026.2.25-py3-none-any.whl", hash = "sha256:027692e4402ad994f1c42e52a4997a9763c646b73e4096e4d5d6db8af1d6f0fa"},
{file = "certifi-2026.2.25.tar.gz", hash = "sha256:e887ab5cee78ea814d3472169153c2d12cd43b14bd03329a39a9c6e2e80bfba7"},
]
+markers = {main = "extra == \"datadog\""}
[[package]]
name = "cffi"
@@ -1130,18 +1184,18 @@ pycparser = {version = "*", markers = "implementation_name != \"PyPy\""}
[[package]]
name = "cfn-lint"
-version = "1.46.0"
+version = "1.48.1"
description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved"
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "cfn_lint-1.46.0-py3-none-any.whl", hash = "sha256:1dfca1993af3159411e4a4f79466617ccdca48eddaf424e216297167c500aa3b"},
- {file = "cfn_lint-1.46.0.tar.gz", hash = "sha256:fa7cb76db683109133241baf1e1734b1d61b46d3900ba2a309db8f3d0e5d3994"},
+ {file = "cfn_lint-1.48.1-py3-none-any.whl", hash = "sha256:73785acd4fcb71ed68183589f7dcf9e46fd0ad9fb01f704243cb07993490a40e"},
+ {file = "cfn_lint-1.48.1.tar.gz", hash = "sha256:1855dce6b97528ff532e3f5a3aa5b659f40e51c338192a0ba82c1af88882b6f7"},
]
[package.dependencies]
-aws-sam-translator = ">=1.97.0"
+aws-sam-translator = ">=1.108.0"
jsonpatch = "*"
networkx = ">=2.4,<4"
pyyaml = ">5.4"
@@ -1277,6 +1331,7 @@ files = [
{file = "charset_normalizer-3.4.5-py3-none-any.whl", hash = "sha256:9db5e3fcdcee89a78c04dffb3fe33c79f77bd741a624946db2591c81b2fc85b0"},
{file = "charset_normalizer-3.4.5.tar.gz", hash = "sha256:95adae7b6c42a6c5b5b559b1a99149f090a57128155daeea91732c8d970d8644"},
]
+markers = {main = "extra == \"datadog\""}
[[package]]
name = "click"
@@ -1325,135 +1380,135 @@ development = ["black", "flake8", "mypy", "pytest", "types-colorama"]
[[package]]
name = "constructs"
-version = "10.5.1"
+version = "10.6.0"
description = "A programming model for software-defined state"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "constructs-10.5.1-py3-none-any.whl", hash = "sha256:fc5c14f6b2770c8542a43e298aa29b63dee4b18701763e8c0fdce202624c3a7c"},
- {file = "constructs-10.5.1.tar.gz", hash = "sha256:c0e90bb2b9c2782f292017820b91714321cb78393c8965c9362b0b624bfaf23b"},
+ {file = "constructs-10.6.0-py3-none-any.whl", hash = "sha256:ad4ffabdb53c17cde00fb94e441a1ba9fddac57c92ad49d263f8dbd416cec513"},
+ {file = "constructs-10.6.0.tar.gz", hash = "sha256:bc55d1d390142424861e5ff5c6b8c243c4bae18fe7302e0939c2003f329ba365"},
]
[package.dependencies]
-jsii = ">=1.126.0,<2.0.0"
+jsii = ">=1.127.0,<2.0.0"
publication = ">=0.0.3"
typeguard = "2.13.3"
[[package]]
name = "coverage"
-version = "7.13.4"
+version = "7.14.0"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "coverage-7.13.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fc31c787a84f8cd6027eba44010517020e0d18487064cd3d8968941856d1415"},
- {file = "coverage-7.13.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a32ebc02a1805adf637fc8dec324b5cdacd2e493515424f70ee33799573d661b"},
- {file = "coverage-7.13.4-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e24f9156097ff9dc286f2f913df3a7f63c0e333dcafa3c196f2c18b4175ca09a"},
- {file = "coverage-7.13.4-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8041b6c5bfdc03257666e9881d33b1abc88daccaf73f7b6340fb7946655cd10f"},
- {file = "coverage-7.13.4-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a09cfa6a5862bc2fc6ca7c3def5b2926194a56b8ab78ffcf617d28911123012"},
- {file = "coverage-7.13.4-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:296f8b0af861d3970c2a4d8c91d48eb4dd4771bcef9baedec6a9b515d7de3def"},
- {file = "coverage-7.13.4-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e101609bcbbfb04605ea1027b10dc3735c094d12d40826a60f897b98b1c30256"},
- {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:aa3feb8db2e87ff5e6d00d7e1480ae241876286691265657b500886c98f38bda"},
- {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4fc7fa81bbaf5a02801b65346c8b3e657f1d93763e58c0abdf7c992addd81a92"},
- {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:33901f604424145c6e9c2398684b92e176c0b12df77d52db81c20abd48c3794c"},
- {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:bb28c0f2cf2782508a40cec377935829d5fcc3ad9a3681375af4e84eb34b6b58"},
- {file = "coverage-7.13.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9d107aff57a83222ddbd8d9ee705ede2af2cc926608b57abed8ef96b50b7e8f9"},
- {file = "coverage-7.13.4-cp310-cp310-win32.whl", hash = "sha256:a6f94a7d00eb18f1b6d403c91a88fd58cfc92d4b16080dfdb774afc8294469bf"},
- {file = "coverage-7.13.4-cp310-cp310-win_amd64.whl", hash = "sha256:2cb0f1e000ebc419632bbe04366a8990b6e32c4e0b51543a6484ffe15eaeda95"},
- {file = "coverage-7.13.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d490ba50c3f35dd7c17953c68f3270e7ccd1c6642e2d2afe2d8e720b98f5a053"},
- {file = "coverage-7.13.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:19bc3c88078789f8ef36acb014d7241961dbf883fd2533d18cb1e7a5b4e28b11"},
- {file = "coverage-7.13.4-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3998e5a32e62fdf410c0dbd3115df86297995d6e3429af80b8798aad894ca7aa"},
- {file = "coverage-7.13.4-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8e264226ec98e01a8e1054314af91ee6cde0eacac4f465cc93b03dbe0bce2fd7"},
- {file = "coverage-7.13.4-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a3aa4e7b9e416774b21797365b358a6e827ffadaaca81b69ee02946852449f00"},
- {file = "coverage-7.13.4-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:71ca20079dd8f27fcf808817e281e90220475cd75115162218d0e27549f95fef"},
- {file = "coverage-7.13.4-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e2f25215f1a359ab17320b47bcdaca3e6e6356652e8256f2441e4ef972052903"},
- {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d65b2d373032411e86960604dc4edac91fdfb5dca539461cf2cbe78327d1e64f"},
- {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94eb63f9b363180aff17de3e7c8760c3ba94664ea2695c52f10111244d16a299"},
- {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e856bf6616714c3a9fbc270ab54103f4e685ba236fa98c054e8f87f266c93505"},
- {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:65dfcbe305c3dfe658492df2d85259e0d79ead4177f9ae724b6fb245198f55d6"},
- {file = "coverage-7.13.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b507778ae8a4c915436ed5c2e05b4a6cecfa70f734e19c22a005152a11c7b6a9"},
- {file = "coverage-7.13.4-cp311-cp311-win32.whl", hash = "sha256:784fc3cf8be001197b652d51d3fd259b1e2262888693a4636e18879f613a62a9"},
- {file = "coverage-7.13.4-cp311-cp311-win_amd64.whl", hash = "sha256:2421d591f8ca05b308cf0092807308b2facbefe54af7c02ac22548b88b95c98f"},
- {file = "coverage-7.13.4-cp311-cp311-win_arm64.whl", hash = "sha256:79e73a76b854d9c6088fe5d8b2ebe745f8681c55f7397c3c0a016192d681045f"},
- {file = "coverage-7.13.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:02231499b08dabbe2b96612993e5fc34217cdae907a51b906ac7fca8027a4459"},
- {file = "coverage-7.13.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40aa8808140e55dc022b15d8aa7f651b6b3d68b365ea0398f1441e0b04d859c3"},
- {file = "coverage-7.13.4-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:5b856a8ccf749480024ff3bd7310adaef57bf31fd17e1bfc404b7940b6986634"},
- {file = "coverage-7.13.4-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2c048ea43875fbf8b45d476ad79f179809c590ec7b79e2035c662e7afa3192e3"},
- {file = "coverage-7.13.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b7b38448866e83176e28086674fe7368ab8590e4610fb662b44e345b86d63ffa"},
- {file = "coverage-7.13.4-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:de6defc1c9badbf8b9e67ae90fd00519186d6ab64e5cc5f3d21359c2a9b2c1d3"},
- {file = "coverage-7.13.4-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7eda778067ad7ffccd23ecffce537dface96212576a07924cbf0d8799d2ded5a"},
- {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e87f6c587c3f34356c3759f0420693e35e7eb0e2e41e4c011cb6ec6ecbbf1db7"},
- {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:8248977c2e33aecb2ced42fef99f2d319e9904a36e55a8a68b69207fb7e43edc"},
- {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:25381386e80ae727608e662474db537d4df1ecd42379b5ba33c84633a2b36d47"},
- {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ee756f00726693e5ba94d6df2bdfd64d4852d23b09bb0bc700e3b30e6f333985"},
- {file = "coverage-7.13.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdfc1e28e7c7cdce44985b3043bc13bbd9c747520f94a4d7164af8260b3d91f0"},
- {file = "coverage-7.13.4-cp312-cp312-win32.whl", hash = "sha256:01d4cbc3c283a17fc1e42d614a119f7f438eabb593391283adca8dc86eff1246"},
- {file = "coverage-7.13.4-cp312-cp312-win_amd64.whl", hash = "sha256:9401ebc7ef522f01d01d45532c68c5ac40fb27113019b6b7d8b208f6e9baa126"},
- {file = "coverage-7.13.4-cp312-cp312-win_arm64.whl", hash = "sha256:b1ec7b6b6e93255f952e27ab58fbc68dcc468844b16ecbee881aeb29b6ab4d8d"},
- {file = "coverage-7.13.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b66a2da594b6068b48b2692f043f35d4d3693fb639d5ea8b39533c2ad9ac3ab9"},
- {file = "coverage-7.13.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3599eb3992d814d23b35c536c28df1a882caa950f8f507cef23d1cbf334995ac"},
- {file = "coverage-7.13.4-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:93550784d9281e374fb5a12bf1324cc8a963fd63b2d2f223503ef0fd4aa339ea"},
- {file = "coverage-7.13.4-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b720ce6a88a2755f7c697c23268ddc47a571b88052e6b155224347389fdf6a3b"},
- {file = "coverage-7.13.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b322db1284a2ed3aa28ffd8ebe3db91c929b7a333c0820abec3d838ef5b3525"},
- {file = "coverage-7.13.4-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f4594c67d8a7c89cf922d9df0438c7c7bb022ad506eddb0fdb2863359ff78242"},
- {file = "coverage-7.13.4-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:53d133df809c743eb8bce33b24bcababb371f4441340578cd406e084d94a6148"},
- {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:76451d1978b95ba6507a039090ba076105c87cc76fc3efd5d35d72093964d49a"},
- {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f57b33491e281e962021de110b451ab8a24182589be17e12a22c79047935e23"},
- {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:1731dc33dc276dafc410a885cbf5992f1ff171393e48a21453b78727d090de80"},
- {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:bd60d4fe2f6fa7dff9223ca1bbc9f05d2b6697bc5961072e5d3b952d46e1b1ea"},
- {file = "coverage-7.13.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9181a3ccead280b828fae232df12b16652702b49d41e99d657f46cc7b1f6ec7a"},
- {file = "coverage-7.13.4-cp313-cp313-win32.whl", hash = "sha256:f53d492307962561ac7de4cd1de3e363589b000ab69617c6156a16ba7237998d"},
- {file = "coverage-7.13.4-cp313-cp313-win_amd64.whl", hash = "sha256:e6f70dec1cc557e52df5306d051ef56003f74d56e9c4dd7ddb07e07ef32a84dd"},
- {file = "coverage-7.13.4-cp313-cp313-win_arm64.whl", hash = "sha256:fb07dc5da7e849e2ad31a5d74e9bece81f30ecf5a42909d0a695f8bd1874d6af"},
- {file = "coverage-7.13.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:40d74da8e6c4b9ac18b15331c4b5ebc35a17069410cad462ad4f40dcd2d50c0d"},
- {file = "coverage-7.13.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:4223b4230a376138939a9173f1bdd6521994f2aff8047fae100d6d94d50c5a12"},
- {file = "coverage-7.13.4-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:1d4be36a5114c499f9f1f9195e95ebf979460dbe2d88e6816ea202010ba1c34b"},
- {file = "coverage-7.13.4-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:200dea7d1e8095cc6e98cdabe3fd1d21ab17d3cee6dab00cadbb2fe35d9c15b9"},
- {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b8eb931ee8e6d8243e253e5ed7336deea6904369d2fd8ae6e43f68abbf167092"},
- {file = "coverage-7.13.4-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:75eab1ebe4f2f64d9509b984f9314d4aa788540368218b858dad56dc8f3e5eb9"},
- {file = "coverage-7.13.4-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c35eb28c1d085eb7d8c9b3296567a1bebe03ce72962e932431b9a61f28facf26"},
- {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:eb88b316ec33760714a4720feb2816a3a59180fd58c1985012054fa7aebee4c2"},
- {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:7d41eead3cc673cbd38a4417deb7fd0b4ca26954ff7dc6078e33f6ff97bed940"},
- {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:fb26a934946a6afe0e326aebe0730cdff393a8bc0bbb65a2f41e30feddca399c"},
- {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:dae88bc0fc77edaa65c14be099bd57ee140cf507e6bfdeea7938457ab387efb0"},
- {file = "coverage-7.13.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:845f352911777a8e722bfce168958214951e07e47e5d5d9744109fa5fe77f79b"},
- {file = "coverage-7.13.4-cp313-cp313t-win32.whl", hash = "sha256:2fa8d5f8de70688a28240de9e139fa16b153cc3cbb01c5f16d88d6505ebdadf9"},
- {file = "coverage-7.13.4-cp313-cp313t-win_amd64.whl", hash = "sha256:9351229c8c8407645840edcc277f4a2d44814d1bc34a2128c11c2a031d45a5dd"},
- {file = "coverage-7.13.4-cp313-cp313t-win_arm64.whl", hash = "sha256:30b8d0512f2dc8c8747557e8fb459d6176a2c9e5731e2b74d311c03b78451997"},
- {file = "coverage-7.13.4-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:300deaee342f90696ed186e3a00c71b5b3d27bffe9e827677954f4ee56969601"},
- {file = "coverage-7.13.4-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:29e3220258d682b6226a9b0925bc563ed9a1ebcff3cad30f043eceea7eaf2689"},
- {file = "coverage-7.13.4-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:391ee8f19bef69210978363ca930f7328081c6a0152f1166c91f0b5fdd2a773c"},
- {file = "coverage-7.13.4-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0dd7ab8278f0d58a0128ba2fca25824321f05d059c1441800e934ff2efa52129"},
- {file = "coverage-7.13.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78cdf0d578b15148b009ccf18c686aa4f719d887e76e6b40c38ffb61d264a552"},
- {file = "coverage-7.13.4-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:48685fee12c2eb3b27c62f2658e7ea21e9c3239cba5a8a242801a0a3f6a8c62a"},
- {file = "coverage-7.13.4-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4e83efc079eb39480e6346a15a1bcb3e9b04759c5202d157e1dd4303cd619356"},
- {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ecae9737b72408d6a950f7e525f30aca12d4bd8dd95e37342e5beb3a2a8c4f71"},
- {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ae4578f8528569d3cf303fef2ea569c7f4c4059a38c8667ccef15c6e1f118aa5"},
- {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:6fdef321fdfbb30a197efa02d48fcd9981f0d8ad2ae8903ac318adc653f5df98"},
- {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:2b0f6ccf3dbe577170bebfce1318707d0e8c3650003cb4b3a9dd744575daa8b5"},
- {file = "coverage-7.13.4-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:75fcd519f2a5765db3f0e391eb3b7d150cce1a771bf4c9f861aeab86c767a3c0"},
- {file = "coverage-7.13.4-cp314-cp314-win32.whl", hash = "sha256:8e798c266c378da2bd819b0677df41ab46d78065fb2a399558f3f6cae78b2fbb"},
- {file = "coverage-7.13.4-cp314-cp314-win_amd64.whl", hash = "sha256:245e37f664d89861cf2329c9afa2c1fe9e6d4e1a09d872c947e70718aeeac505"},
- {file = "coverage-7.13.4-cp314-cp314-win_arm64.whl", hash = "sha256:ad27098a189e5838900ce4c2a99f2fe42a0bf0c2093c17c69b45a71579e8d4a2"},
- {file = "coverage-7.13.4-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:85480adfb35ffc32d40918aad81b89c69c9cc5661a9b8a81476d3e645321a056"},
- {file = "coverage-7.13.4-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:79be69cf7f3bf9b0deeeb062eab7ac7f36cd4cc4c4dd694bd28921ba4d8596cc"},
- {file = "coverage-7.13.4-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:caa421e2684e382c5d8973ac55e4f36bed6821a9bad5c953494de960c74595c9"},
- {file = "coverage-7.13.4-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14375934243ee05f56c45393fe2ce81fe5cc503c07cee2bdf1725fb8bef3ffaf"},
- {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:25a41c3104d08edb094d9db0d905ca54d0cd41c928bb6be3c4c799a54753af55"},
- {file = "coverage-7.13.4-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f01afcff62bf9a08fb32b2c1d6e924236c0383c02c790732b6537269e466a72"},
- {file = "coverage-7.13.4-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:eb9078108fbf0bcdde37c3f4779303673c2fa1fe8f7956e68d447d0dd426d38a"},
- {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e086334e8537ddd17e5f16a344777c1ab8194986ec533711cbe6c41cde841b6"},
- {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:725d985c5ab621268b2edb8e50dfe57633dc69bda071abc470fed55a14935fd3"},
- {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:3c06f0f1337c667b971ca2f975523347e63ec5e500b9aa5882d91931cd3ef750"},
- {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:590c0ed4bf8e85f745e6b805b2e1c457b2e33d5255dd9729743165253bc9ad39"},
- {file = "coverage-7.13.4-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:eb30bf180de3f632cd043322dad5751390e5385108b2807368997d1a92a509d0"},
- {file = "coverage-7.13.4-cp314-cp314t-win32.whl", hash = "sha256:c4240e7eded42d131a2d2c4dec70374b781b043ddc79a9de4d55ca71f8e98aea"},
- {file = "coverage-7.13.4-cp314-cp314t-win_amd64.whl", hash = "sha256:4c7d3cc01e7350f2f0f6f7036caaf5673fb56b6998889ccfe9e1c1fe75a9c932"},
- {file = "coverage-7.13.4-cp314-cp314t-win_arm64.whl", hash = "sha256:23e3f687cf945070d1c90f85db66d11e3025665d8dafa831301a0e0038f3db9b"},
- {file = "coverage-7.13.4-py3-none-any.whl", hash = "sha256:1af1641e57cf7ba1bd67d677c9abdbcd6cc2ab7da3bca7fa1e2b7e50e65f2ad0"},
- {file = "coverage-7.13.4.tar.gz", hash = "sha256:e5c8f6ed1e61a8b2dcdf31eb0b9bbf0130750ca79c1c49eb898e2ad86f5ccc91"},
+ {file = "coverage-7.14.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:84c32d90bf4537f0e7b4dec9aaa9a938fb8205136b9d2ecf4d7629d5262dc075"},
+ {file = "coverage-7.14.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7c843572c605ab51cfdb5c6b5f2586e2a8467c0d28eca4bdef4ec70c5fecbd82"},
+ {file = "coverage-7.14.0-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0c451757d3fa2603354fdc789b5e58a0e327a117c370a40e3476ba4eabab228c"},
+ {file = "coverage-7.14.0-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3fd43f0616e765ab78d069cf8358def7363957a45cee446d65c502dcfeea7893"},
+ {file = "coverage-7.14.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:731e535b1498b27d13594a0527a79b0510867b0ad891532be41cb883f2128e20"},
+ {file = "coverage-7.14.0-cp310-cp310-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c7492f2d493b976941c7ca050f273cbda2f43c381124f7586a3e3c16d1804fec"},
+ {file = "coverage-7.14.0-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc38367eaa2abb1b766ac333142bce7655335a73537f5c8b75aaa89c2b987757"},
+ {file = "coverage-7.14.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0a951308cde22cf77f953955a754d04dccb57fe3bb8e345d685778ed9fc1632a"},
+ {file = "coverage-7.14.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fab3877e4ebb06bd9d4d4d00ee53309ee5478e66873c66a382272e3ee33eb7ea"},
+ {file = "coverage-7.14.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:b812eb847b19876ebf33fb6c4f11819af05ab6050b0bfa1bc53412ae81779adb"},
+ {file = "coverage-7.14.0-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:d9c8ef6ed820c433de075657d72dda1f89a2984955e58b8a75feb3f184250218"},
+ {file = "coverage-7.14.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d128b1bba9361fbaaf6a19e179e6cfd6a9103ce0c0555876f72780acc93efd85"},
+ {file = "coverage-7.14.0-cp310-cp310-win32.whl", hash = "sha256:65f267ca1370726ec2c1aa38bbe4df9a71a740f22878d2d4bf59d71a4cd8d323"},
+ {file = "coverage-7.14.0-cp310-cp310-win_amd64.whl", hash = "sha256:b34ece8065914f938ed7f2c5872bb865336977a52919149846eac3744327267a"},
+ {file = "coverage-7.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6a78e2a9d9c5e3b8d4ab9b9d28c985ea66fced0a7d7c2aec1f216e03a2011480"},
+ {file = "coverage-7.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a1816c505187592dcd1c5a5f226601a549f70365fbd00930ac88b0c225b76bb4"},
+ {file = "coverage-7.14.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d8e1762f0e9cbc26ec315471e7b47855218e833cd5a032d706fbf43845d878c7"},
+ {file = "coverage-7.14.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9336e23e8bb3a3925398261385e2a1533957d3e760e91070dcb0e98bfa514eed"},
+ {file = "coverage-7.14.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd1169b2230f9cbe9c638ba38022ed7a2b1e641cc07f7cea0365e4be2a74980"},
+ {file = "coverage-7.14.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d1bb3543b58fea74d2cd1abc4054cc927e4724687cb4560cd2ed88d2c7d820c0"},
+ {file = "coverage-7.14.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a93bac2cb577ef60074999ed56d8a1535894398e2ed920d4185c3ec0c8864742"},
+ {file = "coverage-7.14.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:5904abf7e18cddc463219b17552229650c6b79e061d31a1059283051169cf7d5"},
+ {file = "coverage-7.14.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:741f57cddc9004a8c81b084660215f33a6b597dbe62c31386b983ee26310e327"},
+ {file = "coverage-7.14.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:664123feb0929d7affc135717dbd70d61d98688a08ab1e5ba464739620c6252d"},
+ {file = "coverage-7.14.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:c83d2399a51bbec8429266905d33616f04bc5726b1138c35844d5fcd896b2e20"},
+ {file = "coverage-7.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:bcb2e855b87321259a037429288ae85216d191c74de3e79bf57cd2bc0761992c"},
+ {file = "coverage-7.14.0-cp311-cp311-win32.whl", hash = "sha256:731dc15b385ac52289743d476245b61e1a2927e803bef655b52bc3b2a75a21f3"},
+ {file = "coverage-7.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:bfb0ed8ec5d25e93face268115d7964db9df8b9aae8edcde9ec6b16c726a7cc1"},
+ {file = "coverage-7.14.0-cp311-cp311-win_arm64.whl", hash = "sha256:7ebb1c6df9f78046a1b1e0a89674cd4bf73b7c648914eebcf976a57fd99a5627"},
+ {file = "coverage-7.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7ffd19fc8aed057fd686a17a4935eef5f9859d69208f96310e893e64b9b6ccf5"},
+ {file = "coverage-7.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:829994cfe1aeb773ca27bf246d4badc1e764893e3bfb98fff820fcecd1ca4662"},
+ {file = "coverage-7.14.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b4f07cf7edcb7ec39431a5074d7ea83b29a9f71fcfc494f0f40af4e65180420f"},
+ {file = "coverage-7.14.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:ca3d9cf2c32b521bd9518385608787fa86f38daf993695307531822c3430ed67"},
+ {file = "coverage-7.14.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92af52828e7f29d827346b0294e5a0853fa206db77db0395b282918d41e28db9"},
+ {file = "coverage-7.14.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7b2bb6c9d7e769360d0f20a0f219603fd64f0c8f97de17ab25853261602be0fb"},
+ {file = "coverage-7.14.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1c9ed6ef99f88fb8c14aa8e2bf8eb0fe55fa2edfea68f8675d78741df1a5ac0e"},
+ {file = "coverage-7.14.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8231ade007f37959fbf58acc677f26b922c02eda6f0428ea307da0fd39681bf3"},
+ {file = "coverage-7.14.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:d8b013632cc1ce1d09dbe4f32667b4d320ec2f54fc326ebeffcd0b0bcc2bb6c4"},
+ {file = "coverage-7.14.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1733198802d71ec4c524f322e2867ee05c62e9e75df86bdca545407a221827d1"},
+ {file = "coverage-7.14.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:72a305291fa8ee01332f1aaf38b348ca34097f6aa0b0ef627eef2837e57bbba5"},
+ {file = "coverage-7.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fcaba850dd317c65423a9d63d88f9573c53b00354d6dd95724576cc98a131595"},
+ {file = "coverage-7.14.0-cp312-cp312-win32.whl", hash = "sha256:5ac83957a80d0701310e96d8bec68cdcf4f90a7674b7d13f15a344315b41ab27"},
+ {file = "coverage-7.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:70390b0da32cb90b501953716302906e8bcce087cb283e70d8c97729f22e92b2"},
+ {file = "coverage-7.14.0-cp312-cp312-win_arm64.whl", hash = "sha256:91b993743d959b8be85b4abf9d5478216a69329c321efe5be0433c1a841d691d"},
+ {file = "coverage-7.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f2bbb8254370eb4c628ff3d6fa8a7f74ddc40565394d4f7ab791d1fe568e37ef"},
+ {file = "coverage-7.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:23b81107f46d3f21d0cbce30664fcec0f5d9f585638a67081750f99738f6bf66"},
+ {file = "coverage-7.14.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:22a7e06a5f11a757cdfe79018e9095f9f69ae283c5cd8123774c788deec8717b"},
+ {file = "coverage-7.14.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9d1aa57a1dc8e05bdc42e81c5d671d849577aeedf279f4c449d6d286f9ed88ca"},
+ {file = "coverage-7.14.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90c1a51bcfddf645b3bb7ec333d9e94393a8e94f55642380fa8a9a5a9e636cb7"},
+ {file = "coverage-7.14.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a841fae2fadcae4f438d43b6ccc4aac2ad609f47cdb6cfdce60cbb3fe5ca7bc2"},
+ {file = "coverage-7.14.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c79d2319cabef1fe8e86df73371126931550804738f78ad7d31e3aad85a67367"},
+ {file = "coverage-7.14.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1b23b0c6f0b1db6ad769b7050c8b641c0bf215ded26c1816955b17b7f26edfa9"},
+ {file = "coverage-7.14.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:55d3089079ce181a4566b1065ab28d2575eb76d8ac8f81f4fcda2bf037fee087"},
+ {file = "coverage-7.14.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:49c005cba1e2f9677fb2845dcdf9a2e72a52a17d63e8231aaaae35d9f50215ef"},
+ {file = "coverage-7.14.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:9117377b823daa28aa8635fbb08cda1cd6be3d7143257345459559aeef852d52"},
+ {file = "coverage-7.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7b79d646cf46d5cf9a9f40281d4441df5849e445726e369006d2b117710b33fe"},
+ {file = "coverage-7.14.0-cp313-cp313-win32.whl", hash = "sha256:fb609b3658479e33f9516d46f1a89dbb9b6c261366e3a11844a96ec487533dae"},
+ {file = "coverage-7.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:0773d8329cf32b6fd222e4b52622c61fe8d503eb966cfc8d3c3c10c96266d50e"},
+ {file = "coverage-7.14.0-cp313-cp313-win_arm64.whl", hash = "sha256:b4e26a0f1b696faf283bffe5b8569e44e336c582439df5d53281ab89ee0cba96"},
+ {file = "coverage-7.14.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:953f521ca9445300397e65fda3dca58b2dbd68fee983777420b57ac3c77e9f90"},
+ {file = "coverage-7.14.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:98af83fd65ae24b1fdd03aaead967a9f523bcd2f1aab2d4f3ffda65bb568a6f1"},
+ {file = "coverage-7.14.0-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:668b92e6958c4db7cf92e81caac328dfbbdbb215db2850ad28f0cbe1eea0bfbd"},
+ {file = "coverage-7.14.0-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9fbd898551762dea00d3fef2b1c4f99afd2c6a3ff952ea07d60a9bd5ed4f34bc"},
+ {file = "coverage-7.14.0-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:68af363c07ecd8d4b7d4043d85cb376d7d227eceb54e5323ee45da73dbd3e426"},
+ {file = "coverage-7.14.0-cp313-cp313t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6e57054a583da8ac55edf24117ea4c9133032cfc4cf72aa2d48c1e5d4b52f899"},
+ {file = "coverage-7.14.0-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cc3499459bbcdd51a65b64c35ab7ed2764eaf3cba826e0df3f1d7fe2e102b70b"},
+ {file = "coverage-7.14.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:45899ec2138a4346ed34d601dedf5076fb74edf2d1dd9dc76a78e82397edee90"},
+ {file = "coverage-7.14.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8767486808c436f05b23ab98eb963fb29185e32a9357a166971685cb3459900f"},
+ {file = "coverage-7.14.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:a3b5ddfd6aa7ddad53ee3edb231e88a2151507a43229b7d71b953916deca127d"},
+ {file = "coverage-7.14.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:63df0fe568e698e1045792399f8ab6da3a6c2dce3182813fb92afa2641087b47"},
+ {file = "coverage-7.14.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:827d6397dbd95144939b18f89edf31f63e1f99633e8d5f32f22ba8bdda567477"},
+ {file = "coverage-7.14.0-cp313-cp313t-win32.whl", hash = "sha256:7bf43e000d24012599b879791cff41589af90674722421ef11b11a5431920bab"},
+ {file = "coverage-7.14.0-cp313-cp313t-win_amd64.whl", hash = "sha256:3f5549365af25d770e06b1f8f5682d9a5637d06eb494db91c6fa75d3950cc917"},
+ {file = "coverage-7.14.0-cp313-cp313t-win_arm64.whl", hash = "sha256:6d160217ec6fe890f16ad3a9531761589443749e448f91986c972714fad361c8"},
+ {file = "coverage-7.14.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:9aed9fa983514ca032790f3fe0d1c0e42ca7e16b42432af1706b50a9a46bef5d"},
+ {file = "coverage-7.14.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:ba3b8390db29296dbbf49e91b6fe08f990743a90c8f447ba4c2ffc29670dfa63"},
+ {file = "coverage-7.14.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3a5d8e876dfa2f102e970b183863d6dedd023d3c0eeca1fe7a9787bc5f28b212"},
+ {file = "coverage-7.14.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5ebb8f4614a3787d567e610bbfdf96a4798dd69a1afb1bd8ad228d4111fe6ff3"},
+ {file = "coverage-7.14.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b9bf47223dd8db3d4c4b2e443b02bace480d428f0822c3f991600448a176c97"},
+ {file = "coverage-7.14.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:3485a836550b303d006d57cc06e3d5afaabc642c77050b7c985a97b13e3776b8"},
+ {file = "coverage-7.14.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:3e7e88110bae996d199d1693ca8ec3fd52441d426401ae963437598667b4c5eb"},
+ {file = "coverage-7.14.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:15228a6800ce7bdf1b74800595e56db7138cecb338fdbf044806e10dcf182dfe"},
+ {file = "coverage-7.14.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:9d26ac7f5398bafc5b57421ad994e8a4749e8a7a0e62d05ec7d53014d5963bfa"},
+ {file = "coverage-7.14.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2fb73254ff43c911c967a899e1359bc5049b4b115d6e8fbdde4937d0a2246cd5"},
+ {file = "coverage-7.14.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:454a380af72c6adada298ed270d38c7a391288198dbfb8467f786f588751a90c"},
+ {file = "coverage-7.14.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:65c86fb646d2bd2972e96bd1a8b45817ed907cee68655d6295fe7ec031d04cca"},
+ {file = "coverage-7.14.0-cp314-cp314-win32.whl", hash = "sha256:6a6516b02a6101398e19a3f44820f69bab2590697f7def4331f668b14adaf828"},
+ {file = "coverage-7.14.0-cp314-cp314-win_amd64.whl", hash = "sha256:45e0f79d8351fa76e256716df91eab12890d32678b9590df7ae1042e4bd4cf5d"},
+ {file = "coverage-7.14.0-cp314-cp314-win_arm64.whl", hash = "sha256:4b899594a8b2d81e5cc064a0d7f9cac2081fed91049456cae7676787e41549c9"},
+ {file = "coverage-7.14.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:f580f8c80acd94ac72e863efe2cab791d8c38d153e0b463b92dfa000d5c84cd1"},
+ {file = "coverage-7.14.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a2bd259c442cd43c49b30fbafc51776eb19ea396faf159d26a83e6a0a5f13b0c"},
+ {file = "coverage-7.14.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a706b908dfa85538863504c624b237a3cc34232bf403c057414ebfdb3b4d9f84"},
+ {file = "coverage-7.14.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:7333cd944ee4393b9b3d3c1b598c936d4fc8d70573a4c7dacfec5590dd50e436"},
+ {file = "coverage-7.14.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0f162bc9a15b82d947b02651b0c7e1609d6f7a8735ca330cfadec8481dd97d5a"},
+ {file = "coverage-7.14.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:362cb78e01a5dc82009d88004cf60f2e6b6d6fcbfdec05b05af73b0abf40118f"},
+ {file = "coverage-7.14.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:acebd068fca5512c3a6fde9c045f901613478781a73f0e82b307b214daef23fb"},
+ {file = "coverage-7.14.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:29fe3da551dface75deb2ccbf87b6b66e2e7ef38f6d89050b428be94afff3490"},
+ {file = "coverage-7.14.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:b4cc4fce8672fffcb09b0eafc167b396b3ba53c4a7230f54b7aaffbf6c835fa9"},
+ {file = "coverage-7.14.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:5d4a51aad8ba8bdcd2b8bd8f03d4aca19693fa2327a3470e4718a25b03481020"},
+ {file = "coverage-7.14.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:9f323af3e1e4f68b60b7b247e37b8515563a61375518fa59de1af48ba28a3db6"},
+ {file = "coverage-7.14.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1a0abc7342ea9711c469dd8b821c6c311e6bc6aac1442e5fbd6b27fae0a8f3db"},
+ {file = "coverage-7.14.0-cp314-cp314t-win32.whl", hash = "sha256:a9f864ef57b7172e2db87a096642dd51e179e085ab6b2c371c29e885f65c8fb2"},
+ {file = "coverage-7.14.0-cp314-cp314t-win_amd64.whl", hash = "sha256:29943e552fdc08e082eb51400fb2f58e118a83b5542bd06531214e084399b644"},
+ {file = "coverage-7.14.0-cp314-cp314t-win_arm64.whl", hash = "sha256:742a73ea621953b012f2c4c2219b512180dd84489acf5b1596b0aafc55b9100b"},
+ {file = "coverage-7.14.0-py3-none-any.whl", hash = "sha256:8de5b61163aee3d05c8a2beab6f47913df7981dad1baf82c414d99158c286ab1"},
+ {file = "coverage-7.14.0.tar.gz", hash = "sha256:057a6af2f160a85384cde4ab36f0d2777bae1057bae255f95413cdd382aa5c74"},
]
[package.dependencies]
@@ -1464,61 +1519,61 @@ toml = ["tomli ; python_full_version <= \"3.11.0a6\""]
[[package]]
name = "cryptography"
-version = "46.0.5"
+version = "46.0.7"
description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
optional = false
python-versions = "!=3.9.0,!=3.9.1,>=3.8"
groups = ["main", "dev"]
files = [
- {file = "cryptography-46.0.5-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:351695ada9ea9618b3500b490ad54c739860883df6c1f555e088eaf25b1bbaad"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c18ff11e86df2e28854939acde2d003f7984f721eba450b56a200ad90eeb0e6b"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4d7e3d356b8cd4ea5aff04f129d5f66ebdc7b6f8eae802b93739ed520c47c79b"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:50bfb6925eff619c9c023b967d5b77a54e04256c4281b0e21336a130cd7fc263"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:803812e111e75d1aa73690d2facc295eaefd4439be1023fefc4995eaea2af90d"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ee190460e2fbe447175cda91b88b84ae8322a104fc27766ad09428754a618ed"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:f145bba11b878005c496e93e257c1e88f154d278d2638e6450d17e0f31e558d2"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:e9251e3be159d1020c4030bd2e5f84d6a43fe54b6c19c12f51cde9542a2817b2"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:47fb8a66058b80e509c47118ef8a75d14c455e81ac369050f20ba0d23e77fee0"},
- {file = "cryptography-46.0.5-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:4c3341037c136030cb46e4b1e17b7418ea4cbd9dd207e4a6f3b2b24e0d4ac731"},
- {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:890bcb4abd5a2d3f852196437129eb3667d62630333aacc13dfd470fad3aaa82"},
- {file = "cryptography-46.0.5-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:80a8d7bfdf38f87ca30a5391c0c9ce4ed2926918e017c29ddf643d0ed2778ea1"},
- {file = "cryptography-46.0.5-cp311-abi3-win32.whl", hash = "sha256:60ee7e19e95104d4c03871d7d7dfb3d22ef8a9b9c6778c94e1c8fcc8365afd48"},
- {file = "cryptography-46.0.5-cp311-abi3-win_amd64.whl", hash = "sha256:38946c54b16c885c72c4f59846be9743d699eee2b69b6988e0a00a01f46a61a4"},
- {file = "cryptography-46.0.5-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:94a76daa32eb78d61339aff7952ea819b1734b46f73646a07decb40e5b3448e2"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:5be7bf2fb40769e05739dd0046e7b26f9d4670badc7b032d6ce4db64dddc0678"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:fe346b143ff9685e40192a4960938545c699054ba11d4f9029f94751e3f71d87"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:c69fd885df7d089548a42d5ec05be26050ebcd2283d89b3d30676eb32ff87dee"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:8293f3dea7fc929ef7240796ba231413afa7b68ce38fd21da2995549f5961981"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:1abfdb89b41c3be0365328a410baa9df3ff8a9110fb75e7b52e66803ddabc9a9"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:d66e421495fdb797610a08f43b05269e0a5ea7f5e652a89bfd5a7d3c1dee3648"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:4e817a8920bfbcff8940ecfd60f23d01836408242b30f1a708d93198393a80b4"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:68f68d13f2e1cb95163fa3b4db4bf9a159a418f5f6e7242564fc75fcae667fd0"},
- {file = "cryptography-46.0.5-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:a3d1fae9863299076f05cb8a778c467578262fae09f9dc0ee9b12eb4268ce663"},
- {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4143987a42a2397f2fc3b4d7e3a7d313fbe684f67ff443999e803dd75a76826"},
- {file = "cryptography-46.0.5-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7d731d4b107030987fd61a7f8ab512b25b53cef8f233a97379ede116f30eb67d"},
- {file = "cryptography-46.0.5-cp314-cp314t-win32.whl", hash = "sha256:c3bcce8521d785d510b2aad26ae2c966092b7daa8f45dd8f44734a104dc0bc1a"},
- {file = "cryptography-46.0.5-cp314-cp314t-win_amd64.whl", hash = "sha256:4d8ae8659ab18c65ced284993c2265910f6c9e650189d4e3f68445ef82a810e4"},
- {file = "cryptography-46.0.5-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:4108d4c09fbbf2789d0c926eb4152ae1760d5a2d97612b92d508d96c861e4d31"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7d1f30a86d2757199cb2d56e48cce14deddf1f9c95f1ef1b64ee91ea43fe2e18"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:039917b0dc418bb9f6edce8a906572d69e74bd330b0b3fea4f79dab7f8ddd235"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:ba2a27ff02f48193fc4daeadf8ad2590516fa3d0adeeb34336b96f7fa64c1e3a"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:61aa400dce22cb001a98014f647dc21cda08f7915ceb95df0c9eaf84b4b6af76"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3ce58ba46e1bc2aac4f7d9290223cead56743fa6ab94a5d53292ffaac6a91614"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:420d0e909050490d04359e7fdb5ed7e667ca5c3c402b809ae2563d7e66a92229"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:582f5fcd2afa31622f317f80426a027f30dc792e9c80ffee87b993200ea115f1"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:bfd56bb4b37ed4f330b82402f6f435845a5f5648edf1ad497da51a8452d5d62d"},
- {file = "cryptography-46.0.5-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:a3d507bb6a513ca96ba84443226af944b0f7f47dcc9a399d110cd6146481d24c"},
- {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9f16fbdf4da055efb21c22d81b89f155f02ba420558db21288b3d0035bafd5f4"},
- {file = "cryptography-46.0.5-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ced80795227d70549a411a4ab66e8ce307899fad2220ce5ab2f296e687eacde9"},
- {file = "cryptography-46.0.5-cp38-abi3-win32.whl", hash = "sha256:02f547fce831f5096c9a567fd41bc12ca8f11df260959ecc7c3202555cc47a72"},
- {file = "cryptography-46.0.5-cp38-abi3-win_amd64.whl", hash = "sha256:556e106ee01aa13484ce9b0239bca667be5004efb0aabbed28d353df86445595"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:3b4995dc971c9fb83c25aa44cf45f02ba86f71ee600d81091c2f0cbae116b06c"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:bc84e875994c3b445871ea7181d424588171efec3e185dced958dad9e001950a"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:2ae6971afd6246710480e3f15824ed3029a60fc16991db250034efd0b9fb4356"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d861ee9e76ace6cf36a6a89b959ec08e7bc2493ee39d07ffe5acb23ef46d27da"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:2b7a67c9cd56372f3249b39699f2ad479f6991e62ea15800973b956f4b73e257"},
- {file = "cryptography-46.0.5-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:8456928655f856c6e1533ff59d5be76578a7157224dbd9ce6872f25055ab9ab7"},
- {file = "cryptography-46.0.5.tar.gz", hash = "sha256:abace499247268e3757271b2f1e244b36b06f8515cf27c4d49468fc9eb16e93d"},
+ {file = "cryptography-46.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:ea42cbe97209df307fdc3b155f1b6fa2577c0defa8f1f7d3be7d31d189108ad4"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b36a4695e29fe69215d75960b22577197aca3f7a25b9cf9d165dcfe9d80bc325"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:5ad9ef796328c5e3c4ceed237a183f5d41d21150f972455a9d926593a1dcb308"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:73510b83623e080a2c35c62c15298096e2a5dc8d51c3b4e1740211839d0dea77"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cbd5fb06b62bd0721e1170273d3f4d5a277044c47ca27ee257025146c34cbdd1"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:420b1e4109cc95f0e5700eed79908cef9268265c773d3a66f7af1eef53d409ef"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:24402210aa54baae71d99441d15bb5a1919c195398a87b563df84468160a65de"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8a469028a86f12eb7d2fe97162d0634026d92a21f3ae0ac87ed1c4a447886c83"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:9694078c5d44c157ef3162e3bf3946510b857df5a3955458381d1c7cfc143ddb"},
+ {file = "cryptography-46.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:42a1e5f98abb6391717978baf9f90dc28a743b7d9be7f0751a6f56a75d14065b"},
+ {file = "cryptography-46.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:91bbcb08347344f810cbe49065914fe048949648f6bd5c2519f34619142bbe85"},
+ {file = "cryptography-46.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5d1c02a14ceb9148cc7816249f64f623fbfee39e8c03b3650d842ad3f34d637e"},
+ {file = "cryptography-46.0.7-cp311-abi3-win32.whl", hash = "sha256:d23c8ca48e44ee015cd0a54aeccdf9f09004eba9fc96f38c911011d9ff1bd457"},
+ {file = "cryptography-46.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:397655da831414d165029da9bc483bed2fe0e75dde6a1523ec2fe63f3c46046b"},
+ {file = "cryptography-46.0.7-cp314-cp314t-macosx_10_9_universal2.whl", hash = "sha256:d151173275e1728cf7839aaa80c34fe550c04ddb27b34f48c232193df8db5842"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:db0f493b9181c7820c8134437eb8b0b4792085d37dbb24da050476ccb664e59c"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ebd6daf519b9f189f85c479427bbd6e9c9037862cf8fe89ee35503bd209ed902"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b7b412817be92117ec5ed95f880defe9cf18a832e8cafacf0a22337dc1981b4d"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:fbfd0e5f273877695cb93baf14b185f4878128b250cc9f8e617ea0c025dfb022"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:ffca7aa1d00cf7d6469b988c581598f2259e46215e0140af408966a24cf086ce"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:60627cf07e0d9274338521205899337c5d18249db56865f943cbe753aa96f40f"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:80406c3065e2c55d7f49a9550fe0c49b3f12e5bfff5dedb727e319e1afb9bf99"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:c5b1ccd1239f48b7151a65bc6dd54bcfcc15e028c8ac126d3fada09db0e07ef1"},
+ {file = "cryptography-46.0.7-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d5f7520159cd9c2154eb61eb67548ca05c5774d39e9c2c4339fd793fe7d097b2"},
+ {file = "cryptography-46.0.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:fcd8eac50d9138c1d7fc53a653ba60a2bee81a505f9f8850b6b2888555a45d0e"},
+ {file = "cryptography-46.0.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:65814c60f8cc400c63131584e3e1fad01235edba2614b61fbfbfa954082db0ee"},
+ {file = "cryptography-46.0.7-cp314-cp314t-win32.whl", hash = "sha256:fdd1736fed309b4300346f88f74cd120c27c56852c3838cab416e7a166f67298"},
+ {file = "cryptography-46.0.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e06acf3c99be55aa3b516397fe42f5855597f430add9c17fa46bf2e0fb34c9bb"},
+ {file = "cryptography-46.0.7-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:462ad5cb1c148a22b2e3bcc5ad52504dff325d17daf5df8d88c17dda1f75f2a4"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:84d4cced91f0f159a7ddacad249cc077e63195c36aac40b4150e7a57e84fffe7"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:128c5edfe5e5938b86b03941e94fac9ee793a94452ad1365c9fc3f4f62216832"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5e51be372b26ef4ba3de3c167cd3d1022934bc838ae9eaad7e644986d2a3d163"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:cdf1a610ef82abb396451862739e3fc93b071c844399e15b90726ef7470eeaf2"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:1d25aee46d0c6f1a501adcddb2d2fee4b979381346a78558ed13e50aa8a59067"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:cdfbe22376065ffcf8be74dc9a909f032df19bc58a699456a21712d6e5eabfd0"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:abad9dac36cbf55de6eb49badd4016806b3165d396f64925bf2999bcb67837ba"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:935ce7e3cfdb53e3536119a542b839bb94ec1ad081013e9ab9b7cfd478b05006"},
+ {file = "cryptography-46.0.7-cp38-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:35719dc79d4730d30f1c2b6474bd6acda36ae2dfae1e3c16f2051f215df33ce0"},
+ {file = "cryptography-46.0.7-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7bbc6ccf49d05ac8f7d7b5e2e2c33830d4fe2061def88210a126d130d7f71a85"},
+ {file = "cryptography-46.0.7-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a1529d614f44b863a7b480c6d000fe93b59acee9c82ffa027cfadc77521a9f5e"},
+ {file = "cryptography-46.0.7-cp38-abi3-win32.whl", hash = "sha256:f247c8c1a1fb45e12586afbb436ef21ff1e80670b2861a90353d9b025583d246"},
+ {file = "cryptography-46.0.7-cp38-abi3-win_amd64.whl", hash = "sha256:506c4ff91eff4f82bdac7633318a526b1d1309fc07ca76a3ad182cb5b686d6d3"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:fc9ab8856ae6cf7c9358430e49b368f3108f050031442eaeb6b9d87e4dcf4e4f"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d3b99c535a9de0adced13d159c5a9cf65c325601aa30f4be08afd680643e9c15"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d02c738dacda7dc2a74d1b2b3177042009d5cab7c7079db74afc19e56ca1b455"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:04959522f938493042d595a736e7dbdff6eb6cc2339c11465b3ff89343b65f65"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:3986ac1dee6def53797289999eabe84798ad7817f3e97779b5061a95b0ee4968"},
+ {file = "cryptography-46.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:258514877e15963bd43b558917bc9f54cf7cf866c38aa576ebf47a77ddbc43a4"},
+ {file = "cryptography-46.0.7.tar.gz", hash = "sha256:e4cfd68c5f3e0bfdad0d38e023239b96a2fe84146481852dffbcca442c245aa5"},
]
markers = {main = "extra == \"all\" or extra == \"datamasking\""}
@@ -1533,7 +1588,7 @@ nox = ["nox[uv] (>=2024.4.15)"]
pep8test = ["check-sdist", "click (>=8.0.1)", "mypy (>=1.14)", "ruff (>=0.11.11)"]
sdist = ["build (>=1.0.0)"]
ssh = ["bcrypt (>=3.1.5)"]
-test = ["certifi (>=2024)", "cryptography-vectors (==46.0.5)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
+test = ["certifi (>=2024)", "cryptography-vectors (==46.0.7)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"]
test-randomorder = ["pytest-randomly"]
[[package]]
@@ -1662,11 +1717,11 @@ files = [
[package.dependencies]
bytecode = [
- {version = ">=0.17.0,<1", markers = "python_version >= \"3.14.0\""},
+ {version = ">=0.13.0,<1", markers = "python_version < \"3.11.0\""},
{version = ">=0.16.0,<1", markers = "python_version >= \"3.13.0\" and python_version < \"3.14.0\""},
- {version = ">=0.15.1,<1", markers = "python_version ~= \"3.12.0\""},
+ {version = ">=0.17.0,<1", markers = "python_version >= \"3.14.0\""},
{version = ">=0.14.0,<1", markers = "python_version ~= \"3.11.0\""},
- {version = ">=0.13.0,<1", markers = "python_version < \"3.11.0\""},
+ {version = ">=0.15.1,<1", markers = "python_version ~= \"3.12.0\""},
]
envier = ">=0.6.1,<0.7.0"
opentelemetry-api = ">=1,<2"
@@ -1841,14 +1896,14 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc
[[package]]
name = "filelock"
-version = "3.25.2"
+version = "3.29.0"
description = "A platform independent file lock."
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "filelock-3.25.2-py3-none-any.whl", hash = "sha256:ca8afb0da15f229774c9ad1b455ed96e85a81373065fb10446672f64444ddf70"},
- {file = "filelock-3.25.2.tar.gz", hash = "sha256:b64ece2b38f4ca29dd3e810287aa8c48182bbecd1ae6e9ae126c9b35f1382694"},
+ {file = "filelock-3.29.0-py3-none-any.whl", hash = "sha256:96f5f6344709aa1572bbf631c640e4ebeeb519e08da902c39a001882f30ac258"},
+ {file = "filelock-3.29.0.tar.gz", hash = "sha256:69974355e960702e789734cb4871f884ea6fe50bd8404051a3530bc07809cf90"},
]
[[package]]
@@ -1886,21 +1941,21 @@ smmap = ">=3.0.1,<6"
[[package]]
name = "gitpython"
-version = "3.1.46"
+version = "3.1.50"
description = "GitPython is a Python library used to interact with Git repositories"
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
- {file = "gitpython-3.1.46-py3-none-any.whl", hash = "sha256:79812ed143d9d25b6d176a10bb511de0f9c67b1fa641d82097b0ab90398a2058"},
- {file = "gitpython-3.1.46.tar.gz", hash = "sha256:400124c7d0ef4ea03f7310ac2fbf7151e09ff97f2a3288d64a440c584a29c37f"},
+ {file = "gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9"},
+ {file = "gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc"},
]
[package.dependencies]
gitdb = ">=4.0.1,<5"
[package.extras]
-doc = ["sphinx (>=7.1.2,<7.2)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"]
+doc = ["sphinx (>=7.4.7,<8)", "sphinx-autodoc-typehints", "sphinx_rtd_theme"]
test = ["coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock ; python_version < \"3.8\"", "mypy (==1.18.2) ; python_version >= \"3.9\"", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "typing-extensions ; python_version < \"3.11\""]
[[package]]
@@ -2047,18 +2102,19 @@ parser = ["pyhcl (>=0.4.4,<0.5.0)"]
[[package]]
name = "idna"
-version = "3.11"
+version = "3.15"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.8"
groups = ["main", "dev"]
files = [
- {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"},
- {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"},
+ {file = "idna-3.15-py3-none-any.whl", hash = "sha256:048adeaf8c2d788c40fee287673ccaa74c24ffd8dcf09ffa555a2fbb59f10ac8"},
+ {file = "idna-3.15.tar.gz", hash = "sha256:ca962446ea538f7092a95e057da437618e886f4d349216d2b1e294abfdb65fdc"},
]
+markers = {main = "extra == \"datadog\" or extra == \"valkey\""}
[package.extras]
-all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
+all = ["mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
[[package]]
name = "ijson"
@@ -2224,19 +2280,18 @@ files = [
[[package]]
name = "isort"
-version = "7.0.0"
+version = "8.0.1"
description = "A Python utility / library to sort Python imports."
optional = false
python-versions = ">=3.10.0"
groups = ["dev"]
files = [
- {file = "isort-7.0.0-py3-none-any.whl", hash = "sha256:1bcabac8bc3c36c7fb7b98a76c8abb18e0f841a3ba81decac7691008592499c1"},
- {file = "isort-7.0.0.tar.gz", hash = "sha256:5513527951aadb3ac4292a41a16cbc50dd1642432f5e8c20057d414bdafb4187"},
+ {file = "isort-8.0.1-py3-none-any.whl", hash = "sha256:28b89bc70f751b559aeca209e6120393d43fbe2490de0559662be7a9787e3d75"},
+ {file = "isort-8.0.1.tar.gz", hash = "sha256:171ac4ff559cdc060bcfff550bc8404a486fee0caab245679c2abe7cb253c78d"},
]
[package.extras]
colors = ["colorama"]
-plugins = ["setuptools"]
[[package]]
name = "jinja2"
@@ -2270,14 +2325,14 @@ files = [
[[package]]
name = "jsii"
-version = "1.127.0"
+version = "1.130.0"
description = "Python client for jsii runtime"
optional = false
python-versions = "~=3.9"
groups = ["dev"]
files = [
- {file = "jsii-1.127.0-py3-none-any.whl", hash = "sha256:92a11f39e461f5168e2467efd53351cc32b118314b95cc6323c2d044eb299eaf"},
- {file = "jsii-1.127.0.tar.gz", hash = "sha256:631a13d73265eaa22c0c0804e77fe59c8fcc3af3a94de9923af65380b6ad267a"},
+ {file = "jsii-1.130.0-py3-none-any.whl", hash = "sha256:ce50e11ea588fe6b2d0766d90edaf4c78b9e97e2e1f075fbd8bc29349c6503c8"},
+ {file = "jsii-1.130.0.tar.gz", hash = "sha256:7436ae382e2de27970b34a4ccfef953a45980c5070241c1bd610bf3af68a2d6b"},
]
[package.dependencies]
@@ -2343,7 +2398,7 @@ files = [
[package.dependencies]
attrs = ">=22.2.0"
-jsonschema-specifications = ">=2023.03.6"
+jsonschema-specifications = ">=2023.3.6"
referencing = ">=0.28.4"
rpds-py = ">=0.25.0"
@@ -2368,103 +2423,103 @@ referencing = ">=0.31.0"
[[package]]
name = "librt"
-version = "0.8.1"
+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.8.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:81fd938344fecb9373ba1b155968c8a329491d2ce38e7ddb76f30ffb938f12dc"},
- {file = "librt-0.8.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5db05697c82b3a2ec53f6e72b2ed373132b0c2e05135f0696784e97d7f5d48e7"},
- {file = "librt-0.8.1-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:d56bc4011975f7460bea7b33e1ff425d2f1adf419935ff6707273c77f8a4ada6"},
- {file = "librt-0.8.1-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5cdc0f588ff4b663ea96c26d2a230c525c6fc62b28314edaaaca8ed5af931ad0"},
- {file = "librt-0.8.1-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97c2b54ff6717a7a563b72627990bec60d8029df17df423f0ed37d56a17a176b"},
- {file = "librt-0.8.1-cp310-cp310-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:8f1125e6bbf2f1657d9a2f3ccc4a2c9b0c8b176965bb565dd4d86be67eddb4b6"},
- {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8f4bb453f408137d7581be309b2fbc6868a80e7ef60c88e689078ee3a296ae71"},
- {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c336d61d2fe74a3195edc1646d53ff1cddd3a9600b09fa6ab75e5514ba4862a7"},
- {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_riscv64.whl", hash = "sha256:eb5656019db7c4deacf0c1a55a898c5bb8f989be904597fcb5232a2f4828fa05"},
- {file = "librt-0.8.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c25d9e338d5bed46c1632f851babf3d13c78f49a225462017cf5e11e845c5891"},
- {file = "librt-0.8.1-cp310-cp310-win32.whl", hash = "sha256:aaab0e307e344cb28d800957ef3ec16605146ef0e59e059a60a176d19543d1b7"},
- {file = "librt-0.8.1-cp310-cp310-win_amd64.whl", hash = "sha256:56e04c14b696300d47b3bc5f1d10a00e86ae978886d0cee14e5714fafb5df5d2"},
- {file = "librt-0.8.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:681dc2451d6d846794a828c16c22dc452d924e9f700a485b7ecb887a30aad1fd"},
- {file = "librt-0.8.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a3b4350b13cc0e6f5bec8fa7caf29a8fb8cdc051a3bae45cfbfd7ce64f009965"},
- {file = "librt-0.8.1-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:ac1e7817fd0ed3d14fd7c5df91daed84c48e4c2a11ee99c0547f9f62fdae13da"},
- {file = "librt-0.8.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:747328be0c5b7075cde86a0e09d7a9196029800ba75a1689332348e998fb85c0"},
- {file = "librt-0.8.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0af2bd2bc204fa27f3d6711d0f360e6b8c684a035206257a81673ab924aa11e"},
- {file = "librt-0.8.1-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d480de377f5b687b6b1bc0c0407426da556e2a757633cc7e4d2e1a057aa688f3"},
- {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d0ee06b5b5291f609ddb37b9750985b27bc567791bc87c76a569b3feed8481ac"},
- {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9e2c6f77b9ad48ce5603b83b7da9ee3e36b3ab425353f695cba13200c5d96596"},
- {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:439352ba9373f11cb8e1933da194dcc6206daf779ff8df0ed69c5e39113e6a99"},
- {file = "librt-0.8.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:82210adabbc331dbb65d7868b105185464ef13f56f7f76688565ad79f648b0fe"},
- {file = "librt-0.8.1-cp311-cp311-win32.whl", hash = "sha256:52c224e14614b750c0a6d97368e16804a98c684657c7518752c356834fff83bb"},
- {file = "librt-0.8.1-cp311-cp311-win_amd64.whl", hash = "sha256:c00e5c884f528c9932d278d5c9cbbea38a6b81eb62c02e06ae53751a83a4d52b"},
- {file = "librt-0.8.1-cp311-cp311-win_arm64.whl", hash = "sha256:f7cdf7f26c2286ffb02e46d7bac56c94655540b26347673bea15fa52a6af17e9"},
- {file = "librt-0.8.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a28f2612ab566b17f3698b0da021ff9960610301607c9a5e8eaca62f5e1c350a"},
- {file = "librt-0.8.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:60a78b694c9aee2a0f1aaeaa7d101cf713e92e8423a941d2897f4fa37908dab9"},
- {file = "librt-0.8.1-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:758509ea3f1eba2a57558e7e98f4659d0ea7670bff49673b0dde18a3c7e6c0eb"},
- {file = "librt-0.8.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:039b9f2c506bd0ab0f8725aa5ba339c6f0cd19d3b514b50d134789809c24285d"},
- {file = "librt-0.8.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5bb54f1205a3a6ab41a6fd71dfcdcbd278670d3a90ca502a30d9da583105b6f7"},
- {file = "librt-0.8.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:05bd41cdee35b0c59c259f870f6da532a2c5ca57db95b5f23689fcb5c9e42440"},
- {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adfab487facf03f0d0857b8710cf82d0704a309d8ffc33b03d9302b4c64e91a9"},
- {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:153188fe98a72f206042be10a2c6026139852805215ed9539186312d50a8e972"},
- {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:dd3c41254ee98604b08bd5b3af5bf0a89740d4ee0711de95b65166bf44091921"},
- {file = "librt-0.8.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e0d138c7ae532908cbb342162b2611dbd4d90c941cd25ab82084aaf71d2c0bd0"},
- {file = "librt-0.8.1-cp312-cp312-win32.whl", hash = "sha256:43353b943613c5d9c49a25aaffdba46f888ec354e71e3529a00cca3f04d66a7a"},
- {file = "librt-0.8.1-cp312-cp312-win_amd64.whl", hash = "sha256:ff8baf1f8d3f4b6b7257fcb75a501f2a5499d0dda57645baa09d4d0d34b19444"},
- {file = "librt-0.8.1-cp312-cp312-win_arm64.whl", hash = "sha256:0f2ae3725904f7377e11cc37722d5d401e8b3d5851fb9273d7f4fe04f6b3d37d"},
- {file = "librt-0.8.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:7e6bad1cd94f6764e1e21950542f818a09316645337fd5ab9a7acc45d99a8f35"},
- {file = "librt-0.8.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cf450f498c30af55551ba4f66b9123b7185362ec8b625a773b3d39aa1a717583"},
- {file = "librt-0.8.1-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:eca45e982fa074090057132e30585a7e8674e9e885d402eae85633e9f449ce6c"},
- {file = "librt-0.8.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c3811485fccfda840861905b8c70bba5ec094e02825598bb9d4ca3936857a04"},
- {file = "librt-0.8.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e4af413908f77294605e28cfd98063f54b2c790561383971d2f52d113d9c363"},
- {file = "librt-0.8.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:5212a5bd7fae98dae95710032902edcd2ec4dc994e883294f75c857b83f9aba0"},
- {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e692aa2d1d604e6ca12d35e51fdc36f4cda6345e28e36374579f7ef3611b3012"},
- {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4be2a5c926b9770c9e08e717f05737a269b9d0ebc5d2f0060f0fe3fe9ce47acb"},
- {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fd1a720332ea335ceb544cf0a03f81df92abd4bb887679fd1e460976b0e6214b"},
- {file = "librt-0.8.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2af9e01e0ef80d95ae3c720be101227edae5f2fe7e3dc63d8857fadfc5a1d"},
- {file = "librt-0.8.1-cp313-cp313-win32.whl", hash = "sha256:086a32dbb71336627e78cc1d6ee305a68d038ef7d4c39aaff41ae8c9aa46e91a"},
- {file = "librt-0.8.1-cp313-cp313-win_amd64.whl", hash = "sha256:e11769a1dbda4da7b00a76cfffa67aa47cfa66921d2724539eee4b9ede780b79"},
- {file = "librt-0.8.1-cp313-cp313-win_arm64.whl", hash = "sha256:924817ab3141aca17893386ee13261f1d100d1ef410d70afe4389f2359fea4f0"},
- {file = "librt-0.8.1-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6cfa7fe54fd4d1f47130017351a959fe5804bda7a0bc7e07a2cdbc3fdd28d34f"},
- {file = "librt-0.8.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:228c2409c079f8c11fb2e5d7b277077f694cb93443eb760e00b3b83cb8b3176c"},
- {file = "librt-0.8.1-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:7aae78ab5e3206181780e56912d1b9bb9f90a7249ce12f0e8bf531d0462dd0fc"},
- {file = "librt-0.8.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:172d57ec04346b047ca6af181e1ea4858086c80bdf455f61994c4aa6fc3f866c"},
- {file = "librt-0.8.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b1977c4ea97ce5eb7755a78fae68d87e4102e4aaf54985e8b56806849cc06a3"},
- {file = "librt-0.8.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:10c42e1f6fd06733ef65ae7bebce2872bcafd8d6e6b0a08fe0a05a23b044fb14"},
- {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4c8dfa264b9193c4ee19113c985c95f876fae5e51f731494fc4e0cf594990ba7"},
- {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:01170b6729a438f0dedc4a26ed342e3dc4f02d1000b4b19f980e1877f0c297e6"},
- {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:7b02679a0d783bdae30d443025b94465d8c3dc512f32f5b5031f93f57ac32071"},
- {file = "librt-0.8.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:190b109bb69592a3401fe1ffdea41a2e73370ace2ffdc4a0e8e2b39cdea81b78"},
- {file = "librt-0.8.1-cp314-cp314-win32.whl", hash = "sha256:e70a57ecf89a0f64c24e37f38d3fe217a58169d2fe6ed6d70554964042474023"},
- {file = "librt-0.8.1-cp314-cp314-win_amd64.whl", hash = "sha256:7e2f3edca35664499fbb36e4770650c4bd4a08abc1f4458eab9df4ec56389730"},
- {file = "librt-0.8.1-cp314-cp314-win_arm64.whl", hash = "sha256:0d2f82168e55ddefd27c01c654ce52379c0750ddc31ee86b4b266bcf4d65f2a3"},
- {file = "librt-0.8.1-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:2c74a2da57a094bd48d03fa5d196da83d2815678385d2978657499063709abe1"},
- {file = "librt-0.8.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:a355d99c4c0d8e5b770313b8b247411ed40949ca44e33e46a4789b9293a907ee"},
- {file = "librt-0.8.1-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2eb345e8b33fb748227409c9f1233d4df354d6e54091f0e8fc53acdb2ffedeb7"},
- {file = "librt-0.8.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9be2f15e53ce4e83cc08adc29b26fb5978db62ef2a366fbdf716c8a6c8901040"},
- {file = "librt-0.8.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:785ae29c1f5c6e7c2cde2c7c0e148147f4503da3abc5d44d482068da5322fd9e"},
- {file = "librt-0.8.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:1d3a7da44baf692f0c6aeb5b2a09c5e6fc7a703bca9ffa337ddd2e2da53f7732"},
- {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:5fc48998000cbc39ec0d5311312dda93ecf92b39aaf184c5e817d5d440b29624"},
- {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:e96baa6820280077a78244b2e06e416480ed859bbd8e5d641cf5742919d8beb4"},
- {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:31362dbfe297b23590530007062c32c6f6176f6099646bb2c95ab1b00a57c382"},
- {file = "librt-0.8.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cc3656283d11540ab0ea01978378e73e10002145117055e03722417aeab30994"},
- {file = "librt-0.8.1-cp314-cp314t-win32.whl", hash = "sha256:738f08021b3142c2918c03692608baed43bc51144c29e35807682f8070ee2a3a"},
- {file = "librt-0.8.1-cp314-cp314t-win_amd64.whl", hash = "sha256:89815a22daf9c51884fb5dbe4f1ef65ee6a146e0b6a8df05f753e2e4a9359bf4"},
- {file = "librt-0.8.1-cp314-cp314t-win_arm64.whl", hash = "sha256:bf512a71a23504ed08103a13c941f763db13fb11177beb3d9244c98c29fb4a61"},
- {file = "librt-0.8.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3dff3d3ca8db20e783b1bc7de49c0a2ab0b8387f31236d6a026597d07fcd68ac"},
- {file = "librt-0.8.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08eec3a1fc435f0d09c87b6bf1ec798986a3544f446b864e4099633a56fcd9ed"},
- {file = "librt-0.8.1-cp39-cp39-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e3f0a41487fd5fad7e760b9e8a90e251e27c2816fbc2cff36a22a0e6bcbbd9dd"},
- {file = "librt-0.8.1-cp39-cp39-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bacdb58d9939d95cc557b4dbaa86527c9db2ac1ed76a18bc8d26f6dc8647d851"},
- {file = "librt-0.8.1-cp39-cp39-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b6d7ab1f01aa753188605b09a51faa44a3327400b00b8cce424c71910fc0a128"},
- {file = "librt-0.8.1-cp39-cp39-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4998009e7cb9e896569f4be7004f09d0ed70d386fa99d42b6d363f6d200501ac"},
- {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2cc68eeeef5e906839c7bb0815748b5b0a974ec27125beefc0f942715785b551"},
- {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:0bf69d79a23f4f40b8673a947a234baeeb133b5078b483b7297c5916539cf5d5"},
- {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_riscv64.whl", hash = "sha256:22b46eabd76c1986ee7d231b0765ad387d7673bbd996aa0d0d054b38ac65d8f6"},
- {file = "librt-0.8.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:237796479f4d0637d6b9cbcb926ff424a97735e68ade6facf402df4ec93375ed"},
- {file = "librt-0.8.1-cp39-cp39-win32.whl", hash = "sha256:4beb04b8c66c6ae62f8c1e0b2f097c1ebad9295c929a8d5286c05eae7c2fc7dc"},
- {file = "librt-0.8.1-cp39-cp39-win_amd64.whl", hash = "sha256:64548cde61b692dc0dc379f4b5f59a2f582c2ebe7890d09c1ae3b9e66fa015b7"},
- {file = "librt-0.8.1.tar.gz", hash = "sha256:be46a14693955b3bd96014ccbdb8339ee8c9346fbe11c1b78901b55125f14c73"},
+ {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]]
@@ -2780,14 +2835,14 @@ mdformat = ">=0.7.21"
[[package]]
name = "mkdocs-material"
-version = "9.7.5"
+version = "9.7.6"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
- {file = "mkdocs_material-9.7.5-py3-none-any.whl", hash = "sha256:7cf9df2ff121fd098ff6e05c732b0be3699afca9642e2dfe4926c40eb5873eec"},
- {file = "mkdocs_material-9.7.5.tar.gz", hash = "sha256:f76bdab532bad1d9c57ca7187b37eccf64dd12e1586909307f8856db3be384ea"},
+ {file = "mkdocs_material-9.7.6-py3-none-any.whl", hash = "sha256:71b84353921b8ea1ba84fe11c50912cc512da8fe0881038fcc9a0761c0e635ba"},
+ {file = "mkdocs_material-9.7.6.tar.gz", hash = "sha256:00bdde50574f776d328b1862fe65daeaf581ec309bd150f7bff345a098c64a69"},
]
[package.dependencies]
@@ -2912,58 +2967,68 @@ dill = ">=0.4.1"
[[package]]
name = "mypy"
-version = "1.19.1"
+version = "2.1.0"
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-2.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:11a6beb180257a805961aea9ec591bbd0bd17f1e18d35b8456d57aee5bedfedc"},
+ {file = "mypy-2.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8ef78c1d306bbf9a8a12f526c44902c9c28dffd6c52c52bf6a72641ce18d3849"},
+ {file = "mypy-2.1.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c209a90853081ff01d01ee895cafe10f7db1474e0d95beaeef0f6c1db9119bbd"},
+ {file = "mypy-2.1.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:47cebf61abde7c088a4e27718a8b13a81655686b2e9c251f5c0915a802248166"},
+ {file = "mypy-2.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d57a90ae5e872138a425ec328edbc9b235d1934c4377881a33ec05b341acc9a8"},
+ {file = "mypy-2.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:aea7f7a8a55b459c34275fc468ada6ca7c173a5e43a68f5dbe588a563d8a06b8"},
+ {file = "mypy-2.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:c989640253f0d76843e9c6c1bbf4bd48c5e85ada61bde4beb37cb3eca035685e"},
+ {file = "mypy-2.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a683016b16fe2f572dc04c72be7ee0504ac1605a265d0200f5cea695fb788f41"},
+ {file = "mypy-2.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1a293c534adb55271fef24a26da04b855540a8c13cc07bc5917b9fd2c394f2ca"},
+ {file = "mypy-2.1.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7406f4d048e71e576f5356d317e5b0a9e666dfd966bd99f9d14ca06e1a341538"},
+ {file = "mypy-2.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e0210d626fc8b31ccc90233754c7bc90e1f43205e85d96387f7db1285b55c398"},
+ {file = "mypy-2.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3712c20deed54e814eaaa825603bada8ea1c390670a397c95b98405347acc563"},
+ {file = "mypy-2.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fcaa0e479066e31f7cceb6a3bea39cb22b2ff51a6b2f24f193d19179ba17c389"},
+ {file = "mypy-2.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:0b1a5260c95aa443083f9ed3592662941951bca3d4ca224a5dc517c38b7cf666"},
+ {file = "mypy-2.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:244358bf1c0da7722230bce60683d52e8e9fd030554926f15b747a84efb5b3af"},
+ {file = "mypy-2.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4ec7c57657493c7a75534df2751c8ae2cda383c16ecc55d2106c54476b1b16f6"},
+ {file = "mypy-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8161b6ff4392410023224f0969d17db93e1e154bc3e4ba62598e720723ae211"},
+ {file = "mypy-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf03e12003084a67395184d3eb8cbd6a489dc3655b5664b28c210a9e2403ab0b"},
+ {file = "mypy-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:20509760fd791c51579d573153407d226385ec1f8bcce55d730b354f3336bc22"},
+ {file = "mypy-2.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:6753d0c1fdd6b1a23b9e4f283ce80b2153b724adcb2653b20b85a8a28ac6436b"},
+ {file = "mypy-2.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:98ebb6589bb3b6d0c6f0c459d53ca55b8091fbc13d277c4041c885392e8195e8"},
+ {file = "mypy-2.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35aac3bb114e03888f535d5eb51b8bafbb3266586b599da1940f9b1be3ec5bd5"},
+ {file = "mypy-2.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8de55a8c861f2a49331f807be98d90caeceeef520bde13d43a160207f8af613e"},
+ {file = "mypy-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5fdf2941a07434af755837d9880f7d7d25f1dacb1af9dcd4b9b66f2220a3024e"},
+ {file = "mypy-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e195b817c13f02352a9c124301f9f30f078405444679b6753c1b96b6eed37285"},
+ {file = "mypy-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5431d42af987ebd92ba2f71d45c85ed41d8e6ca9f5fd209a69f68f707d2469e5"},
+ {file = "mypy-2.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:767fe8c66dc3e01e19e1737d4c38ebefead16125e1b8e58ad421903b376f5c65"},
+ {file = "mypy-2.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:ecfe70d43775ab99562ab128ce49854a362044c9f894961f68f898c23cb7429d"},
+ {file = "mypy-2.1.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:7354c5a7f69d9345c3d6e69921d57088eea3ddeeb6b20d34c1b3855b02c36ec2"},
+ {file = "mypy-2.1.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49890d4f76ac9e06ec117f9e09f3174da70a620a0c300953d8595c926e80947f"},
+ {file = "mypy-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:761be68e023ef5d94678772396a8af1220030f80837a3afd8d0aef3b419666f4"},
+ {file = "mypy-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c90345fc182dc363b891350457ec69c35140858538f38b4540845afcc32b1aef"},
+ {file = "mypy-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:b84802e7b5a6daf1f5e15bc9fcd7ddae77be13981ffab037f1c67bb84d67d135"},
+ {file = "mypy-2.1.0-cp314-cp314-win_amd64.whl", hash = "sha256:022c771234936ceac541ebaf836fe9e2abeb3f5e09aff21588fe543ff006fe21"},
+ {file = "mypy-2.1.0-cp314-cp314-win_arm64.whl", hash = "sha256:498207db725cec88829a6a5c2fc771205fd043719ef98bc49aba8fb9fc4e6d57"},
+ {file = "mypy-2.1.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7d5e5cad0efeba72b93cd17490cc0d69c5ac9ca132994fe3fb0314808aeeb83e"},
+ {file = "mypy-2.1.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:ff715050c127d724fd260a2e666e7747fdd83511c0c47d449d98238970aef780"},
+ {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:82208da9e09414d520e912d3e462d454854bed0810b71540bb016dcbca7308fd"},
+ {file = "mypy-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e79ebc1b904b84f0310dff7469655a9c36c7a68bddb37bdd42b67a332df61d08"},
+ {file = "mypy-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e583edc957cfb0deb142079162ae826f58449b116c1d442f2d91c69d9fced081"},
+ {file = "mypy-2.1.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b33b6cd332695bba180d55e717a79d3038e479a2c49cc5eb3d53603409b9a5d7"},
+ {file = "mypy-2.1.0-cp314-cp314t-win_arm64.whl", hash = "sha256:4f910fe825376a7b66ef7ca8c98e5a149e8cd64c19ae71d84047a74ee060d4e6"},
+ {file = "mypy-2.1.0-py3-none-any.whl", hash = "sha256:a663814603a5c563fb87a4f96fb473eeb30d1f5a4885afcf44f9db000a366289"},
+ {file = "mypy-2.1.0.tar.gz", hash = "sha256:81e76ad12c2d804512e9b13240d1588316531bfba07558286078bfbce9613633"},
]
[package.dependencies]
-librt = {version = ">=0.6.2", markers = "platform_python_implementation != \"PyPy\""}
+ast-serialize = ">=0.3.0,<1.0.0"
+librt = {version = ">=0.11.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)"]
@@ -2974,14 +3039,14 @@ reports = ["lxml"]
[[package]]
name = "mypy-boto3-appconfig"
-version = "1.42.3"
-description = "Type annotations for boto3 AppConfig 1.42.3 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 AppConfig 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_appconfig-1.42.3-py3-none-any.whl", hash = "sha256:88857735f2615bcad49e254c12585a29bdf4fbe348d1f72907210569ec97455e"},
- {file = "mypy_boto3_appconfig-1.42.3.tar.gz", hash = "sha256:606d37765259c854a3574eacc3fe5ca3956b5c456b12ff80c8e1cb20bdab9119"},
+ {file = "mypy_boto3_appconfig-1.43.0-py3-none-any.whl", hash = "sha256:d9ce0805d58653ec948a9674b53854ef5fcd3318f12b619cfa7052045b7852f9"},
+ {file = "mypy_boto3_appconfig-1.43.0.tar.gz", hash = "sha256:25c5e8fdd19dd1a790ceb2450bdb1c3c7288d939daf8f6962d6559c02d7b8a0a"},
]
[package.dependencies]
@@ -2989,14 +3054,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-appconfigdata"
-version = "1.42.3"
-description = "Type annotations for boto3 AppConfigData 1.42.3 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 AppConfigData 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_appconfigdata-1.42.3-py3-none-any.whl", hash = "sha256:3ef47224643a511bd217a92c3360cccf39be8393ed218a199555bc0592ede64f"},
- {file = "mypy_boto3_appconfigdata-1.42.3.tar.gz", hash = "sha256:595e36e9f477205916e1f11d28c6c335d606a20e55bcb793a43a4b48a4b2b32d"},
+ {file = "mypy_boto3_appconfigdata-1.43.0-py3-none-any.whl", hash = "sha256:a80c07bc643d9af1f934a4b76fe6ab0304f03d913bc7393eefe527e2072baa92"},
+ {file = "mypy_boto3_appconfigdata-1.43.0.tar.gz", hash = "sha256:9570014a955620507743e66b93c5e5e6da07b39b48f146c7abc6b259ab39d562"},
]
[package.dependencies]
@@ -3004,14 +3069,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-cloudformation"
-version = "1.42.3"
-description = "Type annotations for boto3 CloudFormation 1.42.3 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 CloudFormation 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_cloudformation-1.42.3-py3-none-any.whl", hash = "sha256:d4c802dd78844f10e944143b9f40c2c1199ed5f57f3540ab7bfc2281ac5bcaf0"},
- {file = "mypy_boto3_cloudformation-1.42.3.tar.gz", hash = "sha256:3bd3849bc89a371d4c368691535b320244ba00579cddd63bb58b73f28d70e510"},
+ {file = "mypy_boto3_cloudformation-1.43.0-py3-none-any.whl", hash = "sha256:bcb2f8b8231f6bd96cc18d17c1c72ea0dfa6dc8156966d8d12495445f5041f4c"},
+ {file = "mypy_boto3_cloudformation-1.43.0.tar.gz", hash = "sha256:5be845bc3dc1b9cdbd8b6b071fad7c42d0221d4087ac0cc7c5b9dd219b324606"},
]
[package.dependencies]
@@ -3019,14 +3084,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-cloudwatch"
-version = "1.42.56"
-description = "Type annotations for boto3 CloudWatch 1.42.56 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.2"
+description = "Type annotations for boto3 CloudWatch 1.43.2 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_cloudwatch-1.42.56-py3-none-any.whl", hash = "sha256:40621e91fbad74a739cdfb76bd5e331059a3d1bc13ae866ab332bf20641c1574"},
- {file = "mypy_boto3_cloudwatch-1.42.56.tar.gz", hash = "sha256:6791ab895dbd2c2871f8c0d686ae5adb39418dbd46515996e2c80a59664d0dcf"},
+ {file = "mypy_boto3_cloudwatch-1.43.2-py3-none-any.whl", hash = "sha256:954a9ac4a7d24310aa4df4e3de943fcc1fedb0b1cd0361c51d05951df0ac7918"},
+ {file = "mypy_boto3_cloudwatch-1.43.2.tar.gz", hash = "sha256:a08fb826321b88da8043a4175d7dce7a28119ac22aca6e12d938b0ae33228d05"},
]
[package.dependencies]
@@ -3034,14 +3099,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-dynamodb"
-version = "1.42.55"
-description = "Type annotations for boto3 DynamoDB 1.42.55 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 DynamoDB 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_dynamodb-1.42.55-py3-none-any.whl", hash = "sha256:652af33641601d223fb35207b89bd98513a7493d2b95ae4cba47c925b6ec103c"},
- {file = "mypy_boto3_dynamodb-1.42.55.tar.gz", hash = "sha256:a445f439b6bc4532fd592cb7f44444c8fc8f397271c0d9087e712f71f196d2f9"},
+ {file = "mypy_boto3_dynamodb-1.43.0-py3-none-any.whl", hash = "sha256:60b64d15e86d406a980d96f734d8c7fb1704668d0234dc8dabd2532c902a3ba6"},
+ {file = "mypy_boto3_dynamodb-1.43.0.tar.gz", hash = "sha256:f0cea38e058f1d07361ecb55d8f40665d824b42cf4864724c7fccc8bf3946fcd"},
]
[package.dependencies]
@@ -3049,14 +3114,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-lambda"
-version = "1.42.37"
-description = "Type annotations for boto3 Lambda 1.42.37 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 Lambda 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_lambda-1.42.37-py3-none-any.whl", hash = "sha256:9614518cbe3c300d3d1e2d9c3d857c3829c44a8544c4cd4ca393d35181b22619"},
- {file = "mypy_boto3_lambda-1.42.37.tar.gz", hash = "sha256:94f7f0708f9b5ffa5b8b3eb6d564be1ef402ebb8b8cd96045332b7a3bc1ea0e0"},
+ {file = "mypy_boto3_lambda-1.43.0-py3-none-any.whl", hash = "sha256:847b8f12b74f881c743464cd0010a04e2b21201b39ac92b1040c6cd276bac4e6"},
+ {file = "mypy_boto3_lambda-1.43.0.tar.gz", hash = "sha256:a58de26b5c13be54deab31723ee9ab7aaa922be1dfbd093dc3a4ca12cc853157"},
]
[package.dependencies]
@@ -3064,14 +3129,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-logs"
-version = "1.42.60"
-description = "Type annotations for boto3 CloudWatchLogs 1.42.60 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.3"
+description = "Type annotations for boto3 CloudWatchLogs 1.43.3 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_logs-1.42.60-py3-none-any.whl", hash = "sha256:4a34c1224a11d09b883789c47f1bd2910e7b50151fdec63266f7ff543caca3d0"},
- {file = "mypy_boto3_logs-1.42.60.tar.gz", hash = "sha256:08110d32d9332d7aa08c2cba0f5c3813ed1beb74c682e7407519fe4f3d1b2bff"},
+ {file = "mypy_boto3_logs-1.43.3-py3-none-any.whl", hash = "sha256:853652fb1fb9de9eb1439c9ebbe578afe080cc7693d12e3ea778bba636aeb836"},
+ {file = "mypy_boto3_logs-1.43.3.tar.gz", hash = "sha256:9c7484a6f848e7e5c346a2ea85663c24d282ae78797748321117b262d6ea845c"},
]
[package.dependencies]
@@ -3079,14 +3144,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-s3"
-version = "1.42.67"
-description = "Type annotations for boto3 S3 1.42.67 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 S3 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_s3-1.42.67-py3-none-any.whl", hash = "sha256:93208799734611da4caa5fa8f5ce677b62758ddcd34b737b9f7ae471d179b95e"},
- {file = "mypy_boto3_s3-1.42.67.tar.gz", hash = "sha256:3a3a918a9949f2d6f8071d490b8968ddce634aa19590697537e5189cbdca403e"},
+ {file = "mypy_boto3_s3-1.43.0-py3-none-any.whl", hash = "sha256:aaa7991e7ffafcf8ff4fb23c5fb4cc4554ef5724c889ff016b87e60f27405b5b"},
+ {file = "mypy_boto3_s3-1.43.0.tar.gz", hash = "sha256:3bfb027b1f3df9316ff72ff29f4b2dc0d7d65ed5032d8bcf4892222994228588"},
]
[package.dependencies]
@@ -3094,14 +3159,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-secretsmanager"
-version = "1.42.8"
-description = "Type annotations for boto3 SecretsManager 1.42.8 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 SecretsManager 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_secretsmanager-1.42.8-py3-none-any.whl", hash = "sha256:50c891a88e725a8dba7444018e47590ea63d8e938abe2b1c0b25e5413f39d51d"},
- {file = "mypy_boto3_secretsmanager-1.42.8.tar.gz", hash = "sha256:5ab42f35ce932765ebb1684146f478a87cc4b83bef950fd1aa0e268b88d59c81"},
+ {file = "mypy_boto3_secretsmanager-1.43.0-py3-none-any.whl", hash = "sha256:38415cdecb73dd20e485707a7cf456f6dde54ff4b155e7fb255eb001eb47d5bc"},
+ {file = "mypy_boto3_secretsmanager-1.43.0.tar.gz", hash = "sha256:265ee2fddf9d3e42ae39685625fb7861a539110d8e324372847c0e1cbd666b20"},
]
[package.dependencies]
@@ -3109,14 +3174,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-ssm"
-version = "1.42.54"
-description = "Type annotations for boto3 SSM 1.42.54 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 SSM 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_ssm-1.42.54-py3-none-any.whl", hash = "sha256:dfd70aa5f60be70437b53482fa6e183bafe922598a50fc6c51f6ad3bd70d8c04"},
- {file = "mypy_boto3_ssm-1.42.54.tar.gz", hash = "sha256:f4bc19a08635757808b66ef94a5b52c3729da998587745962626e60606a1be2c"},
+ {file = "mypy_boto3_ssm-1.43.0-py3-none-any.whl", hash = "sha256:56caee120bdc601aec269b4203e67365db7f1531797d87ff616e318249fc1399"},
+ {file = "mypy_boto3_ssm-1.43.0.tar.gz", hash = "sha256:33cb659b6182160141f9598fbdf6ff921dc94247a86f62152abd870b24e4ff62"},
]
[package.dependencies]
@@ -3124,14 +3189,14 @@ typing-extensions = {version = "*", markers = "python_version < \"3.12\""}
[[package]]
name = "mypy-boto3-xray"
-version = "1.42.3"
-description = "Type annotations for boto3 XRay 1.42.3 service generated with mypy-boto3-builder 8.12.0"
+version = "1.43.0"
+description = "Type annotations for boto3 XRay 1.43.0 service generated with mypy-boto3-builder 8.12.0"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "mypy_boto3_xray-1.42.3-py3-none-any.whl", hash = "sha256:a8bd87257e3931a415bee6b82892190f3588580dbaf0b54233f348a8f27ebccd"},
- {file = "mypy_boto3_xray-1.42.3.tar.gz", hash = "sha256:8092c41967eed2d0fee096a22b082bb107cfe2bb467a8dd7fbdc392593f1969c"},
+ {file = "mypy_boto3_xray-1.43.0-py3-none-any.whl", hash = "sha256:122dd8b99fcd6cbd66314211b692ff32c96a4d9dd02b40d82b5a376faf279a6e"},
+ {file = "mypy_boto3_xray-1.43.0.tar.gz", hash = "sha256:68800f2eb955a85d166ad462b5f9563cbd6d0578845807137c93cd3f8e70eb44"},
]
[package.dependencies]
@@ -3177,7 +3242,7 @@ description = "Python package for creating and manipulating graphs and networks"
optional = false
python-versions = ">=3.11"
groups = ["dev"]
-markers = "python_version >= \"3.14.0\""
+markers = "python_version >= \"3.14.0\" and python_version < \"3.15\""
files = [
{file = "networkx-3.6-py3-none-any.whl", hash = "sha256:cdb395b105806062473d3be36458d8f1459a4e4b98e236a66c3a48996e07684f"},
{file = "networkx-3.6.tar.gz", hash = "sha256:285276002ad1f7f7da0f7b42f004bcba70d381e936559166363707fdad3d72ad"},
@@ -3201,7 +3266,7 @@ description = "Python package for creating and manipulating graphs and networks"
optional = false
python-versions = "!=3.14.1,>=3.11"
groups = ["dev"]
-markers = "python_version >= \"3.11.0\" and python_version < \"3.14.0\""
+markers = "python_version >= \"3.11.0\" and python_version < \"3.14.0\" or python_version >= \"3.15\""
files = [
{file = "networkx-3.6.1-py3-none-any.whl", hash = "sha256:d47fbf302e7d9cbbb9e2555a0d267983d2aa476bac30e90dfbe5669bd57f3762"},
{file = "networkx-3.6.1.tar.gz", hash = "sha256:26b7c357accc0c8cde558ad486283728b65b6a95d85ee1cd66bafab4c8168509"},
@@ -3220,14 +3285,14 @@ test-extras = ["pytest-mpl", "pytest-randomly"]
[[package]]
name = "nox"
-version = "2026.2.9"
+version = "2026.4.10"
description = "Flexible test automation."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "nox-2026.2.9-py3-none-any.whl", hash = "sha256:1b7143bc8ecdf25f2353201326152c5303ae4ae56ca097b1fb6179ad75164c47"},
- {file = "nox-2026.2.9.tar.gz", hash = "sha256:1bc8a202ee8cd69be7aaada63b2a7019126899a06fc930a7aee75585bf8ee41b"},
+ {file = "nox-2026.4.10-py3-none-any.whl", hash = "sha256:082c117627590d9b90aa21f86df89b310b07c5842539524203bcb3c719f116c1"},
+ {file = "nox-2026.4.10.tar.gz", hash = "sha256:2d0af5374f3f37a295428c927d1b04a8182aa01762897d172446dda2f1ce9692"},
]
[package.dependencies]
@@ -3242,7 +3307,7 @@ virtualenv = {version = ">=20.15", markers = "python_version >= \"3.10\""}
[package.extras]
pbs = ["pbs-installer[all] (>=2025.1.6)"]
-tox-to-nox = ["importlib-resources ; python_version < \"3.9\"", "jinja2", "tox (>=4)"]
+tox-to-nox = ["jinja2", "tox (>=4)"]
uv = ["uv (>=0.1.6)"]
[[package]]
@@ -3353,6 +3418,7 @@ files = [
{file = "protobuf-7.34.1-py3-none-any.whl", hash = "sha256:bb3812cd53aefea2b028ef42bd780f5b96407247f20c6ef7c679807e9d188f11"},
{file = "protobuf-7.34.1.tar.gz", hash = "sha256:9ce42245e704cc5027be797c1db1eb93184d44d1cdd71811fb2d9b25ad541280"},
]
+markers = {main = "extra == \"kafka-consumer-protobuf\" or extra == \"valkey\""}
[[package]]
name = "publication"
@@ -3551,15 +3617,15 @@ typing-extensions = ">=4.14.1"
[[package]]
name = "pydantic-settings"
-version = "2.13.1"
+version = "2.14.1"
description = "Settings management using Pydantic"
optional = true
python-versions = ">=3.10"
groups = ["main"]
markers = "extra == \"all\""
files = [
- {file = "pydantic_settings-2.13.1-py3-none-any.whl", hash = "sha256:d56fd801823dbeae7f0975e1f8c8e25c258eb75d278ea7abb5d9cebb01b56237"},
- {file = "pydantic_settings-2.13.1.tar.gz", hash = "sha256:b4c11847b15237fb0171e1462bf540e294affb9b86db4d9aa5c01730bdbe4025"},
+ {file = "pydantic_settings-2.14.1-py3-none-any.whl", hash = "sha256:6e3c7edfd8277687cdc598f56e5cff0e9bfff0910a3749deaa8d4401c3a2b9de"},
+ {file = "pydantic_settings-2.14.1.tar.gz", hash = "sha256:e874d3bec7e787b0c9958277956ed9b4dd5de6a80e162188fdaff7c5e26fd5fa"},
]
[package.dependencies]
@@ -3568,7 +3634,7 @@ python-dotenv = ">=0.21.0"
typing-inspection = ">=0.4.0"
[package.extras]
-aws-secrets-manager = ["boto3 (>=1.35.0)", "boto3-stubs[secretsmanager]"]
+aws-secrets-manager = ["boto3 (>=1.35.0)", "types-boto3[secretsmanager]"]
azure-key-vault = ["azure-identity (>=1.16.0)", "azure-keyvault-secrets (>=4.8.0)"]
gcp-secret-manager = ["google-cloud-secret-manager (>=2.23.1)"]
toml = ["tomli (>=2.0.1)"]
@@ -3576,14 +3642,14 @@ yaml = ["pyyaml (>=6.0.1)"]
[[package]]
name = "pygments"
-version = "2.19.2"
+version = "2.20.0"
description = "Pygments is a syntax highlighting package written in Python."
optional = false
-python-versions = ">=3.8"
+python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b"},
- {file = "pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887"},
+ {file = "pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176"},
+ {file = "pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f"},
]
[package.extras]
@@ -3591,14 +3657,14 @@ windows-terminal = ["colorama (>=0.4.6)"]
[[package]]
name = "pymdown-extensions"
-version = "10.21"
+version = "10.21.3"
description = "Extension pack for Python Markdown."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "pymdown_extensions-10.21-py3-none-any.whl", hash = "sha256:91b879f9f864d49794c2d9534372b10150e6141096c3908a455e45ca72ad9d3f"},
- {file = "pymdown_extensions-10.21.tar.gz", hash = "sha256:39f4a020f40773f6b2ff31d2cd2546c2c04d0a6498c31d9c688d2be07e1767d5"},
+ {file = "pymdown_extensions-10.21.3-py3-none-any.whl", hash = "sha256:d7a5d08014fc571e80ca21dd6f854e31f94c489800350564d55d15b3c41e76b6"},
+ {file = "pymdown_extensions-10.21.3.tar.gz", hash = "sha256:72cfcf55f07aea0d4af2c4f11dd4e52466ddfb1bb819673146398e0bd3a77354"},
]
[package.dependencies]
@@ -3610,14 +3676,14 @@ extra = ["pygments (>=2.19.1)"]
[[package]]
name = "pytest"
-version = "9.0.2"
+version = "9.0.3"
description = "pytest: simple powerful testing with Python"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "pytest-9.0.2-py3-none-any.whl", hash = "sha256:711ffd45bf766d5264d487b917733b453d917afd2b0ad65223959f59089f875b"},
- {file = "pytest-9.0.2.tar.gz", hash = "sha256:75186651a92bd89611d1d9fc20f0b4345fd827c41ccd5c299a868a05d70edf11"},
+ {file = "pytest-9.0.3-py3-none-any.whl", hash = "sha256:2c5efc453d45394fdd706ade797c0a81091eccd1d6e4bccfcd476e2b8e0ab5d9"},
+ {file = "pytest-9.0.3.tar.gz", hash = "sha256:b86ada508af81d19edeb213c681b1d48246c1a91d304c6c81a427674c17eb91c"},
]
[package.dependencies]
@@ -3676,14 +3742,14 @@ histogram = ["pygal", "pygaljs", "setuptools"]
[[package]]
name = "pytest-cov"
-version = "7.0.0"
+version = "7.1.0"
description = "Pytest plugin for measuring coverage."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
- {file = "pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861"},
- {file = "pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1"},
+ {file = "pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678"},
+ {file = "pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2"},
]
[package.dependencies]
@@ -3714,18 +3780,18 @@ dev = ["pre-commit", "pytest-asyncio", "tox"]
[[package]]
name = "pytest-socket"
-version = "0.7.0"
+version = "0.8.0"
description = "Pytest Plugin to disable socket calls during tests"
optional = false
-python-versions = ">=3.8,<4.0"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "pytest_socket-0.7.0-py3-none-any.whl", hash = "sha256:7e0f4642177d55d317bbd58fc68c6bd9048d6eadb2d46a89307fa9221336ce45"},
- {file = "pytest_socket-0.7.0.tar.gz", hash = "sha256:71ab048cbbcb085c15a4423b73b619a8b35d6a307f46f78ea46be51b1b7e11b3"},
+ {file = "pytest_socket-0.8.0-py3-none-any.whl", hash = "sha256:81821ba59f07d7600fe2b551d8714f40b068bd46e8b6704c48664e9d60cdacb8"},
+ {file = "pytest_socket-0.8.0.tar.gz", hash = "sha256:af9bb5f487da72be63573a6194cfac033b6c7a1c1561e150521105970f9e99f2"},
]
[package.dependencies]
-pytest = ">=6.2.5"
+pytest = ">=7.0.0"
[[package]]
name = "pytest-xdist"
@@ -3759,6 +3825,7 @@ files = [
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\" or extra == \"tracer\""}
[package.dependencies]
six = ">=1.5"
@@ -3949,14 +4016,14 @@ toml = ["tomli (>=2.0.1)"]
[[package]]
name = "redis"
-version = "7.3.0"
+version = "7.4.0"
description = "Python client for Redis database and key-value store"
optional = false
python-versions = ">=3.10"
groups = ["main", "dev"]
files = [
- {file = "redis-7.3.0-py3-none-any.whl", hash = "sha256:9d4fcb002a12a5e3c3fbe005d59c48a2cc231f87fbb2f6b70c2d89bb64fec364"},
- {file = "redis-7.3.0.tar.gz", hash = "sha256:4d1b768aafcf41b01022410b3cc4f15a07d9b3d6fe0c66fc967da2c88e551034"},
+ {file = "redis-7.4.0-py3-none-any.whl", hash = "sha256:a9c74a5c893a5ef8455a5adb793a31bb70feb821c86eccb62eebef5a19c429ec"},
+ {file = "redis-7.4.0.tar.gz", hash = "sha256:64a6ea7bf567ad43c964d2c30d82853f8df927c5c9017766c55a1d1ed95d18ad"},
]
markers = {main = "extra == \"redis\""}
@@ -4114,25 +4181,26 @@ files = [
[[package]]
name = "requests"
-version = "2.32.5"
+version = "2.33.1"
description = "Python HTTP for Humans."
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["main", "dev"]
files = [
- {file = "requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6"},
- {file = "requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf"},
+ {file = "requests-2.33.1-py3-none-any.whl", hash = "sha256:4e6d1ef462f3626a1f0a0a9c42dd93c63bad33f9f1c1937509b8c5c8718ab56a"},
+ {file = "requests-2.33.1.tar.gz", hash = "sha256:18817f8c57c6263968bc123d237e3b8b08ac046f5456bd1e307ee8f4250d3517"},
]
+markers = {main = "extra == \"datadog\""}
[package.dependencies]
-certifi = ">=2017.4.17"
+certifi = ">=2023.5.7"
charset_normalizer = ">=2,<4"
idna = ">=2.5,<4"
-urllib3 = ">=1.21.1,<3"
+urllib3 = ">=1.26,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
-use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
+use-chardet-on-py3 = ["chardet (>=3.0.2,<8)"]
[[package]]
name = "retry2"
@@ -4294,31 +4362,30 @@ files = [
[[package]]
name = "ruff"
-version = "0.14.14"
+version = "0.15.14"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
- {file = "ruff-0.14.14-py3-none-linux_armv6l.whl", hash = "sha256:7cfe36b56e8489dee8fbc777c61959f60ec0f1f11817e8f2415f429552846aed"},
- {file = "ruff-0.14.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6006a0082336e7920b9573ef8a7f52eec837add1265cc74e04ea8a4368cd704c"},
- {file = "ruff-0.14.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:026c1d25996818f0bf498636686199d9bd0d9d6341c9c2c3b62e2a0198b758de"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f666445819d31210b71e0a6d1c01e24447a20b85458eea25a25fe8142210ae0e"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c0f18b922c6d2ff9a5e6c3ee16259adc513ca775bcf82c67ebab7cbd9da5bc8"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1629e67489c2dea43e8658c3dba659edbfd87361624b4040d1df04c9740ae906"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:27493a2131ea0f899057d49d303e4292b2cae2bb57253c1ed1f256fbcd1da480"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:01ff589aab3f5b539e35db38425da31a57521efd1e4ad1ae08fc34dbe30bd7df"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1cc12d74eef0f29f51775f5b755913eb523546b88e2d733e1d701fe65144e89b"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bb8481604b7a9e75eff53772496201690ce2687067e038b3cc31aaf16aa0b974"},
- {file = "ruff-0.14.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:14649acb1cf7b5d2d283ebd2f58d56b75836ed8c6f329664fa91cdea19e76e66"},
- {file = "ruff-0.14.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e8058d2145566510790eab4e2fad186002e288dec5e0d343a92fe7b0bc1b3e13"},
- {file = "ruff-0.14.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:e651e977a79e4c758eb807f0481d673a67ffe53cfa92209781dfa3a996cf8412"},
- {file = "ruff-0.14.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:cc8b22da8d9d6fdd844a68ae937e2a0adf9b16514e9a97cc60355e2d4b219fc3"},
- {file = "ruff-0.14.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:16bc890fb4cc9781bb05beb5ab4cd51be9e7cb376bf1dd3580512b24eb3fda2b"},
- {file = "ruff-0.14.14-py3-none-win32.whl", hash = "sha256:b530c191970b143375b6a68e6f743800b2b786bbcf03a7965b06c4bf04568167"},
- {file = "ruff-0.14.14-py3-none-win_amd64.whl", hash = "sha256:3dde1435e6b6fe5b66506c1dff67a421d0b7f6488d466f651c07f4cab3bf20fd"},
- {file = "ruff-0.14.14-py3-none-win_arm64.whl", hash = "sha256:56e6981a98b13a32236a72a8da421d7839221fa308b223b9283312312e5ac76c"},
- {file = "ruff-0.14.14.tar.gz", hash = "sha256:2d0f819c9a90205f3a867dbbd0be083bee9912e170fd7d9704cc8ae45824896b"},
+ {file = "ruff-0.15.14-py3-none-linux_armv6l.whl", hash = "sha256:8dd2db9416e487c8d4b01fa7056bb02c4d05969d4f8d17a08c229c2f4ff3c108"},
+ {file = "ruff-0.15.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:be4ff55af755bd71a00ab3dc6bd7ffc467bd76e0df6881e286c2e3d23e8fb43b"},
+ {file = "ruff-0.15.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:48d5909d7d06276ce7dde6d32bfa4b0d4cb2651145cd8ee4b440722cbc77832f"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca8cbfa94c4f90984a67561978602746d4cd27103568f745fa90eee3f0d4107d"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a6bbc0333f1ab053423bcbf6226477d266ca7cec7738c4c8e3f55647803f3c4"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a24a4f7605d7003a6674d4387651effd939dead3fddd0f36561eb77a9a2e542"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:049b5326e53ed80978f2fc041a280603f69dd6b0c95464342a2bb4572d9d9e2f"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d4ed42e6696c8dfa5f06728e6441993901f548eb92d73bc472cb5a38d1395fbf"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:715c543cf450c4888251f91c52f1942a800541d9bddd7ac060aa4e6b77ae7cba"},
+ {file = "ruff-0.15.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:72ebab6013ec887d439d8b7593737a0a4ffb06d45d209d4e4bf2e92813082d3f"},
+ {file = "ruff-0.15.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:49072d36abdbe97a8dd7f480afe9c675699c0c495d4c84076e2c1203c4550581"},
+ {file = "ruff-0.15.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:958522aee105068640c2c2ceae08f413ae44d922f52a1374ac13d6a96032fc93"},
+ {file = "ruff-0.15.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f3707da619a143a2e8830e2abab8224478d69ace2d28cb6c20543ae97c36bf61"},
+ {file = "ruff-0.15.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:bb01d645694e3ec0102105d07ef2d53703970407d59c04e59d3ba0b7a1d53553"},
+ {file = "ruff-0.15.14-py3-none-win32.whl", hash = "sha256:6d0c1ad2a0ab718d39b6d8fd2217981ce4d625cd96a720095f798fb47d8b13e6"},
+ {file = "ruff-0.15.14-py3-none-win_amd64.whl", hash = "sha256:802342981e056db3851a7836e5b070f8f15f67d4a685ae2a6160939d364b2902"},
+ {file = "ruff-0.15.14-py3-none-win_arm64.whl", hash = "sha256:ff47b90a9ef6a40c9e2f3b479c1fb78531adf055b94c1eba0a7ba04b31951826"},
+ {file = "ruff-0.15.14.tar.gz", hash = "sha256:48e866b165be4a9bdbf310f7d3c9a07edef2fe8cd63ffeb4e00bb590506ebf9f"},
]
[[package]]
@@ -4332,12 +4399,13 @@ files = [
{file = "s3transfer-0.16.0-py3-none-any.whl", hash = "sha256:18e25d66fed509e3868dc1572b3f427ff947dd2c56f844a5bf09481ad3f3b2fe"},
{file = "s3transfer-0.16.0.tar.gz", hash = "sha256:8e990f13268025792229cd52fa10cb7163744bf56e719e0b9cb925ab79abf920"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\""}
[package.dependencies]
-botocore = ">=1.37.4,<2.0a.0"
+botocore = ">=1.37.4,<2.0a0"
[package.extras]
-crt = ["botocore[crt] (>=1.37.4,<2.0a.0)"]
+crt = ["botocore[crt] (>=1.37.4,<2.0a0)"]
[[package]]
name = "scantree"
@@ -4357,14 +4425,14 @@ pathspec = ">=0.10.1"
[[package]]
name = "sentry-sdk"
-version = "2.54.0"
+version = "2.57.0"
description = "Python client for Sentry (https://sentry.io)"
optional = false
python-versions = ">=3.6"
groups = ["dev"]
files = [
- {file = "sentry_sdk-2.54.0-py2.py3-none-any.whl", hash = "sha256:fd74e0e281dcda63afff095d23ebcd6e97006102cdc8e78a29f19ecdf796a0de"},
- {file = "sentry_sdk-2.54.0.tar.gz", hash = "sha256:2620c2575128d009b11b20f7feb81e4e4e8ae08ec1d36cbc845705060b45cc1b"},
+ {file = "sentry_sdk-2.57.0-py2.py3-none-any.whl", hash = "sha256:812c8bf5ff3d2f0e89c82f5ce80ab3a6423e102729c4706af7413fd1eb480585"},
+ {file = "sentry_sdk-2.57.0.tar.gz", hash = "sha256:4be8d1e71c32fb27f79c577a337ac8912137bba4bcbc64a4ec1da4d6d8dc5199"},
]
[package.dependencies]
@@ -4375,6 +4443,7 @@ urllib3 = ">=1.26.11"
aiohttp = ["aiohttp (>=3.5)"]
anthropic = ["anthropic (>=0.16)"]
arq = ["arq (>=0.23)"]
+asyncio = ["httpcore[asyncio] (==1.*)"]
asyncpg = ["asyncpg (>=0.23)"]
beam = ["apache-beam (>=2.12)"]
bottle = ["bottle (>=0.12.13)"]
@@ -4395,7 +4464,7 @@ huggingface-hub = ["huggingface_hub (>=0.22)"]
langchain = ["langchain (>=0.0.210)"]
langgraph = ["langgraph (>=0.6.6)"]
launchdarkly = ["launchdarkly-server-sdk (>=9.8.0)"]
-litellm = ["litellm (>=1.77.5)"]
+litellm = ["litellm (>=1.77.5,!=1.82.7,!=1.82.8)"]
litestar = ["litestar (>=2.0.0)"]
loguru = ["loguru (>=0.5)"]
mcp = ["mcp (>=1.15.0)"]
@@ -4429,6 +4498,7 @@ files = [
{file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"},
{file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\" or extra == \"tracer\""}
[[package]]
name = "smmap"
@@ -4499,58 +4569,59 @@ dev = ["hypothesis (>=6.70.0)", "pytest (>=7.1.0)"]
[[package]]
name = "testcontainers"
-version = "4.14.1"
+version = "4.14.2"
description = "Python library for throwaway instances of anything that can run in a Docker container"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "testcontainers-4.14.1-py3-none-any.whl", hash = "sha256:03dfef4797b31c82e7b762a454b6afec61a2a512ad54af47ab41e4fa5415f891"},
- {file = "testcontainers-4.14.1.tar.gz", hash = "sha256:316f1bb178d829c003acd650233e3ff3c59a833a08d8661c074f58a4fbd42a64"},
+ {file = "testcontainers-4.14.2-py3-none-any.whl", hash = "sha256:0d0522c3cd8f8d9627cda41f7a6b51b639fa57bdc492923c045117933c668d68"},
+ {file = "testcontainers-4.14.2.tar.gz", hash = "sha256:1340ccf16fe3acd9389a6c9e1d9ab21d9fe99a8afdf8165f89c3e69c1967d239"},
]
[package.dependencies]
docker = "*"
python-dotenv = "*"
-redis = {version = ">=7,<8", optional = true, markers = "extra == \"generic\" or extra == \"redis\""}
+redis = {version = ">=7", optional = true, markers = "extra == \"redis\""}
typing-extensions = "*"
urllib3 = "*"
wrapt = "*"
[package.extras]
-arangodb = ["python-arango (>=8,<9)"]
-aws = ["boto3 (>=1,<2)", "httpx"]
-azurite = ["azure-storage-blob (>=12,<13)"]
-chroma = ["chromadb-client (>=1,<2)"]
-cosmosdb = ["azure-cosmos (>=4,<5)"]
-db2 = ["ibm_db_sa ; platform_machine != \"aarch64\" and platform_machine != \"arm64\"", "sqlalchemy (>=2,<3)"]
-generic = ["httpx", "redis (>=7,<8)"]
-google = ["google-cloud-datastore (>=2,<3)", "google-cloud-pubsub (>=2,<3)"]
-influxdb = ["influxdb (>=5,<6)", "influxdb-client (>=1,<2)"]
+arangodb = ["python-arango (>=8)"]
+aws = ["boto3 (>=1)", "httpx"]
+azurite = ["azure-storage-blob (>=12)"]
+chroma = ["chromadb-client (>=1)"]
+clickhouse = ["clickhouse-driver"]
+cosmosdb = ["azure-cosmos (>=4)"]
+db2 = ["ibm-db-sa ; platform_machine != \"aarch64\" and platform_machine != \"arm64\"", "sqlalchemy (>=2)"]
+generic = ["httpx", "redis (>=7)"]
+google = ["google-cloud-datastore (>=2)", "google-cloud-pubsub (>=2)"]
+influxdb = ["influxdb (>=5)", "influxdb-client (>=1)"]
k3s = ["kubernetes", "pyyaml (>=6.0.3)"]
-keycloak = ["python-keycloak (>=6,<7) ; python_version < \"4.0\""]
-localstack = ["boto3 (>=1,<2)"]
+keycloak = ["python-keycloak (>=6) ; python_version < \"4.0\""]
+localstack = ["boto3 (>=1)"]
mailpit = ["cryptography"]
-minio = ["minio (>=7,<8)"]
-mongodb = ["pymongo (>=4,<5)"]
-mssql = ["pymssql (>=2,<3)", "sqlalchemy (>=2,<3)"]
-mysql = ["pymysql[rsa] (>=1,<2)", "sqlalchemy (>=2,<3)"]
-nats = ["nats-py (>=2,<3)"]
-neo4j = ["neo4j (>=6,<7)"]
+minio = ["minio (>=7)"]
+mongodb = ["pymongo (>=4)"]
+mssql = ["pymssql (>=2)", "sqlalchemy (>=2)"]
+mysql = ["pymysql[rsa] (>=1)", "sqlalchemy (>=2)"]
+nats = ["nats-py (>=2)"]
+neo4j = ["neo4j (>=6)"]
openfga = ["openfga-sdk"]
-opensearch = ["opensearch-py (>=3,<4) ; python_version < \"4.0\""]
-oracle = ["oracledb (>=3,<4)", "sqlalchemy (>=2,<3)"]
-oracle-free = ["oracledb (>=3,<4)", "sqlalchemy (>=2,<3)"]
-qdrant = ["qdrant-client (>=1,<2)"]
-rabbitmq = ["pika (>=1,<2)"]
-redis = ["redis (>=7,<8)"]
-registry = ["bcrypt (>=5,<6)"]
-scylla = ["cassandra-driver (>=3,<4)"]
-selenium = ["selenium (>=4,<5)"]
+opensearch = ["opensearch-py (>=3) ; python_version < \"4.0\""]
+oracle = ["oracledb (>=3)", "sqlalchemy (>=2)"]
+oracle-free = ["oracledb (>=3)", "sqlalchemy (>=2)"]
+qdrant = ["qdrant-client (>=1)"]
+rabbitmq = ["pika (>=1)"]
+redis = ["redis (>=7)"]
+registry = ["bcrypt (>=5)"]
+scylla = ["cassandra-driver (>=3)"]
+selenium = ["selenium (>=4)"]
sftp = ["cryptography"]
test-module-import = ["httpx"]
trino = ["trino"]
-weaviate = ["weaviate-client (>=4,<5)"]
+weaviate = ["weaviate-client (>=4)"]
[[package]]
name = "tomli"
@@ -4612,29 +4683,30 @@ files = [
[[package]]
name = "ty"
-version = "0.0.23"
+version = "0.0.35"
description = "An extremely fast Python type checker, written in Rust."
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
- {file = "ty-0.0.23-py3-none-linux_armv6l.whl", hash = "sha256:e810eef1a5f1cfc0731a58af8d2f334906a96835829767aed00026f1334a8dd7"},
- {file = "ty-0.0.23-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e43d36bd89a151ddcad01acaeff7dcc507cb73ff164c1878d2d11549d39a061c"},
- {file = "ty-0.0.23-py3-none-macosx_11_0_arm64.whl", hash = "sha256:bd6a340969577b4645f231572c4e46012acba2d10d4c0c6570fe1ab74e76ae00"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341441783e626eeb7b1ec2160432956aed5734932ab2d1c26f94d0c98b229937"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ce1dc66c26d4167e2c78d12fa870ef5a7ec9cc344d2baaa6243297cfa88bd52"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bae1e7a294bf8528836f7617dc5c360ea2dddb63789fc9471ae6753534adca05"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d2b162768764d9dc177c83fb497a51532bb67cbebe57b8fa0f2668436bf53f3c"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d28384e48ca03b34e4e2beee0e230c39bbfb68994bb44927fec61ef3642900da"},
- {file = "ty-0.0.23-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:559d9a299df793cb7a7902caed5eda8a720ff69164c31c979673e928f02251ee"},
- {file = "ty-0.0.23-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:32a7b8a14a98e1d20a9d8d2af23637ed7efdb297ac1fa2450b8e465d05b94482"},
- {file = "ty-0.0.23-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6f803b9b9cca87af793467973b9abdd4b83e6b96d9b5e749d662cff7ead70b6d"},
- {file = "ty-0.0.23-py3-none-musllinux_1_2_i686.whl", hash = "sha256:4a0bf086ec8e2197b7ea7ebfcf4be36cb6a52b235f8be61647ef1b2d99d6ffd3"},
- {file = "ty-0.0.23-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:252539c3fcd7aeb9b8d5c14e2040682c3e1d7ff640906d63fd2c4ce35865a4ba"},
- {file = "ty-0.0.23-py3-none-win32.whl", hash = "sha256:51b591d19eef23bbc3807aef77d38fa1f003c354e1da908aa80ea2dca0993f77"},
- {file = "ty-0.0.23-py3-none-win_amd64.whl", hash = "sha256:1e137e955f05c501cfbb81dd2190c8fb7d01ec037c7e287024129c722a83c9ad"},
- {file = "ty-0.0.23-py3-none-win_arm64.whl", hash = "sha256:a0399bd13fd2cd6683fd0a2d59b9355155d46546d8203e152c556ddbdeb20842"},
- {file = "ty-0.0.23.tar.gz", hash = "sha256:5fb05db58f202af366f80ef70f806e48f5237807fe424ec787c9f289e3f3a4ef"},
+ {file = "ty-0.0.35-py3-none-linux_armv6l.whl", hash = "sha256:85ae1e59b9fb0b40e9d84fe61b29653c5f2f5e78b487ece371a7a38c20c781cf"},
+ {file = "ty-0.0.35-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:709dbb7af4fcadb1196863c00b8791bbbbcc9dacbe15a0ff17f0af82b35d415b"},
+ {file = "ty-0.0.35-py3-none-macosx_11_0_arm64.whl", hash = "sha256:2cb0877419ab0c8708b6925cb0c2800b263842bd3c425113f200538772f3a0cc"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e7afbcfc61904b7e82e7fe1a1db832a40d8f01e69dee1775f6594e552980536c"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b61498cc3e4178031c079951257fbdb209a891b4feb10ad6c40f615a51846f41"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:573b1eacda349fc8dba0d767b41631c3a6f66412363127c5bf2b1b40a1d898d2"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7209746158d6393c1040aa64b3ca29622e212ea7d8bae22ba50dbcbb4f96f0a"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4466a1470aa4418d49a9aa45d9da7de42033addd0a2837c5b2b0eb71d3c2bcd3"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eb44bb742d52c309dcaa6598bcf4d82eb4bf1241b9e4940461e522e30093fe8b"},
+ {file = "ty-0.0.35-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:34b219250736c989b2670a03782c61315f523f3a2be37f1f90b1207e2212c188"},
+ {file = "ty-0.0.35-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:88e2ac497decc0940ef1a07571dee8a746112a93a09cdc7f8bca0099752e2e05"},
+ {file = "ty-0.0.35-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:02cae51b53e6ec17d5d827ff1a3a76fd119705b56a92156e04399eda6e911596"},
+ {file = "ty-0.0.35-py3-none-musllinux_1_2_i686.whl", hash = "sha256:11871d730c9400d899ac0b9f3d660ed2e7e433377c8725549f8250a36a7f2620"},
+ {file = "ty-0.0.35-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ad0a2f0530d0933dcc99ad36ac556c63e384ea72ab9a18d23ad2e2c9fd61c73"},
+ {file = "ty-0.0.35-py3-none-win32.whl", hash = "sha256:0e25d63ec4ab116e7f6757e44d16ca9216bca679d19ecc36d119cf80faada61a"},
+ {file = "ty-0.0.35-py3-none-win_amd64.whl", hash = "sha256:6a0a6d259f6f2f8f2f954c6f013d4e0b5eba68af6b353bf19a47d59ec254a3d5"},
+ {file = "ty-0.0.35-py3-none-win_arm64.whl", hash = "sha256:619c52c0fb2aa21961a848a1995135ad3b6d0a9aa54da0194e60f679cc200e13"},
+ {file = "ty-0.0.35.tar.gz", hash = "sha256:8375c240ab38138a19db07996c9808fb7a92047c1492e1ce587c2ef5112ad3a9"},
]
[[package]]
@@ -4682,14 +4754,14 @@ types-setuptools = "*"
[[package]]
name = "types-protobuf"
-version = "6.32.1.20260221"
+version = "7.34.1.20260518"
description = "Typing stubs for protobuf"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "types_protobuf-6.32.1.20260221-py3-none-any.whl", hash = "sha256:da7cdd947975964a93c30bfbcc2c6841ee646b318d3816b033adc2c4eb6448e4"},
- {file = "types_protobuf-6.32.1.20260221.tar.gz", hash = "sha256:6d5fb060a616bfb076cbb61b4b3c3969f5fc8bec5810f9a2f7e648ee5cbcbf6e"},
+ {file = "types_protobuf-7.34.1.20260518-py3-none-any.whl", hash = "sha256:a0a5337413347166439c0e07cbc26c6164d091401c6f01b1dfd8cdb966c4dd8f"},
+ {file = "types_protobuf-7.34.1.20260518.tar.gz", hash = "sha256:28cfaded25889cb83ebfb63cfb0a43628f0b6f3785767bec17287dc6468795f2"},
]
[[package]]
@@ -4710,14 +4782,14 @@ types-cffi = "*"
[[package]]
name = "types-python-dateutil"
-version = "2.9.0.20260305"
+version = "2.9.0.20260508"
description = "Typing stubs for python-dateutil"
optional = false
python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "types_python_dateutil-2.9.0.20260305-py3-none-any.whl", hash = "sha256:a3be9ca444d38cadabd756cfbb29780d8b338ae2a3020e73c266a83cc3025dd7"},
- {file = "types_python_dateutil-2.9.0.20260305.tar.gz", hash = "sha256:389717c9f64d8f769f36d55a01873915b37e97e52ce21928198d210fbd393c8b"},
+ {file = "types_python_dateutil-2.9.0.20260508-py3-none-any.whl", hash = "sha256:bfc6fd2d81aa86e5ac97206a64304f6bd247426eedbca9b98619bbc48c6a1c10"},
+ {file = "types_python_dateutil-2.9.0.20260508.tar.gz", hash = "sha256:596a6d63d81f587bf04c8254fb78df9d2344e915ce67948d7400512e3a6206d5"},
]
[[package]]
@@ -4738,14 +4810,14 @@ types-pyOpenSSL = "*"
[[package]]
name = "types-requests"
-version = "2.32.4.20260107"
+version = "2.33.0.20260518"
description = "Typing stubs for requests"
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["dev"]
files = [
- {file = "types_requests-2.32.4.20260107-py3-none-any.whl", hash = "sha256:b703fe72f8ce5b31ef031264fe9395cac8f46a04661a79f7ed31a80fb308730d"},
- {file = "types_requests-2.32.4.20260107.tar.gz", hash = "sha256:018a11ac158f801bfa84857ddec1650750e393df8a004a8a9ae2a9bec6fcb24f"},
+ {file = "types_requests-2.33.0.20260518-py3-none-any.whl", hash = "sha256:626d697d1adaaff76e2044dc8c5c051d8f21abc157bdfe204a75558076fe0bf0"},
+ {file = "types_requests-2.33.0.20260518.tar.gz", hash = "sha256:df7bd3bfe0ca8402dfb841e7d9be714bb5578203283d66d7dc4ef69343449a5e"},
]
[package.dependencies]
@@ -4805,104 +4877,103 @@ typing-extensions = ">=4.12.0"
[[package]]
name = "ujson"
-version = "5.12.0"
+version = "5.12.1"
description = "Ultra fast JSON encoder and decoder for Python"
optional = true
python-versions = ">=3.10"
groups = ["main"]
markers = "extra == \"datadog\""
files = [
- {file = "ujson-5.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:38051f36423f084b909aaadb3b41c9c6a2958e86956ba21a8489636911e87504"},
- {file = "ujson-5.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:457fabc2700a8e6ddb85bc5a1d30d3345fe0d3ec3ee8161a4e032ec585801dfa"},
- {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:57930ac9519099b852e190d2c04b1fb5d97ea128db33bce77ed874eccb4c7f09"},
- {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:9b3b86ec3e818f3dd3e13a9de628e88a9990f4af68ecb0b12dd3de81227f0a26"},
- {file = "ujson-5.12.0-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:460e76a4daff214ae33ab959494962c93918cb44714ea3e3f748b14aa37f8a87"},
- {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e584d0cdd37cac355aca52ed788d1a2d939d6837e2870d3b70e585db24025a50"},
- {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0fe9128e75c6aa6e9ae06c1408d6edd9179a2fef0fe6d9cda3166b887eba521d"},
- {file = "ujson-5.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3ed5cb149892141b1e77ef312924a327f2cc718b34247dae346ed66329e1b8be"},
- {file = "ujson-5.12.0-cp310-cp310-win32.whl", hash = "sha256:973b7d7145b1ac553a7466a64afa8b31ec2693d7c7fff6a755059e0a2885dfd2"},
- {file = "ujson-5.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:1d072a403d82aef8090c6d4f728e3a727dfdba1ad3b7fa3a052c3ecbd37e73cb"},
- {file = "ujson-5.12.0-cp310-cp310-win_arm64.whl", hash = "sha256:55ede2a7a051b3b7e71a394978a098d71b3783e6b904702ff45483fad434ae2d"},
- {file = "ujson-5.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:58a11cb49482f1a095a2bd9a1d81dd7c8fb5d2357f959ece85db4e46a825fd00"},
- {file = "ujson-5.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9b3cf13facf6f77c283af0e1713e5e8c47a0fe295af81326cb3cb4380212e797"},
- {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:fb94245a715b4d6e24689de12772b85329a1f9946cbf6187923a64ecdea39e65"},
- {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:0fe6b8b8968e11dd9b2348bd508f0f57cf49ab3512064b36bc4117328218718e"},
- {file = "ujson-5.12.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:89e302abd3749f6d6699691747969a5d85f7c73081d5ed7e2624c7bd9721a2ab"},
- {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0727363b05ab05ee737a28f6200dc4078bce6b0508e10bd8aab507995a15df61"},
- {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b62cb9a7501e1f5c9ffe190485501349c33e8862dde4377df774e40b8166871f"},
- {file = "ujson-5.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a6ec5bf6bc361f2f0f9644907a36ce527715b488988a8df534120e5c34eeda94"},
- {file = "ujson-5.12.0-cp311-cp311-win32.whl", hash = "sha256:006428d3813b87477d72d306c40c09f898a41b968e57b15a7d88454ecc42a3fb"},
- {file = "ujson-5.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:40aa43a7a3a8d2f05e79900858053d697a88a605e3887be178b43acbcd781161"},
- {file = "ujson-5.12.0-cp311-cp311-win_arm64.whl", hash = "sha256:561f89cc82deeae82e37d4a4764184926fb432f740a9691563a391b13f7339a4"},
- {file = "ujson-5.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:09b4beff9cc91d445d5818632907b85fb06943b61cb346919ce202668bf6794a"},
- {file = "ujson-5.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ca0c7ce828bb76ab78b3991904b477c2fd0f711d7815c252d1ef28ff9450b052"},
- {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d79c6635ccffcbfc1d5c045874ba36b594589be81d50d43472570bb8de9c57"},
- {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:7e07f6f644d2c44d53b7a320a084eef98063651912c1b9449b5f45fcbdc6ccd2"},
- {file = "ujson-5.12.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:085b6ce182cdd6657481c7c4003a417e0655c4f6e58b76f26ee18f0ae21db827"},
- {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:16b4fe9c97dc605f5e1887a9e1224287291e35c56cbc379f8aa44b6b7bcfe2bb"},
- {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0d2e8db5ade3736a163906154ca686203acc7d1d30736cbf577c730d13653d84"},
- {file = "ujson-5.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:93bc91fdadcf046da37a214eaa714574e7e9b1913568e93bb09527b2ceb7f759"},
- {file = "ujson-5.12.0-cp312-cp312-win32.whl", hash = "sha256:2a248750abce1c76fbd11b2e1d88b95401e72819295c3b851ec73399d6849b3d"},
- {file = "ujson-5.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:1b5c6ceb65fecd28a1d20d1eba9dbfa992612b86594e4b6d47bb580d2dd6bcb3"},
- {file = "ujson-5.12.0-cp312-cp312-win_arm64.whl", hash = "sha256:9a5fcbe7b949f2e95c47ea8a80b410fcdf2da61c98553b45a4ee875580418b68"},
- {file = "ujson-5.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:15d416440148f3e56b9b244fdaf8a09fcf5a72e4944b8e119f5bf60417a2bfc8"},
- {file = "ujson-5.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:e0dd3676ea0837cd70ea1879765e9e9f6be063be0436de9b3ea4b775caf83654"},
- {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7bbf05c38debc90d1a195b11340cc85cb43ab3e753dc47558a3a84a38cbc72da"},
- {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:3c2f947e55d3c7cfe124dd4521ee481516f3007d13c6ad4bf6aeb722e190eb1b"},
- {file = "ujson-5.12.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ea6206043385343aff0b7da65cf73677f6f5e50de8f1c879e557f4298cac36a"},
- {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb349dbba57c76eec25e5917e07f35aabaf0a33b9e67fc13d188002500106487"},
- {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:937794042342006f707837f38d721426b11b0774d327a2a45c0bd389eb750a87"},
- {file = "ujson-5.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6ad57654570464eb1b040b5c353dee442608e06cff9102b8fcb105565a44c9ed"},
- {file = "ujson-5.12.0-cp313-cp313-win32.whl", hash = "sha256:76bf3e7406cf23a3e1ca6a23fb1fb9ea82f4f6bd226fe226e09146b0194f85dc"},
- {file = "ujson-5.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:15e555c4caca42411270b2ed2b2ebc7b3a42bb04138cef6c956e1f1d49709fe2"},
- {file = "ujson-5.12.0-cp313-cp313-win_arm64.whl", hash = "sha256:bd03472c36fa3a386a6deb887113b9e3fa40efba8203eb4fe786d3c0ccc724f6"},
- {file = "ujson-5.12.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:85833bca01aa5cae326ac759276dc175c5fa3f7b3733b7d543cf27f2df12d1ef"},
- {file = "ujson-5.12.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d22cad98c2a10bbf6aa083a8980db6ed90d4285a841c4de892890c2b28286ef9"},
- {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:99cc80facad240b0c2fb5a633044420878aac87a8e7c348b9486450cba93f27c"},
- {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:d1831c07bd4dce53c4b666fa846c7eba4b7c414f2e641a4585b7f50b72f502dc"},
- {file = "ujson-5.12.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e00cec383eab2406c9e006bd4edb55d284e94bb943fda558326048178d26961"},
- {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f19b3af31d02a2e79c5f9a6deaab0fb3c116456aeb9277d11720ad433de6dfc6"},
- {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:bacbd3c69862478cbe1c7ed4325caedec580d8acf31b8ee1b9a1e02a56295cad"},
- {file = "ujson-5.12.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:94c5f1621cbcab83c03be46441f090b68b9f307b6c7ec44d4e3f6d5997383df4"},
- {file = "ujson-5.12.0-cp314-cp314-win32.whl", hash = "sha256:e6369ac293d2cc40d52577e4fa3d75a70c1aae2d01fa3580a34a4e6eff9286b9"},
- {file = "ujson-5.12.0-cp314-cp314-win_amd64.whl", hash = "sha256:31348a0ffbfc815ce78daac569d893349d85a0b57e1cd2cdbba50b7f333784da"},
- {file = "ujson-5.12.0-cp314-cp314-win_arm64.whl", hash = "sha256:6879aed770557f0961b252648d36f6fdaab41079d37a2296b5649fd1b35608e0"},
- {file = "ujson-5.12.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:7ddb08b3c2f9213df1f2e3eb2fbea4963d80ec0f8de21f0b59898e34f3b3d96d"},
- {file = "ujson-5.12.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:0a3ae28f0b209be5af50b54ca3e2123a3de3a57d87b75f1e5aa3d7961e041983"},
- {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30ad4359413c8821cc7b3707f7ca38aa8bc852ba3b9c5a759ee2d7740157315"},
- {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:02f93da7a4115e24f886b04fd56df1ee8741c2ce4ea491b7ab3152f744ad8f8e"},
- {file = "ujson-5.12.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3ff4ede90ed771140caa7e1890de17431763a483c54b3c1f88bd30f0cc1affc0"},
- {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a7bf9cc97f05048ac8f3e02cd58f0fe62b901453c24345bfde287f4305dcc31c"},
- {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:2324d9a0502317ffc35d38e153c1b2fa9610ae03775c9d0f8d0cca7b8572b04e"},
- {file = "ujson-5.12.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:50524f4f6a1c839714dbaff5386a1afb245d2d5ec8213a01fbc99cea7307811e"},
- {file = "ujson-5.12.0-cp314-cp314t-win32.whl", hash = "sha256:f7a0430d765f9bda043e6aefaba5944d5f21ec43ff4774417d7e296f61917382"},
- {file = "ujson-5.12.0-cp314-cp314t-win_amd64.whl", hash = "sha256:ccbfd94e59aad4a2566c71912b55f0547ac1680bfac25eb138e6703eb3dd434e"},
- {file = "ujson-5.12.0-cp314-cp314t-win_arm64.whl", hash = "sha256:42d875388fbd091c7ea01edfff260f839ba303038ffb23475ef392012e4d63dd"},
- {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-macosx_10_13_x86_64.whl", hash = "sha256:bf85a00ac3b56a1e7a19c5be7b02b5180a0895ac4d3c234d717a55e86960691c"},
- {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-macosx_11_0_arm64.whl", hash = "sha256:64df53eef4ac857eb5816a56e2885ccf0d7dff6333c94065c93b39c51063e01d"},
- {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6c0aed6a4439994c9666fb8a5b6c4eac94d4ef6ddc95f9b806a599ef83547e3b"},
- {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:efae5df7a8cc8bdb1037b0f786b044ce281081441df5418c3a0f0e1f86fe7bb3"},
- {file = "ujson-5.12.0-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:8712b61eb1b74a4478cfd1c54f576056199e9f093659334aeb5c4a6b385338e5"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:871c0e5102e47995b0e37e8df7819a894a6c3da0d097545cd1f9f1f7d7079927"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:56ba3f7abbd6b0bb282a544dc38406d1a188d8bb9164f49fdb9c2fee62cb29da"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9c5a52987a990eb1bae55f9000994f1afdb0326c154fb089992f839ab3c30688"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:adf28d13a33f9d750fe7a78fb481cac298fa257d8863d8727b2ea4455ea41235"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51acc750ec7a2df786cdc868fb16fa04abd6269a01d58cf59bafc57978773d8e"},
- {file = "ujson-5.12.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:ab9056d94e5db513d9313b34394f3a3b83e6301a581c28ad67773434f3faccab"},
- {file = "ujson-5.12.0.tar.gz", hash = "sha256:14b2e1eb528d77bc0f4c5bd1a7ebc05e02b5b41beefb7e8567c9675b8b13bcf4"},
+ {file = "ujson-5.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:71bdb5d10c6d7e710cfa78e743d9fb79a37c7c66fa916cd287bffbaa520f5abe"},
+ {file = "ujson-5.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:558673c6c3a2309775683ca96d5f1e4cd99889f71b1ba5cb6be8aa37ae67f9e0"},
+ {file = "ujson-5.12.1-cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4b0c9f6a56aa94bb98b403e1f57a866f0b43abaa89757b24d4a4b3cd8643ced"},
+ {file = "ujson-5.12.1-cp310-cp310-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:7bba5ab7965619db7d6f5503133b8e2d8bfce9bb6754224ca64d19261cc52f7c"},
+ {file = "ujson-5.12.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:191d2077fd53441599a2efd3dcc205b9cc5f3a4d685a76e9f73f4b6c19aee0c9"},
+ {file = "ujson-5.12.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d90d27953716ef206c42f166932b3dbb264dc638bbf32acae81b216ae35f566d"},
+ {file = "ujson-5.12.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b6afa86c117b66034004ee83c5149c6dccf7cb88941f9d3a1640c7076577f2d4"},
+ {file = "ujson-5.12.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:9523d67d45334f9a1d62e423bd72be62b58d2289a50420ffffa9363763eab73f"},
+ {file = "ujson-5.12.1-cp310-cp310-win32.whl", hash = "sha256:757f2026bef09d231d63a2250a2c7ad21ea1c9cb1ded6480659d202c4e2ef09e"},
+ {file = "ujson-5.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:7e31afad20cd6837a5ac6965d95b44b0ff06e42a82b01a8d3dc606a07f0b7a2a"},
+ {file = "ujson-5.12.1-cp310-cp310-win_arm64.whl", hash = "sha256:80f58ae2be100da0f525330ee274accd8892d1c125fea75076f60539d9a5f9cd"},
+ {file = "ujson-5.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:26dcb43869057373048cbd2678293c5b0f962d5774cc76fc9488564a209bcbf2"},
+ {file = "ujson-5.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bca3f04b2f590a8211acdc3ca06649b65a7ed1e999437dccf095310be9d3ba4e"},
+ {file = "ujson-5.12.1-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:29d1d64ed2c3c17666f4f0e15462800f3477255dc53667ad5d099277866c5666"},
+ {file = "ujson-5.12.1-cp311-cp311-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:2cfbd6b0c677d5d053964b8f98d8bb1af10c591c8c24454bcd40006ac8ba18db"},
+ {file = "ujson-5.12.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f75caed5b6d1fc271bb720a780c4199914267f7b865f9bf17826c4feccea582c"},
+ {file = "ujson-5.12.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b21b4c680594c8686bcd4cdda0fd3ea2567b9d42bcf1d1e3d92d39bcdb02e8f1"},
+ {file = "ujson-5.12.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:50d07e79ec70d32b4fbe18ab706ed0b172be08710d5901b9d067d7951bfaa164"},
+ {file = "ujson-5.12.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:080bc65ac7c0a6314d45d55b6171d3a48b1aeaf89895654d625b291cfe46309f"},
+ {file = "ujson-5.12.1-cp311-cp311-win32.whl", hash = "sha256:251ba8229e19b4b0b3efb5e7e3ddfa67c5c466aa492707bc3f6568bf714604dc"},
+ {file = "ujson-5.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:46315b82505c99101dcab3bd979f15fecfde85c02df7efbb4e428fa357665290"},
+ {file = "ujson-5.12.1-cp311-cp311-win_arm64.whl", hash = "sha256:12e99e49c62322ed0394c914aff15403ba7ede0b74f05a0faa4ec12c7d17a139"},
+ {file = "ujson-5.12.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:10f44bd08ae52ee23ca6e8b472692e5da1768af2d53ff1bad6f40b532e0bc7ee"},
+ {file = "ujson-5.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6cc6ea753b7303fa5629fa9ac9257ea4b001c4d72583b2bb36ff1855a07db49f"},
+ {file = "ujson-5.12.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:289f13095764d03734adfa10107da9b530ceb64dc1b02a5f507588d978d5b7df"},
+ {file = "ujson-5.12.1-cp312-cp312-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:427893168d074e59214b0ee058337c57f5bb80175cdd5b4799a9c931aae22022"},
+ {file = "ujson-5.12.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7a81724d5d90a2da7155d15d8b156ce57eaed7cdd622df813f36a8e612fd4c8"},
+ {file = "ujson-5.12.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3a6efff7dc6515416366819de4a1bc449b77107c5b48508b101fd40f7f8bec08"},
+ {file = "ujson-5.12.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77a71fe53427a0cf49d56eafd801d9f7e203b784b7f99cc717783fd6f6f7b732"},
+ {file = "ujson-5.12.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ea3bed53d2ea8e5642e814a9e41f3e29420a8067874ba03ace8c0462e160490c"},
+ {file = "ujson-5.12.1-cp312-cp312-win32.whl", hash = "sha256:758e5c8fbe4e6d483041e03b307b01fb5d2f2dd4452d4d4b927ab902e188939e"},
+ {file = "ujson-5.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:f6074d3d3267ba1914c624b6e1fa3d8152648ff36b0ab77ddf83b92db488c30d"},
+ {file = "ujson-5.12.1-cp312-cp312-win_arm64.whl", hash = "sha256:7642a41520ac1b2bc25ea282b66b8da522cc43424442e6fb5e039be4d4f96530"},
+ {file = "ujson-5.12.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c4bdc052a5d097f0a2e56d93aed97355f9f7a62ef9baa4f8517e43245434af9c"},
+ {file = "ujson-5.12.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5dc91fa06ea35920b704fd9d70871897680145998071cfbf5ee3e19f2c9fc242"},
+ {file = "ujson-5.12.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b5db0849c0e3da54822a5834f2dc51d7c51072d7f7d665014ee34600dc10889b"},
+ {file = "ujson-5.12.1-cp313-cp313-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:949cb4863a5d4847edeb47c5364b334e8cadf23a7cbdaa547d86098a4b093106"},
+ {file = "ujson-5.12.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8aa731138d6dfca4ab84501b72384e6c544bfb48cb87a0dd4d304df3246cac25"},
+ {file = "ujson-5.12.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:727e983ef27892d86ee2d28fd517eeb02b2c1165aafcbe929dce988aeee81bfe"},
+ {file = "ujson-5.12.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d57d731ecf492d3d011e65369f8330654f0875b19f646be5270d478e843d3b81"},
+ {file = "ujson-5.12.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1a09636220f26c66f80c6c6283023cb53120e843825f890be92696cd1aa43f39"},
+ {file = "ujson-5.12.1-cp313-cp313-win32.whl", hash = "sha256:ee83fbac03a0896faf190177c938f94eb610b798d495a19d50997242c4eca685"},
+ {file = "ujson-5.12.1-cp313-cp313-win_amd64.whl", hash = "sha256:e08d9e096c416ddc34519241f97c201258b42639f2012d9547d8ae32921800dd"},
+ {file = "ujson-5.12.1-cp313-cp313-win_arm64.whl", hash = "sha256:963287e4b1bc463735c4056968a2dfa59bb831b6daba68bddd14f451191fe9e5"},
+ {file = "ujson-5.12.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:6f19e9a407a24230df0cc1ec1c0f5999872ba526b14a780f80ad6479f5eed9bc"},
+ {file = "ujson-5.12.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:8b657e870c77aaacdeea86cfad3e6d2ef9b52517e45988c9c367f7ee764fe4dd"},
+ {file = "ujson-5.12.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:984b5a99d1e0a037c2046c3c4b34cec832565d62d5017be0a035bf3cbfab72dc"},
+ {file = "ujson-5.12.1-cp314-cp314-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:f48ef8a16f1d85bd7982beac7adfd3fb704058631db84c1c61c8a1b7072b1508"},
+ {file = "ujson-5.12.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4f39ba3b65cc637b59731532f7e7c807786bff1d0332ab2d5b96a04d2584d78f"},
+ {file = "ujson-5.12.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:07f307780f85b49cba93f291718421b6f5f3b627a323b431fad937a18f6587cb"},
+ {file = "ujson-5.12.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:1c335caea51c31494e514b82d50763b9792d3960d2c7d9fdb6b6fb8ed50ebdd0"},
+ {file = "ujson-5.12.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:19ea07e29a45d199f926aadf93a9974128438c01b83141fba32477c0ee604b33"},
+ {file = "ujson-5.12.1-cp314-cp314-win32.whl", hash = "sha256:c8e626b6bc9bdd2e8f7393b7d99f3daa2ca4022e6203662e70de7bb3604b21b9"},
+ {file = "ujson-5.12.1-cp314-cp314-win_amd64.whl", hash = "sha256:c6d3bdd020333688ee60559437021ed68a98a28fdd609b5af16de5dd58f90cba"},
+ {file = "ujson-5.12.1-cp314-cp314-win_arm64.whl", hash = "sha256:e3c9c894971f4ada3ded16a804ed4640e1f2b3e5239beaeec7c48296f39f4232"},
+ {file = "ujson-5.12.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:49dd9c378e1c8e676785ff2b62cb490074229f15ab54abf45b623713cb2c36b5"},
+ {file = "ujson-5.12.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6d8827904358d7da59ccf2e1fd8de59e78248036d17fecc0462e62c6721f1102"},
+ {file = "ujson-5.12.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dc26caebea90425662ef0b979f945f6ac832651881107d6ec9a3c4d4a4ba929c"},
+ {file = "ujson-5.12.1-cp314-cp314t-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:45022aae09ac3d45bda6fbfc631088d1aff9a0465542d40bd6d295ced378c430"},
+ {file = "ujson-5.12.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b22aa0f644516d3d5b29464949e4b23fe784f84b4a1030ab9ac3cb42aaedabb1"},
+ {file = "ujson-5.12.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:7dc5cf44ea42365cd1b66e6ed3fc6ca040c86587b024a6659b98e99d31cff2cd"},
+ {file = "ujson-5.12.1-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:8df5d984ff4ac1ef292d70f30da03417038a7e1e0bc272d28ca9d34f02f41682"},
+ {file = "ujson-5.12.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:485f0182a0c0b54c304061cdc826d8343ce595c4055f7a24e72772a8520e5f7b"},
+ {file = "ujson-5.12.1-cp314-cp314t-win32.whl", hash = "sha256:4e12ca368b397aed7fa1eec534ea1ba8d94977b376f9df3e93ae1acfd004ec40"},
+ {file = "ujson-5.12.1-cp314-cp314t-win_amd64.whl", hash = "sha256:cec6b9b539539affc1f01a795c99574592a635ce22331b64f2b42e0af570659e"},
+ {file = "ujson-5.12.1-cp314-cp314t-win_arm64.whl", hash = "sha256:696224d4cfb8883fa5c0285dff31e5ce924704dd9ccd38e9ea8b5bf4a42b12fc"},
+ {file = "ujson-5.12.1-graalpy312-graalpy250_312_native-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2c419bf42ae40963fc27f70c59e24e9a97f5cf168dbce2c572f3c0ce3595912"},
+ {file = "ujson-5.12.1-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0be2b4f2f547b9f0f3d902640e410e5a2fc851576cbe033c88445a23e3e7aef1"},
+ {file = "ujson-5.12.1-graalpy312-graalpy250_312_native-win_amd64.whl", hash = "sha256:4ea0c490c702c20495e97345acfcf0c2f3153e658ef537ff111929c48b89e10a"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3e30fa6bc7156ed709e13f8b52e917db08fbfd611ba61346b62630974ec0ba8e"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f67c5f0d64eba0fbbd6d2d6a79b0c43c5bc06f27564378fd5d716e0d40360068"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8416bb724db9accfa97bdb77245952494b1800c23e42defd46afb5c661c9af19"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-manylinux_2_24_i686.manylinux_2_28_i686.whl", hash = "sha256:66005b49c753a1b9f2f8853919dc58e1e6bd66846ea341a33afa76c6d7602485"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bdc6b277dcd27663f7fb76b6a5088424c66e0407c23e9884f80cd733f7d71b19"},
+ {file = "ujson-5.12.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:7957b64583793042521f7f7c71c01626b3d32a17528eaab980eb8cdc3d4eec68"},
+ {file = "ujson-5.12.1.tar.gz", hash = "sha256:5b7e96406c301a1366534479a7352ec40ec68bb327c0c119091635acd5925e35"},
]
[[package]]
name = "urllib3"
-version = "2.6.3"
+version = "2.7.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
-python-versions = ">=3.9"
+python-versions = ">=3.10"
groups = ["main", "dev"]
files = [
- {file = "urllib3-2.6.3-py3-none-any.whl", hash = "sha256:bf272323e553dfb2e87d9bfd225ca7b0f467b919d7bbd355436d3fd37cb0acd4"},
- {file = "urllib3-2.6.3.tar.gz", hash = "sha256:1b62b6884944a57dbe321509ab94fd4d3b307075e0c2eae991ac71ee15ad38ed"},
+ {file = "urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897"},
+ {file = "urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c"},
]
+markers = {main = "extra == \"all\" or extra == \"datamasking\" or extra == \"aws-sdk\" or extra == \"tracer\" or extra == \"datadog\""}
[package.extras]
brotli = ["brotli (>=1.2.0) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=1.2.0.0) ; platform_python_implementation != \"CPython\""]
@@ -4912,50 +4983,50 @@ zstd = ["backports-zstd (>=1.0.0) ; python_version < \"3.14\""]
[[package]]
name = "valkey-glide"
-version = "2.2.7"
+version = "2.3.1"
description = "Valkey GLIDE Async client. Supports Valkey and Redis OSS."
optional = true
python-versions = ">=3.9"
groups = ["main"]
markers = "extra == \"valkey\""
files = [
- {file = "valkey_glide-2.2.7-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:701b6ee036a54598ba63d7e6ecdee8f6ddd5b460cef67491f29414447deb7407"},
- {file = "valkey_glide-2.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:556dd3a906f61ff2d53f540fa782eee5c67a2048ed434f87089bb4f62cbd2564"},
- {file = "valkey_glide-2.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6622536445b7c78ae3f0f497ae449efac6a627f7c607b92c9ef934c5dd046c4b"},
- {file = "valkey_glide-2.2.7-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9bd390f66dc324ce3e937a6ac7592bfbd4e6cf9eb5d4c28838fc766645f149b"},
- {file = "valkey_glide-2.2.7-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:e39a1db18d08f5a9995d87158b070af1a625a612dc7e57e27a9becee40f6144c"},
- {file = "valkey_glide-2.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:180aa1ee0cdfbcf34ae7322838fd063a720a6dae9e97a8e9462b8a12b1f65138"},
- {file = "valkey_glide-2.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44a9a6e85e8320220604468c35e0a84bea392dddbab2dcdf9cce9ece01b4a041"},
- {file = "valkey_glide-2.2.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7905c5f3efb67058c5f52b7906aa2d114288eff4aa76a5379107b312af6b8ec8"},
- {file = "valkey_glide-2.2.7-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:4db4ff570c0a63cc8a4551b780dd00069d61c8841a6e6eeaf2dda05d89ec0221"},
- {file = "valkey_glide-2.2.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:05f5ebe701f18b22d331a12af120e1250927391665b66fd78c273d563b2523c6"},
- {file = "valkey_glide-2.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca7aab86a175c678bb0573db29050d49d692adcf87c7dd01e2ff9da94bdac68f"},
- {file = "valkey_glide-2.2.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c81c7cb8bbae7a75c3efcfe9b05ebd97db6f332128606e5464e518ba5a7b8e02"},
- {file = "valkey_glide-2.2.7-cp313-cp313-macosx_10_7_x86_64.whl", hash = "sha256:1d40da535a77ce318367ac255b1d5de95cf0ca669b8cac79a158f678feed9fb3"},
- {file = "valkey_glide-2.2.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0f435ed9c14d7de72df04322300034931aba528d1183770b2f7624dd8fc18d7c"},
- {file = "valkey_glide-2.2.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6cad26daa0775ab6dd7ad5a1d8300c4b97ed4b39401c1f130200456f9f9b5234"},
- {file = "valkey_glide-2.2.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:340a9bdf31e811121e9ea7d95cb75161125c78690334581d4be08aae9c824f29"},
- {file = "valkey_glide-2.2.7-cp314-cp314-macosx_10_7_x86_64.whl", hash = "sha256:085c81403600555a7672cf45d68f2c786d1fac12d5759d8e6e3a3f7d5a79d8b7"},
- {file = "valkey_glide-2.2.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d2470a704f463600a0c12000b48adbcc888210be38fbb39fd33c7f36fe84bd66"},
- {file = "valkey_glide-2.2.7-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d1985f7c579c7b37bf7fc42125b141295dded29257d7b811d318bb5343343c8"},
- {file = "valkey_glide-2.2.7-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba5149f2019164024958778e5b314f05dc61187731e2c23411498cb884a9181b"},
- {file = "valkey_glide-2.2.7-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:20b586d2702a71cd90bb7c85380155f92585129f9534396450e2a64896e5b00c"},
- {file = "valkey_glide-2.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:8316673b56632ae92b4cf22a990b8fc510fe87cbb29d3aac242496cf7a44d96c"},
- {file = "valkey_glide-2.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3c5ae19adbb299c212c0011c1934ea3769b1dc364126a6fb5b443842678c2ec"},
- {file = "valkey_glide-2.2.7-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec85da03bd00402df90152c5e647cade29c0e539311839c844e135e945f84dbc"},
- {file = "valkey_glide-2.2.7-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:47949c900e08de0e64fb5b59abfa069e09a62a9a4db2ba6756ca3a6b440f012a"},
- {file = "valkey_glide-2.2.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:8d6ba5b86d8910545dcd8429807780bae705def558ce38ca8f2a10ee13aa7021"},
- {file = "valkey_glide-2.2.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ce02ce683b42687b72fc21a70b7dfe3597c79cb1594c6e707b464fa37e8f3a3"},
- {file = "valkey_glide-2.2.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5b02900b8e6ea539a5a158c0a74e63d92043b4487dd43f33cc1b0bb03a0aeac0"},
- {file = "valkey_glide-2.2.7-pp311-pypy311_pp73-macosx_10_7_x86_64.whl", hash = "sha256:33e6a21430580499943f29d30c3d74bc9b53f421bb76ea190e43cead428fc832"},
- {file = "valkey_glide-2.2.7-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:0c2eff5bf9e30bb2e2efb4bad09ecf2568a7ca722e39b37f8a10d5244a512b3a"},
- {file = "valkey_glide-2.2.7-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:589e52f909bc7e7736e35af6e4b3d91e7dfcbf26b3bf13fca79668ad633d9ed4"},
- {file = "valkey_glide-2.2.7-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8c9beaff220439b10906e8b84c5a141d4b6515ea28db38f076191777e26c05"},
- {file = "valkey_glide-2.2.7-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:1e353efd6b7d6b511be246e0376be0176869b2a7bde4ba7c4d8d0e25c3bda07b"},
- {file = "valkey_glide-2.2.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:ba90316717570f550ffbacdad36bc023ca404468c35c997f2ee4bbd8b1cbb634"},
- {file = "valkey_glide-2.2.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:170ab03fa9fb958bb1c9ed467a4e173444d7b23886d5be01b8719d7c4d8ced8d"},
- {file = "valkey_glide-2.2.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e6b1ad67ff44d23850713c10191a701c19b8bd4d800ca3ef1a442267563ad92f"},
- {file = "valkey_glide-2.2.7.tar.gz", hash = "sha256:2cd05b8c871c7878cb89679ac34f294f100481b64f79d797cde325a1d051cdc9"},
+ {file = "valkey_glide-2.3.1-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:736a3e58393fa4f0f2fbb10031d46da5f18ebb8e72d2f9428ff24f0f6addeb3f"},
+ {file = "valkey_glide-2.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b2cd6f5c4e9b67b78873f34f19b9182bab5b07a9151855cf059303e05dac3b2f"},
+ {file = "valkey_glide-2.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1ddf70bc7888d565273e4bf858ff6047d5284140ff380a732f807c775be8e108"},
+ {file = "valkey_glide-2.3.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9f947dd44ba9741eadcab154443f447c19f23dab56de33f56d5f133ee0d597c2"},
+ {file = "valkey_glide-2.3.1-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:6ddc4c6bee1a9c102f003cddc5d1bad8173a9d90e1c9a0f73a285228ed8625af"},
+ {file = "valkey_glide-2.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30590532136e4ea38b6a6389cbcfe4edc554418563c6e4f6357b0749907b2c20"},
+ {file = "valkey_glide-2.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4bbdb7baa7aac12c109aefd97f69f9780a4812429db18786254ef288ecf75f19"},
+ {file = "valkey_glide-2.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fd64d77ae26efd524be58456e22636ce4cb0a6110ad722e89f249a45d098692"},
+ {file = "valkey_glide-2.3.1-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:406b73f5ee080406fbfeda542d37de7e330fb4d83b0aa7212b92707d7b7b82a6"},
+ {file = "valkey_glide-2.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0940d4069cbc4896dec3a1ab39db7bf86667fb32892df4dbf3b043129d26d6e5"},
+ {file = "valkey_glide-2.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b47de0ec3d5a253c2b37d33266aaeb22503014f9e8f0611ba999e06f9804966a"},
+ {file = "valkey_glide-2.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a364210002dd0e7c3362299f61a2a1cacf867594a8a0bbf157a345f3f40d4d94"},
+ {file = "valkey_glide-2.3.1-cp313-cp313-macosx_10_7_x86_64.whl", hash = "sha256:86d56756842acd6286601128822c5f1f9dcd61305f0c6a80c3e7fb3a7e0404ef"},
+ {file = "valkey_glide-2.3.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b307795a23473b8e7cff781eb54936cc672a430820f5fa71c6b6fb3748cc1189"},
+ {file = "valkey_glide-2.3.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3cb570f5d637ee55300ccdecd39a51cbf25c67ab6e25f2022d42f32a7bec6163"},
+ {file = "valkey_glide-2.3.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:506c7800eec05caf17136645cc642941a9536578f4d6733845e7d0ed36ed4e3e"},
+ {file = "valkey_glide-2.3.1-cp314-cp314-macosx_10_7_x86_64.whl", hash = "sha256:3d6626e6f9ddfa7f8706023e167b4a2eca8a0f7b7fee1d30f91a83b4811349e4"},
+ {file = "valkey_glide-2.3.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:3466a0c113a951d722036704795ff0377eef11a44ab224472f98d99ac2c5ef28"},
+ {file = "valkey_glide-2.3.1-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe53e4808bdac5b4e6482c66583e1980ecf75666b4e4d0984d89e8b693026543"},
+ {file = "valkey_glide-2.3.1-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1a9662885ea8f3df97a6d873131dea983d42e4735750af368fe2d47e7e44f0c"},
+ {file = "valkey_glide-2.3.1-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:7cd8c7d52411d8add7640eb4982942e0fd0154db5d010e3a8094ae028f91d136"},
+ {file = "valkey_glide-2.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9b3037c5d477172d82ae443f1fbc664dba04a0184efd5a227d541cdf06be478f"},
+ {file = "valkey_glide-2.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcac3e3064de88c57042eaa34980c6f35c8c09138148cceafd7dddbd830602ea"},
+ {file = "valkey_glide-2.3.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1de33b66aba099e3f17199da4edefbeb38c91349a6c0d958581fa77be3475140"},
+ {file = "valkey_glide-2.3.1-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:5533a090953fd6af4c07b80bd042231540fbd1ede95fff42614750b435f01184"},
+ {file = "valkey_glide-2.3.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f814ad759e9fdc6c5ced18ddba38cc2a3badb2839ce3555ec9b44beb794096e4"},
+ {file = "valkey_glide-2.3.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3dc6dea7ce627a8b166d33232aa7bc7f8dd9d224870235a560bc5d1c4ccec8cb"},
+ {file = "valkey_glide-2.3.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1e135bb43e50b1cd6558d93b3108c40a79ce8dc119de883cebb7458d470f629"},
+ {file = "valkey_glide-2.3.1-pp311-pypy311_pp73-macosx_10_7_x86_64.whl", hash = "sha256:993c9bffde847fa3d36c6f11e5e50872dd491f245850d7c6ae1bbb8db5bff346"},
+ {file = "valkey_glide-2.3.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:918ce3b8a2a3602e82d03f254bad5cc5bd1398eb84dec8eef77aefccc039bd5d"},
+ {file = "valkey_glide-2.3.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28d4cbf00b07db273214488f17d59232baaddd0cc30c26064cf3bf384b03e9cd"},
+ {file = "valkey_glide-2.3.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d93ef822a524c8f18c1b750f061373d95e842005116ebcf832d166533bf2bc2"},
+ {file = "valkey_glide-2.3.1-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f66459238f68b165d6b3b8c1a0cb48e63ce291afa82e82f029dbd37b7b27099b"},
+ {file = "valkey_glide-2.3.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:7bc45d65196d03f8651a4f40d5be5faf6925edb3d8d37cc57a79fd555f70c368"},
+ {file = "valkey_glide-2.3.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:115bd85a443fec57d12094aa8ae627a718df64044a978bc4d407f82a29db4c83"},
+ {file = "valkey_glide-2.3.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:beb25b2445e9be63784e67200fdf708694e842f3a6e93530fe974200411dfaf4"},
+ {file = "valkey_glide-2.3.1.tar.gz", hash = "sha256:f4bae030c0aa6e55edb2c27dbd55f82cfb5f581904fff1318eec1c062f30d4b3"},
]
[package.dependencies]
@@ -5172,4 +5243,4 @@ valkey = ["valkey-glide"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.10,<4.0.0"
-content-hash = "ade91e6e8ba781806bb5af43cda5f48fa585acd3005f449e182394d238625deb"
+content-hash = "ec4397857f1745105717c60a48f9791c37387457cba3aca337c2afa55b29d77d"
diff --git a/pyproject.toml b/pyproject.toml
index 8a5e4cec44d..5ca4ee98915 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "aws_lambda_powertools"
-version = "3.26.0"
+version = "3.29.0"
description = "Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity."
authors = ["Amazon Web Services"]
include = ["aws_lambda_powertools/py.typed", "THIRD-PARTY-LICENSES"]
@@ -52,7 +52,7 @@ pydantic-settings = {version = "^2.6.1", optional = true}
boto3 = { version = "^1.34.32", optional = true }
redis = { version = ">=4.4,<8.0", optional = true }
valkey-glide = { version = ">=1.3.5,<3.0", optional = true }
-aws-encryption-sdk = { version = ">=3.1.1,<5.0.0", optional = true }
+aws-encryption-sdk = { version = ">=3.3.1,!=4.0.0,!=4.0.1,!=4.0.2,!=4.0.3,!=4.0.4,<5.0.0", optional = true }
jsonpath-ng = { version = "^1.6.0", optional = true }
datadog-lambda = { version = ">=8.114.0,<9.0.0", optional = true }
avro = { version = "^1.12.0", optional = true }
@@ -83,7 +83,7 @@ kafka-consumer-protobuf = ["protobuf"]
coverage = { extras = ["toml"], version = "^7.6" }
pytest = ">=8.3.4,<10.0.0"
boto3 = "^1.26.164"
-isort = ">=5.13.2,<8.0.0"
+isort = ">=5.13.2,<9.0.0"
pytest-cov = ">=5,<8"
pytest-mock = "^3.14.0"
pytest-asyncio = ">=0.24,<1.4"
@@ -110,15 +110,15 @@ hvac = "^2.3.0"
aws-requests-auth = "^0.4.3"
urllib3 = ">=1.25.4,!=2.2.0,<3"
requests = ">=2.32.0"
-cfn-lint = "1.46.0"
-mypy = "^1.1.1"
+cfn-lint = "1.48.1"
+mypy = ">=1.1.1,<3.0.0"
types-python-dateutil = "^2.8.19.6"
aws-cdk-aws-appsync-alpha = "^2.59.0a0"
httpx = ">=0.23.3,<0.29.0"
sentry-sdk = ">=1.22.2,<3.0.0"
-ruff = ">=0.5.1,<0.14.15"
+ruff = ">=0.5.1,<0.15.15"
retry2 = "^0.9.5"
-pytest-socket = ">=0.6,<0.8"
+pytest-socket = ">=0.6,<0.9"
types-redis = "^4.6.0.7"
testcontainers = { extras = ["redis"], version = ">=3.7.1,<5.0.0" }
multiprocess = "^0.70.16"
@@ -128,8 +128,8 @@ mkdocstrings-python = "^1.13.0"
mkdocs-llmstxt = ">=0.2,<0.5"
avro = "^1.12.0"
protobuf = ">=6.30.2,<8.0.0"
-types-protobuf = "^6.30.2.20250516"
-ty = "^0.0.23"
+types-protobuf = ">=6.30.2.20250516,<8.0.0.0"
+ty = ">=0.0.23,<0.0.36"
[tool.coverage.run]
source = ["aws_lambda_powertools"]
@@ -241,5 +241,6 @@ exclude = [
"aws_lambda_powertools/tracing/**",
"aws_lambda_powertools/utilities/batch/**",
"aws_lambda_powertools/utilities/idempotency/**",
+ "aws_lambda_powertools/utilities/parameters/**",
"aws_lambda_powertools/event_handler/**",
]
diff --git a/tests/functional/event_handler/_pydantic/merge_handlers/shared/__init__.py b/tests/functional/event_handler/_pydantic/merge_handlers/shared/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/functional/event_handler/_pydantic/merge_handlers/shared/categories_routes.py b/tests/functional/event_handler/_pydantic/merge_handlers/shared/categories_routes.py
new file mode 100644
index 00000000000..7029ad332c7
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/merge_handlers/shared/categories_routes.py
@@ -0,0 +1,11 @@
+"""Categories routes - imports shared resolver and registers routes."""
+
+from __future__ import annotations
+
+from tests.functional.event_handler._pydantic.merge_handlers.shared.resolver import app
+
+
+@app.get("/categories")
+def get_categories() -> list[dict]:
+ """Get all categories."""
+ return []
diff --git a/tests/functional/event_handler/_pydantic/merge_handlers/shared/products_routes.py b/tests/functional/event_handler/_pydantic/merge_handlers/shared/products_routes.py
new file mode 100644
index 00000000000..84d9d4bbde5
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/merge_handlers/shared/products_routes.py
@@ -0,0 +1,17 @@
+"""Products routes - imports shared resolver and registers routes."""
+
+from __future__ import annotations
+
+from tests.functional.event_handler._pydantic.merge_handlers.shared.resolver import app
+
+
+@app.get("/products")
+def get_products() -> list[dict]:
+ """Get all products."""
+ return []
+
+
+@app.get("/products/")
+def get_product(product_id: str) -> dict:
+ """Get a product by ID."""
+ return {"id": product_id}
diff --git a/tests/functional/event_handler/_pydantic/merge_handlers/shared/resolver.py b/tests/functional/event_handler/_pydantic/merge_handlers/shared/resolver.py
new file mode 100644
index 00000000000..8a7a472b216
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/merge_handlers/shared/resolver.py
@@ -0,0 +1,5 @@
+"""Shared resolver - routes are registered by other files that import this."""
+
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+app = APIGatewayRestResolver()
diff --git a/tests/functional/event_handler/_pydantic/merge_handlers/typed_handler.py b/tests/functional/event_handler/_pydantic/merge_handlers/typed_handler.py
new file mode 100644
index 00000000000..53c2b4e0a12
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/merge_handlers/typed_handler.py
@@ -0,0 +1,24 @@
+from __future__ import annotations
+
+from pydantic import BaseModel
+
+from aws_lambda_powertools.event_handler import APIGatewayRestResolver
+
+app: APIGatewayRestResolver = APIGatewayRestResolver(enable_validation=True)
+
+
+class Product(BaseModel):
+ id: int
+ name: str
+ price: float
+
+
+@app.get("/products")
+def get_products() -> list[Product]:
+ return [
+ Product(id=1, name="Widget", price=9.99),
+ ]
+
+
+def handler(event, context):
+ return app.resolve(event, context)
diff --git a/tests/functional/event_handler/_pydantic/test_api_gateway.py b/tests/functional/event_handler/_pydantic/test_api_gateway.py
index ce3fd89e864..32a6e3c549d 100644
--- a/tests/functional/event_handler/_pydantic/test_api_gateway.py
+++ b/tests/functional/event_handler/_pydantic/test_api_gateway.py
@@ -80,3 +80,69 @@ def get_lambda(param: int): ...
assert result["statusCode"] == 422
assert result["multiValueHeaders"]["Content-Type"] == [content_types.APPLICATION_JSON]
assert "missing" in result["body"]
+
+
+def test_route_custom_status_code_with_dict():
+ # GIVEN a route with a custom status_code returning a dict
+ app = ApiGatewayResolver(enable_validation=True)
+
+ @app.post("/my/path", status_code=201)
+ def create_item():
+ return {"name": "test"}
+
+ event = {"httpMethod": "POST", "path": "/my/path", "body": "{}"}
+
+ # WHEN calling the event handler
+ result = app(event, {})
+
+ # THEN the response should use the route's custom status code
+ assert result["statusCode"] == 201
+
+
+def test_route_custom_status_code_tuple_override():
+ # GIVEN a route with status_code=201 but handler returns a tuple with 202
+ app = ApiGatewayResolver(enable_validation=True)
+
+ @app.post("/my/path", status_code=201)
+ def create_item():
+ return {"name": "test"}, 202
+
+ event = {"httpMethod": "POST", "path": "/my/path", "body": "{}"}
+
+ # WHEN calling the event handler
+ result = app(event, {})
+
+ # THEN the tuple status code should override the route's status code
+ assert result["statusCode"] == 202
+
+
+def test_route_custom_status_code_response_object_override():
+ # GIVEN a route with status_code=201 but handler returns a Response with 204
+ app = ApiGatewayResolver(enable_validation=True)
+
+ @app.post("/my/path", status_code=201)
+ def create_item():
+ return Response(status_code=204, content_type=content_types.APPLICATION_JSON, body="{}")
+
+ event = {"httpMethod": "POST", "path": "/my/path", "body": "{}"}
+
+ # WHEN calling the event handler
+ result = app(event, {})
+
+ # THEN the Response object's status code should take precedence
+ assert result["statusCode"] == 204
+
+
+def test_route_default_status_code_with_dict():
+ # GIVEN a route without custom status_code returning a dict
+ app = ApiGatewayResolver(enable_validation=True)
+
+ @app.get("/my/path")
+ def get_items():
+ return {"items": []}
+
+ # WHEN calling the event handler
+ result = app(LOAD_GW_EVENT, {})
+
+ # THEN the response should default to 200
+ assert result["statusCode"] == 200
diff --git a/tests/functional/event_handler/_pydantic/test_depends.py b/tests/functional/event_handler/_pydantic/test_depends.py
new file mode 100644
index 00000000000..0cbc05b83c7
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/test_depends.py
@@ -0,0 +1,216 @@
+"""Tests for Depends() with OpenAPI schema generation and validation."""
+
+import json
+from typing import Annotated
+
+from pydantic import BaseModel
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver, Depends
+from aws_lambda_powertools.event_handler.request import Request
+from tests.functional.utils import load_event
+
+API_GW_V2_EVENT = load_event("apiGatewayProxyV2Event.json")
+
+
+# --- Fixtures ---
+
+
+class AppConfig(BaseModel):
+ region: str = "us-east-1"
+ debug: bool = False
+
+
+def get_config() -> AppConfig:
+ return AppConfig(region="eu-west-1", debug=True)
+
+
+def get_tenant() -> str:
+ return "tenant-abc"
+
+
+# --- OpenAPI schema tests ---
+
+
+def test_depends_excluded_from_openapi_schema():
+ """Depends() parameters must NOT appear in the OpenAPI schema."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/orders")
+ def handler(tenant: Annotated[str, Depends(get_tenant)], status: str = "active"):
+ return {"tenant": tenant, "status": status}
+
+ schema = app.get_openapi_schema()
+ get_op = schema.paths["/orders"].get
+ param_names = [p.name for p in (get_op.parameters or [])]
+
+ assert "tenant" not in param_names
+ assert "status" in param_names
+
+
+def test_depends_with_pydantic_model_excluded_from_schema():
+ """Depends() returning a Pydantic model must NOT appear as a body param in the schema."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/info")
+ def handler(config: Annotated[AppConfig, Depends(get_config)]):
+ return {"region": config.region}
+
+ schema = app.get_openapi_schema()
+ get_op = schema.paths["/info"].get
+ param_names = [p.name for p in (get_op.parameters or [])]
+
+ assert "config" not in param_names
+ # Should have no request body either
+ assert get_op.requestBody is None
+
+
+def test_depends_nested_excluded_from_openapi_schema():
+ """Nested Depends() parameters must NOT appear in the OpenAPI schema."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ def get_prefix() -> str:
+ return "Hello"
+
+ def get_greeting(prefix: Annotated[str, Depends(get_prefix)]) -> str:
+ return f"{prefix}, world!"
+
+ @app.get("/greet")
+ def handler(greeting: Annotated[str, Depends(get_greeting)]):
+ return {"greeting": greeting}
+
+ schema = app.get_openapi_schema()
+ get_op = schema.paths["/greet"].get
+ param_names = [p.name for p in (get_op.parameters or [])]
+
+ assert "greeting" not in param_names
+ assert "prefix" not in param_names
+
+
+# --- Validation + Depends integration tests ---
+
+
+def test_depends_with_validation_resolves_and_validates():
+ """Depends() values are injected alongside validated query params."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/orders")
+ def handler(tenant: Annotated[str, Depends(get_tenant)], limit: int = 10):
+ return {"tenant": tenant, "limit": limit}
+
+ event = {**API_GW_V2_EVENT}
+ event["rawPath"] = "/orders"
+ event["requestContext"] = {
+ **event["requestContext"],
+ "http": {"method": "GET", "path": "/orders"},
+ }
+ event["queryStringParameters"] = {"limit": "5"}
+
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["tenant"] == "tenant-abc"
+ assert body["limit"] == 5
+
+
+def test_depends_pydantic_model_with_validation():
+ """Depends() returning a Pydantic model works with enable_validation."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/config")
+ def handler(config: Annotated[AppConfig, Depends(get_config)]):
+ return {"region": config.region, "debug": config.debug}
+
+ event = {**API_GW_V2_EVENT}
+ event["rawPath"] = "/config"
+ event["requestContext"] = {
+ **event["requestContext"],
+ "http": {"method": "GET", "path": "/config"},
+ }
+
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["region"] == "eu-west-1"
+ assert body["debug"] is True
+
+
+def test_depends_with_request_and_validation():
+ """Depends() with Request injection works alongside validation."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ def get_method(request: Request) -> str:
+ return request.method
+
+ @app.post("/my/path")
+ def handler(method: Annotated[str, Depends(get_method)], name: str = "world"):
+ return {"method": method, "name": name}
+
+ event = {**API_GW_V2_EVENT, "queryStringParameters": {"name": "Lambda"}}
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["method"] == "POST"
+ assert body["name"] == "Lambda"
+
+
+def test_depends_override_with_validation():
+ """dependency_overrides works with enable_validation."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/orders")
+ def handler(tenant: Annotated[str, Depends(get_tenant)]):
+ return {"tenant": tenant}
+
+ app.dependency_overrides[get_tenant] = lambda: "test-tenant"
+
+ event = {**API_GW_V2_EVENT}
+ event["rawPath"] = "/orders"
+ event["requestContext"] = {
+ **event["requestContext"],
+ "http": {"method": "GET", "path": "/orders"},
+ }
+
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"tenant": "test-tenant"}
+
+ app.dependency_overrides.clear()
+
+
+def test_depends_with_path_params_and_validation():
+ """Depends() works with path parameters and validation."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/orders/")
+ def handler(order_id: str, tenant: Annotated[str, Depends(get_tenant)]):
+ return {"order_id": order_id, "tenant": tenant}
+
+ event = {**API_GW_V2_EVENT}
+ event["rawPath"] = "/orders/abc-123"
+ event["requestContext"] = {
+ **event["requestContext"],
+ "http": {"method": "GET", "path": "/orders/abc-123"},
+ }
+
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["order_id"] == "abc-123"
+ assert body["tenant"] == "tenant-abc"
+
+
+def test_depends_with_regular_params_and_validation():
+ """Depends() works alongside regular handler parameters with validation."""
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ def get_greeting() -> str:
+ return "hello"
+
+ @app.post("/my/path")
+ def handler(name: str = "world", greeting: Annotated[str, Depends(get_greeting)] = ""):
+ return {"message": f"{greeting}, {name}!"}
+
+ event = {**API_GW_V2_EVENT, "queryStringParameters": {"name": "Lambda"}}
+ result = app(event, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"message": "hello, Lambda!"}
diff --git a/tests/functional/event_handler/_pydantic/test_http_resolver_pydantic.py b/tests/functional/event_handler/_pydantic/test_http_resolver_pydantic.py
index d31185f3239..7cab58a1b70 100644
--- a/tests/functional/event_handler/_pydantic/test_http_resolver_pydantic.py
+++ b/tests/functional/event_handler/_pydantic/test_http_resolver_pydantic.py
@@ -209,7 +209,6 @@ def search(
# =============================================================================
-@pytest.mark.skip("Due to issue #7981.")
@pytest.mark.asyncio
async def test_async_handler_with_validation():
# GIVEN an app with async handler and validation
@@ -241,6 +240,91 @@ async def create_user(user: UserModel) -> UserResponse:
assert body["user"]["name"] == "AsyncUser"
+@pytest.mark.asyncio
+async def test_async_handler_invalid_response_returns_422():
+ # GIVEN an app with async handler and validation
+ app = HttpResolverLocal(enable_validation=True)
+
+ @app.get("/user")
+ async def get_user() -> UserResponse:
+ await asyncio.sleep(0.001)
+ return {"name": "John"} # type: ignore # Missing required fields
+
+ scope = {
+ "type": "http",
+ "method": "GET",
+ "path": "/user",
+ "query_string": b"",
+ "headers": [(b"content-type", b"application/json")],
+ }
+
+ receive = make_asgi_receive()
+ send, captured = make_asgi_send()
+
+ # WHEN called via ASGI interface
+ await app(scope, receive, send)
+
+ # THEN it returns 422 for invalid response
+ assert captured["status_code"] == 422
+
+
+@pytest.mark.asyncio
+async def test_sync_handler_with_validation_via_asgi():
+ # GIVEN an app with a sync handler and validation, called via ASGI
+ app = HttpResolverLocal(enable_validation=True)
+
+ @app.post("/users")
+ def create_user(user: UserModel) -> UserResponse:
+ return UserResponse(id="sync-123", user=user)
+
+ scope = {
+ "type": "http",
+ "method": "POST",
+ "path": "/users",
+ "query_string": b"",
+ "headers": [(b"content-type", b"application/json")],
+ }
+
+ receive = make_asgi_receive(b'{"name": "SyncUser", "age": 30}')
+ send, captured = make_asgi_send()
+
+ # WHEN called via ASGI interface
+ await app(scope, receive, send)
+
+ # THEN validation works with sync handler
+ assert captured["status_code"] == 200
+ body = json.loads(captured["body"])
+ assert body["id"] == "sync-123"
+ assert body["user"]["name"] == "SyncUser"
+
+
+@pytest.mark.asyncio
+async def test_sync_handler_invalid_response_returns_422_via_asgi():
+ # GIVEN an app with a sync handler and validation, called via ASGI
+ app = HttpResolverLocal(enable_validation=True)
+
+ @app.get("/user")
+ def get_user() -> UserResponse:
+ return {"name": "John"} # type: ignore # Missing required fields
+
+ scope = {
+ "type": "http",
+ "method": "GET",
+ "path": "/user",
+ "query_string": b"",
+ "headers": [(b"content-type", b"application/json")],
+ }
+
+ receive = make_asgi_receive()
+ send, captured = make_asgi_send()
+
+ # WHEN called via ASGI interface
+ await app(scope, receive, send)
+
+ # THEN it returns 422 for invalid response
+ assert captured["status_code"] == 422
+
+
# =============================================================================
# OpenAPI Tests
# =============================================================================
diff --git a/tests/functional/event_handler/_pydantic/test_openapi_merge.py b/tests/functional/event_handler/_pydantic/test_openapi_merge.py
index b4dc1d70232..88834667727 100644
--- a/tests/functional/event_handler/_pydantic/test_openapi_merge.py
+++ b/tests/functional/event_handler/_pydantic/test_openapi_merge.py
@@ -367,3 +367,52 @@ def test_openapi_merge_schema_is_cached():
# AND paths should not be duplicated
assert len([p for p in schema1["paths"] if p == "/users"]) == 1
+
+
+def test_openapi_merge_shared_resolver_pattern():
+ # GIVEN a shared resolver pattern where:
+ # - resolver.py defines the resolver
+ # - products_routes.py and categories_routes.py import it and register routes
+ merge = OpenAPIMerge(title="Shared Resolver API", version="1.0.0")
+
+ # WHEN discovering with project_root set to allow absolute imports
+ shared_path = MERGE_HANDLERS_PATH / "shared"
+ project_root = Path(__file__).parent.parent.parent.parent.parent # repo root
+
+ files = merge.discover(
+ path=shared_path,
+ pattern="resolver.py",
+ project_root=project_root,
+ )
+
+ # THEN it should find the resolver file
+ assert len(files) == 1
+ assert files[0].name == "resolver.py"
+
+ # AND it should find dependent files that import the resolver
+ dependent = merge.dependent_files.get(files[0], [])
+ dependent_names = [f.name for f in dependent]
+ assert "products_routes.py" in dependent_names
+ assert "categories_routes.py" in dependent_names
+
+ # AND the merged schema should include routes from all dependent files
+ schema = merge.get_openapi_schema()
+ assert "/products" in schema["paths"]
+ assert "/products/{product_id}" in schema["paths"]
+ assert "/categories" in schema["paths"]
+
+
+def test_openapi_merge_discover_type_annotated_resolver():
+ # GIVEN an OpenAPIMerge instance
+ merge = OpenAPIMerge(title="Typed API", version="1.0.0")
+
+ # WHEN discovering a handler with a type-annotated resolver (app: Resolver = Resolver())
+ merge.discover(
+ path=MERGE_HANDLERS_PATH,
+ pattern="**/typed_handler.py",
+ resolver_name="app",
+ )
+
+ # THEN it should find the resolver and include its routes in the schema
+ schema = merge.get_openapi_schema()
+ assert "/products" in schema["paths"]
diff --git a/tests/functional/event_handler/_pydantic/test_openapi_responses.py b/tests/functional/event_handler/_pydantic/test_openapi_responses.py
index 71c7d186cbe..785d2b8416c 100644
--- a/tests/functional/event_handler/_pydantic/test_openapi_responses.py
+++ b/tests/functional/event_handler/_pydantic/test_openapi_responses.py
@@ -370,3 +370,89 @@ def handler() -> UserResponse:
assert "example2" in examples
assert examples["example2"].summary == "Example 2"
assert examples["example2"].value["id"] == 2
+
+
+def test_openapi_custom_status_code():
+ # GIVEN a route with a custom status_code
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ class Item(BaseModel):
+ name: str
+
+ @app.post("/items", status_code=201)
+ def create_item() -> Item:
+ return Item(name="test")
+
+ # WHEN we retrieve the OpenAPI schema
+ schema = app.get_openapi_schema()
+ responses = schema.paths["/items"].post.responses
+
+ # THEN the schema should use 201 as the success response code instead of 200
+ assert 201 in responses
+ assert responses[201].description == "Successful Response"
+ assert 200 not in responses
+
+
+def test_openapi_custom_status_code_with_description():
+ # GIVEN a route with a custom status_code and response_description
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/items", status_code=201, response_description="Item created")
+ def create_item():
+ return {"name": "test"}
+
+ # WHEN we retrieve the OpenAPI schema
+ schema = app.get_openapi_schema()
+ responses = schema.paths["/items"].post.responses
+
+ # THEN the schema should use 201 with the custom description
+ assert 201 in responses
+ assert responses[201].description == "Item created"
+ assert 200 not in responses
+
+
+def test_openapi_default_status_code():
+ # GIVEN a route without a custom status_code
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/items")
+ def get_items():
+ return {"items": []}
+
+ # WHEN we retrieve the OpenAPI schema
+ schema = app.get_openapi_schema()
+ responses = schema.paths["/items"].get.responses
+
+ # THEN the schema should default to 200
+ assert 200 in responses
+ assert responses[200].description == "Successful Response"
+
+
+def test_openapi_custom_status_code_all_methods():
+ # GIVEN routes with custom status_code on different HTTP methods
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/items", status_code=201)
+ def create():
+ return {}
+
+ @app.put("/items", status_code=204)
+ def update():
+ return {}
+
+ @app.delete("/items", status_code=204)
+ def delete():
+ return {}
+
+ @app.patch("/items", status_code=202)
+ def patch():
+ return {}
+
+ # WHEN we retrieve the OpenAPI schema
+ schema = app.get_openapi_schema()
+
+ # THEN each method should have the correct custom status code
+ assert 201 in schema.paths["/items"].post.responses
+ assert 204 in schema.paths["/items"].put.responses
+ assert 204 in schema.paths["/items"].delete.responses
+ assert 202 in schema.paths["/items"].patch.responses
diff --git a/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py b/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py
index 0df8f6a22c5..d25811d24ae 100644
--- a/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py
+++ b/tests/functional/event_handler/_pydantic/test_openapi_schema_pydantic_v2.py
@@ -3,7 +3,7 @@
from typing import Literal, Optional
import pytest
-from pydantic import BaseModel, Field
+from pydantic import BaseModel, Field, computed_field
from typing_extensions import Annotated
from aws_lambda_powertools.event_handler import APIGatewayRestResolver
@@ -110,3 +110,79 @@ def create_todo(todo: TodoEnvelope): ...
# THEN the schema should be valid
assert openapi31_schema(schema)
+
+
+@pytest.mark.usefixtures("pydanticv2_only")
+def test_openapi_schema_includes_computed_field():
+ # GIVEN a model with a computed_field
+ class User(BaseModel):
+ first_name: str
+ last_name: str
+
+ @computed_field
+ @property
+ def full_name(self) -> str:
+ return f"{self.first_name} {self.last_name}"
+
+ # GIVEN APIGatewayRestResolver with a handler returning that model
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/user")
+ def get_user() -> User:
+ return User(first_name="John", last_name="Doe")
+
+ # WHEN we get the schema
+ schema = json.loads(app.get_openapi_json_schema())
+
+ # THEN the computed_field should appear in the response schema
+ user_schema = schema["components"]["schemas"]["User"]
+ assert "full_name" in user_schema["properties"]
+ assert user_schema["properties"]["full_name"]["type"] == "string"
+ assert user_schema["properties"]["full_name"].get("readOnly") is True
+
+
+@pytest.mark.usefixtures("pydanticv2_only")
+def test_openapi_schema_computed_field_not_in_request_body():
+ # GIVEN a model with a computed_field used as both request and response
+ class Item(BaseModel):
+ price: float
+ quantity: int
+
+ @computed_field
+ @property
+ def total(self) -> float:
+ return self.price * self.quantity
+
+ # GIVEN APIGatewayRestResolver with handlers using the model
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/items")
+ def create_item(item: Item) -> Item:
+ return item
+
+ # WHEN we get the schema
+ schema = json.loads(app.get_openapi_json_schema())
+
+ # THEN the request body schema should NOT include computed_field
+ request_body = schema["paths"]["/items"]["post"]["requestBody"]
+ request_ref = request_body["content"]["application/json"]["schema"]["$ref"]
+ request_schema_name = request_ref.split("/")[-1]
+
+ # THEN the response schema SHOULD include computed_field
+ response_ref = schema["paths"]["/items"]["post"]["responses"]["200"]["content"]["application/json"]["schema"][
+ "$ref"
+ ]
+ response_schema_name = response_ref.split("/")[-1]
+
+ # When input/output schemas are separate, we expect different schema names
+ # When they share a schema, computed_field should be present
+ if request_schema_name == response_schema_name:
+ # Shared schema - computed_field should be present (serialization mode wins)
+ item_schema = schema["components"]["schemas"][response_schema_name]
+ assert "total" in item_schema["properties"]
+ else:
+ # Separate schemas
+ input_schema = schema["components"]["schemas"][request_schema_name]
+ output_schema = schema["components"]["schemas"][response_schema_name]
+ assert "total" not in input_schema["properties"]
+ assert "total" in output_schema["properties"]
diff --git a/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py b/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py
index 21bc9b26e0a..0da092f8aea 100644
--- a/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py
+++ b/tests/functional/event_handler/_pydantic/test_openapi_validation_middleware.py
@@ -1,6 +1,7 @@
import base64
import datetime
import json
+import warnings
from dataclasses import dataclass
from enum import Enum
from pathlib import PurePath
@@ -3327,3 +3328,938 @@ def handler(items: Annotated[Union[_Item, List[_Item]], Body()]) -> Dict[str, An
status, body = _post_json(app, "/items", big_payload)
assert status == 200
assert body["count"] == 100
+
+
+# ---------- File upload (multipart/form-data) ----------
+
+
+def _build_multipart_body(fields: List[Dict], boundary: str = "----TestBoundary") -> Tuple[str, str]:
+ """
+ Build a multipart/form-data body and return (base64_body, content_type).
+
+ Each field dict can have:
+ - name: field name (required)
+ - value: str or bytes (required)
+ - filename: optional filename (makes it a file part)
+ - content_type: optional content type for the part
+ """
+ parts = []
+ for field in fields:
+ headers = f'Content-Disposition: form-data; name="{field["name"]}"'
+ if "filename" in field:
+ headers += f'; filename="{field["filename"]}"'
+ if "content_type" in field:
+ headers += f"\r\nContent-Type: {field['content_type']}"
+ value = field["value"]
+ if isinstance(value, str):
+ value = value.encode("utf-8")
+ parts.append((headers, value))
+
+ body = b""
+ for headers, value in parts:
+ body += f"--{boundary}\r\n".encode()
+ body += f"{headers}\r\n\r\n".encode()
+ body += value
+ body += b"\r\n"
+ body += f"--{boundary}--\r\n".encode()
+
+ content_type = f"multipart/form-data; boundary={boundary}"
+ return base64.b64encode(body).decode("utf-8"), content_type
+
+
+def test_file_upload_basic(gw_event):
+ """Test basic file upload with File() parameter."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ body, content_type = _build_multipart_body(
+ [
+ {"name": "file_data", "value": b"hello world", "filename": "test.txt"},
+ ],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"size": 11}
+
+
+def test_file_upload_with_form_field(gw_event):
+ """Test file upload mixed with a regular form field."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(
+ description: Annotated[str, Form()],
+ file_data: Annotated[bytes, File()],
+ ):
+ return {"description": description, "size": len(file_data)}
+
+ body, content_type = _build_multipart_body(
+ [
+ {"name": "description", "value": "my file"},
+ {"name": "file_data", "value": b"\x89PNG\r\n\x1a\n", "filename": "image.png", "content_type": "image/png"},
+ ],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["description"] == "my file"
+ assert parsed["size"] == 8
+
+
+def test_file_upload_missing_required(gw_event):
+ """Test that missing required File() parameter returns 422."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ # Send empty multipart body (no file_data field)
+ body, content_type = _build_multipart_body(
+ [
+ {"name": "other_field", "value": "some value"},
+ ],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 422
+ assert "missing" in result["body"]
+
+
+def test_file_upload_openapi_schema():
+ """Test that File() parameters generate correct OpenAPI schema."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File(description="The file to upload")]):
+ return {"size": len(file_data)}
+
+ schema = app.get_openapi_schema()
+ path = schema.paths["/upload"]
+ post_op = path.post
+
+ # Should have a request body with multipart/form-data
+ assert post_op.requestBody is not None
+ content = post_op.requestBody.content
+ assert "multipart/form-data" in content
+
+ # The schema should reference a binary format field
+ multipart_schema = content["multipart/form-data"].schema_
+ assert multipart_schema is not None
+
+
+def test_file_upload_non_base64(gw_event):
+ """Test file upload when body is not base64-encoded (edge case)."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ # Build multipart body without base64 encoding
+ boundary = "----TestBoundary"
+ raw_body = (
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="test.txt"\r\n'
+ f"\r\n"
+ f"hello world\r\n"
+ f"--{boundary}--\r\n"
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = raw_body
+ gw_event["isBase64Encoded"] = False
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"size": 11}
+
+
+def test_file_upload_non_base64_emits_warning(gw_event):
+ """Test that non-base64 multipart body emits a warning about API Gateway config."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ boundary = "----TestBoundary"
+ raw_body = (
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="test.txt"\r\n'
+ f"\r\n"
+ f"hello world\r\n"
+ f"--{boundary}--\r\n"
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = raw_body
+ gw_event["isBase64Encoded"] = False
+
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter("always")
+ result = app(gw_event, {})
+
+ assert result["statusCode"] == 200
+ assert len(w) == 1
+ assert "Binary Media Types" in str(w[0].message)
+
+
+def test_file_upload_non_base64_binary_content(gw_event):
+ """Test file upload with raw binary bytes (e.g. JPEG) without base64 encoding."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ # Simulate binary content with bytes that are NOT valid UTF-8 (like JPEG header 0xFF 0xD8)
+ binary_content = b"\xff\xd8\xff\xe0\x00\x10JFIF\x00"
+ boundary = "----TestBoundary"
+ raw_bytes = (
+ (
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="photo.jpg"\r\n'
+ f"Content-Type: image/jpeg\r\n"
+ f"\r\n"
+ ).encode("latin-1")
+ + binary_content
+ + f"\r\n--{boundary}--\r\n".encode("latin-1")
+ )
+
+ # Without binary mode, API Gateway passes body as latin-1 compatible string
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = raw_bytes.decode("latin-1")
+ gw_event["isBase64Encoded"] = False
+
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always")
+ result = app(gw_event, {})
+
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"size": len(binary_content)}
+
+
+def test_upload_file_with_metadata(gw_event):
+ """Test UploadFile annotation provides filename and content_type."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[UploadFile, File()]):
+ return {
+ "filename": file_data.filename,
+ "content_type": file_data.content_type,
+ "size": len(file_data),
+ }
+
+ body, content_type = _build_multipart_body(
+ [
+ {"name": "file_data", "value": b"fake jpeg", "filename": "photo.jpg", "content_type": "image/jpeg"},
+ ],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["filename"] == "photo.jpg"
+ assert parsed["content_type"] == "image/jpeg"
+ assert parsed["size"] == 9
+
+
+def test_upload_file_mixed_with_form(gw_event):
+ """Test UploadFile + Form fields together."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(
+ file_data: Annotated[UploadFile, File()],
+ title: Annotated[str, Form()],
+ ):
+ return {
+ "title": title,
+ "filename": file_data.filename,
+ "size": len(file_data),
+ }
+
+ body, content_type = _build_multipart_body(
+ [
+ {"name": "title", "value": "My Document"},
+ {
+ "name": "file_data",
+ "value": b"pdf content here",
+ "filename": "doc.pdf",
+ "content_type": "application/pdf",
+ },
+ ],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["title"] == "My Document"
+ assert parsed["filename"] == "doc.pdf"
+ assert parsed["size"] == 16
+
+
+def test_upload_file_openapi_schema():
+ """Test UploadFile generates correct OpenAPI schema."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[UploadFile, File(description="A file")]):
+ return {}
+
+ schema = app.get_openapi_schema()
+ schema_dict = schema.model_dump(exclude_none=True, by_alias=True)
+ upload_path = schema_dict["paths"]["/upload"]["post"]
+ content = upload_path["requestBody"]["content"]
+ assert "multipart/form-data" in content
+
+ # Resolve $ref to get the actual schema
+ ref = content["multipart/form-data"]["schema"]["$ref"]
+ schema_name = ref.split("/")[-1]
+ props = schema_dict["components"]["schemas"][schema_name]["properties"]
+ assert props["file_data"]["type"] == "string"
+ assert props["file_data"]["format"] == "binary"
+
+
+def test_multipart_missing_boundary(gw_event):
+ """Test that missing boundary in content-type raises ValueError."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = "multipart/form-data" # no boundary
+ gw_event["body"] = base64.b64encode(b"some data").decode()
+ gw_event["isBase64Encoded"] = True
+
+ with pytest.raises(ValueError, match="Missing boundary"):
+ app(gw_event, {})
+
+
+def test_multipart_quoted_boundary(gw_event):
+ """Test that boundary with quotes is parsed correctly."""
+ from aws_lambda_powertools.event_handler.openapi.params import File
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[bytes, File()]):
+ return {"size": len(file_data)}
+
+ boundary = "----TestBoundary"
+ body, _ = _build_multipart_body(
+ [
+ {"name": "file_data", "value": b"hello", "filename": "test.txt"},
+ ],
+ boundary=boundary,
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ # Use quoted boundary
+ gw_event["headers"]["content-type"] = f'multipart/form-data; boundary="{boundary}"'
+ gw_event["body"] = body
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"size": 5}
+
+
+def test_multipart_multiple_values_same_field(gw_event):
+ """Test multiple values for the same field name are collected as list."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[List[UploadFile], File()]):
+ return {"count": len(file_data), "filenames": [f.filename for f in file_data]}
+
+ # Build body with two parts having the same field name
+ boundary = "----TestBoundary"
+ raw = (
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="a.txt"\r\n'
+ f"\r\n"
+ f"content a\r\n"
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="b.txt"\r\n'
+ f"\r\n"
+ f"content b\r\n"
+ f"--{boundary}--\r\n"
+ ).encode()
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = base64.b64encode(raw).decode()
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["count"] == 2
+ assert parsed["filenames"] == ["a.txt", "b.txt"]
+
+
+def test_multipart_three_values_same_field(gw_event):
+ """Test three or more values for same field name builds onto existing list."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[List[UploadFile], File()]):
+ return {"count": len(file_data), "filenames": [f.filename for f in file_data]}
+
+ boundary = "----TestBoundary"
+ raw = (
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="a.txt"\r\n'
+ f"\r\n"
+ f"aaa\r\n"
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="b.txt"\r\n'
+ f"\r\n"
+ f"bbb\r\n"
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="c.txt"\r\n'
+ f"\r\n"
+ f"ccc\r\n"
+ f"--{boundary}--\r\n"
+ ).encode()
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = base64.b64encode(raw).decode()
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["count"] == 3
+ assert parsed["filenames"] == ["a.txt", "b.txt", "c.txt"]
+
+
+def test_multipart_part_without_headers_separator(gw_event):
+ """Test that a malformed part missing the header/body separator is skipped."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[UploadFile, File()]):
+ return {"filename": file_data.filename}
+
+ # Build a body with one malformed part (no \r\n\r\n) and one valid part
+ boundary = "----TestBoundary"
+ raw = (
+ f"--{boundary}\r\n"
+ f"This part has no header separator at all\r\n"
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="good.txt"\r\n'
+ f"\r\n"
+ f"good content\r\n"
+ f"--{boundary}--\r\n"
+ ).encode()
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = base64.b64encode(raw).decode()
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["filename"] == "good.txt"
+
+
+def test_multipart_part_without_field_name(gw_event):
+ """Test that a part missing the name parameter in Content-Disposition is skipped."""
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[UploadFile, File()]):
+ return {"filename": file_data.filename}
+
+ # Build a body with one part that has no name= param and one valid part
+ boundary = "----TestBoundary"
+ raw = (
+ f"--{boundary}\r\n"
+ f"Content-Disposition: form-data\r\n"
+ f"\r\n"
+ f"orphan content\r\n"
+ f"--{boundary}\r\n"
+ f'Content-Disposition: form-data; name="file_data"; filename="valid.txt"\r\n'
+ f"\r\n"
+ f"valid content\r\n"
+ f"--{boundary}--\r\n"
+ ).encode()
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = f"multipart/form-data; boundary={boundary}"
+ gw_event["body"] = base64.b64encode(raw).decode()
+ gw_event["isBase64Encoded"] = True
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ parsed = json.loads(result["body"])
+ assert parsed["filename"] == "valid.txt"
+
+
+def test_upload_file_validate_error():
+ """Test UploadFile._validate raises ValueError for non-UploadFile values."""
+ from aws_lambda_powertools.event_handler.openapi.params import UploadFile
+
+ with pytest.raises(ValueError, match="Expected UploadFile, got str"):
+ UploadFile._validate("not an upload file")
+
+ with pytest.raises(ValueError, match="Expected UploadFile, got int"):
+ UploadFile._validate(42)
+
+
+def test_multipart_unclosed_quote_in_header():
+ """Test that _extract_header_param returns None when quote is unclosed."""
+ from aws_lambda_powertools.event_handler.middlewares.openapi_validation import _extract_header_param
+
+ # name=" is present but closing quote is missing
+ result = _extract_header_param('Content-Disposition: form-data; name="broken', "name")
+ assert result is None
+
+
+def test_multipart_generic_parse_error(gw_event):
+ """Test that non-ValueError exceptions during multipart parsing produce 422."""
+ from unittest.mock import patch
+
+ from aws_lambda_powertools.event_handler.openapi.params import File, UploadFile
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.post("/upload")
+ def upload(file_data: Annotated[UploadFile, File()]):
+ return {"filename": file_data.filename}
+
+ body_b64, content_type = _build_multipart_body(
+ [{"name": "file_data", "value": b"data", "filename": "test.txt"}],
+ )
+
+ gw_event["httpMethod"] = "POST"
+ gw_event["path"] = "/upload"
+ gw_event["headers"]["content-type"] = content_type
+ gw_event["body"] = body_b64
+ gw_event["isBase64Encoded"] = True
+
+ # Patch _parse_multipart_body to raise a non-ValueError (e.g. TypeError)
+ with patch(
+ "aws_lambda_powertools.event_handler.middlewares.openapi_validation._parse_multipart_body",
+ side_effect=TypeError("unexpected type"),
+ ):
+ result = app(gw_event, {})
+ assert result["statusCode"] == 422
+ body = json.loads(result["body"])
+ assert body["detail"][0]["type"] == "multipart_invalid"
+
+
+# ---------- Cookie parameter tests ----------
+
+
+def test_cookie_param_basic(gw_event):
+ """Test basic cookie parameter extraction from REST API v1 (Cookie header)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"]["cookie"] = "session_id=abc123; theme=dark"
+ # Clear multiValueHeaders to avoid interference
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "abc123"
+
+
+def test_cookie_param_missing_required(gw_event):
+ """Test that a missing required cookie returns 422."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"]["cookie"] = "theme=dark"
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 422
+
+
+def test_cookie_param_with_default(gw_event):
+ """Test cookie parameter with a default value when cookie is absent."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(theme: Annotated[str, Cookie()] = "light"):
+ return {"theme": theme}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"].pop("cookie", None)
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["theme"] == "light"
+
+
+def test_cookie_param_multiple_cookies(gw_event):
+ """Test extracting multiple cookie parameters."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(
+ session_id: Annotated[str, Cookie()],
+ theme: Annotated[str, Cookie()] = "light",
+ ):
+ return {"session_id": session_id, "theme": theme}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"]["cookie"] = "session_id=abc123; theme=dark"
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "abc123"
+ assert body["theme"] == "dark"
+
+
+def test_cookie_param_int_validation(gw_event):
+ """Test cookie parameter with int type validation."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(visits: Annotated[int, Cookie()]):
+ return {"visits": visits}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"]["cookie"] = "visits=42"
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["visits"] == 42
+
+ # Invalid int
+ gw_event["headers"]["cookie"] = "visits=not_a_number"
+ result = app(gw_event, {})
+ assert result["statusCode"] == 422
+
+
+def test_cookie_param_http_api_v2(gw_event_http):
+ """Test cookie parameter with HTTP API v2 (dedicated cookies field)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event_http["rawPath"] = "/me"
+ gw_event_http["requestContext"]["http"]["method"] = "GET"
+ gw_event_http["cookies"] = ["session_id=xyz789", "theme=dark"]
+
+ result = app(gw_event_http, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "xyz789"
+
+
+def test_cookie_param_lambda_function_url(gw_event_lambda_url):
+ """Test cookie parameter with Lambda Function URL (v2 format)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = LambdaFunctionUrlResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event_lambda_url["rawPath"] = "/me"
+ gw_event_lambda_url["requestContext"]["http"]["method"] = "GET"
+ gw_event_lambda_url["cookies"] = ["session_id=fn_url_abc"]
+
+ result = app(gw_event_lambda_url, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "fn_url_abc"
+
+
+def test_cookie_param_alb(gw_event_alb):
+ """Test cookie parameter with ALB (Cookie header in multiValueHeaders)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = ALBResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event_alb["path"] = "/me"
+ gw_event_alb["httpMethod"] = "GET"
+ gw_event_alb["multiValueHeaders"]["cookie"] = ["session_id=alb_abc"]
+
+ result = app(gw_event_alb, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "alb_abc"
+
+
+def test_cookie_param_openapi_schema():
+ """Test that Cookie() generates correct OpenAPI schema with in=cookie."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(
+ session_id: Annotated[str, Cookie(description="Session identifier")],
+ theme: Annotated[str, Cookie(description="UI theme")] = "light",
+ ):
+ return {"session_id": session_id}
+
+ schema = app.get_openapi_schema()
+ schema_dict = schema.model_dump(mode="json", by_alias=True, exclude_none=True)
+
+ path = schema_dict["paths"]["/me"]["get"]
+ params = path["parameters"]
+
+ cookie_params = [p for p in params if p["in"] == "cookie"]
+ assert len(cookie_params) == 2
+
+ session_param = next(p for p in cookie_params if p["name"] == "session_id")
+ assert session_param["required"] is True
+ assert session_param["description"] == "Session identifier"
+
+ theme_param = next(p for p in cookie_params if p["name"] == "theme")
+ assert theme_param.get("required") is not True
+ assert theme_param["description"] == "UI theme"
+
+
+def test_cookie_param_with_query_and_header(gw_event):
+ """Test that Cookie(), Query(), and Header() work together."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(
+ user_id: Annotated[str, Query()],
+ x_request_id: Annotated[str, Header()],
+ session_id: Annotated[str, Cookie()],
+ ):
+ return {
+ "user_id": user_id,
+ "x_request_id": x_request_id,
+ "session_id": session_id,
+ }
+
+ gw_event["path"] = "/me"
+ gw_event["queryStringParameters"] = {"user_id": "u123"}
+ gw_event["multiValueQueryStringParameters"] = {"user_id": ["u123"]}
+ gw_event["headers"]["x-request-id"] = "req-456"
+ gw_event["multiValueHeaders"] = {"x-request-id": ["req-456"], "cookie": ["session_id=sess-789"]}
+ gw_event["headers"]["cookie"] = "session_id=sess-789"
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["user_id"] == "u123"
+ assert body["x_request_id"] == "req-456"
+ assert body["session_id"] == "sess-789"
+
+
+def test_cookie_param_no_cookies_in_request(gw_event):
+ """Test that empty cookies dict is handled gracefully."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = APIGatewayRestResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(theme: Annotated[str, Cookie()] = "light"):
+ return {"theme": theme}
+
+ gw_event["path"] = "/me"
+ gw_event["headers"] = {}
+ gw_event.pop("multiValueHeaders", None)
+
+ result = app(gw_event, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["theme"] == "light"
+
+
+def test_cookie_param_vpc_lattice_v2(gw_event_vpc_lattice):
+ """Test cookie parameter with VPC Lattice v2 (headers are lists)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = VPCLatticeV2Resolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event_vpc_lattice["method"] = "GET"
+ gw_event_vpc_lattice["path"] = "/me"
+ gw_event_vpc_lattice["headers"]["cookie"] = ["session_id=lattice_abc"]
+
+ result = app(gw_event_vpc_lattice, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "lattice_abc"
+
+
+def test_cookie_param_vpc_lattice_v1(gw_event_vpc_lattice_v1):
+ """Test cookie parameter with VPC Lattice v1 (comma-separated headers)."""
+ from aws_lambda_powertools.event_handler.openapi.params import Cookie
+
+ app = VPCLatticeResolver(enable_validation=True)
+
+ @app.get("/me")
+ def handler(session_id: Annotated[str, Cookie()]):
+ return {"session_id": session_id}
+
+ gw_event_vpc_lattice_v1["method"] = "GET"
+ gw_event_vpc_lattice_v1["raw_path"] = "/me"
+ gw_event_vpc_lattice_v1["headers"]["cookie"] = "session_id=lattice_v1_abc"
+
+ result = app(gw_event_vpc_lattice_v1, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["session_id"] == "lattice_v1_abc"
+
+
+def test_alb_response_none_body_with_validation(gw_event_alb):
+ # GIVEN an ALBResolver with validation enabled
+ app = ALBResolver(enable_validation=True)
+
+ gw_event_alb["path"] = "/no-content"
+ gw_event_alb["httpMethod"] = "DELETE"
+
+ # WHEN a handler returns Response with body=None and return type is None
+ @app.delete("/no-content")
+ def handler() -> None:
+ return Response(status_code=204, body=None)
+
+ # THEN the response should be 204 with empty body (not 422 validation error)
+ result = app(gw_event_alb, {})
+ assert result["statusCode"] == 204
+ assert result["body"] == ""
+
+
+def test_alb_response_typed_none_body_with_validation(gw_event_alb):
+ # GIVEN an ALBResolver with validation enabled
+ app = ALBResolver(enable_validation=True)
+
+ gw_event_alb["path"] = "/no-content"
+ gw_event_alb["httpMethod"] = "DELETE"
+
+ # WHEN a handler returns Response[None] with body=None
+ @app.delete("/no-content")
+ def handler() -> Response[None]:
+ return Response(status_code=204, body=None)
+
+ # THEN the response should be 204 with empty body (not 422 validation error)
+ result = app(gw_event_alb, {})
+ assert result["statusCode"] == 204
+ assert result["body"] == ""
diff --git a/tests/functional/event_handler/_pydantic/test_resolve_async_validation.py b/tests/functional/event_handler/_pydantic/test_resolve_async_validation.py
new file mode 100644
index 00000000000..92b414f72b5
--- /dev/null
+++ b/tests/functional/event_handler/_pydantic/test_resolve_async_validation.py
@@ -0,0 +1,55 @@
+import asyncio
+
+from aws_lambda_powertools.event_handler.api_gateway import (
+ APIGatewayHttpResolver,
+ BaseRouter,
+)
+from tests.functional.utils import load_event
+
+API_RESTV2_EVENT = load_event("apiGatewayProxyV2Event_GET.json")
+
+
+def _setup_app(app, event):
+ BaseRouter.current_event = app._to_proxy_event(event)
+ BaseRouter.lambda_context = {}
+
+
+class TestResolveAsyncValidation:
+ def test_validation_middleware_created_and_used(self):
+ # GIVEN a resolver with validation enabled and an async handler
+ app = APIGatewayHttpResolver(enable_validation=True)
+
+ @app.get("/my/path")
+ async def get_lambda() -> dict:
+ await asyncio.sleep(0)
+ return {"message": "validated"}
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_RESTV2_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the validation middlewares are created and the response is valid
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert hasattr(app, "_request_validation_middleware")
+ assert hasattr(app, "_response_validation_middleware")
+
+ def test_validation_middleware_lazy_created_for_per_route_validation(self):
+ # GIVEN a resolver WITHOUT global validation, but a route WITH enable_validation=True
+ app = APIGatewayHttpResolver()
+ assert not hasattr(app, "_request_validation_middleware")
+
+ @app.get("/my/path", enable_validation=True)
+ async def get_lambda() -> dict:
+ await asyncio.sleep(0)
+ return {"message": "lazy validated"}
+
+ # WHEN calling _resolve_async (triggers lazy creation in Route.call_async)
+ _setup_app(app, API_RESTV2_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN validation middlewares are lazily created on the app
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert hasattr(app, "_request_validation_middleware")
+ assert hasattr(app, "_response_validation_middleware")
diff --git a/tests/functional/event_handler/required_dependencies/test_async_middleware_frame.py b/tests/functional/event_handler/required_dependencies/test_async_middleware_frame.py
new file mode 100644
index 00000000000..6154820454d
--- /dev/null
+++ b/tests/functional/event_handler/required_dependencies/test_async_middleware_frame.py
@@ -0,0 +1,89 @@
+import asyncio
+
+import pytest
+
+from aws_lambda_powertools.event_handler import content_types
+from aws_lambda_powertools.event_handler.api_gateway import (
+ ApiGatewayResolver,
+ ProxyEventType,
+ Response,
+)
+from aws_lambda_powertools.event_handler.middlewares import NextMiddleware
+from aws_lambda_powertools.event_handler.middlewares.async_utils import AsyncMiddlewareFrame, wrap_middleware_async
+from tests.functional.utils import load_event
+
+API_REST_EVENT = load_event("apiGatewayProxyEvent.json")
+
+
+def _make_app() -> ApiGatewayResolver:
+ app = ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent)
+ app.current_event = app._to_proxy_event(API_REST_EVENT)
+ app.lambda_context = {}
+ return app
+
+
+def test_sync_middleware_raising_before_next_does_not_deadlock():
+ # GIVEN a sync middleware that raises before calling next()
+ # This previously caused a deadlock because middleware_called_next was never set
+ app = _make_app()
+
+ class AuthError(Exception):
+ pass
+
+ def failing_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ raise AuthError("denied")
+
+ async def next_handler(app: ApiGatewayResolver):
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "should not reach")
+
+ frame = AsyncMiddlewareFrame(current_middleware=failing_middleware, next_middleware=next_handler)
+
+ # WHEN calling the frame
+ # THEN the exception propagates without deadlocking
+ with pytest.raises(AuthError, match="denied"):
+ asyncio.run(frame(app))
+
+
+def test_wrap_middleware_async_sync_raising_before_next_does_not_deadlock():
+ # GIVEN a sync middleware that raises before calling next(), using wrap_middleware_async
+ # This exercises _run_sync_middleware_in_thread directly
+ app = _make_app()
+
+ class AuthError(Exception):
+ pass
+
+ def failing_middleware(app, next_middleware):
+ raise AuthError("denied")
+
+ async def next_handler(app):
+ return Response(200, content_types.TEXT_HTML, "should not reach")
+
+ wrapped = wrap_middleware_async(failing_middleware, next_handler)
+
+ # WHEN calling the wrapped middleware
+ # THEN the exception propagates without deadlocking
+ with pytest.raises(AuthError, match="denied"):
+ asyncio.run(wrapped(app))
+
+
+def test_async_middleware_raising_before_next_propagates():
+ # GIVEN an async middleware that raises before calling next()
+ app = _make_app()
+
+ class ValidationError(Exception):
+ pass
+
+ async def failing_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ raise ValidationError("invalid request")
+
+ async def next_handler(app: ApiGatewayResolver):
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "should not reach")
+
+ frame = AsyncMiddlewareFrame(current_middleware=failing_middleware, next_middleware=next_handler)
+
+ # WHEN calling the frame
+ # THEN the exception propagates
+ with pytest.raises(ValidationError, match="invalid request"):
+ asyncio.run(frame(app))
diff --git a/tests/functional/event_handler/required_dependencies/test_depends.py b/tests/functional/event_handler/required_dependencies/test_depends.py
new file mode 100644
index 00000000000..d5e49e07cdd
--- /dev/null
+++ b/tests/functional/event_handler/required_dependencies/test_depends.py
@@ -0,0 +1,509 @@
+"""Tests for the Depends() dependency injection feature using Annotated."""
+
+import json
+
+import pytest
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import APIGatewayHttpResolver
+from aws_lambda_powertools.event_handler.depends import DependencyResolutionError, Depends
+from aws_lambda_powertools.event_handler.request import Request
+from tests.functional.utils import load_event
+
+API_GW_V2_EVENT = load_event("apiGatewayProxyV2Event.json")
+
+
+def test_depends_simple():
+ """A simple dependency is resolved and injected into the handler."""
+ app = APIGatewayHttpResolver()
+
+ def get_greeting() -> str:
+ return "hello"
+
+ @app.post("/my/path")
+ def handler(greeting: Annotated[str, Depends(get_greeting)]):
+ return {"greeting": greeting}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"greeting": "hello"}
+
+
+def test_depends_nested():
+ """Dependencies can depend on other dependencies."""
+ app = APIGatewayHttpResolver()
+
+ def get_prefix() -> str:
+ return "Hello"
+
+ def get_greeting(prefix: Annotated[str, Depends(get_prefix)]) -> str:
+ return f"{prefix}, world!"
+
+ @app.post("/my/path")
+ def handler(greeting: Annotated[str, Depends(get_greeting)]):
+ return {"greeting": greeting}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"greeting": "Hello, world!"}
+
+
+def test_depends_cache_per_invocation():
+ """Same dependency used twice in one invocation is only resolved once (use_cache=True)."""
+ app = APIGatewayHttpResolver()
+ call_count = 0
+
+ def get_config() -> dict:
+ nonlocal call_count
+ call_count += 1
+ return {"key": "value"}
+
+ def get_a(config: Annotated[dict, Depends(get_config)]) -> str:
+ return config["key"]
+
+ def get_b(config: Annotated[dict, Depends(get_config)]) -> str:
+ return config["key"]
+
+ @app.post("/my/path")
+ def handler(a: Annotated[str, Depends(get_a)], b: Annotated[str, Depends(get_b)]):
+ return {"a": a, "b": b}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert call_count == 1 # get_config called once despite being used by both get_a and get_b
+
+
+def test_depends_no_cache():
+ """use_cache=False resolves every time."""
+ app = APIGatewayHttpResolver()
+ call_count = 0
+
+ def get_value() -> int:
+ nonlocal call_count
+ call_count += 1
+ return call_count
+
+ @app.post("/my/path")
+ def handler(
+ a: Annotated[int, Depends(get_value, use_cache=False)],
+ b: Annotated[int, Depends(get_value, use_cache=False)],
+ ):
+ return {"a": a, "b": b}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert call_count == 2
+
+
+def test_depends_with_request():
+ """A dependency can receive the Request object."""
+ app = APIGatewayHttpResolver()
+
+ def get_method(request: Request) -> str:
+ return request.method
+
+ @app.post("/my/path")
+ def handler(method: Annotated[str, Depends(get_method)]):
+ return {"method": method}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"method": "POST"}
+
+
+def test_depends_override():
+ """dependency_overrides replaces a dependency callable for testing."""
+ app = APIGatewayHttpResolver()
+
+ def get_tenant() -> str:
+ return "real-tenant"
+
+ @app.post("/my/path")
+ def handler(tenant: Annotated[str, Depends(get_tenant)]):
+ return {"tenant": tenant}
+
+ app.dependency_overrides[get_tenant] = lambda: "test-tenant"
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"tenant": "test-tenant"}
+
+ app.dependency_overrides.clear()
+
+
+def test_depends_override_nested():
+ """dependency_overrides works for nested dependencies too."""
+ app = APIGatewayHttpResolver()
+
+ def get_db_client():
+ return "real-db"
+
+ def get_table(db: Annotated[str, Depends(get_db_client)]) -> str:
+ return f"table-from-{db}"
+
+ @app.post("/my/path")
+ def handler(table: Annotated[str, Depends(get_table)]):
+ return {"table": table}
+
+ app.dependency_overrides[get_db_client] = lambda: "mock-db"
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"table": "table-from-mock-db"}
+
+ app.dependency_overrides.clear()
+
+
+def test_depends_multiple_handlers():
+ """Dependencies work across different route handlers."""
+ app = APIGatewayHttpResolver()
+
+ def get_user() -> str:
+ return "user-123"
+
+ @app.get("/my/path")
+ def get_handler(user: Annotated[str, Depends(get_user)]):
+ return {"user": user, "action": "get"}
+
+ @app.post("/my/path")
+ def post_handler(user: Annotated[str, Depends(get_user)]):
+ return {"user": user, "action": "post"}
+
+ # Test POST (matches the event)
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"user": "user-123", "action": "post"}
+
+
+def test_depends_reusable_type_alias():
+ """Annotated type aliases can be reused across handlers."""
+ app = APIGatewayHttpResolver()
+
+ def get_tenant() -> str:
+ return "tenant-abc"
+
+ TenantId = Annotated[str, Depends(get_tenant)]
+
+ @app.post("/my/path")
+ def handler(tenant: TenantId):
+ return {"tenant": tenant}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"tenant": "tenant-abc"}
+
+
+def test_handler_without_depends_works_normally():
+ """A plain handler with no Depends() params is not affected by DI."""
+ app = APIGatewayHttpResolver()
+
+ @app.post("/my/path")
+ def handler():
+ return {"ok": True}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"ok": True}
+
+
+def test_depends_not_cached_across_invocations():
+ """Each app() call resolves dependencies fresh — no cross-request leakage."""
+ app = APIGatewayHttpResolver()
+ call_count = 0
+
+ def get_counter() -> int:
+ nonlocal call_count
+ call_count += 1
+ return call_count
+
+ @app.post("/my/path")
+ def handler(c: Annotated[int, Depends(get_counter)]):
+ return {"c": c}
+
+ result1 = app(API_GW_V2_EVENT, {})
+ result2 = app(API_GW_V2_EVENT, {})
+
+ assert json.loads(result1["body"]) == {"c": 1}
+ assert json.loads(result2["body"]) == {"c": 2}
+ assert call_count == 2
+
+
+def test_depends_deeply_nested():
+ """Three-level dependency chain resolves correctly."""
+ app = APIGatewayHttpResolver()
+
+ def get_url() -> str:
+ return "postgres://localhost"
+
+ def get_conn(url: Annotated[str, Depends(get_url)]) -> str:
+ return f"conn({url})"
+
+ def get_session(conn: Annotated[str, Depends(get_conn)]) -> str:
+ return f"session({conn})"
+
+ @app.post("/my/path")
+ def handler(session: Annotated[str, Depends(get_session)]):
+ return {"session": session}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"session": "session(conn(postgres://localhost))"}
+
+
+def test_depends_with_request_reads_headers():
+ """A dependency using Request can read actual request headers."""
+ app = APIGatewayHttpResolver()
+
+ def get_user_agent(request: Request) -> str:
+ return request.headers.get("user-agent", "unknown")
+
+ @app.post("/my/path")
+ def handler(ua: Annotated[str, Depends(get_user_agent)]):
+ return {"ua": ua}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert isinstance(json.loads(result["body"])["ua"], str)
+
+
+def test_depends_returning_none():
+ """A dependency can return None without breaking."""
+ app = APIGatewayHttpResolver()
+
+ def get_nothing() -> None:
+ return None
+
+ @app.post("/my/path")
+ def handler(val: Annotated[None, Depends(get_nothing)]):
+ return {"val": val}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"val": None}
+
+
+def test_depends_exception_raises_dependency_resolution_error():
+ """If a dependency raises, a DependencyResolutionError wraps the original exception."""
+ app = APIGatewayHttpResolver()
+
+ def broken() -> str:
+ raise ValueError("boom")
+
+ @app.post("/my/path")
+ def handler(val: Annotated[str, Depends(broken)]):
+ return {"val": val}
+
+ with pytest.raises(DependencyResolutionError, match="broken.*boom"):
+ app(API_GW_V2_EVENT, {})
+
+
+def test_depends_non_callable_raises_dependency_resolution_error():
+ """Passing a non-callable to Depends() raises DependencyResolutionError immediately."""
+ with pytest.raises(DependencyResolutionError, match="requires a callable"):
+ Depends("not_a_function") # type: ignore
+
+ with pytest.raises(DependencyResolutionError, match="requires a callable"):
+ Depends(42) # type: ignore
+
+ with pytest.raises(DependencyResolutionError, match="requires a callable"):
+ Depends(None) # type: ignore
+
+
+def test_depends_accepts_lambda():
+ """Depends() works with a lambda as the dependency."""
+ app = APIGatewayHttpResolver()
+
+ @app.post("/my/path")
+ def handler(val: Annotated[str, Depends(lambda: "from-lambda")]):
+ return {"val": val}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"val": "from-lambda"}
+
+
+def test_depends_accepts_class_with_call():
+ """Depends() works with a class that implements __call__."""
+ app = APIGatewayHttpResolver()
+
+ class TenantProvider:
+ def __call__(self) -> str:
+ return "tenant-from-class"
+
+ @app.post("/my/path")
+ def handler(tenant: Annotated[str, Depends(TenantProvider())]):
+ return {"tenant": tenant}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"tenant": "tenant-from-class"}
+
+
+def test_depends_accepts_class_as_factory():
+ """Depends() works with a class itself (constructor as callable)."""
+ app = APIGatewayHttpResolver()
+
+ class Config:
+ def __init__(self):
+ self.region = "us-east-1"
+
+ @app.post("/my/path")
+ def handler(config: Annotated[Config, Depends(Config)]):
+ return {"region": config.region}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"region": "us-east-1"}
+
+
+def test_depends_with_unresolvable_annotations_is_ignored():
+ """A handler whose annotations cannot be resolved by get_type_hints is treated as having no deps."""
+ app = APIGatewayHttpResolver()
+
+ # Build a function with broken annotations that get_type_hints cannot resolve.
+ # The param has a default so the handler can still be called without it.
+ def make_handler():
+ def handler(x: "CompletelyBogusType" = None): # noqa: F821
+ return {"ok": True}
+
+ return handler
+
+ app.post("/my/path")(make_handler())
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"ok": True}
+
+
+def test_depends_without_request_does_not_inject():
+ """A dependency that does NOT declare Request still works when request is available."""
+ app = APIGatewayHttpResolver()
+
+ def get_static() -> str:
+ return "no-request-needed"
+
+ @app.post("/my/path")
+ def handler(val: Annotated[str, Depends(get_static)]):
+ return {"val": val}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"val": "no-request-needed"}
+
+
+def test_depends_with_broken_type_hints_on_dependency():
+ """A dependency callable with broken annotations still resolves (get_type_hints fails gracefully)."""
+ app = APIGatewayHttpResolver()
+
+ # Create a callable whose annotations reference a nonexistent type
+ # so get_type_hints() will raise inside solve_dependencies
+ broken_dep = type(
+ "BrokenDep",
+ (),
+ {
+ "__call__": lambda self: "it-works",
+ "__annotations__": {"x": "NonExistentType"},
+ "__module__": __name__,
+ },
+ )()
+
+ @app.post("/my/path")
+ def handler(val: Annotated[str, Depends(broken_dep)]):
+ return {"val": val}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"val": "it-works"}
+
+
+# ---------------------------------------------------------------------------
+# request.context — bridge between middleware and Depends()
+# ---------------------------------------------------------------------------
+
+
+def test_depends_request_context_writable():
+ """Dependencies can write to request.context and handlers can read it."""
+ app = APIGatewayHttpResolver()
+
+ def set_tenant(request: Request) -> str:
+ tenant = request.headers.get("x-tenant-id", "default")
+ request.context["tenant"] = tenant
+ return tenant
+
+ @app.post("/my/path")
+ def handler(tenant: Annotated[str, Depends(set_tenant)], request: Request):
+ return {"tenant": tenant, "from_context": request.context.get("tenant")}
+
+ event = {**API_GW_V2_EVENT, "headers": {**API_GW_V2_EVENT.get("headers", {}), "x-tenant-id": "acme-corp"}}
+ result = app(event, {})
+
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["tenant"] == "acme-corp"
+ assert body["from_context"] == "acme-corp"
+
+
+def test_depends_request_context_bridges_middleware():
+ """Middleware writes to app.context, Depends() reads via request.context."""
+ app = APIGatewayHttpResolver()
+
+ def auth_middleware(app, next_middleware):
+ app.append_context(user="admin-user")
+ return next_middleware(app)
+
+ app.use(middlewares=[auth_middleware])
+
+ def get_current_user(request: Request) -> str:
+ return request.context["user"]
+
+ @app.post("/my/path")
+ def handler(user: Annotated[str, Depends(get_current_user)]):
+ return {"user": user}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"user": "admin-user"}
+
+
+def test_depends_request_context_with_router():
+ """request.context works when routes come from an included Router."""
+ from aws_lambda_powertools.event_handler.api_gateway import Router
+
+ app = APIGatewayHttpResolver()
+ router = Router()
+
+ def mw(app, next_middleware):
+ app.append_context(role="admin")
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ def get_role(request: Request) -> str:
+ return request.context["role"]
+
+ @router.post("/my/path")
+ def handler(role: Annotated[str, Depends(get_role)]):
+ return {"role": role}
+
+ app.include_router(router)
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ assert json.loads(result["body"]) == {"role": "admin"}
+
+
+def test_depends_request_resolved_event():
+ """Dependencies can access the full event via request.resolved_event."""
+ app = APIGatewayHttpResolver()
+
+ def get_path(request: Request) -> str:
+ return request.resolved_event.path
+
+ @app.post("/my/path")
+ def handler(path: Annotated[str, Depends(get_path)]):
+ return {"path": path}
+
+ result = app(API_GW_V2_EVENT, {})
+ assert result["statusCode"] == 200
+ body = json.loads(result["body"])
+ assert body["path"] == "/my/path"
diff --git a/tests/functional/event_handler/required_dependencies/test_registered_api_adapter_async.py b/tests/functional/event_handler/required_dependencies/test_registered_api_adapter_async.py
new file mode 100644
index 00000000000..10d5b4602f0
--- /dev/null
+++ b/tests/functional/event_handler/required_dependencies/test_registered_api_adapter_async.py
@@ -0,0 +1,335 @@
+import asyncio
+import re
+from typing import cast
+
+import pytest
+from typing_extensions import Annotated
+
+from aws_lambda_powertools.event_handler import content_types
+from aws_lambda_powertools.event_handler.api_gateway import (
+ APIGatewayHttpResolver,
+ ApiGatewayResolver,
+ APIGatewayRestResolver,
+ BaseRouter,
+ ProxyEventType,
+ Response,
+ Route,
+)
+from aws_lambda_powertools.event_handler.depends import Depends
+from aws_lambda_powertools.event_handler.middlewares.async_utils import _registered_api_adapter_async
+from aws_lambda_powertools.event_handler.request import Request
+from tests.functional.utils import load_event
+
+API_REST_EVENT = load_event("apiGatewayProxyEvent.json")
+API_RESTV2_EVENT = load_event("apiGatewayProxyV2Event_GET.json")
+
+
+def _setup_resolver_context(app: ApiGatewayResolver, event: dict) -> None:
+ """Populate the resolver context the same way resolve() does, without calling the full chain."""
+ BaseRouter.current_event = app._to_proxy_event(cast(dict, event))
+ BaseRouter.lambda_context = {}
+
+
+@pytest.mark.parametrize(
+ "app, event",
+ [
+ (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT),
+ (APIGatewayRestResolver(), API_REST_EVENT),
+ (APIGatewayHttpResolver(), API_RESTV2_EVENT),
+ ],
+)
+def test_sync_handler_returns_response(app: ApiGatewayResolver, event):
+ # GIVEN a sync route handler
+ @app.get("/my/path")
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "sync response")
+
+ # WHEN resolving the event through the normal chain
+ result = app(event, {})
+
+ # THEN the sync handler is called and returns correctly
+ assert result["statusCode"] == 200
+ assert result["body"] == "sync response"
+
+
+@pytest.mark.parametrize(
+ "app, event",
+ [
+ (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT),
+ (APIGatewayRestResolver(), API_REST_EVENT),
+ (APIGatewayHttpResolver(), API_RESTV2_EVENT),
+ ],
+)
+def test_async_handler_is_awaited(app: ApiGatewayResolver, event):
+ # GIVEN an async route handler registered on the resolver
+ @app.get("/my/path")
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "async response")
+
+ # WHEN populating context and calling the async adapter directly
+ _setup_resolver_context(app, event)
+ app.append_context(_route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN the async handler is awaited and returns correctly
+ assert result.status_code == 200
+ assert result.body == "async response"
+
+
+@pytest.mark.parametrize(
+ "app, event",
+ [
+ (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT),
+ (APIGatewayRestResolver(), API_REST_EVENT),
+ (APIGatewayHttpResolver(), API_RESTV2_EVENT),
+ ],
+)
+def test_sync_handler_through_adapter(app: ApiGatewayResolver, event):
+ # GIVEN a sync route handler
+ @app.get("/my/path")
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "sync via adapter")
+
+ # WHEN calling _registered_api_adapter_async with a sync handler
+ _setup_resolver_context(app, event)
+ app.append_context(_route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN sync handler works through the async adapter without issue
+ assert result.status_code == 200
+ assert result.body == "sync via adapter"
+
+
+@pytest.mark.parametrize(
+ "app, event",
+ [
+ (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT),
+ (APIGatewayRestResolver(), API_REST_EVENT),
+ (APIGatewayHttpResolver(), API_RESTV2_EVENT),
+ ],
+)
+def test_adapter_passes_route_args_to_async_handler(app: ApiGatewayResolver, event):
+ # GIVEN an async handler that expects route arguments
+ async def get_lambda(name: str):
+ return Response(200, content_types.TEXT_HTML, name)
+
+ # WHEN route_args are set in the context
+ _setup_resolver_context(app, event)
+ app.append_context(_route_args={"name": "powertools"})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN the route args are passed to the handler
+ assert result.status_code == 200
+ assert result.body == "powertools"
+
+
+@pytest.mark.parametrize(
+ "app, event",
+ [
+ (ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent), API_REST_EVENT),
+ (APIGatewayRestResolver(), API_REST_EVENT),
+ (APIGatewayHttpResolver(), API_RESTV2_EVENT),
+ ],
+)
+def test_adapter_passes_route_args_to_sync_handler(app: ApiGatewayResolver, event):
+ # GIVEN a sync handler that expects route arguments
+ def get_lambda(name: str):
+ return Response(200, content_types.TEXT_HTML, name)
+
+ # WHEN route_args are set in the context
+ _setup_resolver_context(app, event)
+ app.append_context(_route_args={"name": "powertools"})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN the route args are passed to the sync handler
+ assert result.status_code == 200
+ assert result.body == "powertools"
+
+
+def test_adapter_converts_dict_response_from_async_handler():
+ # GIVEN an async handler that returns a dict (not a Response object)
+ app = ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent)
+
+ async def get_lambda():
+ return {"message": "hello"}
+
+ # WHEN calling through the async adapter
+ _setup_resolver_context(app, API_REST_EVENT)
+ app.append_context(_route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN _to_response normalizes the dict into a Response object
+ assert result.status_code == 200
+ assert result.body is not None
+
+
+def test_adapter_converts_tuple_response_from_async_handler():
+ # GIVEN an async handler that returns a (dict, status_code) tuple
+ app = ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent)
+
+ async def get_lambda():
+ return {"created": True}, 201
+
+ # WHEN calling through the async adapter
+ _setup_resolver_context(app, API_REST_EVENT)
+ app.append_context(_route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN _to_response normalizes the tuple into a Response object
+ assert result.status_code == 201
+
+
+def test_adapter_with_no_route_in_context():
+ # GIVEN a handler and no _route in context
+ app = ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent)
+
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "no route")
+
+ # WHEN _route is None in context (default)
+ _setup_resolver_context(app, API_REST_EVENT)
+ app.append_context(_route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN the adapter skips request injection and dependency resolution
+ assert result.status_code == 200
+ assert result.body == "no route"
+
+
+def test_adapter_injects_request_param():
+ # GIVEN an async handler that declares a Request parameter
+ app = APIGatewayHttpResolver()
+
+ async def get_lambda(request: Request):
+ return Response(200, content_types.TEXT_HTML, request.method)
+
+ # WHEN a Route is present in context with request_param_name not yet checked
+ _setup_resolver_context(app, API_RESTV2_EVENT)
+ route = Route(
+ method="GET",
+ path="/my/path",
+ rule=re.compile(r"^/my/path$"),
+ func=get_lambda,
+ cors=False,
+ compress=False,
+ )
+ app.append_context(_route=route, _route_args={})
+
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN the Request object is injected and request_param_name is cached
+ assert result.status_code == 200
+ assert route.request_param_name_checked is True
+ assert route.request_param_name == "request"
+
+
+def test_adapter_uses_cached_request_param_name():
+ # GIVEN a Route where request_param_name was already resolved
+ app = APIGatewayHttpResolver()
+
+ async def get_lambda(req: Request):
+ return Response(200, content_types.TEXT_HTML, req.method)
+
+ _setup_resolver_context(app, API_RESTV2_EVENT)
+ route = Route(
+ method="GET",
+ path="/my/path",
+ rule=re.compile(r"^/my/path$"),
+ func=get_lambda,
+ cors=False,
+ compress=False,
+ )
+ route.request_param_name = "req"
+ route.request_param_name_checked = True
+ app.append_context(_route=route, _route_args={})
+
+ # WHEN calling the adapter a second time (cache hit)
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN it still injects the Request using the cached param name
+ assert result.status_code == 200
+
+
+def test_adapter_resolves_dependencies():
+ # GIVEN an async handler with Depends() parameters
+ app = APIGatewayHttpResolver()
+
+ def get_greeting() -> str:
+ return "hello"
+
+ async def get_lambda(greeting: Annotated[str, Depends(get_greeting)]):
+ return {"greeting": greeting}
+
+ _setup_resolver_context(app, API_RESTV2_EVENT)
+ route = Route(
+ method="GET",
+ path="/my/path",
+ rule=re.compile(r"^/my/path$"),
+ func=get_lambda,
+ cors=False,
+ compress=False,
+ )
+ app.append_context(_route=route, _route_args={})
+
+ # WHEN calling the adapter
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN dependencies are resolved and injected
+ assert result.status_code == 200
+
+
+def test_adapter_resolves_dependencies_with_sync_handler():
+ # GIVEN a sync handler with Depends() parameters
+ app = APIGatewayHttpResolver()
+
+ def get_greeting() -> str:
+ return "hello"
+
+ def get_lambda(greeting: Annotated[str, Depends(get_greeting)]):
+ return {"greeting": greeting}
+
+ _setup_resolver_context(app, API_RESTV2_EVENT)
+ route = Route(
+ method="GET",
+ path="/my/path",
+ rule=re.compile(r"^/my/path$"),
+ func=get_lambda,
+ cors=False,
+ compress=False,
+ )
+ app.append_context(_route=route, _route_args={})
+
+ # WHEN calling the adapter with a sync handler that has dependencies
+ result = asyncio.run(
+ _registered_api_adapter_async(app, get_lambda),
+ )
+
+ # THEN dependencies are resolved and injected for sync handler too
+ assert result.status_code == 200
diff --git a/tests/functional/event_handler/required_dependencies/test_request.py b/tests/functional/event_handler/required_dependencies/test_request.py
new file mode 100644
index 00000000000..b00ae6659ba
--- /dev/null
+++ b/tests/functional/event_handler/required_dependencies/test_request.py
@@ -0,0 +1,669 @@
+"""Tests for the Request object feature (GH #7992).
+
+Covers:
+- ``app.request`` availability in global and route-level middleware
+- ``Request`` type-annotation injection in route handlers
+- ``Request`` properties: route, path_parameters, method, headers, query_parameters, body
+- ``RuntimeError`` when ``app.request`` is accessed outside of resolution
+- Backward compatibility: routes without ``Request`` continue to work unchanged
+- ``APIGatewayHttpResolver`` and ``ALBResolver`` variants
+"""
+
+from __future__ import annotations
+
+from typing import TYPE_CHECKING
+
+import pytest
+
+from aws_lambda_powertools.event_handler import (
+ ALBResolver,
+ APIGatewayHttpResolver,
+ APIGatewayRestResolver,
+ Request,
+ Response,
+)
+from tests.functional.utils import load_event
+
+if TYPE_CHECKING:
+ from aws_lambda_powertools.event_handler.middlewares import NextMiddleware
+
+# ---------------------------------------------------------------------------
+# Shared test events
+# ---------------------------------------------------------------------------
+
+API_REST_EVENT = load_event("apiGatewayProxyEvent.json") # GET /my/path
+API_RESTV2_EVENT = load_event("apiGatewayProxyV2Event_GET.json")
+
+
+def _make_rest_event(path: str, method: str = "GET", path_parameters: dict | None = None, body: str | None = None):
+ """Build a minimal API Gateway REST (v1) proxy event."""
+ return {
+ "httpMethod": method,
+ "path": path,
+ "pathParameters": path_parameters,
+ "queryStringParameters": None,
+ "multiValueQueryStringParameters": None,
+ "headers": {"Content-Type": "application/json", "user-agent": "pytest"},
+ "multiValueHeaders": {},
+ "body": body,
+ "isBase64Encoded": False,
+ "requestContext": {"httpMethod": method, "resourcePath": path},
+ "resource": path,
+ "stageVariables": None,
+ }
+
+
+# ---------------------------------------------------------------------------
+# app.request in global middleware
+# ---------------------------------------------------------------------------
+
+
+def test_request_available_in_global_middleware():
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def capture_middleware(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[capture_middleware])
+
+ @app.get("/my/path")
+ def handler():
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ assert len(captured) == 1
+ req = captured[0]
+ assert isinstance(req, Request)
+ assert req.route == "/my/path"
+ assert req.method == "GET"
+
+
+def test_request_route_pattern_uses_openapi_format():
+ """route property should use {param} OpenAPI notation, not Powertools notation."""
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/applications/")
+ def handler(application_id: str):
+ return {}
+
+ event = _make_rest_event(
+ "/applications/42",
+ path_parameters={"application_id": "42"},
+ )
+ app(event, {})
+
+ assert captured[0].route == "/applications/{application_id}"
+
+
+def test_request_path_parameters_in_middleware():
+ app = APIGatewayRestResolver()
+ captured: list[dict] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ captured.append(app.request.path_parameters)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/applications/")
+ def handler(application_id: str):
+ return {}
+
+ event = _make_rest_event(
+ "/applications/4da715ee",
+ path_parameters={"application_id": "4da715ee"},
+ )
+ app(event, {})
+
+ assert captured == [{"application_id": "4da715ee"}]
+
+
+def test_request_method_in_middleware():
+ app = APIGatewayRestResolver()
+ methods_seen: list[str] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ methods_seen.append(app.request.method)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.put("/items/")
+ def handler(item_id: str):
+ return {}
+
+ event = _make_rest_event("/items/99", method="PUT", path_parameters={"item_id": "99"})
+ app(event, {})
+
+ assert methods_seen == ["PUT"]
+
+
+def test_request_headers_in_middleware():
+ app = APIGatewayRestResolver()
+ headers_seen: list[dict] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ headers_seen.append(app.request.headers)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler():
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ assert len(headers_seen) == 1
+ # headers is a dict (may have varying casing depending on event source)
+ assert isinstance(headers_seen[0], dict)
+
+
+def test_request_query_parameters_in_middleware():
+ app = APIGatewayRestResolver()
+ captured: list = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ captured.append(app.request.query_parameters)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/search")
+ def handler():
+ return {}
+
+ event = _make_rest_event("/search")
+ event["queryStringParameters"] = {"q": "powertools"}
+ app(event, {})
+
+ assert captured == [{"q": "powertools"}]
+
+
+def test_request_body_in_middleware():
+ app = APIGatewayRestResolver()
+ bodies_seen: list = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ bodies_seen.append(app.request.body)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.post("/items")
+ def handler():
+ return {}
+
+ event = _make_rest_event("/items", method="POST", body='{"name": "widget"}')
+ event["httpMethod"] = "POST"
+ app(event, {})
+
+ assert bodies_seen == ['{"name": "widget"}']
+
+
+# ---------------------------------------------------------------------------
+# Request injection in route handlers via type annotation
+# ---------------------------------------------------------------------------
+
+
+def test_request_injected_into_handler():
+ app = APIGatewayRestResolver()
+
+ received: list[Request] = []
+
+ @app.get("/my/path")
+ def handler(request: Request):
+ received.append(request)
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ assert len(received) == 1
+ assert isinstance(received[0], Request)
+ assert received[0].route == "/my/path"
+ assert received[0].method == "GET"
+
+
+def test_request_injected_alongside_path_params():
+ app = APIGatewayRestResolver()
+
+ received: list[tuple] = []
+
+ @app.get("/users/")
+ def handler(user_id: str, request: Request):
+ received.append((user_id, request))
+ return {}
+
+ event = _make_rest_event("/users/123", path_parameters={"user_id": "123"})
+ app(event, {})
+
+ assert len(received) == 1
+ user_id, req = received[0]
+ assert user_id == "123"
+ assert isinstance(req, Request)
+ assert req.path_parameters == {"user_id": "123"}
+ assert req.route == "/users/{user_id}"
+
+
+def test_request_injection_parameter_name_is_flexible():
+ """The parameter can be named anything as long as it is annotated as Request."""
+ app = APIGatewayRestResolver()
+
+ received: list[Request] = []
+
+ @app.get("/my/path")
+ def handler(req: Request):
+ received.append(req)
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ assert received[0].route == "/my/path"
+
+
+def test_handler_without_request_annotation_unaffected():
+ """Existing handlers with no Request annotation continue to work identically."""
+ app = APIGatewayRestResolver()
+
+ @app.get("/my/path")
+ def handler():
+ return {"ok": True}
+
+ result = app(API_REST_EVENT, {})
+ assert result["statusCode"] == 200
+
+
+def test_handler_with_path_params_only_unaffected():
+ """Handlers that only use path params continue to work identically."""
+ app = APIGatewayRestResolver()
+
+ @app.get("/users/")
+ def handler(user_id: str):
+ return {"id": user_id}
+
+ event = _make_rest_event("/users/42", path_parameters={"user_id": "42"})
+ result = app(event, {})
+ assert result["statusCode"] == 200
+
+
+# ---------------------------------------------------------------------------
+# Request injection caching (idempotency across multiple calls)
+# ---------------------------------------------------------------------------
+
+
+def test_request_injection_works_across_multiple_invocations():
+ """Injection must work correctly on repeated calls (cached param name must stay valid)."""
+ app = APIGatewayRestResolver()
+ call_count = 0
+
+ @app.get("/counters/")
+ def handler(counter_id: str, request: Request):
+ nonlocal call_count
+ call_count += 1
+ assert request.path_parameters["counter_id"] == counter_id
+ return {}
+
+ for i in range(3):
+ event = _make_rest_event(f"/counters/{i}", path_parameters={"counter_id": str(i)})
+ result = app(event, {})
+ assert result["statusCode"] == 200
+
+ assert call_count == 3
+
+
+# ---------------------------------------------------------------------------
+# RuntimeError when accessed outside of request resolution
+# ---------------------------------------------------------------------------
+
+
+def test_request_raises_before_resolution():
+ app = APIGatewayRestResolver()
+ with pytest.raises(RuntimeError, match="app.request is only available after route resolution"):
+ _ = app.request
+
+
+# ---------------------------------------------------------------------------
+# Route-level middleware also gets app.request
+# ---------------------------------------------------------------------------
+
+
+def test_request_available_in_route_level_middleware():
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def route_mw(app: APIGatewayRestResolver, next_middleware: NextMiddleware) -> Response:
+ captured.append(app.request)
+ return next_middleware(app)
+
+ @app.get("/protected/", middlewares=[route_mw])
+ def handler(resource_id: str):
+ return {}
+
+ event = _make_rest_event("/protected/abc", path_parameters={"resource_id": "abc"})
+ app(event, {})
+
+ assert len(captured) == 1
+ assert captured[0].route == "/protected/{resource_id}"
+ assert captured[0].path_parameters == {"resource_id": "abc"}
+
+
+# ---------------------------------------------------------------------------
+# Other resolver types
+# ---------------------------------------------------------------------------
+
+
+def test_request_available_in_http_resolver_middleware():
+ app = APIGatewayHttpResolver()
+ captured: list[Request] = []
+
+ def mw(app, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler():
+ return {}
+
+ app(API_RESTV2_EVENT, {})
+
+ assert len(captured) == 1
+ assert captured[0].method == "GET"
+
+
+def test_request_available_in_alb_middleware():
+ alb_event = load_event("albEvent.json")
+ app = ALBResolver()
+ captured: list[Request] = []
+
+ def mw(app, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ # Register a route that matches the ALB event's path
+ path = alb_event.get("path", "/lambda")
+
+ @app.get(path)
+ def handler():
+ return {}
+
+ app(alb_event, {})
+
+ assert len(captured) == 1
+ assert isinstance(captured[0], Request)
+
+
+# ---------------------------------------------------------------------------
+# Router / include_router pattern
+# ---------------------------------------------------------------------------
+
+
+def test_request_available_in_middleware_with_include_router():
+ """app.request must work in middleware when routes come from an included Router."""
+ from aws_lambda_powertools.event_handler.api_gateway import Router
+
+ app = APIGatewayRestResolver()
+ router = Router()
+ captured: list[Request] = []
+
+ def mw(app, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @router.get("/users/")
+ def get_user(user_id: str):
+ return {"id": user_id}
+
+ app.include_router(router)
+
+ event = _make_rest_event("/users/abc", path_parameters={"user_id": "abc"})
+ result = app(event, {})
+
+ assert result["statusCode"] == 200
+ assert len(captured) == 1
+ assert captured[0].route == "/users/{user_id}"
+ assert captured[0].path_parameters == {"user_id": "abc"}
+
+
+def test_request_injected_in_handler_with_include_router():
+ """Request injection via type annotation must work when routes come from an included Router."""
+ from aws_lambda_powertools.event_handler.api_gateway import Router
+
+ app = APIGatewayRestResolver()
+ router = Router()
+ received: list[Request] = []
+
+ @router.get("/items/")
+ def get_item(item_id: str, request: Request):
+ received.append(request)
+ return {"id": item_id}
+
+ app.include_router(router)
+
+ event = _make_rest_event("/items/xyz", path_parameters={"item_id": "xyz"})
+ result = app(event, {})
+
+ assert result["statusCode"] == 200
+ assert len(received) == 1
+ assert received[0].route == "/items/{item_id}"
+ assert received[0].path_parameters == {"item_id": "xyz"}
+
+
+# ---------------------------------------------------------------------------
+# Proxy+ use case (the original issue scenario)
+# ---------------------------------------------------------------------------
+
+
+def test_request_resolves_path_params_from_proxy_plus_event():
+ """When API GW uses {proxy+}, app.current_event.pathParameters only has 'proxy'.
+ But app.request.path_parameters should have the *resolved* params from Powertools routing."""
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def auth_middleware(app, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[auth_middleware])
+
+ @app.get("/applications/")
+ def get_application(application_id: str):
+ return {"id": application_id}
+
+ @app.put("/applications/")
+ def put_application(application_id: str):
+ return {"updated": application_id}
+
+ # Simulate a proxy+ event where API GW only knows about {proxy+}
+ event = {
+ "httpMethod": "PUT",
+ "path": "/applications/4da715ee-79d4-4e52-81cb-1ecc464708fb",
+ "pathParameters": {"proxy": "4da715ee-79d4-4e52-81cb-1ecc464708fb"},
+ "queryStringParameters": None,
+ "multiValueQueryStringParameters": None,
+ "headers": {"Content-Type": "application/json"},
+ "multiValueHeaders": {},
+ "body": None,
+ "isBase64Encoded": False,
+ "requestContext": {"httpMethod": "PUT", "resourcePath": "/applications/{proxy+}"},
+ "resource": "/applications/{proxy+}",
+ "stageVariables": None,
+ }
+
+ result = app(event, {})
+
+ assert result["statusCode"] == 200
+ assert len(captured) == 1
+
+ req = captured[0]
+ # Middleware sees the resolved route, NOT the proxy+ pattern
+ assert req.route == "/applications/{application_id}"
+ assert req.path_parameters == {"application_id": "4da715ee-79d4-4e52-81cb-1ecc464708fb"}
+ assert req.method == "PUT"
+
+
+# ---------------------------------------------------------------------------
+# Missing coverage: json_body, query_parameters=None, request caching
+# ---------------------------------------------------------------------------
+
+
+def test_request_json_body_in_middleware():
+ app = APIGatewayRestResolver()
+ bodies_seen: list = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ bodies_seen.append(app.request.json_body)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.post("/items")
+ def handler():
+ return {}
+
+ event = _make_rest_event("/items", method="POST", body='{"name": "widget"}')
+ app(event, {})
+
+ assert bodies_seen == [{"name": "widget"}]
+
+
+def test_request_query_parameters_empty():
+ """When no query string parameters are present, query_parameters returns empty or None."""
+ app = APIGatewayRestResolver()
+ captured: list = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ captured.append(app.request.query_parameters)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler():
+ return {}
+
+ event = _make_rest_event("/my/path")
+ app(event, {})
+
+ # No query params present — should be falsy (empty dict or None depending on event source)
+ assert not captured[0]
+
+
+def test_request_is_cached_across_multiple_accesses():
+ """Accessing app.request multiple times in the same invocation returns the same object."""
+ app = APIGatewayRestResolver()
+ ids_seen: list[int] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ ids_seen.append(id(app.request))
+ ids_seen.append(id(app.request))
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler(request: Request):
+ ids_seen.append(id(request))
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ # All accesses should return the same cached instance
+ assert len(ids_seen) == 3
+ assert ids_seen[0] == ids_seen[1] == ids_seen[2]
+
+
+# ---------------------------------------------------------------------------
+# resolved_event — full Powertools proxy event access
+# ---------------------------------------------------------------------------
+
+
+def test_request_resolved_event_exposes_full_event():
+ """resolved_event should return the full BaseProxyEvent with all helpers."""
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler():
+ return {}
+
+ app(API_REST_EVENT, {})
+
+ req = captured[0]
+ resolved = req.resolved_event
+
+ # resolved_event should be the same object as app.current_event
+ assert resolved is not None
+ assert resolved.http_method == "GET"
+ # Should have helper methods not available on Request directly
+ assert hasattr(resolved, "get_header_value")
+ assert hasattr(resolved, "get_query_string_value")
+
+
+def test_request_resolved_event_provides_cookies_and_path():
+ """resolved_event gives access to path and properties not on Request."""
+ app = APIGatewayRestResolver()
+ captured: list[Request] = []
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ captured.append(app.request)
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/items/")
+ def handler(item_id: str):
+ return {}
+
+ event = _make_rest_event("/items/42", path_parameters={"item_id": "42"})
+ app(event, {})
+
+ resolved = captured[0].resolved_event
+ assert resolved.path == "/items/42"
+
+
+# ---------------------------------------------------------------------------
+# context — shared resolver context (app.context)
+# ---------------------------------------------------------------------------
+
+
+def test_request_context_shares_app_context():
+ """request.context should be the same dict as app.context."""
+ app = APIGatewayRestResolver()
+
+ def mw(app: APIGatewayRestResolver, next_middleware):
+ app.append_context(user="test-user")
+ return next_middleware(app)
+
+ app.use(middlewares=[mw])
+
+ @app.get("/my/path")
+ def handler(request: Request):
+ return {"user": request.context.get("user")}
+
+ result = app(API_REST_EVENT, {})
+ assert result["statusCode"] == 200
+ import json
+
+ assert json.loads(result["body"]) == {"user": "test-user"}
diff --git a/tests/functional/event_handler/required_dependencies/test_resolve_async.py b/tests/functional/event_handler/required_dependencies/test_resolve_async.py
new file mode 100644
index 00000000000..e9b12ce2a2d
--- /dev/null
+++ b/tests/functional/event_handler/required_dependencies/test_resolve_async.py
@@ -0,0 +1,565 @@
+import asyncio
+import json
+
+import pytest
+
+from aws_lambda_powertools.event_handler import content_types
+from aws_lambda_powertools.event_handler.api_gateway import (
+ ALBResolver,
+ APIGatewayHttpResolver,
+ ApiGatewayResolver,
+ APIGatewayRestResolver,
+ BaseRouter,
+ CORSConfig,
+ ProxyEventType,
+ Response,
+)
+from aws_lambda_powertools.event_handler.middlewares import NextMiddleware
+from tests.functional.utils import load_event
+
+API_REST_EVENT = load_event("apiGatewayProxyEvent.json")
+API_RESTV2_EVENT = load_event("apiGatewayProxyV2Event_GET.json")
+ALB_EVENT = load_event("albEvent.json")
+
+
+def _setup_app(app, event):
+ BaseRouter.current_event = app._to_proxy_event(event)
+ BaseRouter.lambda_context = {}
+
+
+RESOLVER_IDS = ["ApiGatewayResolver", "APIGatewayRestResolver", "APIGatewayHttpResolver", "ALBResolver"]
+
+
+@pytest.fixture(
+ params=[
+ ("apigw_v1", API_REST_EVENT, "/my/path"),
+ ("apigw_rest", API_REST_EVENT, "/my/path"),
+ ("apigw_v2", API_RESTV2_EVENT, "/my/path"),
+ ("alb", ALB_EVENT, "/lambda"),
+ ],
+ ids=RESOLVER_IDS,
+)
+def resolver_and_event(request):
+ key, event, path = request.param
+ resolvers = {
+ "apigw_v1": ApiGatewayResolver(proxy_type=ProxyEventType.APIGatewayProxyEvent),
+ "apigw_rest": APIGatewayRestResolver(),
+ "apigw_v2": APIGatewayHttpResolver(),
+ "alb": ALBResolver(),
+ }
+ return resolvers[key], event, path
+
+
+class TestResolveAsyncWithAsyncHandlers:
+ def test_async_handler_through_resolve_chain(self, resolver_and_event):
+ # GIVEN an async handler registered on the resolver
+ app, event, path = resolver_and_event
+
+ @app.get(path)
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "async works")
+
+ # WHEN calling _resolve_async after setting up context
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the async handler is awaited and returns a ResponseBuilder
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert response["body"] == "async works"
+
+ def test_async_handler_returning_dict(self, resolver_and_event):
+ # GIVEN an async handler that returns a dict
+ app, event, path = resolver_and_event
+
+ @app.get(path)
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return {"message": "hello"}
+
+ # WHEN calling _resolve_async
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the dict is normalized into a Response
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+
+ def test_async_handler_returning_tuple(self, resolver_and_event):
+ # GIVEN an async handler that returns a (dict, status_code) tuple
+ app, event, path = resolver_and_event
+
+ @app.get(path)
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return {"created": True}, 201
+
+ # WHEN calling _resolve_async
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the tuple is normalized with the correct status code
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 201
+
+
+class TestResolveAsyncWithSyncHandlers:
+ def test_sync_handler_works_through_async_chain(self, resolver_and_event):
+ # GIVEN a sync handler
+ app, event, path = resolver_and_event
+
+ @app.get(path)
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "sync via async")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the sync handler works through the async chain
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert response["body"] == "sync via async"
+
+
+class TestResolveAsyncRouteArguments:
+ def test_route_args_passed_to_async_handler(self):
+ # GIVEN an async handler with a path parameter
+ app = APIGatewayHttpResolver()
+
+ @app.get("/my/")
+ async def get_lambda(name: str):
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, name)
+
+ # WHEN resolving a matching event
+ event = load_event("apiGatewayProxyV2Event_GET.json")
+ event["rawPath"] = "/my/powertools"
+ event["requestContext"]["http"]["path"] = "/my/powertools"
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN route arguments are passed to the handler
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert response["body"] == "powertools"
+
+
+class TestResolveAsyncNotFound:
+ def test_not_found_returns_404(self, resolver_and_event):
+ # GIVEN no matching route
+ app, event, _path = resolver_and_event
+
+ @app.get("/other/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "should not reach")
+
+ # WHEN resolving an event with a non-matching path
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN a 404 response is returned
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 404
+
+ def test_custom_not_found_handler(self):
+ # GIVEN a custom not_found handler
+ app = APIGatewayRestResolver()
+
+ @app.not_found
+ def custom_not_found(exc):
+ return Response(404, content_types.APPLICATION_JSON, '{"error": "custom 404"}')
+
+ @app.get("/other")
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "not reached")
+
+ # WHEN resolving with no matching route
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the custom handler is called
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 404
+ assert response["body"] == '{"error": "custom 404"}'
+
+ def test_cors_preflight_returns_204(self):
+ # GIVEN a resolver with CORS enabled
+ app = APIGatewayRestResolver(cors=CORSConfig())
+
+ @app.get("/my/path")
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "ok")
+
+ # WHEN an OPTIONS request arrives for a non-matching path
+ event = load_event("apiGatewayProxyEvent.json")
+ event["httpMethod"] = "OPTIONS"
+ _setup_app(app, event)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN a 204 pre-flight response is returned
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 204
+
+
+class TestResolveAsyncExceptionHandling:
+ def test_exception_handler_catches_async_error(self):
+ # GIVEN an async handler that raises and an exception handler
+ app = APIGatewayRestResolver()
+
+ @app.exception_handler(ValueError)
+ def handle_value_error(exc):
+ return Response(422, content_types.APPLICATION_JSON, '{"error": "validation failed"}')
+
+ @app.get("/my/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ raise ValueError("bad input")
+
+ # WHEN resolving
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the exception handler catches the error
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 422
+
+
+class TestResolveAsyncMiddleware:
+ def test_sync_middleware_in_async_chain(self):
+ # GIVEN a sync middleware
+ app = APIGatewayRestResolver()
+
+ def my_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ app.append_context(sync_mw_called=True)
+ return next_middleware(app)
+
+ @app.get("/my/path", middlewares=[my_middleware])
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "with middleware")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the sync middleware runs in the async chain
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert response["body"] == "with middleware"
+ assert app.context.get("sync_mw_called") is True
+
+ def test_async_middleware_in_async_chain(self):
+ # GIVEN an async middleware
+ app = APIGatewayRestResolver()
+
+ async def my_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ app.append_context(async_mw_called=True)
+ return await next_middleware(app)
+
+ @app.get("/my/path", middlewares=[my_middleware])
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "async mw")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the async middleware runs correctly
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 200
+ assert app.context.get("async_mw_called") is True
+
+ def test_not_found_goes_through_middleware(self):
+ # GIVEN a global middleware
+ middleware_called = []
+
+ def tracking_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ middleware_called.append(True)
+ return next_middleware(app)
+
+ app = APIGatewayRestResolver()
+ app.use([tracking_middleware])
+
+ @app.get("/other/path")
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "not reached")
+
+ # WHEN resolving with a non-matching path
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN the middleware still runs (404 goes through chain)
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 404
+ assert len(middleware_called) > 0
+
+
+class TestResolveAsyncProcessedStack:
+ def test_processed_stack_frames_recorded(self):
+ # GIVEN an async handler
+ app = APIGatewayRestResolver()
+
+ @app.get("/my/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "ok")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+ asyncio.run(app._resolve_async())
+
+ # THEN the processed stack frames are populated
+ assert len(app.processed_stack_frames) > 0
+ assert any("_registered_api_adapter_async" in frame for frame in app.processed_stack_frames)
+
+
+class TestResolveAsyncDebugMode:
+ def test_debug_mode_prints_middleware_stack(self, capsys):
+ # GIVEN a resolver with debug=True
+ app = APIGatewayRestResolver(debug=True)
+
+ @app.get("/my/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "debug")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+ asyncio.run(app._resolve_async())
+
+ # THEN the async middleware stack is printed
+ captured = capsys.readouterr()
+ assert "Async Middleware Stack:" in captured.out
+ assert "_registered_api_adapter_async" in captured.out
+
+
+class TestResolveAsyncExceptionNoHandler:
+ def test_unhandled_exception_reraises(self):
+ # GIVEN an async handler that raises with no matching exception handler
+ app = APIGatewayRestResolver()
+
+ @app.get("/my/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ raise RuntimeError("unhandled")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+
+ # THEN the exception propagates
+ with pytest.raises(RuntimeError, match="unhandled"):
+ asyncio.run(app._resolve_async())
+
+ def test_unhandled_exception_with_debug_returns_traceback(self):
+ # GIVEN a resolver with debug=True and no exception handler
+ app = APIGatewayRestResolver(debug=True)
+
+ @app.get("/my/path")
+ async def get_lambda():
+ await asyncio.sleep(0)
+ raise RuntimeError("debug error")
+
+ # WHEN calling _resolve_async
+ _setup_app(app, API_REST_EVENT)
+ result = asyncio.run(app._resolve_async())
+
+ # THEN a 500 response with traceback is returned
+ response = result.build(app.current_event, app._cors)
+ assert response["statusCode"] == 500
+ assert "debug error" in response["body"]
+
+
+# ============================================================================
+# Public resolve_async() tests
+# ============================================================================
+
+
+class MockLambdaContext:
+ function_name = "test-func"
+ memory_limit_in_mb = 128
+ invoked_function_arn = "arn:aws:lambda:eu-west-1:123456789012:function:test-func"
+ aws_request_id = "52fdfc07-2182-154f-163f-5f0f9a621d72"
+
+ def get_remaining_time_in_millis(self) -> int:
+ return 1000
+
+
+RESOLVE_ASYNC_IDS = ["APIGatewayRestResolver", "APIGatewayHttpResolver", "ALBResolver"]
+
+
+@pytest.fixture(
+ params=[
+ ("apigw_rest", API_REST_EVENT, "/my/path"),
+ ("apigw_v2", API_RESTV2_EVENT, "/my/path"),
+ ("alb", ALB_EVENT, "/lambda"),
+ ],
+ ids=RESOLVE_ASYNC_IDS,
+)
+def public_resolver_and_event(request):
+ key, event, path = request.param
+ resolvers = {
+ "apigw_rest": APIGatewayRestResolver(),
+ "apigw_v2": APIGatewayHttpResolver(),
+ "alb": ALBResolver(),
+ }
+ return resolvers[key], event, path
+
+
+class TestResolveAsyncPublic:
+ def test_resolve_async_returns_dict_response(self, public_resolver_and_event):
+ # GIVEN an async handler
+ app, event, path = public_resolver_and_event
+
+ @app.get(path)
+ async def get_lambda():
+ await asyncio.sleep(0)
+ return Response(200, content_types.TEXT_HTML, "async public")
+
+ # WHEN calling resolve_async with event and context
+ response = asyncio.run(app.resolve_async(event, MockLambdaContext()))
+
+ # THEN a dict response is returned directly (no need to call .build())
+ assert response["statusCode"] == 200
+ assert response["body"] == "async public"
+
+ def test_resolve_async_with_sync_handler(self, public_resolver_and_event):
+ # GIVEN a sync handler
+ app, event, path = public_resolver_and_event
+
+ @app.get(path)
+ def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "sync via public async")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(event, MockLambdaContext()))
+
+ # THEN sync handlers work through the async chain
+ assert response["statusCode"] == 200
+ assert response["body"] == "sync via public async"
+
+ def test_resolve_async_clears_context(self, public_resolver_and_event):
+ # GIVEN an async handler
+ app, event, path = public_resolver_and_event
+
+ @app.get(path)
+ async def get_lambda():
+ app.append_context(custom_key="value")
+ return Response(200, content_types.TEXT_HTML, "ok")
+
+ # WHEN calling resolve_async
+ asyncio.run(app.resolve_async(event, MockLambdaContext()))
+
+ # THEN the context is cleared after resolution
+ assert app.context == {}
+
+ def test_resolve_async_not_found(self, public_resolver_and_event):
+ # GIVEN no matching route
+ app, event, _path = public_resolver_and_event
+
+ @app.get("/non/existent/path")
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "unreachable")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(event, MockLambdaContext()))
+
+ # THEN a 404 response is returned
+ assert response["statusCode"] == 404
+
+ def test_resolve_async_with_cors(self):
+ # GIVEN a resolver with CORS and an async handler
+ app = APIGatewayRestResolver(cors=CORSConfig())
+
+ @app.get("/my/path")
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "cors")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(API_REST_EVENT, MockLambdaContext()))
+
+ # THEN CORS headers are included
+ assert response["statusCode"] == 200
+ assert "Access-Control-Allow-Origin" in response.get("multiValueHeaders", response.get("headers", {}))
+
+ def test_resolve_async_with_middleware(self):
+ # GIVEN a resolver with a middleware
+ app = APIGatewayRestResolver()
+ middleware_order = []
+
+ def tracking_middleware(app: ApiGatewayResolver, next_middleware: NextMiddleware):
+ middleware_order.append("before")
+ result = next_middleware(app)
+ middleware_order.append("after")
+ return result
+
+ @app.get("/my/path", middlewares=[tracking_middleware])
+ async def get_lambda():
+ middleware_order.append("handler")
+ return Response(200, content_types.TEXT_HTML, "ok")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(API_REST_EVENT, MockLambdaContext()))
+
+ # THEN middleware runs in correct order around the handler
+ assert response["statusCode"] == 200
+ assert middleware_order == ["before", "handler", "after"]
+
+ def test_resolve_async_exception_handler(self):
+ # GIVEN an async handler that raises with an exception handler registered
+ app = APIGatewayRestResolver()
+
+ @app.exception_handler(ValueError)
+ def handle_value_error(exc):
+ return Response(422, content_types.APPLICATION_JSON, json.dumps({"error": str(exc)}))
+
+ @app.get("/my/path")
+ async def get_lambda():
+ raise ValueError("invalid input")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(API_REST_EVENT, MockLambdaContext()))
+
+ # THEN the exception handler catches the error
+ assert response["statusCode"] == 422
+ assert "invalid input" in response["body"]
+
+ def test_resolve_async_debug_mode(self, capsys):
+ # GIVEN a resolver with debug=True
+ app = APIGatewayRestResolver(debug=True)
+
+ @app.get("/my/path")
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "debug")
+
+ # WHEN calling resolve_async
+ response = asyncio.run(app.resolve_async(API_REST_EVENT, MockLambdaContext()))
+
+ # THEN debug output includes raw event and middleware stack
+ captured = capsys.readouterr()
+ assert response["statusCode"] == 200
+ assert "Processed Middlewares:" in captured.out
+ assert "httpMethod" in captured.out
+
+ def test_resolve_async_with_base_proxy_event(self):
+ # GIVEN a resolver and a BaseProxyEvent passed directly
+ from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent
+
+ app = APIGatewayRestResolver()
+
+ @app.get("/my/path")
+ async def get_lambda():
+ return Response(200, content_types.TEXT_HTML, "from proxy event")
+
+ # WHEN calling resolve_async with a data class instead of raw dict
+ proxy_event = APIGatewayProxyEvent(API_REST_EVENT)
+
+ with pytest.warns(UserWarning, match="You don't need to serialize event"):
+ response = asyncio.run(app.resolve_async(proxy_event, MockLambdaContext()))
+
+ # THEN it still works after extracting raw_event
+ assert response["statusCode"] == 200
+ assert response["body"] == "from proxy event"
diff --git a/tests/functional/idempotency/_pydantic/test_idempotency_pydantic_json_serialization.py b/tests/functional/idempotency/_pydantic/test_idempotency_pydantic_json_serialization.py
new file mode 100644
index 00000000000..624e4239e98
--- /dev/null
+++ b/tests/functional/idempotency/_pydantic/test_idempotency_pydantic_json_serialization.py
@@ -0,0 +1,185 @@
+"""
+Test for issue #8065: @idempotent_function fails with non-JSON-serializable types in Pydantic models
+
+Bug: _prepare_data() calls model_dump() without mode="json", which doesn't
+serialize UUIDs, dates, datetimes, Decimals, and Paths to JSON-compatible strings.
+"""
+
+from datetime import date, datetime
+from decimal import Decimal
+from pathlib import PurePosixPath
+from uuid import UUID
+
+from pydantic import BaseModel
+
+from aws_lambda_powertools.utilities.idempotency import (
+ IdempotencyConfig,
+ idempotent_function,
+)
+from aws_lambda_powertools.utilities.idempotency.persistence.base import (
+ BasePersistenceLayer,
+ DataRecord,
+)
+from tests.functional.idempotency.utils import hash_idempotency_key
+
+TESTS_MODULE_PREFIX = "test-func.tests.functional.idempotency._pydantic.test_idempotency_pydantic_json_serialization"
+
+
+class MockPersistenceLayer(BasePersistenceLayer):
+ def __init__(self, expected_idempotency_key: str):
+ self.expected_idempotency_key = expected_idempotency_key
+ super().__init__()
+
+ def _put_record(self, data_record: DataRecord) -> None:
+ assert data_record.idempotency_key == self.expected_idempotency_key
+
+ def _update_record(self, data_record: DataRecord) -> None:
+ assert data_record.idempotency_key == self.expected_idempotency_key
+
+ def _get_record(self, idempotency_key) -> DataRecord: ...
+
+ def _delete_record(self, data_record: DataRecord) -> None: ...
+
+
+# --- Models ---
+
+
+class PaymentWithUUID(BaseModel):
+ payment_id: UUID
+ customer_id: str
+
+
+class EventWithDate(BaseModel):
+ event_id: str
+ event_date: date
+
+
+class OrderWithDatetime(BaseModel):
+ order_id: str
+ created_at: datetime
+
+
+class InvoiceWithDecimal(BaseModel):
+ invoice_id: str
+ amount: Decimal
+
+
+class ConfigWithPath(BaseModel):
+ config_id: str
+ file_path: PurePosixPath
+
+
+def test_idempotent_function_with_uuid():
+ # GIVEN
+ config = IdempotencyConfig(use_local_cache=True)
+ payment_uuid = UUID("12345678-1234-5678-1234-567812345678")
+ mock_event = {"payment_id": str(payment_uuid), "customer_id": "c-456"}
+ idempotency_key = f"{TESTS_MODULE_PREFIX}.test_idempotent_function_with_uuid..collect_payment#{hash_idempotency_key(mock_event)}" # noqa E501
+ persistence_layer = MockPersistenceLayer(expected_idempotency_key=idempotency_key)
+
+ @idempotent_function(
+ data_keyword_argument="payment",
+ persistence_store=persistence_layer,
+ config=config,
+ )
+ def collect_payment(payment: PaymentWithUUID) -> dict:
+ return {"status": "ok"}
+
+ # WHEN
+ payment = PaymentWithUUID(payment_id=payment_uuid, customer_id="c-456")
+ result = collect_payment(payment=payment)
+
+ # THEN
+ assert result == {"status": "ok"}
+
+
+def test_idempotent_function_with_date():
+ # GIVEN
+ config = IdempotencyConfig(use_local_cache=True)
+ mock_event = {"event_id": "evt-001", "event_date": "2024-03-20"}
+ idempotency_key = f"{TESTS_MODULE_PREFIX}.test_idempotent_function_with_date..process_event#{hash_idempotency_key(mock_event)}" # noqa E501
+ persistence_layer = MockPersistenceLayer(expected_idempotency_key=idempotency_key)
+
+ @idempotent_function(
+ data_keyword_argument="event",
+ persistence_store=persistence_layer,
+ config=config,
+ )
+ def process_event(event: EventWithDate) -> dict:
+ return {"status": "ok"}
+
+ # WHEN
+ event = EventWithDate(event_id="evt-001", event_date=date(2024, 3, 20))
+ result = process_event(event=event)
+
+ # THEN
+ assert result == {"status": "ok"}
+
+
+def test_idempotent_function_with_datetime():
+ # GIVEN
+ config = IdempotencyConfig(use_local_cache=True)
+ mock_event = {"order_id": "ord-001", "created_at": "2024-03-20T14:30:00"}
+ idempotency_key = f"{TESTS_MODULE_PREFIX}.test_idempotent_function_with_datetime..process_order#{hash_idempotency_key(mock_event)}" # noqa E501
+ persistence_layer = MockPersistenceLayer(expected_idempotency_key=idempotency_key)
+
+ @idempotent_function(
+ data_keyword_argument="order",
+ persistence_store=persistence_layer,
+ config=config,
+ )
+ def process_order(order: OrderWithDatetime) -> dict:
+ return {"status": "ok"}
+
+ # WHEN
+ order = OrderWithDatetime(order_id="ord-001", created_at=datetime(2024, 3, 20, 14, 30, 0))
+ result = process_order(order=order)
+
+ # THEN
+ assert result == {"status": "ok"}
+
+
+def test_idempotent_function_with_decimal():
+ # GIVEN
+ config = IdempotencyConfig(use_local_cache=True)
+ mock_event = {"invoice_id": "inv-001", "amount": "199.99"}
+ idempotency_key = f"{TESTS_MODULE_PREFIX}.test_idempotent_function_with_decimal..process_invoice#{hash_idempotency_key(mock_event)}" # noqa E501
+ persistence_layer = MockPersistenceLayer(expected_idempotency_key=idempotency_key)
+
+ @idempotent_function(
+ data_keyword_argument="invoice",
+ persistence_store=persistence_layer,
+ config=config,
+ )
+ def process_invoice(invoice: InvoiceWithDecimal) -> dict:
+ return {"status": "ok"}
+
+ # WHEN
+ invoice = InvoiceWithDecimal(invoice_id="inv-001", amount=Decimal("199.99"))
+ result = process_invoice(invoice=invoice)
+
+ # THEN
+ assert result == {"status": "ok"}
+
+
+def test_idempotent_function_with_path():
+ # GIVEN
+ config = IdempotencyConfig(use_local_cache=True)
+ mock_event = {"config_id": "cfg-001", "file_path": "/etc/app/config.yaml"}
+ idempotency_key = f"{TESTS_MODULE_PREFIX}.test_idempotent_function_with_path..process_config#{hash_idempotency_key(mock_event)}" # noqa E501
+ persistence_layer = MockPersistenceLayer(expected_idempotency_key=idempotency_key)
+
+ @idempotent_function(
+ data_keyword_argument="config",
+ persistence_store=persistence_layer,
+ config=config,
+ )
+ def process_config(config: ConfigWithPath) -> dict:
+ return {"status": "ok"}
+
+ # WHEN
+ cfg = ConfigWithPath(config_id="cfg-001", file_path=PurePosixPath("/etc/app/config.yaml"))
+ result = process_config(config=cfg)
+
+ # THEN
+ assert result == {"status": "ok"}
diff --git a/tests/functional/idempotency/_redis/test_redis_layer.py b/tests/functional/idempotency/_redis/test_redis_layer.py
index c2a0976b0ab..22c3b9a6d83 100644
--- a/tests/functional/idempotency/_redis/test_redis_layer.py
+++ b/tests/functional/idempotency/_redis/test_redis_layer.py
@@ -330,6 +330,25 @@ def test_item_to_datarecord_conversion(valid_record):
assert record.in_progress_expiry_timestamp == item[layer.in_progress_expiry_attr]
+def test_item_to_datarecord_conversion_missing_optional_attributes(persistence_store_standalone_redis):
+ """
+ When data_attr or validation_key_attr is missing from Redis,
+ response_data and payload_hash should be empty string, not the string "None".
+ Regression test for: https://github.com/aws-powertools/powertools-lambda-python/issues/8090
+ """
+ idempotency_key = "test-func#abc123"
+ item = {
+ persistence_store_standalone_redis.status_attr: "COMPLETED",
+ persistence_store_standalone_redis.expiry_attr: 9999999999,
+ # data_attr and validation_key_attr intentionally absent
+ }
+
+ record = persistence_store_standalone_redis._item_to_data_record(idempotency_key, item)
+
+ assert record.response_data == ""
+ assert record.payload_hash == ""
+
+
def test_idempotent_function_and_lambda_handler_redis_basic(
persistence_store_standalone_redis: RedisCachePersistenceLayer,
lambda_context,
diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/requirements.txt b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/requirements.txt
index 1c37b95e202..397c11ba436 100644
--- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/requirements.txt
+++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/requirements.txt
@@ -1,3 +1,3 @@
requests>=2.32.0
aws-lambda-powertools[tracer]
-aws-encryption-sdk>=3.1.1
+aws-encryption-sdk>=3.3.1,!=4.0.0,!=4.0.1,!=4.0.2,!=4.0.3,!=4.0.4
diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/requirements.txt b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/requirements.txt
index 1c37b95e202..397c11ba436 100644
--- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/requirements.txt
+++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/requirements.txt
@@ -1,3 +1,3 @@
requests>=2.32.0
aws-lambda-powertools[tracer]
-aws-encryption-sdk>=3.1.1
+aws-encryption-sdk>=3.3.1,!=4.0.0,!=4.0.1,!=4.0.2,!=4.0.3,!=4.0.4
diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/requirements.txt b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/requirements.txt
index 1c37b95e202..397c11ba436 100644
--- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/requirements.txt
+++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/requirements.txt
@@ -1,3 +1,3 @@
requests>=2.32.0
aws-lambda-powertools[tracer]
-aws-encryption-sdk>=3.1.1
+aws-encryption-sdk>=3.3.1,!=4.0.0,!=4.0.1,!=4.0.2,!=4.0.3,!=4.0.4
diff --git a/tests/unit/data_classes/required_dependencies/test_alb_event.py b/tests/unit/data_classes/required_dependencies/test_alb_event.py
index 13d8b5907be..23ab7af6365 100644
--- a/tests/unit/data_classes/required_dependencies/test_alb_event.py
+++ b/tests/unit/data_classes/required_dependencies/test_alb_event.py
@@ -52,3 +52,17 @@ def test_alb_event_decode_multi_value_query_parameters():
# With decode_query_parameters, the key and value are not decoded
parsed_event.decode_query_parameters = True
assert parsed_event.resolved_query_string_parameters == {expected_key: expected_values}
+
+
+def test_alb_event_merged_query_string_parameters():
+ """When both multiValueQueryStringParameters and queryStringParameters are present,
+ resolved_query_string_parameters should merge them (GH #7993)."""
+ raw_event = load_event("albMultiValueQueryStringEvent.json")
+ raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2", "3"]}
+ raw_event["queryStringParameters"] = {"status": "fizzbuzz"}
+
+ parsed_event = ALBEvent(raw_event)
+ resolved = parsed_event.resolved_query_string_parameters
+
+ assert resolved["ids"] == ["1", "2", "3"]
+ assert resolved["status"] == ["fizzbuzz"]
diff --git a/tests/unit/data_classes/required_dependencies/test_api_gateway_authorizer.py b/tests/unit/data_classes/required_dependencies/test_api_gateway_authorizer.py
index 1fad5176672..c26c1a417e7 100644
--- a/tests/unit/data_classes/required_dependencies/test_api_gateway_authorizer.py
+++ b/tests/unit/data_classes/required_dependencies/test_api_gateway_authorizer.py
@@ -200,6 +200,40 @@ def test_authorizer_response_allow_route_with_underscore(builder: APIGatewayAuth
}
+def test_authorizer_response_allow_route_with_proxy_plus(builder: APIGatewayAuthorizerResponse):
+ builder.allow_route(http_method="GET", resource="/{proxy+}")
+ assert builder.asdict() == {
+ "principalId": "foo",
+ "policyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": "execute-api:Invoke",
+ "Effect": "Allow",
+ "Resource": ["arn:aws:execute-api:us-west-1:123456789:fantom/dev/GET/{proxy+}"],
+ },
+ ],
+ },
+ }
+
+
+def test_authorizer_response_allow_route_with_path_parameter(builder: APIGatewayAuthorizerResponse):
+ builder.allow_route(http_method="GET", resource="/users/{user_id}")
+ assert builder.asdict() == {
+ "principalId": "foo",
+ "policyDocument": {
+ "Version": "2012-10-17",
+ "Statement": [
+ {
+ "Action": "execute-api:Invoke",
+ "Effect": "Allow",
+ "Resource": ["arn:aws:execute-api:us-west-1:123456789:fantom/dev/GET/users/{user_id}"],
+ },
+ ],
+ },
+ }
+
+
def test_parse_api_gateway_arn_with_resource():
mock_event = {
"type": "TOKEN",
diff --git a/tests/unit/data_classes/required_dependencies/test_api_gateway_proxy_event.py b/tests/unit/data_classes/required_dependencies/test_api_gateway_proxy_event.py
index ec71d815a7c..fd9ca1cca76 100644
--- a/tests/unit/data_classes/required_dependencies/test_api_gateway_proxy_event.py
+++ b/tests/unit/data_classes/required_dependencies/test_api_gateway_proxy_event.py
@@ -241,3 +241,53 @@ def test_api_gateway_proxy_v2_iam_event():
assert iam.principal_org_id == iam_raw["principalOrgId"]
assert iam.user_arn == iam_raw["userArn"]
assert iam.user_id == iam_raw["userId"]
+
+
+def test_api_gateway_proxy_event_merged_query_string_parameters():
+ """When both multiValueQueryStringParameters and queryStringParameters are present,
+ resolved_query_string_parameters should merge them (GH #7993)."""
+ raw_event = load_event("apiGatewayProxyEvent.json")
+ raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2", "3"]}
+ raw_event["queryStringParameters"] = {"status": "fizzbuzz"}
+
+ parsed_event = APIGatewayProxyEvent(raw_event)
+ resolved = parsed_event.resolved_query_string_parameters
+
+ assert resolved["ids"] == ["1", "2", "3"]
+ assert resolved["status"] == ["fizzbuzz"]
+
+
+def test_api_gateway_proxy_event_multi_value_takes_precedence():
+ """When the same key exists in both, multiValueQueryStringParameters wins."""
+ raw_event = load_event("apiGatewayProxyEvent.json")
+ raw_event["multiValueQueryStringParameters"] = {"key": ["a", "b"]}
+ raw_event["queryStringParameters"] = {"key": "c"}
+
+ parsed_event = APIGatewayProxyEvent(raw_event)
+ resolved = parsed_event.resolved_query_string_parameters
+
+ assert resolved["key"] == ["a", "b"]
+
+
+def test_api_gateway_proxy_event_only_single_value_query_params():
+ """When only queryStringParameters is present, it should still work."""
+ raw_event = load_event("apiGatewayProxyEvent.json")
+ raw_event["multiValueQueryStringParameters"] = None
+ raw_event["queryStringParameters"] = {"status": "active"}
+
+ parsed_event = APIGatewayProxyEvent(raw_event)
+ resolved = parsed_event.resolved_query_string_parameters
+
+ assert resolved["status"] == ["active"]
+
+
+def test_api_gateway_proxy_event_only_multi_value_query_params():
+ """When only multiValueQueryStringParameters is present, it should still work."""
+ raw_event = load_event("apiGatewayProxyEvent.json")
+ raw_event["multiValueQueryStringParameters"] = {"ids": ["1", "2"]}
+ raw_event["queryStringParameters"] = None
+
+ parsed_event = APIGatewayProxyEvent(raw_event)
+ resolved = parsed_event.resolved_query_string_parameters
+
+ assert resolved["ids"] == ["1", "2"]
diff --git a/tests/unit/event_handler/openapi/test_openapi_merge.py b/tests/unit/event_handler/openapi/test_openapi_merge.py
index 21500145b35..bce18b62dea 100644
--- a/tests/unit/event_handler/openapi/test_openapi_merge.py
+++ b/tests/unit/event_handler/openapi/test_openapi_merge.py
@@ -10,7 +10,7 @@
_discover_resolver_files,
_file_has_resolver,
_is_excluded,
- _load_resolver,
+ _load_resolver_with_dependencies,
)
MERGE_HANDLERS_PATH = Path(__file__).parents[3] / "functional/event_handler/_pydantic/merge_handlers"
@@ -71,7 +71,7 @@ def test_is_excluded_with_file_pattern():
def test_load_resolver_file_not_found():
with pytest.raises(FileNotFoundError):
- _load_resolver(Path("/non/existent/file.py"), "app")
+ _load_resolver_with_dependencies(Path("/non/existent/file.py"), "app", [], Path("/"))
def test_load_resolver_not_found_in_module(tmp_path: Path):
@@ -79,7 +79,7 @@ def test_load_resolver_not_found_in_module(tmp_path: Path):
handler_file.write_text("x = 1")
with pytest.raises(AttributeError, match="Resolver 'app' not found"):
- _load_resolver(handler_file, "app")
+ _load_resolver_with_dependencies(handler_file, "app", [], tmp_path)
def test_load_resolver_success(tmp_path: Path):
@@ -93,6 +93,6 @@ def test_endpoint():
return {"test": True}
""")
- resolver = _load_resolver(handler_file, "app")
+ resolver = _load_resolver_with_dependencies(handler_file, "app", [], tmp_path)
assert resolver is not None
assert hasattr(resolver, "get_openapi_schema")