From 1409499b49ac7ac5e9cd84248c75163d9e6c19a0 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Tue, 16 Jan 2024 17:35:59 +0100 Subject: [PATCH 0001/2666] feat(event_handler): add support for additional response models (#3591) * feat(event_handler): add support for additional response models * fix: I hate sonarcube * fix: pydantic 2 * fix: refactor * fix: increase coverage * chore: update docs --------- Co-authored-by: Leandro Damascena --- .../event_handler/api_gateway.py | 79 +++++++++++++--- .../event_handler/openapi/dependant.py | 34 ++++++- .../event_handler/openapi/params.py | 2 + .../event_handler/openapi/types.py | 15 +++ docs/core/event_handler/api_gateway.md | 18 ++-- .../event_handler/test_openapi_responses.py | 94 ++++++++++++++++++- 6 files changed, 215 insertions(+), 27 deletions(-) diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py index 7a41c99d053..9260ede43e9 100644 --- a/aws_lambda_powertools/event_handler/api_gateway.py +++ b/aws_lambda_powertools/event_handler/api_gateway.py @@ -37,6 +37,9 @@ from aws_lambda_powertools.event_handler.openapi.types import ( COMPONENT_REF_PREFIX, METHODS_WITH_BODY, + OpenAPIResponse, + OpenAPIResponseContentModel, + OpenAPIResponseContentSchema, validation_error_definition, validation_error_response_definition, ) @@ -273,7 +276,7 @@ def __init__( cache_control: Optional[str], summary: Optional[str], description: Optional[str], - responses: Optional[Dict[int, Dict[str, Any]]], + responses: Optional[Dict[int, OpenAPIResponse]], response_description: Optional[str], tags: Optional[List[str]], operation_id: Optional[str], @@ -303,7 +306,7 @@ def __init__( The OpenAPI summary for this route description: Optional[str] The OpenAPI description for this route - responses: Optional[Dict[int, Dict[str, Any]]] + responses: Optional[Dict[int, OpenAPIResponse]] The OpenAPI responses for this route response_description: Optional[str] The OpenAPI response description for this route @@ -442,7 +445,7 @@ def dependant(self) -> "Dependant": if self._dependant is None: from aws_lambda_powertools.event_handler.openapi.dependant import get_dependant - self._dependant = get_dependant(path=self.openapi_path, call=self.func) + self._dependant = get_dependant(path=self.openapi_path, call=self.func, responses=self.responses) return self._dependant @@ -501,11 +504,54 @@ def _get_openapi_path( # Add the response to the OpenAPI operation if self.responses: - # If the user supplied responses, we use them and don't set a default 200 response + for status_code in list(self.responses): + response = self.responses[status_code] + + # Case 1: there is not 'content' key + if "content" not in response: + response["content"] = { + "application/json": self._openapi_operation_return( + param=dependant.return_param, + model_name_map=model_name_map, + field_mapping=field_mapping, + ), + } + + # Case 2: there is a 'content' key + else: + # Need to iterate to transform any 'model' into a 'schema' + for content_type, payload in response["content"].items(): + new_payload: OpenAPIResponseContentSchema + + # Case 2.1: the 'content' has a model + if "model" in payload: + # Find the model in the dependant's extra models + return_field = next( + filter( + lambda model: model.type_ is cast(OpenAPIResponseContentModel, payload)["model"], + self.dependant.response_extra_models, + ), + ) + if not return_field: + raise AssertionError("Model declared in custom responses was not found") + + new_payload = self._openapi_operation_return( + param=return_field, + model_name_map=model_name_map, + field_mapping=field_mapping, + ) + + # Case 2.2: the 'content' has a schema + else: + # Do nothing! We already have what we need! + new_payload = payload + + response["content"][content_type] = new_payload + operation["responses"] = self.responses else: # Set the default 200 response - responses = operation.setdefault("responses", self.responses or {}) + responses = operation.setdefault("responses", {}) success_response = responses.setdefault(200, {}) success_response["description"] = self.response_description or _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION success_response["content"] = {"application/json": {"schema": {}}} @@ -682,7 +728,7 @@ def _openapi_operation_return( Tuple["ModelField", Literal["validation", "serialization"]], "JsonSchemaValue", ], - ) -> Dict[str, Any]: + ) -> OpenAPIResponseContentSchema: """ Returns the OpenAPI operation return. """ @@ -832,7 +878,7 @@ def route( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -890,7 +936,7 @@ def get( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -943,7 +989,7 @@ def post( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -997,7 +1043,7 @@ def put( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -1051,7 +1097,7 @@ def delete( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -1104,7 +1150,7 @@ def patch( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -1662,7 +1708,7 @@ def route( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -2110,6 +2156,9 @@ def _get_fields_from_routes(routes: Sequence[Route]) -> List["ModelField"]: if route.dependant.return_param: responses_from_routes.append(route.dependant.return_param) + if route.dependant.response_extra_models: + responses_from_routes.extend(route.dependant.response_extra_models) + flat_models = list(responses_from_routes + request_fields_from_routes + body_fields_from_routes) return flat_models @@ -2132,7 +2181,7 @@ def route( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: Optional[str] = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, @@ -2221,7 +2270,7 @@ def route( cache_control: Optional[str] = None, summary: Optional[str] = None, description: Optional[str] = None, - responses: Optional[Dict[int, Dict[str, Any]]] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, response_description: str = _DEFAULT_OPENAPI_RESPONSE_DESCRIPTION, tags: Optional[List[str]] = None, operation_id: Optional[str] = None, diff --git a/aws_lambda_powertools/event_handler/openapi/dependant.py b/aws_lambda_powertools/event_handler/openapi/dependant.py index e22eb535a7e..418a86e083c 100644 --- a/aws_lambda_powertools/event_handler/openapi/dependant.py +++ b/aws_lambda_powertools/event_handler/openapi/dependant.py @@ -24,6 +24,7 @@ create_response_field, get_flat_dependant, ) +from aws_lambda_powertools.event_handler.openapi.types import OpenAPIResponse, OpenAPIResponseContentModel """ This turns the opaque function signature into typed, validated models. @@ -145,6 +146,7 @@ def get_dependant( path: str, call: Callable[..., Any], name: Optional[str] = None, + responses: Optional[Dict[int, OpenAPIResponse]] = None, ) -> Dependant: """ Returns a dependant model for a handler function. A dependant model is a model that contains @@ -158,6 +160,8 @@ def get_dependant( The handler function name: str, optional The name of the handler function + responses: List[Dict[int, OpenAPIResponse]], optional + The list of extra responses for the handler function Returns ------- @@ -195,6 +199,34 @@ def get_dependant( else: add_param_to_fields(field=param_field, dependant=dependant) + _add_return_annotation(dependant, endpoint_signature) + _add_extra_responses(dependant, responses) + + return dependant + + +def _add_extra_responses(dependant: Dependant, responses: Optional[Dict[int, OpenAPIResponse]]): + # Also add the optional extra responses to the dependant model. + if not responses: + return + + for response in responses.values(): + for schema in response.get("content", {}).values(): + if "model" in schema: + response_field = analyze_param( + param_name="return", + annotation=cast(OpenAPIResponseContentModel, schema)["model"], + value=None, + is_path_param=False, + is_response_param=True, + ) + if response_field is None: + raise AssertionError("Response field is None for response model") + + dependant.response_extra_models.append(response_field) + + +def _add_return_annotation(dependant: Dependant, endpoint_signature: inspect.Signature): # If the return annotation is not empty, add it to the dependant model. return_annotation = endpoint_signature.return_annotation if return_annotation is not inspect.Signature.empty: @@ -210,8 +242,6 @@ def get_dependant( dependant.return_param = param_field - return dependant - def is_body_param(*, param_field: ModelField, is_path_param: bool) -> bool: """ diff --git a/aws_lambda_powertools/event_handler/openapi/params.py b/aws_lambda_powertools/event_handler/openapi/params.py index bd542ba7932..78426cbc7c9 100644 --- a/aws_lambda_powertools/event_handler/openapi/params.py +++ b/aws_lambda_powertools/event_handler/openapi/params.py @@ -49,6 +49,7 @@ def __init__( cookie_params: Optional[List[ModelField]] = None, body_params: Optional[List[ModelField]] = None, return_param: Optional[ModelField] = None, + response_extra_models: Optional[List[ModelField]] = None, name: Optional[str] = None, call: Optional[Callable[..., Any]] = None, request_param_name: Optional[str] = None, @@ -64,6 +65,7 @@ def __init__( self.cookie_params = cookie_params or [] self.body_params = body_params or [] self.return_param = return_param or None + self.response_extra_models = response_extra_models or [] self.request_param_name = request_param_name self.websocket_param_name = websocket_param_name self.http_connection_param_name = http_connection_param_name diff --git a/aws_lambda_powertools/event_handler/openapi/types.py b/aws_lambda_powertools/event_handler/openapi/types.py index 0d166de1131..beafa0e566c 100644 --- a/aws_lambda_powertools/event_handler/openapi/types.py +++ b/aws_lambda_powertools/event_handler/openapi/types.py @@ -2,6 +2,8 @@ from enum import Enum from typing import TYPE_CHECKING, Any, Callable, Dict, Optional, Set, Type, Union +from aws_lambda_powertools.shared.types import NotRequired, TypedDict + if TYPE_CHECKING: from pydantic import BaseModel # noqa: F401 @@ -43,3 +45,16 @@ }, }, } + + +class OpenAPIResponseContentSchema(TypedDict, total=False): + schema: Dict + + +class OpenAPIResponseContentModel(TypedDict): + model: Any + + +class OpenAPIResponse(TypedDict): + description: str + content: NotRequired[Dict[str, Union[OpenAPIResponseContentSchema, OpenAPIResponseContentModel]]] diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index 4602231a63e..a34a94975bc 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -955,15 +955,15 @@ Customize your API endpoints by adding metadata to endpoint definitions. This pr Here's a breakdown of various customizable fields: -| Field Name | Type | Description | -| ---------------------- | --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `summary` | `str` | A concise overview of the main functionality of the endpoint. This brief introduction is usually displayed in autogenerated API documentation and helps consumers quickly understand what the endpoint does. | -| `description` | `str` | A more detailed explanation of the endpoint, which can include information about the operation's behavior, including side effects, error states, and other operational guidelines. | -| `responses` | `Dict[int, Dict[str, Any]]` | A dictionary that maps each HTTP status code to a Response Object as defined by the [OpenAPI Specification](https://swagger.io/specification/#response-object). This allows you to describe expected responses, including default or error messages, and their corresponding schemas for different status codes. | -| `response_description` | `str` | Provides the default textual description of the response sent by the endpoint when the operation is successful. It is intended to give a human-readable understanding of the result. | -| `tags` | `List[str]` | Tags are a way to categorize and group endpoints within the API documentation. They can help organize the operations by resources or other heuristic. | -| `operation_id` | `str` | A unique identifier for the operation, which can be used for referencing this operation in documentation or code. This ID must be unique across all operations described in the API. | -| `include_in_schema` | `bool` | A boolean value that determines whether or not this operation should be included in the OpenAPI schema. Setting it to `False` can hide the endpoint from generated documentation and schema exports, which might be useful for private or experimental endpoints. | +| Field Name | Type | Description | +| ---------------------- |-----------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `summary` | `str` | A concise overview of the main functionality of the endpoint. This brief introduction is usually displayed in autogenerated API documentation and helps consumers quickly understand what the endpoint does. | +| `description` | `str` | A more detailed explanation of the endpoint, which can include information about the operation's behavior, including side effects, error states, and other operational guidelines. | +| `responses` | `Dict[int, Dict[str, OpenAPIResponse]]` | A dictionary that maps each HTTP status code to a Response Object as defined by the [OpenAPI Specification](https://swagger.io/specification/#response-object). This allows you to describe expected responses, including default or error messages, and their corresponding schemas or models for different status codes. | +| `response_description` | `str` | Provides the default textual description of the response sent by the endpoint when the operation is successful. It is intended to give a human-readable understanding of the result. | +| `tags` | `List[str]` | Tags are a way to categorize and group endpoints within the API documentation. They can help organize the operations by resources or other heuristic. | +| `operation_id` | `str` | A unique identifier for the operation, which can be used for referencing this operation in documentation or code. This ID must be unique across all operations described in the API. | +| `include_in_schema` | `bool` | A boolean value that determines whether or not this operation should be included in the OpenAPI schema. Setting it to `False` can hide the endpoint from generated documentation and schema exports, which might be useful for private or experimental endpoints. | To implement these customizations, include extra parameters when defining your routes: diff --git a/tests/functional/event_handler/test_openapi_responses.py b/tests/functional/event_handler/test_openapi_responses.py index bd470867428..be5d9bca288 100644 --- a/tests/functional/event_handler/test_openapi_responses.py +++ b/tests/functional/event_handler/test_openapi_responses.py @@ -1,4 +1,9 @@ -from aws_lambda_powertools.event_handler import APIGatewayRestResolver +from secrets import randbelow +from typing import Union + +from pydantic import BaseModel + +from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response def test_openapi_default_response(): @@ -47,3 +52,90 @@ def handler(): assert 200 not in responses.keys() assert 422 not in responses.keys() + + +def test_openapi_200_custom_schema(): + app = APIGatewayRestResolver(enable_validation=True) + + class User(BaseModel): + pass + + @app.get( + "/", + responses={200: {"description": "Custom response", "content": {"application/json": {"schema": User.schema()}}}}, + ) + def handler(): + return {"message": "hello world"} + + schema = app.get_openapi_schema() + responses = schema.paths["/"].get.responses + assert 200 in responses.keys() + + assert responses[200].description == "Custom response" + assert responses[200].content["application/json"].schema_.title == "User" + + +def test_openapi_union_response(): + app = APIGatewayRestResolver(enable_validation=True) + + class User(BaseModel): + pass + + class Order(BaseModel): + pass + + @app.get( + "/", + responses={ + 200: {"description": "200 Response", "content": {"application/json": {"model": User}}}, + 202: {"description": "202 Response", "content": {"application/json": {"model": Order}}}, + }, + ) + def handler() -> Response[Union[User, Order]]: + if randbelow(2) > 0: + return Response(status_code=200, body=User()) + else: + return Response(status_code=202, body=Order()) + + schema = app.get_openapi_schema() + responses = schema.paths["/"].get.responses + assert 200 in responses.keys() + assert responses[200].description == "200 Response" + assert responses[200].content["application/json"].schema_.ref == "#/components/schemas/User" + + assert 202 in responses.keys() + assert responses[202].description == "202 Response" + assert responses[202].content["application/json"].schema_.ref == "#/components/schemas/Order" + + +def test_openapi_union_partial_response(): + app = APIGatewayRestResolver(enable_validation=True) + + class User(BaseModel): + pass + + class Order(BaseModel): + pass + + @app.get( + "/", + responses={ + 200: {"description": "200 Response"}, + 202: {"description": "202 Response", "content": {"application/json": {"model": Order}}}, + }, + ) + def handler() -> Response[Union[User, Order]]: + if randbelow(2) > 0: + return Response(status_code=200, body=User()) + else: + return Response(status_code=202, body=Order()) + + schema = app.get_openapi_schema() + responses = schema.paths["/"].get.responses + assert 200 in responses.keys() + assert responses[200].description == "200 Response" + assert responses[200].content["application/json"].schema_.anyOf is not None + + assert 202 in responses.keys() + assert responses[202].description == "202 Response" + assert responses[202].content["application/json"].schema_.ref == "#/components/schemas/Order" From 585ac4d2f605587bc68ca407447f3d614434dd71 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:05:53 +0000 Subject: [PATCH 0002/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3639) chore(deps): bump the layer-balancer group Bumps the layer-balancer group in /layer/scripts/layer-balancer with 1 update: [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2). Updates `github.com/aws/aws-sdk-go-v2/config` from 1.26.3 to 1.26.4 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.26.3...config/v1.26.4) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-type: direct:production update-type: version-update:semver-patch dependency-group: layer-balancer ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 6 +++--- layer/scripts/layer-balancer/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 0ea77faabba..4ead1ea46e3 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/aws/aws-sdk-go-v2 v1.24.1 - github.com/aws/aws-sdk-go-v2/config v1.26.3 + github.com/aws/aws-sdk-go-v2/config v1.26.4 github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 @@ -12,7 +12,7 @@ require ( require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.14 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.15 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect @@ -20,7 +20,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect github.com/aws/smithy-go v1.19.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index d7cb8836d33..f8b2bd14585 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -2,10 +2,10 @@ github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3 github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= -github.com/aws/aws-sdk-go-v2/config v1.26.3 h1:dKuc2jdp10y13dEEvPqWxqLoc0vF3Z9FC45MvuQSxOA= -github.com/aws/aws-sdk-go-v2/config v1.26.3/go.mod h1:Bxgi+DeeswYofcYO0XyGClwlrq3DZEXli0kLf4hkGA0= -github.com/aws/aws-sdk-go-v2/credentials v1.16.14 h1:mMDTwwYO9A0/JbOCOG7EOZHtYM+o7OfGWfu0toa23VE= -github.com/aws/aws-sdk-go-v2/credentials v1.16.14/go.mod h1:cniAUh3ErQPHtCQGPT5ouvSAQ0od8caTO9OOuufZOAE= +github.com/aws/aws-sdk-go-v2/config v1.26.4 h1:Juj7LhtxNudNUlfX22K5AnLafO+v4eq9PA3VWSCIQs4= +github.com/aws/aws-sdk-go-v2/config v1.26.4/go.mod h1:tioqQ7wvxMYnTDpoTTLHhV3Zh+z261i/f2oz+ds8eNI= +github.com/aws/aws-sdk-go-v2/credentials v1.16.15 h1:P0/m1LU08MF2kRzx4P//+7lNjiJod1z4xI2WpWhdpTQ= +github.com/aws/aws-sdk-go-v2/credentials v1.16.15/go.mod h1:pgtMCf7Dx4GWw5EpHOTc2Sy17LIP0A0N2C9nQ83pQ/0= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= @@ -22,8 +22,8 @@ github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 h1:YCvhGwdiZ9tKTjoIOE8jLt+3J github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7/go.mod h1:xqjYGK1M7YTmyfZBW8LVAx7QnefUb/mE5BglUnxtx6E= github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac= github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6 h1:Yf2MIo9x+0tyv76GljxzqA3WtC5mw7NmazD2chwjxE4= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.6/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= From 9afbc78b6d5941419ec867b6923321d81433367f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 17 Jan 2024 08:06:33 +0000 Subject: [PATCH 0003/2666] chore(ci): changelog rebuild (#3641) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8aac6a393c4..2d69809c569 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,18 +19,25 @@ ## Features +* **event_handler:** add support for additional response models ([#3591](https://github.com/aws-powertools/powertools-lambda-python/issues/3591)) * **event_handler:** add support to download OpenAPI spec file ([#3571](https://github.com/aws-powertools/powertools-lambda-python/issues/3571)) +* **event_source:** Add support for policyLevel field in CloudWatch Logs event and parser ([#3624](https://github.com/aws-powertools/powertools-lambda-python/issues/3624)) * **idempotency:** adding redis as idempotency backend ([#2567](https://github.com/aws-powertools/powertools-lambda-python/issues/2567)) ## Maintenance +* **ci:** update boto3 library version to 1.26.164+ ([#3632](https://github.com/aws-powertools/powertools-lambda-python/issues/3632)) * **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) * **deps:** bump gitpython from 3.1.37 to 3.1.41 in /docs ([#3610](https://github.com/aws-powertools/powertools-lambda-python/issues/3610)) * **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) -* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) -* **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) -* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) +* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) * **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) +* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) +* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) +* **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) +* **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) +* **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) +* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) From c466c806985e518a5c52acb54485fbccbaa2548f Mon Sep 17 00:00:00 2001 From: Stephane B Date: Wed, 17 Jan 2024 10:36:12 -0500 Subject: [PATCH 0004/2666] feat(event_source): Add support for S3 batch operations (#3572) * Add support for S3 Batch Operations event and response along with unit tests. This seamlessly support both schema 1.0 and 2.0 A few notes: - S3BatchOperationXXX or S3BatchOperationsXXX ? - s3 key is not url-encoded in real life despite what the documentation implies. Need to test with some keys that contain spaces, etc... - S3BatchOperationResult has some factory methods to simplifies building - S3BatchOperationEvent may need to as it makes initialization needlessly complicated * Add documentation with example based on the AWS S3 documentation * Use unquote_plus and add unit test for key encoded with space * Initial refactor * Changing the DX to improve usability * Documentation * Adding parser * Small refactor * Addressing Ruben's feedback - Docs and examples * Addressing Ruben's feedback - Docs and examples * Addressing Ruben's feedback - Code * Addressing Ruben's feedback - Code --------- Co-authored-by: Leandro Damascena --- .../utilities/data_classes/__init__.py | 8 + .../data_classes/s3_batch_operation_event.py | 242 ++++++++++++++++++ .../utilities/parser/models/__init__.py | 4 + .../parser/models/s3_batch_operation.py | 34 +++ docs/utilities/data_classes.md | 13 +- docs/utilities/parser.md | 1 + .../event_sources/src/s3_batch_operation.py | 37 +++ .../events/s3BatchOperationEventSchemaV1.json | 15 ++ .../events/s3BatchOperationEventSchemaV2.json | 19 ++ .../test_s3_batch_operation_event.py | 60 +++++ .../test_s3_batch_operation_response.py | 152 +++++++++++ tests/unit/parser/test_s3_batch_operation.py | 38 +++ ...bject_event.py => test_s3_object_event.py} | 0 13 files changed, 622 insertions(+), 1 deletion(-) create mode 100644 aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py create mode 100644 aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py create mode 100644 examples/event_sources/src/s3_batch_operation.py create mode 100644 tests/events/s3BatchOperationEventSchemaV1.json create mode 100644 tests/events/s3BatchOperationEventSchemaV2.json create mode 100644 tests/unit/data_classes/test_s3_batch_operation_event.py create mode 100644 tests/unit/data_classes/test_s3_batch_operation_response.py create mode 100644 tests/unit/parser/test_s3_batch_operation.py rename tests/unit/parser/{test_s3 object_event.py => test_s3_object_event.py} (100%) diff --git a/aws_lambda_powertools/utilities/data_classes/__init__.py b/aws_lambda_powertools/utilities/data_classes/__init__.py index fd9294bc8bb..38274f0bab4 100644 --- a/aws_lambda_powertools/utilities/data_classes/__init__.py +++ b/aws_lambda_powertools/utilities/data_classes/__init__.py @@ -23,6 +23,11 @@ ) from .kinesis_stream_event import KinesisStreamEvent from .lambda_function_url_event import LambdaFunctionUrlEvent +from .s3_batch_operation_event import ( + S3BatchOperationEvent, + S3BatchOperationResponse, + S3BatchOperationResponseRecord, +) from .s3_event import S3Event, S3EventBridgeNotificationEvent from .secrets_manager_event import SecretsManagerEvent from .ses_event import SESEvent @@ -52,6 +57,9 @@ "LambdaFunctionUrlEvent", "S3Event", "S3EventBridgeNotificationEvent", + "S3BatchOperationEvent", + "S3BatchOperationResponse", + "S3BatchOperationResponseRecord", "SESEvent", "SNSEvent", "SQSEvent", diff --git a/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py b/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py new file mode 100644 index 00000000000..9c742e0c553 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_classes/s3_batch_operation_event.py @@ -0,0 +1,242 @@ +import warnings +from dataclasses import dataclass, field +from typing import Any, Dict, Iterator, List, Optional, Tuple +from urllib.parse import unquote_plus + +from aws_lambda_powertools.shared.types import Literal +from aws_lambda_powertools.utilities.data_classes.common import DictWrapper + +# list of valid result code. Used both in S3BatchOperationResponse and S3BatchOperationResponseRecord +VALID_RESULT_CODES: Tuple[str, str, str] = ("Succeeded", "TemporaryFailure", "PermanentFailure") +RESULT_CODE_TYPE = Literal["Succeeded", "TemporaryFailure", "PermanentFailure"] + + +@dataclass(repr=False, order=False) +class S3BatchOperationResponseRecord: + task_id: str + result_code: RESULT_CODE_TYPE + result_string: Optional[str] = None + + def asdict(self) -> Dict[str, Any]: + if self.result_code not in VALID_RESULT_CODES: + warnings.warn( + stacklevel=2, + message=f"The resultCode {self.result_code} is not valid. " + f"Choose from {', '.join(map(repr, VALID_RESULT_CODES))}.", + ) + + return { + "taskId": self.task_id, + "resultCode": self.result_code, + "resultString": self.result_string, + } + + +@dataclass(repr=False, order=False) +class S3BatchOperationResponse: + """S3 Batch Operations response object + + Documentation: + -------------- + - https://docs.aws.amazon.com/lambda/latest/dg/services-s3-batch.html + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html#batch-ops-invoke-lambda-custom-functions + - https://docs.aws.amazon.com/AmazonS3/latest/API/API_control_LambdaInvokeOperation.html#AmazonS3-Type-control_LambdaInvokeOperation-InvocationSchemaVersion + + Parameters + ---------- + invocation_schema_version : str + Specifies the schema version for the payload that Batch Operations sends when invoking + an AWS Lambda function., either '1.0' or '2.0'. This must be copied from the event. + + invocation_id : str + The identifier of the invocation request. This must be copied from the event. + + treat_missing_keys_as : Literal["Succeeded", "TemporaryFailure", "PermanentFailure"] + Undocumented parameter, defaults to "Succeeded" + + results : List[S3BatchOperationResult] + Results of each S3 Batch Operations task, + optional parameter at start. Can be added later using `add_result` function. + + Examples + -------- + + **S3 Batch Operations** + + ```python + import boto3 + + from botocore.exceptions import ClientError + + from aws_lambda_powertools.utilities.data_classes import ( + S3BatchOperationEvent, + S3BatchOperationResponse, + event_source + ) + from aws_lambda_powertools.utilities.typing import LambdaContext + + + @event_source(data_class=S3BatchOperationEvent) + def lambda_handler(event: S3BatchOperationEvent, context: LambdaContext): + response = S3BatchOperationResponse( + event.invocation_schema_version, + event.invocation_id, + "PermanentFailure" + ) + + result = None + task = event.task + src_key: str = task.s3_key + src_bucket: str = task.s3_bucket + + s3 = boto3.client("s3", region_name='us-east-1') + + try: + dest_bucket, dest_key = do_some_work(s3, src_bucket, src_key) + result = task.build_task_batch_response("Succeeded", f"s3://{dest_bucket}/{dest_key}") + except ClientError as e: + error_code = e.response['Error']['Code'] + error_message = e.response['Error']['Message'] + if error_code == 'RequestTimeout': + result = task.build_task_batch_response("TemporaryFailure", "Timeout - trying again") + else: + result = task.build_task_batch_response("PermanentFailure", f"{error_code}: {error_message}") + except Exception as e: + result = task.build_task_batch_response("PermanentFailure", str(e)) + finally: + response.add_result(result) + + return response.asdict() + ``` + """ + + invocation_schema_version: str + invocation_id: str + treat_missing_keys_as: RESULT_CODE_TYPE = "Succeeded" + results: List[S3BatchOperationResponseRecord] = field(default_factory=list) + + def __post_init__(self): + if self.treat_missing_keys_as not in VALID_RESULT_CODES: + warnings.warn( + stacklevel=2, + message=f"The value {self.treat_missing_keys_as} is not valid for treat_missing_keys_as, " + f"Choose from {', '.join(map(repr, VALID_RESULT_CODES))}.", + ) + + def add_result(self, result: S3BatchOperationResponseRecord): + self.results.append(result) + + def asdict(self) -> Dict: + result_count = len(self.results) + + if result_count != 1: + raise ValueError(f"Response must have exactly one result, but got {result_count}") + + return { + "invocationSchemaVersion": self.invocation_schema_version, + "treatMissingKeysAs": self.treat_missing_keys_as, + "invocationId": self.invocation_id, + "results": [result.asdict() for result in self.results], + } + + +class S3BatchOperationJob(DictWrapper): + @property + def get_id(self) -> str: + # Note: this name conflicts with existing python builtins + return self["id"] + + @property + def user_arguments(self) -> Optional[Dict[str, str]]: + """Get user arguments provided for this job (only for invocation schema 2.0)""" + return self.get("userArguments") + + +class S3BatchOperationTask(DictWrapper): + @property + def task_id(self) -> str: + """Get the task id""" + return self["taskId"] + + @property + def s3_key(self) -> str: + """Get the object key using unquote_plus""" + return unquote_plus(self["s3Key"]) + + @property + def s3_version_id(self) -> Optional[str]: + """Object version if bucket is versioning-enabled, otherwise null""" + return self.get("s3VersionId") + + @property + def s3_bucket_arn(self) -> Optional[str]: + """Get the s3 bucket arn (present only for invocationSchemaVersion '1.0')""" + return self.get("s3BucketArn") + + @property + def s3_bucket(self) -> str: + """ + Get the s3 bucket, either from 's3Bucket' property (invocationSchemaVersion '2.0') + or from 's3BucketArn' (invocationSchemaVersion '1.0') + """ + if self.s3_bucket_arn: + return self.s3_bucket_arn.split(":::")[-1] + return self["s3Bucket"] + + def build_task_batch_response( + self, + result_code: Literal["Succeeded", "TemporaryFailure", "PermanentFailure"] = "Succeeded", + result_string: str = "", + ) -> S3BatchOperationResponseRecord: + """Create a S3BatchOperationResponseRecord directly using the task_id and given values + + Parameters + ---------- + result_code : Literal["Succeeded", "TemporaryFailure", "PermanentFailure"] = "Succeeded" + task result, supported value: "Succeeded", "TemporaryFailure", "PermanentFailure" + result_string : str + string to identify in the report + """ + return S3BatchOperationResponseRecord( + task_id=self.task_id, + result_code=result_code, + result_string=result_string, + ) + + +class S3BatchOperationEvent(DictWrapper): + """Amazon S3BatchOperation Event + + Documentation: + -------------- + - https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html + """ + + @property + def invocation_id(self) -> str: + """Get the identifier of the invocation request""" + return self["invocationId"] + + @property + def invocation_schema_version(self) -> Literal["1.0", "2.0"]: + """ + Get the schema version for the payload that Batch Operations sends when invoking an + AWS Lambda function. Either '1.0' or '2.0'. + """ + return self["invocationSchemaVersion"] + + @property + def tasks(self) -> Iterator[S3BatchOperationTask]: + """Get s3 batch operation tasks""" + for task in self["tasks"]: + yield S3BatchOperationTask(task) + + @property + def task(self) -> S3BatchOperationTask: + """Get the first s3 batch operation task""" + return next(self.tasks) + + @property + def job(self) -> S3BatchOperationJob: + """Get the s3 batch operation job""" + return S3BatchOperationJob(self["job"]) diff --git a/aws_lambda_powertools/utilities/parser/models/__init__.py b/aws_lambda_powertools/utilities/parser/models/__init__.py index db3aa524377..c036490ec53 100644 --- a/aws_lambda_powertools/utilities/parser/models/__init__.py +++ b/aws_lambda_powertools/utilities/parser/models/__init__.py @@ -68,6 +68,7 @@ S3Model, S3RecordModel, ) +from .s3_batch_operation import S3BatchOperationJobModel, S3BatchOperationModel, S3BatchOperationTaskModel from .s3_event_notification import ( S3SqsEventNotificationModel, S3SqsEventNotificationRecordModel, @@ -177,4 +178,7 @@ "BedrockAgentEventModel", "BedrockAgentRequestBodyModel", "BedrockAgentRequestMediaModel", + "S3BatchOperationJobModel", + "S3BatchOperationModel", + "S3BatchOperationTaskModel", ] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py new file mode 100644 index 00000000000..1b7961999bd --- /dev/null +++ b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py @@ -0,0 +1,34 @@ +from typing import Any, Dict, List, Optional + +from pydantic import BaseModel, validator + +from aws_lambda_powertools.utilities.parser.types import Literal + + +class S3BatchOperationTaskModel(BaseModel): + taskId: str + s3Key: str + s3VersionId: Optional[str] = None + s3BucketArn: Optional[str] = None + s3Bucket: Optional[str] = None + + @validator("s3Bucket", pre=True, always=True) + def validate_bucket(cls, current_value, values): + # Get the s3 bucket, either from 's3Bucket' property (invocationSchemaVersion '2.0') + # or from 's3BucketArn' (invocationSchemaVersion '1.0') + if values.get("s3BucketArn") and not current_value: + # Replace s3Bucket value with the value from s3BucketArn + return values["s3BucketArn"].split(":::")[-1] + return current_value + + +class S3BatchOperationJobModel(BaseModel): + id: str + userArguments: Optional[Dict[str, Any]] = None + + +class S3BatchOperationModel(BaseModel): + invocationId: str + invocationSchemaVersion: Literal["1.0", "2.0"] + job: S3BatchOperationJobModel + tasks: List[S3BatchOperationTaskModel] diff --git a/docs/utilities/data_classes.md b/docs/utilities/data_classes.md index 37d3725967c..97b7a5dfda2 100644 --- a/docs/utilities/data_classes.md +++ b/docs/utilities/data_classes.md @@ -75,7 +75,7 @@ Log Data Event for Troubleshooting ## Supported event sources | Event Source | Data_class | -| ------------------------------------------------------------------------- | -------------------------------------------------- | +|---------------------------------------------------------------------------|----------------------------------------------------| | [Active MQ](#active-mq) | `ActiveMQEvent` | | [API Gateway Authorizer](#api-gateway-authorizer) | `APIGatewayAuthorizerRequestEvent` | | [API Gateway Authorizer V2](#api-gateway-authorizer-v2) | `APIGatewayAuthorizerEventV2` | @@ -99,6 +99,7 @@ Log Data Event for Troubleshooting | [Lambda Function URL](#lambda-function-url) | `LambdaFunctionUrlEvent` | | [Rabbit MQ](#rabbit-mq) | `RabbitMQEvent` | | [S3](#s3) | `S3Event` | +| [S3 Batch Operations](#s3-batch-operations) | `S3BatchOperationEvent` | | [S3 Object Lambda](#s3-object-lambda) | `S3ObjectLambdaEvent` | | [S3 EventBridge Notification](#s3-eventbridge-notification) | `S3EventBridgeNotificationEvent` | | [SES](#ses) | `SESEvent` | @@ -1076,6 +1077,16 @@ for more details. do_something_with(f"{bucket_name}/{object_key}") ``` +### S3 Batch Operations + +This example is based on the AWS S3 Batch Operations documentation [Example Lambda function for S3 Batch Operations](https://docs.aws.amazon.com/AmazonS3/latest/userguide/batch-ops-invoke-lambda.html){target="_blank"}. + +=== "app.py" + + ```python hl_lines="4 8 10 20 25 27 29 33" + --8<-- "examples/event_sources/src/s3_batch_operation.py" + ``` + ### S3 Object Lambda This example is based on the AWS Blog post [Introducing Amazon S3 Object Lambda – Use Your Code to Process Data as It Is Being Retrieved from S3](https://aws.amazon.com/blogs/aws/introducing-amazon-s3-object-lambda-use-your-code-to-process-data-as-it-is-being-retrieved-from-s3/){target="_blank"}. diff --git a/docs/utilities/parser.md b/docs/utilities/parser.md index bfd64f8b7ef..4a91d5aa13c 100644 --- a/docs/utilities/parser.md +++ b/docs/utilities/parser.md @@ -191,6 +191,7 @@ Parser comes with the following built-in models: | **KinesisFirehoseModel** | Lambda Event Source payload for Amazon Kinesis Firehose | | **KinesisFirehoseSqsModel** | Lambda Event Source payload for SQS messages wrapped in Kinesis Firehose records | | **LambdaFunctionUrlModel** | Lambda Event Source payload for Lambda Function URL payload | +| **S3BatchOperationModel** | Lambda Event Source payload for Amazon S3 Batch Operation | | **S3EventNotificationEventBridgeModel** | Lambda Event Source payload for Amazon S3 Event Notification to EventBridge. | | **S3Model** | Lambda Event Source payload for Amazon S3 | | **S3ObjectLambdaEvent** | Lambda Event Source payload for Amazon S3 Object Lambda | diff --git a/examples/event_sources/src/s3_batch_operation.py b/examples/event_sources/src/s3_batch_operation.py new file mode 100644 index 00000000000..e292d8cae47 --- /dev/null +++ b/examples/event_sources/src/s3_batch_operation.py @@ -0,0 +1,37 @@ +import boto3 +from botocore.exceptions import ClientError + +from aws_lambda_powertools.utilities.data_classes import S3BatchOperationEvent, S3BatchOperationResponse, event_source +from aws_lambda_powertools.utilities.typing import LambdaContext + + +@event_source(data_class=S3BatchOperationEvent) +def lambda_handler(event: S3BatchOperationEvent, context: LambdaContext): + response = S3BatchOperationResponse(event.invocation_schema_version, event.invocation_id, "PermanentFailure") + + task = event.task + src_key: str = task.s3_key + src_bucket: str = task.s3_bucket + + s3 = boto3.client("s3", region_name="us-east-1") + + try: + dest_bucket, dest_key = do_some_work(s3, src_bucket, src_key) + result = task.build_task_batch_response("Succeeded", f"s3://{dest_bucket}/{dest_key}") + except ClientError as e: + error_code = e.response["Error"]["Code"] + error_message = e.response["Error"]["Message"] + if error_code == "RequestTimeout": + result = task.build_task_batch_response("TemporaryFailure", "Retry request to Amazon S3 due to timeout.") + else: + result = task.build_task_batch_response("PermanentFailure", f"{error_code}: {error_message}") + except Exception as e: + result = task.build_task_batch_response("PermanentFailure", str(e)) + finally: + response.add_result(result) + + return response.asdict() + + +def do_some_work(s3_client, src_bucket: str, src_key: str): + ... diff --git a/tests/events/s3BatchOperationEventSchemaV1.json b/tests/events/s3BatchOperationEventSchemaV1.json new file mode 100644 index 00000000000..8a7bcabf590 --- /dev/null +++ b/tests/events/s3BatchOperationEventSchemaV1.json @@ -0,0 +1,15 @@ +{ + "invocationSchemaVersion": "1.0", + "invocationId": "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", + "job": { + "id": "f3cc4f60-61f6-4a2b-8a21-d07600c373ce" + }, + "tasks": [ + { + "taskId": "dGFza2lkZ29lc2hlcmUK", + "s3Key": "prefix/dataset/dataset.20231222.json.gz", + "s3VersionId": "1", + "s3BucketArn": "arn:aws:s3:::powertools-dataset" + } + ] +} \ No newline at end of file diff --git a/tests/events/s3BatchOperationEventSchemaV2.json b/tests/events/s3BatchOperationEventSchemaV2.json new file mode 100644 index 00000000000..720dd1f0cf0 --- /dev/null +++ b/tests/events/s3BatchOperationEventSchemaV2.json @@ -0,0 +1,19 @@ +{ + "invocationSchemaVersion": "2.0", + "invocationId": "YXNkbGZqYWRmaiBhc2RmdW9hZHNmZGpmaGFzbGtkaGZza2RmaAo", + "job": { + "id": "f3cc4f60-61f6-4a2b-8a21-d07600c373ce", + "userArguments": { + "k1": "v1", + "k2": "v2" + } + }, + "tasks": [ + { + "taskId": "dGFza2lkZ29lc2hlcmUK", + "s3Key": "prefix/dataset/dataset.20231222.json.gz", + "s3VersionId": null, + "s3Bucket": "powertools-dataset" + } + ] +} \ No newline at end of file diff --git a/tests/unit/data_classes/test_s3_batch_operation_event.py b/tests/unit/data_classes/test_s3_batch_operation_event.py new file mode 100644 index 00000000000..ca0d4ae635c --- /dev/null +++ b/tests/unit/data_classes/test_s3_batch_operation_event.py @@ -0,0 +1,60 @@ +from aws_lambda_powertools.utilities.data_classes import S3BatchOperationEvent +from tests.functional.utils import load_event + + +def test_s3_batch_operation_schema_v1(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + tasks = list(parsed_event.tasks) + assert len(tasks) == 1 + task = tasks[0] + task_raw = raw_event["tasks"][0] + + assert task.task_id == task_raw["taskId"] + assert task.s3_version_id == task_raw["s3VersionId"] + assert task.s3_bucket_arn == task_raw["s3BucketArn"] + assert task.s3_bucket == task_raw["s3BucketArn"].split(":::")[-1] + assert task.s3_key == task_raw["s3Key"] + + job = parsed_event.job + assert job.get_id == raw_event["job"]["id"] + assert job.user_arguments is None + + assert parsed_event.invocation_schema_version == raw_event["invocationSchemaVersion"] + assert parsed_event.invocation_id == raw_event["invocationId"] + + +def test_s3_batch_operation_schema_v2(): + raw_event = load_event("s3BatchOperationEventSchemaV2.json") + parsed_event = S3BatchOperationEvent(raw_event) + + tasks = list(parsed_event.tasks) + assert len(tasks) == 1 + task = tasks[0] + task_raw = raw_event["tasks"][0] + + assert task.task_id == task_raw["taskId"] + assert task.s3_version_id == task_raw["s3VersionId"] + assert task.s3_bucket_arn is None + assert task.s3_bucket == task_raw["s3Bucket"] + assert task.s3_key == task_raw["s3Key"] + + job = parsed_event.job + assert job.get_id == raw_event["job"]["id"] + assert job.user_arguments == raw_event["job"]["userArguments"] + + assert parsed_event.invocation_schema_version == raw_event["invocationSchemaVersion"] + assert parsed_event.invocation_id == raw_event["invocationId"] + + +def test_s3_task_has_key_with_spaces(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + + # When the inventory file is provided, the key must be url encoded + # and the file is will contain "object%20key%20with%20spaces.csv" + # however the event is sent with s3Key as "object+key+with+spaces.csv" + raw_event["tasks"][0]["s3Key"] = "object+key+with+spaces.csv" + parsed_event = S3BatchOperationEvent(raw_event) + + assert parsed_event.task.s3_key == "object key with spaces.csv" diff --git a/tests/unit/data_classes/test_s3_batch_operation_response.py b/tests/unit/data_classes/test_s3_batch_operation_response.py new file mode 100644 index 00000000000..c7106e0bfb7 --- /dev/null +++ b/tests/unit/data_classes/test_s3_batch_operation_response.py @@ -0,0 +1,152 @@ +import pytest + +from aws_lambda_powertools.utilities.data_classes import ( + S3BatchOperationEvent, + S3BatchOperationResponse, + S3BatchOperationResponseRecord, +) +from tests.functional.utils import load_event + + +def test_result_as_succeeded(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + result_string = "Successfully processed" + result = task.build_task_batch_response("Succeeded", result_string) + + assert_result(result, parsed_event.task.task_id, "Succeeded", result_string) + + +def test_result_as_temporary_failure(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + result_string = "Temporary failure" + result = task.build_task_batch_response("TemporaryFailure", result_string) + + assert_result(result, parsed_event.task.task_id, "TemporaryFailure", result_string) + + +def test_result_as_permanent_failure(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + result_string = "Permanent failure" + result = task.build_task_batch_response("PermanentFailure", result_string) + + assert_result(result, parsed_event.task.task_id, "PermanentFailure", result_string) + + +def assert_result( + result: S3BatchOperationResponseRecord, + task_id: str, + expected_result_code: str, + expected_result_string: str, +): + assert result.result_code == expected_result_code + assert result.result_string == expected_result_string + + meta = result.asdict() + + assert meta == { + "taskId": task_id, + "resultCode": expected_result_code, + "resultString": expected_result_string, + } + + +def test_response(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + response = S3BatchOperationResponse( + parsed_event.invocation_schema_version, + parsed_event.invocation_id, + "PermanentFailure", + ) + + result_string = "Successfully processed" + result = task.build_task_batch_response("Succeeded", result_string) + + response.add_result(result) + + assert len(response.results) == 1 + assert response.treat_missing_keys_as == "PermanentFailure" + assert response.invocation_schema_version == parsed_event.invocation_schema_version + assert response.invocation_id == parsed_event.invocation_id + + assert response.asdict() == { + "invocationSchemaVersion": parsed_event.invocation_schema_version, + "treatMissingKeysAs": "PermanentFailure", + "invocationId": parsed_event.invocation_id, + "results": [ + { + "taskId": result.task_id, + "resultCode": result.result_code, + "resultString": result.result_string, + }, + ], + } + + +def test_response_multiple_results(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + response = S3BatchOperationResponse(parsed_event.invocation_schema_version, parsed_event.invocation_id, "Succeeded") + + result_string = "Successfully processed" + result = task.build_task_batch_response("Succeeded", result_string) + + response.add_result(result) + + # add another result + response.add_result(result) + + with pytest.raises(ValueError, match=r"Response must have exactly one result, but got *"): + response.asdict() + + +def test_response_no_results(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + response = S3BatchOperationResponse(parsed_event.invocation_schema_version, parsed_event.invocation_id, "Succeeded") + + with pytest.raises(ValueError, match=r"Response must have exactly one result, but got *"): + response.asdict() + + +def test_invalid_treating_missing_key(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + with pytest.warns(UserWarning, match="The value *"): + S3BatchOperationResponse(parsed_event.invocation_schema_version, parsed_event.invocation_id, "invalid_value") + + +def test_invalid_record_status(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event = S3BatchOperationEvent(raw_event) + + task = parsed_event.task + + response = S3BatchOperationResponse(parsed_event.invocation_schema_version, parsed_event.invocation_id, "Succeeded") + + result_string = "Successfully processed" + result = task.build_task_batch_response("invalid_value", result_string) + response.add_result(result) + + with pytest.warns(UserWarning, match="The resultCode *"): + response.asdict() diff --git a/tests/unit/parser/test_s3_batch_operation.py b/tests/unit/parser/test_s3_batch_operation.py new file mode 100644 index 00000000000..9a27ccc4ef1 --- /dev/null +++ b/tests/unit/parser/test_s3_batch_operation.py @@ -0,0 +1,38 @@ +from aws_lambda_powertools.utilities.parser.models import S3BatchOperationModel +from tests.functional.utils import load_event + + +def test_s3_batch_operation_v1_trigger_event(): + raw_event = load_event("s3BatchOperationEventSchemaV1.json") + parsed_event: S3BatchOperationModel = S3BatchOperationModel(**raw_event) + + tasks = list(parsed_event.tasks) + assert len(tasks) == 1 + + assert parsed_event.invocationId == raw_event["invocationId"] + assert parsed_event.invocationSchemaVersion == raw_event["invocationSchemaVersion"] + assert parsed_event.job.id == raw_event["job"]["id"] + + assert tasks[0].taskId == raw_event["tasks"][0]["taskId"] + assert tasks[0].s3Key == raw_event["tasks"][0]["s3Key"] + assert tasks[0].s3VersionId == raw_event["tasks"][0]["s3VersionId"] + assert tasks[0].s3BucketArn == raw_event["tasks"][0]["s3BucketArn"] + assert tasks[0].s3Bucket == "powertools-dataset" + + +def test_s3_batch_operation_v2_trigger_event(): + raw_event = load_event("s3BatchOperationEventSchemaV2.json") + parsed_event: S3BatchOperationModel = S3BatchOperationModel(**raw_event) + + tasks = list(parsed_event.tasks) + assert len(tasks) == 1 + + assert parsed_event.invocationId == raw_event["invocationId"] + assert parsed_event.invocationSchemaVersion == raw_event["invocationSchemaVersion"] + assert parsed_event.job.id == raw_event["job"]["id"] + assert parsed_event.job.userArguments == raw_event["job"]["userArguments"] + + assert tasks[0].taskId == raw_event["tasks"][0]["taskId"] + assert tasks[0].s3Key == raw_event["tasks"][0]["s3Key"] + assert tasks[0].s3VersionId == raw_event["tasks"][0]["s3VersionId"] + assert tasks[0].s3Bucket == raw_event["tasks"][0]["s3Bucket"] diff --git a/tests/unit/parser/test_s3 object_event.py b/tests/unit/parser/test_s3_object_event.py similarity index 100% rename from tests/unit/parser/test_s3 object_event.py rename to tests/unit/parser/test_s3_object_event.py From c8958c84a4e16e6d4bcd4f5682e0787840f619a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 18 Jan 2024 08:50:43 +0000 Subject: [PATCH 0005/2666] chore(ci): changelog rebuild (#3643) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d69809c569..e5c7fb9d3ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,23 +21,25 @@ * **event_handler:** add support for additional response models ([#3591](https://github.com/aws-powertools/powertools-lambda-python/issues/3591)) * **event_handler:** add support to download OpenAPI spec file ([#3571](https://github.com/aws-powertools/powertools-lambda-python/issues/3571)) +* **event_source:** Add support for S3 batch operations ([#3572](https://github.com/aws-powertools/powertools-lambda-python/issues/3572)) * **event_source:** Add support for policyLevel field in CloudWatch Logs event and parser ([#3624](https://github.com/aws-powertools/powertools-lambda-python/issues/3624)) * **idempotency:** adding redis as idempotency backend ([#2567](https://github.com/aws-powertools/powertools-lambda-python/issues/2567)) ## Maintenance * **ci:** update boto3 library version to 1.26.164+ ([#3632](https://github.com/aws-powertools/powertools-lambda-python/issues/3632)) -* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3639](https://github.com/aws-powertools/powertools-lambda-python/issues/3639)) +* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) * **deps:** bump gitpython from 3.1.37 to 3.1.41 in /docs ([#3610](https://github.com/aws-powertools/powertools-lambda-python/issues/3610)) * **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) -* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) +* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) * **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) -* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) -* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) +* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) +* **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) * **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) +* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) +* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) * **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) -* **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) -* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) From 3c63c24d629f1db141dca09e8d895b2f5ee5bebf Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Thu, 18 Jan 2024 18:29:39 +0000 Subject: [PATCH 0006/2666] refactor(event_handler): fix BedrockAgentResolver docstring (#3645) Fixing docs --- aws_lambda_powertools/event_handler/bedrock_agent.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/aws_lambda_powertools/event_handler/bedrock_agent.py b/aws_lambda_powertools/event_handler/bedrock_agent.py index f292a11519a..9c65547d9a2 100644 --- a/aws_lambda_powertools/event_handler/bedrock_agent.py +++ b/aws_lambda_powertools/event_handler/bedrock_agent.py @@ -66,6 +66,8 @@ def simple_get(): @tracer.capture_lambda_handler def lambda_handler(event, context): return app.resolve(event, context) + ``` + """ current_event: BedrockAgentEvent From 1327a743fd4638936aa6e7fbb7f48b599430cd49 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:02:46 +0000 Subject: [PATCH 0007/2666] chore(deps-dev): bump aws-cdk from 2.121.1 to 2.122.0 (#3648) Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.121.1 to 2.122.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/commits/v2.122.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 753315b6030..9c1f3cb3ee8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.121.1" + "aws-cdk": "^2.122.0" } }, "node_modules/aws-cdk": { - "version": "2.121.1", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.121.1.tgz", - "integrity": "sha512-T8UFuNGDnXNmcHagCGeQ8xQA3zU/o2ENuyGXO/ho+U3KyYs7tnWIr++ovrp2FvhiBpmBv6SuKiueBA6OW7utBw==", + "version": "2.122.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.122.0.tgz", + "integrity": "sha512-WqiVTedcuW4LjH4WqtQncliUdeDa9j9xgu3II8Qd1HmCZotbzBorYIHDvOJ+m3ovIzd9DL+hNq9PPUqxtBe0VQ==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index c443382703f..b2065da493f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.121.1" + "aws-cdk": "^2.122.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 138fe8c9a6243879b806beec2f2a6c466f7b5472 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:06:24 +0000 Subject: [PATCH 0008/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3649) chore(deps): bump the layer-balancer group Bumps the layer-balancer group in /layer/scripts/layer-balancer with 1 update: [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2). Updates `github.com/aws/aws-sdk-go-v2/config` from 1.26.4 to 1.26.5 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.26.4...config/v1.26.5) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-type: direct:production update-type: version-update:semver-patch dependency-group: layer-balancer ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- layer/scripts/layer-balancer/go.mod | 6 +++--- layer/scripts/layer-balancer/go.sum | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 4ead1ea46e3..dfeb6a67fa1 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/aws/aws-sdk-go-v2 v1.24.1 - github.com/aws/aws-sdk-go-v2/config v1.26.4 + github.com/aws/aws-sdk-go-v2/config v1.26.5 github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 @@ -12,14 +12,14 @@ require ( require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.15 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect github.com/aws/smithy-go v1.19.0 // indirect diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index f8b2bd14585..fdaf9f31ef7 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -2,10 +2,10 @@ github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3 github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= -github.com/aws/aws-sdk-go-v2/config v1.26.4 h1:Juj7LhtxNudNUlfX22K5AnLafO+v4eq9PA3VWSCIQs4= -github.com/aws/aws-sdk-go-v2/config v1.26.4/go.mod h1:tioqQ7wvxMYnTDpoTTLHhV3Zh+z261i/f2oz+ds8eNI= -github.com/aws/aws-sdk-go-v2/credentials v1.16.15 h1:P0/m1LU08MF2kRzx4P//+7lNjiJod1z4xI2WpWhdpTQ= -github.com/aws/aws-sdk-go-v2/credentials v1.16.15/go.mod h1:pgtMCf7Dx4GWw5EpHOTc2Sy17LIP0A0N2C9nQ83pQ/0= +github.com/aws/aws-sdk-go-v2/config v1.26.5 h1:lodGSevz7d+kkFJodfauThRxK9mdJbyutUxGq1NNhvw= +github.com/aws/aws-sdk-go-v2/config v1.26.5/go.mod h1:DxHrz6diQJOc9EwDslVRh84VjjrE17g+pVZXUeSxaDU= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= @@ -20,8 +20,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIG github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 h1:YCvhGwdiZ9tKTjoIOE8jLt+3JBK4quAQyhoMCWtxhQc= github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7/go.mod h1:xqjYGK1M7YTmyfZBW8LVAx7QnefUb/mE5BglUnxtx6E= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= From 2a4ec522a817fa7a1d1e298334e32d3c66c4e0b7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 09:07:49 +0000 Subject: [PATCH 0009/2666] chore(ci): changelog rebuild (#3650) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e5c7fb9d3ca..7fdb78d7b88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ## Code Refactoring * **event-handler:** Inject CSS and JS files into SwaggerUI route when no custom CDN is used. ([#3562](https://github.com/aws-powertools/powertools-lambda-python/issues/3562)) +* **event_handler:** fix BedrockAgentResolver docstring ([#3645](https://github.com/aws-powertools/powertools-lambda-python/issues/3645)) ## Documentation @@ -28,18 +29,18 @@ ## Maintenance * **ci:** update boto3 library version to 1.26.164+ ([#3632](https://github.com/aws-powertools/powertools-lambda-python/issues/3632)) +* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) +* **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) * **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3639](https://github.com/aws-powertools/powertools-lambda-python/issues/3639)) -* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) * **deps:** bump gitpython from 3.1.37 to 3.1.41 in /docs ([#3610](https://github.com/aws-powertools/powertools-lambda-python/issues/3610)) -* **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) -* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) -* **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) +* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) +* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) * **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) +* **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) * **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) * **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) -* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) +* **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) * **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) -* **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) From 79e248c0aa0510b4eb8456d4b54d311595bdf7a5 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Fri, 19 Jan 2024 12:13:00 +0000 Subject: [PATCH 0010/2666] chore(ci): Disable Redis e2e until we drop Python 3.7 (#3652) * Disabling Redis e2e until we drop Python 3.7 * Disabling Redis e2e until we drop Python 3.7 --- tests/e2e/idempotency_redis/conftest.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/e2e/idempotency_redis/conftest.py b/tests/e2e/idempotency_redis/conftest.py index 65cffcd1948..6f3183f02dd 100644 --- a/tests/e2e/idempotency_redis/conftest.py +++ b/tests/e2e/idempotency_redis/conftest.py @@ -1,7 +1,5 @@ import pytest -from tests.e2e.idempotency_redis.infrastructure import IdempotencyRedisServerlessStack - @pytest.fixture(autouse=True, scope="package") def infrastructure(): @@ -12,8 +10,6 @@ def infrastructure(): Dict[str, str] CloudFormation Outputs from deployed infrastructure """ - stack = IdempotencyRedisServerlessStack() - try: - yield stack.deploy() - finally: - stack.delete() + + # MAINTENANCE: Add the Stack constructor when Python 3.7 is dropped + return None From f83323396b40444e2dd992acc4707091fdd963b9 Mon Sep 17 00:00:00 2001 From: Dan Straw Date: Fri, 19 Jan 2024 12:34:59 +0000 Subject: [PATCH 0011/2666] feat(idempotency): leverage new DynamoDB Failed conditional writes behavior with ReturnValuesOnConditionCheckFailure (#3446) * feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327 * feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327 * feat: add ReturnValuesOnConditionCheckFailure to DynamoDB idempotency to return a copy of the item on failure and avoid a subsequent get #3327. Changes after PR comments * Improving code readability * Reverting function * Adding comments about some logic decisions * Use DynamoDBPersistenceLayer passed in for test_idempotent_lambda_expired_during_request Co-authored-by: Leandro Damascena Signed-off-by: Dan Straw * Adding docs * wording * Adressing Ruben's feedback * Adressing Ruben's feedback --------- Signed-off-by: Dan Straw Co-authored-by: Dan Straw Co-authored-by: Leandro Damascena Co-authored-by: Cavalcante Damascena --- .../utilities/idempotency/base.py | 19 ++- .../utilities/idempotency/exceptions.py | 14 +++ .../utilities/idempotency/persistence/base.py | 112 ++++-------------- .../idempotency/persistence/datarecord.py | 93 +++++++++++++++ .../idempotency/persistence/dynamodb.py | 55 ++++++++- docs/media/idempotency_first_execution.png | Bin 0 -> 95197 bytes docs/media/idempotency_second_execution.png | Bin 0 -> 90457 bytes docs/utilities/idempotency.md | 30 ++++- tests/functional/idempotency/conftest.py | 2 + .../idempotency/test_idempotency.py | 111 +++++++++-------- tests/functional/idempotency/utils.py | 1 + .../idempotency/test_dynamodb_persistence.py | 11 ++ 12 files changed, 295 insertions(+), 153 deletions(-) create mode 100644 aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py create mode 100644 docs/media/idempotency_first_execution.png create mode 100644 docs/media/idempotency_second_execution.png diff --git a/aws_lambda_powertools/utilities/idempotency/base.py b/aws_lambda_powertools/utilities/idempotency/base.py index a8d509b86eb..771547fe33c 100644 --- a/aws_lambda_powertools/utilities/idempotency/base.py +++ b/aws_lambda_powertools/utilities/idempotency/base.py @@ -14,8 +14,10 @@ IdempotencyValidationError, ) from aws_lambda_powertools.utilities.idempotency.persistence.base import ( - STATUS_CONSTANTS, BasePersistenceLayer, +) +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( + STATUS_CONSTANTS, DataRecord, ) from aws_lambda_powertools.utilities.idempotency.serialization.base import ( @@ -118,12 +120,17 @@ def _process_idempotency(self): data=self.data, remaining_time_in_millis=self._get_remaining_time_in_millis(), ) - except IdempotencyKeyError: + except (IdempotencyKeyError, IdempotencyValidationError): raise - except IdempotencyItemAlreadyExistsError: - # Now we know the item already exists, we can retrieve it - record = self._get_idempotency_record() - if record is not None: + except IdempotencyItemAlreadyExistsError as exc: + # Attempt to retrieve the existing record, either from the exception ReturnValuesOnConditionCheckFailure + # or perform a GET operation if the information is not available. + # We give preference to ReturnValuesOnConditionCheckFailure because it is a faster and more cost-effective + # way of retrieving the existing record after a failed conditional write operation. + record = exc.old_data_record or self._get_idempotency_record() + + # If a record is found, handle it for status + if record: return self._handle_for_status(record) except Exception as exc: raise IdempotencyPersistenceLayerError( diff --git a/aws_lambda_powertools/utilities/idempotency/exceptions.py b/aws_lambda_powertools/utilities/idempotency/exceptions.py index e4c57a8f2b6..55ec662799e 100644 --- a/aws_lambda_powertools/utilities/idempotency/exceptions.py +++ b/aws_lambda_powertools/utilities/idempotency/exceptions.py @@ -5,6 +5,8 @@ from typing import Optional, Union +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import DataRecord + class BaseError(Exception): """ @@ -30,6 +32,18 @@ class IdempotencyItemAlreadyExistsError(BaseError): Item attempting to be inserted into persistence store already exists and is not expired """ + def __init__(self, *args: Optional[Union[str, Exception]], old_data_record: Optional[DataRecord] = None): + self.old_data_record = old_data_record + super().__init__(*args) + + def __str__(self): + """ + Return all arguments formatted or original message + """ + old_data_record = f" from [{(str(self.old_data_record))}]" if self.old_data_record else "" + message = super().__str__() + return f"{message}{old_data_record}" + class IdempotencyItemNotFoundError(BaseError): """ diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index f3b12da0310..335c7ecc9fb 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -8,8 +8,7 @@ import os import warnings from abc import ABC, abstractmethod -from types import MappingProxyType -from typing import Any, Dict, Optional +from typing import Any, Dict, Optional, Union import jmespath @@ -18,95 +17,18 @@ from aws_lambda_powertools.shared.json_encoder import Encoder from aws_lambda_powertools.utilities.idempotency.config import IdempotencyConfig from aws_lambda_powertools.utilities.idempotency.exceptions import ( - IdempotencyInvalidStatusError, IdempotencyItemAlreadyExistsError, IdempotencyKeyError, IdempotencyValidationError, ) +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( + STATUS_CONSTANTS, + DataRecord, +) from aws_lambda_powertools.utilities.jmespath_utils import PowertoolsFunctions logger = logging.getLogger(__name__) -STATUS_CONSTANTS = MappingProxyType({"INPROGRESS": "INPROGRESS", "COMPLETED": "COMPLETED", "EXPIRED": "EXPIRED"}) - - -class DataRecord: - """ - Data Class for idempotency records. - """ - - def __init__( - self, - idempotency_key: str, - status: str = "", - expiry_timestamp: Optional[int] = None, - in_progress_expiry_timestamp: Optional[int] = None, - response_data: str = "", - payload_hash: str = "", - ) -> None: - """ - - Parameters - ---------- - idempotency_key: str - hashed representation of the idempotent data - status: str, optional - status of the idempotent record - expiry_timestamp: int, optional - time before the record should expire, in seconds - in_progress_expiry_timestamp: int, optional - time before the record should expire while in the INPROGRESS state, in seconds - payload_hash: str, optional - hashed representation of payload - response_data: str, optional - response data from previous executions using the record - """ - self.idempotency_key = idempotency_key - self.payload_hash = payload_hash - self.expiry_timestamp = expiry_timestamp - self.in_progress_expiry_timestamp = in_progress_expiry_timestamp - self._status = status - self.response_data = response_data - - @property - def is_expired(self) -> bool: - """ - Check if data record is expired - - Returns - ------- - bool - Whether the record is currently expired or not - """ - return bool(self.expiry_timestamp and int(datetime.datetime.now().timestamp()) > self.expiry_timestamp) - - @property - def status(self) -> str: - """ - Get status of data record - - Returns - ------- - str - """ - if self.is_expired: - return STATUS_CONSTANTS["EXPIRED"] - elif self._status in STATUS_CONSTANTS.values(): - return self._status - else: - raise IdempotencyInvalidStatusError(self._status) - - def response_json_as_dict(self) -> Optional[dict]: - """ - Get response data deserialized to python dict - - Returns - ------- - Optional[dict] - previous response data deserialized - """ - return json.loads(self.response_data) if self.response_data else None - class BasePersistenceLayer(ABC): """ @@ -238,16 +160,20 @@ def _generate_hash(self, data: Any) -> str: hashed_data = self.hash_function(json.dumps(data, cls=Encoder, sort_keys=True).encode()) return hashed_data.hexdigest() - def _validate_payload(self, data: Dict[str, Any], data_record: DataRecord) -> None: + def _validate_payload( + self, + data_payload: Union[Dict[str, Any], DataRecord], + stored_data_record: DataRecord, + ) -> None: """ Validate that the hashed payload matches data provided and stored data record Parameters ---------- - data: Dict[str, Any] + data_payload: Union[Dict[str, Any], DataRecord] Payload - data_record: DataRecord - DataRecord instance + stored_data_record: DataRecord + DataRecord fetched from Dynamo or cache Raises ---------- @@ -256,8 +182,12 @@ def _validate_payload(self, data: Dict[str, Any], data_record: DataRecord) -> No """ if self.payload_validation_enabled: - data_hash = self._get_hashed_payload(data=data) - if data_record.payload_hash != data_hash: + if isinstance(data_payload, DataRecord): + data_hash = data_payload.payload_hash + else: + data_hash = self._get_hashed_payload(data=data_payload) + + if stored_data_record.payload_hash != data_hash: raise IdempotencyValidationError("Payload does not match stored record for this event key") def _get_expiry_timestamp(self) -> int: @@ -448,14 +378,14 @@ def get_record(self, data: Dict[str, Any]) -> Optional[DataRecord]: cached_record = self._retrieve_from_cache(idempotency_key=idempotency_key) if cached_record: logger.debug(f"Idempotency record found in cache with idempotency key: {idempotency_key}") - self._validate_payload(data=data, data_record=cached_record) + self._validate_payload(data_payload=data, stored_data_record=cached_record) return cached_record record = self._get_record(idempotency_key=idempotency_key) self._save_to_cache(data_record=record) - self._validate_payload(data=data, data_record=record) + self._validate_payload(data_payload=data, stored_data_record=record) return record @abstractmethod diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py b/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py new file mode 100644 index 00000000000..607e238c3a0 --- /dev/null +++ b/aws_lambda_powertools/utilities/idempotency/persistence/datarecord.py @@ -0,0 +1,93 @@ +""" +Data Class for idempotency records. +""" + +import datetime +import json +import logging +from types import MappingProxyType +from typing import Optional + +logger = logging.getLogger(__name__) + +STATUS_CONSTANTS = MappingProxyType({"INPROGRESS": "INPROGRESS", "COMPLETED": "COMPLETED", "EXPIRED": "EXPIRED"}) + + +class DataRecord: + """ + Data Class for idempotency records. + """ + + def __init__( + self, + idempotency_key: str, + status: str = "", + expiry_timestamp: Optional[int] = None, + in_progress_expiry_timestamp: Optional[int] = None, + response_data: str = "", + payload_hash: str = "", + ) -> None: + """ + + Parameters + ---------- + idempotency_key: str + hashed representation of the idempotent data + status: str, optional + status of the idempotent record + expiry_timestamp: int, optional + time before the record should expire, in seconds + in_progress_expiry_timestamp: int, optional + time before the record should expire while in the INPROGRESS state, in seconds + payload_hash: str, optional + hashed representation of payload + response_data: str, optional + response data from previous executions using the record + """ + self.idempotency_key = idempotency_key + self.payload_hash = payload_hash + self.expiry_timestamp = expiry_timestamp + self.in_progress_expiry_timestamp = in_progress_expiry_timestamp + self._status = status + self.response_data = response_data + + @property + def is_expired(self) -> bool: + """ + Check if data record is expired + + Returns + ------- + bool + Whether the record is currently expired or not + """ + return bool(self.expiry_timestamp and int(datetime.datetime.now().timestamp()) > self.expiry_timestamp) + + @property + def status(self) -> str: + """ + Get status of data record + + Returns + ------- + str + """ + if self.is_expired: + return STATUS_CONSTANTS["EXPIRED"] + if self._status in STATUS_CONSTANTS.values(): + return self._status + + from aws_lambda_powertools.utilities.idempotency.exceptions import IdempotencyInvalidStatusError + + raise IdempotencyInvalidStatusError(self._status) + + def response_json_as_dict(self) -> Optional[dict]: + """ + Get response data deserialized to python dict + + Returns + ------- + Optional[dict] + previous response data deserialized + """ + return json.loads(self.response_data) if self.response_data else None diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 913e88524e2..6cb86121092 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -15,8 +15,9 @@ from aws_lambda_powertools.utilities.idempotency.exceptions import ( IdempotencyItemAlreadyExistsError, IdempotencyItemNotFoundError, + IdempotencyValidationError, ) -from aws_lambda_powertools.utilities.idempotency.persistence.base import ( +from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import ( STATUS_CONSTANTS, DataRecord, ) @@ -114,6 +115,14 @@ def __init__( self.data_attr = data_attr self.validation_key_attr = validation_key_attr + # Use DynamoDB's ReturnValuesOnConditionCheckFailure to optimize put and get operations and optimize costs. + # This feature is supported in boto3 versions 1.26.164 and later. + self.return_value_on_condition = ( + {"ReturnValuesOnConditionCheckFailure": "ALL_OLD"} + if self.boto3_supports_condition_check_failure(boto3.__version__) + else {} + ) + self._deserializer = TypeDeserializer() super(DynamoDBPersistenceLayer, self).__init__() @@ -221,6 +230,7 @@ def _put_record(self, data_record: DataRecord) -> None: condition_expression = ( f"{idempotency_key_not_exist} OR {idempotency_expiry_expired} OR ({inprogress_expiry_expired})" ) + self.client.put_item( TableName=self.table_name, Item=item, @@ -236,16 +246,53 @@ def _put_record(self, data_record: DataRecord) -> None: ":now_in_millis": {"N": str(int(now.timestamp() * 1000))}, ":inprogress": {"S": STATUS_CONSTANTS["INPROGRESS"]}, }, + **self.return_value_on_condition, # type: ignore ) except ClientError as exc: error_code = exc.response.get("Error", {}).get("Code") if error_code == "ConditionalCheckFailedException": + old_data_record = self._item_to_data_record(exc.response["Item"]) if "Item" in exc.response else None + if old_data_record is not None: + logger.debug( + f"Failed to put record for already existing idempotency key: " + f"{data_record.idempotency_key} with status: {old_data_record.status}, " + f"expiry_timestamp: {old_data_record.expiry_timestamp}, " + f"and in_progress_expiry_timestamp: {old_data_record.in_progress_expiry_timestamp}", + ) + self._save_to_cache(data_record=old_data_record) + + try: + self._validate_payload(data_payload=data_record, stored_data_record=old_data_record) + except IdempotencyValidationError as idempotency_validation_error: + raise idempotency_validation_error from exc + + raise IdempotencyItemAlreadyExistsError(old_data_record=old_data_record) from exc + logger.debug( f"Failed to put record for already existing idempotency key: {data_record.idempotency_key}", ) - raise IdempotencyItemAlreadyExistsError from exc - else: - raise + raise IdempotencyItemAlreadyExistsError() from exc + + raise + + @staticmethod + def boto3_supports_condition_check_failure(boto3_version: str) -> bool: + """ + Check if the installed boto3 version supports condition check failure. + + Params + ------ + boto3_version: str + The boto3 version + + Returns + ------- + bool + True if the boto3 version supports condition check failure, False otherwise. + """ + # Only supported in boto3 1.26.164 and above + major, minor, *patch = map(int, boto3_version.split(".")) + return (major, minor, *patch) >= (1, 26, 164) def _update_record(self, data_record: DataRecord): logger.debug(f"Updating record for idempotency key: {data_record.idempotency_key}") diff --git a/docs/media/idempotency_first_execution.png b/docs/media/idempotency_first_execution.png new file mode 100644 index 0000000000000000000000000000000000000000..23d185bbf6f3dab97cea2c1b8c60711c2bbdb576 GIT binary patch literal 95197 zcmeFZ2UOF|);Agz5fDVG0)hew5FjX_N%a9jAfcI1giw5d5Fm5}6tFxhy$A^*5UM}| zgeHWJU_nZNAT5AYr7F#W9Yw$Rp7%V@`M&QxXWjRH_pWvCT4!hF|NmuX{xh@pOlJ1% z+4KMT?B@%>Q6wAz2khGi0PN#@06&-ZJwuq9UObPsg(IxY{uaRmaER*+01y}y9)>nI zIpySxId$m8-=6pt=izlJb(kIM@9+900IW4gd%^0{|i;005uMf5dSv|DliSd{_TxrQ?h>4Gf6?Dd=G^z~=Q?nZ z6J;RutEByh4j%f&_J5?=w_ivEb%0A)R-N!x)YzkVR1R$ydXu<#Q0y_Z{++yuX9*Cb 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 A0ssI2 literal 0 HcmV?d00001 diff --git a/docs/media/idempotency_second_execution.png b/docs/media/idempotency_second_execution.png new file mode 100644 index 0000000000000000000000000000000000000000..32ecb13ef0ff68fca43e68c6431239292547f141 GIT binary patch literal 90457 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 y;R1fgLXt1K0pdufr%ScXxZ2Me-i*421`@` literal 0 HcmV?d00001 diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index 3b7fe344b1c..bc355580935 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -102,12 +102,16 @@ If you're not [changing the default configuration for the DynamoDB persistence l Larger items cannot be written to DynamoDB and will cause exceptions. If your response exceeds 400kb, consider using Redis as your persistence layer. + ???+ info "Info: DynamoDB" - Each function invocation will generally make 2 requests to DynamoDB. If the - result returned by your Lambda is less than 1kb, you can expect 2 WCUs per invocation. For retried invocations, you will - see 1WCU and 1RCU. Review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to - estimate the cost. + During the first invocation with a payload, the Lambda function executes both a `PutItem` and an `UpdateItem` operations to store the data in DynamoDB. If the result returned by your Lambda is less than 1kb, you can expect 2 WCUs per Lambda invocation. + + On subsequent invocations with the same payload, you can expect just 1 `PutItem` request to DynamoDB. + + **Note:** While we try to minimize requests to DynamoDB to 1 per invocation, if your boto3 version is lower than `1.26.194`, you may experience 2 requests in every invocation. Ensure to check your boto3 version and review the [DynamoDB pricing documentation](https://aws.amazon.com/dynamodb/pricing/){target="_blank"} to estimate the cost. + + ### Idempotent decorator You can quickly start by initializing the `DynamoDBPersistenceLayer` class and using it with the `idempotent` decorator on your lambda handler. @@ -936,6 +940,24 @@ The idempotency utility can be used with the `validator` decorator. Ensure that ???+ tip "Tip: JMESPath Powertools for AWS Lambda (Python) functions are also available" Built-in functions known in the validation utility like `powertools_json`, `powertools_base64`, `powertools_base64_gzip` are also available to use in this utility. +### Tracer + +The idempotency utility can be used with the `tracer` decorator. Ensure that idempotency is the innermost decorator. + +#### First execution + +During the first execution with a payload, Lambda performs a `PutItem` followed by an `UpdateItem` operation to persist the record in DynamoDB. + +![Tracer showcase](../media/idempotency_first_execution.png) + +#### Subsequent executions + +On subsequent executions with the same payload, Lambda optimistically tries to save the record in DynamoDB. If the record already exists, DynamoDB returns the item. + +Explore how to handle conditional write errors in high-concurrency scenarios with DynamoDB in this [blog post](https://aws.amazon.com/pt/blogs/database/handle-conditional-write-errors-in-high-concurrency-scenarios-with-amazon-dynamodb/){target="_blank"}. + +![Tracer showcase](../media/idempotency_second_execution.png) + ## Testing your code The idempotency utility provides several routes to test your code. diff --git a/tests/functional/idempotency/conftest.py b/tests/functional/idempotency/conftest.py index 9bacfb58779..f8d48cd7da2 100644 --- a/tests/functional/idempotency/conftest.py +++ b/tests/functional/idempotency/conftest.py @@ -131,6 +131,7 @@ def expected_params_put_item(hashed_idempotency_key): "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", @@ -159,6 +160,7 @@ def expected_params_put_item_with_validation(hashed_idempotency_key, hashed_vali "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 24fcd76b4d5..905248011e6 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -87,14 +87,7 @@ def test_idempotent_lambda_already_completed( "status": {"S": "COMPLETED"}, }, } - - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -124,11 +117,6 @@ def test_idempotent_lambda_in_progress( stubber = stub.Stubber(persistence_store.client) - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } ddb_response = { "Item": { "id": {"S": hashed_idempotency_key}, @@ -137,8 +125,7 @@ def test_idempotent_lambda_in_progress( }, } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -176,11 +163,6 @@ def test_idempotent_lambda_in_progress_with_cache( retrieve_from_cache_spy = mocker.spy(persistence_store, "_retrieve_from_cache") stubber = stub.Stubber(persistence_store.client) - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } ddb_response = { "Item": { "id": {"S": hashed_idempotency_key}, @@ -189,14 +171,12 @@ def test_idempotent_lambda_in_progress_with_cache( }, } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", copy.deepcopy(ddb_response), copy.deepcopy(expected_params)) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=copy.deepcopy(ddb_response)) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=copy.deepcopy(ddb_response)) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", copy.deepcopy(ddb_response), copy.deepcopy(expected_params)) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -212,7 +192,7 @@ def lambda_handler(event, context): "body=a3edd699125517bb49d562501179ecbd" ) - assert retrieve_from_cache_spy.call_count == 2 * loops + assert retrieve_from_cache_spy.call_count == loops retrieve_from_cache_spy.assert_called_with(idempotency_key=hashed_idempotency_key) save_to_cache_spy.assert_called() @@ -411,7 +391,6 @@ def lambda_handler(event, context): "idempotency_config", [ {"use_local_cache": False, "payload_validation_jmespath": "requestContext"}, - {"use_local_cache": True, "payload_validation_jmespath": "requestContext"}, ], indirect=True, ) @@ -439,11 +418,7 @@ def test_idempotent_lambda_already_completed_with_validation_bad_payload( "validation": {"S": hashed_validation_key}, }, } - - expected_params = {"TableName": TABLE_NAME, "Key": {"id": {"S": hashed_idempotency_key}}, "ConsistentRead": True} - - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store) @@ -466,6 +441,7 @@ def test_idempotent_lambda_expired_during_request( timestamp_expired, lambda_response, hashed_idempotency_key, + mocker, lambda_context, ): """ @@ -502,6 +478,9 @@ def test_idempotent_lambda_expired_during_request( stubber.activate() + submethod_mocked = mocker.patch.object(persistence_store, "boto3_supports_condition_check_failure") + submethod_mocked.return_value = False + @idempotent(config=idempotency_config, persistence_store=persistence_store) def lambda_handler(event, context): return lambda_response @@ -514,6 +493,55 @@ def lambda_handler(event, context): stubber.deactivate() +@pytest.mark.parametrize( + "idempotency_config", + [{"use_local_cache": True, "payload_validation_jmespath": "requestContext"}], + indirect=True, +) +def test_idempotent_lambda_already_completed_with_validation_bad_payload_from_local_cache( + idempotency_config: IdempotencyConfig, + persistence_store: DynamoDBPersistenceLayer, + lambda_apigw_event, + timestamp_future, + lambda_response, + hashed_idempotency_key, + hashed_validation_key, + lambda_context, +): + """ + Test idempotent decorator where event with matching event key has already been successfully processed + Fetching record from local cache + """ + + stubber = stub.Stubber(persistence_store.client) + ddb_response = { + "Item": { + "id": {"S": hashed_idempotency_key}, + "expiration": {"N": timestamp_future}, + "data": {"S": '{"message": "test", "statusCode": 200}'}, + "status": {"S": "COMPLETED"}, + "validation": {"S": hashed_validation_key}, + }, + } + + expected_params = {"TableName": TABLE_NAME, "Key": {"id": {"S": hashed_idempotency_key}}, "ConsistentRead": True} + + stubber.add_client_error("put_item", "ConditionalCheckFailedException") + stubber.add_response("get_item", ddb_response, expected_params) + stubber.activate() + + @idempotent(config=idempotency_config, persistence_store=persistence_store) + def lambda_handler(event, context): + return lambda_response + + with pytest.raises(IdempotencyValidationError): + lambda_apigw_event["requestContext"]["accountId"] += "1" # Alter the request payload + lambda_handler(lambda_apigw_event, lambda_context) + + stubber.assert_no_pending_responses() + stubber.deactivate() + + @pytest.mark.parametrize("idempotency_config", [{"use_local_cache": False}, {"use_local_cache": True}], indirect=True) def test_idempotent_persistence_exception_deleting( idempotency_config: IdempotencyConfig, @@ -675,13 +703,7 @@ def test_idempotent_lambda_with_validator_util( }, } - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": hashed_idempotency_key_with_envelope}}, - "ConsistentRead": True, - } - stubber.add_client_error("put_item", "ConditionalCheckFailedException") - stubber.add_response("get_item", ddb_response, expected_params) + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @validator(envelope=envelopes.API_GATEWAY_HTTP) @@ -1791,7 +1813,6 @@ def test_idempotent_lambda_compound_already_completed( """ stubber = stub.Stubber(persistence_store_compound.client) - stubber.add_client_error("put_item", "ConditionalCheckFailedException") ddb_response = { "Item": { "id": {"S": "idempotency#"}, @@ -1801,13 +1822,7 @@ def test_idempotent_lambda_compound_already_completed( "status": {"S": "COMPLETED"}, }, } - expected_params = { - "TableName": TABLE_NAME, - "Key": {"id": {"S": "idempotency#"}, "sk": {"S": hashed_idempotency_key}}, - "ConsistentRead": True, - } - stubber.add_response("get_item", ddb_response, expected_params) - + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) stubber.activate() @idempotent(config=idempotency_config, persistence_store=persistence_store_compound) diff --git a/tests/functional/idempotency/utils.py b/tests/functional/idempotency/utils.py index bf57259fe76..60f28b075b6 100644 --- a/tests/functional/idempotency/utils.py +++ b/tests/functional/idempotency/utils.py @@ -26,6 +26,7 @@ def build_idempotency_put_item_stub( "attribute_not_exists(#id) OR #expiry < :now OR " "(#status = :inprogress AND attribute_exists(#in_progress_expiry) AND #in_progress_expiry < :now_in_millis)" ), + "ReturnValuesOnConditionCheckFailure": "ALL_OLD", "ExpressionAttributeNames": { "#id": "id", "#expiry": "expiration", diff --git a/tests/unit/idempotency/test_dynamodb_persistence.py b/tests/unit/idempotency/test_dynamodb_persistence.py index 9455c41ad8d..b27ef00550c 100644 --- a/tests/unit/idempotency/test_dynamodb_persistence.py +++ b/tests/unit/idempotency/test_dynamodb_persistence.py @@ -19,3 +19,14 @@ class DummyClient: # THEN assert persistence_layer.table_name == table_name assert persistence_layer.client == fake_client + + +def test_boto3_version_supports_condition_check_failure(): + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("0.0.3") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.25") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.25") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.163") is False + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.164") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.26.165") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("1.27.0") is True + assert DynamoDBPersistenceLayer.boto3_supports_condition_check_failure("2.0.0") is True From fb786c713fa96e35d0205145cf5e03a403f5fd8f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 13:59:00 +0000 Subject: [PATCH 0012/2666] chore(ci): bump version to 2.32.0 (#3653) Co-authored-by: Powertools for AWS Lambda (Python) bot --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index 2a25f6a0cb5..adcf3dc5272 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.31.0" +VERSION = "2.32.0" diff --git a/pyproject.toml b/pyproject.toml index af55ba1cfff..23b81905431 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.31.0" +version = "2.32.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"] From acdf1ab1014ef7df8499a80f6747e322b9832382 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 19 Jan 2024 14:01:10 +0000 Subject: [PATCH 0013/2666] chore(ci): layer docs update (#3654) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 38 ++------ docs/index.md | 142 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 5 files changed, 80 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7fdb78d7b88..b8442ea037e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,43 +4,16 @@ # Unreleased -## Bug Fixes - -* **event_handler:** escape OpenAPI schema on Swagger UI ([#3606](https://github.com/aws-powertools/powertools-lambda-python/issues/3606)) - -## Code Refactoring - -* **event-handler:** Inject CSS and JS files into SwaggerUI route when no custom CDN is used. ([#3562](https://github.com/aws-powertools/powertools-lambda-python/issues/3562)) -* **event_handler:** fix BedrockAgentResolver docstring ([#3645](https://github.com/aws-powertools/powertools-lambda-python/issues/3645)) - -## Documentation - -* **homepage:** add banner about Python 3.7 deprecation ([#3618](https://github.com/aws-powertools/powertools-lambda-python/issues/3618)) -* **i-made-this:** added new article on how to create a serverless API with CDK and Powertools ([#3605](https://github.com/aws-powertools/powertools-lambda-python/issues/3605)) + +## [v2.32.0] - 2024-01-19 ## Features -* **event_handler:** add support for additional response models ([#3591](https://github.com/aws-powertools/powertools-lambda-python/issues/3591)) -* **event_handler:** add support to download OpenAPI spec file ([#3571](https://github.com/aws-powertools/powertools-lambda-python/issues/3571)) -* **event_source:** Add support for S3 batch operations ([#3572](https://github.com/aws-powertools/powertools-lambda-python/issues/3572)) -* **event_source:** Add support for policyLevel field in CloudWatch Logs event and parser ([#3624](https://github.com/aws-powertools/powertools-lambda-python/issues/3624)) -* **idempotency:** adding redis as idempotency backend ([#2567](https://github.com/aws-powertools/powertools-lambda-python/issues/2567)) +* **idempotency:** leverage new DynamoDB Failed conditional writes behavior with ReturnValuesOnConditionCheckFailure ([#3446](https://github.com/aws-powertools/powertools-lambda-python/issues/3446)) ## Maintenance -* **ci:** update boto3 library version to 1.26.164+ ([#3632](https://github.com/aws-powertools/powertools-lambda-python/issues/3632)) -* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) -* **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3639](https://github.com/aws-powertools/powertools-lambda-python/issues/3639)) -* **deps:** bump gitpython from 3.1.37 to 3.1.41 in /docs ([#3610](https://github.com/aws-powertools/powertools-lambda-python/issues/3610)) -* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) -* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) -* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) -* **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) -* **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) -* **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) -* **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) -* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) +* version bump @@ -4268,7 +4241,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.31.0...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...HEAD +[v2.32.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.31.0...v2.32.0 [v2.31.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.2...v2.31.0 [v2.30.2]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.1...v2.30.2 [v2.30.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.0...v2.30.1 diff --git a/docs/index.md b/docs/index.md index a298004d5f0..7f1ca98fb74 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverles You can install Powertools for AWS Lambda (Python) using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** !!! question "Looking for Pip signed releases? [Learn more about verifying signed builds](./security.md#verifying-signed-builds)" @@ -80,67 +80,67 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:59](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -153,7 +153,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 ``` === "Serverless framework" @@ -163,7 +163,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 ``` === "CDK" @@ -179,7 +179,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -228,7 +228,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -281,7 +281,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd ? 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:AWSLambdaPowertoolsPythonV2:59 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 ❯ amplify push -y @@ -292,7 +292,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd - 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:AWSLambdaPowertoolsPythonV2:59 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 ? Do you want to edit the local lambda function now? No ``` @@ -306,7 +306,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 ``` === "Serverless framework" @@ -317,7 +317,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 ``` === "CDK" @@ -333,7 +333,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -383,7 +383,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:59"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -439,7 +439,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd ? 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:AWSLambdaPowertoolsPythonV2-Arm64:59 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 ❯ amplify push -y @@ -450,7 +450,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd - 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:AWSLambdaPowertoolsPythonV2-Arm64:59 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 ? Do you want to edit the local lambda function now? No ``` @@ -458,7 +458,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:59 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index d3fc453e09a..9440f37c48f 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:AWSLambdaPowertoolsPythonV2:59 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 38e78ce18a1..e479ef1732a 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,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:AWSLambdaPowertoolsPythonV2:59 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index ac9bcf6f4d8..e48d27a75ea 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:AWSLambdaPowertoolsPythonV2:59 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 Resources: CaptureLambdaHandlerExample: From 5e8937903b700db58ac74df14f88a4d0cb201a88 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:30:04 +0000 Subject: [PATCH 0014/2666] chore(deps): bump pydantic from 1.10.13 to 1.10.14 (#3655) Bumps [pydantic](https://github.com/pydantic/pydantic) from 1.10.13 to 1.10.14. - [Release notes](https://github.com/pydantic/pydantic/releases) - [Changelog](https://github.com/pydantic/pydantic/blob/v1.10.14/HISTORY.md) - [Commits](https://github.com/pydantic/pydantic/compare/v1.10.13...v1.10.14) --- updated-dependencies: - dependency-name: pydantic dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 122 ++++++++++++++++++++++++++++++---------------------- 1 file changed, 70 insertions(+), 52 deletions(-) diff --git a/poetry.lock b/poetry.lock index ab030247828..5bc2291b907 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "anyio" @@ -1250,6 +1250,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1626,6 +1637,16 @@ files = [ {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, + {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, @@ -2207,47 +2228,47 @@ files = [ [[package]] name = "pydantic" -version = "1.10.13" +version = "1.10.14" description = "Data validation and settings management using python type hints" optional = false python-versions = ">=3.7" files = [ - {file = "pydantic-1.10.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:efff03cc7a4f29d9009d1c96ceb1e7a70a65cfe86e89d34e4a5f2ab1e5693737"}, - {file = "pydantic-1.10.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3ecea2b9d80e5333303eeb77e180b90e95eea8f765d08c3d278cd56b00345d01"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1740068fd8e2ef6eb27a20e5651df000978edce6da6803c2bef0bc74540f9548"}, - {file = "pydantic-1.10.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:84bafe2e60b5e78bc64a2941b4c071a4b7404c5c907f5f5a99b0139781e69ed8"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:bc0898c12f8e9c97f6cd44c0ed70d55749eaf783716896960b4ecce2edfd2d69"}, - {file = "pydantic-1.10.13-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:654db58ae399fe6434e55325a2c3e959836bd17a6f6a0b6ca8107ea0571d2e17"}, - {file = "pydantic-1.10.13-cp310-cp310-win_amd64.whl", hash = "sha256:75ac15385a3534d887a99c713aa3da88a30fbd6204a5cd0dc4dab3d770b9bd2f"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c553f6a156deb868ba38a23cf0df886c63492e9257f60a79c0fd8e7173537653"}, - {file = "pydantic-1.10.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5e08865bc6464df8c7d61439ef4439829e3ab62ab1669cddea8dd00cd74b9ffe"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e31647d85a2013d926ce60b84f9dd5300d44535a9941fe825dc349ae1f760df9"}, - {file = "pydantic-1.10.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:210ce042e8f6f7c01168b2d84d4c9eb2b009fe7bf572c2266e235edf14bacd80"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:8ae5dd6b721459bfa30805f4c25880e0dd78fc5b5879f9f7a692196ddcb5a580"}, - {file = "pydantic-1.10.13-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8e81fc5fb17dae698f52bdd1c4f18b6ca674d7068242b2aff075f588301bbb0"}, - {file = "pydantic-1.10.13-cp311-cp311-win_amd64.whl", hash = "sha256:61d9dce220447fb74f45e73d7ff3b530e25db30192ad8d425166d43c5deb6df0"}, - {file = "pydantic-1.10.13-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4b03e42ec20286f052490423682016fd80fda830d8e4119f8ab13ec7464c0132"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f59ef915cac80275245824e9d771ee939133be38215555e9dc90c6cb148aaeb5"}, - {file = "pydantic-1.10.13-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a1f9f747851338933942db7af7b6ee8268568ef2ed86c4185c6ef4402e80ba8"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:97cce3ae7341f7620a0ba5ef6cf043975cd9d2b81f3aa5f4ea37928269bc1b87"}, - {file = "pydantic-1.10.13-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:854223752ba81e3abf663d685f105c64150873cc6f5d0c01d3e3220bcff7d36f"}, - {file = "pydantic-1.10.13-cp37-cp37m-win_amd64.whl", hash = "sha256:b97c1fac8c49be29486df85968682b0afa77e1b809aff74b83081cc115e52f33"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c958d053453a1c4b1c2062b05cd42d9d5c8eb67537b8d5a7e3c3032943ecd261"}, - {file = "pydantic-1.10.13-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4c5370a7edaac06daee3af1c8b1192e305bc102abcbf2a92374b5bc793818599"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d6f6e7305244bddb4414ba7094ce910560c907bdfa3501e9db1a7fd7eaea127"}, - {file = "pydantic-1.10.13-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d3a3c792a58e1622667a2837512099eac62490cdfd63bd407993aaf200a4cf1f"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c636925f38b8db208e09d344c7aa4f29a86bb9947495dd6b6d376ad10334fb78"}, - {file = "pydantic-1.10.13-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:678bcf5591b63cc917100dc50ab6caebe597ac67e8c9ccb75e698f66038ea953"}, - {file = "pydantic-1.10.13-cp38-cp38-win_amd64.whl", hash = "sha256:6cf25c1a65c27923a17b3da28a0bdb99f62ee04230c931d83e888012851f4e7f"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8ef467901d7a41fa0ca6db9ae3ec0021e3f657ce2c208e98cd511f3161c762c6"}, - {file = "pydantic-1.10.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:968ac42970f57b8344ee08837b62f6ee6f53c33f603547a55571c954a4225691"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9849f031cf8a2f0a928fe885e5a04b08006d6d41876b8bbd2fc68a18f9f2e3fd"}, - {file = "pydantic-1.10.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:56e3ff861c3b9c6857579de282ce8baabf443f42ffba355bf070770ed63e11e1"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f00790179497767aae6bcdc36355792c79e7bbb20b145ff449700eb076c5f96"}, - {file = "pydantic-1.10.13-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:75b297827b59bc229cac1a23a2f7a4ac0031068e5be0ce385be1462e7e17a35d"}, - {file = "pydantic-1.10.13-cp39-cp39-win_amd64.whl", hash = "sha256:e70ca129d2053fb8b728ee7d1af8e553a928d7e301a311094b8a0501adc8763d"}, - {file = "pydantic-1.10.13-py3-none-any.whl", hash = "sha256:b87326822e71bd5f313e7d3bfdc77ac3247035ac10b0c0618bd99dcf95b1e687"}, - {file = "pydantic-1.10.13.tar.gz", hash = "sha256:32c8b48dcd3b2ac4e78b0ba4af3a2c2eb6048cb75202f0ea7b34feb740efc340"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7f4fcec873f90537c382840f330b90f4715eebc2bc9925f04cb92de593eae054"}, + {file = "pydantic-1.10.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e3a76f571970fcd3c43ad982daf936ae39b3e90b8a2e96c04113a369869dc87"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d886bd3c3fbeaa963692ef6b643159ccb4b4cefaf7ff1617720cbead04fd1d"}, + {file = "pydantic-1.10.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:798a3d05ee3b71967844a1164fd5bdb8c22c6d674f26274e78b9f29d81770c4e"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:23d47a4b57a38e8652bcab15a658fdb13c785b9ce217cc3a729504ab4e1d6bc9"}, + {file = "pydantic-1.10.14-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:f9f674b5c3bebc2eba401de64f29948ae1e646ba2735f884d1594c5f675d6f2a"}, + {file = "pydantic-1.10.14-cp310-cp310-win_amd64.whl", hash = "sha256:24a7679fab2e0eeedb5a8924fc4a694b3bcaac7d305aeeac72dd7d4e05ecbebf"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9d578ac4bf7fdf10ce14caba6f734c178379bd35c486c6deb6f49006e1ba78a7"}, + {file = "pydantic-1.10.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa7790e94c60f809c95602a26d906eba01a0abee9cc24150e4ce2189352deb1b"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad4e10efa5474ed1a611b6d7f0d130f4aafadceb73c11d9e72823e8f508e663"}, + {file = "pydantic-1.10.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245f4f61f467cb3dfeced2b119afef3db386aec3d24a22a1de08c65038b255f"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:21efacc678a11114c765eb52ec0db62edffa89e9a562a94cbf8fa10b5db5c046"}, + {file = "pydantic-1.10.14-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:412ab4a3f6dbd2bf18aefa9f79c7cca23744846b31f1d6555c2ee2b05a2e14ca"}, + {file = "pydantic-1.10.14-cp311-cp311-win_amd64.whl", hash = "sha256:e897c9f35281f7889873a3e6d6b69aa1447ceb024e8495a5f0d02ecd17742a7f"}, + {file = "pydantic-1.10.14-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:d604be0f0b44d473e54fdcb12302495fe0467c56509a2f80483476f3ba92b33c"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a42c7d17706911199798d4c464b352e640cab4351efe69c2267823d619a937e5"}, + {file = "pydantic-1.10.14-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:596f12a1085e38dbda5cbb874d0973303e34227b400b6414782bf205cc14940c"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bfb113860e9288d0886e3b9e49d9cf4a9d48b441f52ded7d96db7819028514cc"}, + {file = "pydantic-1.10.14-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:bc3ed06ab13660b565eed80887fcfbc0070f0aa0691fbb351657041d3e874efe"}, + {file = "pydantic-1.10.14-cp37-cp37m-win_amd64.whl", hash = "sha256:ad8c2bc677ae5f6dbd3cf92f2c7dc613507eafe8f71719727cbc0a7dec9a8c01"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c37c28449752bb1f47975d22ef2882d70513c546f8f37201e0fec3a97b816eee"}, + {file = "pydantic-1.10.14-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:49a46a0994dd551ec051986806122767cf144b9702e31d47f6d493c336462597"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:53e3819bd20a42470d6dd0fe7fc1c121c92247bca104ce608e609b59bc7a77ee"}, + {file = "pydantic-1.10.14-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbb503bbbbab0c588ed3cd21975a1d0d4163b87e360fec17a792f7d8c4ff29f"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:336709883c15c050b9c55a63d6c7ff09be883dbc17805d2b063395dd9d9d0022"}, + {file = "pydantic-1.10.14-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:4ae57b4d8e3312d486e2498d42aed3ece7b51848336964e43abbf9671584e67f"}, + {file = "pydantic-1.10.14-cp38-cp38-win_amd64.whl", hash = "sha256:dba49d52500c35cfec0b28aa8b3ea5c37c9df183ffc7210b10ff2a415c125c4a"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c66609e138c31cba607d8e2a7b6a5dc38979a06c900815495b2d90ce6ded35b4"}, + {file = "pydantic-1.10.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d986e115e0b39604b9eee3507987368ff8148222da213cd38c359f6f57b3b347"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:646b2b12df4295b4c3148850c85bff29ef6d0d9621a8d091e98094871a62e5c7"}, + {file = "pydantic-1.10.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282613a5969c47c83a8710cc8bfd1e70c9223feb76566f74683af889faadc0ea"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:466669501d08ad8eb3c4fecd991c5e793c4e0bbd62299d05111d4f827cded64f"}, + {file = "pydantic-1.10.14-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:13e86a19dca96373dcf3190fcb8797d40a6f12f154a244a8d1e8e03b8f280593"}, + {file = "pydantic-1.10.14-cp39-cp39-win_amd64.whl", hash = "sha256:08b6ec0917c30861e3fe71a93be1648a2aa4f62f866142ba21670b24444d7fd8"}, + {file = "pydantic-1.10.14-py3-none-any.whl", hash = "sha256:8ee853cd12ac2ddbf0ecbac1c289f95882b2d4482258048079d13be700aa114c"}, + {file = "pydantic-1.10.14.tar.gz", hash = "sha256:46f17b832fe27de7850896f3afee50ea682220dd218f7e9c88d436788419dca6"}, ] [package.dependencies] @@ -2528,6 +2549,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2535,8 +2557,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2553,6 +2583,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2560,6 +2591,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3112,20 +3144,6 @@ files = [ [package.dependencies] types-urllib3 = "*" -[[package]] -name = "types-requests" -version = "2.31.0.20231231" -description = "Typing stubs for requests" -optional = false -python-versions = ">=3.7" -files = [ - {file = "types-requests-2.31.0.20231231.tar.gz", hash = "sha256:0f8c0c9764773384122813548d9eea92a5c4e1f33ed54556b508968ec5065cee"}, - {file = "types_requests-2.31.0.20231231-py3-none-any.whl", hash = "sha256:2e2230c7bc8dd63fa3153c1c0ae335f8a368447f0582fc332f17d54f88e69027"}, -] - -[package.dependencies] -urllib3 = ">=2" - [[package]] name = "types-urllib3" version = "1.26.25.14" From 517acd6726ebf717a458846c59aeb1f247817ecb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:35:23 +0000 Subject: [PATCH 0015/2666] chore(deps-dev): bump ruff from 0.1.13 to 0.1.14 (#3656) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.13 to 0.1.14. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.13...v0.1.14) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 5bc2291b907..ec9ea847df8 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2801,28 +2801,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.1.13" +version = "0.1.14" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:e3fd36e0d48aeac672aa850045e784673449ce619afc12823ea7868fcc41d8ba"}, - {file = "ruff-0.1.13-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:9fb6b3b86450d4ec6a6732f9f60c4406061b6851c4b29f944f8c9d91c3611c7a"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b13ba5d7156daaf3fd08b6b993360a96060500aca7e307d95ecbc5bb47a69296"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9ebb40442f7b531e136d334ef0851412410061e65d61ca8ce90d894a094feb22"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:226b517f42d59a543d6383cfe03cccf0091e3e0ed1b856c6824be03d2a75d3b6"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5f0312ba1061e9b8c724e9a702d3c8621e3c6e6c2c9bd862550ab2951ac75c16"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2f59bcf5217c661254bd6bc42d65a6fd1a8b80c48763cb5c2293295babd945dd"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6894b00495e00c27b6ba61af1fc666f17de6140345e5ef27dd6e08fb987259d"}, - {file = "ruff-0.1.13-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1600942485c6e66119da294c6294856b5c86fd6df591ce293e4a4cc8e72989"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ee3febce7863e231a467f90e681d3d89210b900d49ce88723ce052c8761be8c7"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:dcaab50e278ff497ee4d1fe69b29ca0a9a47cd954bb17963628fa417933c6eb1"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_i686.whl", hash = "sha256:f57de973de4edef3ad3044d6a50c02ad9fc2dff0d88587f25f1a48e3f72edf5e"}, - {file = "ruff-0.1.13-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:7a36fa90eb12208272a858475ec43ac811ac37e91ef868759770b71bdabe27b6"}, - {file = "ruff-0.1.13-py3-none-win32.whl", hash = "sha256:a623349a505ff768dad6bd57087e2461be8db58305ebd5577bd0e98631f9ae69"}, - {file = "ruff-0.1.13-py3-none-win_amd64.whl", hash = "sha256:f988746e3c3982bea7f824c8fa318ce7f538c4dfefec99cd09c8770bd33e6539"}, - {file = "ruff-0.1.13-py3-none-win_arm64.whl", hash = "sha256:6bbbc3042075871ec17f28864808540a26f0f79a4478c357d3e3d2284e832998"}, - {file = "ruff-0.1.13.tar.gz", hash = "sha256:e261f1baed6291f434ffb1d5c6bd8051d1c2a26958072d38dfbec39b3dda7352"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:96f76536df9b26622755c12ed8680f159817be2f725c17ed9305b472a757cdbb"}, + {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab3f71f64498c7241123bb5a768544cf42821d2a537f894b22457a543d3ca7a9"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060156ecc572b8f984fd20fd8b0fcb692dd5d837b7606e968334ab7ff0090ab"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a53d8e35313d7b67eb3db15a66c08434809107659226a90dcd7acb2afa55faea"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea9be712b8f5b4ebed40e1949379cfb2a7d907f42921cf9ab3aae07e6fba9eb"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2270504d629a0b064247983cbc495bed277f372fb9eaba41e5cf51f7ba705a6a"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80258bb3b8909b1700610dfabef7876423eed1bc930fe177c71c414921898efa"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:653230dd00aaf449eb5ff25d10a6e03bc3006813e2cb99799e568f55482e5cae"}, + {file = "ruff-0.1.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b3acc6c4e6928459ba9eb7459dd4f0c4bf266a053c863d72a44c33246bfdbf"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b3dadc9522d0eccc060699a9816e8127b27addbb4697fc0c08611e4e6aeb8b5"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c8eca1a47b4150dc0fbec7fe68fc91c695aed798532a18dbb1424e61e9b721f"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:62ce2ae46303ee896fc6811f63d6dabf8d9c389da0f3e3f2bce8bc7f15ef5488"}, + {file = "ruff-0.1.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b2027dde79d217b211d725fc833e8965dc90a16d0d3213f1298f97465956661b"}, + {file = "ruff-0.1.14-py3-none-win32.whl", hash = "sha256:722bafc299145575a63bbd6b5069cb643eaa62546a5b6398f82b3e4403329cab"}, + {file = "ruff-0.1.14-py3-none-win_amd64.whl", hash = "sha256:e3d241aa61f92b0805a7082bd89a9990826448e4d0398f0e2bc8f05c75c63d99"}, + {file = "ruff-0.1.14-py3-none-win_arm64.whl", hash = "sha256:269302b31ade4cde6cf6f9dd58ea593773a37ed3f7b97e793c8594b262466b67"}, + {file = "ruff-0.1.14.tar.gz", hash = "sha256:ad3f8088b2dfd884820289a06ab718cde7d38b94972212cc4ba90d5fbc9955f3"}, ] [[package]] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "6871c1fdddbdf8dd05002be4feb639430863e3c51a00bfdcdead19f255ba0693" +content-hash = "10841362fd6d21eed52d656803e056dcba30a7835c5a00dda8275eaa4e1cc41c" diff --git a/pyproject.toml b/pyproject.toml index 23b81905431..7f04dba78a4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -109,7 +109,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.1.14" +ruff = ">=0.0.272,<0.1.15" retry2 = "^0.9.5" pytest-socket = "^0.6.0" types-redis = "^4.6.0.7" From a194cd2491c3c0d92d58f5cfe49645c042ea5464 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 21 Jan 2024 16:35:47 +0000 Subject: [PATCH 0016/2666] chore(ci): changelog rebuild (#3658) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8442ea037e..b28e62b3249 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,54 @@ # Unreleased +## Maintenance + + ## [v2.32.0] - 2024-01-19 +## Bug Fixes + +* **event_handler:** escape OpenAPI schema on Swagger UI ([#3606](https://github.com/aws-powertools/powertools-lambda-python/issues/3606)) + +## Code Refactoring + +* **event-handler:** Inject CSS and JS files into SwaggerUI route when no custom CDN is used. ([#3562](https://github.com/aws-powertools/powertools-lambda-python/issues/3562)) +* **event_handler:** fix BedrockAgentResolver docstring ([#3645](https://github.com/aws-powertools/powertools-lambda-python/issues/3645)) + +## Documentation + +* **homepage:** add banner about Python 3.7 deprecation ([#3618](https://github.com/aws-powertools/powertools-lambda-python/issues/3618)) +* **i-made-this:** added new article on how to create a serverless API with CDK and Powertools ([#3605](https://github.com/aws-powertools/powertools-lambda-python/issues/3605)) + ## Features +* **event_handler:** add support for additional response models ([#3591](https://github.com/aws-powertools/powertools-lambda-python/issues/3591)) +* **event_handler:** add support to download OpenAPI spec file ([#3571](https://github.com/aws-powertools/powertools-lambda-python/issues/3571)) +* **event_source:** Add support for S3 batch operations ([#3572](https://github.com/aws-powertools/powertools-lambda-python/issues/3572)) +* **event_source:** Add support for policyLevel field in CloudWatch Logs event and parser ([#3624](https://github.com/aws-powertools/powertools-lambda-python/issues/3624)) * **idempotency:** leverage new DynamoDB Failed conditional writes behavior with ReturnValuesOnConditionCheckFailure ([#3446](https://github.com/aws-powertools/powertools-lambda-python/issues/3446)) +* **idempotency:** adding redis as idempotency backend ([#2567](https://github.com/aws-powertools/powertools-lambda-python/issues/2567)) ## Maintenance * version bump +* **ci:** Disable Redis e2e until we drop Python 3.7 ([#3652](https://github.com/aws-powertools/powertools-lambda-python/issues/3652)) +* **ci:** update boto3 library version to 1.26.164+ ([#3632](https://github.com/aws-powertools/powertools-lambda-python/issues/3632)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3649](https://github.com/aws-powertools/powertools-lambda-python/issues/3649)) +* **deps:** bump jinja2 from 3.1.2 to 3.1.3 in /docs ([#3620](https://github.com/aws-powertools/powertools-lambda-python/issues/3620)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3639](https://github.com/aws-powertools/powertools-lambda-python/issues/3639)) +* **deps:** bump gitpython from 3.1.37 to 3.1.41 in /docs ([#3610](https://github.com/aws-powertools/powertools-lambda-python/issues/3610)) +* **deps:** bump squidfunk/mkdocs-material from `2f29d71` to `58eef6c` in /docs ([#3633](https://github.com/aws-powertools/powertools-lambda-python/issues/3633)) +* **deps:** bump redis from 4.6.0 to 5.0.1 ([#3613](https://github.com/aws-powertools/powertools-lambda-python/issues/3613)) +* **deps-dev:** bump gitpython from 3.1.40 to 3.1.41 ([#3611](https://github.com/aws-powertools/powertools-lambda-python/issues/3611)) +* **deps-dev:** bump sentry-sdk from 1.39.1 to 1.39.2 ([#3614](https://github.com/aws-powertools/powertools-lambda-python/issues/3614)) +* **deps-dev:** bump aws-cdk from 2.120.0 to 2.121.1 ([#3634](https://github.com/aws-powertools/powertools-lambda-python/issues/3634)) +* **deps-dev:** bump jinja2 from 3.1.2 to 3.1.3 ([#3619](https://github.com/aws-powertools/powertools-lambda-python/issues/3619)) +* **deps-dev:** bump cfn-lint from 0.83.7 to 0.83.8 ([#3603](https://github.com/aws-powertools/powertools-lambda-python/issues/3603)) +* **deps-dev:** bump aws-cdk from 2.121.1 to 2.122.0 ([#3648](https://github.com/aws-powertools/powertools-lambda-python/issues/3648)) +* **deps-dev:** bump ruff from 0.1.11 to 0.1.13 ([#3625](https://github.com/aws-powertools/powertools-lambda-python/issues/3625)) +* **deps-dev:** bump aws-cdk from 2.118.0 to 2.120.0 ([#3627](https://github.com/aws-powertools/powertools-lambda-python/issues/3627)) From 8b5341c38af6233c2d3e019c50891b31441ddf61 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 22 Jan 2024 09:04:00 +0000 Subject: [PATCH 0017/2666] chore(ci): changelog rebuild (#3659) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b28e62b3249..7b3370a95e0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ ## Maintenance +* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) From 2a509d0c32cde2fdbf50e76b6214e7419133ea15 Mon Sep 17 00:00:00 2001 From: Martti Aukia <122444627+maauk@users.noreply.github.com> Date: Mon, 22 Jan 2024 18:14:07 +0200 Subject: [PATCH 0018/2666] docs(metrics): fix empty metric warning filter (#3660) --- docs/core/metrics.md | 2 +- docs/core/metrics/datadog.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/core/metrics.md b/docs/core/metrics.md index 31b4ea99ce7..19a34cf21ad 100644 --- a/docs/core/metrics.md +++ b/docs/core/metrics.md @@ -165,7 +165,7 @@ If you want to ensure at least one metric is always emitted, you can pass `raise ``` ???+ tip "Suppressing warning messages on empty metrics" - If you expect your function to execute without publishing metrics every time, you can suppress the warning with **`warnings.filterwarnings("ignore", "No metrics to publish*")`**. + If you expect your function to execute without publishing metrics every time, you can suppress the warning with **`warnings.filterwarnings("ignore", "No application metrics to publish*")`**. ### Capturing cold start metric diff --git a/docs/core/metrics/datadog.md b/docs/core/metrics/datadog.md index eb036fd3270..ecbdf93f7f8 100644 --- a/docs/core/metrics/datadog.md +++ b/docs/core/metrics/datadog.md @@ -142,7 +142,7 @@ Use `raise_on_empty_metrics=True` if you want to ensure at least one metric is a ``` ???+ tip "Suppressing warning messages on empty metrics" - If you expect your function to execute without publishing metrics every time, you can suppress the warning with **`warnings.filterwarnings("ignore", "No metrics to publish*")`**. + If you expect your function to execute without publishing metrics every time, you can suppress the warning with **`warnings.filterwarnings("ignore", "No application metrics to publish*")`**. ### Capturing cold start metric From 4a43a5051ab266fb6dc8043b4ef3cf77555c4b9d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 00:08:01 +0000 Subject: [PATCH 0019/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3665) chore(deps): bump the layer-balancer group Bumps the layer-balancer group in /layer/scripts/layer-balancer with 1 update: [github.com/aws/aws-sdk-go-v2/config](https://github.com/aws/aws-sdk-go-v2). Updates `github.com/aws/aws-sdk-go-v2/config` from 1.26.5 to 1.26.6 - [Release notes](https://github.com/aws/aws-sdk-go-v2/releases) - [Commits](https://github.com/aws/aws-sdk-go-v2/compare/config/v1.26.5...config/v1.26.6) --- updated-dependencies: - dependency-name: github.com/aws/aws-sdk-go-v2/config dependency-type: direct:production update-type: version-update:semver-patch dependency-group: layer-balancer ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 4 ++-- layer/scripts/layer-balancer/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index dfeb6a67fa1..4548c3f44f2 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -4,7 +4,7 @@ go 1.18 require ( github.com/aws/aws-sdk-go-v2 v1.24.1 - github.com/aws/aws-sdk-go-v2/config v1.26.5 + github.com/aws/aws-sdk-go-v2/config v1.26.6 github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 @@ -16,7 +16,7 @@ require ( github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index fdaf9f31ef7..ec29fc3ea00 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -2,8 +2,8 @@ github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3 github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= -github.com/aws/aws-sdk-go-v2/config v1.26.5 h1:lodGSevz7d+kkFJodfauThRxK9mdJbyutUxGq1NNhvw= -github.com/aws/aws-sdk-go-v2/config v1.26.5/go.mod h1:DxHrz6diQJOc9EwDslVRh84VjjrE17g+pVZXUeSxaDU= +github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o= +github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4= github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= @@ -12,8 +12,8 @@ github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5B github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= From f98ead0f06892dd9832c927bf21c83185909052f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 23 Jan 2024 09:54:46 +0000 Subject: [PATCH 0020/2666] chore(ci): changelog rebuild (#3666) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7b3370a95e0..75cb3166a63 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,9 +4,14 @@ # Unreleased +## Documentation + +* **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) + ## Maintenance * **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) From 0519fa37049a0ebc4df634317d575abe17598d6a Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 23 Jan 2024 15:09:09 +0000 Subject: [PATCH 0021/2666] feat(event_handler): add support for multiValueQueryStringParameters in OpenAPI schema (#3667) * Initial code for multivalue querystring * Adding tests and improving code * Adding tests and improving code * Refactoging to avoid abstraction leaky * Making Pydanticv2 happy * Adding documentation * Addressing Ruben's feedback * Addressing Ruben's feedback * Mypy.... --- .../middlewares/openapi_validation.py | 35 ++- .../utilities/data_classes/alb_event.py | 9 +- .../data_classes/api_gateway_proxy_event.py | 17 ++ .../data_classes/bedrock_agent_event.py | 4 + .../utilities/data_classes/common.py | 11 + .../utilities/data_classes/vpc_lattice.py | 8 + docs/core/event_handler/api_gateway.md | 10 + .../src/working_with_multi_query_values.py | 34 +++ .../events/albMultiValueQueryStringEvent.json | 38 +++ .../lambdaFunctionUrlEventWithHeaders.json | 51 ++++ .../events/vpcLatticeV2EventWithHeaders.json | 36 +++ .../event_handler/test_openapi_params.py | 14 + .../test_openapi_validation_middleware.py | 281 +++++++++++++++++- 13 files changed, 544 insertions(+), 4 deletions(-) create mode 100644 examples/event_handler_rest/src/working_with_multi_query_values.py create mode 100644 tests/events/albMultiValueQueryStringEvent.json create mode 100644 tests/events/lambdaFunctionUrlEventWithHeaders.json create mode 100644 tests/events/vpcLatticeV2EventWithHeaders.json diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py index 34011b64384..e819947b147 100644 --- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py @@ -16,6 +16,7 @@ _regenerate_error_with_loc, get_missing_field_error, ) +from aws_lambda_powertools.event_handler.openapi.dependant import is_scalar_field from aws_lambda_powertools.event_handler.openapi.encoders import jsonable_encoder from aws_lambda_powertools.event_handler.openapi.exceptions import RequestValidationError from aws_lambda_powertools.event_handler.openapi.params import Param @@ -68,10 +69,16 @@ def handler(self, app: EventHandlerInstance, next_middleware: NextMiddleware) -> app.context["_route_args"], ) + # Normalize query values before validate this + query_string = _normalize_multi_query_string_with_param( + app.current_event.resolved_query_string_parameters, + route.dependant.query_params, + ) + # Process query values query_values, query_errors = _request_params_to_args( route.dependant.query_params, - app.current_event.query_string_parameters or {}, + query_string, ) values.update(path_values) @@ -344,3 +351,29 @@ def _get_embed_body( received_body = {field.alias: received_body} return received_body, field_alias_omitted + + +def _normalize_multi_query_string_with_param(query_string: Optional[Dict[str, str]], params: Sequence[ModelField]): + """ + Extract and normalize resolved_query_string_parameters + + Parameters + ---------- + query_string: Dict + A dictionary containing the initial query string parameters. + params: Sequence[ModelField] + A sequence of ModelField objects representing parameters. + + Returns + ------- + A dictionary containing the processed multi_query_string_parameters. + """ + if query_string: + for param in filter(is_scalar_field, params): + try: + # if the target parameter is a scalar, we keep the first value of the query string + # regardless if there are more in the payload + query_string[param.name] = query_string[param.name][0] + except KeyError: + pass + return query_string diff --git a/aws_lambda_powertools/utilities/data_classes/alb_event.py b/aws_lambda_powertools/utilities/data_classes/alb_event.py index 51a6f61f368..688c9567efa 100644 --- a/aws_lambda_powertools/utilities/data_classes/alb_event.py +++ b/aws_lambda_powertools/utilities/data_classes/alb_event.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional from aws_lambda_powertools.shared.headers_serializer import ( BaseHeadersSerializer, @@ -35,6 +35,13 @@ def request_context(self) -> ALBEventRequestContext: def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueQueryStringParameters") + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: + if self.multi_value_query_string_parameters: + return self.multi_value_query_string_parameters + + return self.query_string_parameters + @property def multi_value_headers(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueHeaders") diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index 5c2ef12e62c..9e013eac038 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -118,6 +118,13 @@ def multi_value_headers(self) -> Dict[str, List[str]]: def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueQueryStringParameters") + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: + if self.multi_value_query_string_parameters: + return self.multi_value_query_string_parameters + + return self.query_string_parameters + @property def request_context(self) -> APIGatewayEventRequestContext: return APIGatewayEventRequestContext(self._data) @@ -299,3 +306,13 @@ def http_method(self) -> str: def header_serializer(self): return HttpApiHeadersSerializer() + + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: + if self.query_string_parameters is not None: + query_string = { + key: value.split(",") if "," in value else value for key, value in self.query_string_parameters.items() + } + return query_string + + return {} diff --git a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py index 9534af0e7f6..d9b45242376 100644 --- a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +++ b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py @@ -108,3 +108,7 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]: # In Bedrock Agent events, query string parameters are passed as undifferentiated parameters, # together with the other parameters. So we just return all parameters here. return {x["name"]: x["value"] for x in self["parameters"]} if self.get("parameters") else None + + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: + return self.query_string_parameters diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 28229c21a62..d2cf57d4af5 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -103,6 +103,17 @@ def headers(self) -> Dict[str, str]: def query_string_parameters(self) -> Optional[Dict[str, str]]: return self.get("queryStringParameters") + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: + """ + This property determines the appropriate query string parameter to be used + as a trusted source for validating OpenAPI. + + This is necessary because different resolvers use different formats to encode + multi query string parameters. + """ + return self.query_string_parameters + @property def is_base64_encoded(self) -> Optional[bool]: return self.get("isBase64Encoded") diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py index 00ba5136eec..633ce068f6e 100644 --- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py @@ -141,6 +141,10 @@ def query_string_parameters(self) -> Dict[str, str]: """The request query string parameters.""" return self["query_string_parameters"] + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: + return self.query_string_parameters + class vpcLatticeEventV2Identity(DictWrapper): @property @@ -251,3 +255,7 @@ def request_context(self) -> vpcLatticeEventV2RequestContext: def query_string_parameters(self) -> Optional[Dict[str, str]]: """The request query string parameters.""" return self.get("queryStringParameters") + + @property + def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: + return self.query_string_parameters diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index a34a94975bc..86b97c87e4b 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -400,6 +400,16 @@ In the following example, we use a new `Query` OpenAPI type to add [one out of m 1. `completed` is still the same query string as before, except we simply state it's an string. No `Query` or `Annotated` to validate it. +=== "working_with_multi_query_values.py" + + If you need to handle multi-value query parameters, you can create a list of the desired type. + + ```python hl_lines="23" + --8<-- "examples/event_handler_rest/src/working_with_multi_query_values.py" + ``` + + 1. `example_multi_value_param` is a list containing values from the `ExampleEnum` enumeration. + #### Validating path parameters diff --git a/examples/event_handler_rest/src/working_with_multi_query_values.py b/examples/event_handler_rest/src/working_with_multi_query_values.py new file mode 100644 index 00000000000..7f6049dad46 --- /dev/null +++ b/examples/event_handler_rest/src/working_with_multi_query_values.py @@ -0,0 +1,34 @@ +from enum import Enum +from typing import List + +from aws_lambda_powertools.event_handler import APIGatewayRestResolver +from aws_lambda_powertools.event_handler.openapi.params import Query +from aws_lambda_powertools.shared.types import Annotated +from aws_lambda_powertools.utilities.typing import LambdaContext + +app = APIGatewayRestResolver(enable_validation=True) + + +class ExampleEnum(Enum): + """Example of an Enum class.""" + + ONE = "value_one" + TWO = "value_two" + THREE = "value_three" + + +@app.get("/todos") +def get( + example_multi_value_param: Annotated[ + List[ExampleEnum], # (1)! + Query( + description="This is multi value query parameter.", + ), + ], +): + """Return validated multi-value param values.""" + return example_multi_value_param + + +def lambda_handler(event: dict, context: LambdaContext) -> dict: + return app.resolve(event, context) diff --git a/tests/events/albMultiValueQueryStringEvent.json b/tests/events/albMultiValueQueryStringEvent.json new file mode 100644 index 00000000000..4584ba7c477 --- /dev/null +++ b/tests/events/albMultiValueQueryStringEvent.json @@ -0,0 +1,38 @@ +{ + "requestContext": { + "elb": { + "targetGroupArn": "arn:aws:elasticloadbalancing:eu-central-1:1234567890:targetgroup/alb-c-Targe-11GDXTPQ7663S/804a67588bfdc10f" + } + }, + "httpMethod": "GET", + "path": "/todos", + "multiValueQueryStringParameters": { + "parameter1": ["value1","value2"], + "parameter2": ["value"] + }, + "multiValueHeaders": { + "accept": [ + "*/*" + ], + "host": [ + "alb-c-LoadB-14POFKYCLBNSF-1815800096.eu-central-1.elb.amazonaws.com" + ], + "user-agent": [ + "curl/7.79.1" + ], + "x-amzn-trace-id": [ + "Root=1-62fa9327-21cdd4da4c6db451490a5fb7" + ], + "x-forwarded-for": [ + "123.123.123.123" + ], + "x-forwarded-port": [ + "80" + ], + "x-forwarded-proto": [ + "http" + ] + }, + "body": "", + "isBase64Encoded": false +} diff --git a/tests/events/lambdaFunctionUrlEventWithHeaders.json b/tests/events/lambdaFunctionUrlEventWithHeaders.json new file mode 100644 index 00000000000..e453690d9b3 --- /dev/null +++ b/tests/events/lambdaFunctionUrlEventWithHeaders.json @@ -0,0 +1,51 @@ +{ + "version":"2.0", + "routeKey":"$default", + "rawPath":"/", + "rawQueryString":"", + "headers":{ + "sec-fetch-mode":"navigate", + "x-amzn-tls-version":"TLSv1.2", + "sec-fetch-site":"cross-site", + "accept-language":"pt-BR,pt;q=0.9", + "x-forwarded-proto":"https", + "x-forwarded-port":"443", + "x-forwarded-for":"123.123.123.123", + "sec-fetch-user":"?1", + "accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9", + "x-amzn-tls-cipher-suite":"ECDHE-RSA-AES128-GCM-SHA256", + "sec-ch-ua":"\" Not A;Brand\";v=\"99\", \"Chromium\";v=\"102\", \"Google Chrome\";v=\"102\"", + "sec-ch-ua-mobile":"?0", + "x-amzn-trace-id":"Root=1-62ecd163-5f302e550dcde3b12402207d", + "sec-ch-ua-platform":"\"Linux\"", + "host":".lambda-url.us-east-1.on.aws", + "upgrade-insecure-requests":"1", + "cache-control":"max-age=0", + "accept-encoding":"gzip, deflate, br", + "sec-fetch-dest":"document", + "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" + }, + "queryStringParameters": { + "parameter1": "value1,value2", + "parameter2": "value" + }, + "requestContext":{ + "accountId":"anonymous", + "apiId":"", + "domainName":".lambda-url.us-east-1.on.aws", + "domainPrefix":"", + "http":{ + "method":"GET", + "path":"/", + "protocol":"HTTP/1.1", + "sourceIp":"123.123.123.123", + "userAgent":"agent" + }, + "requestId":"id", + "routeKey":"$default", + "stage":"$default", + "time":"05/Aug/2022:08:14:39 +0000", + "timeEpoch":1659687279885 + }, + "isBase64Encoded":false +} diff --git a/tests/events/vpcLatticeV2EventWithHeaders.json b/tests/events/vpcLatticeV2EventWithHeaders.json new file mode 100644 index 00000000000..11b36ef118b --- /dev/null +++ b/tests/events/vpcLatticeV2EventWithHeaders.json @@ -0,0 +1,36 @@ +{ + "version": "2.0", + "path": "/newpath", + "method": "GET", + "headers": { + "user_agent": "curl/7.64.1", + "x-forwarded-for": "10.213.229.10", + "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", + "accept": "*/*" + }, + "queryStringParameters": { + "parameter1": [ + "value1", + "value2" + ], + "parameter2": [ + "value" + ] + }, + "body": "{\"message\": \"Hello from Lambda!\"}", + "isBase64Encoded": false, + "requestContext": { + "serviceNetworkArn": "arn:aws:vpc-lattice:us-east-2:123456789012:servicenetwork/sn-0bf3f2882e9cc805a", + "serviceArn": "arn:aws:vpc-lattice:us-east-2:123456789012:service/svc-0a40eebed65f8d69c", + "targetGroupArn": "arn:aws:vpc-lattice:us-east-2:123456789012:targetgroup/tg-6d0ecf831eec9f09", + "identity": { + "sourceVpcArn": "arn:aws:ec2:region:123456789012:vpc/vpc-0b8276c84697e7339", + "type" : "AWS_IAM", + "principal": "arn:aws:sts::123456789012:assumed-role/example-role/057d00f8b51257ba3c853a0f248943cf", + "sessionName": "057d00f8b51257ba3c853a0f248943cf", + "x509SanDns": "example.com" + }, + "region": "us-east-2", + "timeEpoch": "1696331543569073" + } +} diff --git a/tests/functional/event_handler/test_openapi_params.py b/tests/functional/event_handler/test_openapi_params.py index 0f06524ea6d..2f48f5aa534 100644 --- a/tests/functional/event_handler/test_openapi_params.py +++ b/tests/functional/event_handler/test_openapi_params.py @@ -184,6 +184,20 @@ def handler(page: Annotated[str, Query(include_in_schema=False)]): assert get.parameters is None +def test_openapi_with_list_param(): + app = APIGatewayRestResolver() + + @app.get("/") + def handler(page: Annotated[List[str], Query()]): + return page + + schema = app.get_openapi_schema() + assert len(schema.paths.keys()) == 1 + + get = schema.paths["/"].get + assert get.parameters[0].schema_.type == "array" + + def test_openapi_with_description(): app = APIGatewayRestResolver() diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index f558bd23ced..ea4305257d4 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -6,12 +6,23 @@ from pydantic import BaseModel -from aws_lambda_powertools.event_handler import APIGatewayRestResolver, Response -from aws_lambda_powertools.event_handler.openapi.params import Body +from aws_lambda_powertools.event_handler import ( + ALBResolver, + APIGatewayHttpResolver, + APIGatewayRestResolver, + LambdaFunctionUrlResolver, + Response, + VPCLatticeV2Resolver, +) +from aws_lambda_powertools.event_handler.openapi.params import Body, Query from aws_lambda_powertools.shared.types import Annotated from tests.functional.utils import load_event LOAD_GW_EVENT = load_event("apiGatewayProxyEvent.json") +LOAD_GW_EVENT_HTTP = load_event("apiGatewayProxyV2Event.json") +LOAD_GW_EVENT_ALB = load_event("albMultiValueQueryStringEvent.json") +LOAD_GW_EVENT_LAMBDA_URL = load_event("lambdaFunctionUrlEventWithHeaders.json") +LOAD_GW_EVENT_VPC_LATTICE = load_event("vpcLatticeV2EventWithHeaders.json") def test_validate_scalars(): @@ -378,3 +389,269 @@ def handler(user: Model) -> Response[Model]: result = app(LOAD_GW_EVENT, {}) assert result["statusCode"] == 422 assert "missing" in result["body"] + + +def test_validate_rest_api_resolver_with_multi_query_params(): + # GIVEN an APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT["httpMethod"] = "GET" + LOAD_GW_EVENT["path"] = "/users" + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT, {}) + assert result["statusCode"] == 200 + + +def test_validate_rest_api_resolver_with_multi_query_params_fail(): + # GIVEN an APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT["httpMethod"] = "GET" + LOAD_GW_EVENT["path"] = "/users" + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT, {}) + assert result["statusCode"] == 422 + assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + + +def test_validate_rest_api_resolver_without_query_params(): + # GIVEN an APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(): + return None + + LOAD_GW_EVENT["httpMethod"] = "GET" + LOAD_GW_EVENT["path"] = "/users" + LOAD_GW_EVENT["queryStringParameters"] = None + LOAD_GW_EVENT["multiValueQueryStringParameters"] = None + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT, {}) + assert result["statusCode"] == 200 + + +def test_validate_http_resolver_with_multi_query_params(): + # GIVEN an APIGatewayHttpResolver with validation enabled + app = APIGatewayHttpResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_HTTP["rawPath"] = "/users" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_HTTP, {}) + assert result["statusCode"] == 200 + + +def test_validate_http_resolver_with_multi_query_values_fail(): + # GIVEN an APIGatewayHttpResolver with validation enabled + app = APIGatewayHttpResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_HTTP["rawPath"] = "/users" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT_HTTP, {}) + assert result["statusCode"] == 422 + assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + + +def test_validate_http_resolver_without_query_params(): + # GIVEN an APIGatewayHttpResolver with validation enabled + app = APIGatewayHttpResolver(enable_validation=True) + + # WHEN a handler is defined without any query params + @app.get("/users") + def handler(): + return None + + LOAD_GW_EVENT_HTTP["rawPath"] = "/users" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + LOAD_GW_EVENT_HTTP["queryStringParameters"] = None + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_HTTP, {}) + assert result["statusCode"] == 200 + + +def test_validate_alb_resolver_with_multi_query_values(): + # GIVEN an ALBResolver with validation enabled + app = ALBResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_ALB["path"] = "/users" + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_ALB, {}) + assert result["statusCode"] == 200 + + +def test_validate_alb_resolver_with_multi_query_values_fail(): + # GIVEN an ALBResolver with validation enabled + app = ALBResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_ALB["path"] = "/users" + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT_ALB, {}) + assert result["statusCode"] == 422 + assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + + +def test_validate_alb_resolver_without_query_params(): + # GIVEN an ALBResolver with validation enabled + app = ALBResolver(enable_validation=True) + + # WHEN a handler is defined without any query params + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_ALB["path"] = "/users" + LOAD_GW_EVENT_HTTP["multiValueQueryStringParameters"] = None + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_ALB, {}) + assert result["statusCode"] == 200 + + +def test_validate_lambda_url_resolver_with_multi_query_params(): + # GIVEN an LambdaFunctionUrlResolver with validation enabled + app = LambdaFunctionUrlResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + assert result["statusCode"] == 200 + + +def test_validate_lambda_url_resolver_with_multi_query_params_fail(): + # GIVEN an LambdaFunctionUrlResolver with validation enabled + app = LambdaFunctionUrlResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + assert result["statusCode"] == 422 + assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + + +def test_validate_lambda_url_resolver_without_query_params(): + # GIVEN an LambdaFunctionUrlResolver with validation enabled + app = LambdaFunctionUrlResolver(enable_validation=True) + + # WHEN a handler is defined without any query params + @app.get("/users") + def handler(): + return None + + LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + LOAD_GW_EVENT_LAMBDA_URL["queryStringParameters"] = None + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + assert result["statusCode"] == 200 + + +def test_validate_vpc_lattice_resolver_with_multi_params_values(): + # GIVEN an VPCLatticeV2Resolver with validation enabled + app = VPCLatticeV2Resolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list + @app.get("/users") + def handler(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + assert result["statusCode"] == 200 + + +def test_validate_vpc_lattice_resolver_with_multi_query_params_fail(): + # GIVEN an VPCLatticeV2Resolver with validation enabled + app = VPCLatticeV2Resolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter and a list with wrong type + @app.get("/users") + def handler(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + + # THEN the handler should be invoked and return 422 + result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + assert result["statusCode"] == 422 + assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + + +def test_validate_vpc_lattice_resolver_without_query_params(): + # GIVEN an VPCLatticeV2Resolver with validation enabled + app = VPCLatticeV2Resolver(enable_validation=True) + + # WHEN a handler is defined without any query params + @app.get("/users") + def handler(): + return None + + LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + LOAD_GW_EVENT_VPC_LATTICE["queryStringParameters"] = None + + # THEN the handler should be invoked and return 200 + result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + assert result["statusCode"] == 200 From e1ca5842ad828588fcf2af538fdc88404418cf97 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jan 2024 08:51:26 +0000 Subject: [PATCH 0022/2666] chore(ci): changelog rebuild (#3669) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75cb3166a63..9776e3cbe93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ * **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) +## Features + +* **event_handler:** add support for multiValueQueryStringParameters in OpenAPI schema ([#3667](https://github.com/aws-powertools/powertools-lambda-python/issues/3667)) + ## Maintenance * **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) From aac14dc277f57cfb05ef6d37bca19d3756cb7632 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 10:31:04 +0000 Subject: [PATCH 0023/2666] chore(deps): bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs (#3670) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `58eef6c` to `9aad7af`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 1da6d6b491c..ce3cae8a9a3 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:58eef6c68ad4c8687f7d43c560852a8f62d403126c90c919242dec93bd3eee68 +FROM squidfunk/mkdocs-material@sha256:9aad7af2f62950826f57928e984ea8aa77a561f67b7f5fc251ced67d52a2a5fe # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From 83ba2d154183a111a73e39110e9d66ff2d70b7c7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 22:14:42 +0000 Subject: [PATCH 0024/2666] chore(deps-dev): bump aws-cdk from 2.122.0 to 2.123.0 (#3673) Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.122.0 to 2.123.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/commits/v2.123.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 9c1f3cb3ee8..24659a4e69b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.122.0" + "aws-cdk": "^2.123.0" } }, "node_modules/aws-cdk": { - "version": "2.122.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.122.0.tgz", - "integrity": "sha512-WqiVTedcuW4LjH4WqtQncliUdeDa9j9xgu3II8Qd1HmCZotbzBorYIHDvOJ+m3ovIzd9DL+hNq9PPUqxtBe0VQ==", + "version": "2.123.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.123.0.tgz", + "integrity": "sha512-JvGNN1FobSaGwirJJQZ1oIkaHFfQoLbRyuxzFNQSs2wlVltwFb1VdR7FNxh0sVzugM2RsYQu8xQPUa53ZnDlyg==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index b2065da493f..cfa167558d4 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.122.0" + "aws-cdk": "^2.123.0" }, "dependencies": { "package-lock.json": "^1.0.0" From d112af7a1d146f96983712004b156afc34b021b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 25 Jan 2024 22:15:12 +0000 Subject: [PATCH 0025/2666] chore(deps): bump codecov/codecov-action from 3.1.4 to 3.1.5 (#3674) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.4 to 3.1.5. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/eaaf4bedf32dbdc6b720b63067d99c4d77d6047d...4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- .github/workflows/quality_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index 06912442553..db54c571509 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@eaaf4bedf32dbdc6b720b63067d99c4d77d6047d # 3.1.4 + uses: codecov/codecov-action@4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0 # 3.1.5 with: file: ./coverage.xml env_vars: PYTHON From 3268c71f5e0498b60198b0422c1346c1570b05b2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Jan 2024 09:21:00 +0000 Subject: [PATCH 0026/2666] chore(ci): changelog rebuild (#3675) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9776e3cbe93..e0fbb34b687 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,11 @@ ## Maintenance +* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) +* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) * **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) * **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) +* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) From b2c1047e11bd8f39e0a0f7a877e21c963eb6d91f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sat, 27 Jan 2024 17:26:39 +0000 Subject: [PATCH 0027/2666] chore(ci): changelog rebuild (#3676) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e0fbb34b687..9342503c3ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,8 +15,8 @@ ## Maintenance * **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) -* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) * **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) * **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) * **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) From a7c2a7506d48000fad6862a14ceae23adae5800d Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 29 Jan 2024 16:47:44 +0000 Subject: [PATCH 0028/2666] fix(event-handler): strip whitespace from Content-Type headers during OpenAPI schema validation (#3677) Fixing problems with spaces in header --- .../middlewares/openapi_validation.py | 2 +- .../test_openapi_validation_middleware.py | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py index e819947b147..fd7507603de 100644 --- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py @@ -212,7 +212,7 @@ def _get_body(self, app: EventHandlerInstance) -> Dict[str, Any]: """ content_type_value = app.current_event.get_header_value("content-type") - if not content_type_value or content_type_value.startswith("application/json"): + if not content_type_value or content_type_value.strip().startswith("application/json"): try: return app.current_event.json_body except json.JSONDecodeError as e: diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index ea4305257d4..23fa131ab9f 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -289,6 +289,32 @@ def handler(user: Model) -> Model: assert json.loads(result["body"]) == {"name": "John", "age": 30} +def test_validate_body_param_with_stripped_headers(): + # GIVEN an APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) + + class Model(BaseModel): + name: str + age: int + + # WHEN a handler is defined with a body parameter + # WHEN headers has spaces + @app.post("/") + def handler(user: Model) -> Model: + return user + + LOAD_GW_EVENT["httpMethod"] = "POST" + LOAD_GW_EVENT["headers"] = {"Content-type": " application/json "} + LOAD_GW_EVENT["path"] = "/" + LOAD_GW_EVENT["body"] = json.dumps({"name": "John", "age": 30}) + + # THEN the handler should be invoked and return 200 + # THEN the body must be a JSON object + result = app(LOAD_GW_EVENT, {}) + assert result["statusCode"] == 200 + assert json.loads(result["body"]) == {"name": "John", "age": 30} + + def test_validate_body_param_with_invalid_date(): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) From e8daf9e9381da0841709f60c9b8a7dd27b687482 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:05:29 +0000 Subject: [PATCH 0029/2666] chore(deps): bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs (#3679) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `9aad7af` to `a4a2029`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index ce3cae8a9a3..82bf5a39aeb 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:9aad7af2f62950826f57928e984ea8aa77a561f67b7f5fc251ced67d52a2a5fe +FROM squidfunk/mkdocs-material@sha256:a4a2029fdf524f0c727852e492cd2bbae30cc9471959da60d7dc46bf565a521b # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From ee78db0b4a8bc3662a1d9079906a5272b436ec19 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 29 Jan 2024 23:14:11 +0000 Subject: [PATCH 0030/2666] chore(deps-dev): bump aws-cdk from 2.123.0 to 2.124.0 (#3678) Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.123.0 to 2.124.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/v2.124.0/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/commits/v2.124.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 24659a4e69b..cdfbdeceff1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.123.0" + "aws-cdk": "^2.124.0" } }, "node_modules/aws-cdk": { - "version": "2.123.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.123.0.tgz", - "integrity": "sha512-JvGNN1FobSaGwirJJQZ1oIkaHFfQoLbRyuxzFNQSs2wlVltwFb1VdR7FNxh0sVzugM2RsYQu8xQPUa53ZnDlyg==", + "version": "2.124.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.124.0.tgz", + "integrity": "sha512-kUOfqwIAaTEx4ZozojZEhWa8G+O9KU+P0tERtDVmTw9ip4QXNMwTTkjj/IPtoH8qfXGdeibTQ9MJwRvHOR8kXQ==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index cfa167558d4..bf23efc23e3 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.123.0" + "aws-cdk": "^2.124.0" }, "dependencies": { "package-lock.json": "^1.0.0" From fe70d9132a5ea63f873a1172c5cb5e29bce9faa5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 08:37:45 +0000 Subject: [PATCH 0031/2666] chore(ci): changelog rebuild (#3680) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9342503c3ca..9eacdda2d41 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,10 @@ # Unreleased +## Bug Fixes + +* **event-handler:** strip whitespace from Content-Type headers during OpenAPI schema validation ([#3677](https://github.com/aws-powertools/powertools-lambda-python/issues/3677)) + ## Documentation * **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) @@ -15,11 +19,13 @@ ## Maintenance * **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) -* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) -* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) * **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) +* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) +* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) * **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) +* **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) From fd4903fc95be73eed38281a9b23173067732fa42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 20:44:47 +0000 Subject: [PATCH 0032/2666] chore(deps): bump codecov/codecov-action from 3.1.5 to 3.1.6 (#3683) --- .github/workflows/quality_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index db54c571509..40ccbe99887 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@4fe8c5f003fae66aa5ebb77cfd3e7bfbbda0b6b0 # 3.1.5 + uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 with: file: ./coverage.xml env_vars: PYTHON From 6a06a6693428c2e6323712be918f0f78f00af97c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 22:08:09 +0000 Subject: [PATCH 0033/2666] chore(deps-dev): bump sentry-sdk from 1.39.2 to 1.40.0 (#3684) Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.39.2 to 1.40.0. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/1.39.2...1.40.0) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index ec9ea847df8..8e41d5f459a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2859,13 +2859,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.39.2" +version = "1.40.0" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.39.2.tar.gz", hash = "sha256:24c83b0b41c887d33328a9166f5950dc37ad58f01c9f2fbff6b87a6f1094170c"}, - {file = "sentry_sdk-1.39.2-py2.py3-none-any.whl", hash = "sha256:acaf597b30258fc7663063b291aa99e58f3096e91fe1e6634f4b79f9c1943e8e"}, + {file = "sentry-sdk-1.40.0.tar.gz", hash = "sha256:34ad8cfc9b877aaa2a8eb86bfe5296a467fffe0619b931a05b181c45f6da59bf"}, + {file = "sentry_sdk-1.40.0-py2.py3-none-any.whl", hash = "sha256:78575620331186d32f34b7ece6edea97ce751f58df822547d3ab85517881a27a"}, ] [package.dependencies] @@ -2891,7 +2891,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure_eval"] +pure-eval = ["asttokens", "executing", "pure-eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] From 7d88b5477d74237c3337cb7e1f1e561e765298b8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 30 Jan 2024 22:15:57 +0000 Subject: [PATCH 0034/2666] chore(deps-dev): bump ruff from 0.1.14 to 0.1.15 (#3685) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.14 to 0.1.15. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.14...v0.1.15) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8e41d5f459a..b6bf62d37bb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2801,28 +2801,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.1.14" +version = "0.1.15" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:96f76536df9b26622755c12ed8680f159817be2f725c17ed9305b472a757cdbb"}, - {file = "ruff-0.1.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:ab3f71f64498c7241123bb5a768544cf42821d2a537f894b22457a543d3ca7a9"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7060156ecc572b8f984fd20fd8b0fcb692dd5d837b7606e968334ab7ff0090ab"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a53d8e35313d7b67eb3db15a66c08434809107659226a90dcd7acb2afa55faea"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bea9be712b8f5b4ebed40e1949379cfb2a7d907f42921cf9ab3aae07e6fba9eb"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:2270504d629a0b064247983cbc495bed277f372fb9eaba41e5cf51f7ba705a6a"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80258bb3b8909b1700610dfabef7876423eed1bc930fe177c71c414921898efa"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:653230dd00aaf449eb5ff25d10a6e03bc3006813e2cb99799e568f55482e5cae"}, - {file = "ruff-0.1.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87b3acc6c4e6928459ba9eb7459dd4f0c4bf266a053c863d72a44c33246bfdbf"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b3dadc9522d0eccc060699a9816e8127b27addbb4697fc0c08611e4e6aeb8b5"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:1c8eca1a47b4150dc0fbec7fe68fc91c695aed798532a18dbb1424e61e9b721f"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_i686.whl", hash = "sha256:62ce2ae46303ee896fc6811f63d6dabf8d9c389da0f3e3f2bce8bc7f15ef5488"}, - {file = "ruff-0.1.14-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:b2027dde79d217b211d725fc833e8965dc90a16d0d3213f1298f97465956661b"}, - {file = "ruff-0.1.14-py3-none-win32.whl", hash = "sha256:722bafc299145575a63bbd6b5069cb643eaa62546a5b6398f82b3e4403329cab"}, - {file = "ruff-0.1.14-py3-none-win_amd64.whl", hash = "sha256:e3d241aa61f92b0805a7082bd89a9990826448e4d0398f0e2bc8f05c75c63d99"}, - {file = "ruff-0.1.14-py3-none-win_arm64.whl", hash = "sha256:269302b31ade4cde6cf6f9dd58ea593773a37ed3f7b97e793c8594b262466b67"}, - {file = "ruff-0.1.14.tar.gz", hash = "sha256:ad3f8088b2dfd884820289a06ab718cde7d38b94972212cc4ba90d5fbc9955f3"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, + {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, + {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, + {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, + {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, + {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, + {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, + {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, ] [[package]] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "10841362fd6d21eed52d656803e056dcba30a7835c5a00dda8275eaa4e1cc41c" +content-hash = "f4c66a8fa656902aba0c04cc8b5dc236d7f0ed6f7c3e22507cc89e711b0b62b2" diff --git a/pyproject.toml b/pyproject.toml index 7f04dba78a4..0e576d412df 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -109,7 +109,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.1.15" +ruff = ">=0.0.272,<0.1.16" retry2 = "^0.9.5" pytest-socket = "^0.6.0" types-redis = "^4.6.0.7" From b591bb8c85db7c36f088a9db3ef1b6e1788bab39 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 09:05:12 +0000 Subject: [PATCH 0035/2666] chore(ci): changelog rebuild (#3686) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9eacdda2d41..479bde82545 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,14 +18,17 @@ ## Maintenance -* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) * **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) -* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) * **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) +* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) +* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) * **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) * **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) +* **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) +* **deps-dev:** bump ruff from 0.1.14 to 0.1.15 ([#3685](https://github.com/aws-powertools/powertools-lambda-python/issues/3685)) From e1a4d1ec0b422a5ba16249aedde14543c2f3ec2f Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Wed, 31 Jan 2024 09:40:39 +0000 Subject: [PATCH 0036/2666] docs(proccess): add versioning and maintenance policy (#3682) * Adding versioning policy * docs: update wording to reflect Powertools for AWS Lambda * docs: adjust timelines, refer to tight coupling w/ Lambda runtime policy * docs: fix grammar * Adressing Andrea's feedback * docs: GA minimal commitment adjustment to allow each language to set their baseline * docs: final line editing --------- Co-authored-by: heitorlessa --- docs/versioning.md | 63 ++++++++++++++++++++++++++++++++++++++++++++++ mkdocs.yml | 1 + 2 files changed, 64 insertions(+) create mode 100644 docs/versioning.md diff --git a/docs/versioning.md b/docs/versioning.md new file mode 100644 index 00000000000..44349f4bfc2 --- /dev/null +++ b/docs/versioning.md @@ -0,0 +1,63 @@ +--- +title: Versioning and maintenance policy +description: Versioning and maintenance policy for Powertools for AWS Lambda (Python) +--- + + + +### Overview + +This document outlines the maintenance policy for Powertools for AWS Lambda and their underlying dependencies. AWS regularly provides Powertools for AWS Lambda with updates that may contain new features, enhancements, bug fixes, security patches, or documentation updates. Updates may also address changes with dependencies, language runtimes, and operating systems. Powertools for AWS Lambda is published to package managers (e.g. PyPi, NPM, Maven, NuGet), and are available as source code on GitHub. + +We recommend users to stay up-to-date with Powertools for AWS Lambda releases to keep up with the latest features, security updates, and underlying dependencies. Continued use of an unsupported Powertools for AWS Lambda version is not recommended and is done at the user’s discretion. + +!!! info "For brevity, we will interchangeably refer to Powertools for AWS Lambda as "SDK" _(Software Development Toolkit)_." + +### Versioning + +Powertools for AWS Lambda release versions are in the form of X.Y.Z where X represents the major version. Increasing the major version of an SDK indicates that this SDK underwent significant and substantial changes to support new idioms and patterns in the language. Major versions are introduced when public interfaces _(e.g. classes, methods, types, etc.)_, behaviors, or semantics have changed. Applications need to be updated in order for them to work with the newest SDK version. It is important to update major versions carefully and in accordance with the upgrade guidelines provided by AWS. + +### SDK major version lifecycle + +The lifecycle for major Powertools for AWS Lambda versions consists of 5 phases, which are outlined below. + +* **Developer Preview** (Phase 0) - During this phase, SDKs are not supported, should not be used in production environments, and are meant for early access and feedback purposes only. It is possible for future releases to introduce breaking changes. Once AWS identifies a release to be a stable product, it may mark it as a Release Candidate. Release Candidates are ready for GA release unless significant bugs emerge, and will receive full AWS support. +* **General Availability (GA)** (Phase 1) - During this phase, SDKs are fully supported. AWS will provide regular SDK releases that include support for new features, enhancements, as well as bug and security fixes. AWS will support the GA version of an SDK for _at least 24 months_, unless otherwise specified. +* **Maintenance Announcement** (Phase 2) - AWS will make a public announcement at least 6 months before an SDK enters maintenance mode. During this period, the SDK will continue to be fully supported. Typically, maintenance mode is announced at the same time as the next major version is transitioned to GA. +* **Maintenance** (Phase 3) - During the maintenance mode, AWS limits SDK releases to address critical bug fixes and security issues only. An SDK will not receive API updates for new or existing services, or be updated to support new regions. Maintenance mode has a _default duration of 6 months_, unless otherwise specified. +* **End-of-Support** (Phase 4) - When an SDK reaches end-of support, it will no longer receive updates or releases. Previously published releases will continue to be available via public package managers and the code will remain on GitHub. The GitHub repository may be archived. Use of an SDK which has reached end-of-support is done at the user’s discretion. We recommend users upgrade to the new major version. + +!!! note "Please note that the timelines shown below are illustrative and not binding" + +![Maintenance policy timelines](https://docs.aws.amazon.com/images/sdkref/latest/guide/images/maint-policy.png) + +### Dependency lifecycle + +Most AWS SDKs have underlying dependencies, such as language runtimes, AWS Lambda runtime, or third party libraries and frameworks. These dependencies are typically tied to the language community or the vendor who owns that particular component. Each community or vendor publishes their own end-of-support schedule for their product. + +The following terms are used to classify underlying third party dependencies: + +* [**AWS Lambda Runtime**](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html): Examples include `nodejs20.x`, `python3.12`, etc. +* **Language Runtime**: Examples include Python 3.12, NodeJS 20, Java 17, .NET Core, etc. +* **Third party Library**: Examples include Pydantic, AWS X-Ray SDK, AWS Encryption SDK, Middy.js, etc. + +Powertools for AWS Lambda follows the [AWS Lambda Runtime deprecation policy cycle](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtime-support-policy), when it comes to Language Runtime. This means we will stop supporting their respective deprecated Language Runtime _(e.g., `python37`)_ without increasing the major SDK version. + +!!! note "AWS reserves the right to stop support for an underlying dependency without increasing the major SDK version" + +### Communication methods + +Maintenance announcements are communicated in several ways: + +* A pinned GitHub Request For Comments (RFC) issue indicating the campaign for the next major version. The RFC will outline the path to end-of-support, specify campaign timelines, and upgrade guidance. +* AWS SDK documentation, such as API reference documentation, user guides, SDK product marketing pages, and GitHub readme(s) are updated to indicate the campaign timeline and provide guidance on upgrading affected applications. +* Deprecation warnings are added to the SDKs, outlining the path to end-of-support and linking to the upgrade guide. + +To see the list of available major versions of Powertools for AWS Lambda and where they are in their maintenance lifecycle, see [version support matrix](#version-support-matrix) + +### Version support matrix + +| SDK | Major version | Current Phase | General Availability Date | Notes | +| -------------------------------- | ------------- | -------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Powertools for AWS Lambda Python | 2.x | General Availability | 10/24/2022 | See [Release Notes](https://github.com/aws-powertools/powertools-lambda-python/releases/tag/v2.0.0) | +| Powertools for AWS Lambda Python | 1.x | End of Support | 06/18/2020 | See [RFC](https://github.com/aws-powertools/powertools-lambda-python/issues/1459) and [upgrade guide](https://docs.powertools.aws.dev/lambda/python/latest/upgrade/) | diff --git a/mkdocs.yml b/mkdocs.yml index 0a844fd392f..a862430a054 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -38,6 +38,7 @@ nav: - Processes: - Security: security.md - Automation: automation.md + - Versioning policy: versioning.md - Roadmap: roadmap.md - Maintainers: maintainers.md - Contributing: From b7845980297db326ffc257b9f097c22fffefea85 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 08:55:35 +0000 Subject: [PATCH 0037/2666] chore(ci): changelog rebuild (#3690) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 479bde82545..b5024e61b44 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ## Documentation * **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) +* **proccess:** add versioning and maintenance policy ([#3682](https://github.com/aws-powertools/powertools-lambda-python/issues/3682)) ## Features @@ -19,16 +20,16 @@ ## Maintenance * **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) +* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) * **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) -* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) -* **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) * **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) -* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) -* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) -* **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) +* **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) +* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) * **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) * **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) +* **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) * **deps-dev:** bump ruff from 0.1.14 to 0.1.15 ([#3685](https://github.com/aws-powertools/powertools-lambda-python/issues/3685)) +* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) From ced0a3d620714c9dd0188f09718c5bf88f00c2e1 Mon Sep 17 00:00:00 2001 From: seshubaws <116689586+seshubaws@users.noreply.github.com> Date: Thu, 1 Feb 2024 03:56:19 -0800 Subject: [PATCH 0038/2666] docs(data-masking): add docs for data masking utility (#3186) --- Makefile | 4 +- README.md | 1 + aws_lambda_powertools/shared/functions.py | 12 +- .../utilities/_data_masking/base.py | 174 ----- .../utilities/_data_masking/constants.py | 5 - .../_data_masking/provider/__init__.py | 5 - .../utilities/_data_masking/provider/base.py | 34 - .../_data_masking/provider/kms/__init__.py | 5 - .../provider/kms/aws_encryption_sdk.py | 177 ----- .../__init__.py | 2 +- .../utilities/data_masking/base.py | 291 ++++++++ .../utilities/data_masking/constants.py | 14 + .../utilities/data_masking/exceptions.py | 34 + .../data_masking/provider/__init__.py | 5 + .../utilities/data_masking/provider/base.py | 81 +++ .../data_masking/provider/kms/__init__.py | 5 + .../provider/kms/aws_encryption_sdk.py | 247 +++++++ docs/index.md | 1 + docs/utilities/data_masking.md | 638 ++++++++++++++++++ examples/data_masking/sam/template.yaml | 67 ++ .../src/advanced_custom_serializer.py | 26 + .../src/aws_encryption_provider_example.py | 34 + .../src/changing_default_algorithm.py | 33 + .../src/choosing_payload_all_nested_keys.json | 19 + ...oosing_payload_all_nested_keys_output.json | 9 + .../choosing_payload_complex_nested_keys.json | 11 + ...ng_payload_complex_nested_keys_output.json | 11 + .../src/choosing_payload_complex_search.json | 19 + ...hoosing_payload_complex_search_output.json | 19 + .../src/choosing_payload_list_all_index.json | 15 + ...hoosing_payload_list_all_index_output.json | 16 + .../src/choosing_payload_list_index.json | 15 + .../choosing_payload_list_index_output.json | 16 + .../src/choosing_payload_list_slice.json | 19 + .../choosing_payload_list_slice_output.json | 19 + .../src/choosing_payload_multiple_keys.json | 9 + ...choosing_payload_multiple_keys_output.json | 9 + .../src/choosing_payload_nested_key.json | 8 + .../choosing_payload_nested_key_output.json | 8 + .../src/choosing_payload_simple_json.json | 1 + .../choosing_payload_simple_json_output.json | 8 + .../src/choosing_payload_top_keys.json | 5 + .../src/choosing_payload_top_keys_output.json | 5 + .../src/data_masking_function_example.py | 26 + .../data_masking_function_example_output.json | 34 + .../data_masking/src/encrypt_data_output.json | 3 + .../data_masking/src/generic_data_input.json | 21 + .../src/getting_started_decrypt_data.py | 26 + .../getting_started_decrypt_data_input.json | 3 + .../getting_started_decrypt_data_output.json | 18 + .../src/getting_started_decryption_context.py | 31 + .../src/getting_started_encrypt_data.py | 28 + .../src/getting_started_encryption_context.py | 31 + .../src/getting_started_erase_data.py | 19 + .../getting_started_erase_data_output.json | 13 + .../data_masking/src/large_data_input.json | 32 + .../data_masking/src/using_multiple_keys.py | 29 + examples/data_masking/tests/lambda_mask.py | 14 + .../data_masking/tests/test_lambda_mask.py | 30 + mkdocs.yml | 1 + mypy.ini | 8 +- poetry.lock | 410 +++++------ pyproject.toml | 5 +- .../data_masking/handlers/basic_handler.py | 6 +- .../e2e/data_masking/test_e2e_data_masking.py | 18 +- .../data_masking/test_aws_encryption_sdk.py | 301 +++++++-- .../pt-load-test-stack/function_1024/app.py | 6 +- .../pt-load-test-stack/function_128/app.py | 6 +- .../pt-load-test-stack/function_1769/app.py | 6 +- .../pt-load-test-stack/template.yaml | 12 +- .../data_masking/test_perf_data_masking.py | 12 +- tests/unit/data_masking/test_kms_provider.py | 42 ++ .../data_masking/test_unit_data_masking.py | 132 ++-- 73 files changed, 2709 insertions(+), 750 deletions(-) delete mode 100644 aws_lambda_powertools/utilities/_data_masking/base.py delete mode 100644 aws_lambda_powertools/utilities/_data_masking/constants.py delete mode 100644 aws_lambda_powertools/utilities/_data_masking/provider/__init__.py delete mode 100644 aws_lambda_powertools/utilities/_data_masking/provider/base.py delete mode 100644 aws_lambda_powertools/utilities/_data_masking/provider/kms/__init__.py delete mode 100644 aws_lambda_powertools/utilities/_data_masking/provider/kms/aws_encryption_sdk.py rename aws_lambda_powertools/utilities/{_data_masking => data_masking}/__init__.py (81%) create mode 100644 aws_lambda_powertools/utilities/data_masking/base.py create mode 100644 aws_lambda_powertools/utilities/data_masking/constants.py create mode 100644 aws_lambda_powertools/utilities/data_masking/exceptions.py create mode 100644 aws_lambda_powertools/utilities/data_masking/provider/__init__.py create mode 100644 aws_lambda_powertools/utilities/data_masking/provider/base.py create mode 100644 aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py create mode 100644 aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py create mode 100644 docs/utilities/data_masking.md create mode 100644 examples/data_masking/sam/template.yaml create mode 100644 examples/data_masking/src/advanced_custom_serializer.py create mode 100644 examples/data_masking/src/aws_encryption_provider_example.py create mode 100644 examples/data_masking/src/changing_default_algorithm.py create mode 100644 examples/data_masking/src/choosing_payload_all_nested_keys.json create mode 100644 examples/data_masking/src/choosing_payload_all_nested_keys_output.json create mode 100644 examples/data_masking/src/choosing_payload_complex_nested_keys.json create mode 100644 examples/data_masking/src/choosing_payload_complex_nested_keys_output.json create mode 100644 examples/data_masking/src/choosing_payload_complex_search.json create mode 100644 examples/data_masking/src/choosing_payload_complex_search_output.json create mode 100644 examples/data_masking/src/choosing_payload_list_all_index.json create mode 100644 examples/data_masking/src/choosing_payload_list_all_index_output.json create mode 100644 examples/data_masking/src/choosing_payload_list_index.json create mode 100644 examples/data_masking/src/choosing_payload_list_index_output.json create mode 100644 examples/data_masking/src/choosing_payload_list_slice.json create mode 100644 examples/data_masking/src/choosing_payload_list_slice_output.json create mode 100644 examples/data_masking/src/choosing_payload_multiple_keys.json create mode 100644 examples/data_masking/src/choosing_payload_multiple_keys_output.json create mode 100644 examples/data_masking/src/choosing_payload_nested_key.json create mode 100644 examples/data_masking/src/choosing_payload_nested_key_output.json create mode 100644 examples/data_masking/src/choosing_payload_simple_json.json create mode 100644 examples/data_masking/src/choosing_payload_simple_json_output.json create mode 100644 examples/data_masking/src/choosing_payload_top_keys.json create mode 100644 examples/data_masking/src/choosing_payload_top_keys_output.json create mode 100644 examples/data_masking/src/data_masking_function_example.py create mode 100644 examples/data_masking/src/data_masking_function_example_output.json create mode 100644 examples/data_masking/src/encrypt_data_output.json create mode 100644 examples/data_masking/src/generic_data_input.json create mode 100644 examples/data_masking/src/getting_started_decrypt_data.py create mode 100644 examples/data_masking/src/getting_started_decrypt_data_input.json create mode 100644 examples/data_masking/src/getting_started_decrypt_data_output.json create mode 100644 examples/data_masking/src/getting_started_decryption_context.py create mode 100644 examples/data_masking/src/getting_started_encrypt_data.py create mode 100644 examples/data_masking/src/getting_started_encryption_context.py create mode 100644 examples/data_masking/src/getting_started_erase_data.py create mode 100644 examples/data_masking/src/getting_started_erase_data_output.json create mode 100644 examples/data_masking/src/large_data_input.json create mode 100644 examples/data_masking/src/using_multiple_keys.py create mode 100644 examples/data_masking/tests/lambda_mask.py create mode 100644 examples/data_masking/tests/test_lambda_mask.py create mode 100644 tests/unit/data_masking/test_kms_provider.py diff --git a/Makefile b/Makefile index 80c89f72961..7fa170b28c6 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ dev: pip install --upgrade pip pre-commit poetry poetry config --local virtualenvs.in-project true @$(MAKE) dev-version-plugin - poetry install --extras "all datamasking-aws-sdk redis" + poetry install --extras "all redis" pre-commit install dev-gitpod: pip install --upgrade pip poetry @$(MAKE) dev-version-plugin - poetry install --extras "all datamasking-aws-sdk redis" + poetry install --extras "all redis" pre-commit install format: diff --git a/README.md b/README.md index d230c31906e..d3f0ec30603 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverles * **[Event source data classes](https://docs.powertools.aws.dev/lambda/python/latest/utilities/data_classes/)** - Data classes describing the schema of common Lambda event triggers * **[Parser](https://docs.powertools.aws.dev/lambda/python/latest/utilities/parser/)** - Data parsing and deep validation using Pydantic * **[Idempotency](https://docs.powertools.aws.dev/lambda/python/latest/utilities/idempotency/)** - Convert your Lambda functions into idempotent operations which are safe to retry +* **[Data Masking](https://docs.powertools.aws.dev/lambda/python/latest/utilities/data_masking/)** - Protect confidential data with easy removal or encryption * **[Feature Flags](https://docs.powertools.aws.dev/lambda/python/latest/utilities/feature_flags/)** - A simple rule engine to evaluate when one or multiple features should be enabled depending on the input * **[Streaming](https://docs.powertools.aws.dev/lambda/python/latest/utilities/streaming/)** - Streams datasets larger than the available memory as streaming data. diff --git a/aws_lambda_powertools/shared/functions.py b/aws_lambda_powertools/shared/functions.py index c427f0d720f..9765f55c025 100644 --- a/aws_lambda_powertools/shared/functions.py +++ b/aws_lambda_powertools/shared/functions.py @@ -96,10 +96,18 @@ def resolve_env_var_choice( def base64_decode(value: str) -> bytes: try: - logger.debug("Decoding base64 record item before parsing") + logger.debug("Decoding base64 item to bytes") return base64.b64decode(value) except (BinAsciiError, TypeError): - raise ValueError("base64 decode failed") + raise ValueError("base64 decode failed - is this base64 encoded string?") + + +def bytes_to_base64_string(value: bytes) -> str: + try: + logger.debug("Encoding bytes to base64 string") + return base64.b64encode(value).decode() + except TypeError: + raise ValueError(f"base64 encoding failed - is this bytes data? type: {type(value)}") def bytes_to_string(value: bytes) -> str: diff --git a/aws_lambda_powertools/utilities/_data_masking/base.py b/aws_lambda_powertools/utilities/_data_masking/base.py deleted file mode 100644 index 211e44c3759..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/base.py +++ /dev/null @@ -1,174 +0,0 @@ -import json -from typing import Optional, Union - -from aws_lambda_powertools.utilities._data_masking.provider import BaseProvider - - -class DataMasking: - """ - Note: This utility is currently in a Non-General Availability (Non-GA) phase and may have limitations. - Please DON'T USE THIS utility in production environments. - Keep in mind that when we transition to General Availability (GA), there might be breaking changes introduced. - - A utility class for masking sensitive data within various data types. - - This class provides methods for masking sensitive information, such as personal - identifiers or confidential data, within different data types such as strings, - dictionaries, lists, and more. It helps protect sensitive information while - preserving the structure of the original data. - - Usage: - Instantiate an object of this class and use its methods to mask sensitive data - based on the data type. Supported data types include strings, dictionaries, - and more. - - Example: - ``` - from aws_lambda_powertools.utilities.data_masking.base import DataMasking - - def lambda_handler(event, context): - masker = DataMasking() - - data = { - "project": "powertools", - "sensitive": "xxxxxxxxxx" - } - - masked = masker.mask(data,fields=["sensitive"]) - - return masked - - ``` - """ - - def __init__(self, provider: Optional[BaseProvider] = None): - self.provider = provider or BaseProvider() - - def encrypt(self, data, fields=None, **provider_options): - return self._apply_action(data, fields, self.provider.encrypt, **provider_options) - - def decrypt(self, data, fields=None, **provider_options): - return self._apply_action(data, fields, self.provider.decrypt, **provider_options) - - def mask(self, data, fields=None, **provider_options): - return self._apply_action(data, fields, self.provider.mask, **provider_options) - - def _apply_action(self, data, fields, action, **provider_options): - """ - Helper method to determine whether to apply a given action to the entire input data - or to specific fields if the 'fields' argument is specified. - - Parameters - ---------- - data : any - The input data to process. - fields : Optional[List[any]] = None - A list of fields to apply the action to. If 'None', the action is applied to the entire 'data'. - action : Callable - The action to apply to the data. It should be a callable that performs an operation on the data - and returns the modified value. - - Returns - ------- - any - The modified data after applying the action. - """ - - if fields is not None: - return self._apply_action_to_fields(data, fields, action, **provider_options) - else: - return action(data, **provider_options) - - def _apply_action_to_fields( - self, - data: Union[dict, str], - fields: list, - action, - **provider_options, - ) -> Union[dict, str]: - """ - This method takes the input data, which can be either a dictionary or a JSON string, - and applies a mask, an encryption, or a decryption to the specified fields. - - Parameters - ---------- - data : Union[dict, str]) - The input data to process. It can be either a dictionary or a JSON string. - fields : List - A list of fields to apply the action to. Each field can be specified as a string or - a list of strings representing nested keys in the dictionary. - action : Callable - The action to apply to the fields. It should be a callable that takes the current - value of the field as the first argument and any additional arguments that might be required - for the action. It performs an operation on the current value using the provided arguments and - returns the modified value. - **provider_options: - Additional keyword arguments to pass to the 'action' function. - - Returns - ------- - dict - The modified dictionary after applying the action to the - specified fields. - - Raises - ------- - ValueError - If 'fields' parameter is None. - TypeError - If the 'data' parameter is not a traversable type - - Example - ------- - ```python - >>> data = {'a': {'b': {'c': 1}}, 'x': {'y': 2}} - >>> fields = ['a.b.c', 'a.x.y'] - # The function will transform the value at 'a.b.c' (1) and 'a.x.y' (2) - # and store the result as: - new_dict = {'a': {'b': {'c': 'transformed_value'}}, 'x': {'y': 'transformed_value'}} - ``` - """ - - if fields is None: - raise ValueError("No fields specified.") - - if isinstance(data, str): - # Parse JSON string as dictionary - my_dict_parsed = json.loads(data) - elif isinstance(data, dict): - # In case their data has keys that are not strings (i.e. ints), convert it all into a JSON string - my_dict_parsed = json.dumps(data) - # Turn back into dict so can parse it - my_dict_parsed = json.loads(my_dict_parsed) - else: - raise TypeError( - f"Unsupported data type for 'data' parameter. Expected a traversable type, but got {type(data)}.", - ) - - # For example: ['a.b.c'] in ['a.b.c', 'a.x.y'] - for nested_key in fields: - # Prevent overriding loop variable - curr_nested_key = nested_key - - # If the nested_key is not a string, convert it to a string representation - if not isinstance(curr_nested_key, str): - curr_nested_key = json.dumps(curr_nested_key) - - # Split the nested key string into a list of nested keys - # ['a.b.c'] -> ['a', 'b', 'c'] - keys = curr_nested_key.split(".") - - # Initialize a current dictionary to the root dictionary - curr_dict = my_dict_parsed - - # Traverse the dictionary hierarchy by iterating through the list of nested keys - for key in keys[:-1]: - curr_dict = curr_dict[key] - - # Retrieve the final value of the nested field - valtochange = curr_dict[(keys[-1])] - - # Apply the specified 'action' to the target value - curr_dict[keys[-1]] = action(valtochange, **provider_options) - - return my_dict_parsed diff --git a/aws_lambda_powertools/utilities/_data_masking/constants.py b/aws_lambda_powertools/utilities/_data_masking/constants.py deleted file mode 100644 index 47e74f472cf..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/constants.py +++ /dev/null @@ -1,5 +0,0 @@ -DATA_MASKING_STRING: str = "*****" -CACHE_CAPACITY: int = 100 -MAX_CACHE_AGE_SECONDS: float = 300.0 -MAX_MESSAGES_ENCRYPTED: int = 200 -# NOTE: You can also set max messages/bytes per data key diff --git a/aws_lambda_powertools/utilities/_data_masking/provider/__init__.py b/aws_lambda_powertools/utilities/_data_masking/provider/__init__.py deleted file mode 100644 index 7ee07f964b1..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/provider/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from aws_lambda_powertools.utilities._data_masking.provider.base import BaseProvider - -__all__ = [ - "BaseProvider", -] diff --git a/aws_lambda_powertools/utilities/_data_masking/provider/base.py b/aws_lambda_powertools/utilities/_data_masking/provider/base.py deleted file mode 100644 index a293c6aff9a..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/provider/base.py +++ /dev/null @@ -1,34 +0,0 @@ -import json -from typing import Any - -from aws_lambda_powertools.utilities._data_masking.constants import DATA_MASKING_STRING - - -class BaseProvider: - """ - When you try to create an instance of a subclass that does not implement the encrypt method, - you will get a NotImplementedError with a message that says the method is not implemented: - """ - - def __init__(self, json_serializer=None, json_deserializer=None) -> None: - self.json_serializer = json_serializer or self.default_json_serializer - self.json_deserializer = json_deserializer or self.default_json_deserializer - - def default_json_serializer(self, data): - return json.dumps(data).encode("utf-8") - - def default_json_deserializer(self, data): - return json.loads(data.decode("utf-8")) - - def encrypt(self, data) -> str: - raise NotImplementedError("Subclasses must implement encrypt()") - - def decrypt(self, data) -> Any: - raise NotImplementedError("Subclasses must implement decrypt()") - - def mask(self, data) -> Any: - if isinstance(data, (str, dict, bytes)): - return DATA_MASKING_STRING - elif isinstance(data, (list, tuple, set)): - return type(data)([DATA_MASKING_STRING] * len(data)) - return DATA_MASKING_STRING diff --git a/aws_lambda_powertools/utilities/_data_masking/provider/kms/__init__.py b/aws_lambda_powertools/utilities/_data_masking/provider/kms/__init__.py deleted file mode 100644 index f257339d634..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/provider/kms/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import AwsEncryptionSdkProvider - -__all__ = [ - "AwsEncryptionSdkProvider", -] diff --git a/aws_lambda_powertools/utilities/_data_masking/provider/kms/aws_encryption_sdk.py b/aws_lambda_powertools/utilities/_data_masking/provider/kms/aws_encryption_sdk.py deleted file mode 100644 index a895f8de0ac..00000000000 --- a/aws_lambda_powertools/utilities/_data_masking/provider/kms/aws_encryption_sdk.py +++ /dev/null @@ -1,177 +0,0 @@ -from __future__ import annotations - -import base64 -from typing import Any, Callable, Dict, List - -import botocore -from aws_encryption_sdk import ( - CachingCryptoMaterialsManager, - EncryptionSDKClient, - LocalCryptoMaterialsCache, - StrictAwsKmsMasterKeyProvider, -) - -from aws_lambda_powertools.shared.user_agent import register_feature_to_botocore_session -from aws_lambda_powertools.utilities._data_masking.constants import ( - CACHE_CAPACITY, - MAX_CACHE_AGE_SECONDS, - MAX_MESSAGES_ENCRYPTED, -) -from aws_lambda_powertools.utilities._data_masking.provider import BaseProvider - - -class ContextMismatchError(Exception): - def __init__(self, key): - super().__init__(f"Encryption Context does not match expected value for key: {key}") - self.key = key - - -class AwsEncryptionSdkProvider(BaseProvider): - """ - The AwsEncryptionSdkProvider is used as a provider for the DataMasking class. - - This provider allows you to perform data masking using the AWS Encryption SDK - for encryption and decryption. It integrates with the DataMasking class to - securely encrypt and decrypt sensitive data. - - Usage Example: - ``` - from aws_lambda_powertools.utilities.data_masking import DataMasking - from aws_lambda_powertools.utilities.data_masking.providers.kms.aws_encryption_sdk import ( - AwsEncryptionSdkProvider, - ) - - - def lambda_handler(event, context): - provider = AwsEncryptionSdkProvider(["arn:aws:kms:us-east-1:0123456789012:key/key-id"]) - masker = DataMasking(provider=provider) - - data = { - "project": "powertools", - "sensitive": "xxxxxxxxxx" - } - - masked = masker.encrypt(data,fields=["sensitive"]) - - return masked - - ``` - """ - - def __init__( - self, - keys: List[str], - key_provider=None, - local_cache_capacity: int = CACHE_CAPACITY, - max_cache_age_seconds: float = MAX_CACHE_AGE_SECONDS, - max_messages_encrypted: int = MAX_MESSAGES_ENCRYPTED, - json_serializer: Callable | None = None, - json_deserializer: Callable | None = None, - ): - super().__init__(json_serializer=json_serializer, json_deserializer=json_deserializer) - - self._key_provider = key_provider or KMSKeyProvider( - keys=keys, - local_cache_capacity=local_cache_capacity, - max_cache_age_seconds=max_cache_age_seconds, - max_messages_encrypted=max_messages_encrypted, - json_serializer=self.json_serializer, - json_deserializer=self.json_deserializer, - ) - - def encrypt(self, data: bytes | str | Dict | int, **provider_options) -> str: - return self._key_provider.encrypt(data=data, **provider_options) - - def decrypt(self, data: str, **provider_options) -> Any: - return self._key_provider.decrypt(data=data, **provider_options) - - -class KMSKeyProvider: - - """ - The KMSKeyProvider is responsible for assembling an AWS Key Management Service (KMS) - client, a caching mechanism, and a keyring for secure key management and data encryption. - """ - - def __init__( - self, - keys: List[str], - json_serializer: Callable, - json_deserializer: Callable, - local_cache_capacity: int = CACHE_CAPACITY, - max_cache_age_seconds: float = MAX_CACHE_AGE_SECONDS, - max_messages_encrypted: int = MAX_MESSAGES_ENCRYPTED, - ): - session = botocore.session.Session() - register_feature_to_botocore_session(session, "data-masking") - - self.json_serializer = json_serializer - self.json_deserializer = json_deserializer - self.client = EncryptionSDKClient() - self.keys = keys - self.cache = LocalCryptoMaterialsCache(local_cache_capacity) - self.key_provider = StrictAwsKmsMasterKeyProvider(key_ids=self.keys, botocore_session=session) - self.cache_cmm = CachingCryptoMaterialsManager( - master_key_provider=self.key_provider, - cache=self.cache, - max_age=max_cache_age_seconds, - max_messages_encrypted=max_messages_encrypted, - ) - - def encrypt(self, data: bytes | str | Dict | float, **provider_options) -> str: - """ - Encrypt data using the AwsEncryptionSdkProvider. - - Parameters - ------- - data : Union[bytes, str] - The data to be encrypted. - provider_options - Additional options for the aws_encryption_sdk.EncryptionSDKClient - - Returns - ------- - ciphertext : str - The encrypted data, as a base64-encoded string. - """ - data_encoded = self.json_serializer(data) - ciphertext, _ = self.client.encrypt( - source=data_encoded, - materials_manager=self.cache_cmm, - **provider_options, - ) - ciphertext = base64.b64encode(ciphertext).decode() - return ciphertext - - def decrypt(self, data: str, **provider_options) -> Any: - """ - Decrypt data using AwsEncryptionSdkProvider. - - Parameters - ------- - data : Union[bytes, str] - The encrypted data, as a base64-encoded string - provider_options - Additional options for the aws_encryption_sdk.EncryptionSDKClient - - Returns - ------- - ciphertext : bytes - The decrypted data in bytes - """ - ciphertext_decoded = base64.b64decode(data) - - expected_context = provider_options.pop("encryption_context", {}) - - ciphertext, decryptor_header = self.client.decrypt( - source=ciphertext_decoded, - key_provider=self.key_provider, - **provider_options, - ) - - for key, value in expected_context.items(): - if decryptor_header.encryption_context.get(key) != value: - raise ContextMismatchError(key) - - ciphertext = self.json_deserializer(ciphertext) - return ciphertext diff --git a/aws_lambda_powertools/utilities/_data_masking/__init__.py b/aws_lambda_powertools/utilities/data_masking/__init__.py similarity index 81% rename from aws_lambda_powertools/utilities/_data_masking/__init__.py rename to aws_lambda_powertools/utilities/data_masking/__init__.py index 806c856ba75..4d767e83ce1 100644 --- a/aws_lambda_powertools/utilities/_data_masking/__init__.py +++ b/aws_lambda_powertools/utilities/data_masking/__init__.py @@ -4,7 +4,7 @@ Keep in mind that when we transition to General Availability (GA), there might be breaking changes introduced. """ -from aws_lambda_powertools.utilities._data_masking.base import DataMasking +from aws_lambda_powertools.utilities.data_masking.base import DataMasking __all__ = [ "DataMasking", diff --git a/aws_lambda_powertools/utilities/data_masking/base.py b/aws_lambda_powertools/utilities/data_masking/base.py new file mode 100644 index 00000000000..c2557dcef24 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/base.py @@ -0,0 +1,291 @@ +from __future__ import annotations + +import functools +import logging +import warnings +from numbers import Number +from typing import Any, Callable, Mapping, Optional, Sequence, Union, overload + +from jsonpath_ng.ext import parse + +from aws_lambda_powertools.utilities.data_masking.exceptions import ( + DataMaskingFieldNotFoundError, + DataMaskingUnsupportedTypeError, +) +from aws_lambda_powertools.utilities.data_masking.provider import BaseProvider + +logger = logging.getLogger(__name__) + + +class DataMasking: + """ + Note: This utility is currently in a Non-General Availability (Non-GA) phase and may have limitations. + Please DON'T USE THIS utility in production environments. + Keep in mind that when we transition to General Availability (GA), there might be breaking changes introduced. + + The DataMasking class orchestrates erasing, encrypting, and decrypting + for the base provider. + + Example: + ``` + from aws_lambda_powertools.utilities.data_masking.base import DataMasking + + def lambda_handler(event, context): + masker = DataMasking() + + data = { + "project": "powertools", + "sensitive": "password" + } + + erased = masker.erase(data,fields=["sensitive"]) + + return erased + + ``` + """ + + def __init__( + self, + provider: Optional[BaseProvider] = None, + raise_on_missing_field: bool = True, + ): + self.provider = provider or BaseProvider() + # NOTE: we depend on Provider to not confuse customers in passing the same 2 serializers in 2 places + self.json_serializer = self.provider.json_serializer + self.json_deserializer = self.provider.json_deserializer + self.raise_on_missing_field = raise_on_missing_field + + def encrypt( + self, + data: dict | Mapping | Sequence | Number, + provider_options: dict | None = None, + **encryption_context: str, + ) -> str: + return self._apply_action( + data=data, + fields=None, + action=self.provider.encrypt, + provider_options=provider_options or {}, + **encryption_context, + ) + + def decrypt( + self, + data, + provider_options: dict | None = None, + **encryption_context: str, + ) -> Any: + return self._apply_action( + data=data, + fields=None, + action=self.provider.decrypt, + provider_options=provider_options or {}, + **encryption_context, + ) + + @overload + def erase(self, data, fields: None) -> str: + ... + + @overload + def erase(self, data: list, fields: list[str]) -> list[str]: + ... + + @overload + def erase(self, data: tuple, fields: list[str]) -> tuple[str]: + ... + + @overload + def erase(self, data: dict, fields: list[str]) -> dict: + ... + + def erase(self, data: Sequence | Mapping, fields: list[str] | None = None) -> str | list[str] | tuple[str] | dict: + return self._apply_action(data=data, fields=fields, action=self.provider.erase) + + def _apply_action( + self, + data, + fields: list[str] | None, + action: Callable, + provider_options: dict | None = None, + **encryption_context: str, + ): + """ + Helper method to determine whether to apply a given action to the entire input data + or to specific fields if the 'fields' argument is specified. + + Parameters + ---------- + data : str | dict + The input data to process. + fields : Optional[List[str]] + A list of fields to apply the action to. If 'None', the action is applied to the entire 'data'. + action : Callable + The action to apply to the data. It should be a callable that performs an operation on the data + and returns the modified value. + provider_options : dict + Provider specific keyword arguments to propagate; used as an escape hatch. + encryption_context: str + Encryption context to use in encrypt and decrypt operations. + + Returns + ------- + any + The modified data after applying the action. + """ + + if fields is not None: + logger.debug(f"Running action {action.__name__} with fields {fields}") + return self._apply_action_to_fields( + data=data, + fields=fields, + action=action, + provider_options=provider_options, + **encryption_context, + ) + else: + logger.debug(f"Running action {action.__name__} with the entire data") + return action(data=data, provider_options=provider_options, **encryption_context) + + def _apply_action_to_fields( + self, + data: Union[dict, str], + fields: list, + action: Callable, + provider_options: dict | None = None, + **encryption_context: str, + ) -> Union[dict, str]: + """ + This method takes the input data, which can be either a dictionary or a JSON string, + and erases, encrypts, or decrypts the specified fields. + + Parameters + ---------- + data : Union[dict, str]) + The input data to process. It can be either a dictionary or a JSON string. + fields : List + A list of fields to apply the action to. Each field can be specified as a string or + a list of strings representing nested keys in the dictionary. + action : Callable + The action to apply to the fields. It should be a callable that takes the current + value of the field as the first argument and any additional arguments that might be required + for the action. It performs an operation on the current value using the provided arguments and + returns the modified value. + provider_options : dict + Optional dictionary representing additional options for the action. + **encryption_context: str + Additional keyword arguments collected into a dictionary. + + Returns + ------- + dict | str + The modified dictionary or string after applying the action to the + specified fields. + + Raises + ------- + ValueError + If 'fields' parameter is None. + TypeError + If the 'data' parameter is not a traversable type + + Example + ------- + ```python + >>> data = {'a': {'b': {'c': 1}}, 'x': {'y': 2}} + >>> fields = ['a.b.c', 'a.x.y'] + # The function will transform the value at 'a.b.c' (1) and 'a.x.y' (2) + # and store the result as: + new_dict = {'a': {'b': {'c': '*****'}}, 'x': {'y': '*****'}} + ``` + """ + + data_parsed: dict = self._normalize_data_to_parse(fields, data) + + # For in-place updates, json_parse accepts a callback function + # this function must receive 3 args: field_value, fields, field_name + # We create a partial callback to pre-populate known options (action, provider opts, enc ctx) + update_callback = functools.partial( + self._call_action, + action=action, + provider_options=provider_options, + **encryption_context, + ) + + # Iterate over each field to be parsed. + for field_parse in fields: + # Parse the field expression using a 'parse' function. + json_parse = parse(field_parse) + # Find the corresponding keys in the normalized data using the parsed expression. + result_parse = json_parse.find(data_parsed) + + if not result_parse: + if self.raise_on_missing_field: + # If the data for the field is not found, raise an exception. + raise DataMaskingFieldNotFoundError(f"Field or expression {field_parse} not found in {data_parsed}") + else: + # If the data for the field is not found, warning. + warnings.warn(f"Field or expression {field_parse} not found in {data_parsed}", stacklevel=2) + + # For in-place updates, json_parse accepts a callback function + # that receives 3 args: field_value, fields, field_name + # We create a partial callback to pre-populate known provider options (action, provider opts, enc ctx) + update_callback = functools.partial( + self._call_action, + action=action, + provider_options=provider_options, + **encryption_context, + ) + + json_parse.update( + data_parsed, + lambda field_value, fields, field_name: update_callback(field_value, fields, field_name), # noqa: B023 + ) + + return data_parsed + + @staticmethod + def _call_action( + field_value: Any, + fields: dict[str, Any], + field_name: str, + action: Callable, + provider_options: dict | None = None, + **encryption_context, + ) -> None: + """ + Apply a specified action to a field value and update the fields dictionary. + + Params: + -------- + - field_value: Current value of the field being processed. + - fields: Dictionary representing the fields being processed (mutable). + - field_name: Name of the field being processed. + - action: Callable (function or method) to be applied to the field_value. + - provider_options: Optional dictionary representing additional options for the action. + - **encryption_context: Additional keyword arguments collected into a dictionary. + + Returns: + - fields[field_name]: Returns the processed field value + """ + fields[field_name] = action(field_value, provider_options=provider_options, **encryption_context) + return fields[field_name] + + def _normalize_data_to_parse(self, fields: list, data: str | dict) -> dict: + if not fields: + raise ValueError("No fields specified.") + + if isinstance(data, str): + # Parse JSON string as dictionary + data_parsed = self.json_deserializer(data) + elif isinstance(data, dict): + # Convert the data to a JSON string in case it contains non-string keys (e.g., ints) + # Parse the JSON string back into a dictionary + data_parsed = self.json_deserializer(self.json_serializer(data)) + else: + raise DataMaskingUnsupportedTypeError( + f"Unsupported data type. Expected a traversable type (dict or str), but got {type(data)}.", + ) + + return data_parsed diff --git a/aws_lambda_powertools/utilities/data_masking/constants.py b/aws_lambda_powertools/utilities/data_masking/constants.py new file mode 100644 index 00000000000..f35f4291e40 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/constants.py @@ -0,0 +1,14 @@ +# The string that replaces values that have been erased +DATA_MASKING_STRING: str = "*****" +# The maximum number of entries that can be retained in the local cryptographic materials cache +CACHE_CAPACITY: int = 100 +# The maximum time (in seconds) that a cache entry may be kept in the cache +MAX_CACHE_AGE_SECONDS: float = 300.0 +# Maximum number of messages which are allowed to be encrypted under a single cached data key +# Values can be [1 - 4294967296] (2 ** 32) +MAX_MESSAGES_ENCRYPTED: int = 4294967296 +# Maximum number of bytes which are allowed to be encrypted under a single cached data key +# Values can be [1 - 9223372036854775807] (2 ** 63 - 1) +MAX_BYTES_ENCRYPTED: int = 9223372036854775807 + +ENCRYPTED_DATA_KEY_CTX_KEY = "aws-crypto-public-key" diff --git a/aws_lambda_powertools/utilities/data_masking/exceptions.py b/aws_lambda_powertools/utilities/data_masking/exceptions.py new file mode 100644 index 00000000000..7c962ddf385 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/exceptions.py @@ -0,0 +1,34 @@ +class DataMaskingUnsupportedTypeError(Exception): + """ + UnsupportedType Error + """ + + +class DataMaskingDecryptKeyError(Exception): + """ + Decrypting with an invalid AWS KMS Key ARN. + """ + + +class DataMaskingEncryptKeyError(Exception): + """ + Encrypting with an invalid AWS KMS Key ARN. + """ + + +class DataMaskingDecryptValueError(Exception): + """ + Decrypting an invalid field. + """ + + +class DataMaskingContextMismatchError(Exception): + """ + Decrypting with the incorrect encryption context. + """ + + +class DataMaskingFieldNotFoundError(Exception): + """ + Field not found. + """ diff --git a/aws_lambda_powertools/utilities/data_masking/provider/__init__.py b/aws_lambda_powertools/utilities/data_masking/provider/__init__.py new file mode 100644 index 00000000000..5a0180eb82b --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/provider/__init__.py @@ -0,0 +1,5 @@ +from aws_lambda_powertools.utilities.data_masking.provider.base import BaseProvider + +__all__ = [ + "BaseProvider", +] diff --git a/aws_lambda_powertools/utilities/data_masking/provider/base.py b/aws_lambda_powertools/utilities/data_masking/provider/base.py new file mode 100644 index 00000000000..3aacba1b7b2 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/provider/base.py @@ -0,0 +1,81 @@ +from __future__ import annotations + +import functools +import json +from typing import Any, Callable, Iterable + +from aws_lambda_powertools.utilities.data_masking.constants import DATA_MASKING_STRING + + +class BaseProvider: + """ + The BaseProvider class serves as an abstract base class for data masking providers. + + Examples + -------- + ``` + from aws_lambda_powertools.utilities._data_masking.provider import BaseProvider + from aws_lambda_powertools.utilities.data_masking import DataMasking + + class MyCustomProvider(BaseProvider): + def encrypt(self, data) -> str: + # Implementation logic for data encryption + + def decrypt(self, data) -> Any: + # Implementation logic for data decryption + + def erase(self, data) -> Union[str, Iterable]: + # Implementation logic for data masking + pass + + def lambda_handler(event, context): + provider = MyCustomProvider(["secret-key"]) + data_masker = DataMasking(provider=provider) + + data = { + "project": "powertools", + "sensitive": "password" + } + + encrypted = data_masker.encrypt(data) + + return encrypted + ``` + """ + + def __init__( + self, + json_serializer: Callable[..., str] = functools.partial(json.dumps, ensure_ascii=False), + json_deserializer: Callable[[str], Any] = json.loads, + ) -> None: + self.json_serializer = json_serializer + self.json_deserializer = json_deserializer + + def encrypt(self, data, provider_options: dict | None = None, **encryption_context: str) -> str: + """ + Abstract method for encrypting data. Subclasses must implement this method. + """ + raise NotImplementedError("Subclasses must implement encrypt()") + + def decrypt(self, data, provider_options: dict | None = None, **encryption_context: str) -> Any: + """ + Abstract method for decrypting data. Subclasses must implement this method. + """ + raise NotImplementedError("Subclasses must implement decrypt()") + + def erase(self, data, **kwargs) -> Iterable[str]: + """ + This method irreversibly erases data. + + If the data to be erased is of type `str`, `dict`, or `bytes`, + this method will return an erased string, i.e. "*****". + + If the data to be erased is of an iterable type like `list`, `tuple`, + or `set`, this method will return a new object of the same type as the + input data but with each element replaced by the string "*****". + """ + if isinstance(data, (str, dict, bytes)): + return DATA_MASKING_STRING + elif isinstance(data, (list, tuple, set)): + return type(data)([DATA_MASKING_STRING] * len(data)) + return DATA_MASKING_STRING diff --git a/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py b/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py new file mode 100644 index 00000000000..c1353094144 --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/provider/kms/__init__.py @@ -0,0 +1,5 @@ +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider + +__all__ = [ + "AWSEncryptionSDKProvider", +] diff --git a/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py b/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py new file mode 100644 index 00000000000..bbdbb0bad6f --- /dev/null +++ b/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py @@ -0,0 +1,247 @@ +from __future__ import annotations + +import functools +import json +import logging +from binascii import Error +from typing import Any, Callable, List + +import botocore +from aws_encryption_sdk import ( + CachingCryptoMaterialsManager, + EncryptionSDKClient, + LocalCryptoMaterialsCache, + StrictAwsKmsMasterKeyProvider, +) +from aws_encryption_sdk.exceptions import ( + DecryptKeyError, + GenerateKeyError, + NotSupportedError, +) +from aws_encryption_sdk.structures import MessageHeader + +from aws_lambda_powertools.shared.functions import ( + base64_decode, + bytes_to_base64_string, + bytes_to_string, +) +from aws_lambda_powertools.shared.user_agent import register_feature_to_botocore_session +from aws_lambda_powertools.utilities.data_masking.constants import ( + CACHE_CAPACITY, + ENCRYPTED_DATA_KEY_CTX_KEY, + MAX_BYTES_ENCRYPTED, + MAX_CACHE_AGE_SECONDS, + MAX_MESSAGES_ENCRYPTED, +) +from aws_lambda_powertools.utilities.data_masking.exceptions import ( + DataMaskingContextMismatchError, + DataMaskingDecryptKeyError, + DataMaskingDecryptValueError, + DataMaskingEncryptKeyError, + DataMaskingUnsupportedTypeError, +) +from aws_lambda_powertools.utilities.data_masking.provider import BaseProvider + +logger = logging.getLogger(__name__) + + +class AWSEncryptionSDKProvider(BaseProvider): + """ + The AWSEncryptionSDKProvider is used as a provider for the DataMasking class. + + Usage + ------- + ``` + from aws_lambda_powertools.utilities.data_masking import DataMasking + from aws_lambda_powertools.utilities.data_masking.providers.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, + ) + + + def lambda_handler(event, context): + provider = AWSEncryptionSDKProvider(["arn:aws:kms:us-east-1:0123456789012:key/key-id"]) + data_masker = DataMasking(provider=provider) + + data = { + "project": "powertools", + "sensitive": "password" + } + + encrypted = data_masker.encrypt(data) + + return encrypted + + ``` + """ + + def __init__( + self, + keys: List[str], + key_provider=None, + local_cache_capacity: int = CACHE_CAPACITY, + max_cache_age_seconds: float = MAX_CACHE_AGE_SECONDS, + max_messages_encrypted: int = MAX_MESSAGES_ENCRYPTED, + max_bytes_encrypted: int = MAX_BYTES_ENCRYPTED, + json_serializer: Callable[..., str] = functools.partial(json.dumps, ensure_ascii=False), + json_deserializer: Callable[[str], Any] = json.loads, + ): + super().__init__(json_serializer=json_serializer, json_deserializer=json_deserializer) + + self._key_provider = key_provider or KMSKeyProvider( + keys=keys, + local_cache_capacity=local_cache_capacity, + max_cache_age_seconds=max_cache_age_seconds, + max_messages_encrypted=max_messages_encrypted, + max_bytes_encrypted=max_bytes_encrypted, + json_serializer=json_serializer, + json_deserializer=json_deserializer, + ) + + def encrypt(self, data: Any, provider_options: dict | None = None, **encryption_context: str) -> str: + return self._key_provider.encrypt(data=data, provider_options=provider_options, **encryption_context) + + def decrypt(self, data: str, provider_options: dict | None = None, **encryption_context: str) -> Any: + return self._key_provider.decrypt(data=data, provider_options=provider_options, **encryption_context) + + +class KMSKeyProvider: + + """ + The KMSKeyProvider is responsible for assembling an AWS Key Management Service (KMS) + client, a caching mechanism, and a keyring for secure key management and data encryption. + """ + + def __init__( + self, + keys: List[str], + json_serializer: Callable[..., str], + json_deserializer: Callable[[str], Any], + local_cache_capacity: int = CACHE_CAPACITY, + max_cache_age_seconds: float = MAX_CACHE_AGE_SECONDS, + max_messages_encrypted: int = MAX_MESSAGES_ENCRYPTED, + max_bytes_encrypted: int = MAX_BYTES_ENCRYPTED, + ): + session = botocore.session.Session() + register_feature_to_botocore_session(session, "data-masking") + + self.json_serializer = json_serializer + self.json_deserializer = json_deserializer + self.client = EncryptionSDKClient() + self.keys = keys + self.cache = LocalCryptoMaterialsCache(local_cache_capacity) + self.key_provider = StrictAwsKmsMasterKeyProvider(key_ids=self.keys, botocore_session=session) + self.cache_cmm = CachingCryptoMaterialsManager( + master_key_provider=self.key_provider, + cache=self.cache, + max_age=max_cache_age_seconds, + max_messages_encrypted=max_messages_encrypted, + max_bytes_encrypted=max_bytes_encrypted, + ) + + def encrypt(self, data: Any, provider_options: dict | None = None, **encryption_context: str) -> str: + """ + Encrypt data using the AWSEncryptionSDKProvider. + + Parameters + ------- + data : Union[bytes, str] + The data to be encrypted. + provider_options : dict + Additional options for the aws_encryption_sdk.EncryptionSDKClient + **encryption_context : str + Additional keyword arguments collected into a dictionary. + + Returns + ------- + ciphertext : str + The encrypted data, as a base64-encoded string. + """ + provider_options = provider_options or {} + self._validate_encryption_context(encryption_context) + + data_encoded = self.json_serializer(data).encode("utf-8") + + try: + ciphertext, _ = self.client.encrypt( + source=data_encoded, + materials_manager=self.cache_cmm, + encryption_context=encryption_context, + **provider_options, + ) + except GenerateKeyError: + raise DataMaskingEncryptKeyError( + "Failed to encrypt data. Please ensure you are using a valid Symmetric AWS KMS Key ARN, not KMS Key ID or alias.", # noqa E501 + ) + + return bytes_to_base64_string(ciphertext) + + def decrypt(self, data: str, provider_options: dict | None = None, **encryption_context: str) -> Any: + """ + Decrypt data using AWSEncryptionSDKProvider. + + Parameters + ------- + data : Union[bytes, str] + The encrypted data, as a base64-encoded string + provider_options + Additional options for the aws_encryption_sdk.EncryptionSDKClient + + Returns + ------- + ciphertext : bytes + The decrypted data in bytes + """ + provider_options = provider_options or {} + self._validate_encryption_context(encryption_context) + + try: + ciphertext_decoded = base64_decode(data) + except Error: + raise DataMaskingDecryptValueError( + "Data decryption failed. Please ensure that you are attempting to decrypt data that was previously encrypted.", # noqa E501 + ) + + try: + decryptor_header: MessageHeader + + ciphertext, decryptor_header = self.client.decrypt( + source=ciphertext_decoded, + key_provider=self.key_provider, + **provider_options, + ) + except DecryptKeyError: + raise DataMaskingDecryptKeyError( + "Failed to decrypt data - Please ensure you are using a valid Symmetric AWS KMS Key ARN, not KMS Key ID or alias.", # noqa E501 + ) + except (TypeError, NotSupportedError): + raise DataMaskingDecryptValueError( + "Data decryption failed. Please ensure that you are attempting to decrypt data that was previously encrypted.", # noqa E501 + ) + + self._compare_encryption_context(decryptor_header.encryption_context, encryption_context) + + decoded_ciphertext = bytes_to_string(ciphertext) + + return self.json_deserializer(decoded_ciphertext) + + @staticmethod + def _validate_encryption_context(context: dict): + if not context: + return + + for key, value in context.items(): + if not isinstance(value, str): + raise DataMaskingUnsupportedTypeError( + f"Encryption context values must be string. Received: {key}={value}", + ) + + @staticmethod + def _compare_encryption_context(actual_context: dict, expected_context: dict): + # We can safely remove encrypted data key after decryption for exact match verification + actual_context.pop(ENCRYPTED_DATA_KEY_CTX_KEY, None) + + # Encryption context could be out of order hence a set + if set(actual_context.items()) != set(expected_context.items()): + raise DataMaskingContextMismatchError( + "Encryption context does not match. You must use the exact same context used during encryption", + ) diff --git a/docs/index.md b/docs/index.md index 7f1ca98fb74..b13bbc122d8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -701,6 +701,7 @@ Core utilities such as Tracing, Logging, Metrics, and Event Handler will be avai | [**Event source data classes**](./utilities/data_classes.md){target="_blank"} | Data classes describing the schema of common Lambda event triggers | | [**Parser**](./utilities/parser.md){target="_blank"} | Data parsing and deep validation using Pydantic | | [**Idempotency**](./utilities/idempotency.md){target="_blank"} | Idempotent Lambda handler | +| [**Data Masking**](./utilities/data_masking.md){target="_blank"} | Protect confidential data with easy removal or encryption | | [**Feature Flags**](./utilities/feature_flags.md){target="_blank"} | A simple rule engine to evaluate when one or multiple features should be enabled depending on the input | | [**Streaming**](./utilities/streaming.md){target="_blank"} | Streams datasets larger than the available memory as streaming data. | diff --git a/docs/utilities/data_masking.md b/docs/utilities/data_masking.md new file mode 100644 index 00000000000..5c30edc6bff --- /dev/null +++ b/docs/utilities/data_masking.md @@ -0,0 +1,638 @@ +--- +title: Data Masking +description: Utility +--- + + + +The data masking utility can encrypt, decrypt, or irreversibly erase sensitive information to protect data confidentiality. + +```mermaid +stateDiagram-v2 + direction LR + LambdaFn: Your Lambda function + DataMasking: DataMasking + Operation: Possible operations + Input: Sensitive value + Erase: Erase + Encrypt: Encrypt + Decrypt: Decrypt + Provider: AWS Encryption SDK provider + Result: Data transformed (erased, encrypted, or decrypted) + + LambdaFn --> DataMasking + DataMasking --> Operation + + state Operation { + [*] --> Input + Input --> Erase: Irreversible + Input --> Encrypt + Input --> Decrypt + Encrypt --> Provider + Decrypt --> Provider + } + + Operation --> Result +``` + +## Key features + +* Encrypt, decrypt, or irreversibly erase data with ease +* Erase sensitive information in one or more fields within nested data +* Seamless integration with [AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html){target="_blank"} for industry and AWS security best practices + +## Terminology + +**Erasing** replaces sensitive information **irreversibly** with a non-sensitive placeholder _(`*****`)_. This operation replaces data in-memory, making it a one-way action. + +**Encrypting** transforms plaintext into ciphertext using an encryption algorithm and a cryptographic key. It allows you to encrypt any sensitive data, so only allowed personnel to decrypt it. Learn more about encryption [here](https://aws.amazon.com/blogs/security/importance-of-encryption-and-how-aws-can-help/){target="_blank"}. + +**Decrypting** transforms ciphertext back into plaintext using a decryption algorithm and the correct decryption key. + +**Encryption context** is a non-secret `key=value` data used for authentication like `tenant_id:`. This adds extra security and confirms encrypted data relationship with a context. + +**[Encrypted message](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/message-format.html){target="_blank"}** is a portable data structure that includes encrypted data along with copies of the encrypted data key. It includes everything Encryption SDK needs to validate authenticity, integrity, and to decrypt with the right master key. + + +**[Envelope encryption](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/concepts.html#envelope-encryption){target="_blank"}** uses two different keys to encrypt data safely: master and data key. The data key encrypts the plaintext, and the master key encrypts the data key. It simplifies key management _(you own the master key)_, isolates compromises to data key, and scales better with large data volumes. + + +
+```mermaid +graph LR + M(Master key) --> |Encrypts| D(Data key) + D(Data key) --> |Encrypts| S(Sensitive data) +``` +Envelope encryption visualized. +
+ +## Getting started + +???+ tip + All examples shared in this documentation are available within the [project repository](https://github.com/aws-powertools/powertools-lambda-python/tree/develop/examples){target="_blank"}. + +### Install + +!!! note "This is not necessary if you're installing Powertools for AWS Lambda (Python) via [Lambda Layer/SAR](../index.md#lambda-layer){target="_blank"}" + +Add `aws-lambda-powertools[datamasking]` as a dependency in your preferred tool: _e.g._, _requirements.txt_, _pyproject.toml_. This will install the [AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html){target="_blank"}. + + +AWS Encryption SDK contains non-Python dependencies. This means you should use [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/using-sam-cli-build.html#using-sam-cli-build-options-container){target="_blank"} or [official build container images](https://gallery.ecr.aws/search?searchTerm=sam%2Fbuild-python&popularRegistries=amazon){target="_blank"} when building your application for AWS Lambda. Local development should work as expected. + + +### Required resources + +!!! info "By default, we use Amazon Key Management Service (KMS) for encryption and decryption operations." + +Before you start, you will need a KMS symmetric key to encrypt and decrypt your data. Your Lambda function will need read and write access to it. + +**NOTE**. We recommend setting a minimum of 1024MB of memory _(CPU intensive)_, and separate Lambda functions for encrypt and decrypt. For more information, you can see the full reports of our [load tests](https://github.com/aws-powertools/powertools-lambda-python/pull/2197#issuecomment-1730571597){target="_blank"} and [traces](https://github.com/aws-powertools/powertools-lambda-python/pull/2197#issuecomment-1732060923){target="_blank"}. + +=== "AWS Serverless Application Model (SAM) example" + ```yaml hl_lines="15 29 41 61 66-67" + --8<-- "examples/data_masking/sam/template.yaml" + ``` + + 1. [Key policy examples using IAM Roles](https://docs.aws.amazon.com/kms/latest/developerguide/key-policy-default.html#key-policy-default-allow-administrators){target="_blank"} + 2. [SAM generated CloudFormation Resources](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-generated-resources-function.html#sam-specification-generated-resources-function-not-role){target="_blank"} + 3. Required only when using [multiple keys](#using-multiple-keys) + +### Erasing data + +Erasing will remove the original data and replace it with a `*****`. This means you cannot recover erased data, and the data type will change to `str` for all data unless the data to be erased is of an Iterable type (`list`, `tuple`, `set`), in which case the method will return a new object of the same type as the input data but with each element replaced by the string `*****`. + +=== "getting_started_erase_data.py" + ```python hl_lines="4 8 17" + --8<-- "examples/data_masking/src/getting_started_erase_data.py" + ``` + + 1. See [working with nested data](#working-with-nested-data) to learn more about the `fields` parameter.

If we omit `fields` parameter, the entire dictionary will be erased with `*****`. + +=== "generic_data_input.json" + ```json hl_lines="7 9 14" + --8<-- "examples/data_masking/src/generic_data_input.json" + ``` + +=== "getting_started_erase_data_output.json" + ```json hl_lines="5 7 12" + --8<-- "examples/data_masking/src/getting_started_erase_data_output.json" + ``` + +### Encrypting data + +???+ note "About static typing and encryption" + Encrypting data may lead to a different data type, as it always transforms into a string _(``)_. + +To encrypt, you will need an [encryption provider](#providers). Here, we will use `AWSEncryptionSDKProvider`. + +Under the hood, we delegate a [number of operations](#encrypt-operation-with-encryption-sdk-kms) to AWS Encryption SDK to authenticate, create a portable encryption message, and actual data encryption. + +=== "getting_started_encrypt_data.py" + ```python hl_lines="6-8 14-15 26" + --8<-- "examples/data_masking/src/getting_started_encrypt_data.py" + ``` + + 1. You can use more than one KMS Key for higher availability but increased latency.

Encryption SDK will ensure the data key is encrypted with both keys. + +=== "generic_data_input.json" + ```json + --8<-- "examples/data_masking/src/generic_data_input.json" + ``` + +=== "encrypt_data_output.json" + ```json + --8<-- "examples/data_masking/src/encrypt_data_output.json" + ``` + +### Decrypting data + +???+ note "About static typing and decryption" + Decrypting data may lead to a different data type, as encrypted data is always a string _(``)_. + +To decrypt, you will need an [encryption provider](#providers). Here, we will use `AWSEncryptionSDKProvider`. + +Under the hood, we delegate a [number of operations](#decrypt-operation-with-encryption-sdk-kms) to AWS Encryption SDK to verify authentication, integrity, and actual ciphertext decryption. + +=== "getting_started_decrypt_data.py" + + **NOTE**. Decryption only works with KMS Key ARN. + + ```python hl_lines="6-7 12-13 24" + --8<-- "examples/data_masking/src/getting_started_decrypt_data.py" + ``` + + 1. Note that KMS key alias or key ID won't work. + 2. You can use more than one KMS Key for higher availability but increased latency.

Encryption SDK will call `Decrypt` API with all master keys when trying to decrypt the data key. + +=== "getting_started_decrypt_data_input.json" + + ```json + --8<-- "examples/data_masking/src/getting_started_decrypt_data_input.json" + ``` + +=== "getting_started_decrypt_data_output.json" + + ```json + --8<-- "examples/data_masking/src/getting_started_decrypt_data_output.json" + ``` + +### Encryption context for integrity and authenticity + + +For a stronger security posture, you can add metadata to each encryption operation, and verify them during decryption. This is known as additional authenticated data (AAD). These are non-sensitive data that can help protect authenticity and integrity of your encrypted data, and even help to prevent a [confused deputy](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html){target="_blank"} situation. + + +???+ danger "Important considerations you should know" + 1. **Exact match verification on decrypt**. Be careful using random data like `timestamps` as encryption context if you can't provide them on decrypt. + 2. **Only `string` values are supported**. We will raise `DataMaskingUnsupportedTypeError` for non-string values. + 3. **Use non-sensitive data only**. When using KMS, encryption context is available as plaintext in AWS CloudTrail, unless you [intentionally disabled KMS events](https://docs.aws.amazon.com/kms/latest/developerguide/logging-using-cloudtrail.html#filtering-kms-events){target="_blank"}. + +=== "getting_started_encryption_context.py" + + ```python hl_lines="26-28" + --8<-- "examples/data_masking/src/getting_started_encryption_context.py" + ``` + + 1. They must match on `decrypt()` otherwise the operation will fail with `DataMaskingContextMismatchError`. + +=== "getting_started_decryption_context.py" + + ```python hl_lines="26-28" + --8<-- "examples/data_masking/src/getting_started_decryption_context.py" + ``` + + 1. They must match otherwise the operation will fail with `DataMaskingContextMismatchError`. + +### Choosing parts of your data + +???+ note "Current limitations" + 1. The `fields` parameter is not yet supported in `encrypt` and `decrypt` operations. + 2. We support `JSON` data types only - see [data serialization for more details](#data-serialization). + +You can use the `fields` parameter with the dot notation `.` to choose one or more parts of your data to `erase`. This is useful when you want to keep data structure intact except the confidential fields. + +When `fields` is present, `erase` behaves differently: + +| Operation | Behavior | Example | Result | +| --------- | ----------------------------------------------------------- | ----------------------- | ------------------------------- | +| `erase` | Replace data while keeping collections type intact. | `{"cards": ["a", "b"]}` | `{"cards": ["*****", "*****"]}` | + +Here are common scenarios to best visualize how to use `fields`. + +=== "Top keys only" + + You want to erase data in the `card_number` field. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["card_number"])` + + ```json hl_lines="4" + --8<-- "examples/data_masking/src/choosing_payload_top_keys.json" + ``` + + === "Result" + + ```json hl_lines="4" + --8<-- "examples/data_masking/src/choosing_payload_top_keys_output.json" + ``` + +=== "Nested key" + + You want to erase data in the `postcode` field. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["address.postcode"])` + + ```json hl_lines="6" + --8<-- "examples/data_masking/src/choosing_payload_nested_key.json" + ``` + + === "Result" + + ```json hl_lines="6" + --8<-- "examples/data_masking/src/choosing_payload_nested_key_output.json" + ``` + +=== "Multiple keys" + + You want to erase data in both `postcode` and `street` fields. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["address.postcode", "address.street"])` + + ```json hl_lines="6-7" + --8<-- "examples/data_masking/src/choosing_payload_multiple_keys.json" + ``` + + === "Result" + + ```json hl_lines="6-7" + --8<-- "examples/data_masking/src/choosing_payload_multiple_keys_output.json" + ``` + +=== "All key items" + + You want to erase data under `address` field. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["address"])` + + ```json hl_lines="6-17" + --8<-- "examples/data_masking/src/choosing_payload_all_nested_keys.json" + ``` + + === "Result" + + ```json hl_lines="6-7" + --8<-- "examples/data_masking/src/choosing_payload_all_nested_keys_output.json" + ``` + +=== "Complex nested key" + + You want to erase data under `name` field. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["category..name"])` + + ```json hl_lines="6" + --8<-- "examples/data_masking/src/choosing_payload_complex_nested_keys.json" + ``` + + === "Result" + + ```json hl_lines="6" + --8<-- "examples/data_masking/src/choosing_payload_complex_nested_keys_output.json" + ``` + +=== "All fields in a list" + + You want to erase data under `street` field located at the any index of the address list. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["address[*].street"])` + + ```json hl_lines="8 12" + --8<-- "examples/data_masking/src/choosing_payload_list_all_index.json" + ``` + + === "Result" + + ```json hl_lines="8 12" + --8<-- "examples/data_masking/src/choosing_payload_list_all_index_output.json" + ``` + +=== "Slicing a list" + + You want to erase data by slicing a list. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["address[-1].street"])` + + ```json hl_lines="16" + --8<-- "examples/data_masking/src/choosing_payload_list_slice.json" + ``` + + === "Result" + + ```json hl_lines="16" + --8<-- "examples/data_masking/src/choosing_payload_list_slice_output.json" + ``` + +=== "Complex expressions" + + You want to erase data by finding for a field with conditional expression. + + === "Data" + + > Expression: `data_masker.erase(data, fields=["$.address[?(@.postcode > 12000)]"])` + + > `$`: Represents the root of the JSON structure. + + > `.address`: Selects the "address" property within the JSON structure. + + > `(@.postcode > 12000)`: Specifies the condition that elements should meet. It selects elements where the value of the `postcode` property is `greater than 12000`. + + ```json hl_lines="8 12" + --8<-- "examples/data_masking/src/choosing_payload_complex_search.json" + ``` + + === "Result" + + ```json hl_lines="8 12" + --8<-- "examples/data_masking/src/choosing_payload_complex_search_output.json" + ``` + +For comprehensive guidance on using JSONPath syntax, please refer to the official documentation available at [jsonpath-ng](https://github.com/h2non/jsonpath-ng#jsonpath-syntax){target="_blank" rel="nofollow"} + +#### JSON + +We also support data in JSON string format as input. We automatically deserialize it, then handle each field operation as expected. + +Note that the return will be a deserialized JSON and your desired fields updated. + +=== "Data" + + Expression: `data_masker.erase(data, fields=["card_number", "address.postcode"])` + + ```json + --8<-- "examples/data_masking/src/choosing_payload_simple_json.json" + ``` + +=== "Result" + + ```json + --8<-- "examples/data_masking/src/choosing_payload_simple_json_output.json" + ``` + +## Advanced + +### Data serialization + +???+ note "Current limitations" + 1. Python classes, `Dataclasses`, and `Pydantic models` are not supported yet. + +Before we traverse the data structure, we perform two important operations on input data: + +1. If `JSON string`, **deserialize** using default or provided deserializer. +2. If `dictionary`, **normalize** into `JSON` to prevent traversing unsupported data types. + +When decrypting, we revert the operation to restore the original data structure. + +For compatibility or performance, you can optionally pass your own JSON serializer and deserializer to replace `json.dumps` and `json.loads` respectively: + +```python hl_lines="17-18" title="advanced_custom_serializer.py" +--8<-- "examples/data_masking/src/advanced_custom_serializer.py" +``` + +### Using multiple keys + +You can use multiple KMS keys from more than one AWS account for higher availability, when instantiating `AWSEncryptionSDKProvider`. + +```python hl_lines="15" title="using_multiple_keys.py" +--8<-- "examples/data_masking/src/using_multiple_keys.py" +``` + +### Providers + +#### AWS Encryption SDK + +You can modify the following values when initializing the `AWSEncryptionSDKProvider` to best accommodate your security and performance thresholds. + +| Parameter | Default | Description | +| -------------------------- | --------------------- | --------------------------------------------------------------------------------------------- | +| **local_cache_capacity** | `100` | The maximum number of entries that can be retained in the local cryptographic materials cache | +| **max_cache_age_seconds** | `300` | The maximum time (in seconds) that a cache entry may be kept in the cache | +| **max_messages_encrypted** | `4294967296` | The maximum number of messages that may be encrypted under a cache entry | +| **max_bytes_encrypted** | `9223372036854775807` | The maximum number of bytes that may be encrypted under a cache entry | + +If required, you can customize the default values when initializing the `AWSEncryptionSDKProvider` class. + +```python hl_lines="14-19" title="aws_encryption_provider_example.py" +--8<-- "examples/data_masking/src/aws_encryption_provider_example.py" +``` + +##### Passing additional SDK arguments + +!!! note "See the [AWS Encryption SDK docs for more details](https://aws-encryption-sdk-python.readthedocs.io/en/latest/generated/aws_encryption_sdk.html#aws_encryption_sdk.EncryptionSDKClient.encrypt){target="_blank"}" + +As an escape hatch mechanism, you can pass additional arguments to the `AWSEncryptionSDKProvider` via the `provider_options` parameter. + +For example, the AWS Encryption SDK defaults to using the `AES_256_GCM_HKDF_SHA512_COMMIT_KEY_ECDSA_P384` algorithm for encrypting your Data Key. If you want, you have the flexibility to customize and choose a different encryption algorithm. + +```python hl_lines="5 26 30" title="changing_default_algorithm.py" +--8<-- "examples/data_masking/src/changing_default_algorithm.py" +``` + +### Data masking request flow + +The following sequence diagrams explain how `DataMasking` behaves under different scenarios. + +#### Erase operation + +Erasing operations occur in-memory and we cannot recover the original value. + +
+```mermaid +sequenceDiagram + autonumber + participant Client + participant Lambda + participant DataMasking as Data Masking (in memory) + Client->>Lambda: Invoke (event) + Lambda->>DataMasking: erase(data) + DataMasking->>DataMasking: replaces data with ***** + Note over Lambda,DataMasking: No encryption providers involved. + DataMasking->>Lambda: data masked + Lambda-->>Client: Return response +``` +Simple masking operation +
+ +#### Encrypt operation with Encryption SDK (KMS) + +We call KMS to generate an unique data key that can be used for multiple `encrypt` operation in-memory. It improves performance, cost and prevent throttling. + +To make this operation simpler to visualize, we keep caching details in a [separate sequence diagram](#caching-encrypt-operations-with-encryption-sdk). Caching is enabled by default. + +
+```mermaid +sequenceDiagram + autonumber + participant Client + participant Lambda + participant DataMasking as Data Masking + participant EncryptionProvider as Encryption Provider + Client->>Lambda: Invoke (event) + Lambda->>DataMasking: Init Encryption Provider with master key + Note over Lambda,DataMasking: AWSEncryptionSDKProvider([KMS_KEY]) + Lambda->>DataMasking: encrypt(data) + DataMasking->>EncryptionProvider: Create unique data key + Note over DataMasking,EncryptionProvider: KMS GenerateDataKey API + DataMasking->>DataMasking: Cache new unique data key + DataMasking->>DataMasking: DATA_KEY.encrypt(data) + DataMasking->>DataMasking: MASTER_KEY.encrypt(DATA_KEY) + DataMasking->>DataMasking: Create encrypted message + Note over DataMasking: Encrypted message includes encrypted data, data key encrypted, algorithm, and more. + DataMasking->>Lambda: Ciphertext from encrypted message + Lambda-->>Client: Return response +``` +Encrypting operation using envelope encryption. +
+ +#### Encrypt operation with multiple KMS Keys + +When encrypting data with multiple KMS keys, the `aws_encryption_sdk` makes additional API calls to encrypt the data with each of the specified keys. + +
+```mermaid +sequenceDiagram + autonumber + participant Client + participant Lambda + participant DataMasking as Data Masking + participant EncryptionProvider as Encryption Provider + Client->>Lambda: Invoke (event) + Lambda->>DataMasking: Init Encryption Provider with master key + Note over Lambda,DataMasking: AWSEncryptionSDKProvider([KEY_1, KEY_2]) + Lambda->>DataMasking: encrypt(data) + DataMasking->>EncryptionProvider: Create unique data key + Note over DataMasking,EncryptionProvider: KMS GenerateDataKey API - KEY_1 + DataMasking->>DataMasking: Cache new unique data key + DataMasking->>DataMasking: DATA_KEY.encrypt(data) + DataMasking->>DataMasking: KEY_1.encrypt(DATA_KEY) + loop For every additional KMS Key + DataMasking->>EncryptionProvider: Encrypt DATA_KEY + Note over DataMasking,EncryptionProvider: KMS Encrypt API - KEY_2 + end + DataMasking->>DataMasking: Create encrypted message + Note over DataMasking: Encrypted message includes encrypted data, all data keys encrypted, algorithm, and more. + DataMasking->>Lambda: Ciphertext from encrypted message + Lambda-->>Client: Return response +``` +Encrypting operation using envelope encryption. +
+ +#### Decrypt operation with Encryption SDK (KMS) + +We call KMS to decrypt the encrypted data key available in the encrypted message. If successful, we run authentication _(context)_ and integrity checks (_algorithm, data key length, etc_) to confirm its proceedings. + +Lastly, we decrypt the original encrypted data, throw away the decrypted data key for security reasons, and return the original plaintext data. + +
+```mermaid +sequenceDiagram + autonumber + participant Client + participant Lambda + participant DataMasking as Data Masking + participant EncryptionProvider as Encryption Provider + Client->>Lambda: Invoke (event) + Lambda->>DataMasking: Init Encryption Provider with master key + Note over Lambda,DataMasking: AWSEncryptionSDKProvider([KMS_KEY]) + Lambda->>DataMasking: decrypt(data) + DataMasking->>EncryptionProvider: Decrypt encrypted data key + Note over DataMasking,EncryptionProvider: KMS Decrypt API + DataMasking->>DataMasking: Authentication and integrity checks + DataMasking->>DataMasking: DATA_KEY.decrypt(data) + DataMasking->>DataMasking: MASTER_KEY.encrypt(DATA_KEY) + DataMasking->>DataMasking: Discards decrypted data key + DataMasking->>Lambda: Plaintext + Lambda-->>Client: Return response +``` +Decrypting operation using envelope encryption. +
+ +#### Caching encrypt operations with Encryption SDK + +Without caching, every `encrypt()` operation would generate a new data key. It significantly increases latency and cost for ephemeral and short running environments like Lambda. + +With caching, we balance ephemeral Lambda environment performance characteristics with [adjustable thresholds](#aws-encryption-sdk) to meet your security needs. + +!!! info "Data key recycling" + We request a new data key when a cached data key exceeds any of the following security thresholds: + + 1. **Max age in seconds** + 2. **Max number of encrypted messages** + 3. **Max bytes encrypted** across all operations + +
+```mermaid +sequenceDiagram + autonumber + participant Client + participant Lambda + participant DataMasking as Data Masking + participant EncryptionProvider as Encryption Provider + Client->>Lambda: Invoke (event) + Lambda->>DataMasking: Init Encryption Provider with master key + Note over Lambda,DataMasking: AWSEncryptionSDKProvider([KMS_KEY]) + Lambda->>DataMasking: encrypt(data) + DataMasking->>EncryptionProvider: Create unique data key + Note over DataMasking,EncryptionProvider: KMS GenerateDataKey API + DataMasking->>DataMasking: Cache new unique data key + DataMasking->>DataMasking: DATA_KEY.encrypt(data) + DataMasking->>DataMasking: MASTER_KEY.encrypt(DATA_KEY) + DataMasking->>DataMasking: Create encrypted message + Note over DataMasking: Encrypted message includes encrypted data, data key encrypted, algorithm, and more. + DataMasking->>Lambda: Ciphertext from encrypted message + Lambda->>DataMasking: encrypt(another_data) + DataMasking->>DataMasking: Searches for data key in cache + alt Is Data key in cache? + DataMasking->>DataMasking: Reuses data key + else Is Data key evicted from cache? + DataMasking->>EncryptionProvider: Create unique data key + DataMasking->>DataMasking: MASTER_KEY.encrypt(DATA_KEY) + end + DataMasking->>DataMasking: DATA_KEY.encrypt(data) + DataMasking->>DataMasking: Create encrypted message + DataMasking->>Lambda: Ciphertext from encrypted message + Lambda-->>Client: Return response +``` +Caching data keys during encrypt operation. +
+ +## Testing your code + +### Testing erase operation + +Testing your code with a simple erase operation + +=== "test_lambda_mask.py" + +```python hl_lines="22" +--8<-- "examples/data_masking/tests/test_lambda_mask.py" +``` + +=== "lambda_mask.py" + +```python hl_lines="3 12" +--8<-- "examples/data_masking/tests/lambda_mask.py" +``` diff --git a/examples/data_masking/sam/template.yaml b/examples/data_masking/sam/template.yaml new file mode 100644 index 00000000000..67d5d923515 --- /dev/null +++ b/examples/data_masking/sam/template.yaml @@ -0,0 +1,67 @@ +AWSTemplateFormatVersion: "2010-09-09" +Transform: AWS::Serverless-2016-10-31 +Description: > + Powertools for AWS Lambda (Python) data masking example + +Globals: # https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-specification-template-anatomy-globals.html + Function: + Timeout: 5 + Runtime: python3.11 + Tracing: Active + Environment: + Variables: + POWERTOOLS_SERVICE_NAME: PowertoolsHelloWorld + POWERTOOLS_LOG_LEVEL: INFO + KMS_KEY_ARN: !GetAtt DataMaskingMasterKey.Arn + +# In production, we recommend you split up the encrypt and decrypt for fine-grained security. +# For example, one function can act as the encryption proxy via HTTP requests, data pipeline, etc., +# while only authorized personnel can call decrypt via a separate function. +Resources: + DataMaskingEncryptFunctionExample: + Type: AWS::Serverless::Function + Properties: + Handler: data_masking_function_example.lambda_handler + CodeUri: ../src + Description: Data Masking encryption function + # Cryptographic operations demand more CPU. CPU is proportionally allocated based on memory size. + # We recommend allocating a minimum of 1024MB of memory. + MemorySize: 1024 + + # DataMaskingDecryptFunctionExample: + # Type: AWS::Serverless::Function + # Properties: + # Handler: data_masking_function_decrypt.lambda_handler + # CodeUri: ../src + # Description: Data Masking decryption function + # MemorySize: 1024 + + # KMS Key + DataMaskingMasterKey: + Type: "AWS::KMS::Key" + Properties: + Description: KMS Key for encryption and decryption using Powertools for AWS Lambda Data masking feature + # KMS Key support both IAM Resource Policies and Key Policies + # For more details: https://docs.aws.amazon.com/kms/latest/developerguide/key-policies.html + KeyPolicy: + Version: "2012-10-17" + Id: data-masking-enc-dec + Statement: + # For security reasons, ensure your KMS Key has at least one administrator. + # In this example, the root account is granted administrator permissions. + # However, we recommended configuring specific IAM Roles for enhanced security in production. + - Effect: Allow + Principal: + AWS: !Sub "arn:aws:iam::${AWS::AccountId}:root" # (1)! + Action: "kms:*" + Resource: "*" + # We must grant Lambda's IAM Role access to the KMS Key + - Effect: Allow + Principal: + AWS: !GetAtt DataMaskingEncryptFunctionExampleRole.Arn # (2)! + Action: + - kms:Decrypt # to decrypt encrypted data key + - kms:GenerateDataKey # to create an unique and random data key for encryption + # Encrypt permission is required only when using multiple keys + - kms:Encrypt # (3)! + Resource: "*" diff --git a/examples/data_masking/src/advanced_custom_serializer.py b/examples/data_masking/src/advanced_custom_serializer.py new file mode 100644 index 00000000000..f870624bccb --- /dev/null +++ b/examples/data_masking/src/advanced_custom_serializer.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import os + +import ujson + +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, +) +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider( + keys=[KMS_KEY_ARN], + json_serializer=ujson.dumps, + json_deserializer=ujson.loads, +) +data_masker = DataMasking(provider=encryption_provider) + + +def lambda_handler(event: dict, context: LambdaContext) -> str: + data: dict = event.get("body", {}) + + return data_masker.encrypt(data) diff --git a/examples/data_masking/src/aws_encryption_provider_example.py b/examples/data_masking/src/aws_encryption_provider_example.py new file mode 100644 index 00000000000..2ef34a82934 --- /dev/null +++ b/examples/data_masking/src/aws_encryption_provider_example.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, +) +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider( + keys=[KMS_KEY_ARN], + local_cache_capacity=200, + max_cache_age_seconds=400, + max_messages_encrypted=200, + max_bytes_encrypted=2000) + +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data: dict = event.get("body", {}) + + logger.info("Encrypting the whole object") + + encrypted = data_masker.encrypt(data) + + return {"body": encrypted} diff --git a/examples/data_masking/src/changing_default_algorithm.py b/examples/data_masking/src/changing_default_algorithm.py new file mode 100644 index 00000000000..27d52905459 --- /dev/null +++ b/examples/data_masking/src/changing_default_algorithm.py @@ -0,0 +1,33 @@ +from __future__ import annotations + +import os + +from aws_encryption_sdk.identifiers import Algorithm + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN]) +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> str: + data: dict = event.get("body", {}) + + logger.info("Encrypting whole object with a different algorithm") + + provider_options = {"algorithm": Algorithm.AES_256_GCM_HKDF_SHA512_COMMIT_KEY} + + encrypted = data_masker.encrypt( + data, + provider_options=provider_options, + ) + + return encrypted diff --git a/examples/data_masking/src/choosing_payload_all_nested_keys.json b/examples/data_masking/src/choosing_payload_all_nested_keys.json new file mode 100644 index 00000000000..7fad154c03e --- /dev/null +++ b/examples/data_masking/src/choosing_payload_all_nested_keys.json @@ -0,0 +1,19 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Street", + "country": "United States", + "timezone": "America/La_Paz" + }, + { + "postcode": 67890, + "street": "100 Main Street", + "country": "United States", + "timezone": "America/Mazatlan" + } + ] +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_all_nested_keys_output.json b/examples/data_masking/src/choosing_payload_all_nested_keys_output.json new file mode 100644 index 00000000000..a28bfee974e --- /dev/null +++ b/examples/data_masking/src/choosing_payload_all_nested_keys_output.json @@ -0,0 +1,9 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + "*****", + "*****" + ] +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_complex_nested_keys.json b/examples/data_masking/src/choosing_payload_complex_nested_keys.json new file mode 100644 index 00000000000..7096e0074d9 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_complex_nested_keys.json @@ -0,0 +1,11 @@ +{ + "category": { + "subcategory": { + "brand" : { + "product": { + "name": "Car" + } + } + } + } +} diff --git a/examples/data_masking/src/choosing_payload_complex_nested_keys_output.json b/examples/data_masking/src/choosing_payload_complex_nested_keys_output.json new file mode 100644 index 00000000000..843c8c7e1ce --- /dev/null +++ b/examples/data_masking/src/choosing_payload_complex_nested_keys_output.json @@ -0,0 +1,11 @@ +{ + "category": { + "subcategory": { + "brand" : { + "product": { + "name": "*****" + } + } + } + } +} diff --git a/examples/data_masking/src/choosing_payload_complex_search.json b/examples/data_masking/src/choosing_payload_complex_search.json new file mode 100644 index 00000000000..e8db38a79ad --- /dev/null +++ b/examples/data_masking/src/choosing_payload_complex_search.json @@ -0,0 +1,19 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Drive" + }, + { + "postcode": 67890, + "street": "111 Main Street" + }, + { + "postcode": 11111, + "street": "100 Any Street" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_complex_search_output.json b/examples/data_masking/src/choosing_payload_complex_search_output.json new file mode 100644 index 00000000000..6198e27c09a --- /dev/null +++ b/examples/data_masking/src/choosing_payload_complex_search_output.json @@ -0,0 +1,19 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "*****" + }, + { + "postcode": 67890, + "street": "*****" + }, + { + "postcode": 11111, + "street": "100 Any Street" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_all_index.json b/examples/data_masking/src/choosing_payload_list_all_index.json new file mode 100644 index 00000000000..670e3c420be --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_all_index.json @@ -0,0 +1,15 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Drive" + }, + { + "postcode": 67890, + "street": "100 Main Street," + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_all_index_output.json b/examples/data_masking/src/choosing_payload_list_all_index_output.json new file mode 100644 index 00000000000..8fb1f1b1c6d --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_all_index_output.json @@ -0,0 +1,16 @@ + +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "*****" + }, + { + "postcode": 67890, + "street": "*****" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_index.json b/examples/data_masking/src/choosing_payload_list_index.json new file mode 100644 index 00000000000..0f543b42f5f --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_index.json @@ -0,0 +1,15 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Street" + }, + { + "postcode": 67890, + "street": "100 Main Street" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_index_output.json b/examples/data_masking/src/choosing_payload_list_index_output.json new file mode 100644 index 00000000000..1481d78f4b6 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_index_output.json @@ -0,0 +1,16 @@ + +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Street" + }, + { + "postcode": 67890, + "street": "*****" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_slice.json b/examples/data_masking/src/choosing_payload_list_slice.json new file mode 100644 index 00000000000..c8a9f7f58af --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_slice.json @@ -0,0 +1,19 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Street" + }, + { + "postcode": 67890, + "street": "100 Main Street" + }, + { + "postcode": 78495, + "street": "111 Any Drive" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_list_slice_output.json b/examples/data_masking/src/choosing_payload_list_slice_output.json new file mode 100644 index 00000000000..efab8b03400 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_list_slice_output.json @@ -0,0 +1,19 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": [ + { + "postcode": 12345, + "street": "123 Any Street" + }, + { + "postcode": 67890, + "street": "100 Main Street" + }, + { + "postcode": 11111, + "street": "*****" + } + ] +} diff --git a/examples/data_masking/src/choosing_payload_multiple_keys.json b/examples/data_masking/src/choosing_payload_multiple_keys.json new file mode 100644 index 00000000000..640c274868e --- /dev/null +++ b/examples/data_masking/src/choosing_payload_multiple_keys.json @@ -0,0 +1,9 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": { + "postcode": 12345, + "street": "123 Any Street" + } +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_multiple_keys_output.json b/examples/data_masking/src/choosing_payload_multiple_keys_output.json new file mode 100644 index 00000000000..fca3391f2f4 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_multiple_keys_output.json @@ -0,0 +1,9 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": { + "postcode": "*****", + "street": "*****" + } +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_nested_key.json b/examples/data_masking/src/choosing_payload_nested_key.json new file mode 100644 index 00000000000..e3ff995026f --- /dev/null +++ b/examples/data_masking/src/choosing_payload_nested_key.json @@ -0,0 +1,8 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": { + "postcode": 12345 + } +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_nested_key_output.json b/examples/data_masking/src/choosing_payload_nested_key_output.json new file mode 100644 index 00000000000..463f5a943f3 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_nested_key_output.json @@ -0,0 +1,8 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444", + "address": { + "postcode": "*****" + } +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_simple_json.json b/examples/data_masking/src/choosing_payload_simple_json.json new file mode 100644 index 00000000000..057d43087f0 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_simple_json.json @@ -0,0 +1 @@ +'{"name": "Carlos", "operation": "non sensitive", "card_number": "1111 2222 3333 4444", "address": {"postcode": 12345}}' \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_simple_json_output.json b/examples/data_masking/src/choosing_payload_simple_json_output.json new file mode 100644 index 00000000000..b8920dc9696 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_simple_json_output.json @@ -0,0 +1,8 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "*****", + "address": { + "postcode": "*****" + } +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_top_keys.json b/examples/data_masking/src/choosing_payload_top_keys.json new file mode 100644 index 00000000000..dce6ed78780 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_top_keys.json @@ -0,0 +1,5 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "1111 2222 3333 4444" +} \ No newline at end of file diff --git a/examples/data_masking/src/choosing_payload_top_keys_output.json b/examples/data_masking/src/choosing_payload_top_keys_output.json new file mode 100644 index 00000000000..c7d877cb804 --- /dev/null +++ b/examples/data_masking/src/choosing_payload_top_keys_output.json @@ -0,0 +1,5 @@ +{ + "name": "Carlos", + "operation": "non sensitive", + "card_number": "*****" +} \ No newline at end of file diff --git a/examples/data_masking/src/data_masking_function_example.py b/examples/data_masking/src/data_masking_function_example.py new file mode 100644 index 00000000000..e7ed3326890 --- /dev/null +++ b/examples/data_masking/src/data_masking_function_example.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +tracer = Tracer() +logger = Logger() + + +@tracer.capture_lambda_handler +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + logger.info("Hello world function - HTTP 200") + + data = event["body"] + + data_masker = DataMasking(provider=AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])) + encrypted = data_masker.encrypt(data) + decrypted = data_masker.decrypt(encrypted) + return {"Decrypted_json": decrypted} diff --git a/examples/data_masking/src/data_masking_function_example_output.json b/examples/data_masking/src/data_masking_function_example_output.json new file mode 100644 index 00000000000..87601e79ee4 --- /dev/null +++ b/examples/data_masking/src/data_masking_function_example_output.json @@ -0,0 +1,34 @@ +{ + "Decrypted_json": { + "id": 1, + "name": "John Doe", + "age": 30, + "email": "johndoe@example.com", + "address": { + "street": "123 Main St", + "city": "Anytown", + "state": "CA", + "zip": "12345" + }, + "phone_numbers": [ + "+1-555-555-1234", + "+1-555-555-5678" + ], + "interests": [ + "Hiking", + "Traveling", + "Photography", + "Reading" + ], + "job_history": { + "company": { + "company_name": "Acme Inc.", + "company_address": "5678 Interview Dr." + }, + "position": "Software Engineer", + "start_date": "2015-01-01", + "end_date": "2017-12-31" + }, + "about_me": "\n Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tincidunt velit quis\n sapien mollis, at egestas massa tincidunt. Suspendisse ultrices arcu a dolor dapibus,\n ut pretium turpis volutpat. Vestibulum at sapien quis sapien dignissim volutpat ut a enim.\n Praesent fringilla sem eu dui convallis luctus. Donec ullamcorper, sapien ut convallis congue,\n risus mauris pretium tortor, nec dignissim arcu urna a nisl. Vivamus non fermentum ex. Proin\n interdum nisi id sagittis egestas. Nam sit amet nisi nec quam pharetra sagittis. Aliquam erat\n volutpat. Donec nec luctus sem, nec ornare lorem. Vivamus vitae orci quis enim faucibus placerat.\n Nulla facilisi. Proin in turpis orci. Donec imperdiet velit ac tellus gravida, eget laoreet tellus\n malesuada. Praesent venenatis tellus ac urna blandit, at varius felis posuere. Integer a commodo nunc.\n " + } + } \ No newline at end of file diff --git a/examples/data_masking/src/encrypt_data_output.json b/examples/data_masking/src/encrypt_data_output.json new file mode 100644 index 00000000000..06e32c83804 --- /dev/null +++ b/examples/data_masking/src/encrypt_data_output.json @@ -0,0 +1,3 @@ +{ + "body": "AgV4uF5K2YMtNhYrtviTwKNrUHhqQr73l/jNfukkh+qLOC8AXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREEvcjEyaFZHY1R5cjJuTDNKbTJ3UFA3R3ZjaytIdi9hekZqbXVUb25Ya3J5SzFBOUlJZDZxZXpSR1NTVnZDUUxoZz09AAEAB2F3cy1rbXMAS2Fybjphd3M6a21zOnVzLWVhc3QtMToyMDA5ODQxMTIzODY6a2V5LzZkODJiMzRlLTM2NjAtNDRlMi04YWJiLTdmMzA1OGJlYTIxMgC4AQIBAHjxYXAO7wQGd+7qxoyvXAajwqboF5FL/9lgYUNJTB8VtAHBP2hwVgw+zypp7GoMNTPAAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMx/B25MTgWwpL7CmuAgEQgDtan3orAOKFUfyNm3v6rFcglb+BVVVDV71fj4aRljhpg1ixsYFaKsoej8NcwRktIiWE+mw9XmTEVb6xFQIAABAA9DeLzlRaRQgTcXMJG0iBu/YTyyDKiROD+bU1Y09X9RBz5LA1nWIENJKq2seAhNSB/////wAAAAEAAAAAAAAAAAAAAAEAAAEBExLJ9wI4n7t+wyPEEP4kjYFBdkmNuLLsVC2Yt8mv9Y1iH2G+/g9SaIcdK57pkoW0ECpBxZVOxCuhmK2s74AJCUdem9McjS1waUKyzYTi9vv2ySNBsABIDwT990rE7jZJ3tEZAqcWZg/eWlxvnksFR/akBWZKsKzFz6lF57+cTgdISCEJRV0E7fcUeCuaMaQGK1Qw2OCmIeHEG5j5iztBkZG2IB2CVND/AbxmDUFHwgjsrJPTzaDYSufcGMoZW1A9X1sLVfqNVKvnOFP5tNY7kPF5eAI9FhGBw8SjTqODXz4k6zuqzy9no8HtXowP265U8NZ5VbVTd/zuVEbZyK5KBqzP1sExW4RhnlpXMoOs9WSuAGcwZQIxANTeEwb9V7CacV2Urt/oCqysUzhoV2AcT2ZjryFqY79Tsg+FRpIx7cBizL4ieRzbhQIwcRasNncO5OZOcmVr0MqHv+gCVznndMgjXJmWwUa7h6skJKmhhMPlN0CsugxtVWnD" +} diff --git a/examples/data_masking/src/generic_data_input.json b/examples/data_masking/src/generic_data_input.json new file mode 100644 index 00000000000..60ab0aa278e --- /dev/null +++ b/examples/data_masking/src/generic_data_input.json @@ -0,0 +1,21 @@ +{ + "body": + { + "id": 1, + "name": "John Doe", + "age": 30, + "email": "johndoe@example.com", + "address": { + "street": "123 Main St", + "city": "Anytown", + "state": "CA", + "zip": "12345" + }, + "company_address": { + "street": "456 ACME Ave", + "city": "Anytown", + "state": "CA", + "zip": "12345" + } + } +} \ No newline at end of file diff --git a/examples/data_masking/src/getting_started_decrypt_data.py b/examples/data_masking/src/getting_started_decrypt_data.py new file mode 100644 index 00000000000..d8e746a8dfe --- /dev/null +++ b/examples/data_masking/src/getting_started_decrypt_data.py @@ -0,0 +1,26 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") # (1)! + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN]) # (2)! +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data: dict = event.get("body", {}) + + logger.info("Decrypting whole object") + + decrypted = data_masker.decrypt(data) + + return decrypted diff --git a/examples/data_masking/src/getting_started_decrypt_data_input.json b/examples/data_masking/src/getting_started_decrypt_data_input.json new file mode 100644 index 00000000000..06e32c83804 --- /dev/null +++ b/examples/data_masking/src/getting_started_decrypt_data_input.json @@ -0,0 +1,3 @@ +{ + "body": "AgV4uF5K2YMtNhYrtviTwKNrUHhqQr73l/jNfukkh+qLOC8AXwABABVhd3MtY3J5cHRvLXB1YmxpYy1rZXkAREEvcjEyaFZHY1R5cjJuTDNKbTJ3UFA3R3ZjaytIdi9hekZqbXVUb25Ya3J5SzFBOUlJZDZxZXpSR1NTVnZDUUxoZz09AAEAB2F3cy1rbXMAS2Fybjphd3M6a21zOnVzLWVhc3QtMToyMDA5ODQxMTIzODY6a2V5LzZkODJiMzRlLTM2NjAtNDRlMi04YWJiLTdmMzA1OGJlYTIxMgC4AQIBAHjxYXAO7wQGd+7qxoyvXAajwqboF5FL/9lgYUNJTB8VtAHBP2hwVgw+zypp7GoMNTPAAAAAfjB8BgkqhkiG9w0BBwagbzBtAgEAMGgGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMx/B25MTgWwpL7CmuAgEQgDtan3orAOKFUfyNm3v6rFcglb+BVVVDV71fj4aRljhpg1ixsYFaKsoej8NcwRktIiWE+mw9XmTEVb6xFQIAABAA9DeLzlRaRQgTcXMJG0iBu/YTyyDKiROD+bU1Y09X9RBz5LA1nWIENJKq2seAhNSB/////wAAAAEAAAAAAAAAAAAAAAEAAAEBExLJ9wI4n7t+wyPEEP4kjYFBdkmNuLLsVC2Yt8mv9Y1iH2G+/g9SaIcdK57pkoW0ECpBxZVOxCuhmK2s74AJCUdem9McjS1waUKyzYTi9vv2ySNBsABIDwT990rE7jZJ3tEZAqcWZg/eWlxvnksFR/akBWZKsKzFz6lF57+cTgdISCEJRV0E7fcUeCuaMaQGK1Qw2OCmIeHEG5j5iztBkZG2IB2CVND/AbxmDUFHwgjsrJPTzaDYSufcGMoZW1A9X1sLVfqNVKvnOFP5tNY7kPF5eAI9FhGBw8SjTqODXz4k6zuqzy9no8HtXowP265U8NZ5VbVTd/zuVEbZyK5KBqzP1sExW4RhnlpXMoOs9WSuAGcwZQIxANTeEwb9V7CacV2Urt/oCqysUzhoV2AcT2ZjryFqY79Tsg+FRpIx7cBizL4ieRzbhQIwcRasNncO5OZOcmVr0MqHv+gCVznndMgjXJmWwUa7h6skJKmhhMPlN0CsugxtVWnD" +} diff --git a/examples/data_masking/src/getting_started_decrypt_data_output.json b/examples/data_masking/src/getting_started_decrypt_data_output.json new file mode 100644 index 00000000000..7871a0416e7 --- /dev/null +++ b/examples/data_masking/src/getting_started_decrypt_data_output.json @@ -0,0 +1,18 @@ +{ + "id": 1, + "name": "John Doe", + "age": 30, + "email": "johndoe@example.com", + "address": { + "street": "123 Main St", + "city": "Anytown", + "state": "CA", + "zip": "12345" + }, + "company_address": { + "street": "456 ACME Ave", + "city": "Anytown", + "state": "CA", + "zip": "12345" + } +} \ No newline at end of file diff --git a/examples/data_masking/src/getting_started_decryption_context.py b/examples/data_masking/src/getting_started_decryption_context.py new file mode 100644 index 00000000000..f4b0f6d8ac3 --- /dev/null +++ b/examples/data_masking/src/getting_started_decryption_context.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN]) +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data = event.get("body", {}) + + logger.info("Decrypting whole object") + + decrypted: dict = data_masker.decrypt( + data, + data_classification="confidential", # (1)! + data_type="customer-data", + tenant_id="a06bf973-0734-4b53-9072-39d7ac5b2cba", + ) + + return decrypted diff --git a/examples/data_masking/src/getting_started_encrypt_data.py b/examples/data_masking/src/getting_started_encrypt_data.py new file mode 100644 index 00000000000..579170113dd --- /dev/null +++ b/examples/data_masking/src/getting_started_encrypt_data.py @@ -0,0 +1,28 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, +) +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN]) # (1)! +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data: dict = event.get("body", {}) + + logger.info("Encrypting the whole object") + + encrypted = data_masker.encrypt(data) + + return {"body": encrypted} diff --git a/examples/data_masking/src/getting_started_encryption_context.py b/examples/data_masking/src/getting_started_encryption_context.py new file mode 100644 index 00000000000..6fea5dc9f65 --- /dev/null +++ b/examples/data_masking/src/getting_started_encryption_context.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN = os.getenv("KMS_KEY_ARN", "") + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN]) +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> str: + data = event.get("body", {}) + + logger.info("Encrypting whole object") + + encrypted: str = data_masker.encrypt( + data, + data_classification="confidential", # (1)! + data_type="customer-data", + tenant_id="a06bf973-0734-4b53-9072-39d7ac5b2cba", + ) + + return encrypted diff --git a/examples/data_masking/src/getting_started_erase_data.py b/examples/data_masking/src/getting_started_erase_data.py new file mode 100644 index 00000000000..a3e9fc7217e --- /dev/null +++ b/examples/data_masking/src/getting_started_erase_data.py @@ -0,0 +1,19 @@ +from __future__ import annotations + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.typing import LambdaContext + +logger = Logger() +data_masker = DataMasking() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data: dict = event.get("body", {}) + + logger.info("Erasing fields email, address.street, and company_address") + + erased = data_masker.erase(data, fields=["email", "address.street", "company_address"]) # (1)! + + return erased diff --git a/examples/data_masking/src/getting_started_erase_data_output.json b/examples/data_masking/src/getting_started_erase_data_output.json new file mode 100644 index 00000000000..76a43cc81e7 --- /dev/null +++ b/examples/data_masking/src/getting_started_erase_data_output.json @@ -0,0 +1,13 @@ +{ + "id": 1, + "name": "John Doe", + "age": 30, + "email": "*****", + "address": { + "street": "*****", + "city": "Anytown", + "state": "CA", + "zip": "12345" + }, + "company_address": "*****" +} \ No newline at end of file diff --git a/examples/data_masking/src/large_data_input.json b/examples/data_masking/src/large_data_input.json new file mode 100644 index 00000000000..34275c3fa73 --- /dev/null +++ b/examples/data_masking/src/large_data_input.json @@ -0,0 +1,32 @@ +{ + "body": + { + "id": 1, + "name": "John Doe", + "age": 30, + "email": "johndoe@example.com", + "address": {"street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"}, + "phone_numbers": ["+1-555-555-1234", "+1-555-555-5678"], + "interests": ["Hiking", "Traveling", "Photography", "Reading"], + "job_history": { + "company": { + "company_name": "Acme Inc.", + "company_address": "5678 Interview Dr." + }, + "position": "Software Engineer", + "start_date": "2015-01-01", + "end_date": "2017-12-31" + }, + "about_me": """ + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tincidunt velit quis + sapien mollis, at egestas massa tincidunt. Suspendisse ultrices arcu a dolor dapibus, + ut pretium turpis volutpat. Vestibulum at sapien quis sapien dignissim volutpat ut a enim. + Praesent fringilla sem eu dui convallis luctus. Donec ullamcorper, sapien ut convallis congue, + risus mauris pretium tortor, nec dignissim arcu urna a nisl. Vivamus non fermentum ex. Proin + interdum nisi id sagittis egestas. Nam sit amet nisi nec quam pharetra sagittis. Aliquam erat + volutpat. Donec nec luctus sem, nec ornare lorem. Vivamus vitae orci quis enim faucibus placerat. + Nulla facilisi. Proin in turpis orci. Donec imperdiet velit ac tellus gravida, eget laoreet tellus + malesuada. Praesent venenatis tellus ac urna blandit, at varius felis posuere. Integer a commodo nunc. + """ + } +} diff --git a/examples/data_masking/src/using_multiple_keys.py b/examples/data_masking/src/using_multiple_keys.py new file mode 100644 index 00000000000..45c49f467d3 --- /dev/null +++ b/examples/data_masking/src/using_multiple_keys.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +import os + +from aws_lambda_powertools import Logger +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, +) +from aws_lambda_powertools.utilities.typing import LambdaContext + +KMS_KEY_ARN_1 = os.getenv("KMS_KEY_ARN_1", "") +KMS_KEY_ARN_2 = os.getenv("KMS_KEY_ARN_2", "") + +encryption_provider = AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN_1, KMS_KEY_ARN_2]) +data_masker = DataMasking(provider=encryption_provider) + +logger = Logger() + + +@logger.inject_lambda_context +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data: dict = event.get("body", {}) + + logger.info("Encrypting the whole object") + + encrypted = data_masker.encrypt(data) + + return {"body": encrypted} diff --git a/examples/data_masking/tests/lambda_mask.py b/examples/data_masking/tests/lambda_mask.py new file mode 100644 index 00000000000..6b2f461e663 --- /dev/null +++ b/examples/data_masking/tests/lambda_mask.py @@ -0,0 +1,14 @@ +from __future__ import annotations + +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.typing import LambdaContext + +data_masker = DataMasking() + + +def lambda_handler(event: dict, context: LambdaContext) -> dict: + data = event + + erased = data_masker.erase(data, fields=["testkey"]) + + return erased diff --git a/examples/data_masking/tests/test_lambda_mask.py b/examples/data_masking/tests/test_lambda_mask.py new file mode 100644 index 00000000000..596f065b380 --- /dev/null +++ b/examples/data_masking/tests/test_lambda_mask.py @@ -0,0 +1,30 @@ +from dataclasses import dataclass + +import pytest +import test_lambda_mask + + +@pytest.fixture +def lambda_context(): + @dataclass + class LambdaContext: + function_name: str = "test" + memory_limit_in_mb: int = 128 + invoked_function_arn: str = "arn:aws:lambda:eu-west-1:111111111:function:test" + aws_request_id: str = "52fdfc07-2182-154f-163f-5f0f9a621d72" + + def get_remaining_time_in_millis(self) -> int: + return 5 + + return LambdaContext() + + +def test_encrypt_lambda(lambda_context): + # GIVEN: A sample event for testing + event = {"testkey": "testvalue"} + + # WHEN: Invoking the lambda_handler function with the sample event and Lambda context + result = test_lambda_mask.lambda_handler(event, lambda_context) + + # THEN: Assert that the result matches the expected output + assert result == {"testkey": "*****"} diff --git a/mkdocs.yml b/mkdocs.yml index a862430a054..50fe632539c 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -29,6 +29,7 @@ nav: - utilities/data_classes.md - utilities/parser.md - utilities/idempotency.md + - utilities/data_masking.md - utilities/feature_flags.md - utilities/streaming.md - utilities/middleware_factory.md diff --git a/mypy.ini b/mypy.ini index cb2d3ce2443..5fcb1533707 100644 --- a/mypy.ini +++ b/mypy.ini @@ -12,12 +12,15 @@ disable_error_code = annotation-unchecked [mypy-jmespath] ignore_missing_imports=True -[mypy-aws_encryption_sdk] +[mypy-aws_encryption_sdk.*] ignore_missing_imports=True [mypy-sentry_sdk] ignore_missing_imports=True +[mypy-jsonpath_ng.*] +ignore_missing_imports=True + [mypy-jmespath.exceptions] ignore_missing_imports=True @@ -71,3 +74,6 @@ ignore_missing_imports = True [mypy-importlib.metadata] ignore_missing_imports = True + +[mypy-ujson] +ignore_missing_imports = True diff --git a/poetry.lock b/poetry.lock index b6bf62d37bb..8e7fcad2cd9 100644 --- a/poetry.lock +++ b/poetry.lock @@ -768,58 +768,67 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "41.0.7" +version = "42.0.2" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:3c78451b78313fa81607fa1b3f1ae0a5ddd8014c38a02d9db0616133987b9cdf"}, - {file = "cryptography-41.0.7-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:928258ba5d6f8ae644e764d0f996d61a8777559f72dfeb2eea7e2fe0ad6e782d"}, - {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5a1b41bc97f1ad230a41657d9155113c7521953869ae57ac39ac7f1bb471469a"}, - {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:841df4caa01008bad253bce2a6f7b47f86dc9f08df4b433c404def869f590a15"}, - {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:5429ec739a29df2e29e15d082f1d9ad683701f0ec7709ca479b3ff2708dae65a"}, - {file = "cryptography-41.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:43f2552a2378b44869fe8827aa19e69512e3245a219104438692385b0ee119d1"}, - {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:af03b32695b24d85a75d40e1ba39ffe7db7ffcb099fe507b39fd41a565f1b157"}, - {file = "cryptography-41.0.7-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:49f0805fc0b2ac8d4882dd52f4a3b935b210935d500b6b805f321addc8177406"}, - {file = "cryptography-41.0.7-cp37-abi3-win32.whl", hash = "sha256:f983596065a18a2183e7f79ab3fd4c475205b839e02cbc0efbbf9666c4b3083d"}, - {file = "cryptography-41.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:90452ba79b8788fa380dfb587cca692976ef4e757b194b093d845e8d99f612f2"}, - {file = "cryptography-41.0.7-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:079b85658ea2f59c4f43b70f8119a52414cdb7be34da5d019a77bf96d473b960"}, - {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:b640981bf64a3e978a56167594a0e97db71c89a479da8e175d8bb5be5178c003"}, - {file = "cryptography-41.0.7-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e3114da6d7f95d2dee7d3f4eec16dacff819740bbab931aff8648cb13c5ff5e7"}, - {file = "cryptography-41.0.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d5ec85080cce7b0513cfd233914eb8b7bbd0633f1d1703aa28d1dd5a72f678ec"}, - {file = "cryptography-41.0.7-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:7a698cb1dac82c35fcf8fe3417a3aaba97de16a01ac914b89a0889d364d2f6be"}, - {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:37a138589b12069efb424220bf78eac59ca68b95696fc622b6ccc1c0a197204a"}, - {file = "cryptography-41.0.7-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:68a2dec79deebc5d26d617bfdf6e8aab065a4f34934b22d3b5010df3ba36612c"}, - {file = "cryptography-41.0.7-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:09616eeaef406f99046553b8a40fbf8b1e70795a91885ba4c96a70793de5504a"}, - {file = "cryptography-41.0.7-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:48a0476626da912a44cc078f9893f292f0b3e4c739caf289268168d8f4702a39"}, - {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:c7f3201ec47d5207841402594f1d7950879ef890c0c495052fa62f58283fde1a"}, - {file = "cryptography-41.0.7-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c5ca78485a255e03c32b513f8c2bc39fedb7f5c5f8535545bdc223a03b24f248"}, - {file = "cryptography-41.0.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:d6c391c021ab1f7a82da5d8d0b3cee2f4b2c455ec86c8aebbc84837a631ff309"}, - {file = "cryptography-41.0.7.tar.gz", hash = "sha256:13f93ce9bea8016c253b34afc6bd6a75993e5c40672ed5405a9c832f0d4a00bc"}, -] - -[package.dependencies] -cffi = ">=1.12" + {file = "cryptography-42.0.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:701171f825dcab90969596ce2af253143b93b08f1a716d4b2a9d2db5084ef7be"}, + {file = "cryptography-42.0.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:61321672b3ac7aade25c40449ccedbc6db72c7f5f0fdf34def5e2f8b51ca530d"}, + {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea2c3ffb662fec8bbbfce5602e2c159ff097a4631d96235fcf0fb00e59e3ece4"}, + {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b15c678f27d66d247132cbf13df2f75255627bcc9b6a570f7d2fd08e8c081d2"}, + {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8e88bb9eafbf6a4014d55fb222e7360eef53e613215085e65a13290577394529"}, + {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a047682d324ba56e61b7ea7c7299d51e61fd3bca7dad2ccc39b72bd0118d60a1"}, + {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:36d4b7c4be6411f58f60d9ce555a73df8406d484ba12a63549c88bd64f7967f1"}, + {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a00aee5d1b6c20620161984f8ab2ab69134466c51f58c052c11b076715e72929"}, + {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b97fe7d7991c25e6a31e5d5e795986b18fbbb3107b873d5f3ae6dc9a103278e9"}, + {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5fa82a26f92871eca593b53359c12ad7949772462f887c35edaf36f87953c0e2"}, + {file = "cryptography-42.0.2-cp37-abi3-win32.whl", hash = "sha256:4b063d3413f853e056161eb0c7724822a9740ad3caa24b8424d776cebf98e7ee"}, + {file = "cryptography-42.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:841ec8af7a8491ac76ec5a9522226e287187a3107e12b7d686ad354bb78facee"}, + {file = "cryptography-42.0.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:55d1580e2d7e17f45d19d3b12098e352f3a37fe86d380bf45846ef257054b242"}, + {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28cb2c41f131a5758d6ba6a0504150d644054fd9f3203a1e8e8d7ac3aea7f73a"}, + {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9097a208875fc7bbeb1286d0125d90bdfed961f61f214d3f5be62cd4ed8a446"}, + {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:44c95c0e96b3cb628e8452ec060413a49002a247b2b9938989e23a2c8291fc90"}, + {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2f9f14185962e6a04ab32d1abe34eae8a9001569ee4edb64d2304bf0d65c53f3"}, + {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:09a77e5b2e8ca732a19a90c5bca2d124621a1edb5438c5daa2d2738bfeb02589"}, + {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad28cff53f60d99a928dfcf1e861e0b2ceb2bc1f08a074fdd601b314e1cc9e0a"}, + {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:130c0f77022b2b9c99d8cebcdd834d81705f61c68e91ddd614ce74c657f8b3ea"}, + {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa3dec4ba8fb6e662770b74f62f1a0c7d4e37e25b58b2bf2c1be4c95372b4a33"}, + {file = "cryptography-42.0.2-cp39-abi3-win32.whl", hash = "sha256:3dbd37e14ce795b4af61b89b037d4bc157f2cb23e676fa16932185a04dfbf635"}, + {file = "cryptography-42.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:8a06641fb07d4e8f6c7dda4fc3f8871d327803ab6542e33831c7ccfdcb4d0ad6"}, + {file = "cryptography-42.0.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:087887e55e0b9c8724cf05361357875adb5c20dec27e5816b653492980d20380"}, + {file = "cryptography-42.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a7ef8dd0bf2e1d0a27042b231a3baac6883cdd5557036f5e8df7139255feaac6"}, + {file = "cryptography-42.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4383b47f45b14459cab66048d384614019965ba6c1a1a141f11b5a551cace1b2"}, + {file = "cryptography-42.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:fbeb725c9dc799a574518109336acccaf1303c30d45c075c665c0793c2f79a7f"}, + {file = "cryptography-42.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:320948ab49883557a256eab46149df79435a22d2fefd6a66fe6946f1b9d9d008"}, + {file = "cryptography-42.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5ef9bc3d046ce83c4bbf4c25e1e0547b9c441c01d30922d812e887dc5f125c12"}, + {file = "cryptography-42.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:52ed9ebf8ac602385126c9a2fe951db36f2cb0c2538d22971487f89d0de4065a"}, + {file = "cryptography-42.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:141e2aa5ba100d3788c0ad7919b288f89d1fe015878b9659b307c9ef867d3a65"}, + {file = "cryptography-42.0.2.tar.gz", hash = "sha256:e0ec52ba3c7f1b7d813cd52649a5b3ef1fc0d433219dc8c93827c57eab6cf888"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} [package.extras] docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=1.1.1)"] -docstest = ["pyenchant (>=1.6.11)", "sphinxcontrib-spelling (>=4.0.1)", "twine (>=1.12.0)"] +docstest = ["pyenchant (>=1.6.11)", "readme-renderer", "sphinxcontrib-spelling (>=4.0.1)"] nox = ["nox"] -pep8test = ["black", "check-sdist", "mypy", "ruff"] +pep8test = ["check-sdist", "click", "mypy", "ruff"] sdist = ["build"] ssh = ["bcrypt (>=3.1.5)"] -test = ["pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] +test = ["certifi", "pretend", "pytest (>=6.2.0)", "pytest-benchmark", "pytest-cov", "pytest-xdist"] test-randomorder = ["pytest-randomly"] [[package]] name = "datadog" -version = "0.47.0" +version = "0.48.0" description = "The Datadog Python library" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ - {file = "datadog-0.47.0-py2.py3-none-any.whl", hash = "sha256:a45ec997ab554208837e8c44d81d0e1456539dc14da5743687250e028bc809b7"}, - {file = "datadog-0.47.0.tar.gz", hash = "sha256:47be3b2c3d709a7f5b709eb126ed4fe6cc7977d618fe5c158dd89c2a9f7d9916"}, + {file = "datadog-0.48.0-py2.py3-none-any.whl", hash = "sha256:c3f819e2dc632a546a5b4e8d45409e996d4fa18c60df7814c82eda548e0cca59"}, + {file = "datadog-0.48.0.tar.gz", hash = "sha256:d4d661358c3e7f801fbfe15118f5ccf08b9bd9b1f45b8b910605965283edad64"}, ] [package.dependencies] @@ -867,71 +876,71 @@ six = "*" [[package]] name = "ddtrace" -version = "2.4.0" +version = "2.5.2" description = "Datadog APM client library" optional = false python-versions = ">=3.7" files = [ - {file = "ddtrace-2.4.0-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:90641de597d3424573aa96263509800bb64018727bf74e29e250e6d21200a4be"}, - {file = "ddtrace-2.4.0-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:75b7d01af5fb8d279a2edb56d48af0dc221ed43f4e5049387e4a9be529217033"}, - {file = "ddtrace-2.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f104933ffbae735887e10e3e0d9a5d28dd7d42d1fd86141c4fa171c07598b561"}, - {file = "ddtrace-2.4.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d675545d2fd7c5be10fe704a3f151add0ce8b101c976ca0ab452699aac0d8489"}, - {file = "ddtrace-2.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b380dabf377a318ebd909423293b02beaa43ffda03ad129a5a93c4a1a4b5c6"}, - {file = "ddtrace-2.4.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d2f93337c1546404967525388a45174481daa72ecf7d3a1e4c21349e1a2d572c"}, - {file = "ddtrace-2.4.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0e345e034e8962d76642ab2763f5bdb1bc4424c2ea17d9ca5f82e093160d6ca1"}, - {file = "ddtrace-2.4.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:1aa5e1a7121d08d50795e3f6218f3959cfa55363a3896210410ef354a7573de9"}, - {file = "ddtrace-2.4.0-cp310-cp310-win32.whl", hash = "sha256:d9c69a42919a27cff8d42461b301014d79683c40f60d0cb5f3000e4ff7cb907f"}, - {file = "ddtrace-2.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:962de6a60f42e2cde1823c47a3383bb0d6beaa954d57b12687688935d0ddd3d3"}, - {file = "ddtrace-2.4.0-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ed91c32353c8288fb95de67faa341c5ab9a089c0161ad51fc739f0db2b46866e"}, - {file = "ddtrace-2.4.0-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:410c9b9241ed2514dc9413887d852140cc7ff396b40ffc412835a14668b9b1a3"}, - {file = "ddtrace-2.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:639b11f780d0ed1a372a2a6b92cc1b9c586a0fea27439557e768d5ebedabbc34"}, - {file = "ddtrace-2.4.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:08861e4acd61198428f0d994db1bc5d2893ec816b9cd78c0c6d1fc963f0dc771"}, - {file = "ddtrace-2.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aad627a4611bff8f527e2c0c0fc51be9d74a563328269f53b871901570ee4ff3"}, - {file = "ddtrace-2.4.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e6ae2f75f2edc068d6c104ceb0e882a6dfad8f702b27384b3dac5290aebbc248"}, - {file = "ddtrace-2.4.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:82a0832000fedcb95856477bab95c6f151fa28ede3aceafaabe7c08beffaa577"}, - {file = "ddtrace-2.4.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:f8b1baac10f9cc3803854f802062e02ae5de0d5546f19165c3b6e8840e9b09f4"}, - {file = "ddtrace-2.4.0-cp311-cp311-win32.whl", hash = "sha256:c687fe20b17e2d24de222913dc2383e6b1462641d8ff18d27678dcb72ced82a3"}, - {file = "ddtrace-2.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:47296b116a97e01fe6bf48a4eea4e825212ee23288ee064964ab87ba608fc038"}, - {file = "ddtrace-2.4.0-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:6e2b2b4160ea53dd3e4f8bb35af7124a5e8954c8badffa81468c8a62d12acc51"}, - {file = "ddtrace-2.4.0-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:49ac0d69f98a4ff2175db39481598300fd94f038a027b537d0a66d9dbeca1ed7"}, - {file = "ddtrace-2.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2604e1c91b44d3b6fb15d0337cda1ac2c15aec215f6a44e1bb39d25b47c2633c"}, - {file = "ddtrace-2.4.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb7d2c846e3d7e8156199855d4db014a71d62daedba84a213416e2a488e834b3"}, - {file = "ddtrace-2.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85774e12d5d92152cd1c64f3a8a2f4dbe7f3d39201f8a8ff5e914b9639fe6e17"}, - {file = "ddtrace-2.4.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:418c0c990c505accc8665bfc056f4297938a54176157bf1f0765f2fae584efec"}, - {file = "ddtrace-2.4.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:183f7c3ddd9a2891bd1b6f5ea3af6d16517775268b3940259820ca3c83292d16"}, - {file = "ddtrace-2.4.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:eb90e71b70e3ea6c24711cfb5c48c711a2175c315daf07f4f28903aa773a48b7"}, - {file = "ddtrace-2.4.0-cp312-cp312-win32.whl", hash = "sha256:5eab75f1d4170c41de1f9c32e7e39714b2dd11a59d9ff7e94a199b88fa813ecd"}, - {file = "ddtrace-2.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:d892e0b71f3b6bcf31920b5e7fd699c86aea734bc02eec3c1b22acd8f63057e4"}, - {file = "ddtrace-2.4.0-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:c07ea7a17a2897d891ee5e95de3b0e4f57184c471e87ffcc7208b3ccd68b9fcc"}, - {file = "ddtrace-2.4.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05b28815e65d6361cd056c877ab051e132a6929b0d353313a499122e6522ea3"}, - {file = "ddtrace-2.4.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:63719bfc8fe5e8510022a3275145d6b2b1c4f955c395698fb792d99d4cda698d"}, - {file = "ddtrace-2.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:190f96eccdd8107cc93db6e79af4b8fc9403418c823d895af898cf635f5cada6"}, - {file = "ddtrace-2.4.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b0fdb6a2fe0eadd122df4ea3a11690cb88f4f642bd19b1a21d01e9dcfd6eb20c"}, - {file = "ddtrace-2.4.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:1b2bf18ee10ea8fe668096a6c70db4161e228edee161b04719506947d7117937"}, - {file = "ddtrace-2.4.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ca5fa396b8df0d7b55ad9e8d5b19be09c5dedefa388bf7590340ace5ce392e14"}, - {file = "ddtrace-2.4.0-cp37-cp37m-win32.whl", hash = "sha256:c67a4d8767aa269f8dfab79ae39b8170b95de6813bd1cba17dc951f0a1ee462b"}, - {file = "ddtrace-2.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1db7931541052622a91c8c6594b274d96efe956d5dbbe09c57a50c0f74640b52"}, - {file = "ddtrace-2.4.0-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:a8b6ab9f26d2ea50dfa69a282d727c865461f0c1b535f973922072f700cde031"}, - {file = "ddtrace-2.4.0-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:9ad7aa89988b77b893c3e9898fc48e3cef9471bc2648d6a83cc800b49cad1f1f"}, - {file = "ddtrace-2.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38b95920bcc17289a0e3871830ef19030df763039021a796a1debb7fd4ea347b"}, - {file = "ddtrace-2.4.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9152dcc4b8a98392ce5853b8e160f8d215ddd148337d42861ab3c12635b32b75"}, - {file = "ddtrace-2.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c335be0ab8f4f376f51111219a9d85bcdbd6d75c18a8d5471817645bed1430c0"}, - {file = "ddtrace-2.4.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0c95339694034d4fbf9e1b2a0918f99b3936336e8deb4d513e9cf7a6ae1532f3"}, - {file = "ddtrace-2.4.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:f8bddc5e84e50663b64fbad2e2c61203484dea06de7759a47f096514d99f5c8f"}, - {file = "ddtrace-2.4.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:0af7c4c94959481bc4060c7dfb5f7e70b1929b18089c7ea0329fc3f28707fd8a"}, - {file = "ddtrace-2.4.0-cp38-cp38-win32.whl", hash = "sha256:de3fcca4747340c835e7816009dd363d4e02dc5fc25365b2418dc3d986a6550a"}, - {file = "ddtrace-2.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:2f3dbcff2b305d34ecc63db05d0efeb923846ba07871be6f0a3509a33290fb69"}, - {file = "ddtrace-2.4.0-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:7b43e2e890e868a133afc25f57774bb6bc8ae8841094cba4e8f2b3ee50f9c7ee"}, - {file = "ddtrace-2.4.0-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:de66ea03ca5b3f02d0f878fc9d486d4d4f654cf66b38d3fdf73bf314fc0e3f5b"}, - {file = "ddtrace-2.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01cba8d20d4754135411e0e3398af02bc29b3c5f3dc85b1ee8cdfb9a0532f793"}, - {file = "ddtrace-2.4.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb324809582b65baa682f045cb2873d686de3aa93cac75718462d0a23f980836"}, - {file = "ddtrace-2.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f475ea4e2086e6a16a48568688918b21043ba391a6f968cb9bc17ec70d51de75"}, - {file = "ddtrace-2.4.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f1d4a5d9c89db2cc0e4a6eaf10b6d1af449d1ef14060000b23eceee19497705e"}, - {file = "ddtrace-2.4.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:a057db38d52271b6206bac2ab23f2a36cbe547397cba1ce586021df711570559"}, - {file = "ddtrace-2.4.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:45ee78018276764f7fdaf1cf3b945660cf1ab39e1a03e0c61bf1984a71562204"}, - {file = "ddtrace-2.4.0-cp39-cp39-win32.whl", hash = "sha256:4f63dea207c90bb2c2d52ff9de0ee71b27aedb5d8540745e4e0b38a896737de0"}, - {file = "ddtrace-2.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:e3523c71d37fb3135d0817e92b486bcee7829c41e5465ed41b080286d7e2739d"}, - {file = "ddtrace-2.4.0.tar.gz", hash = "sha256:fb1bab23debb3a1fb71e3d6a1ce9818bc5e6ad9b885b901f78f3f28639393ecb"}, + {file = "ddtrace-2.5.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:f918538a6adb33696be653d343ee318b16ea977376d9b7214d14fe97c42e9bd9"}, + {file = "ddtrace-2.5.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:f56735eb636d3ab2f7224f261d3a6bd43f884e9901d68407d485ea65f3dc0f46"}, + {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72d21fe6842a8d80c8765dd699153a2475ae2d49e82e10f9668eadb08b454040"}, + {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6e48caf63506d7ac3df7caa955b6258de91c1a1f55149506ab8ac36143770b9"}, + {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc3f26e04ba7521f6885d871fd6266fedc0a7ccf2637b85579c058927404bad7"}, + {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:15d78b0cd5d2090c063031d76e933b8b24e043d524a6091a751cf57b0fab025f"}, + {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ee76beaf87695f2204b0c2c2a3664b39f3483b7a8447b28e5e2bcc899861b3eb"}, + {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8840f0e82d6dca3888bd06e7ab0ca6d39009f3cd3475028d8bc03c939127afc2"}, + {file = "ddtrace-2.5.2-cp310-cp310-win32.whl", hash = "sha256:a34ccab0c8991c5fc5252d5cd6e88852cd7f77c8bf838de84e70b4a3bfacaad4"}, + {file = "ddtrace-2.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:ffa4f5779c7000fe5960156bd15339184355b30a661b0955799cae50da5d03a7"}, + {file = "ddtrace-2.5.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ea2740a3d61876cb07b271af444e98cdc8b730497cfcddbc3794c7a7441b8d15"}, + {file = "ddtrace-2.5.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:62e775ba9d2a2b5f952a6609029e965057bdd852ccd6e53b55c0f82ae83aa542"}, + {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30186112f156a564efda5e2018240b55baee7664897ca5fc35c452d032a77185"}, + {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9dccdc69de364cffc2b892280724c78cb54db151452a0b6d1b4a89b6f060c44"}, + {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa2543c2303ab325af7794f2a8a420133cd9222e70bfbce3869da146fc5e2ba"}, + {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aa2e64f79ada9f2fd5307cd0eba726d8585e47b0282fb9463aaa4b267265e94a"}, + {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:37b4d55a5be59530e6e5761a36d727aee812be69c81b00ee0182eb62be6f3b75"}, + {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6d97f990d2322a23e82203cc5a2aa694fb0d42541a44bb120390e6598a63e5f5"}, + {file = "ddtrace-2.5.2-cp311-cp311-win32.whl", hash = "sha256:5d3f1bc3ce87fbcf2256197178179ef681df720ebbc39b0559bda00247744533"}, + {file = "ddtrace-2.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:a50057085b0972e695bb1ef3042f6cd6a1a3b12111fac4985942f2dbbcf8ac2f"}, + {file = "ddtrace-2.5.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b923b099b9a1e50f01ce8bcd4d11e3255a48c71f3e6314dd9a482baed0a87ed6"}, + {file = "ddtrace-2.5.2-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:512d3975b1657c706ca9c84373e5fce323f6fc94bfac33c30876ad8d55e0ea71"}, + {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c54bc474c70151d5a141061b6c20a1efabdf458e4239c790d45fa12a13b8e7d"}, + {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5fb2bbd38dc46ba6a7ea1031c4751b1ca888be5fac8a42049ebc2517707c00d"}, + {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa6fb6bcfb3810d8f0882e489e7d2ef4dd3a92b452cfdd8d1fd4703dc496b17"}, + {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3f4eed40d978352c7371804ecb68bbe9e55967bb904bd03b0568554e0b6b92cf"}, + {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:57606af5380888e2e7cc67b7c4fa5e1bc51d29c48f004b4be0cbe1b319fddc75"}, + {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ee8d0259a004964a8eddb394aa84a5754435d4270cd2041e6559c9e68fa49141"}, + {file = "ddtrace-2.5.2-cp312-cp312-win32.whl", hash = "sha256:4df564e620ec7e657fcdb0d5bf1231aa1357bf49b736f0d9e9f6df17a23fc569"}, + {file = "ddtrace-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:637f16af1c84566bde044798312c67bc5676df949632ab02e740440558f2a598"}, + {file = "ddtrace-2.5.2-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:d24841a9390f3e169edcaf1ca5ac80599062e66dee43a510decb25e779b6f7b4"}, + {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49aa4e0210862e829e09569de2e2f34ac17c5e246567c5b6662ec21e2a06d938"}, + {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:985738fe875b11f05dfa2b1f21a619d499344eb740f63e01d6eae1fb29eb949b"}, + {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8814321822e4afc95ac86fbc476dc20d78dd4b1d510c02606459df4580093d18"}, + {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ad6c0ae7baff9d00c689834aec0627274d681ed1d2a8ae627348a6191e8d32ec"}, + {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa596f2e80c525a2310e605bfa3fa6ba6790b2ae90c02e47ceee0e62ceae17a6"}, + {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6bdfae9fa03af334820678196a4895450d0b6bd9f1b5119d42ddbd327a55fcce"}, + {file = "ddtrace-2.5.2-cp37-cp37m-win32.whl", hash = "sha256:227bb0391d310e0d5a54505c7ab59f9692a5db91dc492373489bc45726980e1d"}, + {file = "ddtrace-2.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6e55c4738b58b4452933204305243e19000f6f283af93bf51b63382100cb8f21"}, + {file = "ddtrace-2.5.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:4d9e7a9e26c38ae1e368f5d820e78459ff2d39689f40d4a3db185ddb3686c383"}, + {file = "ddtrace-2.5.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:c361ea11b442b04d8e011528205ed65b926d71d18f38d372270204eabf49b068"}, + {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aafd86eeea622cd0e8cf6b63632efc67a52a32317d2a376382ef6170d383c9f"}, + {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ff039635470ba483ed448baaf6337d85a731b17af62fef06dfa811f761f374f"}, + {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f1cb3bea1170410d603f9d557918c24d4d8783659c03817daea6352d9f37f9"}, + {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7351500241eb24c7d789b371a6860ca2b0e2db1ff9d317089153b562a3a461e1"}, + {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a2cfc6ee800890556e404b94d13680c83952efa5d3dafa72ef8cb08a8782f874"}, + {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:96a791f03b62ebdb9f3e635a0e93711149123a8fc1c1c152be0d1cdb5d8e6359"}, + {file = "ddtrace-2.5.2-cp38-cp38-win32.whl", hash = "sha256:6c61e72abec3f2f6b46e53712a32a971de1b6a9be657d5ebeff1334f6146babc"}, + {file = "ddtrace-2.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:b93d8b536f5fc45a72bb2785051dc729f4d581ef2d69ed10bccae6a7487477b2"}, + {file = "ddtrace-2.5.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:38cbcb7b4ff1371480b29228d2b8e570e7d7b386a7632b96f9600135ec3eb9db"}, + {file = "ddtrace-2.5.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a270d128c6067f52a76ecbb658fae3f4d3bd4888baa9e6159ff82b6de14c53be"}, + {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e59f3958016fcec5eb16abd7979a9ec4d850733e2a03b878b096277fc092784"}, + {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:066403f0e00a8de09c8187037befe7463d1fab5d8178b62a07c2542792710d14"}, + {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbcbf24bca8497f1412ec438fbdc94847aef9e86092ffd4f8626bbe6d278d33"}, + {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d34f8da809e2783770a6c88396b3653fb12a4196e9b5f16b8c10f37bbf2b7b31"}, + {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9eaca41664dd0c2bd7257fe2e91c7e46718b20591bfaa0b5c01c39b599115f88"}, + {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f4b67e02ba5c316711719dcfc15e94f47684e7af1785289d016a29a2c664827"}, + {file = "ddtrace-2.5.2-cp39-cp39-win32.whl", hash = "sha256:9bbd675d73aae6516e02a86cb830778771dafb0e182d5a122270ccd82ee77eed"}, + {file = "ddtrace-2.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:e93f3f5d3d57beb492b04286c758be65495908bd313df6f56865ad7af222e49e"}, + {file = "ddtrace-2.5.2.tar.gz", hash = "sha256:5addeb19eea5ebdc23c493e5635f4c8737795b48ba637117a1895f31b900985f"}, ] [package.dependencies] @@ -943,7 +952,7 @@ bytecode = [ cattrs = "*" ddsketch = ">=2.0.1" envier = "*" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} +importlib-metadata = {version = "<=6.5.0", markers = "python_version < \"3.8\""} opentelemetry-api = ">=1" protobuf = ">=3" setuptools = {version = "*", markers = "python_version >= \"3.12\""} @@ -1019,13 +1028,13 @@ ssh = ["paramiko (>=2.4.3)"] [[package]] name = "envier" -version = "0.5.0" +version = "0.5.1" description = "Python application configuration via the environment" optional = false python-versions = ">=3.7" files = [ - {file = "envier-0.5.0-py3-none-any.whl", hash = "sha256:5fed6099ee5d7ad4cf664f8bb99d1281d4ab5fadeec8f40ba9458610938293be"}, - {file = "envier-0.5.0.tar.gz", hash = "sha256:f35ca8605f0c70c2c0367133af9dc1ef16710021dbd0e28c1b0a83070db06768"}, + {file = "envier-0.5.1-py3-none-any.whl", hash = "sha256:b45ef6051fea33d0c32a64e186bff2cfb446e2242d6781216c9bc9ce708c5909"}, + {file = "envier-0.5.1.tar.gz", hash = "sha256:bd5ccf707447973ea0f4125b7df202ba415ad888bcdcb8df80e0b002ee11ffdb"}, ] [package.extras] @@ -1250,17 +1259,6 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, - {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, - {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1321,13 +1319,13 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.7.0" +version = "6.5.0" description = "Read metadata from Python packages" optional = false python-versions = ">=3.7" files = [ - {file = "importlib_metadata-6.7.0-py3-none-any.whl", hash = "sha256:cb52082e659e97afc5dac71e79de97d8681de3aa07ff18578330904a9d18e5b5"}, - {file = "importlib_metadata-6.7.0.tar.gz", hash = "sha256:1aaf550d4f73e5d6783e7acb77aec43d49da8017410afae93822cc9cca98c4d4"}, + {file = "importlib_metadata-6.5.0-py3-none-any.whl", hash = "sha256:03ba783c3a2c69d751b109fc0c94a62c51f581b3d6acf8ed1331b6d5729321ff"}, + {file = "importlib_metadata-6.5.0.tar.gz", hash = "sha256:7a8bdf1bc3a726297f5cfbc999e6e7ff6b4fa41b26bba4afc580448624460045"}, ] [package.dependencies] @@ -1337,7 +1335,7 @@ zipp = ">=0.5" [package.extras] docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] +testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] [[package]] name = "importlib-resources" @@ -1463,6 +1461,20 @@ files = [ [package.dependencies] jsonpointer = ">=1.9" +[[package]] +name = "jsonpath-ng" +version = "1.6.1" +description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming." +optional = true +python-versions = "*" +files = [ + {file = "jsonpath-ng-1.6.1.tar.gz", hash = "sha256:086c37ba4917304850bd837aeab806670224d3f038fe2833ff593a672ef0a5fa"}, + {file = "jsonpath_ng-1.6.1-py3-none-any.whl", hash = "sha256:8f22cd8273d7772eea9aaa84d922e0841aa36fdb8a2c6b7f6c3791a16a9bc0be"}, +] + +[package.dependencies] +ply = "*" + [[package]] name = "jsonpickle" version = "3.0.2" @@ -1612,71 +1624,71 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.3" +version = "2.1.4" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win32.whl", hash = "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431"}, - {file = "MarkupSafe-2.1.3-cp310-cp310-win_amd64.whl", hash = "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win32.whl", hash = "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb"}, - {file = "MarkupSafe-2.1.3-cp311-cp311-win_amd64.whl", hash = "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:f698de3fd0c4e6972b92290a45bd9b1536bffe8c6759c62471efaa8acb4c37bc"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:aa57bd9cf8ae831a362185ee444e15a93ecb2e344c8e52e4d721ea3ab6ef1823"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffcc3f7c66b5f5b7931a5aa68fc9cecc51e685ef90282f4a82f0f5e9b704ad11"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d4f1c5f80fc62fdd7777d0d40a2e9dda0a05883ab11374334f6c4de38adffd"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1f67c7038d560d92149c060157d623c542173016c4babc0c1913cca0564b9939"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:9aad3c1755095ce347e26488214ef77e0485a3c34a50c5a5e2471dff60b9dd9c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:14ff806850827afd6b07a5f32bd917fb7f45b046ba40c57abdb636674a8b559c"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8f9293864fe09b8149f0cc42ce56e3f0e54de883a9de90cd427f191c346eb2e1"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win32.whl", hash = "sha256:715d3562f79d540f251b99ebd6d8baa547118974341db04f5ad06d5ea3eb8007"}, - {file = "MarkupSafe-2.1.3-cp312-cp312-win_amd64.whl", hash = "sha256:1b8dd8c3fd14349433c79fa8abeb573a55fc0fdd769133baac1f5e07abf54aeb"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win32.whl", hash = "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0"}, - {file = "MarkupSafe-2.1.3-cp37-cp37m-win_amd64.whl", hash = "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win32.whl", hash = "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5"}, - {file = "MarkupSafe-2.1.3-cp38-cp38-win_amd64.whl", hash = "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win32.whl", hash = "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2"}, - {file = "MarkupSafe-2.1.3-cp39-cp39-win_amd64.whl", hash = "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba"}, - {file = "MarkupSafe-2.1.3.tar.gz", hash = "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, + {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, + {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, + {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, + {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, + {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, + {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, + {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, ] [[package]] @@ -2171,6 +2183,17 @@ importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "ply" +version = "3.11" +description = "Python Lex & Yacc" +optional = true +python-versions = "*" +files = [ + {file = "ply-3.11-py2.py3-none-any.whl", hash = "sha256:096f9b8350b65ebd2fd1346b12452efe5b9607f7482813ffca50c22722a807ce"}, + {file = "ply-3.11.tar.gz", hash = "sha256:00c7c1aaa88358b9c765b6d3000c6eec0ba42abca5351b095321aef446081da3"}, +] + [[package]] name = "protobuf" version = "4.24.4" @@ -2505,13 +2528,13 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.3.post1" +version = "2023.4" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.3.post1-py2.py3-none-any.whl", hash = "sha256:ce42d816b81b68506614c11e8937d3aa9e41007ceb50bfdcb0749b921bf646c7"}, - {file = "pytz-2023.3.post1.tar.gz", hash = "sha256:7b4fddbeb94a1eba4b557da24f19fdf9db575192544270a9101d8509f9f43d7b"}, + {file = "pytz-2023.4-py2.py3-none-any.whl", hash = "sha256:f90ef520d95e7c46951105338d918664ebfd6f1d995bd7d153127ce90efafa6a"}, + {file = "pytz-2023.4.tar.gz", hash = "sha256:31d4583c4ed539cd037956140d695e42c033a19e984bfce9964a3f7d59bc2b40"}, ] [[package]] @@ -2549,7 +2572,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2557,16 +2579,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2583,7 +2597,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2591,7 +2604,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3144,6 +3156,20 @@ files = [ [package.dependencies] types-urllib3 = "*" +[[package]] +name = "types-requests" +version = "2.31.0.20231231" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.7" +files = [ + {file = "types-requests-2.31.0.20231231.tar.gz", hash = "sha256:0f8c0c9764773384122813548d9eea92a5c4e1f33ed54556b508968ec5065cee"}, + {file = "types_requests-2.31.0.20231231-py3-none-any.whl", hash = "sha256:2e2230c7bc8dd63fa3153c1c0ae335f8a368447f0582fc332f17d54f88e69027"}, +] + +[package.dependencies] +urllib3 = ">=2" + [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -3390,10 +3416,10 @@ docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] [extras] -all = ["aws-xray-sdk", "fastjsonschema", "pydantic"] +all = ["aws-encryption-sdk", "aws-xray-sdk", "fastjsonschema", "jsonpath-ng", "pydantic"] aws-sdk = ["boto3"] datadog = ["datadog-lambda"] -datamasking-aws-sdk = ["aws-encryption-sdk"] +datamasking = ["aws-encryption-sdk", "jsonpath-ng"] parser = ["pydantic"] redis = ["redis"] tracer = ["aws-xray-sdk"] @@ -3402,4 +3428,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "f4c66a8fa656902aba0c04cc8b5dc236d7f0ed6f7c3e22507cc89e711b0b62b2" +content-hash = "28c3a405185f635f8e65ea51adfe1cfc589cb469497d800100521f91037ba26a" diff --git a/pyproject.toml b/pyproject.toml index 0e576d412df..cb1f322e9ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ redis = {version = ">=4.4,<6.0", optional = true} typing-extensions = "^4.6.2" datadog-lambda = { version = ">=4.77,<6.0", optional = true } aws-encryption-sdk = { version = "^3.1.1", optional = true } +jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] coverage = {extras = ["toml"], version = "^7.2"} @@ -97,11 +98,11 @@ parser = ["pydantic"] validation = ["fastjsonschema"] tracer = ["aws-xray-sdk"] redis = ["redis"] -all = ["pydantic", "aws-xray-sdk", "fastjsonschema"] +all = ["pydantic", "aws-xray-sdk", "fastjsonschema", "aws-encryption-sdk", "jsonpath-ng"] # allow customers to run code locally without emulators (SAM CLI, etc.) aws-sdk = ["boto3"] datadog = ["datadog-lambda"] -datamasking-aws-sdk = ["aws-encryption-sdk"] +datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] cfn-lint = "0.83.8" diff --git a/tests/e2e/data_masking/handlers/basic_handler.py b/tests/e2e/data_masking/handlers/basic_handler.py index f31e822429a..6f696391822 100644 --- a/tests/e2e/data_masking/handlers/basic_handler.py +++ b/tests/e2e/data_masking/handlers/basic_handler.py @@ -1,6 +1,6 @@ from aws_lambda_powertools import Logger -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import AwsEncryptionSdkProvider +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider logger = Logger() @@ -14,7 +14,7 @@ def lambda_handler(event, context): # Encrypting data for test_encryption_in_handler test kms_key = event.get("kms_key", "") - data_masker = DataMasking(provider=AwsEncryptionSdkProvider(keys=[kms_key])) + data_masker = DataMasking(provider=AWSEncryptionSDKProvider(keys=[kms_key])) value = [1, 2, "string", 4.5] encrypted_data = data_masker.encrypt(value) response = {} diff --git a/tests/e2e/data_masking/test_e2e_data_masking.py b/tests/e2e/data_masking/test_e2e_data_masking.py index 80f45564177..a720a265d83 100644 --- a/tests/e2e/data_masking/test_e2e_data_masking.py +++ b/tests/e2e/data_masking/test_e2e_data_masking.py @@ -4,15 +4,13 @@ import pytest from aws_encryption_sdk.exceptions import DecryptKeyError -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import ( - AwsEncryptionSdkProvider, - ContextMismatchError, +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.exceptions import DataMaskingContextMismatchError +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + AWSEncryptionSDKProvider, ) from tests.e2e.utils import data_fetcher -pytest.skip(reason="Data masking tests disabled until we go GA.", allow_module_level=True) - @pytest.fixture def basic_handler_fn(infrastructure: dict) -> str: @@ -36,7 +34,7 @@ def kms_key2_arn(infrastructure: dict) -> str: @pytest.fixture def data_masker(kms_key1_arn) -> DataMasking: - return DataMasking(provider=AwsEncryptionSdkProvider(keys=[kms_key1_arn])) + return DataMasking(provider=AWSEncryptionSDKProvider(keys=[kms_key1_arn])) @pytest.mark.xdist_group(name="data_masking") @@ -79,7 +77,7 @@ def test_encryption_context_mismatch(data_masker): encrypted_data = data_masker.encrypt(value, encryption_context={"this": "is_secure"}) # THEN decrypting with a different encryption_context should raise a ContextMismatchError - with pytest.raises(ContextMismatchError): + with pytest.raises(DataMaskingContextMismatchError): data_masker.decrypt(encrypted_data, encryption_context={"not": "same_context"}) @@ -93,7 +91,7 @@ def test_encryption_no_context_fail(data_masker): encrypted_data = data_masker.encrypt(value) # THEN decrypting with an encryption_context should raise a ContextMismatchError - with pytest.raises(ContextMismatchError): + with pytest.raises(DataMaskingContextMismatchError): data_masker.decrypt(encrypted_data, encryption_context={"this": "is_secure"}) @@ -106,7 +104,7 @@ def test_encryption_decryption_key_mismatch(data_masker, kms_key2_arn): encrypted_data = data_masker.encrypt(value) # THEN when decrypting with a different key it should fail - data_masker_key2 = DataMasking(provider=AwsEncryptionSdkProvider(keys=[kms_key2_arn])) + data_masker_key2 = DataMasking(provider=AWSEncryptionSDKProvider(keys=[kms_key2_arn])) with pytest.raises(DecryptKeyError): data_masker_key2.decrypt(encrypted_data) diff --git a/tests/functional/data_masking/test_aws_encryption_sdk.py b/tests/functional/data_masking/test_aws_encryption_sdk.py index 978c2e21572..c1dfd22c6b9 100644 --- a/tests/functional/data_masking/test_aws_encryption_sdk.py +++ b/tests/functional/data_masking/test_aws_encryption_sdk.py @@ -1,34 +1,36 @@ from __future__ import annotations import base64 +import functools import json -from typing import Any, Callable, Dict, Union +from typing import Any, Callable import pytest +from aws_encryption_sdk.identifiers import Algorithm -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.constants import DATA_MASKING_STRING -from aws_lambda_powertools.utilities._data_masking.provider import BaseProvider -from aws_lambda_powertools.utilities._data_masking.provider.kms import ( - AwsEncryptionSdkProvider, +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.constants import DATA_MASKING_STRING +from aws_lambda_powertools.utilities.data_masking.provider import BaseProvider +from aws_lambda_powertools.utilities.data_masking.provider.kms import ( + AWSEncryptionSDKProvider, ) class FakeEncryptionKeyProvider(BaseProvider): def __init__( self, - json_serializer: Callable[[Dict], str] | None = None, - json_deserializer: Callable[[Union[Dict, str, bool, int, float]], str] | None = None, - ): - super().__init__(json_serializer=json_serializer, json_deserializer=json_deserializer) + json_serializer: Callable = functools.partial(json.dumps, ensure_ascii=False), + json_deserializer: Callable = json.loads, + ) -> None: + super().__init__(json_serializer, json_deserializer) def encrypt(self, data: bytes | str, **kwargs) -> str: - data = self.json_serializer(data) - ciphertext = base64.b64encode(data).decode() + encoded_data: str = self.json_serializer(data) + ciphertext = base64.b64encode(encoded_data.encode("utf-8")).decode() return ciphertext def decrypt(self, data: bytes, **kwargs) -> Any: - ciphertext_decoded = base64.b64decode(data) + ciphertext_decoded = base64.b64decode(data).decode("utf-8") ciphertext = self.json_deserializer(ciphertext_decoded) return ciphertext @@ -37,74 +39,74 @@ def decrypt(self, data: bytes, **kwargs) -> Any: def data_masker(monkeypatch) -> DataMasking: """DataMasking using AWS Encryption SDK Provider with a fake client""" fake_key_provider = FakeEncryptionKeyProvider() - provider = AwsEncryptionSdkProvider( + provider = AWSEncryptionSDKProvider( keys=["dummy"], key_provider=fake_key_provider, ) return DataMasking(provider=provider) -def test_mask_int(data_masker): +def test_erase_int(data_masker): # GIVEN an int data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(42) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(42) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_float(data_masker): +def test_erase_float(data_masker): # GIVEN a float data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(4.2) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(4.2) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_bool(data_masker): +def test_erase_bool(data_masker): # GIVEN a bool data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(True) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(True) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_none(data_masker): +def test_erase_none(data_masker): # GIVEN a None data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(None) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(None) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_str(data_masker): +def test_erase_str(data_masker): # GIVEN a str data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask("this is a string") + # WHEN erase is called with no fields argument + erased_string = data_masker.erase("this is a string") # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_list(data_masker): +def test_erase_list(data_masker): # GIVEN a list data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask([1, 2, "string", 3]) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase([1, 2, "string", 3]) # THEN the result is the data masked, while maintaining type list - assert masked_string == [DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING] + assert erased_string == [DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING] -def test_mask_dict(data_masker): +def test_erase_dict(data_masker): # GIVEN a dict data type data = { "a": { @@ -113,14 +115,14 @@ def test_mask_dict(data_masker): }, } - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(data) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(data) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_dict_with_fields(data_masker): +def test_erase_dict_with_fields(data_masker): # GIVEN a dict data type data = { "a": { @@ -129,11 +131,11 @@ def test_mask_dict_with_fields(data_masker): }, } - # WHEN mask is called with a list of fields specified - masked_string = data_masker.mask(data, fields=["a.1.None", "a.b.3.4"]) + # WHEN erase is called with a list of fields specified + erased_string = data_masker.erase(data, fields=["a.'1'.None", "a..'4'"]) # THEN the result is only the specified fields are masked - assert masked_string == { + assert erased_string == { "a": { "1": {"None": DATA_MASKING_STRING, "four": "world"}, "b": {"3": {"4": DATA_MASKING_STRING, "e": "world"}}, @@ -141,7 +143,7 @@ def test_mask_dict_with_fields(data_masker): } -def test_mask_json_dict_with_fields(data_masker): +def test_erase_json_dict_with_fields(data_masker): # GIVEN the data type is a json representation of a dictionary data = json.dumps( { @@ -152,8 +154,8 @@ def test_mask_json_dict_with_fields(data_masker): }, ) - # WHEN mask is called with a list of fields specified - masked_json_string = data_masker.mask(data, fields=["a.1.None", "a.b.3.4"]) + # WHEN erase is called with a list of fields specified + masked_json_string = data_masker.erase(data, fields=["a.'1'.None", "a..'4'"]) # THEN the result is only the specified fields are masked assert masked_json_string == { @@ -257,8 +259,8 @@ def test_encrypt_dict_with_fields(data_masker): } # WHEN encrypting and then decrypting the encrypted data - encrypted_data = data_masker.encrypt(data, fields=["a.1.None", "a.b.3.4"]) - decrypted_data = data_masker.decrypt(encrypted_data, fields=["a.1.None", "a.b.3.4"]) + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) # THEN the result is only the specified fields are masked assert decrypted_data == data @@ -276,8 +278,199 @@ def test_encrypt_json_dict_with_fields(data_masker): ) # WHEN encrypting and then decrypting the encrypted data - encrypted_data = data_masker.encrypt(data, fields=["a.1.None", "a.b.3.4"]) - decrypted_data = data_masker.decrypt(encrypted_data, fields=["a.1.None", "a.b.3.4"]) + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) # THEN the result is only the specified fields are masked - assert decrypted_data == json.loads(data) + assert decrypted_data == data + + +def test_encrypt_json_with_list_fields(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "payload": { + "first": ["value1", "value2"], + "second": [{"key1": [0, 1]}], + }, + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_json_with_tuple_fields(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "payload": { + "first": ["value1", "value2"], + "second": (0, 1), + }, + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_with_encryption_context(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "payload": { + "first": ["value1", "value2"], + "second": (0, 1), + }, + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data, data_classification="confidential") + decrypted_data = data_masker.decrypt(encrypted_data, data_classification="confidential") + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_with_complex_dict(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "name": "Leandro", + "operation": "non sensitive", + "card_number": "1000 4444 333 2222", + "address": [ + { + "postcode": 81847, + "street": "38986 Joanne Stravenue", + "country": "United States", + "timezone": "America/La_Paz", + }, + { + "postcode": 94400, + "street": "623 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + { + "postcode": 94480, + "street": "123 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + ], + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_with_slice(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "name": "Leandro", + "operation": "non sensitive", + "card_number": "1000 4444 333 2222", + "address": [ + { + "postcode": 81847, + "street": "38986 Joanne Stravenue", + "country": "United States", + "timezone": "America/La_Paz", + }, + { + "postcode": 94400, + "street": "623 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + { + "postcode": 94480, + "street": "123 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + ], + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_with_complex_search(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "name": "Leandro", + "operation": "non sensitive", + "card_number": "1000 4444 333 2222", + "address": [ + { + "postcode": 81847, + "street": "38986 Joanne Stravenue", + "country": "United States", + "timezone": "America/La_Paz", + }, + { + "postcode": 94400, + "street": "623 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + { + "postcode": 94480, + "street": "123 Kraig Mall", + "country": "United States", + "timezone": "America/Mazatlan", + }, + ], + }, + ) + + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data + + +def test_encrypt_with_provider_options(data_masker): + # GIVEN the data type is a json representation of a dictionary with a list inside + data = json.dumps( + { + "payload": { + "first": ["value1", "value2"], + "second": (0, 1), + }, + }, + ) + + provider_options = {"algorithm": Algorithm.AES_256_GCM_HKDF_SHA512_COMMIT_KEY} + # WHEN encrypting and then decrypting the encrypted data + encrypted_data = data_masker.encrypt(data, provider_options=provider_options) + decrypted_data = data_masker.decrypt(encrypted_data) + + # THEN the result is only the specified fields are masked + assert decrypted_data == data diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/app.py b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/app.py index 9a898ea10cd..76081b20392 100644 --- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/app.py +++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1024/app.py @@ -3,8 +3,8 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.logging import correlation_paths -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import AwsEncryptionSdkProvider +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider from aws_lambda_powertools.utilities.typing import LambdaContext KMS_KEY_ARN = os.environ["KMS_KEY_ARN"] @@ -48,7 +48,7 @@ @tracer.capture_method def function1024(): logger.info("Hello world function1024 - HTTP 200") - data_masker = DataMasking(provider=AwsEncryptionSdkProvider(keys=[KMS_KEY_ARN])) + data_masker = DataMasking(provider=AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])) encrypted = data_masker.encrypt(json_blob, fields=["address.street", "job_history.company.company_name"]) decrypted = data_masker.decrypt(encrypted, fields=["address.street", "job_history.company.company_name"]) return {"Decrypted_json_blob_function_1024": decrypted} diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/app.py b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/app.py index 6b8250579a5..b191ade241a 100644 --- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/app.py +++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_128/app.py @@ -3,8 +3,8 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.logging import correlation_paths -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import AwsEncryptionSdkProvider +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider from aws_lambda_powertools.utilities.typing import LambdaContext KMS_KEY_ARN = os.environ["KMS_KEY_ARN"] @@ -48,7 +48,7 @@ @tracer.capture_method def function128(): logger.info("Hello world function128 - HTTP 200") - data_masker = DataMasking(provider=AwsEncryptionSdkProvider(keys=[KMS_KEY_ARN])) + data_masker = DataMasking(provider=AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])) encrypted = data_masker.encrypt(json_blob, fields=["address.street", "job_history.company.company_name"]) decrypted = data_masker.decrypt(encrypted, fields=["address.street", "job_history.company.company_name"]) return {"Decrypted_json_blob_function_128": decrypted} diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/app.py b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/app.py index 623a1f7b232..19d287e6011 100644 --- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/app.py +++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/function_1769/app.py @@ -3,8 +3,8 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import APIGatewayRestResolver from aws_lambda_powertools.logging import correlation_paths -from aws_lambda_powertools.utilities._data_masking import DataMasking -from aws_lambda_powertools.utilities._data_masking.provider.kms.aws_encryption_sdk import AwsEncryptionSdkProvider +from aws_lambda_powertools.utilities.data_masking import DataMasking +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import AWSEncryptionSDKProvider from aws_lambda_powertools.utilities.typing import LambdaContext KMS_KEY_ARN = os.environ["KMS_KEY_ARN"] @@ -48,7 +48,7 @@ @tracer.capture_method def function1769(): logger.info("Hello world function1769 - HTTP 200") - data_masker = DataMasking(provider=AwsEncryptionSdkProvider(keys=[KMS_KEY_ARN])) + data_masker = DataMasking(provider=AWSEncryptionSDKProvider(keys=[KMS_KEY_ARN])) encrypted = data_masker.encrypt(json_blob, fields=["address.street", "job_history.company.company_name"]) decrypted = data_masker.decrypt(encrypted, fields=["address.street", "job_history.company.company_name"]) return {"Decrypted_json_blob_function_1769": decrypted} diff --git a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/template.yaml b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/template.yaml index b70fb6d061e..7df194d80bb 100644 --- a/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/template.yaml +++ b/tests/performance/data_masking/load_test_data_masking/pt-load-test-stack/template.yaml @@ -38,7 +38,9 @@ Resources: Policies: Statement: - Effect: Allow - Action: kms:* + Action: + - kms:Decrypt + - kms:GenerateDataKey Resource: !GetAtt MyKMSKey.Arn Tracing: Active Events: @@ -68,7 +70,9 @@ Resources: Policies: Statement: - Effect: Allow - Action: kms:* + Action: + - kms:Decrypt + - kms:GenerateDataKey Resource: !GetAtt MyKMSKey.Arn Tracing: Active Events: @@ -98,7 +102,9 @@ Resources: Policies: Statement: - Effect: Allow - Action: kms:* + Action: + - kms:Decrypt + - kms:GenerateDataKey Resource: !GetAtt MyKMSKey.Arn Tracing: Active Events: diff --git a/tests/performance/data_masking/test_perf_data_masking.py b/tests/performance/data_masking/test_perf_data_masking.py index 688e36c7a64..668da32a6e9 100644 --- a/tests/performance/data_masking/test_perf_data_masking.py +++ b/tests/performance/data_masking/test_perf_data_masking.py @@ -3,11 +3,11 @@ import pytest -from aws_lambda_powertools.utilities._data_masking.base import DataMasking +from aws_lambda_powertools.utilities.data_masking.base import DataMasking -DATA_MASKING_PACKAGE = "aws_lambda_powertools.utilities._data_masking" +DATA_MASKING_PACKAGE = "aws_lambda_powertools.utilities.data_masking" DATA_MASKING_INIT_SLA: float = 0.002 -DATA_MASKING_NESTED_ENCRYPT_SLA: float = 0.001 +DATA_MASKING_NESTED_ENCRYPT_SLA: float = 0.05 json_blob = { "id": 1, @@ -55,15 +55,15 @@ def test_data_masking_init(benchmark): pytest.fail(f"High level imports should be below {DATA_MASKING_INIT_SLA}s: {stat}") -def mask_json_blob(): +def erase_json_blob(): data_masker = DataMasking() - data_masker.mask(json_blob, json_blob_fields) + data_masker.erase(json_blob, json_blob_fields) @pytest.mark.perf @pytest.mark.benchmark(group="core", disable_gc=True, warmup=False) def test_data_masking_encrypt_with_json_blob(benchmark): - benchmark.pedantic(mask_json_blob) + benchmark.pedantic(erase_json_blob) stat = benchmark.stats.stats.max if stat > DATA_MASKING_NESTED_ENCRYPT_SLA: pytest.fail(f"High level imports should be below {DATA_MASKING_NESTED_ENCRYPT_SLA}s: {stat}") diff --git a/tests/unit/data_masking/test_kms_provider.py b/tests/unit/data_masking/test_kms_provider.py new file mode 100644 index 00000000000..5fe9b2e53ed --- /dev/null +++ b/tests/unit/data_masking/test_kms_provider.py @@ -0,0 +1,42 @@ +import pytest + +from aws_lambda_powertools.utilities.data_masking.exceptions import ( + DataMaskingContextMismatchError, + DataMaskingUnsupportedTypeError, +) +from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( + KMSKeyProvider, +) + + +def test_encryption_context_exact_match(): + ctx = {"data_classification": "confidential", "data_type": "customer_data"} + ctx_two = {"data_type": "customer_data", "data_classification": "confidential"} + + KMSKeyProvider._compare_encryption_context(ctx, ctx_two) + + +def test_encryption_context_partial_match(): + ctx = {"data_classification": "confidential", "data_type": "customer_data"} + ctx_two = {"data_type": "customer_data"} + + with pytest.raises(DataMaskingContextMismatchError): + KMSKeyProvider._compare_encryption_context(ctx, ctx_two) + + +def test_encryption_context_supported_values(): + ctx = {"a": "b", "c": "d"} + KMSKeyProvider._validate_encryption_context(ctx) + KMSKeyProvider._validate_encryption_context({}) + + +@pytest.mark.parametrize( + "ctx", + [ + pytest.param({"a": 10, "b": True, "c": []}, id="non_string_values"), + pytest.param({"a": {"b": "c"}}, id="nested_dict"), + ], +) +def test_encryption_context_non_str_validation(ctx): + with pytest.raises(DataMaskingUnsupportedTypeError): + KMSKeyProvider._validate_encryption_context(ctx) diff --git a/tests/unit/data_masking/test_unit_data_masking.py b/tests/unit/data_masking/test_unit_data_masking.py index 4a92a668d73..4fbbc188ceb 100644 --- a/tests/unit/data_masking/test_unit_data_masking.py +++ b/tests/unit/data_masking/test_unit_data_masking.py @@ -2,8 +2,12 @@ import pytest -from aws_lambda_powertools.utilities._data_masking.base import DataMasking -from aws_lambda_powertools.utilities._data_masking.constants import DATA_MASKING_STRING +from aws_lambda_powertools.utilities.data_masking.base import DataMasking +from aws_lambda_powertools.utilities.data_masking.constants import DATA_MASKING_STRING +from aws_lambda_powertools.utilities.data_masking.exceptions import ( + DataMaskingFieldNotFoundError, + DataMaskingUnsupportedTypeError, +) @pytest.fixture @@ -11,67 +15,67 @@ def data_masker() -> DataMasking: return DataMasking() -def test_mask_int(data_masker): +def test_erase_int(data_masker): # GIVEN an int data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(42) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(42) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_float(data_masker): +def test_erase_float(data_masker): # GIVEN a float data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(4.2) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(4.2) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_bool(data_masker): +def test_erase_bool(data_masker): # GIVEN a bool data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(True) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(True) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_none(data_masker): +def test_erase_none(data_masker): # GIVEN a None data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(None) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(None) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_str(data_masker): +def test_erase_str(data_masker): # GIVEN a str data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask("this is a string") + # WHEN erase is called with no fields argument + erased_string = data_masker.erase("this is a string") # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_list(data_masker): +def test_erase_list(data_masker): # GIVEN a list data type - # WHEN mask is called with no fields argument - masked_string = data_masker.mask([1, 2, "string", 3]) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase([1, 2, "string", 3]) # THEN the result is the data masked, while maintaining type list - assert masked_string == [DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING] + assert erased_string == [DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING, DATA_MASKING_STRING] -def test_mask_dict(data_masker): +def test_erase_dict(data_masker): # GIVEN a dict data type data = { "a": { @@ -80,14 +84,14 @@ def test_mask_dict(data_masker): }, } - # WHEN mask is called with no fields argument - masked_string = data_masker.mask(data) + # WHEN erase is called with no fields argument + erased_string = data_masker.erase(data) # THEN the result is the data masked - assert masked_string == DATA_MASKING_STRING + assert erased_string == DATA_MASKING_STRING -def test_mask_dict_with_fields(data_masker): +def test_erase_dict_with_fields(data_masker): # GIVEN a dict data type data = { "a": { @@ -96,11 +100,11 @@ def test_mask_dict_with_fields(data_masker): }, } - # WHEN mask is called with a list of fields specified - masked_string = data_masker.mask(data, fields=["a.1.None", "a.b.3.4"]) + # WHEN erase is called with a list of fields specified + erased_string = data_masker.erase(data, fields=["a.'1'.None", "a..'4'"]) - # THEN the result is only the specified fields are masked - assert masked_string == { + # THEN the result is only the specified fields are erased + assert erased_string == { "a": { "1": {"None": DATA_MASKING_STRING, "four": "world"}, "b": {"3": {"4": DATA_MASKING_STRING, "e": "world"}}, @@ -108,7 +112,7 @@ def test_mask_dict_with_fields(data_masker): } -def test_mask_json_dict_with_fields(data_masker): +def test_erase_json_dict_with_fields(data_masker): # GIVEN the data type is a json representation of a dictionary data = json.dumps( { @@ -119,10 +123,10 @@ def test_mask_json_dict_with_fields(data_masker): }, ) - # WHEN mask is called with a list of fields specified - masked_json_string = data_masker.mask(data, fields=["a.1.None", "a.b.3.4"]) + # WHEN erase is called with a list of fields specified + masked_json_string = data_masker.erase(data, fields=["a.'1'.None", "a..'4'"]) - # THEN the result is only the specified fields are masked + # THEN the result is only the specified fields are erased assert masked_json_string == { "a": { "1": {"None": DATA_MASKING_STRING, "four": "world"}, @@ -153,13 +157,24 @@ def test_parsing_unsupported_data_type(data_masker): # GIVEN an initialization of the DataMasking class # WHEN attempting to pass in a list of fields with input data that is not a dict - with pytest.raises(TypeError): + with pytest.raises(DataMaskingUnsupportedTypeError): # THEN the result is a TypeError - data_masker.mask(42, ["this.field"]) + data_masker.erase(42, ["this.field"]) -def test_parsing_nonexistent_fields(data_masker): +def test_parsing_with_empty_field(data_masker): + # GIVEN an initialization of the DataMasking class + + # WHEN attempting to pass in a list of fields with input data that is not a dict + with pytest.raises(ValueError): + # THEN the result is a TypeError + data_masker.erase(42, []) + + +def test_parsing_nonexistent_fields_with_raise_on_missing_field(): # GIVEN a dict data type + + data_masker = DataMasking(raise_on_missing_field=True) data = { "3": { "1": {"None": "hello", "four": "world"}, @@ -168,13 +183,15 @@ def test_parsing_nonexistent_fields(data_masker): } # WHEN attempting to pass in fields that do not exist in the input data - with pytest.raises(KeyError): + with pytest.raises(DataMaskingFieldNotFoundError): # THEN the result is a KeyError - data_masker.mask(data, ["3.1.True"]) + data_masker.erase(data, ["'3'..True"]) -def test_parsing_nonstring_fields(data_masker): +def test_parsing_nonexistent_fields_warning_on_missing_field(): # GIVEN a dict data type + + data_masker = DataMasking(raise_on_missing_field=False) data = { "3": { "1": {"None": "hello", "four": "world"}, @@ -182,24 +199,9 @@ def test_parsing_nonstring_fields(data_masker): }, } - # WHEN attempting to pass in a list of fields that are not strings - masked = data_masker.mask(data, fields=[3.4]) - - # THEN the result is the value of the nested field should be masked as normal - assert masked == {"3": {"1": {"None": "hello", "four": "world"}, "4": DATA_MASKING_STRING}} - - -def test_parsing_nonstring_keys_and_fields(data_masker): - # GIVEN a dict data type with integer keys - data = { - 3: { - "1": {"None": "hello", "four": "world"}, - 4: {"33": {"5": "goodbye", "e": "world"}}, - }, - } - - # WHEN masked with a list of fields that are integer keys - masked = data_masker.mask(data, fields=[3.4]) + # WHEN erase is called with a non-existing field + with pytest.warns(UserWarning, match="Field or expression*"): + masked_json_string = data_masker.erase(data, fields=["non-existing"]) - # THEN the result is the value of the nested field should be masked - assert masked == {"3": {"1": {"None": "hello", "four": "world"}, "4": DATA_MASKING_STRING}} + # THEN the "erased" payload is the same of the original + assert masked_json_string == data From 33820d12921aa8491588aa6a281a45066073e767 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Thu, 1 Feb 2024 16:44:47 +0000 Subject: [PATCH 0039/2666] feat(event_handler): support Header parameter validation in OpenAPI schema (#3687) * Adding header - Initial commit * Adding header - Fix VPC Lattice Payload * Adding header - tests and final changes * Making sonarqube happy * Adding documentation * Rafactoring to be complaint with RFC * Adding tests * Adding test with Uppercase variables * Revert event changes * Adding HTTP RFC * Adding getter/setter to clean the code * Adding getter/setter to clean the code * Addressing Ruben's feedback --- .../middlewares/openapi_validation.py | 48 +- .../event_handler/openapi/dependant.py | 27 +- .../event_handler/openapi/params.py | 79 +- .../utilities/data_classes/alb_event.py | 11 + .../data_classes/api_gateway_proxy_event.py | 19 + .../data_classes/bedrock_agent_event.py | 6 +- .../utilities/data_classes/common.py | 15 + .../utilities/data_classes/vpc_lattice.py | 15 + docs/core/event_handler/api_gateway.md | 40 +- .../src/validating_headers.py | 39 + .../src/working_with_headers_multi_value.py | 34 + .../events/albMultiValueQueryStringEvent.json | 7 + tests/events/apiGatewayProxyEvent.json | 2 +- .../lambdaFunctionUrlEventWithHeaders.json | 4 +- tests/events/vpcLatticeEvent.json | 4 +- .../events/vpcLatticeV2EventWithHeaders.json | 31 +- .../event_handler/test_openapi_params.py | 6 +- .../test_openapi_validation_middleware.py | 699 +++++++++++++----- 18 files changed, 873 insertions(+), 213 deletions(-) create mode 100644 examples/event_handler_rest/src/validating_headers.py create mode 100644 examples/event_handler_rest/src/working_with_headers_multi_value.py diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py index fd7507603de..54c48189282 100644 --- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py @@ -81,9 +81,22 @@ def handler(self, app: EventHandlerInstance, next_middleware: NextMiddleware) -> query_string, ) + # Normalize header values before validate this + headers = _normalize_multi_header_values_with_param( + app.current_event.resolved_headers_field, + route.dependant.header_params, + ) + + # Process header values + header_values, header_errors = _request_params_to_args( + route.dependant.header_params, + headers, + ) + values.update(path_values) values.update(query_values) - errors += path_errors + query_errors + values.update(header_values) + errors += path_errors + query_errors + header_errors # Process the request body, if it exists if route.dependant.body_params: @@ -243,12 +256,14 @@ def _request_params_to_args( errors = [] for field in required_params: - value = received_params.get(field.alias) - field_info = field.field_info + + # To ensure early failure, we check if it's not an instance of Param. if not isinstance(field_info, Param): raise AssertionError(f"Expected Param field_info, got {field_info}") + value = received_params.get(field.alias) + loc = (field_info.in_.value, field.alias) # If we don't have a value, see if it's required or has a default @@ -377,3 +392,30 @@ def _normalize_multi_query_string_with_param(query_string: Optional[Dict[str, st except KeyError: pass return query_string + + +def _normalize_multi_header_values_with_param(headers: Optional[Dict[str, str]], params: Sequence[ModelField]): + """ + Extract and normalize resolved_headers_field + + Parameters + ---------- + headers: Dict + A dictionary containing the initial header parameters. + params: Sequence[ModelField] + A sequence of ModelField objects representing parameters. + + Returns + ------- + A dictionary containing the processed headers. + """ + if headers: + for param in filter(is_scalar_field, params): + try: + if len(headers[param.alias]) == 1: + # if the target parameter is a scalar and the list contains only 1 element + # we keep the first value of the headers regardless if there are more in the payload + headers[param.alias] = headers[param.alias][0] + except KeyError: + pass + return headers diff --git a/aws_lambda_powertools/event_handler/openapi/dependant.py b/aws_lambda_powertools/event_handler/openapi/dependant.py index 418a86e083c..abcb91e90dd 100644 --- a/aws_lambda_powertools/event_handler/openapi/dependant.py +++ b/aws_lambda_powertools/event_handler/openapi/dependant.py @@ -14,12 +14,12 @@ from aws_lambda_powertools.event_handler.openapi.params import ( Body, Dependant, + Header, Param, ParamTypes, Query, _File, _Form, - _Header, analyze_param, create_response_field, get_flat_dependant, @@ -59,16 +59,21 @@ def add_param_to_fields( """ field_info = cast(Param, field.field_info) - if field_info.in_ == ParamTypes.path: - dependant.path_params.append(field) - elif field_info.in_ == ParamTypes.query: - dependant.query_params.append(field) - elif field_info.in_ == ParamTypes.header: - dependant.header_params.append(field) + + # Dictionary to map ParamTypes to their corresponding lists in dependant + param_type_map = { + ParamTypes.path: dependant.path_params, + ParamTypes.query: dependant.query_params, + ParamTypes.header: dependant.header_params, + ParamTypes.cookie: dependant.cookie_params, + } + + # Check if field_info.in_ is a valid key in param_type_map and append the field to the corresponding list + # or raise an exception if it's not a valid key. + if field_info.in_ in param_type_map: + param_type_map[field_info.in_].append(field) else: - if field_info.in_ != ParamTypes.cookie: - raise AssertionError(f"Unsupported param type: {field_info.in_}") - dependant.cookie_params.append(field) + raise AssertionError(f"Unsupported param type: {field_info.in_}") def get_typed_annotation(annotation: Any, globalns: Dict[str, Any]) -> Any: @@ -265,7 +270,7 @@ def is_body_param(*, param_field: ModelField, is_path_param: bool) -> bool: return False elif is_scalar_field(field=param_field): return False - elif isinstance(param_field.field_info, (Query, _Header)) and is_scalar_sequence_field(param_field): + elif isinstance(param_field.field_info, (Query, Header)) and is_scalar_sequence_field(param_field): return False else: if not isinstance(param_field.field_info, Body): diff --git a/aws_lambda_powertools/event_handler/openapi/params.py b/aws_lambda_powertools/event_handler/openapi/params.py index 78426cbc7c9..d5665a48d30 100644 --- a/aws_lambda_powertools/event_handler/openapi/params.py +++ b/aws_lambda_powertools/event_handler/openapi/params.py @@ -486,7 +486,7 @@ def __init__( ) -class _Header(Param): +class Header(Param): """ A class used internally to represent a header parameter in a path operation. """ @@ -527,12 +527,75 @@ def __init__( json_schema_extra: Union[Dict[str, Any], None] = None, **extra: Any, ): + """ + Constructs a new Query param. + + Parameters + ---------- + default: Any + The default value of the parameter + default_factory: Callable[[], Any], optional + Callable that will be called when a default value is needed for this field + annotation: Any, optional + The type annotation of the parameter + alias: str, optional + The public name of the field + alias_priority: int, optional + Priority of the alias. This affects whether an alias generator is used + validation_alias: str | AliasPath | AliasChoices | None, optional + Alias to be used for validation only + serialization_alias: str | AliasPath | AliasChoices | None, optional + Alias to be used for serialization only + convert_underscores: bool + If true convert "_" to "-" + See RFC: https://www.rfc-editor.org/rfc/rfc9110.html#name-field-name-registry + title: str, optional + The title of the parameter + description: str, optional + The description of the parameter + gt: float, optional + Only applies to numbers, required the field to be "greater than" + ge: float, optional + Only applies to numbers, required the field to be "greater than or equal" + lt: float, optional + Only applies to numbers, required the field to be "less than" + le: float, optional + Only applies to numbers, required the field to be "less than or equal" + min_length: int, optional + Only applies to strings, required the field to have a minimum length + max_length: int, optional + Only applies to strings, required the field to have a maximum length + pattern: str, optional + Only applies to strings, requires the field match against a regular expression pattern string + discriminator: str, optional + Parameter field name for discriminating the type in a tagged union + strict: bool, optional + Enables Pydantic's strict mode for the field + multiple_of: float, optional + Only applies to numbers, requires the field to be a multiple of the given value + allow_inf_nan: bool, optional + Only applies to numbers, requires the field to allow infinity and NaN values + max_digits: int, optional + Only applies to Decimals, requires the field to have a maxmium number of digits within the decimal. + decimal_places: int, optional + Only applies to Decimals, requires the field to have at most a number of decimal places + examples: List[Any], optional + A list of examples for the parameter + deprecated: bool, optional + If `True`, the parameter will be marked as deprecated + include_in_schema: bool, optional + If `False`, the parameter will be excluded from the generated OpenAPI schema + json_schema_extra: Dict[str, Any], optional + Extra values to include in the generated OpenAPI schema + """ self.convert_underscores = convert_underscores + self._alias = alias + super().__init__( default=default, default_factory=default_factory, annotation=annotation, - alias=alias, + alias=self._alias, alias_priority=alias_priority, validation_alias=validation_alias, serialization_alias=serialization_alias, @@ -558,6 +621,18 @@ def __init__( **extra, ) + @property + def alias(self): + return self._alias + + @alias.setter + def alias(self, value: Optional[str] = None): + if value is not None: + # Headers are case-insensitive according to RFC 7540 (HTTP/2), so we lower the parameter name + # This ensures that customers can access headers with any casing, as per the RFC guidelines. + # Reference: https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2 + self._alias = value.lower() + class Body(FieldInfo): """ diff --git a/aws_lambda_powertools/utilities/data_classes/alb_event.py b/aws_lambda_powertools/utilities/data_classes/alb_event.py index 688c9567efa..98f37b4f415 100644 --- a/aws_lambda_powertools/utilities/data_classes/alb_event.py +++ b/aws_lambda_powertools/utilities/data_classes/alb_event.py @@ -42,6 +42,17 @@ def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: return self.query_string_parameters + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + headers: Dict[str, Any] = {} + + if self.multi_value_headers: + headers = self.multi_value_headers + else: + headers = self.headers + + return {key.lower(): value for key, value in headers.items()} + @property def multi_value_headers(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueHeaders") diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index 9e013eac038..c37bd22ca53 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -125,6 +125,17 @@ def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: return self.query_string_parameters + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + headers: Dict[str, Any] = {} + + if self.multi_value_headers: + headers = self.multi_value_headers + else: + headers = self.headers + + return {key.lower(): value for key, value in headers.items()} + @property def request_context(self) -> APIGatewayEventRequestContext: return APIGatewayEventRequestContext(self._data) @@ -316,3 +327,11 @@ def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: return query_string return {} + + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + if self.headers is not None: + headers = {key.lower(): value.split(",") if "," in value else value for key, value in self.headers.items()} + return headers + + return {} diff --git a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py index d9b45242376..0fa97036a3e 100644 --- a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +++ b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from typing import Any, Dict, List, Optional from aws_lambda_powertools.utilities.data_classes.common import BaseProxyEvent, DictWrapper @@ -112,3 +112,7 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]: @property def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: return self.query_string_parameters + + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + return {} diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index d2cf57d4af5..0560159ecc5 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -114,6 +114,21 @@ def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: """ return self.query_string_parameters + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + """ + This property determines the appropriate header to be used + as a trusted source for validating OpenAPI. + + This is necessary because different resolvers use different formats to encode + headers parameters. + + Headers are case-insensitive according to RFC 7540 (HTTP/2), so we lower the header name + This ensures that customers can access headers with any casing, as per the RFC guidelines. + Reference: https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2 + """ + return self.headers + @property def is_base64_encoded(self) -> Optional[bool]: return self.get("isBase64Encoded") diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py index 633ce068f6e..f12c53d841a 100644 --- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py @@ -145,6 +145,14 @@ def query_string_parameters(self) -> Dict[str, str]: def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: return self.query_string_parameters + @property + def resolved_headers_field(self) -> Optional[Dict[str, Any]]: + if self.headers is not None: + headers = {key.lower(): value.split(",") if "," in value else value for key, value in self.headers.items()} + return headers + + return {} + class vpcLatticeEventV2Identity(DictWrapper): @property @@ -259,3 +267,10 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]: @property def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: return self.query_string_parameters + + @property + def resolved_headers_field(self) -> Optional[Dict[str, str]]: + if self.headers is not None: + return {key.lower(): value for key, value in self.headers.items()} + + return {} diff --git a/docs/core/event_handler/api_gateway.md b/docs/core/event_handler/api_gateway.md index 86b97c87e4b..32631ac867e 100644 --- a/docs/core/event_handler/api_gateway.md +++ b/docs/core/event_handler/api_gateway.md @@ -368,13 +368,13 @@ We use the `Annotated` and OpenAPI `Body` type to instruct Event Handler that ou !!! info "We will automatically validate and inject incoming query strings via type annotation." -We use the `Annotated` type to tell Event Handler that a particular parameter is not only an optional string, but also a query string with constraints. +We use the `Annotated` type to tell the Event Handler that a particular parameter is not only an optional string, but also a query string with constraints. In the following example, we use a new `Query` OpenAPI type to add [one out of many possible constraints](#customizing-openapi-parameters), which should read as: * `completed` is a query string with a `None` as its default value * `completed`, when set, should have at minimum 4 characters -* Doesn't match? Event Handler will return a validation error response +* No match? Event Handler will return a validation error response @@ -386,7 +386,7 @@ In the following example, we use a new `Query` OpenAPI type to add [one out of m 1. If you're not using Python 3.9 or higher, you can install and use [`typing_extensions`](https://pypi.org/project/typing-extensions/){target="_blank" rel="nofollow"} to the same effect 2. `Query` is a special OpenAPI type that can add constraints to a query string as well as document them - 3. **First time seeing the `Annotated`?**

This special type uses the first argument as the actual type, and subsequent arguments are metadata.

At runtime, static checkers will also see the first argument, but anyone receiving them could inspect them to fetch their metadata. + 3. **First time seeing `Annotated`?**

This special type uses the first argument as the actual type, and subsequent arguments as metadata.

At runtime, static checkers will also see the first argument, but any receiver can inspect it to get the metadata. === "skip_validating_query_strings.py" @@ -424,6 +424,40 @@ For example, we could validate that `` dynamic path should be no greate 1. `Path` is a special OpenAPI type that allows us to constrain todo_id to be less than 999. +#### Validating headers + +We use the `Annotated` type to tell the Event Handler that a particular parameter is a header that needs to be validated. + +!!! info "We adhere to [HTTP RFC standards](https://www.rfc-editor.org/rfc/rfc7540#section-8.1.2){target="_blank" rel="nofollow"}, which means we treat HTTP headers as case-insensitive." + +In the following example, we use a new `Header` OpenAPI type to add [one out of many possible constraints](#customizing-openapi-parameters), which should read as: + +* `correlation_id` is a header that must be present in the request +* `correlation_id` should have 16 characters +* No match? Event Handler will return a validation error response + + + +=== "validating_headers.py" + + ```python hl_lines="8 10 27" + --8<-- "examples/event_handler_rest/src/validating_headers.py" + ``` + + 1. If you're not using Python 3.9 or higher, you can install and use [`typing_extensions`](https://pypi.org/project/typing-extensions/){target="_blank" rel="nofollow"} to the same effect + 2. `Header` is a special OpenAPI type that can add constraints and documentation to a header + 3. **First time seeing `Annotated`?**

This special type uses the first argument as the actual type, and subsequent arguments as metadata.

At runtime, static checkers will also see the first argument, but any receiver can inspect it to get the metadata. + +=== "working_with_headers_multi_value.py" + + You can handle multi-value headers by declaring it as a list of the desired type. + + ```python hl_lines="23" + --8<-- "examples/event_handler_rest/src/working_with_headers_multi_value.py" + ``` + + 1. `cloudfront_viewer_country` is a list that must contain values from the `CountriesAllowed` enumeration. + ### Accessing request details Event Handler integrates with [Event Source Data Classes utilities](../../utilities/data_classes.md){target="_blank"}, and it exposes their respective resolver request details and convenient methods under `app.current_event`. diff --git a/examples/event_handler_rest/src/validating_headers.py b/examples/event_handler_rest/src/validating_headers.py new file mode 100644 index 00000000000..e830a49c38c --- /dev/null +++ b/examples/event_handler_rest/src/validating_headers.py @@ -0,0 +1,39 @@ +from typing import List, Optional + +import requests +from pydantic import BaseModel, Field + +from aws_lambda_powertools import Logger, Tracer +from aws_lambda_powertools.event_handler import APIGatewayRestResolver +from aws_lambda_powertools.event_handler.openapi.params import Header # (2)! +from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import Annotated # (1)! +from aws_lambda_powertools.utilities.typing import LambdaContext + +tracer = Tracer() +logger = Logger() +app = APIGatewayRestResolver(enable_validation=True) + + +class Todo(BaseModel): + userId: int + id_: Optional[int] = Field(alias="id", default=None) + title: str + completed: bool + + +@app.get("/todos") +@tracer.capture_method +def get_todos(correlation_id: Annotated[str, Header(min_length=16, max_length=16)]) -> List[Todo]: # (3)! + url = "https://jsonplaceholder.typicode.com/todos" + + todo = requests.get(url, headers={"correlation_id": correlation_id}) + todo.raise_for_status() + + return todo.json() + + +@logger.inject_lambda_context(correlation_id_path=correlation_paths.API_GATEWAY_HTTP) +@tracer.capture_lambda_handler +def lambda_handler(event: dict, context: LambdaContext) -> dict: + return app.resolve(event, context) diff --git a/examples/event_handler_rest/src/working_with_headers_multi_value.py b/examples/event_handler_rest/src/working_with_headers_multi_value.py new file mode 100644 index 00000000000..956fd58b14d --- /dev/null +++ b/examples/event_handler_rest/src/working_with_headers_multi_value.py @@ -0,0 +1,34 @@ +from enum import Enum +from typing import List + +from aws_lambda_powertools.event_handler import APIGatewayRestResolver +from aws_lambda_powertools.event_handler.openapi.params import Header +from aws_lambda_powertools.shared.types import Annotated +from aws_lambda_powertools.utilities.typing import LambdaContext + +app = APIGatewayRestResolver(enable_validation=True) + + +class CountriesAllowed(Enum): + """Example of an Enum class.""" + + US = "US" + PT = "PT" + BR = "BR" + + +@app.get("/hello") +def get( + cloudfront_viewer_country: Annotated[ + List[CountriesAllowed], # (1)! + Header( + description="This is multi value header parameter.", + ), + ], +): + """Return validated multi-value header values.""" + return cloudfront_viewer_country + + +def lambda_handler(event: dict, context: LambdaContext) -> dict: + return app.resolve(event, context) diff --git a/tests/events/albMultiValueQueryStringEvent.json b/tests/events/albMultiValueQueryStringEvent.json index 4584ba7c477..d5cdf18f023 100644 --- a/tests/events/albMultiValueQueryStringEvent.json +++ b/tests/events/albMultiValueQueryStringEvent.json @@ -14,6 +14,13 @@ "accept": [ "*/*" ], + "header2": [ + "value1", + "value2" + ], + "header1": [ + "value1" + ], "host": [ "alb-c-LoadB-14POFKYCLBNSF-1815800096.eu-central-1.elb.amazonaws.com" ], diff --git a/tests/events/apiGatewayProxyEvent.json b/tests/events/apiGatewayProxyEvent.json index 3f095e28e45..da814c91100 100644 --- a/tests/events/apiGatewayProxyEvent.json +++ b/tests/events/apiGatewayProxyEvent.json @@ -78,4 +78,4 @@ "stageVariables": null, "body": "Hello from Lambda!", "isBase64Encoded": false -} \ No newline at end of file +} diff --git a/tests/events/lambdaFunctionUrlEventWithHeaders.json b/tests/events/lambdaFunctionUrlEventWithHeaders.json index e453690d9b3..d1cc50630a8 100644 --- a/tests/events/lambdaFunctionUrlEventWithHeaders.json +++ b/tests/events/lambdaFunctionUrlEventWithHeaders.json @@ -23,7 +23,9 @@ "cache-control":"max-age=0", "accept-encoding":"gzip, deflate, br", "sec-fetch-dest":"document", - "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36" + "user-agent":"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36", + "header1": "value1", + "header2": "value1,value2" }, "queryStringParameters": { "parameter1": "value1,value2", diff --git a/tests/events/vpcLatticeEvent.json b/tests/events/vpcLatticeEvent.json index 936bfb22d1b..fa9031f7dc4 100644 --- a/tests/events/vpcLatticeEvent.json +++ b/tests/events/vpcLatticeEvent.json @@ -5,7 +5,9 @@ "user_agent": "curl/7.64.1", "x-forwarded-for": "10.213.229.10", "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", - "accept": "*/*" + "accept": "*/*", + "header1": "value1", + "header2": "value1,value2" }, "query_string_parameters": { "order-id": "1" diff --git a/tests/events/vpcLatticeV2EventWithHeaders.json b/tests/events/vpcLatticeV2EventWithHeaders.json index 11b36ef118b..fdaf7dc7891 100644 --- a/tests/events/vpcLatticeV2EventWithHeaders.json +++ b/tests/events/vpcLatticeV2EventWithHeaders.json @@ -2,12 +2,31 @@ "version": "2.0", "path": "/newpath", "method": "GET", - "headers": { - "user_agent": "curl/7.64.1", - "x-forwarded-for": "10.213.229.10", - "host": "test-lambda-service-3908sdf9u3u.dkfjd93.vpc-lattice-svcs.us-east-2.on.aws", - "accept": "*/*" - }, + "headers":{ + "user-agent":[ + "curl/8.3.0" + ], + "accept":[ + "*/*" + ], + "powertools":[ + "a", + "b" + ], + "x-forwarded-for":[ + "172.31.40.143" + ], + "host":[ + "lattice-svc-027b423199122da5f.7d67968.vpc-lattice-svcs.us-east-1.on.aws" + ], + "Header1": [ + "value1" + ], + "Header2": [ + "value1", + "value2" + ] + }, "queryStringParameters": { "parameter1": [ "value1", diff --git a/tests/functional/event_handler/test_openapi_params.py b/tests/functional/event_handler/test_openapi_params.py index 2f48f5aa534..38b0cbed307 100644 --- a/tests/functional/event_handler/test_openapi_params.py +++ b/tests/functional/event_handler/test_openapi_params.py @@ -13,11 +13,11 @@ ) from aws_lambda_powertools.event_handler.openapi.params import ( Body, + Header, Param, ParamTypes, Query, _create_model_field, - _Header, ) from aws_lambda_powertools.shared.types import Annotated @@ -431,7 +431,7 @@ def handler(): def test_create_header(): - header = _Header(convert_underscores=True) + header = Header(convert_underscores=True) assert header.convert_underscores is True @@ -456,7 +456,7 @@ def test_create_model_field_with_empty_in(): # Tests that when we try to create a model field with convert_underscore, we convert the field name def test_create_model_field_convert_underscore(): - field_info = _Header(alias=None, convert_underscores=True) + field_info = Header(alias=None, convert_underscores=True) result = _create_model_field(field_info, int, "user_id", False) assert result.alias == "user-id" diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index 23fa131ab9f..07e2a34ac42 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -4,6 +4,7 @@ from pathlib import PurePath from typing import List, Tuple +import pytest from pydantic import BaseModel from aws_lambda_powertools.event_handler import ( @@ -12,9 +13,10 @@ APIGatewayRestResolver, LambdaFunctionUrlResolver, Response, + VPCLatticeResolver, VPCLatticeV2Resolver, ) -from aws_lambda_powertools.event_handler.openapi.params import Body, Query +from aws_lambda_powertools.event_handler.openapi.params import Body, Header, Query from aws_lambda_powertools.shared.types import Annotated from tests.functional.utils import load_event @@ -23,6 +25,7 @@ LOAD_GW_EVENT_ALB = load_event("albMultiValueQueryStringEvent.json") LOAD_GW_EVENT_LAMBDA_URL = load_event("lambdaFunctionUrlEventWithHeaders.json") LOAD_GW_EVENT_VPC_LATTICE = load_event("vpcLatticeV2EventWithHeaders.json") +LOAD_GW_EVENT_VPC_LATTICE_V1 = load_event("vpcLatticeEvent.json") def test_validate_scalars(): @@ -417,267 +420,601 @@ def handler(user: Model) -> Response[Model]: assert "missing" in result["body"] -def test_validate_rest_api_resolver_with_multi_query_params(): - # GIVEN an APIGatewayRestResolver with validation enabled +########### TEST WITH QUERY PARAMS +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_without_query_params", 200, None), + ], +) +def test_validation_query_string_with_api_rest_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) - # WHEN a handler is defined with a default scalar parameter and a list - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) - LOAD_GW_EVENT["httpMethod"] = "GET" LOAD_GW_EVENT["path"] = "/users" + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT, {}) - assert result["statusCode"] == 200 + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) -def test_validate_rest_api_resolver_with_multi_query_params_fail(): - # GIVEN an APIGatewayRestResolver with validation enabled - app = APIGatewayRestResolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(parameter1: Annotated[List[int], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) - LOAD_GW_EVENT["httpMethod"] = "GET" - LOAD_GW_EVENT["path"] = "/users" + # Define handler3 without params + if handler_func == "handler3_without_query_params": + LOAD_GW_EVENT["queryStringParameters"] = None + LOAD_GW_EVENT["multiValueQueryStringParameters"] = None - # THEN the handler should be invoked and return 422 + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code result = app(LOAD_GW_EVENT, {}) - assert result["statusCode"] == 422 - assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + assert result["statusCode"] == expected_status_code + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) -def test_validate_rest_api_resolver_without_query_params(): - # GIVEN an APIGatewayRestResolver with validation enabled - app = APIGatewayRestResolver(enable_validation=True) - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(): - return None +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_without_query_params", 200, None), + ], +) +def test_validation_query_string_with_api_http_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a APIGatewayHttpResolver with validation enabled + app = APIGatewayHttpResolver(enable_validation=True) - LOAD_GW_EVENT["httpMethod"] = "GET" - LOAD_GW_EVENT["path"] = "/users" - LOAD_GW_EVENT["queryStringParameters"] = None - LOAD_GW_EVENT["multiValueQueryStringParameters"] = None + LOAD_GW_EVENT_HTTP["rawPath"] = "/users" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT, {}) - assert result["statusCode"] == 200 + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) -def test_validate_http_resolver_with_multi_query_params(): - # GIVEN an APIGatewayHttpResolver with validation enabled - app = APIGatewayHttpResolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined with a default scalar parameter and a list - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) - LOAD_GW_EVENT_HTTP["rawPath"] = "/users" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + # Define handler3 without params + if handler_func == "handler3_without_query_params": + LOAD_GW_EVENT_HTTP["queryStringParameters"] = None - # THEN the handler should be invoked and return 200 + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code result = app(LOAD_GW_EVENT_HTTP, {}) - assert result["statusCode"] == 200 + assert result["statusCode"] == expected_status_code + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) -def test_validate_http_resolver_with_multi_query_values_fail(): - # GIVEN an APIGatewayHttpResolver with validation enabled - app = APIGatewayHttpResolver(enable_validation=True) - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(parameter1: Annotated[List[int], Query()], parameter2: str): - print(parameter2) +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_without_query_params", 200, None), + ], +) +def test_validation_query_string_with_alb_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a ALBResolver with validation enabled + app = ALBResolver(enable_validation=True) - LOAD_GW_EVENT_HTTP["rawPath"] = "/users" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + LOAD_GW_EVENT_ALB["path"] = "/users" + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT_HTTP, {}) - assert result["statusCode"] == 422 - assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) -def test_validate_http_resolver_without_query_params(): - # GIVEN an APIGatewayHttpResolver with validation enabled - app = APIGatewayHttpResolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": + + @app.get("/users") + def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + # Define handler3 without params + if handler_func == "handler3_without_query_params": + LOAD_GW_EVENT_HTTP["multiValueQueryStringParameters"] = None + + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_ALB, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) + + +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_without_query_params", 200, None), + ], +) +def test_validation_query_string_with_lambda_url_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a LambdaFunctionUrlResolver with validation enabled + app = LambdaFunctionUrlResolver(enable_validation=True) + + LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" + LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + # WHEN a handler is defined with various parameters and routes + + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + + @app.get("/users") + def handler1(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": + + @app.get("/users") + def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + # Define handler3 without params + if handler_func == "handler3_without_query_params": + LOAD_GW_EVENT_LAMBDA_URL["queryStringParameters"] = None + + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) + + +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_without_query_params", 200, None), + ], +) +def test_validation_query_string_with_vpc_lattice_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a VPCLatticeV2Resolver with validation enabled + app = VPCLatticeV2Resolver(enable_validation=True) + + LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + + # WHEN a handler is defined with various parameters and routes + + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + + @app.get("/users") + def handler1(parameter1: Annotated[List[str], Query()], parameter2: str): + print(parameter2) + + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": + + @app.get("/users") + def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): + print(parameter2) + + # Define handler3 without params + if handler_func == "handler3_without_query_params": + LOAD_GW_EVENT_VPC_LATTICE["queryStringParameters"] = None + + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) + + +########### TEST WITH HEADER PARAMS +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_api_rest_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) - # WHEN a handler is defined without any query params - @app.get("/users") - def handler(): - return None + LOAD_GW_EVENT["httpMethod"] = "GET" + LOAD_GW_EVENT["path"] = "/users" + # WHEN a handler is defined with various parameters and routes + + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) + + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": + + @app.get("/users") + def handler2(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) + + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": + + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT["headers"] = None + LOAD_GW_EVENT["multiValueHeaders"] = None + + @app.get("/users") + def handler4(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) + + +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_http_rest_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a APIGatewayHttpResolver with validation enabled + app = APIGatewayHttpResolver(enable_validation=True) LOAD_GW_EVENT_HTTP["rawPath"] = "/users" LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" - LOAD_GW_EVENT_HTTP["queryStringParameters"] = None + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_HTTP, {}) - assert result["statusCode"] == 200 + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) -def test_validate_alb_resolver_with_multi_query_values(): - # GIVEN an ALBResolver with validation enabled - app = ALBResolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined with a default scalar parameter and a list - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler2(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) - LOAD_GW_EVENT_ALB["path"] = "/users" + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_ALB, {}) - assert result["statusCode"] == 200 + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT_HTTP["headers"] = None -def test_validate_alb_resolver_with_multi_query_values_fail(): - # GIVEN an ALBResolver with validation enabled - app = ALBResolver(enable_validation=True) - - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(parameter1: Annotated[List[int], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler4(): + return None - LOAD_GW_EVENT_ALB["path"] = "/users" + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_HTTP, {}) + assert result["statusCode"] == expected_status_code - # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT_ALB, {}) - assert result["statusCode"] == 422 - assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) -def test_validate_alb_resolver_without_query_params(): - # GIVEN an ALBResolver with validation enabled +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_alb_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a ALBResolver with validation enabled app = ALBResolver(enable_validation=True) - # WHEN a handler is defined without any query params - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) - LOAD_GW_EVENT_ALB["path"] = "/users" - LOAD_GW_EVENT_HTTP["multiValueQueryStringParameters"] = None + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_ALB, {}) - assert result["statusCode"] == 200 + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) -def test_validate_lambda_url_resolver_with_multi_query_params(): - # GIVEN an LambdaFunctionUrlResolver with validation enabled - app = LambdaFunctionUrlResolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined with a default scalar parameter and a list - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler2(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) - LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) - assert result["statusCode"] == 200 + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT_ALB["multiValueHeaders"] = None -def test_validate_lambda_url_resolver_with_multi_query_params_fail(): - # GIVEN an LambdaFunctionUrlResolver with validation enabled - app = LambdaFunctionUrlResolver(enable_validation=True) + @app.get("/users") + def handler4(): + return None - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(parameter1: Annotated[List[int], Query()], parameter2: str): - print(parameter2) + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_ALB, {}) + assert result["statusCode"] == expected_status_code - LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) - # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) - assert result["statusCode"] == 422 - assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) - -def test_validate_lambda_url_resolver_without_query_params(): - # GIVEN an LambdaFunctionUrlResolver with validation enabled +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_lambda_url_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a LambdaFunctionUrlResolver with validation enabled app = LambdaFunctionUrlResolver(enable_validation=True) - # WHEN a handler is defined without any query params - @app.get("/users") - def handler(): - return None - LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" - LOAD_GW_EVENT_LAMBDA_URL["queryStringParameters"] = None + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) - assert result["statusCode"] == 200 + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) -def test_validate_vpc_lattice_resolver_with_multi_params_values(): - # GIVEN an VPCLatticeV2Resolver with validation enabled - app = VPCLatticeV2Resolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined with a default scalar parameter and a list - @app.get("/users") - def handler(parameter1: Annotated[List[str], Query()], parameter2: str): - print(parameter2) + @app.get("/users") + def handler2(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) - LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": - # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) - assert result["statusCode"] == 200 + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT_LAMBDA_URL["headers"] = None -def test_validate_vpc_lattice_resolver_with_multi_query_params_fail(): - # GIVEN an VPCLatticeV2Resolver with validation enabled - app = VPCLatticeV2Resolver(enable_validation=True) + @app.get("/users") + def handler4(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) - # WHEN a handler is defined with a default scalar parameter and a list with wrong type - @app.get("/users") - def handler(parameter1: Annotated[List[int], Query()], parameter2: str): - print(parameter2) + +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_vpc_lattice_v1_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a VPCLatticeResolver with validation enabled + app = VPCLatticeResolver(enable_validation=True) + + LOAD_GW_EVENT_VPC_LATTICE_V1["raw_path"] = "/users" + LOAD_GW_EVENT_VPC_LATTICE_V1["method"] = "GET" + # WHEN a handler is defined with various parameters and routes + + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) + + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": + + @app.get("/users") + def handler2(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) + + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": + + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT_VPC_LATTICE_V1["headers"] = None + + @app.get("/users") + def handler4(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code + result = app(LOAD_GW_EVENT_VPC_LATTICE_V1, {}) + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) + + +@pytest.mark.parametrize( + "handler_func, expected_status_code, expected_error_text", + [ + ("handler1_with_correct_params", 200, None), + ("handler2_with_wrong_params", 422, "['type_error.integer', 'int_parsing']"), + ("handler3_with_uppercase_params", 200, None), + ("handler4_without_header_params", 200, None), + ], +) +def test_validation_header_with_vpc_lattice_v2_resolver(handler_func, expected_status_code, expected_error_text): + # GIVEN a VPCLatticeV2Resolver with validation enabled + app = VPCLatticeV2Resolver(enable_validation=True) LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + LOAD_GW_EVENT_VPC_LATTICE["method"] = "GET" + # WHEN a handler is defined with various parameters and routes - # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) - assert result["statusCode"] == 422 - assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) + # Define handler1 with correct params + if handler_func == "handler1_with_correct_params": + @app.get("/users") + def handler1(header2: Annotated[List[str], Header()], header1: Annotated[str, Header()]): + print(header2) -def test_validate_vpc_lattice_resolver_without_query_params(): - # GIVEN an VPCLatticeV2Resolver with validation enabled - app = VPCLatticeV2Resolver(enable_validation=True) + # Define handler2 with wrong params + if handler_func == "handler2_with_wrong_params": - # WHEN a handler is defined without any query params - @app.get("/users") - def handler(): - return None + @app.get("/users") + def handler1(header2: Annotated[List[int], Header()], header1: Annotated[str, Header()]): + print(header2) - LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" - LOAD_GW_EVENT_VPC_LATTICE["queryStringParameters"] = None + # Define handler3 with uppercase parameters + if handler_func == "handler3_with_uppercase_params": - # THEN the handler should be invoked and return 200 + @app.get("/users") + def handler3( + header2: Annotated[List[str], Header(name="Header2")], + header1: Annotated[str, Header(name="Header1")], + ): + print(header2) + + # Define handler4 without params + if handler_func == "handler4_without_header_params": + LOAD_GW_EVENT_VPC_LATTICE["headers"] = None + + @app.get("/users") + def handler3(): + return None + + # THEN the handler should be invoked with the expected result + # AND the status code should match the expected_status_code result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) - assert result["statusCode"] == 200 + assert result["statusCode"] == expected_status_code + + # IF expected_error_text is provided, THEN check for its presence in the response body + if expected_error_text: + assert any(text in result["body"] for text in expected_error_text) From a15a3587d93391c41e8872f350a3d9237c4fd750 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 1 Feb 2024 22:49:32 +0000 Subject: [PATCH 0040/2666] chore(deps-dev): bump aws-cdk from 2.124.0 to 2.125.0 (#3693) Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.124.0 to 2.125.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/commits/v2.125.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index cdfbdeceff1..514a6b2f6de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.124.0" + "aws-cdk": "^2.125.0" } }, "node_modules/aws-cdk": { - "version": "2.124.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.124.0.tgz", - "integrity": "sha512-kUOfqwIAaTEx4ZozojZEhWa8G+O9KU+P0tERtDVmTw9ip4QXNMwTTkjj/IPtoH8qfXGdeibTQ9MJwRvHOR8kXQ==", + "version": "2.125.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.125.0.tgz", + "integrity": "sha512-6qFtaDPzhddhwIbCpqBjMePzZS7bfthGFQYfcwF1OhqMv2f3VpHQQ0f7kz4UxXJXUIR5BbgCnlpawH3c0aNzKw==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index bf23efc23e3..78063c6eb64 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.124.0" + "aws-cdk": "^2.125.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 90df6b168bed04102b567a43cfe2f0867395b85b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 07:30:18 +0000 Subject: [PATCH 0041/2666] chore(ci): changelog rebuild (#3696) --- CHANGELOG.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5024e61b44..59162d1c4bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,26 +10,29 @@ ## Documentation +* **data-masking:** add docs for data masking utility ([#3186](https://github.com/aws-powertools/powertools-lambda-python/issues/3186)) * **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) * **proccess:** add versioning and maintenance policy ([#3682](https://github.com/aws-powertools/powertools-lambda-python/issues/3682)) ## Features +* **event_handler:** support Header parameter validation in OpenAPI schema ([#3687](https://github.com/aws-powertools/powertools-lambda-python/issues/3687)) * **event_handler:** add support for multiValueQueryStringParameters in OpenAPI schema ([#3667](https://github.com/aws-powertools/powertools-lambda-python/issues/3667)) ## Maintenance -* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) -* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) * **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) * **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) +* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) * **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) +* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) +* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) * **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) -* **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) * **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) +* **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) * **deps-dev:** bump ruff from 0.1.14 to 0.1.15 ([#3685](https://github.com/aws-powertools/powertools-lambda-python/issues/3685)) -* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) +* **deps-dev:** bump aws-cdk from 2.124.0 to 2.125.0 ([#3693](https://github.com/aws-powertools/powertools-lambda-python/issues/3693)) From 94c588e7db8a65354dcd7a8be821ae41f3068adc Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Fri, 2 Feb 2024 09:23:07 +0000 Subject: [PATCH 0042/2666] fix(data-masking): fix and improve e2e tests for DataMasking (#3695) Fixing and improving e2e tests for DataMasking Co-authored-by: Heitor Lessa --- .../e2e/data_masking/test_e2e_data_masking.py | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/tests/e2e/data_masking/test_e2e_data_masking.py b/tests/e2e/data_masking/test_e2e_data_masking.py index a720a265d83..3ee2400b5cc 100644 --- a/tests/e2e/data_masking/test_e2e_data_masking.py +++ b/tests/e2e/data_masking/test_e2e_data_masking.py @@ -2,16 +2,23 @@ from uuid import uuid4 import pytest -from aws_encryption_sdk.exceptions import DecryptKeyError from aws_lambda_powertools.utilities.data_masking import DataMasking -from aws_lambda_powertools.utilities.data_masking.exceptions import DataMaskingContextMismatchError +from aws_lambda_powertools.utilities.data_masking.exceptions import ( + DataMaskingContextMismatchError, + DataMaskingDecryptKeyError, +) from aws_lambda_powertools.utilities.data_masking.provider.kms.aws_encryption_sdk import ( AWSEncryptionSDKProvider, ) from tests.e2e.utils import data_fetcher +@pytest.fixture +def security_context(): + return {"this": "is_secure"} + + @pytest.fixture def basic_handler_fn(infrastructure: dict) -> str: return infrastructure.get("BasicHandler", "") @@ -53,36 +60,35 @@ def test_encryption(data_masker): @pytest.mark.xdist_group(name="data_masking") -def test_encryption_context(data_masker): +def test_encryption_context(data_masker, security_context): # GIVEN an instantiation of DataMasking with the AWS encryption provider value = [1, 2, "string", 4.5] - context = {"this": "is_secure"} # WHEN encrypting and then decrypting the encrypted data with an encryption_context - encrypted_data = data_masker.encrypt(value, encryption_context=context) - decrypted_data = data_masker.decrypt(encrypted_data, encryption_context=context) + encrypted_data = data_masker.encrypt(value, **security_context) + decrypted_data = data_masker.decrypt(encrypted_data, **security_context) # THEN the result is the original input data assert decrypted_data == value @pytest.mark.xdist_group(name="data_masking") -def test_encryption_context_mismatch(data_masker): +def test_encryption_context_mismatch(data_masker, security_context): # GIVEN an instantiation of DataMasking with the AWS encryption provider value = [1, 2, "string", 4.5] # WHEN encrypting with a encryption_context - encrypted_data = data_masker.encrypt(value, encryption_context={"this": "is_secure"}) + encrypted_data = data_masker.encrypt(value, **security_context) # THEN decrypting with a different encryption_context should raise a ContextMismatchError with pytest.raises(DataMaskingContextMismatchError): - data_masker.decrypt(encrypted_data, encryption_context={"not": "same_context"}) + data_masker.decrypt(encrypted_data, this="different_context") @pytest.mark.xdist_group(name="data_masking") -def test_encryption_no_context_fail(data_masker): +def test_encryption_no_context_fail(data_masker, security_context): # GIVEN an instantiation of DataMasking with the AWS encryption provider value = [1, 2, "string", 4.5] @@ -92,7 +98,7 @@ def test_encryption_no_context_fail(data_masker): # THEN decrypting with an encryption_context should raise a ContextMismatchError with pytest.raises(DataMaskingContextMismatchError): - data_masker.decrypt(encrypted_data, encryption_context={"this": "is_secure"}) + data_masker.decrypt(encrypted_data, **security_context) @pytest.mark.xdist_group(name="data_masking") @@ -106,7 +112,7 @@ def test_encryption_decryption_key_mismatch(data_masker, kms_key2_arn): # THEN when decrypting with a different key it should fail data_masker_key2 = DataMasking(provider=AWSEncryptionSDKProvider(keys=[kms_key2_arn])) - with pytest.raises(DecryptKeyError): + with pytest.raises(DataMaskingDecryptKeyError): data_masker_key2.decrypt(encrypted_data) From 2d1fe1d724f8ebda49f4486cd13bd0a672da7838 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:13:53 +0000 Subject: [PATCH 0043/2666] chore(ci): layer docs update (#3698) Co-authored-by: Powertools for AWS Lambda (Python) bot --- CHANGELOG.md | 32 ++----- docs/index.md | 142 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 5 files changed, 81 insertions(+), 99 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 59162d1c4bb..182dc2c948a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,35 +4,16 @@ # Unreleased -## Bug Fixes - -* **event-handler:** strip whitespace from Content-Type headers during OpenAPI schema validation ([#3677](https://github.com/aws-powertools/powertools-lambda-python/issues/3677)) - -## Documentation -* **data-masking:** add docs for data masking utility ([#3186](https://github.com/aws-powertools/powertools-lambda-python/issues/3186)) -* **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) -* **proccess:** add versioning and maintenance policy ([#3682](https://github.com/aws-powertools/powertools-lambda-python/issues/3682)) - -## Features + +## [v2.33.0] - 2024-02-02 +## Bug Fixes -* **event_handler:** support Header parameter validation in OpenAPI schema ([#3687](https://github.com/aws-powertools/powertools-lambda-python/issues/3687)) -* **event_handler:** add support for multiValueQueryStringParameters in OpenAPI schema ([#3667](https://github.com/aws-powertools/powertools-lambda-python/issues/3667)) +* **data-masking:** fix and improve e2e tests for DataMasking ([#3695](https://github.com/aws-powertools/powertools-lambda-python/issues/3695)) ## Maintenance -* **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) -* **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) -* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) -* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) -* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) -* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) -* **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) -* **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) -* **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) -* **deps-dev:** bump ruff from 0.1.14 to 0.1.15 ([#3685](https://github.com/aws-powertools/powertools-lambda-python/issues/3685)) -* **deps-dev:** bump aws-cdk from 2.124.0 to 2.125.0 ([#3693](https://github.com/aws-powertools/powertools-lambda-python/issues/3693)) +* version bump @@ -4306,7 +4287,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...HEAD +[v2.33.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...v2.33.0 [v2.32.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.31.0...v2.32.0 [v2.31.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.2...v2.31.0 [v2.30.2]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.1...v2.30.2 diff --git a/docs/index.md b/docs/index.md index b13bbc122d8..a5132120490 100644 --- a/docs/index.md +++ b/docs/index.md @@ -26,8 +26,8 @@ Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverles You can install Powertools for AWS Lambda (Python) using one of the following options: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: +* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: +* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: * **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** !!! question "Looking for Pip signed releases? [Learn more about verifying signed builds](./security.md#verifying-signed-builds)" @@ -80,67 +80,67 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:60](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | ??? note "Note: Click to expand and copy code snippets for popular frameworks" @@ -153,7 +153,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 ``` === "Serverless framework" @@ -163,7 +163,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 ``` === "CDK" @@ -179,7 +179,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -228,7 +228,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -281,7 +281,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd ? 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:AWSLambdaPowertoolsPythonV2:60 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 ❯ amplify push -y @@ -292,7 +292,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd - 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:AWSLambdaPowertoolsPythonV2:60 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 ? Do you want to edit the local lambda function now? No ``` @@ -306,7 +306,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 ``` === "Serverless framework" @@ -317,7 +317,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 ``` === "CDK" @@ -333,7 +333,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -383,7 +383,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:60"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -439,7 +439,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd ? 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:AWSLambdaPowertoolsPythonV2-Arm64:60 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 ❯ amplify push -y @@ -450,7 +450,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd - 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:AWSLambdaPowertoolsPythonV2-Arm64:60 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 ? Do you want to edit the local lambda function now? No ``` @@ -458,7 +458,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd Change {region} to your AWS region, e.g. `eu-west-1` ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:60 --region {region} + aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 --region {region} ``` The pre-signed URL to download this Lambda Layer will be within `Location` key. diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 9440f37c48f..02885ffb3bb 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:AWSLambdaPowertoolsPythonV2:60 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index e479ef1732a..2b9e885f20d 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,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:AWSLambdaPowertoolsPythonV2:60 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index e48d27a75ea..a7961c7c44b 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:AWSLambdaPowertoolsPythonV2:60 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 Resources: CaptureLambdaHandlerExample: From 61223e1606b7ebeab8802c3e47b18989532ebddc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 2 Feb 2024 10:59:24 +0000 Subject: [PATCH 0044/2666] chore(ci): bump version to 2.33.0 (#3697) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index adcf3dc5272..7cac1198767 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.32.0" +VERSION = "2.33.0" diff --git a/pyproject.toml b/pyproject.toml index cb1f322e9ba..98917d05f5d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.32.0" +version = "2.33.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"] From 3a5e2b6a923755bc9b96c8cacaa0512b4ccbbe5f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 4 Feb 2024 00:05:54 +0000 Subject: [PATCH 0045/2666] chore(deps-dev): bump aws-cdk from 2.125.0 to 2.126.0 (#3701) Bumps [aws-cdk](https://github.com/aws/aws-cdk/tree/HEAD/packages/aws-cdk) from 2.125.0 to 2.126.0. - [Release notes](https://github.com/aws/aws-cdk/releases) - [Changelog](https://github.com/aws/aws-cdk/blob/main/CHANGELOG.v2.md) - [Commits](https://github.com/aws/aws-cdk/commits/v2.126.0/packages/aws-cdk) --- updated-dependencies: - dependency-name: aws-cdk dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 514a6b2f6de..ed5b64eee4e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.125.0" + "aws-cdk": "^2.126.0" } }, "node_modules/aws-cdk": { - "version": "2.125.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.125.0.tgz", - "integrity": "sha512-6qFtaDPzhddhwIbCpqBjMePzZS7bfthGFQYfcwF1OhqMv2f3VpHQQ0f7kz4UxXJXUIR5BbgCnlpawH3c0aNzKw==", + "version": "2.126.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.126.0.tgz", + "integrity": "sha512-hEyy8UCEEUnkieH6JbJBN8XAbvuVZNdBmVQ8wHCqo8RSNqmpwM1qvLiyXV/2JvCqJJ0bl9uBiZ98Ytd5i3wW7g==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index 78063c6eb64..130e74e8067 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.125.0" + "aws-cdk": "^2.126.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 2a33556929a201fdf1c6b021f6007d599b6b6023 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:13:18 +0000 Subject: [PATCH 0046/2666] chore(deps-dev): bump ruff from 0.1.15 to 0.2.0 (#3702) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.15 to 0.2.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.1.15...v0.2.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- poetry.lock | 74 ++++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 42 insertions(+), 34 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8e7fcad2cd9..0469f6df30f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1259,6 +1259,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -2572,6 +2583,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2579,8 +2591,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2597,6 +2617,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2604,6 +2625,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2813,28 +2835,28 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "ruff" -version = "0.1.15" +version = "0.2.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, - {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, - {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, - {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, - {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"}, + {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"}, + {file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"}, + {file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"}, + {file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"}, + {file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"}, + {file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"}, + {file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"}, ] [[package]] @@ -3156,20 +3178,6 @@ files = [ [package.dependencies] types-urllib3 = "*" -[[package]] -name = "types-requests" -version = "2.31.0.20231231" -description = "Typing stubs for requests" -optional = false -python-versions = ">=3.7" -files = [ - {file = "types-requests-2.31.0.20231231.tar.gz", hash = "sha256:0f8c0c9764773384122813548d9eea92a5c4e1f33ed54556b508968ec5065cee"}, - {file = "types_requests-2.31.0.20231231-py3-none-any.whl", hash = "sha256:2e2230c7bc8dd63fa3153c1c0ae335f8a368447f0582fc332f17d54f88e69027"}, -] - -[package.dependencies] -urllib3 = ">=2" - [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -3428,4 +3436,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "28c3a405185f635f8e65ea51adfe1cfc589cb469497d800100521f91037ba26a" +content-hash = "ed9d43fd5827d270530b7e9eb60fb2e398e9d42b4317035396bb51c52485d313" diff --git a/pyproject.toml b/pyproject.toml index 98917d05f5d..12b64b23cbd 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -110,7 +110,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.25.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.1.16" +ruff = ">=0.0.272,<0.2.1" retry2 = "^0.9.5" pytest-socket = "^0.6.0" types-redis = "^4.6.0.7" From e0d20736e61d2ee9b60250cf6c81d220cf4b3591 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 09:18:13 +0000 Subject: [PATCH 0047/2666] chore(ci): changelog rebuild (#3707) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 182dc2c948a..2ea1e02b55a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,44 @@ # Unreleased +## Maintenance + +* **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) + ## [v2.33.0] - 2024-02-02 ## Bug Fixes * **data-masking:** fix and improve e2e tests for DataMasking ([#3695](https://github.com/aws-powertools/powertools-lambda-python/issues/3695)) +* **event-handler:** strip whitespace from Content-Type headers during OpenAPI schema validation ([#3677](https://github.com/aws-powertools/powertools-lambda-python/issues/3677)) + +## Documentation + +* **data-masking:** add docs for data masking utility ([#3186](https://github.com/aws-powertools/powertools-lambda-python/issues/3186)) +* **metrics:** fix empty metric warning filter ([#3660](https://github.com/aws-powertools/powertools-lambda-python/issues/3660)) +* **proccess:** add versioning and maintenance policy ([#3682](https://github.com/aws-powertools/powertools-lambda-python/issues/3682)) + +## Features + +* **event_handler:** support Header parameter validation in OpenAPI schema ([#3687](https://github.com/aws-powertools/powertools-lambda-python/issues/3687)) +* **event_handler:** add support for multiValueQueryStringParameters in OpenAPI schema ([#3667](https://github.com/aws-powertools/powertools-lambda-python/issues/3667)) ## Maintenance * version bump +* **deps:** bump codecov/codecov-action from 3.1.5 to 3.1.6 ([#3683](https://github.com/aws-powertools/powertools-lambda-python/issues/3683)) +* **deps:** bump codecov/codecov-action from 3.1.4 to 3.1.5 ([#3674](https://github.com/aws-powertools/powertools-lambda-python/issues/3674)) +* **deps:** bump pydantic from 1.10.13 to 1.10.14 ([#3655](https://github.com/aws-powertools/powertools-lambda-python/issues/3655)) +* **deps:** bump squidfunk/mkdocs-material from `58eef6c` to `9aad7af` in /docs ([#3670](https://github.com/aws-powertools/powertools-lambda-python/issues/3670)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3665](https://github.com/aws-powertools/powertools-lambda-python/issues/3665)) +* **deps:** bump squidfunk/mkdocs-material from `9aad7af` to `a4a2029` in /docs ([#3679](https://github.com/aws-powertools/powertools-lambda-python/issues/3679)) +* **deps-dev:** bump sentry-sdk from 1.39.2 to 1.40.0 ([#3684](https://github.com/aws-powertools/powertools-lambda-python/issues/3684)) +* **deps-dev:** bump ruff from 0.1.14 to 0.1.15 ([#3685](https://github.com/aws-powertools/powertools-lambda-python/issues/3685)) +* **deps-dev:** bump ruff from 0.1.13 to 0.1.14 ([#3656](https://github.com/aws-powertools/powertools-lambda-python/issues/3656)) +* **deps-dev:** bump aws-cdk from 2.122.0 to 2.123.0 ([#3673](https://github.com/aws-powertools/powertools-lambda-python/issues/3673)) +* **deps-dev:** bump aws-cdk from 2.124.0 to 2.125.0 ([#3693](https://github.com/aws-powertools/powertools-lambda-python/issues/3693)) +* **deps-dev:** bump aws-cdk from 2.123.0 to 2.124.0 ([#3678](https://github.com/aws-powertools/powertools-lambda-python/issues/3678)) From 190e9a9aadd3e3891569a5f1d86942f0fe48d361 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:14:16 +0100 Subject: [PATCH 0048/2666] chore(deps): bump actions/dependency-review-action from 3.1.5 to 4.0.0 (#3646) Bumps [actions/dependency-review-action](https://github.com/actions/dependency-review-action) from 3.1.5 to 4.0.0. - [Release notes](https://github.com/actions/dependency-review-action/releases) - [Commits](https://github.com/actions/dependency-review-action/compare/c74b580d73376b7750d3d2a50bfb8adc2c937507...4901385134134e04cec5fbe5ddfe3b2c5bd5d976) --- updated-dependencies: - dependency-name: actions/dependency-review-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 61b48420cfc..3fee4d6b427 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -19,4 +19,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Dependency Review' - uses: actions/dependency-review-action@c74b580d73376b7750d3d2a50bfb8adc2c937507 # v3.1.5 + uses: actions/dependency-review-action@4901385134134e04cec5fbe5ddfe3b2c5bd5d976 # v4.0.0 From 95d8edabd6f660479dcfe624c61cae055812ffc4 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 5 Feb 2024 15:55:09 +0000 Subject: [PATCH 0049/2666] chore(ci): drop support for Python 3.7 (#3638) * Python 3.7 deprecation + cleaning code with unnecessary compats * Ops, missing a file * Ops, missing a file * Reverting a potential breaking change * Refactoring data class to cache some properties * Importing from typing_extensions directly * Reverting * Addressing Heitor's feedback --------- Co-authored-by: Heitor Lessa --- .github/ISSUE_TEMPLATE/bug_report.yml | 1 - .github/ISSUE_TEMPLATE/static_typing.yml | 1 - .github/workflows/quality_check.yml | 2 +- .../workflows/quality_check_pydanticv2.yml | 2 +- .github/workflows/run-e2e-tests.yml | 2 +- README.md | 2 +- aws_lambda_powertools/logging/compat.py | 51 ----- aws_lambda_powertools/logging/logger.py | 22 -- aws_lambda_powertools/shared/types.py | 8 +- .../utilities/data_classes/active_mq_event.py | 8 +- .../data_classes/code_pipeline_job_event.py | 10 +- .../utilities/data_classes/common.py | 10 +- .../utilities/data_classes/kafka_event.py | 7 +- .../data_classes/kinesis_firehose_event.py | 15 +- .../utilities/data_classes/rabbit_mq_event.py | 7 +- .../utilities/data_classes/sqs_event.py | 7 +- .../utilities/data_classes/vpc_lattice.py | 7 +- .../utilities/streaming/compat.py | 208 +----------------- docs/core/event_handler/appsync.md | 22 +- docs/roadmap.md | 3 +- docs/upgrade.md | 2 +- docs/utilities/idempotency.md | 2 +- .../assert_async_graphql_response_module.py | 8 +- .../src/assert_graphql_response_module.py | 8 +- .../src/async_resolvers.py | 8 +- .../src/custom_models.py | 8 +- .../getting_started_graphql_api_resolver.py | 8 +- .../src/graphql_transformer_merchant_info.py | 8 +- .../graphql_transformer_search_merchant.py | 8 +- .../src/nested_mappings.py | 8 +- .../split_operation_append_context_module.py | 8 +- .../src/split_operation_module.py | 8 +- layer/sar/template.txt | 3 +- pyproject.toml | 3 +- .../test_idempotency_redis.py | 2 - tests/e2e/utils/infrastructure.py | 4 +- .../functional/event_handler/test_appsync.py | 2 - .../idempotency/test_idempotency.py | 5 - tests/unit/test_tracing.py | 5 +- 39 files changed, 67 insertions(+), 436 deletions(-) delete mode 100644 aws_lambda_powertools/logging/compat.py diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml index 74242e8c9ab..c670ea38274 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.yml +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -58,7 +58,6 @@ body: attributes: label: AWS Lambda function runtime options: - - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/.github/ISSUE_TEMPLATE/static_typing.yml b/.github/ISSUE_TEMPLATE/static_typing.yml index 29b59ea1461..eb8c7a77387 100644 --- a/.github/ISSUE_TEMPLATE/static_typing.yml +++ b/.github/ISSUE_TEMPLATE/static_typing.yml @@ -25,7 +25,6 @@ body: attributes: label: AWS Lambda function runtime options: - - "3.7" - "3.8" - "3.9" - "3.10" diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index 40ccbe99887..d28357be3b1 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -44,7 +44,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] env: PYTHON: "${{ matrix.python-version }}" permissions: diff --git a/.github/workflows/quality_check_pydanticv2.yml b/.github/workflows/quality_check_pydanticv2.yml index d0af2934986..2d84f1154ba 100644 --- a/.github/workflows/quality_check_pydanticv2.yml +++ b/.github/workflows/quality_check_pydanticv2.yml @@ -43,7 +43,7 @@ jobs: strategy: max-parallel: 4 matrix: - python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] env: PYTHON: "${{ matrix.python-version }}" permissions: diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index cff41718d87..5780bba255b 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -47,7 +47,7 @@ jobs: strategy: fail-fast: false # needed so if a version fails, the others will still be able to complete and cleanup matrix: - version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"] + version: ["3.8", "3.9", "3.10", "3.11", "3.12"] if: ${{ github.actor != 'dependabot[bot]' && github.repository == 'aws-powertools/powertools-lambda-python' }} steps: - name: "Checkout" diff --git a/README.md b/README.md index d3f0ec30603..c1ab7abaf29 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/quality_check.yml/badge.svg)](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/python_build.yml) [![codecov.io](https://codecov.io/github/aws-powertools/powertools-lambda-python/branch/develop/graphs/badge.svg)](https://app.codecov.io/gh/aws-powertools/powertools-lambda-python) -![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.7|%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET) +![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET) Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.powertools.aws.dev/lambda/python/latest/#features). diff --git a/aws_lambda_powertools/logging/compat.py b/aws_lambda_powertools/logging/compat.py deleted file mode 100644 index ebbefb7af6c..00000000000 --- a/aws_lambda_powertools/logging/compat.py +++ /dev/null @@ -1,51 +0,0 @@ -"""Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work.""" -from __future__ import annotations - -import io -import logging -import os -import traceback - - -def findCaller(stack_info=False, stacklevel=2): # pragma: no cover - """ - Find the stack frame of the caller so that we can note the source - file name, line number and function name. - """ - f = logging.currentframe() # noqa: VNE001 - # On some versions of IronPython, currentframe() returns None if - # IronPython isn't run with -X:Frames. - if f is None: - return "(unknown file)", 0, "(unknown function)", None - while stacklevel > 0: - next_f = f.f_back - if next_f is None: - ## We've got options here. - ## If we want to use the last (deepest) frame: - break - ## If we want to mimic the warnings module: - # return ("sys", 1, "(unknown function)", None) # noqa: ERA001 - ## If we want to be pedantic: # noqa: ERA001 - # raise ValueError("call stack is not deep enough") # noqa: ERA001 - f = next_f # noqa: VNE001 - if not _is_internal_frame(f): - stacklevel -= 1 - co = f.f_code - sinfo = None - if stack_info: - with io.StringIO() as sio: - sio.write("Stack (most recent call last):\n") - traceback.print_stack(f, file=sio) - sinfo = sio.getvalue() - if sinfo[-1] == "\n": - sinfo = sinfo[:-1] - return co.co_filename, f.f_lineno, co.co_name, sinfo - - -# The following is based on warnings._is_internal_frame. It makes sure that -# frames of the import mechanism are skipped when logging at module level and -# using a stacklevel value greater than one. -def _is_internal_frame(frame): # pragma: no cover - """Signal whether the frame is a CPython or logging module internal.""" - filename = os.path.normcase(frame.f_code.co_filename) - return filename == logging._srcfile or ("importlib" in filename and "_bootstrap" in filename) diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py index 88c903b7cb6..ab159061bff 100644 --- a/aws_lambda_powertools/logging/logger.py +++ b/aws_lambda_powertools/logging/logger.py @@ -22,7 +22,6 @@ overload, ) -from aws_lambda_powertools.logging import compat from aws_lambda_powertools.shared import constants from aws_lambda_powertools.shared.functions import ( extract_event_from_common_models, @@ -302,9 +301,6 @@ def _init_logger( self.addHandler(self.logger_handler) self.structure_logs(formatter_options=formatter_options, **kwargs) - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - self._logger.findCaller = compat.findCaller # type: ignore[method-assign] - # Pytest Live Log feature duplicates log records for colored output # but we explicitly add a filter for log deduplication. # This flag disables this protection when you explicit want logs to be duplicated (#262) @@ -467,9 +463,6 @@ def info( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.info(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.info( msg, *args, @@ -492,9 +485,6 @@ def error( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.error(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.error( msg, *args, @@ -517,9 +507,6 @@ def exception( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.exception(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.exception( msg, *args, @@ -542,9 +529,6 @@ def critical( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.critical(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.critical( msg, *args, @@ -567,9 +551,6 @@ def warning( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.warning(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.warning( msg, *args, @@ -592,9 +573,6 @@ def debug( extra = extra or {} extra = {**extra, **kwargs} - # Maintenance: We can drop this upon Py3.7 EOL. It's a backport for "location" key to work - if sys.version_info < (3, 8): # pragma: no cover - return self._logger.debug(msg, *args, exc_info=exc_info, stack_info=stack_info, extra=extra) return self._logger.debug( msg, *args, diff --git a/aws_lambda_powertools/shared/types.py b/aws_lambda_powertools/shared/types.py index 100005159e4..d5014c4c467 100644 --- a/aws_lambda_powertools/shared/types.py +++ b/aws_lambda_powertools/shared/types.py @@ -1,10 +1,5 @@ import sys -from typing import Any, Callable, Dict, List, TypeVar, Union - -if sys.version_info >= (3, 8): - from typing import Literal, Protocol, TypedDict -else: - from typing_extensions import Literal, Protocol, TypedDict +from typing import Any, Callable, Dict, List, Literal, Protocol, TypedDict, TypeVar, Union if sys.version_info >= (3, 9): from typing import Annotated @@ -16,7 +11,6 @@ else: from typing_extensions import NotRequired - # Even though `get_args` and `get_origin` were added in Python 3.8, they only handle Annotated correctly on 3.10. # So for python < 3.10 we use the backport from typing_extensions. if sys.version_info >= (3, 10): diff --git a/aws_lambda_powertools/utilities/data_classes/active_mq_event.py b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py index f5404154ea7..f0839a70442 100644 --- a/aws_lambda_powertools/utilities/data_classes/active_mq_event.py +++ b/aws_lambda_powertools/utilities/data_classes/active_mq_event.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import Any, Dict, Iterator, Optional from aws_lambda_powertools.utilities.data_classes.common import DictWrapper @@ -23,12 +24,9 @@ def decoded_data(self) -> str: """Decodes the data as a str""" return base64_decode(self.data) - @property + @cached_property def json_data(self) -> Any: - """Parses the data as json""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.decoded_data) - return self._json_data + return self._json_deserializer(self.decoded_data) @property def connection_id(self) -> str: diff --git a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py index 1813d6016b5..cc7a75cc05e 100644 --- a/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py +++ b/aws_lambda_powertools/utilities/data_classes/code_pipeline_job_event.py @@ -1,5 +1,6 @@ import tempfile import zipfile +from functools import cached_property from typing import Any, Dict, List, Optional from urllib.parse import unquote_plus @@ -17,12 +18,13 @@ def user_parameters(self) -> Optional[str]: """User parameters""" return self.get("UserParameters", None) - @property + @cached_property def decoded_user_parameters(self) -> Optional[Dict[str, Any]]: """Json Decoded user parameters""" - if self._json_data is None and self.user_parameters is not None: - self._json_data = self._json_deserializer(self.user_parameters) - return self._json_data + if self.user_parameters is not None: + return self._json_deserializer(self.user_parameters) + + return None class CodePipelineActionConfiguration(DictWrapper): diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 0560159ecc5..25fb5a4c170 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -1,6 +1,7 @@ import base64 import json from collections.abc import Mapping +from functools import cached_property from typing import Any, Callable, Dict, Iterator, List, Optional, overload from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer @@ -24,7 +25,6 @@ def __init__(self, data: Dict[str, Any], json_deserializer: Optional[Callable] = by default json.loads """ self._data = data - self._json_data: Optional[Any] = None self._json_deserializer = json_deserializer or json.loads def __getitem__(self, key: str) -> Any: @@ -138,14 +138,12 @@ def body(self) -> Optional[str]: """Submitted body of the request as a string""" return self.get("body") - @property + @cached_property def json_body(self) -> Any: """Parses the submitted body as json""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.decoded_body) - return self._json_data + return self._json_deserializer(self.decoded_body) - @property + @cached_property def decoded_body(self) -> str: """Dynamically base64 decode body as a str""" body: str = self["body"] diff --git a/aws_lambda_powertools/utilities/data_classes/kafka_event.py b/aws_lambda_powertools/utilities/data_classes/kafka_event.py index f54f979bace..d3d1425f0f2 100644 --- a/aws_lambda_powertools/utilities/data_classes/kafka_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kafka_event.py @@ -1,4 +1,5 @@ import base64 +from functools import cached_property from typing import Any, Dict, Iterator, List, Optional from aws_lambda_powertools.utilities.data_classes.common import DictWrapper @@ -53,12 +54,10 @@ def decoded_value(self) -> bytes: """Decodes the base64 encoded value as bytes.""" return base64.b64decode(self.value) - @property + @cached_property def json_value(self) -> Any: """Decodes the text encoded data as JSON.""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.decoded_value.decode("utf-8")) - return self._json_data + return self._json_deserializer(self.decoded_value.decode("utf-8")) @property def headers(self) -> List[Dict[str, List[int]]]: diff --git a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py index 3e5db8cb9d8..492aac53176 100644 --- a/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py +++ b/aws_lambda_powertools/utilities/data_classes/kinesis_firehose_event.py @@ -2,6 +2,7 @@ import json import warnings from dataclasses import dataclass, field +from functools import cached_property from typing import Any, Callable, ClassVar, Dict, Iterator, List, Optional, Tuple from typing_extensions import Literal @@ -70,7 +71,6 @@ class KinesisFirehoseDataTransformationRecord: metadata: Optional[KinesisFirehoseDataTransformationRecordMetadata] = None json_serializer: Callable = json.dumps json_deserializer: Callable = json.loads - _json_data: Optional[Any] = None def asdict(self) -> Dict: if self.result not in self._valid_result_types: @@ -102,14 +102,13 @@ def data_as_text(self) -> str: return "" return self.data_as_bytes.decode("utf-8") - @property + @cached_property def data_as_json(self) -> Dict: """Decoded base64-encoded data loaded to json""" if not self.data: return {} - if self._json_data is None: - self._json_data = self.json_deserializer(self.data_as_text) - return self._json_data + + return self.json_deserializer(self.data_as_text) @dataclass(repr=False, order=False) @@ -240,12 +239,10 @@ def data_as_text(self) -> str: """Decoded base64-encoded data as text""" return self.data_as_bytes.decode("utf-8") - @property + @cached_property def data_as_json(self) -> dict: """Decoded base64-encoded data loaded to json""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.data_as_text) - return self._json_data + return self._json_deserializer(self.data_as_text) def build_data_transformation_response( self, diff --git a/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py index ab792f3b893..0eaae042621 100644 --- a/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py +++ b/aws_lambda_powertools/utilities/data_classes/rabbit_mq_event.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import Any, Dict, List from aws_lambda_powertools.utilities.data_classes.common import DictWrapper @@ -84,12 +85,10 @@ def decoded_data(self) -> str: """Decodes the data as a str""" return base64_decode(self.data) - @property + @cached_property def json_data(self) -> Any: """Parses the data as json""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.decoded_data) - return self._json_data + return self._json_deserializer(self.decoded_data) class RabbitMQEvent(DictWrapper): diff --git a/aws_lambda_powertools/utilities/data_classes/sqs_event.py b/aws_lambda_powertools/utilities/data_classes/sqs_event.py index ffec9854a2e..4ca1b8f51c9 100644 --- a/aws_lambda_powertools/utilities/data_classes/sqs_event.py +++ b/aws_lambda_powertools/utilities/data_classes/sqs_event.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import Any, Dict, Iterator, Optional, Type, TypeVar from aws_lambda_powertools.utilities.data_classes import S3Event @@ -107,7 +108,7 @@ def body(self) -> str: """The message's contents (not URL-encoded).""" return self["body"] - @property + @cached_property def json_body(self) -> Any: """Deserializes JSON string available in 'body' property @@ -132,9 +133,7 @@ def json_body(self) -> Any: data: list = record.json_body # ["telemetry_values"] ``` """ - if self._json_data is None: - self._json_data = self._json_deserializer(self["body"]) - return self._json_data + return self._json_deserializer(self["body"]) @property def attributes(self) -> SQSRecordAttributes: diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py index f12c53d841a..15144e41d7d 100644 --- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py @@ -1,3 +1,4 @@ +from functools import cached_property from typing import Any, Dict, Optional, overload from aws_lambda_powertools.shared.headers_serializer import ( @@ -18,12 +19,10 @@ def body(self) -> str: """The VPC Lattice body.""" return self["body"] - @property + @cached_property def json_body(self) -> Any: """Parses the submitted body as json""" - if self._json_data is None: - self._json_data = self._json_deserializer(self.decoded_body) - return self._json_data + return self._json_deserializer(self.decoded_body) @property def headers(self) -> Dict[str, str]: diff --git a/aws_lambda_powertools/utilities/streaming/compat.py b/aws_lambda_powertools/utilities/streaming/compat.py index 531c7c6e7fa..1b30b3a74f0 100644 --- a/aws_lambda_powertools/utilities/streaming/compat.py +++ b/aws_lambda_powertools/utilities/streaming/compat.py @@ -1,206 +1,4 @@ -""" -Currently, the same as https://github.com/boto/botocore/blob/b9c540905a6c9/botocore/response.py -We created this because the version of StreamingBody included with the Lambda Runtime is too old, and -doesn't support many of the standard IO methods (like readline). +from botocore.response import StreamingBody -As soon as the version of botocore included with the Lambda runtime is equal or greater than 1.29.13, we can drop -this file completely. See https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html. -""" -import logging -from io import IOBase -from typing import Optional - -import botocore -from botocore import endpoint -from botocore.compat import set_socket_timeout -from botocore.exceptions import ( - IncompleteReadError, - ReadTimeoutError, - ResponseStreamingError, -) -from urllib3.exceptions import ProtocolError as URLLib3ProtocolError -from urllib3.exceptions import ReadTimeoutError as URLLib3ReadTimeoutError - -logger = logging.getLogger(__name__) - -# Splitting the botocore version string into major, minor, and patch versions, -# and performing a conditional check based on the extracted versions. -major, minor, patch = map(int, botocore.__version__.split(".")) - -if major == 1 and (minor < 29 or patch < 13): - - class PowertoolsStreamingBody(IOBase): - """Wrapper class for a HTTP response body. - - This provides a few additional conveniences that do not exist - in the urllib3 model: - * Set the timeout on the socket (i.e read() timeouts) - * Auto validation of content length, if the amount of bytes - we read does not match the content length, an exception - is raised. - """ - - _DEFAULT_CHUNK_SIZE = 1024 - - def __init__(self, raw_stream, content_length): - self._raw_stream = raw_stream - self._content_length = content_length - self._amount_read = 0 - - def __del__(self): - # Extending destructor in order to preserve the underlying raw_stream. - # The ability to add custom cleanup logic introduced in Python3.4+. - # https://www.python.org/dev/peps/pep-0442/ - pass - - def set_socket_timeout(self, timeout): - """Set the timeout seconds on the socket.""" - # The problem we're trying to solve is to prevent .read() calls from - # hanging. This can happen in rare cases. What we'd like to ideally - # do is set a timeout on the .read() call so that callers can retry - # the request. - # Unfortunately, this isn't currently possible in requests. - # See: https://github.com/kennethreitz/requests/issues/1803 - # So what we're going to do is reach into the guts of the stream and - # grab the socket object, which we can set the timeout on. We're - # putting in a check here so in case this interface goes away, we'll - # know. - try: - set_socket_timeout(self._raw_stream, timeout) - except AttributeError: - logger.error( - "Cannot access the socket object of " - "a streaming response. It's possible " - "the interface has changed.", - exc_info=True, - ) - raise - - def readable(self): - try: - return self._raw_stream.readable() - except AttributeError: - return False - - def read(self, amt=None): - """Read at most amt bytes from the stream. - If the amt argument is omitted, read all data. - """ - try: - chunk = self._raw_stream.read(amt) - except URLLib3ReadTimeoutError as e: - raise ReadTimeoutError(endpoint_url=e.url, error=e) - except URLLib3ProtocolError as e: - raise ResponseStreamingError(error=e) - self._amount_read += len(chunk) - if amt is None or (not chunk and amt > 0): - # If the server sends empty contents or - # we ask to read all of the contents, then we know - # we need to verify the content length. - self._verify_content_length() - return chunk - - def readlines(self, hint: Optional[int] = -1): - return self._raw_stream.readlines(hint) - - def __iter__(self): - """Return an iterator to yield 1k chunks from the raw stream.""" - return self.iter_chunks(self._DEFAULT_CHUNK_SIZE) - - def __next__(self): - """Return the next 1k chunk from the raw stream.""" - current_chunk = self.read(self._DEFAULT_CHUNK_SIZE) - if current_chunk: - return current_chunk - raise StopIteration() - - def __enter__(self): - return self._raw_stream - - def __exit__(self, *args): - self._raw_stream.close() - - next = __next__ # noqa: A003, VNE003 - - def iter_lines(self, chunk_size=_DEFAULT_CHUNK_SIZE, keepends=False): - """Return an iterator to yield lines from the raw stream. - This is achieved by reading chunk of bytes (of size chunk_size) at a - time from the raw stream, and then yielding lines from there. - """ - pending = b"" - for chunk in self.iter_chunks(chunk_size): - lines = (pending + chunk).splitlines(True) - for line in lines[:-1]: - yield line.splitlines(keepends)[0] - pending = lines[-1] - if pending: - yield pending.splitlines(keepends)[0] - - def iter_chunks(self, chunk_size=_DEFAULT_CHUNK_SIZE): - """Return an iterator to yield chunks of chunk_size bytes from the raw - stream. - """ - while True: - current_chunk = self.read(chunk_size) - if current_chunk == b"": - break - yield current_chunk - - def _verify_content_length(self): - # See: https://github.com/kennethreitz/requests/issues/1855 - # Basically, our http library doesn't do this for us, so we have - # to do this ourself. - if self._content_length is not None and self._amount_read != int(self._content_length): - raise IncompleteReadError( - actual_bytes=self._amount_read, - expected_bytes=int(self._content_length), - ) - - def tell(self): - return self._raw_stream.tell() - - def close(self): - """Close the underlying http response stream.""" - self._raw_stream.close() - - def convert_to_response_dict(http_response, operation_model): - """Convert an HTTP response object to a request dict. - - This converts the requests library's HTTP response object to - a dictionary. - - :type http_response: botocore.vendored.requests.model.Response - :param http_response: The HTTP response from an AWS service request. - - :rtype: dict - :return: A response dictionary which will contain the following keys: - * headers (dict) - * status_code (int) - * body (string or file-like object) - - """ - response_dict = { - "headers": http_response.headers, - "status_code": http_response.status_code, - "context": { - "operation_name": operation_model.name, - }, - } - if response_dict["status_code"] >= 300: - response_dict["body"] = http_response.content - elif operation_model.has_event_stream_output: - response_dict["body"] = http_response.raw - elif operation_model.has_streaming_output: - length = response_dict["headers"].get("content-length") - response_dict["body"] = PowertoolsStreamingBody(http_response.raw, length) - else: - response_dict["body"] = http_response.content - return response_dict - - # monkey patch boto3 - endpoint.convert_to_response_dict = convert_to_response_dict -else: - from botocore.response import StreamingBody - - # Expose PowertoolsStreamingBody as StreamingBody - vars()["PowertoolsStreamingBody"] = StreamingBody +# aliasing as 3.7 is no longer supported but unsure if anyone took a dependency on it (hyrum's law) +PowertoolsStreamingBody = StreamingBody diff --git a/docs/core/event_handler/appsync.md b/docs/core/event_handler/appsync.md index 789bf788004..fcadc2a1f27 100644 --- a/docs/core/event_handler/appsync.md +++ b/docs/core/event_handler/appsync.md @@ -61,7 +61,7 @@ Here's an example with two separate functions to resolve `getTodo` and `listTodo === "getting_started_graphql_api_resolver.py" - ```python hl_lines="14 21 31 33-34 43 45 53 55 66" + ```python hl_lines="7 15 25 27 28 37 39 47 49 60" --8<-- "examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py" ``` @@ -123,7 +123,7 @@ You can nest `app.resolver()` decorator multiple times when resolving fields wit === "nested_mappings.py" - ```python hl_lines="11 17 27-28 28 30 37" + ```python hl_lines="4 11 21 22 24 31" --8<-- "examples/event_handler_graphql/src/nested_mappings.py" ``` @@ -137,7 +137,7 @@ You can nest `app.resolver()` decorator multiple times when resolving fields wit For Lambda Python3.8+ runtime, this utility supports async functions when you use in conjunction with `asyncio.run`. -```python hl_lines="14 21 31-32 41 43" title="Resolving GraphQL resolvers async" +```python hl_lines="6 15 25 26 35 37" title="Resolving GraphQL resolvers async" --8<-- "examples/event_handler_graphql/src/async_resolvers.py" ``` @@ -162,13 +162,13 @@ Use the following code for `merchantInfo` and `searchMerchant` functions respect === "graphql_transformer_merchant_info.py" - ```python hl_lines="11 13 29-30 34-35 43" + ```python hl_lines="4 7 23 24 29 30 37" --8<-- "examples/event_handler_graphql/src/graphql_transformer_merchant_info.py" ``` === "graphql_transformer_search_merchant.py" - ```python hl_lines="11 13 28-29 43 49" + ```python hl_lines="4 7 22 23 37 43" --8<-- "examples/event_handler_graphql/src/graphql_transformer_search_merchant.py" ``` @@ -196,7 +196,7 @@ You can subclass [AppSyncResolverEvent](../../utilities/data_classes.md#appsync- === "custom_models.py.py" - ```python hl_lines="11 14 32-34 37-38 45 52" + ```python hl_lines="4 8-10 26-28 31 32 39 46" --8<-- "examples/event_handler_graphql/src/custom_models.py" ``` @@ -225,7 +225,7 @@ Let's assume you have `split_operation.py` as your Lambda function entrypoint an We import **Router** instead of **AppSyncResolver**; syntax wise is exactly the same. - ```python hl_lines="11 15 25-26" + ```python hl_lines="4 9 19 20" --8<-- "examples/event_handler_graphql/src/split_operation_module.py" ``` @@ -255,7 +255,7 @@ You can use `append_context` when you want to share data between your App and Ro === "split_route_append_context_module.py" - ```python hl_lines="29" + ```python hl_lines="23" --8<-- "examples/event_handler_graphql/src/split_operation_append_context_module.py" ``` @@ -269,13 +269,13 @@ Here's an example of how you can test your synchronous resolvers: === "assert_graphql_response.py" - ```python hl_lines="6 26 29" + ```python hl_lines="8 28 31" --8<-- "examples/event_handler_graphql/src/assert_graphql_response.py" ``` === "assert_graphql_response_module.py" - ```python hl_lines="17" + ```python hl_lines="11" --8<-- "examples/event_handler_graphql/src/assert_graphql_response_module.py" ``` @@ -298,7 +298,7 @@ And an example for testing asynchronous resolvers. Note that this requires the ` === "assert_async_graphql_response_module.py" - ```python hl_lines="21" + ```python hl_lines="15" --8<-- "examples/event_handler_graphql/src/assert_async_graphql_response_module.py" ``` diff --git a/docs/roadmap.md b/docs/roadmap.md index e42fae21c97..766733c754c 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -120,7 +120,7 @@ We want to investigate security and scaling requirements for these special regio ### V3 -With Python 3.7 reaching [end-of-life in AWS Lambda by the end of the year](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html), we want to plan some breaking changes. As always, we plan on having ample notice, a detailed upgrade guide, and keep breaking changes to a minimum to ease transition (e.g., it took ~7 months from v2 to surpass v1 downloads). +We are in the process of planning the roadmap for v3. As always, our approach includes providing sufficient advance notice, a comprehensive upgrade guide, and minimizing breaking changes to facilitate a smooth transition (e.g., it took ~7 months from v2 to surpass v1 downloads). For example, these are on our mind but not settled yet until we have a public tracker to discuss what these means in detail. @@ -128,7 +128,6 @@ For example, these are on our mind but not settled yet until we have a public tr - **Parser**: Deserialize Amazon DynamoDB data types automatically (like Event Source Data Classes) - **Parameters**: Increase default `max_age` for `get_secret` - **Event Source Data Classes**: Return sane defaults for any property that has `Optional[]` returns -- **Python 3.7 EOL**: Update PyPi and Layers to only support 3.8 - **Upgrade tool**: Consider building a CST (Concrete Syntax Tree) tool to ease certain upgrade actions like `pyupgrade` and `django-upgrade` - **Batch**: Stop at first error for Amazon DynamoDB Streams and Amazon Kinesis Data Streams (e.g., `stop_on_failure=True`) diff --git a/docs/upgrade.md b/docs/upgrade.md index d9602da1a53..11d8cdbe83a 100644 --- a/docs/upgrade.md +++ b/docs/upgrade.md @@ -32,7 +32,7 @@ We've made minimal breaking changes to make your transition to v2 as smooth as p Before you start, we suggest making a copy of your current working project or create a new branch with git. -1. **Upgrade** Python to at least v3.7 +1. **Upgrade** Python to at least v3.8 2. **Ensure** you have the latest version via [Lambda Layer or PyPi](index.md#install){target="_blank"}. 3. **Review** the following sections to confirm whether they affect your code diff --git a/docs/utilities/idempotency.md b/docs/utilities/idempotency.md index bc355580935..17848a7828b 100644 --- a/docs/utilities/idempotency.md +++ b/docs/utilities/idempotency.md @@ -143,7 +143,7 @@ Similar to [idempotent decorator](#idempotent-decorator), you can use `idempoten When using `idempotent_function`, you must tell us which keyword parameter in your function signature has the data we should use via **`data_keyword_argument`**. -!!! tip "We support JSON serializable data, [Python Dataclasses](https://docs.python.org/3.7/library/dataclasses.html){target="_blank" rel="nofollow"}, [Parser/Pydantic Models](parser.md){target="_blank"}, and our [Event Source Data Classes](./data_classes.md){target="_blank"}." +!!! tip "We support JSON serializable data, [Python Dataclasses](https://docs.python.org/3.12/library/dataclasses.html){target="_blank" rel="nofollow"}, [Parser/Pydantic Models](parser.md){target="_blank"}, and our [Event Source Data Classes](./data_classes.md){target="_blank"}." ???+ warning "Limitation" Make sure to call your decorated function using keyword arguments. diff --git a/examples/event_handler_graphql/src/assert_async_graphql_response_module.py b/examples/event_handler_graphql/src/assert_async_graphql_response_module.py index 8ef072a02f7..371eeaa23f8 100644 --- a/examples/event_handler_graphql/src/assert_async_graphql_response_module.py +++ b/examples/event_handler_graphql/src/assert_async_graphql_response_module.py @@ -1,10 +1,3 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - import asyncio from typing import List @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.tracing import aiohttp_trace_config from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/assert_graphql_response_module.py b/examples/event_handler_graphql/src/assert_graphql_response_module.py index c7869a587fc..a7cb58c1d98 100644 --- a/examples/event_handler_graphql/src/assert_graphql_response_module.py +++ b/examples/event_handler_graphql/src/assert_graphql_response_module.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.typing import LambdaContext tracer = Tracer() diff --git a/examples/event_handler_graphql/src/async_resolvers.py b/examples/event_handler_graphql/src/async_resolvers.py index 072f42dbba9..08ecbcba85b 100644 --- a/examples/event_handler_graphql/src/async_resolvers.py +++ b/examples/event_handler_graphql/src/async_resolvers.py @@ -1,11 +1,4 @@ import asyncio -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List import aiohttp @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.tracing import aiohttp_trace_config from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/custom_models.py b/examples/event_handler_graphql/src/custom_models.py index 6d82e1ba9be..ae2f0180e15 100644 --- a/examples/event_handler_graphql/src/custom_models.py +++ b/examples/event_handler_graphql/src/custom_models.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.data_classes.appsync_resolver_event import ( AppSyncResolverEvent, diff --git a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py index 9edd8c68dad..e960a357d17 100644 --- a/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py +++ b/examples/event_handler_graphql/src/getting_started_graphql_api_resolver.py @@ -1,10 +1,3 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List import requests @@ -13,6 +6,7 @@ from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py b/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py index 55f963bb8d5..017528e3481 100644 --- a/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py +++ b/examples/event_handler_graphql/src/graphql_transformer_merchant_info.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py b/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py index 1dd52945f93..9b685a280dd 100644 --- a/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py +++ b/examples/event_handler_graphql/src/graphql_transformer_search_merchant.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.data_classes.appsync import scalar_types_utils from aws_lambda_powertools.utilities.typing import LambdaContext diff --git a/examples/event_handler_graphql/src/nested_mappings.py b/examples/event_handler_graphql/src/nested_mappings.py index c7869a587fc..a7cb58c1d98 100644 --- a/examples/event_handler_graphql/src/nested_mappings.py +++ b/examples/event_handler_graphql/src/nested_mappings.py @@ -1,15 +1,9 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler import AppSyncResolver from aws_lambda_powertools.logging import correlation_paths +from aws_lambda_powertools.shared.types import TypedDict from aws_lambda_powertools.utilities.typing import LambdaContext tracer = Tracer() diff --git a/examples/event_handler_graphql/src/split_operation_append_context_module.py b/examples/event_handler_graphql/src/split_operation_append_context_module.py index e30e345c313..15ed7af1b9e 100644 --- a/examples/event_handler_graphql/src/split_operation_append_context_module.py +++ b/examples/event_handler_graphql/src/split_operation_append_context_module.py @@ -1,14 +1,8 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler.appsync import Router +from aws_lambda_powertools.shared.types import TypedDict tracer = Tracer() logger = Logger() diff --git a/examples/event_handler_graphql/src/split_operation_module.py b/examples/event_handler_graphql/src/split_operation_module.py index 12569bc23bc..e4c7f978b73 100644 --- a/examples/event_handler_graphql/src/split_operation_module.py +++ b/examples/event_handler_graphql/src/split_operation_module.py @@ -1,14 +1,8 @@ -import sys - -if sys.version_info >= (3, 8): - from typing import TypedDict -else: - from typing_extensions import TypedDict - from typing import List from aws_lambda_powertools import Logger, Tracer from aws_lambda_powertools.event_handler.appsync import Router +from aws_lambda_powertools.shared.types import TypedDict tracer = Tracer() logger = Logger() diff --git a/layer/sar/template.txt b/layer/sar/template.txt index fc6ed8892a4..d813a6a77d7 100644 --- a/layer/sar/template.txt +++ b/layer/sar/template.txt @@ -14,7 +14,7 @@ Metadata: SourceCodeUrl: https://github.com/aws-powertools/powertools-lambda-python Transform: AWS::Serverless-2016-10-31 -Description: AWS Lambda Layer for aws-lambda-powertools with python 3.12, 3.11, 3.10, 3.9, 3.8 or 3.7 +Description: AWS Lambda Layer for aws-lambda-powertools with python 3.12, 3.11, 3.10, 3.9 or 3.8 Resources: LambdaLayer: @@ -29,7 +29,6 @@ Resources: - python3.10 - python3.9 - python3.8 - - python3.7 LicenseInfo: 'Available under the Apache-2.0 license.' RetentionPolicy: Retain diff --git a/pyproject.toml b/pyproject.toml index 12b64b23cbd..c0349853aca 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,6 @@ classifiers = [ "Intended Audience :: Developers", "License :: OSI Approved :: MIT No Attribution License (MIT-0)", "Natural Language :: English", - "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", @@ -39,7 +38,7 @@ license = "MIT" "Releases" = "https://github.com/aws-powertools/powertools-lambda-python/releases" [tool.poetry.dependencies] -python = "^3.7.4" +python = ">=3.8,<4.0.0" aws-xray-sdk = { version = "^2.8.0", optional = true } fastjsonschema = { version = "^2.14.5", optional = true } pydantic = { version = "^1.8.2", optional = true } diff --git a/tests/e2e/idempotency_redis/test_idempotency_redis.py b/tests/e2e/idempotency_redis/test_idempotency_redis.py index 7a8c55374f8..4b5840ac477 100644 --- a/tests/e2e/idempotency_redis/test_idempotency_redis.py +++ b/tests/e2e/idempotency_redis/test_idempotency_redis.py @@ -6,8 +6,6 @@ from tests.e2e.utils import data_fetcher from tests.e2e.utils.data_fetcher.common import GetLambdaResponseOptions, get_lambda_response_in_parallel -pytest.skip(reason="Redis tests disabled until we deprecate Python 3.7.", allow_module_level=True) - @pytest.fixture def ttl_cache_expiration_handler_fn_arn(infrastructure: dict) -> str: diff --git a/tests/e2e/utils/infrastructure.py b/tests/e2e/utils/infrastructure.py index 5adef6133f8..1137fc222a3 100644 --- a/tests/e2e/utils/infrastructure.py +++ b/tests/e2e/utils/infrastructure.py @@ -251,9 +251,7 @@ def _create_temp_cdk_app(self): def _determine_runtime_version(self) -> Runtime: """Determine Python runtime version based on the current Python interpreter""" version = sys.version_info - if version.major == 3 and version.minor == 7: - return Runtime.PYTHON_3_7 - elif version.major == 3 and version.minor == 8: + if version.major == 3 and version.minor == 8: return Runtime.PYTHON_3_8 elif version.major == 3 and version.minor == 9: return Runtime.PYTHON_3_9 diff --git a/tests/functional/event_handler/test_appsync.py b/tests/functional/event_handler/test_appsync.py index 54695eba240..5699e560065 100644 --- a/tests/functional/event_handler/test_appsync.py +++ b/tests/functional/event_handler/test_appsync.py @@ -1,5 +1,4 @@ import asyncio -import sys import pytest @@ -121,7 +120,6 @@ def get_locations(name: str, description: str = ""): assert result2 == "value2description" -@pytest.mark.skipif(sys.version_info < (3, 8), reason="only for python versions that support asyncio.run") def test_resolver_async(): # GIVEN app = AppSyncResolver() diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 905248011e6..f5b441e5e91 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -1,6 +1,5 @@ import copy import datetime -import sys import warnings from unittest.mock import MagicMock @@ -143,7 +142,6 @@ def lambda_handler(event, context): stubber.deactivate() -@pytest.mark.skipif(sys.version_info < (3, 8), reason="issue with pytest mock lib for < 3.8") @pytest.mark.parametrize("idempotency_config", [{"use_local_cache": True}], indirect=True) def test_idempotent_lambda_in_progress_with_cache( idempotency_config: IdempotencyConfig, @@ -1713,7 +1711,6 @@ def test_invalid_dynamodb_persistence_layer(): assert str(ve.value) == "key_attr [id] and sort_key_attr [id] cannot be the same!" -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_dataclasses(): # Scenario _prepare_data should convert a python dataclasses to a dict dataclasses = get_dataclasses_lib() @@ -1747,7 +1744,6 @@ def test_idempotent_function_other(data): assert _prepare_data(data) == data -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_dataclass_with_jmespath(): # GIVEN dataclasses = get_dataclasses_lib() @@ -1773,7 +1769,6 @@ def collect_payment(payment: Payment): assert result == payment.transaction_id -@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires python3.7 or higher for dataclasses") def test_idempotent_function_pydantic_with_jmespath(): # GIVEN config = IdempotencyConfig(event_key_jmespath="transaction_id", use_local_cache=True) diff --git a/tests/unit/test_tracing.py b/tests/unit/test_tracing.py index ae140eb2bee..fdb7310495b 100644 --- a/tests/unit/test_tracing.py +++ b/tests/unit/test_tracing.py @@ -1,5 +1,4 @@ import contextlib -import sys from typing import NamedTuple from unittest import mock from unittest.mock import MagicMock @@ -83,9 +82,7 @@ class InSubsegment(NamedTuple): in_subsegment = InSubsegment() in_subsegment.in_subsegment.return_value.__enter__.return_value.put_annotation = in_subsegment.put_annotation in_subsegment.in_subsegment.return_value.__enter__.return_value.put_metadata = in_subsegment.put_metadata - - if sys.version_info >= (3, 8): # 3.8 introduced AsyncMock - in_subsegment.in_subsegment.return_value.__aenter__.return_value.put_metadata = in_subsegment.put_metadata + in_subsegment.in_subsegment.return_value.__aenter__.return_value.put_metadata = in_subsegment.put_metadata yield in_subsegment From 833f6fa13ab53b51d99f90cf7619329a56fe5e8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 16:59:25 +0100 Subject: [PATCH 0050/2666] chore(deps): bump release-drafter/release-drafter from 5.25.0 to 6.0.0 (#3699) Bumps [release-drafter/release-drafter](https://github.com/release-drafter/release-drafter) from 5.25.0 to 6.0.0. - [Release notes](https://github.com/release-drafter/release-drafter/releases) - [Commits](https://github.com/release-drafter/release-drafter/compare/09c613e259eb8d4e7c81c2cb00618eb5fc4575a7...3f0f87098bd6b5c5b9a36d49c41d998ea58f9348) --- updated-dependencies: - dependency-name: release-drafter/release-drafter dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release-drafter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index 6d4ef78ecc1..473968803b0 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -27,6 +27,6 @@ jobs: permissions: contents: write # create release in draft mode steps: - - uses: release-drafter/release-drafter@09c613e259eb8d4e7c81c2cb00618eb5fc4575a7 # v5.20.1 + - uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v5.20.1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From e0b38f1f2ee90f7402e0bda2271e9dc8b2db2cd4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:02:42 +0000 Subject: [PATCH 0051/2666] chore(deps): bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs (#3708) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `a4a2029` to `e0d6c67`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 82bf5a39aeb..640182ff441 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:a4a2029fdf524f0c727852e492cd2bbae30cc9471959da60d7dc46bf565a521b +FROM squidfunk/mkdocs-material@sha256:e0d6c671fa3d5cf332043a5231c6f0cd68f48607e9edf710c2f3a57a74dbdc93 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From 17333b7d576a013d64761a8ad1ed7e8ee4305955 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 21:33:31 +0000 Subject: [PATCH 0052/2666] chore(deps-dev): bump the boto-typing group with 7 updates (#3709) --- poetry.lock | 175 +++++++++++-------------------------------------- pyproject.toml | 14 ++-- 2 files changed, 44 insertions(+), 145 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0469f6df30f..c3a44ba90f6 100644 --- a/poetry.lock +++ b/poetry.lock @@ -15,7 +15,6 @@ files = [ exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] @@ -33,9 +32,6 @@ files = [ {file = "async_timeout-4.0.3-py3-none-any.whl", hash = "sha256:7405140ff1230c310e51dc27b3145b9092d659ce68ff733fb0cefe3ee42be028"}, ] -[package.dependencies] -typing-extensions = {version = ">=3.6.5", markers = "python_version < \"3.8\""} - [[package]] name = "attrs" version = "23.2.0" @@ -47,9 +43,6 @@ files = [ {file = "attrs-23.2.0.tar.gz", hash = "sha256:935dc3b529c262f6cf76e50877d35a4bd3c1de194fd41f47a2b7ae8f19971f30"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] cov = ["attrs[tests]", "coverage[toml] (>=5.3)"] dev = ["attrs[tests]", "pre-commit"] @@ -329,7 +322,6 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} [package.extras] @@ -379,17 +371,6 @@ urllib3 = [ [package.extras] crt = ["awscrt (==0.19.17)"] -[[package]] -name = "bytecode" -version = "0.13.0" -description = "Python module to generate and modify bytecode" -optional = false -python-versions = ">=3.6" -files = [ - {file = "bytecode-0.13.0-py3-none-any.whl", hash = "sha256:e69f92e7d27f99d5d7d76e6a824bd3d9ff857c72b59927aaf87e1a620f67fe50"}, - {file = "bytecode-0.13.0.tar.gz", hash = "sha256:6af3c2f0a31ce05dce41f7eea5cc380e33f5e8fbb7dcee3b52467a00acd52fcd"}, -] - [[package]] name = "bytecode" version = "0.15.1" @@ -662,7 +643,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} [[package]] name = "colorama" @@ -848,8 +828,6 @@ files = [ [package.dependencies] datadog = ">=0.41.0,<1.0.0" ddtrace = ">=2.3.1" -importlib_metadata = {version = "*", markers = "python_version < \"3.8\""} -typing_extensions = {version = ">=4.0,<5.0", markers = "python_version < \"3.8\""} urllib3 = [ {version = "<2.0.0", markers = "python_version < \"3.11\""}, {version = "<2.1.0", markers = "python_version >= \"3.11\""}, @@ -945,14 +923,10 @@ files = [ [package.dependencies] attrs = ">=20" -bytecode = [ - {version = ">=0.13.0,<0.14.0", markers = "python_version == \"3.7\""}, - {version = "*", markers = "python_version >= \"3.8\""}, -] +bytecode = {version = "*", markers = "python_version >= \"3.8\""} cattrs = "*" ddsketch = ">=2.0.1" envier = "*" -importlib-metadata = {version = "<=6.5.0", markers = "python_version < \"3.8\""} opentelemetry-api = ">=1" protobuf = ">=3" setuptools = {version = "*", markers = "python_version >= \"3.12\""} @@ -1141,7 +1115,6 @@ files = [ [package.dependencies] gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} [package.extras] test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] @@ -1157,9 +1130,6 @@ files = [ {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, ] -[package.dependencies] -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - [[package]] name = "httpcore" version = "0.17.3" @@ -1340,7 +1310,6 @@ files = [ ] [package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] @@ -1497,9 +1466,6 @@ files = [ {file = "jsonpickle-3.0.2.tar.gz", hash = "sha256:e37abba4bfb3ca4a4647d28bb9f4706436f7b46c8a8333b4a718abafa8e46b37"}, ] -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - [package.extras] docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] testing = ["ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-black-multipy", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-flake8 (>=1.1.1)", "scikit-learn", "sqlalchemy"] @@ -1529,11 +1495,9 @@ files = [ [package.dependencies] attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] @@ -1565,7 +1529,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} MarkupSafe = ">=0.9.2" [package.extras] @@ -1621,7 +1584,6 @@ files = [ [package.dependencies] mdurl = ">=0.1,<1.0" -typing_extensions = {version = ">=3.7.4", markers = "python_version < \"3.8\""} [package.extras] benchmarking = ["psutil", "pytest", "pytest-benchmark"] @@ -1770,7 +1732,6 @@ pathspec = ">=0.11.1" platformdirs = ">=2.2.0" pyyaml = ">=5.1" pyyaml-env-tag = ">=0.1" -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.8\""} watchdog = ">=2.0" [package.extras] @@ -1882,7 +1843,6 @@ files = [ [package.dependencies] mypy-extensions = ">=1.0.0" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} typing-extensions = ">=4.1.0" [package.extras] @@ -1907,13 +1867,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-appconfigdata" -version = "1.34.0" -description = "Type annotations for boto3.AppConfigData 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.24" +description = "Type annotations for boto3.AppConfigData 1.34.24 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-appconfigdata-1.34.0.tar.gz", hash = "sha256:5b48444398bc11ff9cb80659e67051689840cd40bf883ab06c1d7a4570b576ad"}, - {file = "mypy_boto3_appconfigdata-1.34.0-py3-none-any.whl", hash = "sha256:07972612091d388b22aeac1353475ebc1199a52f5ce80fba0e4d5d1201b3907b"}, + {file = "mypy-boto3-appconfigdata-1.34.24.tar.gz", hash = "sha256:a52a35430e9928dd17cc4465091982b6f2443a383277e6bcdade90de93da53c4"}, + {file = "mypy_boto3_appconfigdata-1.34.24-py3-none-any.whl", hash = "sha256:229014bf41f2d98ff0c230716f45740ca9b23a369c2513cab78ad9a02f6a1515"}, ] [package.dependencies] @@ -1921,13 +1881,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-cloudformation" -version = "1.34.0" -description = "Type annotations for boto3.CloudFormation 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.32" +description = "Type annotations for boto3.CloudFormation 1.34.32 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-cloudformation-1.34.0.tar.gz", hash = "sha256:9b25df9ef15d9dc8e4e892cc07aa9343f15f2ed5eb7d33eb5eb65adfa63f538f"}, - {file = "mypy_boto3_cloudformation-1.34.0-py3-none-any.whl", hash = "sha256:4e63a2bca1882971881d65983acd774c2fc636bbc5dc8c3e1f4a41c539cf3c90"}, + {file = "mypy-boto3-cloudformation-1.34.32.tar.gz", hash = "sha256:49d04c090dae3fd8289738ae592cac9d6faa5169684de40c2730b425bba2a32d"}, + {file = "mypy_boto3_cloudformation-1.34.32-py3-none-any.whl", hash = "sha256:bfe5ec405eae6dae31dc9874729eef5e668e634eae8972032f00400d17bd2c7d"}, ] [package.dependencies] @@ -1949,13 +1909,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-dynamodb" -version = "1.34.0" -description = "Type annotations for boto3.DynamoDB 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.34" +description = "Type annotations for boto3.DynamoDB 1.34.34 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-dynamodb-1.34.0.tar.gz", hash = "sha256:c0d98d7e83b0bc22e5039f703889fb96202d818171c4206fd31e665a37654e84"}, - {file = "mypy_boto3_dynamodb-1.34.0-py3-none-any.whl", hash = "sha256:76869c3fec882ddeeaca485074e302bf38c3b61103664d665dfed9425234ff75"}, + {file = "mypy-boto3-dynamodb-1.34.34.tar.gz", hash = "sha256:023b0284027ab5f4e5c912dfae86583c62b0e6c8b1d34fad8c6fba37f9baf17b"}, + {file = "mypy_boto3_dynamodb-1.34.34-py3-none-any.whl", hash = "sha256:fb5e49ec0632ff9c15be3ce25302cdd7a917ffa0a80c49f30e3a136ecc9601f0"}, ] [package.dependencies] @@ -1977,13 +1937,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-logs" -version = "1.34.0" -description = "Type annotations for boto3.CloudWatchLogs 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.16" +description = "Type annotations for boto3.CloudWatchLogs 1.34.16 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-logs-1.34.0.tar.gz", hash = "sha256:a852bf6c48733a51c324ca97da042bfe4c66b0d33aabe042fb27d3092572d55b"}, - {file = "mypy_boto3_logs-1.34.0-py3-none-any.whl", hash = "sha256:cb2d29096d3b07d7d508fa1f236f9cd15c292d41c8807aba7347627868e7ebdc"}, + {file = "mypy-boto3-logs-1.34.16.tar.gz", hash = "sha256:fff912fd8e9b7ce2bd5ea64c7f3e1f07885660226190f86353083836338a2d2a"}, + {file = "mypy_boto3_logs-1.34.16-py3-none-any.whl", hash = "sha256:2f0c918a59fbac279117bef67666aafd7d6ebdd5fbc7015352206553afb82c40"}, ] [package.dependencies] @@ -1991,13 +1951,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-s3" -version = "1.34.0" -description = "Type annotations for boto3.S3 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.14" +description = "Type annotations for boto3.S3 1.34.14 service generated with mypy-boto3-builder 7.21.0" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-s3-1.34.0.tar.gz", hash = "sha256:7644a00e096ebb1c3292551059f64ff8329625dacd40827ced9481b14d64c733"}, - {file = "mypy_boto3_s3-1.34.0-py3-none-any.whl", hash = "sha256:633876d2a96dbb924f9667084316c1759bff40c19a9a38313d5a4e825c5fc641"}, + {file = "mypy-boto3-s3-1.34.14.tar.gz", hash = "sha256:71c39ab0623cdb442d225b71c1783f6a513cff4c4a13505a2efbb2e3aff2e965"}, + {file = "mypy_boto3_s3-1.34.14-py3-none-any.whl", hash = "sha256:f9669ecd182d5bf3532f5f2dcc5e5237776afe157ad5a0b37b26d6bec5fcc432"}, ] [package.dependencies] @@ -2005,13 +1965,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-secretsmanager" -version = "1.34.0" -description = "Type annotations for boto3.SecretsManager 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.17" +description = "Type annotations for boto3.SecretsManager 1.34.17 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-secretsmanager-1.34.0.tar.gz", hash = "sha256:f7c1a99a28e650ac91834db69a8dabe6734f9ace92f1d7a2d366160a11401133"}, - {file = "mypy_boto3_secretsmanager-1.34.0-py3-none-any.whl", hash = "sha256:d3b0c26f4264775a2505cbd4a73a4efd5c4a151d8fcdcf938683afb1bf717a32"}, + {file = "mypy-boto3-secretsmanager-1.34.17.tar.gz", hash = "sha256:a547932d99c3f711b27b9ea1c38fc063050910c0bf6c8eb346abd96ace61668e"}, + {file = "mypy_boto3_secretsmanager-1.34.17-py3-none-any.whl", hash = "sha256:0dbd1cdbe7992324c3414cccf0256e3905827bbf1f6a8d58c255635f6a2b4bfb"}, ] [package.dependencies] @@ -2019,13 +1979,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-ssm" -version = "1.34.0" -description = "Type annotations for boto3.SSM 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.32" +description = "Type annotations for boto3.SSM 1.34.32 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-ssm-1.34.0.tar.gz", hash = "sha256:ae82936d77496f7958dc25d5db7d48f63b164cac03686c60475c709107deafec"}, - {file = "mypy_boto3_ssm-1.34.0-py3-none-any.whl", hash = "sha256:e2c34db563851939cab1f12fb392be904f83146af88f515c5cd50bf6c612dda4"}, + {file = "mypy-boto3-ssm-1.34.32.tar.gz", hash = "sha256:1d78f8bfb85d4bfb820046b7c864b75e2ef1a04ea7fed88b4d6d6abf252077e6"}, + {file = "mypy_boto3_ssm-1.34.32-py3-none-any.whl", hash = "sha256:185e46fa5996843e34a5c7fb5e2129df57a37fca3187daa1ab81996d5633c772"}, ] [package.dependencies] @@ -2169,9 +2129,6 @@ files = [ {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, ] -[package.dependencies] -typing-extensions = {version = ">=4.7.1", markers = "python_version < \"3.8\""} - [package.extras] docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] @@ -2187,9 +2144,6 @@ files = [ {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, ] -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - [package.extras] dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] @@ -2406,7 +2360,6 @@ files = [ [package.dependencies] colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} iniconfig = "*" packaging = "*" pluggy = ">=0.12,<2.0" @@ -2428,7 +2381,6 @@ files = [ [package.dependencies] pytest = ">=7.0.0" -typing-extensions = {version = ">=3.7.2", markers = "python_version < \"3.8\""} [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] @@ -2676,8 +2628,6 @@ files = [ [package.dependencies] async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} -importlib-metadata = {version = ">=1.0", markers = "python_version < \"3.8\""} -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} [package.extras] hiredis = ["hiredis (>=1.0.0)"] @@ -2997,7 +2947,6 @@ files = [ ] [package.dependencies] -importlib-metadata = {version = ">=1.7.0", markers = "python_version < \"3.8\""} pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] @@ -3059,56 +3008,6 @@ files = [ {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, ] -[[package]] -name = "typed-ast" -version = "1.5.5" -description = "a fork of Python 2 and 3 ast modules with type comment support" -optional = false -python-versions = ">=3.6" -files = [ - {file = "typed_ast-1.5.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4bc1efe0ce3ffb74784e06460f01a223ac1f6ab31c6bc0376a21184bf5aabe3b"}, - {file = "typed_ast-1.5.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5f7a8c46a8b333f71abd61d7ab9255440d4a588f34a21f126bbfc95f6049e686"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:597fc66b4162f959ee6a96b978c0435bd63791e31e4f410622d19f1686d5e769"}, - {file = "typed_ast-1.5.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d41b7a686ce653e06c2609075d397ebd5b969d821b9797d029fccd71fdec8e04"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:5fe83a9a44c4ce67c796a1b466c270c1272e176603d5e06f6afbc101a572859d"}, - {file = "typed_ast-1.5.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d5c0c112a74c0e5db2c75882a0adf3133adedcdbfd8cf7c9d6ed77365ab90a1d"}, - {file = "typed_ast-1.5.5-cp310-cp310-win_amd64.whl", hash = "sha256:e1a976ed4cc2d71bb073e1b2a250892a6e968ff02aa14c1f40eba4f365ffec02"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c631da9710271cb67b08bd3f3813b7af7f4c69c319b75475436fcab8c3d21bee"}, - {file = "typed_ast-1.5.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b445c2abfecab89a932b20bd8261488d574591173d07827c1eda32c457358b18"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc95ffaaab2be3b25eb938779e43f513e0e538a84dd14a5d844b8f2932593d88"}, - {file = "typed_ast-1.5.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61443214d9b4c660dcf4b5307f15c12cb30bdfe9588ce6158f4a005baeb167b2"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6eb936d107e4d474940469e8ec5b380c9b329b5f08b78282d46baeebd3692dc9"}, - {file = "typed_ast-1.5.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e48bf27022897577d8479eaed64701ecaf0467182448bd95759883300ca818c8"}, - {file = "typed_ast-1.5.5-cp311-cp311-win_amd64.whl", hash = "sha256:83509f9324011c9a39faaef0922c6f720f9623afe3fe220b6d0b15638247206b"}, - {file = "typed_ast-1.5.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:44f214394fc1af23ca6d4e9e744804d890045d1643dd7e8229951e0ef39429b5"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:118c1ce46ce58fda78503eae14b7664163aa735b620b64b5b725453696f2a35c"}, - {file = "typed_ast-1.5.5-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:be4919b808efa61101456e87f2d4c75b228f4e52618621c77f1ddcaae15904fa"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:fc2b8c4e1bc5cd96c1a823a885e6b158f8451cf6f5530e1829390b4d27d0807f"}, - {file = "typed_ast-1.5.5-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:16f7313e0a08c7de57f2998c85e2a69a642e97cb32f87eb65fbfe88381a5e44d"}, - {file = "typed_ast-1.5.5-cp36-cp36m-win_amd64.whl", hash = "sha256:2b946ef8c04f77230489f75b4b5a4a6f24c078be4aed241cfabe9cbf4156e7e5"}, - {file = "typed_ast-1.5.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2188bc33d85951ea4ddad55d2b35598b2709d122c11c75cffd529fbc9965508e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0635900d16ae133cab3b26c607586131269f88266954eb04ec31535c9a12ef1e"}, - {file = "typed_ast-1.5.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57bfc3cf35a0f2fdf0a88a3044aafaec1d2f24d8ae8cd87c4f58d615fb5b6311"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:fe58ef6a764de7b4b36edfc8592641f56e69b7163bba9f9c8089838ee596bfb2"}, - {file = "typed_ast-1.5.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d09d930c2d1d621f717bb217bf1fe2584616febb5138d9b3e8cdd26506c3f6d4"}, - {file = "typed_ast-1.5.5-cp37-cp37m-win_amd64.whl", hash = "sha256:d40c10326893ecab8a80a53039164a224984339b2c32a6baf55ecbd5b1df6431"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:fd946abf3c31fb50eee07451a6aedbfff912fcd13cf357363f5b4e834cc5e71a"}, - {file = "typed_ast-1.5.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ed4a1a42df8a3dfb6b40c3d2de109e935949f2f66b19703eafade03173f8f437"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:045f9930a1550d9352464e5149710d56a2aed23a2ffe78946478f7b5416f1ede"}, - {file = "typed_ast-1.5.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381eed9c95484ceef5ced626355fdc0765ab51d8553fec08661dce654a935db4"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:bfd39a41c0ef6f31684daff53befddae608f9daf6957140228a08e51f312d7e6"}, - {file = "typed_ast-1.5.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8c524eb3024edcc04e288db9541fe1f438f82d281e591c548903d5b77ad1ddd4"}, - {file = "typed_ast-1.5.5-cp38-cp38-win_amd64.whl", hash = "sha256:7f58fabdde8dcbe764cef5e1a7fcb440f2463c1bbbec1cf2a86ca7bc1f95184b"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:042eb665ff6bf020dd2243307d11ed626306b82812aba21836096d229fdc6a10"}, - {file = "typed_ast-1.5.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:622e4a006472b05cf6ef7f9f2636edc51bda670b7bbffa18d26b255269d3d814"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1efebbbf4604ad1283e963e8915daa240cb4bf5067053cf2f0baadc4d4fb51b8"}, - {file = "typed_ast-1.5.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f0aefdd66f1784c58f65b502b6cf8b121544680456d1cebbd300c2c813899274"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:48074261a842acf825af1968cd912f6f21357316080ebaca5f19abbb11690c8a"}, - {file = "typed_ast-1.5.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:429ae404f69dc94b9361bb62291885894b7c6fb4640d561179548c849f8492ba"}, - {file = "typed_ast-1.5.5-cp39-cp39-win_amd64.whl", hash = "sha256:335f22ccb244da2b5c296e6f96b06ee9bed46526db0de38d2f0e5a6597b81155"}, - {file = "typed_ast-1.5.5.tar.gz", hash = "sha256:94282f7a354f36ef5dbce0ef3467ebf6a258e370ab33d5b40c249fa996e590dd"}, -] - [[package]] name = "typeguard" version = "2.13.3" @@ -3436,4 +3335,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "ed9d43fd5827d270530b7e9eb60fb2e398e9d42b4317035396bb51c52485d313" +content-hash = "8b0f7472389080ee2e1c9fbf40d97754d9add5c2edf0a3d33fc0af2fa96f6468" diff --git a/pyproject.toml b/pyproject.toml index c0349853aca..d8c8a1cf8d2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -71,21 +71,21 @@ aws-cdk-lib = "^2.111.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" pytest-benchmark = "^4.0.0" mypy-boto3-appconfig = "^1.34.0" -mypy-boto3-cloudformation = "^1.34.0" +mypy-boto3-cloudformation = "^1.34.32" mypy-boto3-cloudwatch = "^1.34.0" -mypy-boto3-dynamodb = "^1.34.0" +mypy-boto3-dynamodb = "^1.34.34" mypy-boto3-lambda = "^1.34.0" -mypy-boto3-logs = "^1.34.0" -mypy-boto3-secretsmanager = "^1.34.0" -mypy-boto3-ssm = "^1.34.0" -mypy-boto3-s3 = "^1.34.0" +mypy-boto3-logs = "^1.34.16" +mypy-boto3-secretsmanager = "^1.34.17" +mypy-boto3-ssm = "^1.34.32" +mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" typing-extensions = "^4.6.2" mkdocs-material = "^9.2.7" filelock = "^3.12.2" checksumdir = "^1.2.0" -mypy-boto3-appconfigdata = "^1.34.0" +mypy-boto3-appconfigdata = "^1.34.24" ijson = "^3.2.2" typed-ast = { version = "^1.5.5", python = "< 3.8"} hvac = "^1.2.1" From e14e76884465d087424a1b2e6915daf562b9b8fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:12:16 +0000 Subject: [PATCH 0053/2666] chore(deps-dev): bump coverage from 7.2.7 to 7.4.1 (#3713) Bumps [coverage](https://github.com/nedbat/coveragepy) from 7.2.7 to 7.4.1. - [Release notes](https://github.com/nedbat/coveragepy/releases) - [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst) - [Commits](https://github.com/nedbat/coveragepy/compare/7.2.7...7.4.1) --- updated-dependencies: - dependency-name: coverage dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 118 +++++++++++++++++++++++-------------------------- pyproject.toml | 2 +- 2 files changed, 56 insertions(+), 64 deletions(-) diff --git a/poetry.lock b/poetry.lock index c3a44ba90f6..b14d10c7638 100644 --- a/poetry.lock +++ b/poetry.lock @@ -673,71 +673,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.2.7" +version = "7.4.1" description = "Code coverage measurement for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "coverage-7.2.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d39b5b4f2a66ccae8b7263ac3c8170994b65266797fb96cbbfd3fb5b23921db8"}, - {file = "coverage-7.2.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6d040ef7c9859bb11dfeb056ff5b3872436e3b5e401817d87a31e1750b9ae2fb"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba90a9563ba44a72fda2e85302c3abc71c5589cea608ca16c22b9804262aaeb6"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7d9405291c6928619403db1d10bd07888888ec1abcbd9748fdaa971d7d661b2"}, - {file = "coverage-7.2.7-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31563e97dae5598556600466ad9beea39fb04e0229e61c12eaa206e0aa202063"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ebba1cd308ef115925421d3e6a586e655ca5a77b5bf41e02eb0e4562a111f2d1"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:cb017fd1b2603ef59e374ba2063f593abe0fc45f2ad9abdde5b4d83bd922a353"}, - {file = "coverage-7.2.7-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:d62a5c7dad11015c66fbb9d881bc4caa5b12f16292f857842d9d1871595f4495"}, - {file = "coverage-7.2.7-cp310-cp310-win32.whl", hash = "sha256:ee57190f24fba796e36bb6d3aa8a8783c643d8fa9760c89f7a98ab5455fbf818"}, - {file = "coverage-7.2.7-cp310-cp310-win_amd64.whl", hash = "sha256:f75f7168ab25dd93110c8a8117a22450c19976afbc44234cbf71481094c1b850"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:06a9a2be0b5b576c3f18f1a241f0473575c4a26021b52b2a85263a00f034d51f"}, - {file = "coverage-7.2.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5baa06420f837184130752b7c5ea0808762083bf3487b5038d68b012e5937dbe"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fdec9e8cbf13a5bf63290fc6013d216a4c7232efb51548594ca3631a7f13c3a3"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:52edc1a60c0d34afa421c9c37078817b2e67a392cab17d97283b64c5833f427f"}, - {file = "coverage-7.2.7-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63426706118b7f5cf6bb6c895dc215d8a418d5952544042c8a2d9fe87fcf09cb"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:afb17f84d56068a7c29f5fa37bfd38d5aba69e3304af08ee94da8ed5b0865833"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:48c19d2159d433ccc99e729ceae7d5293fbffa0bdb94952d3579983d1c8c9d97"}, - {file = "coverage-7.2.7-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:0e1f928eaf5469c11e886fe0885ad2bf1ec606434e79842a879277895a50942a"}, - {file = "coverage-7.2.7-cp311-cp311-win32.whl", hash = "sha256:33d6d3ea29d5b3a1a632b3c4e4f4ecae24ef170b0b9ee493883f2df10039959a"}, - {file = "coverage-7.2.7-cp311-cp311-win_amd64.whl", hash = "sha256:5b7540161790b2f28143191f5f8ec02fb132660ff175b7747b95dcb77ac26562"}, - {file = "coverage-7.2.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f2f67fe12b22cd130d34d0ef79206061bfb5eda52feb6ce0dba0644e20a03cf4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a342242fe22407f3c17f4b499276a02b01e80f861f1682ad1d95b04018e0c0d4"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:171717c7cb6b453aebac9a2ef603699da237f341b38eebfee9be75d27dc38e01"}, - {file = "coverage-7.2.7-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:49969a9f7ffa086d973d91cec8d2e31080436ef0fb4a359cae927e742abfaaa6"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b46517c02ccd08092f4fa99f24c3b83d8f92f739b4657b0f146246a0ca6a831d"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a3d33a6b3eae87ceaefa91ffdc130b5e8536182cd6dfdbfc1aa56b46ff8c86de"}, - {file = "coverage-7.2.7-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:976b9c42fb2a43ebf304fa7d4a310e5f16cc99992f33eced91ef6f908bd8f33d"}, - {file = "coverage-7.2.7-cp312-cp312-win32.whl", hash = "sha256:8de8bb0e5ad103888d65abef8bca41ab93721647590a3f740100cd65c3b00511"}, - {file = "coverage-7.2.7-cp312-cp312-win_amd64.whl", hash = "sha256:9e31cb64d7de6b6f09702bb27c02d1904b3aebfca610c12772452c4e6c21a0d3"}, - {file = "coverage-7.2.7-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:58c2ccc2f00ecb51253cbe5d8d7122a34590fac9646a960d1430d5b15321d95f"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d22656368f0e6189e24722214ed8d66b8022db19d182927b9a248a2a8a2f67eb"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a895fcc7b15c3fc72beb43cdcbdf0ddb7d2ebc959edac9cef390b0d14f39f8a9"}, - {file = "coverage-7.2.7-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e84606b74eb7de6ff581a7915e2dab7a28a0517fbe1c9239eb227e1354064dcd"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:0a5f9e1dbd7fbe30196578ca36f3fba75376fb99888c395c5880b355e2875f8a"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:419bfd2caae268623dd469eff96d510a920c90928b60f2073d79f8fe2bbc5959"}, - {file = "coverage-7.2.7-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:2aee274c46590717f38ae5e4650988d1af340fe06167546cc32fe2f58ed05b02"}, - {file = "coverage-7.2.7-cp37-cp37m-win32.whl", hash = "sha256:61b9a528fb348373c433e8966535074b802c7a5d7f23c4f421e6c6e2f1697a6f"}, - {file = "coverage-7.2.7-cp37-cp37m-win_amd64.whl", hash = "sha256:b1c546aca0ca4d028901d825015dc8e4d56aac4b541877690eb76490f1dc8ed0"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:54b896376ab563bd38453cecb813c295cf347cf5906e8b41d340b0321a5433e5"}, - {file = "coverage-7.2.7-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3d376df58cc111dc8e21e3b6e24606b5bb5dee6024f46a5abca99124b2229ef5"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5e330fc79bd7207e46c7d7fd2bb4af2963f5f635703925543a70b99574b0fea9"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e9d683426464e4a252bf70c3498756055016f99ddaec3774bf368e76bbe02b6"}, - {file = "coverage-7.2.7-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d13c64ee2d33eccf7437961b6ea7ad8673e2be040b4f7fd4fd4d4d28d9ccb1e"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7aa5f8a41217360e600da646004f878250a0d6738bcdc11a0a39928d7dc2050"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:8fa03bce9bfbeeef9f3b160a8bed39a221d82308b4152b27d82d8daa7041fee5"}, - {file = "coverage-7.2.7-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:245167dd26180ab4c91d5e1496a30be4cd721a5cf2abf52974f965f10f11419f"}, - {file = "coverage-7.2.7-cp38-cp38-win32.whl", hash = "sha256:d2c2db7fd82e9b72937969bceac4d6ca89660db0a0967614ce2481e81a0b771e"}, - {file = "coverage-7.2.7-cp38-cp38-win_amd64.whl", hash = "sha256:2e07b54284e381531c87f785f613b833569c14ecacdcb85d56b25c4622c16c3c"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:537891ae8ce59ef63d0123f7ac9e2ae0fc8b72c7ccbe5296fec45fd68967b6c9"}, - {file = "coverage-7.2.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:06fb182e69f33f6cd1d39a6c597294cff3143554b64b9825d1dc69d18cc2fff2"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:201e7389591af40950a6480bd9edfa8ed04346ff80002cec1a66cac4549c1ad7"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f6951407391b639504e3b3be51b7ba5f3528adbf1a8ac3302b687ecababf929e"}, - {file = "coverage-7.2.7-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f48351d66575f535669306aa7d6d6f71bc43372473b54a832222803eb956fd1"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:b29019c76039dc3c0fd815c41392a044ce555d9bcdd38b0fb60fb4cd8e475ba9"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:81c13a1fc7468c40f13420732805a4c38a105d89848b7c10af65a90beff25250"}, - {file = "coverage-7.2.7-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:975d70ab7e3c80a3fe86001d8751f6778905ec723f5b110aed1e450da9d4b7f2"}, - {file = "coverage-7.2.7-cp39-cp39-win32.whl", hash = "sha256:7ee7d9d4822c8acc74a5e26c50604dff824710bc8de424904c0982e25c39c6cb"}, - {file = "coverage-7.2.7-cp39-cp39-win_amd64.whl", hash = "sha256:eb393e5ebc85245347950143969b241d08b52b88a3dc39479822e073a1a8eb27"}, - {file = "coverage-7.2.7-pp37.pp38.pp39-none-any.whl", hash = "sha256:b7b4c971f05e6ae490fef852c218b0e79d4e52f79ef0c8475566584a8fb3e01d"}, - {file = "coverage-7.2.7.tar.gz", hash = "sha256:924d94291ca674905fe9481f12294eb11f2d3d3fd1adb20314ba89e94f44ed59"}, + {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, + {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, + {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, + {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, + {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, + {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, + {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, + {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, + {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, + {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, + {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, + {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, + {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, + {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, + {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, + {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, + {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, + {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, + {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, + {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, + {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, + {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, + {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, + {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, + {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, + {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, + {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, + {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, ] [package.dependencies] @@ -3335,4 +3327,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "8b0f7472389080ee2e1c9fbf40d97754d9add5c2edf0a3d33fc0af2fa96f6468" +content-hash = "a3e95d91f440eaffacf5df82abdf33459f60471929d1f0b9ad7829e16a5e61ef" diff --git a/pyproject.toml b/pyproject.toml index d8c8a1cf8d2..27ea55d2e24 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -50,7 +50,7 @@ aws-encryption-sdk = { version = "^3.1.1", optional = true } jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] -coverage = {extras = ["toml"], version = "^7.2"} +coverage = {extras = ["toml"], version = "^7.4"} pytest = "^7.4.4" black = "^23.3" boto3 = "^1.26.164" From 1a098e01b14b5951b05a638b13737f61463b9516 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:13:54 +0000 Subject: [PATCH 0054/2666] chore(deps): bump codecov/codecov-action from 3.1.6 to 4.0.1 (#3700) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 3.1.6 to 4.0.1. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/ab904c41d6ece82784817410c45d8b8c02684457...e0b68c6749509c5f83f984dd99a76a1c1a231044) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- .github/workflows/quality_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index d28357be3b1..fe5616711c6 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@ab904c41d6ece82784817410c45d8b8c02684457 # 3.1.6 + uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # 4.0.1 with: file: ./coverage.xml env_vars: PYTHON From 287574d3292b5e8bd9fbb4e77f40560d97670505 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:14:29 +0000 Subject: [PATCH 0055/2666] chore(deps): bump actions/download-artifact from 3.0.2 to 4.1.1 (#3612) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3.0.2 to 4.1.1. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/9bc31d5ccc31df68ecc42ccf4149144866c47d8a...6b208ae046db98c579e8a3aa621ab581ff575935) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- .github/workflows/reusable_deploy_v2_sar.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index f067d02becd..1dc6231b6a7 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -258,7 +258,7 @@ jobs: artifact_name: ${{ inputs.source_code_artifact_name }} - name: Download CDK layer artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: name: cdk-layer-stack path: cdk-layer-stack/ diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index d271050fa86..e9d9d65aff6 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -180,7 +180,7 @@ jobs: - name: install deps run: poetry install - name: Download artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: name: ${{ inputs.artefact-name }} path: layer diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml index c95bc69a006..ef6a58f0aa2 100644 --- a/.github/workflows/reusable_deploy_v2_sar.yml +++ b/.github/workflows/reusable_deploy_v2_sar.yml @@ -115,7 +115,7 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} - name: Download artifact - uses: actions/download-artifact@9bc31d5ccc31df68ecc42ccf4149144866c47d8a # v3.0.2 + uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 with: name: ${{ inputs.artefact-name }} - name: Unzip artefact From 9b5245e32db4015ce79c04f31bfe88a38ebb4d4f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Feb 2024 22:41:12 +0000 Subject: [PATCH 0056/2666] chore(deps-dev): bump httpx from 0.24.1 to 0.26.0 (#3712) Bumps [httpx](https://github.com/encode/httpx) from 0.24.1 to 0.26.0. - [Release notes](https://github.com/encode/httpx/releases) - [Changelog](https://github.com/encode/httpx/blob/master/CHANGELOG.md) - [Commits](https://github.com/encode/httpx/compare/0.24.1...0.26.0) --- updated-dependencies: - dependency-name: httpx dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 25 +++++++++++++------------ pyproject.toml | 2 +- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index b14d10c7638..546608d35e5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1124,39 +1124,40 @@ files = [ [[package]] name = "httpcore" -version = "0.17.3" +version = "1.0.2" description = "A minimal low-level HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpcore-0.17.3-py3-none-any.whl", hash = "sha256:c2789b767ddddfa2a5782e3199b2b7f6894540b17b16ec26b2c4d8e103510b87"}, - {file = "httpcore-0.17.3.tar.gz", hash = "sha256:a6f30213335e34c1ade7be6ec7c47f19f50c56db36abef1a9dfa3815b1cb3888"}, + {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, + {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, ] [package.dependencies] -anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" [package.extras] +asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] +trio = ["trio (>=0.22.0,<0.23.0)"] [[package]] name = "httpx" -version = "0.24.1" +version = "0.26.0" description = "The next generation HTTP client." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "httpx-0.24.1-py3-none-any.whl", hash = "sha256:06781eb9ac53cde990577af654bd990a4949de37a28bdb4a230d434f3a30b9bd"}, - {file = "httpx-0.24.1.tar.gz", hash = "sha256:5853a43053df830c20f8110c5e69fe44d035d850b2dfe795e196f00fdb774bdd"}, + {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, + {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, ] [package.dependencies] +anyio = "*" certifi = "*" -httpcore = ">=0.15.0,<0.18.0" +httpcore = "==1.*" idna = "*" sniffio = "*" @@ -3327,4 +3328,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "a3e95d91f440eaffacf5df82abdf33459f60471929d1f0b9ad7829e16a5e61ef" +content-hash = "1f6979025f2fa294a718f2eb2356cc02a0a8af15e867a4f9abf2ec6bed985a8a" diff --git a/pyproject.toml b/pyproject.toml index 27ea55d2e24..1802c718ec2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -107,7 +107,7 @@ datamasking = ["aws-encryption-sdk", "jsonpath-ng"] cfn-lint = "0.83.8" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" -httpx = ">=0.23.3,<0.25.0" +httpx = ">=0.23.3,<0.27.0" sentry-sdk = "^1.22.2" ruff = ">=0.0.272,<0.2.1" retry2 = "^0.9.5" From f7ca5b0c31a4c84a6dcb667a9ba7c2f5c53c5de8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 09:41:21 +0100 Subject: [PATCH 0057/2666] chore(deps-dev): bump mypy from 1.4.1 to 1.8.0 (#3710) * chore(deps-dev): bump mypy from 1.4.1 to 1.8.0 Bumps [mypy](https://github.com/python/mypy) from 1.4.1 to 1.8.0. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.4.1...v1.8.0) --- updated-dependencies: - dependency-name: mypy dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * Fixing mypy problems --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- .../provider/cloudwatch_emf/cloudwatch.py | 4 +- ...otent_function_custom_output_serializer.py | 2 +- poetry.lock | 59 ++++++++++--------- 3 files changed, 33 insertions(+), 32 deletions(-) diff --git a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py index e1366a8a725..f5859c5a48d 100644 --- a/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py +++ b/aws_lambda_powertools/metrics/provider/cloudwatch_emf/cloudwatch.py @@ -241,8 +241,8 @@ def serialize_metric_set( ], }, # NOTE: Mypy doesn't recognize splats '** syntax' in TypedDict - **dimensions, # type: ignore[misc] # "service": "test_service" - **metadata, # "username": "test" + **dimensions, # "service": "test_service" + **metadata, # type: ignore[typeddict-item] # "username": "test" **metric_names_and_values, # "single_metric": 1.0 } diff --git a/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py b/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py index e32d5da868e..a62961fa5f3 100644 --- a/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py +++ b/examples/idempotency/src/working_with_idempotent_function_custom_output_serializer.py @@ -30,7 +30,7 @@ def __init__(self, order_id: int): def order_to_dict(x: Type[OrderOutput]) -> Dict: # (1)! - return x.__dict__ + return dict(x.__dict__) def dict_to_order(x: Dict) -> OrderOutput: # (2)! diff --git a/poetry.lock b/poetry.lock index 546608d35e5..0b970ab555a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1800,37 +1800,38 @@ tests = ["pytest (>=4.6)"] [[package]] name = "mypy" -version = "1.4.1" +version = "1.8.0" description = "Optional static typing for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-1.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:566e72b0cd6598503e48ea610e0052d1b8168e60a46e0bfd34b3acf2d57f96a8"}, - {file = "mypy-1.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ca637024ca67ab24a7fd6f65d280572c3794665eaf5edcc7e90a866544076878"}, - {file = "mypy-1.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dde1d180cd84f0624c5dcaaa89c89775550a675aff96b5848de78fb11adabcd"}, - {file = "mypy-1.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8c4d8e89aa7de683e2056a581ce63c46a0c41e31bd2b6d34144e2c80f5ea53dc"}, - {file = "mypy-1.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:bfdca17c36ae01a21274a3c387a63aa1aafe72bff976522886869ef131b937f1"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7549fbf655e5825d787bbc9ecf6028731973f78088fbca3a1f4145c39ef09462"}, - {file = "mypy-1.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:98324ec3ecf12296e6422939e54763faedbfcc502ea4a4c38502082711867258"}, - {file = "mypy-1.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:141dedfdbfe8a04142881ff30ce6e6653c9685b354876b12e4fe6c78598b45e2"}, - {file = "mypy-1.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8207b7105829eca6f3d774f64a904190bb2231de91b8b186d21ffd98005f14a7"}, - {file = "mypy-1.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:16f0db5b641ba159eff72cff08edc3875f2b62b2fa2bc24f68c1e7a4e8232d01"}, - {file = "mypy-1.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:470c969bb3f9a9efcedbadcd19a74ffb34a25f8e6b0e02dae7c0e71f8372f97b"}, - {file = "mypy-1.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5952d2d18b79f7dc25e62e014fe5a23eb1a3d2bc66318df8988a01b1a037c5b"}, - {file = "mypy-1.4.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:190b6bab0302cec4e9e6767d3eb66085aef2a1cc98fe04936d8a42ed2ba77bb7"}, - {file = "mypy-1.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9d40652cc4fe33871ad3338581dca3297ff5f2213d0df345bcfbde5162abf0c9"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:01fd2e9f85622d981fd9063bfaef1aed6e336eaacca00892cd2d82801ab7c042"}, - {file = "mypy-1.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2460a58faeea905aeb1b9b36f5065f2dc9a9c6e4c992a6499a2360c6c74ceca3"}, - {file = "mypy-1.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a2746d69a8196698146a3dbe29104f9eb6a2a4d8a27878d92169a6c0b74435b6"}, - {file = "mypy-1.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae704dcfaa180ff7c4cfbad23e74321a2b774f92ca77fd94ce1049175a21c97f"}, - {file = "mypy-1.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:43d24f6437925ce50139a310a64b2ab048cb2d3694c84c71c3f2a1626d8101dc"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c482e1246726616088532b5e964e39765b6d1520791348e6c9dc3af25b233828"}, - {file = "mypy-1.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:43b592511672017f5b1a483527fd2684347fdffc041c9ef53428c8dc530f79a3"}, - {file = "mypy-1.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:34a9239d5b3502c17f07fd7c0b2ae6b7dd7d7f6af35fbb5072c6208e76295816"}, - {file = "mypy-1.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5703097c4936bbb9e9bce41478c8d08edd2865e177dc4c52be759f81ee4dd26c"}, - {file = "mypy-1.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:e02d700ec8d9b1859790c0475df4e4092c7bf3272a4fd2c9f33d87fac4427b8f"}, - {file = "mypy-1.4.1-py3-none-any.whl", hash = "sha256:45d32cec14e7b97af848bddd97d85ea4f0db4d5a149ed9676caa4eb2f7402bb4"}, - {file = "mypy-1.4.1.tar.gz", hash = "sha256:9bbcd9ab8ea1f2e1c8031c21445b511442cc45c89951e49bbf852cbb70755b1b"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:485a8942f671120f76afffff70f259e1cd0f0cfe08f81c05d8816d958d4577d3"}, + {file = "mypy-1.8.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:df9824ac11deaf007443e7ed2a4a26bebff98d2bc43c6da21b2b64185da011c4"}, + {file = "mypy-1.8.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2afecd6354bbfb6e0160f4e4ad9ba6e4e003b767dd80d85516e71f2e955ab50d"}, + {file = "mypy-1.8.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8963b83d53ee733a6e4196954502b33567ad07dfd74851f32be18eb932fb1cb9"}, + {file = "mypy-1.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:e46f44b54ebddbeedbd3d5b289a893219065ef805d95094d16a0af6630f5d410"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:855fe27b80375e5c5878492f0729540db47b186509c98dae341254c8f45f42ae"}, + {file = "mypy-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c886c6cce2d070bd7df4ec4a05a13ee20c0aa60cb587e8d1265b6c03cf91da3"}, + {file = "mypy-1.8.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d19c413b3c07cbecf1f991e2221746b0d2a9410b59cb3f4fb9557f0365a1a817"}, + {file = "mypy-1.8.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9261ed810972061388918c83c3f5cd46079d875026ba97380f3e3978a72f503d"}, + {file = "mypy-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:51720c776d148bad2372ca21ca29256ed483aa9a4cdefefcef49006dff2a6835"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:52825b01f5c4c1c4eb0db253ec09c7aa17e1a7304d247c48b6f3599ef40db8bd"}, + {file = "mypy-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f5ac9a4eeb1ec0f1ccdc6f326bcdb464de5f80eb07fb38b5ddd7b0de6bc61e55"}, + {file = "mypy-1.8.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afe3fe972c645b4632c563d3f3eff1cdca2fa058f730df2b93a35e3b0c538218"}, + {file = "mypy-1.8.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:42c6680d256ab35637ef88891c6bd02514ccb7e1122133ac96055ff458f93fc3"}, + {file = "mypy-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:720a5ca70e136b675af3af63db533c1c8c9181314d207568bbe79051f122669e"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:028cf9f2cae89e202d7b6593cd98db6759379f17a319b5faf4f9978d7084cdc6"}, + {file = "mypy-1.8.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4e6d97288757e1ddba10dd9549ac27982e3e74a49d8d0179fc14d4365c7add66"}, + {file = "mypy-1.8.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f1478736fcebb90f97e40aff11a5f253af890c845ee0c850fe80aa060a267c6"}, + {file = "mypy-1.8.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:42419861b43e6962a649068a61f4a4839205a3ef525b858377a960b9e2de6e0d"}, + {file = "mypy-1.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:2b5b6c721bd4aabaadead3a5e6fa85c11c6c795e0c81a7215776ef8afc66de02"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5c1538c38584029352878a0466f03a8ee7547d7bd9f641f57a0f3017a7c905b8"}, + {file = "mypy-1.8.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4ef4be7baf08a203170f29e89d79064463b7fc7a0908b9d0d5114e8009c3a259"}, + {file = "mypy-1.8.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7178def594014aa6c35a8ff411cf37d682f428b3b5617ca79029d8ae72f5402b"}, + {file = "mypy-1.8.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:ab3c84fa13c04aeeeabb2a7f67a25ef5d77ac9d6486ff33ded762ef353aa5592"}, + {file = "mypy-1.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:99b00bc72855812a60d253420d8a2eae839b0afa4938f09f4d2aa9bb4654263a"}, + {file = "mypy-1.8.0-py3-none-any.whl", hash = "sha256:538fd81bb5e430cc1381a443971c0475582ff9f434c16cd46d2c66763ce85d9d"}, + {file = "mypy-1.8.0.tar.gz", hash = "sha256:6ff8b244d7085a0b425b56d327b480c3b29cafbd2eff27316a004f9a7391ae07"}, ] [package.dependencies] @@ -1841,7 +1842,7 @@ typing-extensions = ">=4.1.0" [package.extras] dmypy = ["psutil (>=4.0)"] install-types = ["pip"] -python2 = ["typed-ast (>=1.4.0,<2)"] +mypyc = ["setuptools (>=50)"] reports = ["lxml"] [[package]] From d255a866a4ae52649909f4c145852388b695432d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 10:03:54 +0000 Subject: [PATCH 0058/2666] chore(ci): changelog rebuild (#3715) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Leandro Damascena --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ea1e02b55a..9bceb7116d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,17 @@ ## Maintenance +* **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) +* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) +* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) +* **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) +* **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) +* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) +* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) +* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) +* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) * **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) +* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) From b63a69cfa8285a4556186671f55e81573a4b030b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 14:26:20 +0100 Subject: [PATCH 0059/2666] chore(deps): bump actions/upload-artifact from 3.1.3 to 4.3.1 (#3714) * chore(deps): bump actions/upload-artifact from 3.1.3 to 4.3.1 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.3 to 4.3.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/a8a3f3ad30e3422c9c7b888a15615d19a852ae32...5d5d22a31266ced268874388b861e4b58bb5c2f3) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] * Adding new required parameter * Addressing Andrea's feedback --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena Co-authored-by: Heitor Lessa --- .github/workflows/ossf_scorecard.yml | 2 +- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/record_pr.yml | 2 +- .github/workflows/reusable_deploy_v2_layer_stack.yml | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ossf_scorecard.yml b/.github/workflows/ossf_scorecard.yml index b74a138f692..d9e065bf1e8 100644 --- a/.github/workflows/ossf_scorecard.yml +++ b/.github/workflows/ossf_scorecard.yml @@ -35,7 +35,7 @@ jobs: repo_token: ${{ secrets.SCORECARD_TOKEN }} # read-only fine-grained token to read branch protection settings - name: "Upload results" - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: SARIF file path: results.sarif diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 1dc6231b6a7..ded91ac4313 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -146,7 +146,7 @@ jobs: - name: zip output run: zip -r cdk.out.zip cdk.out - name: Archive CDK artifacts - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: cdk-layer-artefact path: layer/cdk.out.zip diff --git a/.github/workflows/record_pr.yml b/.github/workflows/record_pr.yml index b74dd4b4ee0..ddfd7c249a3 100644 --- a/.github/workflows/record_pr.yml +++ b/.github/workflows/record_pr.yml @@ -53,7 +53,7 @@ jobs: script: | const script = require('.github/scripts/save_pr_details.js') await script({github, context, core}) - - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + - uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: pr path: pr.txt diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index e9d9d65aff6..7a217d0a11c 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -197,11 +197,12 @@ jobs: cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt - name: Save Layer ARN artifact if: ${{ inputs.stage == 'PROD' }} - uses: actions/upload-artifact@a8a3f3ad30e3422c9c7b888a15615d19a852ae32 # v3.1.3 + uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: name: cdk-layer-stack path: ./layer/cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting. if-no-files-found: error retention-days: 1 + overwrite: true - name: CDK Deploy Canary run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters DeployStage="${{ inputs.stage }}" --parameters HasARM64Support=${{ matrix.has_arm64_support }} 'CanaryV2Stack' --require-approval never --verbose From 8e8fb27976c9834e65ab79d4e92d4c6ea8c3105d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 13:43:17 +0000 Subject: [PATCH 0060/2666] chore(deps-dev): bump pytest from 7.4.4 to 8.0.0 (#3711) Bumps [pytest](https://github.com/pytest-dev/pytest) from 7.4.4 to 8.0.0. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/7.4.4...8.0.0) --- updated-dependencies: - dependency-name: pytest dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- poetry.lock | 20 ++++++++++---------- pyproject.toml | 2 +- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/poetry.lock b/poetry.lock index 0b970ab555a..a03eb23032c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2129,13 +2129,13 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co [[package]] name = "pluggy" -version = "1.2.0" +version = "1.4.0" description = "plugin and hook calling mechanisms for python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pluggy-1.2.0-py3-none-any.whl", hash = "sha256:c2fd55a7d7a3863cba1a013e4e2414658b1d07b6bc57b3919e0c63c9abb99849"}, - {file = "pluggy-1.2.0.tar.gz", hash = "sha256:d12f0c4b579b15f5e054301bb226ee85eeeba08ffec228092f8defbaa3a4c4b3"}, + {file = "pluggy-1.4.0-py3-none-any.whl", hash = "sha256:7db9f7b503d67d1c5b95f59773ebb58a8c1c288129a88665838012cfb07b8981"}, + {file = "pluggy-1.4.0.tar.gz", hash = "sha256:8c85c2876142a764e5b7548e7d9a0e0ddb46f5185161049a79b7e974454223be"}, ] [package.extras] @@ -2342,13 +2342,13 @@ files = [ [[package]] name = "pytest" -version = "7.4.4" +version = "8.0.0" description = "pytest: simple powerful testing with Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" 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-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, + {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, ] [package.dependencies] @@ -2356,7 +2356,7 @@ colorama = {version = "*", markers = "sys_platform == \"win32\""} exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} iniconfig = "*" packaging = "*" -pluggy = ">=0.12,<2.0" +pluggy = ">=1.3.0,<2.0" tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} [package.extras] @@ -3329,4 +3329,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = "^3.7.4" -content-hash = "1f6979025f2fa294a718f2eb2356cc02a0a8af15e867a4f9abf2ec6bed985a8a" +content-hash = "9e53f4ad2478f560e40ee3d0f4347c68cf1539f7d34b3c01f4e7b80a6b7d96c3" diff --git a/pyproject.toml b/pyproject.toml index 1802c718ec2..5c876c10f07 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] coverage = {extras = ["toml"], version = "^7.4"} -pytest = "^7.4.4" +pytest = "^8.0.0" black = "^23.3" boto3 = "^1.26.164" isort = "^5.11.5" From ada8156ea46015da4a449ee4425eaa59078750d2 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Tue, 6 Feb 2024 15:40:10 +0000 Subject: [PATCH 0061/2666] chore(ci): enable Redis e2e tests (#3718) Enabling Redis e2e tests --- poetry.lock | 60 ++++++++----------------- pyproject.toml | 1 + tests/e2e/idempotency_redis/conftest.py | 9 +++- 3 files changed, 27 insertions(+), 43 deletions(-) diff --git a/poetry.lock b/poetry.lock index a03eb23032c..37da2e39fba 100644 --- a/poetry.lock +++ b/poetry.lock @@ -53,17 +53,17 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p [[package]] name = "aws-cdk-asset-awscli-v1" -version = "2.2.201" +version = "2.2.202" description = "A library that contains the AWS CLI for use in Lambda Layers" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk.asset-awscli-v1-2.2.201.tar.gz", hash = "sha256:88d1c269fd5cf8c9f6e0464ed22e2d4f269dfd5b36b8c4d37687bdba9c269839"}, - {file = "aws_cdk.asset_awscli_v1-2.2.201-py3-none-any.whl", hash = "sha256:56fe2ef91d3c8d33559aa32d2130e5f35f23af1fb82f06648ebbc82ffe0a5879"}, + {file = "aws-cdk.asset-awscli-v1-2.2.202.tar.gz", hash = "sha256:3ef87d6530736b3a7b0f777fe3b4297994dd40c3ce9306d95f80f48fb18036e8"}, + {file = "aws_cdk.asset_awscli_v1-2.2.202-py3-none-any.whl", hash = "sha256:96205ea2e5e132ec52fabfff37ea25b9b859498f167d05b32564c949822cd331"}, ] [package.dependencies] -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.93.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -157,21 +157,21 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.111.0" +version = "2.126.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk-lib-2.111.0.tar.gz", hash = "sha256:60a0adaddad146ca682ded4762cb2665b11a095f2d9c2ad84a33ff8f473da161"}, - {file = "aws_cdk_lib-2.111.0-py3-none-any.whl", hash = "sha256:f73174509eb89528a4bcbd50b40dd228120c8bced8089031e72148031ee605a3"}, + {file = "aws-cdk-lib-2.126.0.tar.gz", hash = "sha256:291f9a15fb45f1461644ffa2ff360c8c2ed2797ac29082655252de291fa04333"}, + {file = "aws_cdk_lib-2.126.0-py3-none-any.whl", hash = "sha256:8e00c0a3bfe8f5c20d305d149df251b8fbf292aa7e74df0765ba47fdbbec82d6"}, ] [package.dependencies] -"aws-cdk.asset-awscli-v1" = ">=2.2.201,<3.0.0" +"aws-cdk.asset-awscli-v1" = ">=2.2.202,<3.0.0" "aws-cdk.asset-kubectl-v20" = ">=2.1.2,<3.0.0" "aws-cdk.asset-node-proxy-agent-v6" = ">=2.0.1,<3.0.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.94.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -1222,17 +1222,6 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, - {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, - {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1402,23 +1391,23 @@ pbr = "*" [[package]] name = "jsii" -version = "1.91.0" +version = "1.94.0" description = "Python client for jsii runtime" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "jsii-1.91.0-py3-none-any.whl", hash = "sha256:2905a4ea030ae7289b859e97003c01f4569650b4865c51e7f83d975b95c5b20a"}, - {file = "jsii-1.91.0.tar.gz", hash = "sha256:9600ac7d04b237ee229c74ffde65ece27202ceec5df5e7eebd88a532d2cb28d6"}, + {file = "jsii-1.94.0-py3-none-any.whl", hash = "sha256:1105bae271ae47c27cf31c1565c5157306efed5ad9323c9a27336f962f465716"}, + {file = "jsii-1.94.0.tar.gz", hash = "sha256:175abc356603d98f18ab6f6aa74bfeae253e4e56340aef9dc40bbb1a6a59868b"}, ] [package.dependencies] attrs = ">=21.2,<24.0" -cattrs = ">=1.8,<23.2" +cattrs = ">=1.8,<23.3" importlib-resources = ">=5.2.0" publication = ">=0.0.3" python-dateutil = "*" typeguard = ">=2.13.3,<2.14.0" -typing-extensions = ">=3.7,<5.0" +typing-extensions = ">=3.8,<5.0" [[package]] name = "jsonpatch" @@ -2529,7 +2518,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2537,16 +2525,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2563,7 +2543,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2571,7 +2550,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3328,5 +3306,5 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" -python-versions = "^3.7.4" -content-hash = "9e53f4ad2478f560e40ee3d0f4347c68cf1539f7d34b3c01f4e7b80a6b7d96c3" +python-versions = ">=3.8,<4.0.0" +content-hash = "dd48516b189bd9d5b28daf78b91917ac30dcb75e8591aaf27e2f1a2da430d22c" diff --git a/pyproject.toml b/pyproject.toml index 5c876c10f07..baeee34f5f0 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -48,6 +48,7 @@ typing-extensions = "^4.6.2" datadog-lambda = { version = ">=4.77,<6.0", optional = true } aws-encryption-sdk = { version = "^3.1.1", optional = true } jsonpath-ng = { version = "^1.6.0", optional = true } +aws-cdk-lib = "^2.126.0" [tool.poetry.dev-dependencies] coverage = {extras = ["toml"], version = "^7.4"} diff --git a/tests/e2e/idempotency_redis/conftest.py b/tests/e2e/idempotency_redis/conftest.py index 6f3183f02dd..0e12288fe9a 100644 --- a/tests/e2e/idempotency_redis/conftest.py +++ b/tests/e2e/idempotency_redis/conftest.py @@ -1,5 +1,7 @@ import pytest +from tests.e2e.idempotency_redis.infrastructure import IdempotencyRedisServerlessStack + @pytest.fixture(autouse=True, scope="package") def infrastructure(): @@ -11,5 +13,8 @@ def infrastructure(): CloudFormation Outputs from deployed infrastructure """ - # MAINTENANCE: Add the Stack constructor when Python 3.7 is dropped - return None + stack = IdempotencyRedisServerlessStack() + try: + yield stack.deploy() + finally: + stack.delete() From 1b3e78faa249c4895d675f4df7d57e74d2a94641 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:50:12 +0000 Subject: [PATCH 0062/2666] chore(deps-dev): bump types-python-dateutil from 2.8.19.14 to 2.8.19.20240106 (#3720) --- poetry.lock | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 37da2e39fba..96c159a0a0e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1222,6 +1222,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -2518,6 +2529,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2525,8 +2537,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2543,6 +2563,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2550,6 +2571,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3011,13 +3033,13 @@ cryptography = ">=35.0.0" [[package]] name = "types-python-dateutil" -version = "2.8.19.14" +version = "2.8.19.20240106" description = "Typing stubs for python-dateutil" optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "types-python-dateutil-2.8.19.14.tar.gz", hash = "sha256:1f4f10ac98bb8b16ade9dbee3518d9ace017821d94b057a425b069f834737f4b"}, - {file = "types_python_dateutil-2.8.19.14-py3-none-any.whl", hash = "sha256:f977b8de27787639986b4e28963263fd0e5158942b3ecef91b9335c130cb1ce9"}, + {file = "types-python-dateutil-2.8.19.20240106.tar.gz", hash = "sha256:1f8db221c3b98e6ca02ea83a58371b22c374f42ae5bbdf186db9c9a76581459f"}, + {file = "types_python_dateutil-2.8.19.20240106-py3-none-any.whl", hash = "sha256:efbbdc54590d0f16152fa103c9879c7d4a00e82078f6e2cf01769042165acaa2"}, ] [[package]] From 3694bcddade758c36d2247f0f7bfa747f523e2df Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:51:33 +0000 Subject: [PATCH 0063/2666] chore(deps): bump actions/download-artifact from 4.1.1 to 4.1.2 (#3725) --- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- .github/workflows/reusable_deploy_v2_sar.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index ded91ac4313..f9a5bded5e0 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -258,7 +258,7 @@ jobs: artifact_name: ${{ inputs.source_code_artifact_name }} - name: Download CDK layer artifact - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: cdk-layer-stack path: cdk-layer-stack/ diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index 7a217d0a11c..e0441015fe6 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -180,7 +180,7 @@ jobs: - name: install deps run: poetry install - name: Download artifact - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: ${{ inputs.artefact-name }} path: layer diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml index ef6a58f0aa2..8fc0480f319 100644 --- a/.github/workflows/reusable_deploy_v2_sar.yml +++ b/.github/workflows/reusable_deploy_v2_sar.yml @@ -115,7 +115,7 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} - name: Download artifact - uses: actions/download-artifact@6b208ae046db98c579e8a3aa621ab581ff575935 # v4.1.1 + uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: name: ${{ inputs.artefact-name }} - name: Unzip artefact From 818e53f2b4bedf8f62d45c46457c06727a5bd86c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 21:56:11 +0000 Subject: [PATCH 0064/2666] chore(deps-dev): bump cfn-lint from 0.83.8 to 0.85.0 (#3724) --- poetry.lock | 24 ++++++++++++------------ pyproject.toml | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/poetry.lock b/poetry.lock index 96c159a0a0e..2d571c76384 100644 --- a/poetry.lock +++ b/poetry.lock @@ -208,23 +208,23 @@ requests = ">=0.14.0" [[package]] name = "aws-sam-translator" -version = "1.82.0" +version = "1.84.0" description = "AWS SAM Translator is a library that transform SAM templates into AWS CloudFormation templates" optional = false -python-versions = ">=3.7, <=4.0, !=4.0" +python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "aws-sam-translator-1.82.0.tar.gz", hash = "sha256:f78e58194461635aef6255d04e82a9b690e331ca9fd669d1401bf7f9a93ae49f"}, - {file = "aws_sam_translator-1.82.0-py3-none-any.whl", hash = "sha256:29ba61f2a70b2b1cf0c76b92b78a23c7cdd19ea1b0a5992753180b56d040d20b"}, + {file = "aws-sam-translator-1.84.0.tar.gz", hash = "sha256:dbfd5669b5ef4bd7bc7af4775eec2ce4db61a2c2a17d721e67b51cf6a6dd63f9"}, + {file = "aws_sam_translator-1.84.0-py3-none-any.whl", hash = "sha256:a24f43e80095c79258a1f1c7a0b8169f55daf0b2bc237d5b9010b02ba86fa3bb"}, ] [package.dependencies] boto3 = ">=1.19.5,<2.dev0" jsonschema = ">=3.2,<5" pydantic = ">=1.8,<3" -typing-extensions = ">=4.4,<5" +typing-extensions = ">=4.4" [package.extras] -dev = ["black (==23.3.0)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.dev0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "importlib-metadata", "mypy (>=1.3.0,<1.4.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.0.284)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] +dev = ["black (==23.10.1)", "boto3 (>=1.23,<2)", "boto3-stubs[appconfig,serverlessrepo] (>=1.19.5,<2.dev0)", "coverage (>=5.3,<8)", "dateparser (>=1.1,<2.0)", "mypy (>=1.3.0,<1.4.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.1.0,<0.2.0)", "tenacity (>=8.0,<9.0)", "types-PyYAML (>=6.0,<7.0)", "types-jsonschema (>=3.2,<4.0)"] [[package]] name = "aws-xray-sdk" @@ -499,17 +499,17 @@ pycparser = "*" [[package]] name = "cfn-lint" -version = "0.83.8" +version = "0.85.0" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" optional = false -python-versions = ">=3.7, <=4.0, !=4.0" +python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.83.8.tar.gz", hash = "sha256:fbbe31925d78cb9373b160d944ba30cafc085dcd256a3c30139004ef96482154"}, - {file = "cfn_lint-0.83.8-py3-none-any.whl", hash = "sha256:e53b81095e21f0be76de9dc303ddc0290a5eb1ef78173cf3cbc1b6cce9b2dd22"}, + {file = "cfn-lint-0.85.0.tar.gz", hash = "sha256:64d6e8d85cdc573b61add78f9ff95a142a1834edb4793d1291551f6d953f73fe"}, + {file = "cfn_lint-0.85.0-py3-none-any.whl", hash = "sha256:e4849e1779bd1a9f4543617372708a20519b6d7cad5f980e20c6deaa227361a2"}, ] [package.dependencies] -aws-sam-translator = ">=1.82.0" +aws-sam-translator = ">=1.83.0" jschema-to-python = ">=1.2.3,<1.3.0" jsonpatch = "*" jsonschema = ">=3.0,<5" @@ -3329,4 +3329,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "dd48516b189bd9d5b28daf78b91917ac30dcb75e8591aaf27e2f1a2da430d22c" +content-hash = "db50c6e0d3bb94db558aef5220d8f06c42af3d5772e32de19250970448b0531c" diff --git a/pyproject.toml b/pyproject.toml index baeee34f5f0..b2260d4c232 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -105,7 +105,7 @@ datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.83.8" +cfn-lint = "0.85.0" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.27.0" From 529dca8e28c35e156c3df44a9232fc971b19b4d5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 6 Feb 2024 22:10:23 +0000 Subject: [PATCH 0065/2666] chore(deps-dev): bump isort from 5.11.5 to 5.13.2 (#3723) --- poetry.lock | 15 ++++++--------- pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/poetry.lock b/poetry.lock index 2d571c76384..b62788f35fa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1341,20 +1341,17 @@ files = [ [[package]] name = "isort" -version = "5.11.5" +version = "5.13.2" description = "A Python utility / library to sort Python imports." optional = false -python-versions = ">=3.7.0" +python-versions = ">=3.8.0" files = [ - {file = "isort-5.11.5-py3-none-any.whl", hash = "sha256:ba1d72fb2595a01c7895a5128f9585a5cc4b6d395f1c8d514989b9a7eb2a8746"}, - {file = "isort-5.11.5.tar.gz", hash = "sha256:6be1f76a507cb2ecf16c7cf14a37e41609ca082330be4e3436a18ef74add55db"}, + {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, + {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, ] [package.extras] -colors = ["colorama (>=0.4.3,<0.5.0)"] -pipfile-deprecated-finder = ["pip-shims (>=0.5.2)", "pipreqs", "requirementslib"] -plugins = ["setuptools"] -requirements-deprecated-finder = ["pip-api", "pipreqs"] +colors = ["colorama (>=0.4.6)"] [[package]] name = "jinja2" @@ -3329,4 +3326,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "db50c6e0d3bb94db558aef5220d8f06c42af3d5772e32de19250970448b0531c" +content-hash = "1eb623d82065a5ab34897f92712b38bb28e8d316ed307a38ece0427a58d80545" diff --git a/pyproject.toml b/pyproject.toml index b2260d4c232..36767102e12 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -55,7 +55,7 @@ coverage = {extras = ["toml"], version = "^7.4"} pytest = "^8.0.0" black = "^23.3" boto3 = "^1.26.164" -isort = "^5.11.5" +isort = "^5.13.2" pytest-cov = "^4.1.0" pytest-mock = "^3.11.1" pdoc3 = "^0.10.0" From 2fc51a5ce4f19859638fc535588611dc66216343 Mon Sep 17 00:00:00 2001 From: Ran Isenberg <60175085+ran-isenberg@users.noreply.github.com> Date: Wed, 7 Feb 2024 11:01:06 +0200 Subject: [PATCH 0066/2666] docs: Add nathan hanks post community (#3727) Co-authored-by: Ran Isenberg --- docs/we_made_this.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/we_made_this.md b/docs/we_made_this.md index 74d68e29227..d57a0b7325c 100644 --- a/docs/we_made_this.md +++ b/docs/we_made_this.md @@ -104,6 +104,14 @@ This blog post showcases how to use AWS CDK and Powertools for AWS Lambda, along [Creating a serverless API using Powertools for AWS Lambda and CDK](https://how.wtf/creating-a-serverless-api-using-aws-lambda-powertools-and-cdk.html){target="_blank" rel="nofollow"} +### Boost App Engagement with AWS CloudWatch Metrics & Powertools for AWS + +This article will guide you through personalizing observability by integrating CloudWatch metrics with Powertools for AWS Lambda into mobile push notifications, a strategy that significantly enhances mobile app engagement + +> **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"} + ## Videos #### Building a resilient input handling with Parser From 3a02a4fefff9aeec7c28728a68e63cc2ba7deb78 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:43:53 +0100 Subject: [PATCH 0067/2666] chore(ci): changelog rebuild (#3728) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Heitor Lessa --- CHANGELOG.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bceb7116d0..e777c9a4daf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,16 +7,24 @@ ## Maintenance * **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) +* **ci:** enable Redis e2e tests ([#3718](https://github.com/aws-powertools/powertools-lambda-python/issues/3718)) * **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) +* **deps:** bump actions/upload-artifact from 3.1.3 to 4.3.1 ([#3714](https://github.com/aws-powertools/powertools-lambda-python/issues/3714)) +* **deps:** bump actions/download-artifact from 4.1.1 to 4.1.2 ([#3725](https://github.com/aws-powertools/powertools-lambda-python/issues/3725)) * **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) +* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) * **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) * **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) -* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) * **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) * **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) +* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) +* **deps-dev:** bump mypy from 1.4.1 to 1.8.0 ([#3710](https://github.com/aws-powertools/powertools-lambda-python/issues/3710)) +* **deps-dev:** bump pytest from 7.4.4 to 8.0.0 ([#3711](https://github.com/aws-powertools/powertools-lambda-python/issues/3711)) +* **deps-dev:** bump types-python-dateutil from 2.8.19.14 to 2.8.19.20240106 ([#3720](https://github.com/aws-powertools/powertools-lambda-python/issues/3720)) * **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) * **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) -* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) +* **deps-dev:** bump cfn-lint from 0.83.8 to 0.85.0 ([#3724](https://github.com/aws-powertools/powertools-lambda-python/issues/3724)) +* **deps-dev:** bump isort from 5.11.5 to 5.13.2 ([#3723](https://github.com/aws-powertools/powertools-lambda-python/issues/3723)) From 7ec4a13e541991f495587c0c05d3cc2acb0ae20c Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 7 Feb 2024 11:51:36 +0100 Subject: [PATCH 0068/2666] chore(deps): revert aws-cdk-lib as a runtime dep (#3730) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * chore(deps): revert aws-cdk-lib as dev dependency Signed-off-by: heitorlessa --------- Signed-off-by: heitorlessa --- poetry.lock | 1197 ++++++++++++++++++++++++++---------------------- pyproject.toml | 19 +- 2 files changed, 649 insertions(+), 567 deletions(-) diff --git a/poetry.lock b/poetry.lock index b62788f35fa..947f35da799 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2,24 +2,25 @@ [[package]] name = "anyio" -version = "3.7.1" +version = "4.2.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "anyio-3.7.1-py3-none-any.whl", hash = "sha256:91dee416e570e92c64041bd18b900d1d6fa78dff7048769ce5ac5ddad004fbb5"}, - {file = "anyio-3.7.1.tar.gz", hash = "sha256:44a3c9aba0f5defa43261a8b3efb97891f2bd7d804e0e1f56419befa1adfc780"}, + {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, + {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, ] [package.dependencies] -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} +exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} idna = ">=2.8" sniffio = ">=1.1" +typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} [package.extras] -doc = ["Sphinx", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme (>=1.2.2)", "sphinxcontrib-jquery"] -test = ["anyio[trio]", "coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "mock (>=4)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (<0.22)"] +doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] +test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] +trio = ["trio (>=0.23)"] [[package]] name = "async-timeout" @@ -101,57 +102,57 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-alpha" -version = "2.111.0a0" -description = "The CDK Construct Library for AWS::APIGatewayv2" +version = "2.114.1a0" +description = "This module is deprecated. All constructs are now available under aws-cdk-lib/aws-apigatewayv2" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk.aws-apigatewayv2-alpha-2.111.0a0.tar.gz", hash = "sha256:f5692aca2806cb289ba669f33fd245062e1b350da94c8d86dea788b9a397d49f"}, - {file = "aws_cdk.aws_apigatewayv2_alpha-2.111.0a0-py3-none-any.whl", hash = "sha256:a8e125a88cd0c1f39732e32100d41a17b23ed81b86019a56e450c358b6f28f03"}, + {file = "aws-cdk.aws-apigatewayv2-alpha-2.114.1a0.tar.gz", hash = "sha256:9e8c3131f4fa3e0926eb3d76aeacd578a6aa51f95b39c10a86112c991bb75864"}, + {file = "aws_cdk.aws_apigatewayv2_alpha-2.114.1a0-py3-none-any.whl", hash = "sha256:a101ce56d846976ad1c8020054dfe73fd9f45afdbe71f2a297acc84c1a201403"}, ] [package.dependencies] -aws-cdk-lib = ">=2.111.0,<3.0.0" +aws-cdk-lib = ">=2.114.1,<3.0.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.92.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-authorizers-alpha" -version = "2.111.0a0" -description = "Authorizers for AWS APIGateway V2" +version = "2.114.1a0" +description = "This module is deprecated. All constructs are now available under aws-cdk-lib/aws-apigatewayv2-authorizers" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.111.0a0.tar.gz", hash = "sha256:8380f9c59019874b0c20374b951c96b2a7b670ad544caca318ce7f7524010046"}, - {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.111.0a0-py3-none-any.whl", hash = "sha256:833791d3377f529e0faae67da1f26c4c892faf9f317ca749f99c3a1ced01b1de"}, + {file = "aws-cdk.aws-apigatewayv2-authorizers-alpha-2.114.1a0.tar.gz", hash = "sha256:ee290e2ed0f1506dbbb12b3b8963f50b379121759077002c265977fbaf18fd9f"}, + {file = "aws_cdk.aws_apigatewayv2_authorizers_alpha-2.114.1a0-py3-none-any.whl", hash = "sha256:2576e1ce06dab314020bff50f5d59b8715a7adf18106eac811028c22f61c9baa"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.111.0.a0" -aws-cdk-lib = ">=2.111.0,<3.0.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1.a0" +aws-cdk-lib = ">=2.114.1,<3.0.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.92.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-aws-apigatewayv2-integrations-alpha" -version = "2.111.0a0" -description = "Integrations for AWS APIGateway V2" +version = "2.114.1a0" +description = "This module is deprecated. All constructs are now available under aws-cdk-lib/aws-apigatewayv2-integrations" optional = false -python-versions = "~=3.7" +python-versions = "~=3.8" files = [ - {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.111.0a0.tar.gz", hash = "sha256:6f365c0fe5b9b6fce5ffb34ebfb04f54d882afa2b57402ce317b97c8511fe671"}, - {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.111.0a0-py3-none-any.whl", hash = "sha256:d67c5c78fe5bd160916e8d05afec1b1a212865376e73985d844e6eeb10c779d3"}, + {file = "aws-cdk.aws-apigatewayv2-integrations-alpha-2.114.1a0.tar.gz", hash = "sha256:19e1824b577683e7d3c2b01fd58c176ebe4c7b8d1b4af4cfdc3893d3ffbac9af"}, + {file = "aws_cdk.aws_apigatewayv2_integrations_alpha-2.114.1a0-py3-none-any.whl", hash = "sha256:1e440a70e6b4cbe077c95ffdd3fd0cfb3962f90762ea2e973eaa2ab7719ccb2c"}, ] [package.dependencies] -"aws-cdk.aws-apigatewayv2-alpha" = "2.111.0.a0" -aws-cdk-lib = ">=2.111.0,<3.0.0" +"aws-cdk.aws-apigatewayv2-alpha" = "2.114.1.a0" +aws-cdk-lib = ">=2.114.1,<3.0.0" constructs = ">=10.0.0,<11.0.0" -jsii = ">=1.91.0,<2.0.0" +jsii = ">=1.92.0,<2.0.0" publication = ">=0.0.3" typeguard = ">=2.13.3,<2.14.0" @@ -260,59 +261,56 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] [[package]] name = "bandit" -version = "1.7.5" +version = "1.7.7" description = "Security oriented static analyser for python code." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "bandit-1.7.5-py3-none-any.whl", hash = "sha256:75665181dc1e0096369112541a056c59d1c5f66f9bb74a8d686c3c362b83f549"}, - {file = "bandit-1.7.5.tar.gz", hash = "sha256:bdfc739baa03b880c2d15d0431b31c658ffc348e907fe197e54e0389dd59e11e"}, + {file = "bandit-1.7.7-py3-none-any.whl", hash = "sha256:17e60786a7ea3c9ec84569fd5aee09936d116cb0cb43151023258340dbffb7ed"}, + {file = "bandit-1.7.7.tar.gz", hash = "sha256:527906bec6088cb499aae31bc962864b4e77569e9d529ee51df3a93b4b8ab28a"}, ] [package.dependencies] colorama = {version = ">=0.3.9", markers = "platform_system == \"Windows\""} -GitPython = ">=1.0.1" PyYAML = ">=5.3.1" rich = "*" stevedore = ">=1.20.0" [package.extras] -test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)", "tomli (>=1.1.0)"] +baseline = ["GitPython (>=3.1.30)"] +test = ["beautifulsoup4 (>=4.8.0)", "coverage (>=4.5.4)", "fixtures (>=3.0.0)", "flake8 (>=4.0.0)", "pylint (==1.9.4)", "stestr (>=2.5.0)", "testscenarios (>=0.5.0)", "testtools (>=2.3.0)"] toml = ["tomli (>=1.1.0)"] yaml = ["PyYAML"] [[package]] name = "black" -version = "23.3.0" +version = "23.12.1" description = "The uncompromising code formatter." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "black-23.3.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:0945e13506be58bf7db93ee5853243eb368ace1c08a24c65ce108986eac65915"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_universal2.whl", hash = "sha256:67de8d0c209eb5b330cce2469503de11bca4085880d62f1628bd9972cc3366b9"}, - {file = "black-23.3.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:7c3eb7cea23904399866c55826b31c1f55bbcd3890ce22ff70466b907b6775c2"}, - {file = "black-23.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32daa9783106c28815d05b724238e30718f34155653d4d6e125dc7daec8e260c"}, - {file = "black-23.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:35d1381d7a22cc5b2be2f72c7dfdae4072a3336060635718cc7e1ede24221d6c"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:a8a968125d0a6a404842fa1bf0b349a568634f856aa08ffaff40ae0dfa52e7c6"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_universal2.whl", hash = "sha256:c7ab5790333c448903c4b721b59c0d80b11fe5e9803d8703e84dcb8da56fec1b"}, - {file = "black-23.3.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:a6f6886c9869d4daae2d1715ce34a19bbc4b95006d20ed785ca00fa03cba312d"}, - {file = "black-23.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f3c333ea1dd6771b2d3777482429864f8e258899f6ff05826c3a4fcc5ce3f70"}, - {file = "black-23.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:11c410f71b876f961d1de77b9699ad19f939094c3a677323f43d7a29855fe326"}, - {file = "black-23.3.0-cp37-cp37m-macosx_10_16_x86_64.whl", hash = "sha256:1d06691f1eb8de91cd1b322f21e3bfc9efe0c7ca1f0e1eb1db44ea367dff656b"}, - {file = "black-23.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50cb33cac881766a5cd9913e10ff75b1e8eb71babf4c7104f2e9c52da1fb7de2"}, - {file = "black-23.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:e114420bf26b90d4b9daa597351337762b63039752bdf72bf361364c1aa05925"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:48f9d345675bb7fbc3dd85821b12487e1b9a75242028adad0333ce36ed2a6d27"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_universal2.whl", hash = "sha256:714290490c18fb0126baa0fca0a54ee795f7502b44177e1ce7624ba1c00f2331"}, - {file = "black-23.3.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:064101748afa12ad2291c2b91c960be28b817c0c7eaa35bec09cc63aa56493c5"}, - {file = "black-23.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:562bd3a70495facf56814293149e51aa1be9931567474993c7942ff7d3533961"}, - {file = "black-23.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:e198cf27888ad6f4ff331ca1c48ffc038848ea9f031a3b40ba36aced7e22f2c8"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:3238f2aacf827d18d26db07524e44741233ae09a584273aa059066d644ca7b30"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_universal2.whl", hash = "sha256:f0bd2f4a58d6666500542b26354978218a9babcdc972722f4bf90779524515f3"}, - {file = "black-23.3.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:92c543f6854c28a3c7f39f4d9b7694f9a6eb9d3c5e2ece488c327b6e7ea9b266"}, - {file = "black-23.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a150542a204124ed00683f0db1f5cf1c2aaaa9cc3495b7a3b5976fb136090ab"}, - {file = "black-23.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:6b39abdfb402002b8a7d030ccc85cf5afff64ee90fa4c5aebc531e3ad0175ddb"}, - {file = "black-23.3.0-py3-none-any.whl", hash = "sha256:ec751418022185b0c1bb7d7736e6933d40bbb14c14a0abcf9123d1b159f98dd4"}, - {file = "black-23.3.0.tar.gz", hash = "sha256:1c7b8d606e728a41ea1ccbd7264677e494e87cf630e399262ced92d4a8dac940"}, + {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, + {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, + {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, + {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, + {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, + {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, + {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, + {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, + {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, + {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, + {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, + {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, + {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, + {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, + {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, + {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, + {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, + {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, + {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, + {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, + {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, + {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, ] [package.dependencies] @@ -322,42 +320,42 @@ packaging = ">=22.0" pathspec = ">=0.9.0" platformdirs = ">=2" tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} +typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""} [package.extras] colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] +d = ["aiohttp (>=3.7.4)", "aiohttp (>=3.7.4,!=3.9.0)"] jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.33.13" +version = "1.34.36" description = "The AWS SDK for Python" optional = false -python-versions = ">= 3.7" +python-versions = ">= 3.8" files = [ - {file = "boto3-1.33.13-py3-none-any.whl", hash = "sha256:5f278b95fb2b32f3d09d950759a05664357ba35d81107bab1537c4ddd212cd8c"}, - {file = "boto3-1.33.13.tar.gz", hash = "sha256:0e966b8a475ecb06cc0846304454b8da2473d4c8198a45dfb2c5304871986883"}, + {file = "boto3-1.34.36-py3-none-any.whl", hash = "sha256:1e38a4ea4bb8bc66fbb858abb411820709fda5d6c5604c2da0f696653d49c684"}, + {file = "boto3-1.34.36.tar.gz", hash = "sha256:7ec36deb7ccc9c4943510692303cf93883ef61dc2c79f8bd4d75ee42209559d3"}, ] [package.dependencies] -botocore = ">=1.33.13,<1.34.0" +botocore = ">=1.34.36,<1.35.0" jmespath = ">=0.7.1,<2.0.0" -s3transfer = ">=0.8.2,<0.9.0" +s3transfer = ">=0.10.0,<0.11.0" [package.extras] crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.33.13" +version = "1.34.36" description = "Low-level, data-driven core of boto 3." optional = false -python-versions = ">= 3.7" +python-versions = ">= 3.8" files = [ - {file = "botocore-1.33.13-py3-none-any.whl", hash = "sha256:aeadccf4b7c674c7d47e713ef34671b834bc3e89723ef96d994409c9f54666e6"}, - {file = "botocore-1.33.13.tar.gz", hash = "sha256:fb577f4cb175605527458b04571451db1bd1a2036976b626206036acd4496617"}, + {file = "botocore-1.34.36-py3-none-any.whl", hash = "sha256:3f39ae0165f1a27f621fc91a46fb59f87e819671fad106c230dadcc724892f70"}, + {file = "botocore-1.34.36.tar.gz", hash = "sha256:89c3dc15b6ffae146029df636d51b9952740051204c444ec765286b081c917bc"}, ] [package.dependencies] @@ -369,7 +367,7 @@ urllib3 = [ ] [package.extras] -crt = ["awscrt (==0.19.17)"] +crt = ["awscrt (==0.19.19)"] [[package]] name = "bytecode" @@ -387,111 +385,99 @@ typing-extensions = {version = "*", markers = "python_version < \"3.10\""} [[package]] name = "cattrs" -version = "23.1.2" +version = "23.2.3" description = "Composable complex class support for attrs and dataclasses." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "cattrs-23.1.2-py3-none-any.whl", hash = "sha256:b2bb14311ac17bed0d58785e5a60f022e5431aca3932e3fc5cc8ed8639de50a4"}, - {file = "cattrs-23.1.2.tar.gz", hash = "sha256:db1c821b8c537382b2c7c66678c3790091ca0275ac486c76f3c8f3920e83c657"}, + {file = "cattrs-23.2.3-py3-none-any.whl", hash = "sha256:0341994d94971052e9ee70662542699a3162ea1e0c62f7ce1b4a57f563685108"}, + {file = "cattrs-23.2.3.tar.gz", hash = "sha256:a934090d95abaa9e911dac357e3a8699e0b4b14f8529bcc7d2b1ad9d51672b9f"}, ] [package.dependencies] -attrs = ">=20" -exceptiongroup = {version = "*", markers = "python_version < \"3.11\""} -typing_extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""} +attrs = ">=23.1.0" +exceptiongroup = {version = ">=1.1.1", markers = "python_version < \"3.11\""} +typing-extensions = {version = ">=4.1.0,<4.6.3 || >4.6.3", markers = "python_version < \"3.11\""} [package.extras] -bson = ["pymongo (>=4.2.0,<5.0.0)"] -cbor2 = ["cbor2 (>=5.4.6,<6.0.0)"] -msgpack = ["msgpack (>=1.0.2,<2.0.0)"] -orjson = ["orjson (>=3.5.2,<4.0.0)"] -pyyaml = ["PyYAML (>=6.0,<7.0)"] -tomlkit = ["tomlkit (>=0.11.4,<0.12.0)"] -ujson = ["ujson (>=5.4.0,<6.0.0)"] +bson = ["pymongo (>=4.4.0)"] +cbor2 = ["cbor2 (>=5.4.6)"] +msgpack = ["msgpack (>=1.0.5)"] +orjson = ["orjson (>=3.9.2)"] +pyyaml = ["pyyaml (>=6.0)"] +tomlkit = ["tomlkit (>=0.11.8)"] +ujson = ["ujson (>=5.7.0)"] [[package]] name = "certifi" -version = "2023.11.17" +version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2023.11.17-py3-none-any.whl", hash = "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474"}, - {file = "certifi-2023.11.17.tar.gz", hash = "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1"}, + {file = "certifi-2024.2.2-py3-none-any.whl", hash = "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1"}, + {file = "certifi-2024.2.2.tar.gz", hash = "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f"}, ] [[package]] name = "cffi" -version = "1.15.1" +version = "1.16.0" description = "Foreign Function Interface for Python calling C code." optional = false -python-versions = "*" +python-versions = ">=3.8" files = [ - {file = "cffi-1.15.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:a66d3508133af6e8548451b25058d5812812ec3798c886bf38ed24a98216fab2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:470c103ae716238bbe698d67ad020e1db9d9dba34fa5a899b5e21577e6d52ed2"}, - {file = "cffi-1.15.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:9ad5db27f9cabae298d151c85cf2bad1d359a1b9c686a275df03385758e2f914"}, - {file = "cffi-1.15.1-cp27-cp27m-win32.whl", hash = "sha256:b3bbeb01c2b273cca1e1e0c5df57f12dce9a4dd331b4fa1635b8bec26350bde3"}, - {file = "cffi-1.15.1-cp27-cp27m-win_amd64.whl", hash = "sha256:e00b098126fd45523dd056d2efba6c5a63b71ffe9f2bbe1a4fe1716e1d0c331e"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:d61f4695e6c866a23a21acab0509af1cdfd2c013cf256bbf5b6b5e2695827162"}, - {file = "cffi-1.15.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:ed9cb427ba5504c1dc15ede7d516b84757c3e3d7868ccc85121d9310d27eed0b"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:39d39875251ca8f612b6f33e6b1195af86d1b3e60086068be9cc053aa4376e21"}, - {file = "cffi-1.15.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:285d29981935eb726a4399badae8f0ffdff4f5050eaa6d0cfc3f64b857b77185"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3eb6971dcff08619f8d91607cfc726518b6fa2a9eba42856be181c6d0d9515fd"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:21157295583fe8943475029ed5abdcf71eb3911894724e360acff1d61c1d54bc"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5635bd9cb9731e6d4a1132a498dd34f764034a8ce60cef4f5319c0541159392f"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2012c72d854c2d03e45d06ae57f40d78e5770d252f195b93f581acf3ba44496e"}, - {file = "cffi-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd86c085fae2efd48ac91dd7ccffcfc0571387fe1193d33b6394db7ef31fe2a4"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:fa6693661a4c91757f4412306191b6dc88c1703f780c8234035eac011922bc01"}, - {file = "cffi-1.15.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:59c0b02d0a6c384d453fece7566d1c7e6b7bae4fc5874ef2ef46d56776d61c9e"}, - {file = "cffi-1.15.1-cp310-cp310-win32.whl", hash = "sha256:cba9d6b9a7d64d4bd46167096fc9d2f835e25d7e4c121fb2ddfc6528fb0413b2"}, - {file = "cffi-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:ce4bcc037df4fc5e3d184794f27bdaab018943698f4ca31630bc7f84a7b69c6d"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3d08afd128ddaa624a48cf2b859afef385b720bb4b43df214f85616922e6a5ac"}, - {file = "cffi-1.15.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3799aecf2e17cf585d977b780ce79ff0dc9b78d799fc694221ce814c2c19db83"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a591fe9e525846e4d154205572a029f653ada1a78b93697f3b5a8f1f2bc055b9"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3548db281cd7d2561c9ad9984681c95f7b0e38881201e157833a2342c30d5e8c"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:91fc98adde3d7881af9b59ed0294046f3806221863722ba7d8d120c575314325"}, - {file = "cffi-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:94411f22c3985acaec6f83c6df553f2dbe17b698cc7f8ae751ff2237d96b9e3c"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:03425bdae262c76aad70202debd780501fabeaca237cdfddc008987c0e0f59ef"}, - {file = "cffi-1.15.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cc4d65aeeaa04136a12677d3dd0b1c0c94dc43abac5860ab33cceb42b801c1e8"}, - {file = "cffi-1.15.1-cp311-cp311-win32.whl", hash = "sha256:a0f100c8912c114ff53e1202d0078b425bee3649ae34d7b070e9697f93c5d52d"}, - {file = "cffi-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:04ed324bda3cda42b9b695d51bb7d54b680b9719cfab04227cdd1e04e5de3104"}, - {file = "cffi-1.15.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50a74364d85fd319352182ef59c5c790484a336f6db772c1a9231f1c3ed0cbd7"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e263d77ee3dd201c3a142934a086a4450861778baaeeb45db4591ef65550b0a6"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:cec7d9412a9102bdc577382c3929b337320c4c4c4849f2c5cdd14d7368c5562d"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4289fc34b2f5316fbb762d75362931e351941fa95fa18789191b33fc4cf9504a"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:173379135477dc8cac4bc58f45db08ab45d228b3363adb7af79436135d028405"}, - {file = "cffi-1.15.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:6975a3fac6bc83c4a65c9f9fcab9e47019a11d3d2cf7f3c0d03431bf145a941e"}, - {file = "cffi-1.15.1-cp36-cp36m-win32.whl", hash = "sha256:2470043b93ff09bf8fb1d46d1cb756ce6132c54826661a32d4e4d132e1977adf"}, - {file = "cffi-1.15.1-cp36-cp36m-win_amd64.whl", hash = "sha256:30d78fbc8ebf9c92c9b7823ee18eb92f2e6ef79b45ac84db507f52fbe3ec4497"}, - {file = "cffi-1.15.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:198caafb44239b60e252492445da556afafc7d1e3ab7a1fb3f0584ef6d742375"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef34d190326c3b1f822a5b7a45f6c4535e2f47ed06fec77d3d799c450b2651e"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8102eaf27e1e448db915d08afa8b41d6c7ca7a04b7d73af6514df10a3e74bd82"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5df2768244d19ab7f60546d0c7c63ce1581f7af8b5de3eb3004b9b6fc8a9f84b"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a8c4917bd7ad33e8eb21e9a5bbba979b49d9a97acb3a803092cbc1133e20343c"}, - {file = "cffi-1.15.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2642fe3142e4cc4af0799748233ad6da94c62a8bec3a6648bf8ee68b1c7426"}, - {file = "cffi-1.15.1-cp37-cp37m-win32.whl", hash = "sha256:e229a521186c75c8ad9490854fd8bbdd9a0c9aa3a524326b55be83b54d4e0ad9"}, - {file = "cffi-1.15.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a0b71b1b8fbf2b96e41c4d990244165e2c9be83d54962a9a1d118fd8657d2045"}, - {file = "cffi-1.15.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:320dab6e7cb2eacdf0e658569d2575c4dad258c0fcc794f46215e1e39f90f2c3"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e74c6b51a9ed6589199c787bf5f9875612ca4a8a0785fb2d4a84429badaf22a"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5c84c68147988265e60416b57fc83425a78058853509c1b0629c180094904a5"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b926aa83d1edb5aa5b427b4053dc420ec295a08e40911296b9eb1b6170f6cca"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:87c450779d0914f2861b8526e035c5e6da0a3199d8f1add1a665e1cbc6fc6d02"}, - {file = "cffi-1.15.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f2c9f67e9821cad2e5f480bc8d83b8742896f1242dba247911072d4fa94c192"}, - {file = "cffi-1.15.1-cp38-cp38-win32.whl", hash = "sha256:8b7ee99e510d7b66cdb6c593f21c043c248537a32e0bedf02e01e9553a172314"}, - {file = "cffi-1.15.1-cp38-cp38-win_amd64.whl", hash = "sha256:00a9ed42e88df81ffae7a8ab6d9356b371399b91dbdf0c3cb1e84c03a13aceb5"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:54a2db7b78338edd780e7ef7f9f6c442500fb0d41a5a4ea24fff1c929d5af585"}, - {file = "cffi-1.15.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:fcd131dd944808b5bdb38e6f5b53013c5aa4f334c5cad0c72742f6eba4b73db0"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7473e861101c9e72452f9bf8acb984947aa1661a7704553a9f6e4baa5ba64415"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c9a799e985904922a4d207a94eae35c78ebae90e128f0c4e521ce339396be9d"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bcde07039e586f91b45c88f8583ea7cf7a0770df3a1649627bf598332cb6984"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33ab79603146aace82c2427da5ca6e58f2b3f2fb5da893ceac0c42218a40be35"}, - {file = "cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d598b938678ebf3c67377cdd45e09d431369c3b1a5b331058c338e201f12b27"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db0fbb9c62743ce59a9ff687eb5f4afbe77e5e8403d6697f7446e5f609976f76"}, - {file = "cffi-1.15.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:98d85c6a2bef81588d9227dde12db8a7f47f639f4a17c9ae08e773aa9c697bf3"}, - {file = "cffi-1.15.1-cp39-cp39-win32.whl", hash = "sha256:40f4774f5a9d4f5e344f31a32b5096977b5d48560c5592e2f3d2c4374bd543ee"}, - {file = "cffi-1.15.1-cp39-cp39-win_amd64.whl", hash = "sha256:70df4e3b545a17496c9b3f41f5115e69a4f2e77e94e1d2a8e1070bc0c38c8a3c"}, - {file = "cffi-1.15.1.tar.gz", hash = "sha256:d400bfb9a37b1351253cb402671cea7e89bdecc294e8016a707f6d1d8ac934f9"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6b3d6606d369fc1da4fd8c357d026317fbb9c9b75d36dc16e90e84c26854b088"}, + {file = "cffi-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ac0f5edd2360eea2f1daa9e26a41db02dd4b0451b48f7c318e217ee092a213e9"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e61e3e4fa664a8588aa25c883eab612a188c725755afff6289454d6362b9673"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a72e8961a86d19bdb45851d8f1f08b041ea37d2bd8d4fd19903bc3083d80c896"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b50bf3f55561dac5438f8e70bfcdfd74543fd60df5fa5f62d94e5867deca684"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7651c50c8c5ef7bdb41108b7b8c5a83013bfaa8a935590c5d74627c047a583c7"}, + {file = "cffi-1.16.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4108df7fe9b707191e55f33efbcb2d81928e10cea45527879a4749cbe472614"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:32c68ef735dbe5857c810328cb2481e24722a59a2003018885514d4c09af9743"}, + {file = "cffi-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:673739cb539f8cdaa07d92d02efa93c9ccf87e345b9a0b556e3ecc666718468d"}, + {file = "cffi-1.16.0-cp310-cp310-win32.whl", hash = "sha256:9f90389693731ff1f659e55c7d1640e2ec43ff725cc61b04b2f9c6d8d017df6a"}, + {file = "cffi-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:e6024675e67af929088fda399b2094574609396b1decb609c55fa58b028a32a1"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b84834d0cf97e7d27dd5b7f3aca7b6e9263c56308ab9dc8aae9784abb774d404"}, + {file = "cffi-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1b8ebc27c014c59692bb2664c7d13ce7a6e9a629be20e54e7271fa696ff2b417"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ee07e47c12890ef248766a6e55bd38ebfb2bb8edd4142d56db91b21ea68b7627"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8a9d3ebe49f084ad71f9269834ceccbf398253c9fac910c4fd7053ff1386936"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e70f54f1796669ef691ca07d046cd81a29cb4deb1e5f942003f401c0c4a2695d"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5bf44d66cdf9e893637896c7faa22298baebcd18d1ddb6d2626a6e39793a1d56"}, + {file = "cffi-1.16.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7b78010e7b97fef4bee1e896df8a4bbb6712b7f05b7ef630f9d1da00f6444d2e"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c6a164aa47843fb1b01e941d385aab7215563bb8816d80ff3a363a9f8448a8dc"}, + {file = "cffi-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e09f3ff613345df5e8c3667da1d918f9149bd623cd9070c983c013792a9a62eb"}, + {file = "cffi-1.16.0-cp311-cp311-win32.whl", hash = "sha256:2c56b361916f390cd758a57f2e16233eb4f64bcbeee88a4881ea90fca14dc6ab"}, + {file = "cffi-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:db8e577c19c0fda0beb7e0d4e09e0ba74b1e4c092e0e40bfa12fe05b6f6d75ba"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:fa3a0128b152627161ce47201262d3140edb5a5c3da88d73a1b790a959126956"}, + {file = "cffi-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:68e7c44931cc171c54ccb702482e9fc723192e88d25a0e133edd7aff8fcd1f6e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abd808f9c129ba2beda4cfc53bde801e5bcf9d6e0f22f095e45327c038bfe68e"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88e2b3c14bdb32e440be531ade29d3c50a1a59cd4e51b1dd8b0865c54ea5d2e2"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fcc8eb6d5902bb1cf6dc4f187ee3ea80a1eba0a89aba40a5cb20a5087d961357"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b7be2d771cdba2942e13215c4e340bfd76398e9227ad10402a8767ab1865d2e6"}, + {file = "cffi-1.16.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e715596e683d2ce000574bae5d07bd522c781a822866c20495e52520564f0969"}, + {file = "cffi-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2d92b25dbf6cae33f65005baf472d2c245c050b1ce709cc4588cdcdd5495b520"}, + {file = "cffi-1.16.0-cp312-cp312-win32.whl", hash = "sha256:b2ca4e77f9f47c55c194982e10f058db063937845bb2b7a86c84a6cfe0aefa8b"}, + {file = "cffi-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:68678abf380b42ce21a5f2abde8efee05c114c2fdb2e9eef2efdb0257fba1235"}, + {file = "cffi-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0c9ef6ff37e974b73c25eecc13952c55bceed9112be2d9d938ded8e856138bcc"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a09582f178759ee8128d9270cd1344154fd473bb77d94ce0aeb2a93ebf0feaf0"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e760191dd42581e023a68b758769e2da259b5d52e3103c6060ddc02c9edb8d7b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:80876338e19c951fdfed6198e70bc88f1c9758b94578d5a7c4c91a87af3cf31c"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a6a14b17d7e17fa0d207ac08642c8820f84f25ce17a442fd15e27ea18d67c59b"}, + {file = "cffi-1.16.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6602bc8dc6f3a9e02b6c22c4fc1e47aa50f8f8e6d3f78a5e16ac33ef5fefa324"}, + {file = "cffi-1.16.0-cp38-cp38-win32.whl", hash = "sha256:131fd094d1065b19540c3d72594260f118b231090295d8c34e19a7bbcf2e860a"}, + {file = "cffi-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:31d13b0f99e0836b7ff893d37af07366ebc90b678b6664c955b54561fc36ef36"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:582215a0e9adbe0e379761260553ba11c58943e4bbe9c36430c4ca6ac74b15ed"}, + {file = "cffi-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b29ebffcf550f9da55bec9e02ad430c992a87e5f512cd63388abb76f1036d8d2"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dc9b18bf40cc75f66f40a7379f6a9513244fe33c0e8aa72e2d56b0196a7ef872"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cb4a35b3642fc5c005a6755a5d17c6c8b6bcb6981baf81cea8bfbc8903e8ba8"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b86851a328eedc692acf81fb05444bdf1891747c25af7529e39ddafaf68a4f3f"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c0f31130ebc2d37cdd8e44605fb5fa7ad59049298b3f745c74fa74c62fbfcfc4"}, + {file = "cffi-1.16.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f8e709127c6c77446a8c0a8c8bf3c8ee706a06cd44b1e827c3e6a2ee6b8c098"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:748dcd1e3d3d7cd5443ef03ce8685043294ad6bd7c02a38d1bd367cfd968e000"}, + {file = "cffi-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8895613bcc094d4a1b2dbe179d88d7fb4a15cee43c052e8885783fac397d91fe"}, + {file = "cffi-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed86a35631f7bfbb28e108dd96773b9d5a6ce4811cf6ea468bb6a359b256b1e4"}, + {file = "cffi-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:3686dffb02459559c74dd3d81748269ffb0eb027c39a6fc99502de37d501faa8"}, + {file = "cffi-1.16.0.tar.gz", hash = "sha256:bcb3ef43e58665bbda2fb198698fcae6776483e0c4a631aa5647806c25e02cc0"}, ] [package.dependencies] @@ -808,18 +794,18 @@ requests = ">=2.6.0" [[package]] name = "datadog-lambda" -version = "5.85.0" +version = "5.88.0" description = "The Datadog AWS Lambda Library" optional = false -python-versions = ">=3.7.0,<4" +python-versions = ">=3.8.0,<4" files = [ - {file = "datadog_lambda-5.85.0-py3-none-any.whl", hash = "sha256:b341f8062007375fa06f6e8c5ea3da937333101ef426574967ccd06c7490febf"}, - {file = "datadog_lambda-5.85.0.tar.gz", hash = "sha256:0bc3714cc40c06cc0bedc8c5e029117160886a882a903d2652ff77298e703e6d"}, + {file = "datadog_lambda-5.88.0-py3-none-any.whl", hash = "sha256:84eacaab1c5b274bdb9b5843e3ebfb32c8b9624bf22a5813283a6cf482e66805"}, + {file = "datadog_lambda-5.88.0.tar.gz", hash = "sha256:ce191634c36fed62d82f1b624e25e8ab226a5f67397e29286015e2eb6482094e"}, ] [package.dependencies] datadog = ">=0.41.0,<1.0.0" -ddtrace = ">=2.3.1" +ddtrace = ">=2.5.1" urllib3 = [ {version = "<2.0.0", markers = "python_version < \"3.11\""}, {version = "<2.1.0", markers = "python_version >= \"3.11\""}, @@ -827,7 +813,7 @@ urllib3 = [ wrapt = ">=1.11.2,<2.0.0" [package.extras] -dev = ["boto3 (>=1.28.0,<2.0.0)", "flake8 (>=3.7.9,<4.0.0)", "httpretty (>=0.9.7,<0.10.0)", "nose2 (>=0.9.1,<0.10.0)", "requests (>=2.22.0,<3.0.0)"] +dev = ["boto3 (>=1.28.0,<2.0.0)", "flake8 (>=5.0.4,<6.0.0)", "nose2 (>=0.9.1,<0.10.0)", "requests (>=2.22.0,<3.0.0)"] [[package]] name = "ddsketch" @@ -973,13 +959,13 @@ packaging = "*" [[package]] name = "docker" -version = "6.1.3" +version = "7.0.0" description = "A Python library for the Docker Engine API." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "docker-6.1.3-py3-none-any.whl", hash = "sha256:aecd2277b8bf8e506e484f6ab7aec39abe0038e29fa4a6d3ba86c3fe01844ed9"}, - {file = "docker-6.1.3.tar.gz", hash = "sha256:aa6d17830045ba5ef0168d5eaa34d37beeb113948c413affe1d5991fc11f9a20"}, + {file = "docker-7.0.0-py3-none-any.whl", hash = "sha256:12ba681f2777a0ad28ffbcc846a69c31b4dfd9752b47eb425a274ee269c5e14b"}, + {file = "docker-7.0.0.tar.gz", hash = "sha256:323736fb92cd9418fc5e7133bc953e11a9da04f4483f828b527db553f1e7e5a3"}, ] [package.dependencies] @@ -987,10 +973,10 @@ packaging = ">=14.0" pywin32 = {version = ">=304", markers = "sys_platform == \"win32\""} requests = ">=2.26.0" urllib3 = ">=1.26.0" -websocket-client = ">=0.32.0" [package.extras] ssh = ["paramiko (>=2.4.3)"] +websockets = ["websocket-client (>=1.3.0)"] [[package]] name = "envier" @@ -1050,18 +1036,19 @@ devel = ["colorama", "json-spec", "jsonschema", "pylint", "pytest", "pytest-benc [[package]] name = "filelock" -version = "3.12.2" +version = "3.13.1" description = "A platform independent file lock." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "filelock-3.12.2-py3-none-any.whl", hash = "sha256:cbb791cdea2a72f23da6ac5b5269ab0a0d161e9ef0100e653b69049a7706d1ec"}, - {file = "filelock-3.12.2.tar.gz", hash = "sha256:002740518d8aa59a26b0c76e10fb8c6e15eae825d34b6fdf670333fd7b938d81"}, + {file = "filelock-3.13.1-py3-none-any.whl", hash = "sha256:57dbda9b35157b05fb3e58ee91448612eb674172fab98ee235ccb0b5bee19a1c"}, + {file = "filelock-3.13.1.tar.gz", hash = "sha256:521f5f56c50f8426f5e03ad3b281b490a87ef15bc6c526f168290f0c7148d44e"}, ] [package.extras] -docs = ["furo (>=2023.5.20)", "sphinx (>=7.0.1)", "sphinx-autodoc-typehints (>=1.23,!=1.23.4)"] -testing = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "diff-cover (>=7.5)", "pytest (>=7.3.1)", "pytest-cov (>=4.1)", "pytest-mock (>=3.10)", "pytest-timeout (>=2.1)"] +docs = ["furo (>=2023.9.10)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.24)"] +testing = ["covdefaults (>=2.3)", "coverage (>=7.3.2)", "diff-cover (>=8)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)", "pytest-timeout (>=2.2)"] +typing = ["typing-extensions (>=4.8)"] [[package]] name = "ghp-import" @@ -1222,17 +1209,6 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, - {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, - {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1293,40 +1269,40 @@ files = [ [[package]] name = "importlib-metadata" -version = "6.5.0" +version = "6.11.0" description = "Read metadata from Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_metadata-6.5.0-py3-none-any.whl", hash = "sha256:03ba783c3a2c69d751b109fc0c94a62c51f581b3d6acf8ed1331b6d5729321ff"}, - {file = "importlib_metadata-6.5.0.tar.gz", hash = "sha256:7a8bdf1bc3a726297f5cfbc999e6e7ff6b4fa41b26bba4afc580448624460045"}, + {file = "importlib_metadata-6.11.0-py3-none-any.whl", hash = "sha256:f0afba6205ad8f8947c7d338b5342d5db2afbfd82f9cbef7879a9539cc12eb9b"}, + {file = "importlib_metadata-6.11.0.tar.gz", hash = "sha256:1231cf92d825c9e03cfc4da076a16de6422c863558229ea0b22b675657463443"}, ] [package.dependencies] zipp = ">=0.5" [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] perf = ["ipython"] -testing = ["flake8 (<5)", "flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)"] +testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf (>=0.9.2)", "pytest-ruff"] [[package]] name = "importlib-resources" -version = "5.12.0" +version = "6.1.1" description = "Read resources from Python packages" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "importlib_resources-5.12.0-py3-none-any.whl", hash = "sha256:7b1deeebbf351c7578e09bf2f63fa2ce8b5ffec296e0d349139d43cca061a81a"}, - {file = "importlib_resources-5.12.0.tar.gz", hash = "sha256:4be82589bf5c1d7999aedf2a45159d10cb3ca4f19b2271f8792bc8e6da7b22f6"}, + {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, + {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, ] [package.dependencies] zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["flake8 (<5)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -1474,25 +1450,42 @@ files = [ [[package]] name = "jsonschema" -version = "4.17.3" +version = "4.21.1" description = "An implementation of JSON Schema validation for Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "jsonschema-4.17.3-py3-none-any.whl", hash = "sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6"}, - {file = "jsonschema-4.17.3.tar.gz", hash = "sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d"}, + {file = "jsonschema-4.21.1-py3-none-any.whl", hash = "sha256:7996507afae316306f9e2290407761157c6f78002dcf7419acb99822143d1c6f"}, + {file = "jsonschema-4.21.1.tar.gz", hash = "sha256:85727c00279f5fa6bedbe6238d2aa6403bedd8b4864ab11207d07df3cc1b2ee5"}, ] [package.dependencies] -attrs = ">=17.4.0" +attrs = ">=22.2.0" importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +jsonschema-specifications = ">=2023.03.6" pkgutil-resolve-name = {version = ">=1.3.10", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" +referencing = ">=0.28.4" +rpds-py = ">=0.7.1" [package.extras] format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] +[[package]] +name = "jsonschema-specifications" +version = "2023.12.1" +description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +optional = false +python-versions = ">=3.8" +files = [ + {file = "jsonschema_specifications-2023.12.1-py3-none-any.whl", hash = "sha256:87e4fdf3a94858b8a2ba2778d9ba57d8a9cafca7c7489c46ba0d30a8bc6a9c3c"}, + {file = "jsonschema_specifications-2023.12.1.tar.gz", hash = "sha256:48a76787b3e70f5ed53f1160d2b81f586e4ca6d1548c5de7085d1682674764cc"}, +] + +[package.dependencies] +importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} +referencing = ">=0.31.0" + [[package]] name = "junit-xml" version = "1.9" @@ -1509,13 +1502,13 @@ six = "*" [[package]] name = "mako" -version = "1.2.4" +version = "1.3.2" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Mako-1.2.4-py3-none-any.whl", hash = "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818"}, - {file = "Mako-1.2.4.tar.gz", hash = "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34"}, + {file = "Mako-1.3.2-py3-none-any.whl", hash = "sha256:32a99d70754dfce237019d17ffe4a282d2d3351b9c476e90d8a60e63f133b80c"}, + {file = "Mako-1.3.2.tar.gz", hash = "sha256:2a0c8ad7f6274271b3bb7467dd37cf9cc6dab4bc19cb69a4ef10669402de698e"}, ] [package.dependencies] @@ -1545,31 +1538,31 @@ restructuredtext = ["rst2ansi"] [[package]] name = "markdown" -version = "3.4.4" +version = "3.5.2" description = "Python implementation of John Gruber's Markdown." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "Markdown-3.4.4-py3-none-any.whl", hash = "sha256:a4c1b65c0957b4bd9e7d86ddc7b3c9868fb9670660f6f99f6d1bca8954d5a941"}, - {file = "Markdown-3.4.4.tar.gz", hash = "sha256:225c6123522495d4119a90b3a3ba31a1e87a70369e03f14799ea9c0d7183a3d6"}, + {file = "Markdown-3.5.2-py3-none-any.whl", hash = "sha256:d43323865d89fc0cb9b20c75fc8ad313af307cc087e84b657d9eec768eddeadd"}, + {file = "Markdown-3.5.2.tar.gz", hash = "sha256:e1ac7b3dc550ee80e602e71c1d168002f062e49f1b11e26a36264dafd4df2ef8"}, ] [package.dependencies] importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} [package.extras] -docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.0)", "mkdocs-nature (>=0.4)"] +docs = ["mdx-gh-links (>=0.2)", "mkdocs (>=1.5)", "mkdocs-gen-files", "mkdocs-literate-nav", "mkdocs-nature (>=0.6)", "mkdocs-section-index", "mkdocstrings[python]"] testing = ["coverage", "pyyaml"] [[package]] name = "markdown-it-py" -version = "2.2.0" +version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "markdown-it-py-2.2.0.tar.gz", hash = "sha256:7c9a5e412688bc771c67432cbfebcdd686c93ce6484913dccf06cb5a0bea35a1"}, - {file = "markdown_it_py-2.2.0-py3-none-any.whl", hash = "sha256:5a35f8d1870171d9acc47b99612dc146129b631baf04970128b568f190d0cc30"}, + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, ] [package.dependencies] @@ -1582,76 +1575,76 @@ compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0 linkify = ["linkify-it-py (>=1,<3)"] plugins = ["mdit-py-plugins"] profiling = ["gprof2dot"] -rtd = ["attrs", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] [[package]] name = "markupsafe" -version = "2.1.4" +version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.7" files = [ - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:de8153a7aae3835484ac168a9a9bdaa0c5eee4e0bc595503c95d53b942879c84"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e888ff76ceb39601c59e219f281466c6d7e66bd375b4ec1ce83bcdc68306796b"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0b838c37ba596fcbfca71651a104a611543077156cb0a26fe0c475e1f152ee8"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dac1ebf6983148b45b5fa48593950f90ed6d1d26300604f321c74a9ca1609f8e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0fbad3d346df8f9d72622ac71b69565e621ada2ce6572f37c2eae8dacd60385d"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:d5291d98cd3ad9a562883468c690a2a238c4a6388ab3bd155b0c75dd55ece858"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a7cc49ef48a3c7a0005a949f3c04f8baa5409d3f663a1b36f0eba9bfe2a0396e"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b83041cda633871572f0d3c41dddd5582ad7d22f65a72eacd8d3d6d00291df26"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win32.whl", hash = "sha256:0c26f67b3fe27302d3a412b85ef696792c4a2386293c53ba683a89562f9399b0"}, - {file = "MarkupSafe-2.1.4-cp310-cp310-win_amd64.whl", hash = "sha256:a76055d5cb1c23485d7ddae533229039b850db711c554a12ea64a0fd8a0129e2"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9e9e3c4020aa2dc62d5dd6743a69e399ce3de58320522948af6140ac959ab863"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0042d6a9880b38e1dd9ff83146cc3c9c18a059b9360ceae207805567aacccc69"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55d03fea4c4e9fd0ad75dc2e7e2b6757b80c152c032ea1d1de487461d8140efc"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ab3a886a237f6e9c9f4f7d272067e712cdb4efa774bef494dccad08f39d8ae6"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:abf5ebbec056817057bfafc0445916bb688a255a5146f900445d081db08cbabb"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e1a0d1924a5013d4f294087e00024ad25668234569289650929ab871231668e7"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e7902211afd0af05fbadcc9a312e4cf10f27b779cf1323e78d52377ae4b72bea"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:c669391319973e49a7c6230c218a1e3044710bc1ce4c8e6eb71f7e6d43a2c131"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win32.whl", hash = "sha256:31f57d64c336b8ccb1966d156932f3daa4fee74176b0fdc48ef580be774aae74"}, - {file = "MarkupSafe-2.1.4-cp311-cp311-win_amd64.whl", hash = "sha256:54a7e1380dfece8847c71bf7e33da5d084e9b889c75eca19100ef98027bd9f56"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:a76cd37d229fc385738bd1ce4cba2a121cf26b53864c1772694ad0ad348e509e"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:987d13fe1d23e12a66ca2073b8d2e2a75cec2ecb8eab43ff5624ba0ad42764bc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5244324676254697fe5c181fc762284e2c5fceeb1c4e3e7f6aca2b6f107e60dc"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78bc995e004681246e85e28e068111a4c3f35f34e6c62da1471e844ee1446250"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d176cfdfde84f732c4a53109b293d05883e952bbba68b857ae446fa3119b4f"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:f9917691f410a2e0897d1ef99619fd3f7dd503647c8ff2475bf90c3cf222ad74"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:f06e5a9e99b7df44640767842f414ed5d7bedaaa78cd817ce04bbd6fd86e2dd6"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:396549cea79e8ca4ba65525470d534e8a41070e6b3500ce2414921099cb73e8d"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win32.whl", hash = "sha256:f6be2d708a9d0e9b0054856f07ac7070fbe1754be40ca8525d5adccdbda8f475"}, - {file = "MarkupSafe-2.1.4-cp312-cp312-win_amd64.whl", hash = "sha256:5045e892cfdaecc5b4c01822f353cf2c8feb88a6ec1c0adef2a2e705eef0f656"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7a07f40ef8f0fbc5ef1000d0c78771f4d5ca03b4953fc162749772916b298fc4"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d18b66fe626ac412d96c2ab536306c736c66cf2a31c243a45025156cc190dc8a"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:698e84142f3f884114ea8cf83e7a67ca8f4ace8454e78fe960646c6c91c63bfa"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a3b78a5af63ec10d8604180380c13dcd870aba7928c1fe04e881d5c792dc4e"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:15866d7f2dc60cfdde12ebb4e75e41be862348b4728300c36cdf405e258415ec"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:6aa5e2e7fc9bc042ae82d8b79d795b9a62bd8f15ba1e7594e3db243f158b5565"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:54635102ba3cf5da26eb6f96c4b8c53af8a9c0d97b64bdcb592596a6255d8518"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win32.whl", hash = "sha256:3583a3a3ab7958e354dc1d25be74aee6228938312ee875a22330c4dc2e41beb0"}, - {file = "MarkupSafe-2.1.4-cp37-cp37m-win_amd64.whl", hash = "sha256:d6e427c7378c7f1b2bef6a344c925b8b63623d3321c09a237b7cc0e77dd98ceb"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:bf1196dcc239e608605b716e7b166eb5faf4bc192f8a44b81e85251e62584bd2"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4df98d4a9cd6a88d6a585852f56f2155c9cdb6aec78361a19f938810aa020954"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b835aba863195269ea358cecc21b400276747cc977492319fd7682b8cd2c253d"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:23984d1bdae01bee794267424af55eef4dfc038dc5d1272860669b2aa025c9e3"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1c98c33ffe20e9a489145d97070a435ea0679fddaabcafe19982fe9c971987d5"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:9896fca4a8eb246defc8b2a7ac77ef7553b638e04fbf170bff78a40fa8a91474"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:b0fe73bac2fed83839dbdbe6da84ae2a31c11cfc1c777a40dbd8ac8a6ed1560f"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c7556bafeaa0a50e2fe7dc86e0382dea349ebcad8f010d5a7dc6ba568eaaa789"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win32.whl", hash = "sha256:fc1a75aa8f11b87910ffd98de62b29d6520b6d6e8a3de69a70ca34dea85d2a8a"}, - {file = "MarkupSafe-2.1.4-cp38-cp38-win_amd64.whl", hash = "sha256:3a66c36a3864df95e4f62f9167c734b3b1192cb0851b43d7cc08040c074c6279"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:765f036a3d00395a326df2835d8f86b637dbaf9832f90f5d196c3b8a7a5080cb"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:21e7af8091007bf4bebf4521184f4880a6acab8df0df52ef9e513d8e5db23411"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d5c31fe855c77cad679b302aabc42d724ed87c043b1432d457f4976add1c2c3e"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7653fa39578957bc42e5ebc15cf4361d9e0ee4b702d7d5ec96cdac860953c5b4"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47bb5f0142b8b64ed1399b6b60f700a580335c8e1c57f2f15587bd072012decc"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:fe8512ed897d5daf089e5bd010c3dc03bb1bdae00b35588c49b98268d4a01e00"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:36d7626a8cca4d34216875aee5a1d3d654bb3dac201c1c003d182283e3205949"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b6f14a9cd50c3cb100eb94b3273131c80d102e19bb20253ac7bd7336118a673a"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win32.whl", hash = "sha256:c8f253a84dbd2c63c19590fa86a032ef3d8cc18923b8049d91bcdeeb2581fbf6"}, - {file = "MarkupSafe-2.1.4-cp39-cp39-win_amd64.whl", hash = "sha256:8b570a1537367b52396e53325769608f2a687ec9a4363647af1cded8928af959"}, - {file = "MarkupSafe-2.1.4.tar.gz", hash = "sha256:3aae9af4cac263007fd6309c64c6ab4506dd2b79382d9d19a1994f9240b8db4f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a17a92de5231666cfbe003f0e4b9b3a7ae3afb1ec2845aadc2bacc93ff85febc"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:72b6be590cc35924b02c78ef34b467da4ba07e4e0f0454a2c5907f473fc50ce5"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e61659ba32cf2cf1481e575d0462554625196a1f2fc06a1c777d3f48e8865d46"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2174c595a0d73a3080ca3257b40096db99799265e1c27cc5a610743acd86d62f"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae2ad8ae6ebee9d2d94b17fb62763125f3f374c25618198f40cbb8b525411900"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:075202fa5b72c86ad32dc7d0b56024ebdbcf2048c0ba09f1cde31bfdd57bcfff"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:598e3276b64aff0e7b3451b72e94fa3c238d452e7ddcd893c3ab324717456bad"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fce659a462a1be54d2ffcacea5e3ba2d74daa74f30f5f143fe0c58636e355fdd"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win32.whl", hash = "sha256:d9fad5155d72433c921b782e58892377c44bd6252b5af2f67f16b194987338a4"}, + {file = "MarkupSafe-2.1.5-cp310-cp310-win_amd64.whl", hash = "sha256:bf50cd79a75d181c9181df03572cdce0fbb75cc353bc350712073108cba98de5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:629ddd2ca402ae6dbedfceeba9c46d5f7b2a61d9749597d4307f943ef198fc1f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5b7b716f97b52c5a14bffdf688f971b2d5ef4029127f1ad7a513973cfd818df2"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ec585f69cec0aa07d945b20805be741395e28ac1627333b1c5b0105962ffced"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b91c037585eba9095565a3556f611e3cbfaa42ca1e865f7b8015fe5c7336d5a5"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7502934a33b54030eaf1194c21c692a534196063db72176b0c4028e140f8f32c"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0e397ac966fdf721b2c528cf028494e86172b4feba51d65f81ffd65c63798f3f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:c061bb86a71b42465156a3ee7bd58c8c2ceacdbeb95d05a99893e08b8467359a"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3a57fdd7ce31c7ff06cdfbf31dafa96cc533c21e443d57f5b1ecc6cdc668ec7f"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win32.whl", hash = "sha256:397081c1a0bfb5124355710fe79478cdbeb39626492b15d399526ae53422b906"}, + {file = "MarkupSafe-2.1.5-cp311-cp311-win_amd64.whl", hash = "sha256:2b7c57a4dfc4f16f7142221afe5ba4e093e09e728ca65c51f5620c9aaeb9a617"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8dec4936e9c3100156f8a2dc89c4b88d5c435175ff03413b443469c7c8c5f4d1"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:3c6b973f22eb18a789b1460b4b91bf04ae3f0c4234a0a6aa6b0a92f6f7b951d4"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ac07bad82163452a6884fe8fa0963fb98c2346ba78d779ec06bd7a6262132aee"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5dfb42c4604dddc8e4305050aa6deb084540643ed5804d7455b5df8fe16f5e5"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ea3d8a3d18833cf4304cd2fc9cbb1efe188ca9b5efef2bdac7adc20594a0e46b"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:d050b3361367a06d752db6ead6e7edeb0009be66bc3bae0ee9d97fb326badc2a"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:bec0a414d016ac1a18862a519e54b2fd0fc8bbfd6890376898a6c0891dd82e9f"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:58c98fee265677f63a4385256a6d7683ab1832f3ddd1e66fe948d5880c21a169"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win32.whl", hash = "sha256:8590b4ae07a35970728874632fed7bd57b26b0102df2d2b233b6d9d82f6c62ad"}, + {file = "MarkupSafe-2.1.5-cp312-cp312-win_amd64.whl", hash = "sha256:823b65d8706e32ad2df51ed89496147a42a2a6e01c13cfb6ffb8b1e92bc910bb"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c8b29db45f8fe46ad280a7294f5c3ec36dbac9491f2d1c17345be8e69cc5928f"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec6a563cff360b50eed26f13adc43e61bc0c04d94b8be985e6fb24b81f6dcfdf"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a549b9c31bec33820e885335b451286e2969a2d9e24879f83fe904a5ce59d70a"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4f11aa001c540f62c6166c7726f71f7573b52c68c31f014c25cc7901deea0b52"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:7b2e5a267c855eea6b4283940daa6e88a285f5f2a67f2220203786dfa59b37e9"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2d2d793e36e230fd32babe143b04cec8a8b3eb8a3122d2aceb4a371e6b09b8df"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ce409136744f6521e39fd8e2a24c53fa18ad67aa5bc7c2cf83645cce5b5c4e50"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win32.whl", hash = "sha256:4096e9de5c6fdf43fb4f04c26fb114f61ef0bf2e5604b6ee3019d51b69e8c371"}, + {file = "MarkupSafe-2.1.5-cp37-cp37m-win_amd64.whl", hash = "sha256:4275d846e41ecefa46e2015117a9f491e57a71ddd59bbead77e904dc02b1bed2"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:656f7526c69fac7f600bd1f400991cc282b417d17539a1b228617081106feb4a"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:97cafb1f3cbcd3fd2b6fbfb99ae11cdb14deea0736fc2b0952ee177f2b813a46"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f3fbcb7ef1f16e48246f704ab79d79da8a46891e2da03f8783a5b6fa41a9532"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa9db3f79de01457b03d4f01b34cf91bc0048eb2c3846ff26f66687c2f6d16ab"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffee1f21e5ef0d712f9033568f8344d5da8cc2869dbd08d87c84656e6a2d2f68"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5dedb4db619ba5a2787a94d877bc8ffc0566f92a01c0ef214865e54ecc9ee5e0"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:30b600cf0a7ac9234b2638fbc0fb6158ba5bdcdf46aeb631ead21248b9affbc4"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8dd717634f5a044f860435c1d8c16a270ddf0ef8588d4887037c5028b859b0c3"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win32.whl", hash = "sha256:daa4ee5a243f0f20d528d939d06670a298dd39b1ad5f8a72a4275124a7819eff"}, + {file = "MarkupSafe-2.1.5-cp38-cp38-win_amd64.whl", hash = "sha256:619bc166c4f2de5caa5a633b8b7326fbe98e0ccbfacabd87268a2b15ff73a029"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7a68b554d356a91cce1236aa7682dc01df0edba8d043fd1ce607c49dd3c1edcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:db0b55e0f3cc0be60c1f19efdde9a637c32740486004f20d1cff53c3c0ece4d2"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e53af139f8579a6d5f7b76549125f0d94d7e630761a2111bc431fd820e163b8"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:17b950fccb810b3293638215058e432159d2b71005c74371d784862b7e4683f3"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c31f53cdae6ecfa91a77820e8b151dba54ab528ba65dfd235c80b086d68a465"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bff1b4290a66b490a2f4719358c0cdcd9bafb6b8f061e45c7a2460866bf50c2e"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc1667f8b83f48511b94671e0e441401371dfd0f0a795c7daa4a3cd1dde55bea"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5049256f536511ee3f7e1b3f87d1d1209d327e818e6ae1365e8653d7e3abb6a6"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win32.whl", hash = "sha256:00e046b6dd71aa03a41079792f8473dc494d564611a8f89bbbd7cb93295ebdcf"}, + {file = "MarkupSafe-2.1.5-cp39-cp39-win_amd64.whl", hash = "sha256:fa173ec60341d6bb97a89f5ea19c85c5643c1e7dedebc22f5181eb73573142c5"}, + {file = "MarkupSafe-2.1.5.tar.gz", hash = "sha256:d283d37a890ba4c1ae73ffadf8046435c76e7bc2247bbb63c00bd1a709c6544b"}, ] [[package]] @@ -1745,13 +1738,13 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.2.7" +version = "9.5.8" description = "Documentation that simply works" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.2.7-py3-none-any.whl", hash = "sha256:92e4160d191cc76121fed14ab9f14638e43a6da0f2e9d7a9194d377f0a4e7f18"}, - {file = "mkdocs_material-9.2.7.tar.gz", hash = "sha256:b44da35b0d98cd762d09ef74f1ddce5b6d6e35c13f13beb0c9d82a629e5f229e"}, + {file = "mkdocs_material-9.5.8-py3-none-any.whl", hash = "sha256:14563314bbf97da4bfafc69053772341babfaeb3329cde01d3e63cec03997af8"}, + {file = "mkdocs_material-9.5.8.tar.gz", hash = "sha256:2a429213e83f84eda7a588e2b186316d806aac602b7f93990042f7a1f3d3cf65"}, ] [package.dependencies] @@ -1759,23 +1752,28 @@ babel = ">=2.10,<3.0" colorama = ">=0.4,<1.0" jinja2 = ">=3.0,<4.0" markdown = ">=3.2,<4.0" -mkdocs = ">=1.5,<2.0" -mkdocs-material-extensions = ">=1.1,<2.0" +mkdocs = ">=1.5.3,<1.6.0" +mkdocs-material-extensions = ">=1.3,<2.0" paginate = ">=0.5,<1.0" pygments = ">=2.16,<3.0" pymdown-extensions = ">=10.2,<11.0" -regex = ">=2022.4,<2023.0" +regex = ">=2022.4" requests = ">=2.26,<3.0" +[package.extras] +git = ["mkdocs-git-committers-plugin-2 (>=1.1,<2.0)", "mkdocs-git-revision-date-localized-plugin (>=1.2.4,<2.0)"] +imaging = ["cairosvg (>=2.6,<3.0)", "pillow (>=10.2,<11.0)"] +recommended = ["mkdocs-minify-plugin (>=0.7,<1.0)", "mkdocs-redirects (>=1.2,<2.0)", "mkdocs-rss-plugin (>=1.6,<2.0)"] + [[package]] name = "mkdocs-material-extensions" -version = "1.2" +version = "1.3.1" description = "Extension pack for Python Markdown and MkDocs Material." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mkdocs_material_extensions-1.2-py3-none-any.whl", hash = "sha256:c767bd6d6305f6420a50f0b541b0c9966d52068839af97029be14443849fb8a1"}, - {file = "mkdocs_material_extensions-1.2.tar.gz", hash = "sha256:27e2d1ed2d031426a6e10d5ea06989d67e90bb02acd588bc5673106b5ee5eedf"}, + {file = "mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31"}, + {file = "mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443"}, ] [[package]] @@ -1928,13 +1926,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-logs" -version = "1.34.16" -description = "Type annotations for boto3.CloudWatchLogs 1.34.16 service generated with mypy-boto3-builder 7.23.1" +version = "1.34.36" +description = "Type annotations for boto3.CloudWatchLogs 1.34.36 service generated with mypy-boto3-builder 7.23.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-boto3-logs-1.34.16.tar.gz", hash = "sha256:fff912fd8e9b7ce2bd5ea64c7f3e1f07885660226190f86353083836338a2d2a"}, - {file = "mypy_boto3_logs-1.34.16-py3-none-any.whl", hash = "sha256:2f0c918a59fbac279117bef67666aafd7d6ebdd5fbc7015352206553afb82c40"}, + {file = "mypy-boto3-logs-1.34.36.tar.gz", hash = "sha256:1549b54da88a869852458e186e589449d53a7805354b5afd7d53b4d275c53c2e"}, + {file = "mypy_boto3_logs-1.34.36-py3-none-any.whl", hash = "sha256:c58cc7d498e24b963d4c78700a3e82d5af82e62d6694e30237c166a1fd6d326f"}, ] [package.dependencies] @@ -2009,21 +2007,21 @@ files = [ [[package]] name = "networkx" -version = "2.6.3" +version = "3.1" description = "Python package for creating and manipulating graphs and networks" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "networkx-2.6.3-py3-none-any.whl", hash = "sha256:80b6b89c77d1dfb64a4c7854981b60aeea6360ac02c6d4e4913319e0a313abef"}, - {file = "networkx-2.6.3.tar.gz", hash = "sha256:c0946ed31d71f1b732b5aaa6da5a0388a345019af232ce2f49c766e2d6795c51"}, + {file = "networkx-3.1-py3-none-any.whl", hash = "sha256:4f33f68cb2afcf86f28a45f43efc27a9386b535d567d2127f8f61d51dec58d36"}, + {file = "networkx-3.1.tar.gz", hash = "sha256:de346335408f84de0eada6ff9fafafff9bcda11f0a0dfaa931133debb146ab61"}, ] [package.extras] -default = ["matplotlib (>=3.3)", "numpy (>=1.19)", "pandas (>=1.1)", "scipy (>=1.5,!=1.6.1)"] -developer = ["black (==21.5b1)", "pre-commit (>=2.12)"] -doc = ["nb2plots (>=0.6)", "numpydoc (>=1.1)", "pillow (>=8.2)", "pydata-sphinx-theme (>=0.6,<1.0)", "sphinx (>=4.0,<5.0)", "sphinx-gallery (>=0.9,<1.0)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.5)", "pydot (>=1.4.1)", "pygraphviz (>=1.7)"] -test = ["codecov (>=2.1)", "pytest (>=6.2)", "pytest-cov (>=2.12)"] +default = ["matplotlib (>=3.4)", "numpy (>=1.20)", "pandas (>=1.3)", "scipy (>=1.8)"] +developer = ["mypy (>=1.1)", "pre-commit (>=3.2)"] +doc = ["nb2plots (>=0.6)", "numpydoc (>=1.5)", "pillow (>=9.4)", "pydata-sphinx-theme (>=0.13)", "sphinx (>=6.1)", "sphinx-gallery (>=0.12)", "texext (>=0.6.7)"] +extra = ["lxml (>=4.6)", "pydot (>=1.4.2)", "pygraphviz (>=1.10)", "sympy (>=1.10)"] +test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "opentelemetry-api" @@ -2063,13 +2061,13 @@ files = [ [[package]] name = "pathspec" -version = "0.11.2" +version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pathspec-0.11.2-py3-none-any.whl", hash = "sha256:1d6ed233af05e679efb96b1851550ea95bbb64b7c490b0f5aa52996c11e92a20"}, - {file = "pathspec-0.11.2.tar.gz", hash = "sha256:e0d8d0ac2f12da61956eb2306b69f9469b42f4deb0f3cb6ed47b9cce9996ced3"}, + {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, + {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, ] [[package]] @@ -2111,18 +2109,18 @@ files = [ [[package]] name = "platformdirs" -version = "4.0.0" +version = "4.2.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "platformdirs-4.0.0-py3-none-any.whl", hash = "sha256:118c954d7e949b35437270383a3f2531e99dd93cf7ce4dc8340d3356d30f173b"}, - {file = "platformdirs-4.0.0.tar.gz", hash = "sha256:cb633b2bcf10c51af60beb0ab06d2f1d69064b43abf4c185ca6b28865f3f9731"}, + {file = "platformdirs-4.2.0-py3-none-any.whl", hash = "sha256:0614df2a2f37e1a662acbd8e2b25b92ccf8632929bc6d43467e17fe89c75e068"}, + {file = "platformdirs-4.2.0.tar.gz", hash = "sha256:ef0cc731df711022c174543cb70a9b5bd22e5a9337c8624ef2c2ceb8ddad8768"}, ] [package.extras] -docs = ["furo (>=2023.7.26)", "proselint (>=0.13)", "sphinx (>=7.1.1)", "sphinx-autodoc-typehints (>=1.24)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-cov (>=4.1)", "pytest-mock (>=3.11.1)"] +docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] +test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] [[package]] name = "pluggy" @@ -2152,24 +2150,22 @@ files = [ [[package]] name = "protobuf" -version = "4.24.4" +version = "4.25.2" description = "" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "protobuf-4.24.4-cp310-abi3-win32.whl", hash = "sha256:ec9912d5cb6714a5710e28e592ee1093d68c5ebfeda61983b3f40331da0b1ebb"}, - {file = "protobuf-4.24.4-cp310-abi3-win_amd64.whl", hash = "sha256:1badab72aa8a3a2b812eacfede5020472e16c6b2212d737cefd685884c191085"}, - {file = "protobuf-4.24.4-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e61a27f362369c2f33248a0ff6896c20dcd47b5d48239cb9720134bef6082e4"}, - {file = "protobuf-4.24.4-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:bffa46ad9612e6779d0e51ae586fde768339b791a50610d85eb162daeb23661e"}, - {file = "protobuf-4.24.4-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:b493cb590960ff863743b9ff1452c413c2ee12b782f48beca77c8da3e2ffe9d9"}, - {file = "protobuf-4.24.4-cp37-cp37m-win32.whl", hash = "sha256:dbbed8a56e56cee8d9d522ce844a1379a72a70f453bde6243e3c86c30c2a3d46"}, - {file = "protobuf-4.24.4-cp37-cp37m-win_amd64.whl", hash = "sha256:6b7d2e1c753715dcfe9d284a25a52d67818dd43c4932574307daf836f0071e37"}, - {file = "protobuf-4.24.4-cp38-cp38-win32.whl", hash = "sha256:02212557a76cd99574775a81fefeba8738d0f668d6abd0c6b1d3adcc75503dbe"}, - {file = "protobuf-4.24.4-cp38-cp38-win_amd64.whl", hash = "sha256:2fa3886dfaae6b4c5ed2730d3bf47c7a38a72b3a1f0acb4d4caf68e6874b947b"}, - {file = "protobuf-4.24.4-cp39-cp39-win32.whl", hash = "sha256:b77272f3e28bb416e2071186cb39efd4abbf696d682cbb5dc731308ad37fa6dd"}, - {file = "protobuf-4.24.4-cp39-cp39-win_amd64.whl", hash = "sha256:9fee5e8aa20ef1b84123bb9232b3f4a5114d9897ed89b4b8142d81924e05d79b"}, - {file = "protobuf-4.24.4-py3-none-any.whl", hash = "sha256:80797ce7424f8c8d2f2547e2d42bfbb6c08230ce5832d6c099a37335c9c90a92"}, - {file = "protobuf-4.24.4.tar.gz", hash = "sha256:5a70731910cd9104762161719c3d883c960151eea077134458503723b60e3667"}, + {file = "protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6"}, + {file = "protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9"}, + {file = "protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62"}, + {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020"}, + {file = "protobuf-4.25.2-cp38-cp38-win32.whl", hash = "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61"}, + {file = "protobuf-4.25.2-cp38-cp38-win_amd64.whl", hash = "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62"}, + {file = "protobuf-4.25.2-cp39-cp39-win32.whl", hash = "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3"}, + {file = "protobuf-4.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0"}, + {file = "protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830"}, + {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, ] [[package]] @@ -2285,58 +2281,22 @@ files = [ [[package]] name = "pymdown-extensions" -version = "10.2.1" +version = "10.7" description = "Extension pack for Python Markdown." optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pymdown_extensions-10.2.1-py3-none-any.whl", hash = "sha256:bded105eb8d93f88f2f821f00108cb70cef1269db6a40128c09c5f48bfc60ea4"}, - {file = "pymdown_extensions-10.2.1.tar.gz", hash = "sha256:d0c534b4a5725a4be7ccef25d65a4c97dba58b54ad7c813babf0eb5ba9c81591"}, + {file = "pymdown_extensions-10.7-py3-none-any.whl", hash = "sha256:6ca215bc57bc12bf32b414887a68b810637d039124ed9b2e5bd3325cbb2c050c"}, + {file = "pymdown_extensions-10.7.tar.gz", hash = "sha256:c0d64d5cf62566f59e6b2b690a4095c931107c250a8c8e1351c1de5f6b036deb"}, ] [package.dependencies] -markdown = ">=3.2" +markdown = ">=3.5" pyyaml = "*" [package.extras] extra = ["pygments (>=2.12)"] -[[package]] -name = "pyrsistent" -version = "0.19.3" -description = "Persistent/Functional/Immutable data structures" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pyrsistent-0.19.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64"}, - {file = "pyrsistent-0.19.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win32.whl", hash = "sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a"}, - {file = "pyrsistent-0.19.3-cp310-cp310-win_amd64.whl", hash = "sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da"}, - {file = "pyrsistent-0.19.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393"}, - {file = "pyrsistent-0.19.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win32.whl", hash = "sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3"}, - {file = "pyrsistent-0.19.3-cp311-cp311-win_amd64.whl", hash = "sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win32.whl", hash = "sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1"}, - {file = "pyrsistent-0.19.3-cp37-cp37m-win_amd64.whl", hash = "sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b"}, - {file = "pyrsistent-0.19.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a"}, - {file = "pyrsistent-0.19.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win32.whl", hash = "sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c"}, - {file = "pyrsistent-0.19.3-cp38-cp38-win_amd64.whl", hash = "sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7"}, - {file = "pyrsistent-0.19.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win32.whl", hash = "sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2"}, - {file = "pyrsistent-0.19.3-cp39-cp39-win_amd64.whl", hash = "sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98"}, - {file = "pyrsistent-0.19.3-py3-none-any.whl", hash = "sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64"}, - {file = "pyrsistent-0.19.3.tar.gz", hash = "sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440"}, -] - [[package]] name = "pytest" version = "8.0.0" @@ -2417,13 +2377,13 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale [[package]] name = "pytest-mock" -version = "3.11.1" +version = "3.12.0" description = "Thin-wrapper around the mock package for easier use with pytest" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-mock-3.11.1.tar.gz", hash = "sha256:7f6b125602ac6d743e523ae0bfa71e1a697a2f5534064528c6ff84c2f7c2fc7f"}, - {file = "pytest_mock-3.11.1-py3-none-any.whl", hash = "sha256:21c279fff83d70763b05f8874cc9cfb3fcacd6d354247a976f9529d19f9acf39"}, + {file = "pytest-mock-3.12.0.tar.gz", hash = "sha256:31a40f038c22cad32287bb43932054451ff5583ff094bca6f675df2f8bc1a6e9"}, + {file = "pytest_mock-3.12.0-py3-none-any.whl", hash = "sha256:0972719a7263072da3a21c7f4773069bcc7486027d7e8e1f81d98a47e701bc4f"}, ] [package.dependencies] @@ -2482,13 +2442,13 @@ six = ">=1.5" [[package]] name = "pytz" -version = "2023.4" +version = "2024.1" description = "World timezone definitions, modern and historical" optional = false python-versions = "*" files = [ - {file = "pytz-2023.4-py2.py3-none-any.whl", hash = "sha256:f90ef520d95e7c46951105338d918664ebfd6f1d995bd7d153127ce90efafa6a"}, - {file = "pytz-2023.4.tar.gz", hash = "sha256:31d4583c4ed539cd037956140d695e42c033a19e984bfce9964a3f7d59bc2b40"}, + {file = "pytz-2024.1-py2.py3-none-any.whl", hash = "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319"}, + {file = "pytz-2024.1.tar.gz", hash = "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812"}, ] [[package]] @@ -2526,7 +2486,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2534,16 +2493,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2560,7 +2511,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2568,7 +2518,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2624,101 +2573,121 @@ async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2 hiredis = ["hiredis (>=1.0.0)"] ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"] +[[package]] +name = "referencing" +version = "0.33.0" +description = "JSON Referencing + Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "referencing-0.33.0-py3-none-any.whl", hash = "sha256:39240f2ecc770258f28b642dd47fd74bc8b02484de54e1882b74b35ebd779bd5"}, + {file = "referencing-0.33.0.tar.gz", hash = "sha256:c775fedf74bc0f9189c2a3be1c12fd03e8c23f4d371dce795df44e06c5b412f7"}, +] + +[package.dependencies] +attrs = ">=22.2.0" +rpds-py = ">=0.7.0" + [[package]] name = "regex" -version = "2022.10.31" +version = "2023.12.25" description = "Alternative regular expression module, to replace re." optional = false -python-versions = ">=3.6" +python-versions = ">=3.7" files = [ - {file = "regex-2022.10.31-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a8ff454ef0bb061e37df03557afda9d785c905dab15584860f982e88be73015f"}, - {file = "regex-2022.10.31-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1eba476b1b242620c266edf6325b443a2e22b633217a9835a52d8da2b5c051f9"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d0e5af9a9effb88535a472e19169e09ce750c3d442fb222254a276d77808620b"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d03fe67b2325cb3f09be029fd5da8df9e6974f0cde2c2ac6a79d2634e791dd57"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9d0b68ac1743964755ae2d89772c7e6fb0118acd4d0b7464eaf3921c6b49dd4"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a45b6514861916c429e6059a55cf7db74670eaed2052a648e3e4d04f070e001"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8b0886885f7323beea6f552c28bff62cbe0983b9fbb94126531693ea6c5ebb90"}, - {file = "regex-2022.10.31-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5aefb84a301327ad115e9d346c8e2760009131d9d4b4c6b213648d02e2abe144"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:702d8fc6f25bbf412ee706bd73019da5e44a8400861dfff7ff31eb5b4a1276dc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:a3c1ebd4ed8e76e886507c9eddb1a891673686c813adf889b864a17fafcf6d66"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:50921c140561d3db2ab9f5b11c5184846cde686bb5a9dc64cae442926e86f3af"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:7db345956ecce0c99b97b042b4ca7326feeec6b75facd8390af73b18e2650ffc"}, - {file = "regex-2022.10.31-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:763b64853b0a8f4f9cfb41a76a4a85a9bcda7fdda5cb057016e7706fde928e66"}, - {file = "regex-2022.10.31-cp310-cp310-win32.whl", hash = "sha256:44136355e2f5e06bf6b23d337a75386371ba742ffa771440b85bed367c1318d1"}, - {file = "regex-2022.10.31-cp310-cp310-win_amd64.whl", hash = "sha256:bfff48c7bd23c6e2aec6454aaf6edc44444b229e94743b34bdcdda2e35126cf5"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4b4b1fe58cd102d75ef0552cf17242705ce0759f9695334a56644ad2d83903fe"}, - {file = "regex-2022.10.31-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:542e3e306d1669b25936b64917285cdffcd4f5c6f0247636fec037187bd93542"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c27cc1e4b197092e50ddbf0118c788d9977f3f8f35bfbbd3e76c1846a3443df7"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b8e38472739028e5f2c3a4aded0ab7eadc447f0d84f310c7a8bb697ec417229e"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:76c598ca73ec73a2f568e2a72ba46c3b6c8690ad9a07092b18e48ceb936e9f0c"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c28d3309ebd6d6b2cf82969b5179bed5fefe6142c70f354ece94324fa11bf6a1"}, - {file = "regex-2022.10.31-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9af69f6746120998cd9c355e9c3c6aec7dff70d47247188feb4f829502be8ab4"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a5f9505efd574d1e5b4a76ac9dd92a12acb2b309551e9aa874c13c11caefbe4f"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:5ff525698de226c0ca743bfa71fc6b378cda2ddcf0d22d7c37b1cc925c9650a5"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:4fe7fda2fe7c8890d454f2cbc91d6c01baf206fbc96d89a80241a02985118c0c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:2cdc55ca07b4e70dda898d2ab7150ecf17c990076d3acd7a5f3b25cb23a69f1c"}, - {file = "regex-2022.10.31-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:44a6c2f6374e0033873e9ed577a54a3602b4f609867794c1a3ebba65e4c93ee7"}, - {file = "regex-2022.10.31-cp311-cp311-win32.whl", hash = "sha256:d8716f82502997b3d0895d1c64c3b834181b1eaca28f3f6336a71777e437c2af"}, - {file = "regex-2022.10.31-cp311-cp311-win_amd64.whl", hash = "sha256:61edbca89aa3f5ef7ecac8c23d975fe7261c12665f1d90a6b1af527bba86ce61"}, - {file = "regex-2022.10.31-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a069c8483466806ab94ea9068c34b200b8bfc66b6762f45a831c4baaa9e8cdd"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d26166acf62f731f50bdd885b04b38828436d74e8e362bfcb8df221d868b5d9b"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ac741bf78b9bb432e2d314439275235f41656e189856b11fb4e774d9f7246d81"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75f591b2055523fc02a4bbe598aa867df9e953255f0b7f7715d2a36a9c30065c"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b30bddd61d2a3261f025ad0f9ee2586988c6a00c780a2fb0a92cea2aa702c54"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef4163770525257876f10e8ece1cf25b71468316f61451ded1a6f44273eedeb5"}, - {file = "regex-2022.10.31-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7b280948d00bd3973c1998f92e22aa3ecb76682e3a4255f33e1020bd32adf443"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:d0213671691e341f6849bf33cd9fad21f7b1cb88b89e024f33370733fec58742"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:22e7ebc231d28393dfdc19b185d97e14a0f178bedd78e85aad660e93b646604e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:8ad241da7fac963d7573cc67a064c57c58766b62a9a20c452ca1f21050868dfa"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:586b36ebda81e6c1a9c5a5d0bfdc236399ba6595e1397842fd4a45648c30f35e"}, - {file = "regex-2022.10.31-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:0653d012b3bf45f194e5e6a41df9258811ac8fc395579fa82958a8b76286bea4"}, - {file = "regex-2022.10.31-cp36-cp36m-win32.whl", hash = "sha256:144486e029793a733e43b2e37df16a16df4ceb62102636ff3db6033994711066"}, - {file = "regex-2022.10.31-cp36-cp36m-win_amd64.whl", hash = "sha256:c14b63c9d7bab795d17392c7c1f9aaabbffd4cf4387725a0ac69109fb3b550c6"}, - {file = "regex-2022.10.31-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4cac3405d8dda8bc6ed499557625585544dd5cbf32072dcc72b5a176cb1271c8"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:23cbb932cc53a86ebde0fb72e7e645f9a5eec1a5af7aa9ce333e46286caef783"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:74bcab50a13960f2a610cdcd066e25f1fd59e23b69637c92ad470784a51b1347"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:78d680ef3e4d405f36f0d6d1ea54e740366f061645930072d39bca16a10d8c93"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ce6910b56b700bea7be82c54ddf2e0ed792a577dfaa4a76b9af07d550af435c6"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:659175b2144d199560d99a8d13b2228b85e6019b6e09e556209dfb8c37b78a11"}, - {file = "regex-2022.10.31-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1ddf14031a3882f684b8642cb74eea3af93a2be68893901b2b387c5fd92a03ec"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b683e5fd7f74fb66e89a1ed16076dbab3f8e9f34c18b1979ded614fe10cdc4d9"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:2bde29cc44fa81c0a0c8686992c3080b37c488df167a371500b2a43ce9f026d1"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:4919899577ba37f505aaebdf6e7dc812d55e8f097331312db7f1aab18767cce8"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:9c94f7cc91ab16b36ba5ce476f1904c91d6c92441f01cd61a8e2729442d6fcf5"}, - {file = "regex-2022.10.31-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:ae1e96785696b543394a4e3f15f3f225d44f3c55dafe3f206493031419fedf95"}, - {file = "regex-2022.10.31-cp37-cp37m-win32.whl", hash = "sha256:c670f4773f2f6f1957ff8a3962c7dd12e4be54d05839b216cb7fd70b5a1df394"}, - {file = "regex-2022.10.31-cp37-cp37m-win_amd64.whl", hash = "sha256:8e0caeff18b96ea90fc0eb6e3bdb2b10ab5b01a95128dfeccb64a7238decf5f0"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:131d4be09bea7ce2577f9623e415cab287a3c8e0624f778c1d955ec7c281bd4d"}, - {file = "regex-2022.10.31-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:e613a98ead2005c4ce037c7b061f2409a1a4e45099edb0ef3200ee26ed2a69a8"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:052b670fafbe30966bbe5d025e90b2a491f85dfe5b2583a163b5e60a85a321ad"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa62a07ac93b7cb6b7d0389d8ef57ffc321d78f60c037b19dfa78d6b17c928ee"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5352bea8a8f84b89d45ccc503f390a6be77917932b1c98c4cdc3565137acc714"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f61c9944f0be2dc2b75689ba409938c14876c19d02f7585af4460b6a21403e"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29c04741b9ae13d1e94cf93fca257730b97ce6ea64cfe1eba11cf9ac4e85afb6"}, - {file = "regex-2022.10.31-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:543883e3496c8b6d58bd036c99486c3c8387c2fc01f7a342b760c1ea3158a318"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:b7a8b43ee64ca8f4befa2bea4083f7c52c92864d8518244bfa6e88c751fa8fff"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:6a9a19bea8495bb419dc5d38c4519567781cd8d571c72efc6aa959473d10221a"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:6ffd55b5aedc6f25fd8d9f905c9376ca44fcf768673ffb9d160dd6f409bfda73"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4bdd56ee719a8f751cf5a593476a441c4e56c9b64dc1f0f30902858c4ef8771d"}, - {file = "regex-2022.10.31-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:8ca88da1bd78990b536c4a7765f719803eb4f8f9971cc22d6ca965c10a7f2c4c"}, - {file = "regex-2022.10.31-cp38-cp38-win32.whl", hash = "sha256:5a260758454580f11dd8743fa98319bb046037dfab4f7828008909d0aa5292bc"}, - {file = "regex-2022.10.31-cp38-cp38-win_amd64.whl", hash = "sha256:5e6a5567078b3eaed93558842346c9d678e116ab0135e22eb72db8325e90b453"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:5217c25229b6a85049416a5c1e6451e9060a1edcf988641e309dbe3ab26d3e49"}, - {file = "regex-2022.10.31-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4bf41b8b0a80708f7e0384519795e80dcb44d7199a35d52c15cc674d10b3081b"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0cf0da36a212978be2c2e2e2d04bdff46f850108fccc1851332bcae51c8907cc"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d403d781b0e06d2922435ce3b8d2376579f0c217ae491e273bab8d092727d244"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a37d51fa9a00d265cf73f3de3930fa9c41548177ba4f0faf76e61d512c774690"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4f781ffedd17b0b834c8731b75cce2639d5a8afe961c1e58ee7f1f20b3af185"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d243b36fbf3d73c25e48014961e83c19c9cc92530516ce3c43050ea6276a2ab7"}, - {file = "regex-2022.10.31-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:370f6e97d02bf2dd20d7468ce4f38e173a124e769762d00beadec3bc2f4b3bc4"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:597f899f4ed42a38df7b0e46714880fb4e19a25c2f66e5c908805466721760f5"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:7dbdce0c534bbf52274b94768b3498abdf675a691fec5f751b6057b3030f34c1"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:22960019a842777a9fa5134c2364efaed5fbf9610ddc5c904bd3a400973b0eb8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7f5a3ffc731494f1a57bd91c47dc483a1e10048131ffb52d901bfe2beb6102e8"}, - {file = "regex-2022.10.31-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7ef6b5942e6bfc5706301a18a62300c60db9af7f6368042227ccb7eeb22d0892"}, - {file = "regex-2022.10.31-cp39-cp39-win32.whl", hash = "sha256:395161bbdbd04a8333b9ff9763a05e9ceb4fe210e3c7690f5e68cedd3d65d8e1"}, - {file = "regex-2022.10.31-cp39-cp39-win_amd64.whl", hash = "sha256:957403a978e10fb3ca42572a23e6f7badff39aa1ce2f4ade68ee452dc6807692"}, - {file = "regex-2022.10.31.tar.gz", hash = "sha256:a3a98921da9a1bf8457aeee6a551948a83601689e5ecdd736894ea9bbec77e83"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0694219a1d54336fd0445ea382d49d36882415c0134ee1e8332afd1529f0baa5"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b014333bd0217ad3d54c143de9d4b9a3ca1c5a29a6d0d554952ea071cff0f1f8"}, + {file = "regex-2023.12.25-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d865984b3f71f6d0af64d0d88f5733521698f6c16f445bb09ce746c92c97c586"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e0eabac536b4cc7f57a5f3d095bfa557860ab912f25965e08fe1545e2ed8b4c"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25a8ad70e716f96e13a637802813f65d8a6760ef48672aa3502f4c24ea8b400"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a9b6d73353f777630626f403b0652055ebfe8ff142a44ec2cf18ae470395766e"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a9cc99d6946d750eb75827cb53c4371b8b0fe89c733a94b1573c9dd16ea6c9e4"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88d1f7bef20c721359d8675f7d9f8e414ec5003d8f642fdfd8087777ff7f94b5"}, + {file = "regex-2023.12.25-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cb3fe77aec8f1995611f966d0c656fdce398317f850d0e6e7aebdfe61f40e1cd"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:7aa47c2e9ea33a4a2a05f40fcd3ea36d73853a2aae7b4feab6fc85f8bf2c9704"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:df26481f0c7a3f8739fecb3e81bc9da3fcfae34d6c094563b9d4670b047312e1"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c40281f7d70baf6e0db0c2f7472b31609f5bc2748fe7275ea65a0b4601d9b392"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:d94a1db462d5690ebf6ae86d11c5e420042b9898af5dcf278bd97d6bda065423"}, + {file = "regex-2023.12.25-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:ba1b30765a55acf15dce3f364e4928b80858fa8f979ad41f862358939bdd1f2f"}, + {file = "regex-2023.12.25-cp310-cp310-win32.whl", hash = "sha256:150c39f5b964e4d7dba46a7962a088fbc91f06e606f023ce57bb347a3b2d4630"}, + {file = "regex-2023.12.25-cp310-cp310-win_amd64.whl", hash = "sha256:09da66917262d9481c719599116c7dc0c321ffcec4b1f510c4f8a066f8768105"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1b9d811f72210fa9306aeb88385b8f8bcef0dfbf3873410413c00aa94c56c2b6"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d902a43085a308cef32c0d3aea962524b725403fd9373dea18110904003bac97"}, + {file = "regex-2023.12.25-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d166eafc19f4718df38887b2bbe1467a4f74a9830e8605089ea7a30dd4da8887"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7ad32824b7f02bb3c9f80306d405a1d9b7bb89362d68b3c5a9be53836caebdb"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:636ba0a77de609d6510235b7f0e77ec494d2657108f777e8765efc060094c98c"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fda75704357805eb953a3ee15a2b240694a9a514548cd49b3c5124b4e2ad01b"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f72cbae7f6b01591f90814250e636065850c5926751af02bb48da94dfced7baa"}, + {file = "regex-2023.12.25-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:db2a0b1857f18b11e3b0e54ddfefc96af46b0896fb678c85f63fb8c37518b3e7"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:7502534e55c7c36c0978c91ba6f61703faf7ce733715ca48f499d3dbbd7657e0"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:e8c7e08bb566de4faaf11984af13f6bcf6a08f327b13631d41d62592681d24fe"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:283fc8eed679758de38fe493b7d7d84a198b558942b03f017b1f94dda8efae80"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f44dd4d68697559d007462b0a3a1d9acd61d97072b71f6d1968daef26bc744bd"}, + {file = "regex-2023.12.25-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:67d3ccfc590e5e7197750fcb3a2915b416a53e2de847a728cfa60141054123d4"}, + {file = "regex-2023.12.25-cp311-cp311-win32.whl", hash = "sha256:68191f80a9bad283432385961d9efe09d783bcd36ed35a60fb1ff3f1ec2efe87"}, + {file = "regex-2023.12.25-cp311-cp311-win_amd64.whl", hash = "sha256:7d2af3f6b8419661a0c421584cfe8aaec1c0e435ce7e47ee2a97e344b98f794f"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:8a0ccf52bb37d1a700375a6b395bff5dd15c50acb745f7db30415bae3c2b0715"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c3c4a78615b7762740531c27cf46e2f388d8d727d0c0c739e72048beb26c8a9d"}, + {file = "regex-2023.12.25-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ad83e7545b4ab69216cef4cc47e344d19622e28aabec61574b20257c65466d6a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7a635871143661feccce3979e1727c4e094f2bdfd3ec4b90dfd4f16f571a87a"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d498eea3f581fbe1b34b59c697512a8baef88212f92e4c7830fcc1499f5b45a5"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:43f7cd5754d02a56ae4ebb91b33461dc67be8e3e0153f593c509e21d219c5060"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:51f4b32f793812714fd5307222a7f77e739b9bc566dc94a18126aba3b92b98a3"}, + {file = "regex-2023.12.25-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ba99d8077424501b9616b43a2d208095746fb1284fc5ba490139651f971d39d9"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4bfc2b16e3ba8850e0e262467275dd4d62f0d045e0e9eda2bc65078c0110a11f"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:8c2c19dae8a3eb0ea45a8448356ed561be843b13cbc34b840922ddf565498c1c"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:60080bb3d8617d96f0fb7e19796384cc2467447ef1c491694850ebd3670bc457"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:b77e27b79448e34c2c51c09836033056a0547aa360c45eeeb67803da7b0eedaf"}, + {file = "regex-2023.12.25-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:518440c991f514331f4850a63560321f833979d145d7d81186dbe2f19e27ae3d"}, + {file = "regex-2023.12.25-cp312-cp312-win32.whl", hash = "sha256:e2610e9406d3b0073636a3a2e80db05a02f0c3169b5632022b4e81c0364bcda5"}, + {file = "regex-2023.12.25-cp312-cp312-win_amd64.whl", hash = "sha256:cc37b9aeebab425f11f27e5e9e6cf580be7206c6582a64467a14dda211abc232"}, + {file = "regex-2023.12.25-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:da695d75ac97cb1cd725adac136d25ca687da4536154cdc2815f576e4da11c69"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d126361607b33c4eb7b36debc173bf25d7805847346dd4d99b5499e1fef52bc7"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4719bb05094d7d8563a450cf8738d2e1061420f79cfcc1fa7f0a44744c4d8f73"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5dd58946bce44b53b06d94aa95560d0b243eb2fe64227cba50017a8d8b3cd3e2"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:22a86d9fff2009302c440b9d799ef2fe322416d2d58fc124b926aa89365ec482"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aae8101919e8aa05ecfe6322b278f41ce2994c4a430303c4cd163fef746e04f"}, + {file = "regex-2023.12.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e692296c4cc2873967771345a876bcfc1c547e8dd695c6b89342488b0ea55cd8"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:263ef5cc10979837f243950637fffb06e8daed7f1ac1e39d5910fd29929e489a"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d6f7e255e5fa94642a0724e35406e6cb7001c09d476ab5fce002f652b36d0c39"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:88ad44e220e22b63b0f8f81f007e8abbb92874d8ced66f32571ef8beb0643b2b"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:3a17d3ede18f9cedcbe23d2daa8a2cd6f59fe2bf082c567e43083bba3fb00347"}, + {file = "regex-2023.12.25-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:d15b274f9e15b1a0b7a45d2ac86d1f634d983ca40d6b886721626c47a400bf39"}, + {file = "regex-2023.12.25-cp37-cp37m-win32.whl", hash = "sha256:ed19b3a05ae0c97dd8f75a5d8f21f7723a8c33bbc555da6bbe1f96c470139d3c"}, + {file = "regex-2023.12.25-cp37-cp37m-win_amd64.whl", hash = "sha256:a6d1047952c0b8104a1d371f88f4ab62e6275567d4458c1e26e9627ad489b445"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b43523d7bc2abd757119dbfb38af91b5735eea45537ec6ec3a5ec3f9562a1c53"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:efb2d82f33b2212898f1659fb1c2e9ac30493ac41e4d53123da374c3b5541e64"}, + {file = "regex-2023.12.25-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b7fca9205b59c1a3d5031f7e64ed627a1074730a51c2a80e97653e3e9fa0d415"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:086dd15e9435b393ae06f96ab69ab2d333f5d65cbe65ca5a3ef0ec9564dfe770"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e81469f7d01efed9b53740aedd26085f20d49da65f9c1f41e822a33992cb1590"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:34e4af5b27232f68042aa40a91c3b9bb4da0eeb31b7632e0091afc4310afe6cb"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9852b76ab558e45b20bf1893b59af64a28bd3820b0c2efc80e0a70a4a3ea51c1"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff100b203092af77d1a5a7abe085b3506b7eaaf9abf65b73b7d6905b6cb76988"}, + {file = "regex-2023.12.25-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cc038b2d8b1470364b1888a98fd22d616fba2b6309c5b5f181ad4483e0017861"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:094ba386bb5c01e54e14434d4caabf6583334090865b23ef58e0424a6286d3dc"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:5cd05d0f57846d8ba4b71d9c00f6f37d6b97d5e5ef8b3c3840426a475c8f70f4"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:9aa1a67bbf0f957bbe096375887b2505f5d8ae16bf04488e8b0f334c36e31360"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:98a2636994f943b871786c9e82bfe7883ecdaba2ef5df54e1450fa9869d1f756"}, + {file = "regex-2023.12.25-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:37f8e93a81fc5e5bd8db7e10e62dc64261bcd88f8d7e6640aaebe9bc180d9ce2"}, + {file = "regex-2023.12.25-cp38-cp38-win32.whl", hash = "sha256:d78bd484930c1da2b9679290a41cdb25cc127d783768a0369d6b449e72f88beb"}, + {file = "regex-2023.12.25-cp38-cp38-win_amd64.whl", hash = "sha256:b521dcecebc5b978b447f0f69b5b7f3840eac454862270406a39837ffae4e697"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f7bc09bc9c29ebead055bcba136a67378f03d66bf359e87d0f7c759d6d4ffa31"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e14b73607d6231f3cc4622809c196b540a6a44e903bcfad940779c80dffa7be7"}, + {file = "regex-2023.12.25-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9eda5f7a50141291beda3edd00abc2d4a5b16c29c92daf8d5bd76934150f3edc"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc6bb9aa69aacf0f6032c307da718f61a40cf970849e471254e0e91c56ffca95"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:298dc6354d414bc921581be85695d18912bea163a8b23cac9a2562bbcd5088b1"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f4e475a80ecbd15896a976aa0b386c5525d0ed34d5c600b6d3ebac0a67c7ddf"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:531ac6cf22b53e0696f8e1d56ce2396311254eb806111ddd3922c9d937151dae"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22f3470f7524b6da61e2020672df2f3063676aff444db1daa283c2ea4ed259d6"}, + {file = "regex-2023.12.25-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:89723d2112697feaa320c9d351e5f5e7b841e83f8b143dba8e2d2b5f04e10923"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0ecf44ddf9171cd7566ef1768047f6e66975788258b1c6c6ca78098b95cf9a3d"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:905466ad1702ed4acfd67a902af50b8db1feeb9781436372261808df7a2a7bca"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:4558410b7a5607a645e9804a3e9dd509af12fb72b9825b13791a37cd417d73a5"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:7e316026cc1095f2a3e8cc012822c99f413b702eaa2ca5408a513609488cb62f"}, + {file = "regex-2023.12.25-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3b1de218d5375cd6ac4b5493e0b9f3df2be331e86520f23382f216c137913d20"}, + {file = "regex-2023.12.25-cp39-cp39-win32.whl", hash = "sha256:11a963f8e25ab5c61348d090bf1b07f1953929c13bd2309a0662e9ff680763c9"}, + {file = "regex-2023.12.25-cp39-cp39-win_amd64.whl", hash = "sha256:e693e233ac92ba83a87024e1d32b5f9ab15ca55ddd916d878146f4e3406b5c91"}, + {file = "regex-2023.12.25.tar.gz", hash = "sha256:29171aa128da69afdf4bde412d5bedc335f2ca8fcfe4489038577d05f16181e5"}, ] [[package]] @@ -2774,6 +2743,114 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9 [package.extras] jupyter = ["ipywidgets (>=7.5.1,<9)"] +[[package]] +name = "rpds-py" +version = "0.17.1" +description = "Python bindings to Rust's persistent data structures (rpds)" +optional = false +python-versions = ">=3.8" +files = [ + {file = "rpds_py-0.17.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d"}, + {file = "rpds_py-0.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9"}, + {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453"}, + {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc"}, + {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394"}, + {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59"}, + {file = "rpds_py-0.17.1-cp310-none-win32.whl", hash = "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d"}, + {file = "rpds_py-0.17.1-cp310-none-win_amd64.whl", hash = "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6"}, + {file = "rpds_py-0.17.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b"}, + {file = "rpds_py-0.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8"}, + {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a"}, + {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383"}, + {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd"}, + {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea"}, + {file = "rpds_py-0.17.1-cp311-none-win32.whl", hash = "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518"}, + {file = "rpds_py-0.17.1-cp311-none-win_amd64.whl", hash = "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf"}, + {file = "rpds_py-0.17.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf"}, + {file = "rpds_py-0.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9"}, + {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140"}, + {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2"}, + {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253"}, + {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23"}, + {file = "rpds_py-0.17.1-cp312-none-win32.whl", hash = "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1"}, + {file = "rpds_py-0.17.1-cp312-none-win_amd64.whl", hash = "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3"}, + {file = "rpds_py-0.17.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d"}, + {file = "rpds_py-0.17.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae"}, + {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4"}, + {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896"}, + {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde"}, + {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6"}, + {file = "rpds_py-0.17.1-cp38-none-win32.whl", hash = "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a"}, + {file = "rpds_py-0.17.1-cp38-none-win_amd64.whl", hash = "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb"}, + {file = "rpds_py-0.17.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a"}, + {file = "rpds_py-0.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256"}, + {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74"}, + {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4"}, + {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772"}, + {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b"}, + {file = "rpds_py-0.17.1-cp39-none-win32.whl", hash = "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f"}, + {file = "rpds_py-0.17.1-cp39-none-win_amd64.whl", hash = "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6"}, + {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb"}, + {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296"}, + {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68"}, + {file = "rpds_py-0.17.1.tar.gz", hash = "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7"}, +] + [[package]] name = "ruff" version = "0.2.0" @@ -2802,13 +2879,13 @@ files = [ [[package]] name = "s3transfer" -version = "0.8.2" +version = "0.10.0" description = "An Amazon S3 Transfer Manager" optional = false -python-versions = ">= 3.7" +python-versions = ">= 3.8" files = [ - {file = "s3transfer-0.8.2-py3-none-any.whl", hash = "sha256:c9e56cbe88b28d8e197cf841f1f0c130f246595e77ae5b5a05b69fe7cb83de76"}, - {file = "s3transfer-0.8.2.tar.gz", hash = "sha256:368ac6876a9e9ed91f6bc86581e319be08188dc60d50e0d56308ed5765446283"}, + {file = "s3transfer-0.10.0-py3-none-any.whl", hash = "sha256:3cdb40f5cfa6966e812209d0994f2a4709b561c88e90cf00c2696d2df4e56b2e"}, + {file = "s3transfer-0.10.0.tar.gz", hash = "sha256:d0c8bbf672d5eebbe4e57945e23b972d963f07d82f661cabf678a5c88831595b"}, ] [package.dependencies] @@ -2834,13 +2911,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.0" +version = "1.40.1" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.0.tar.gz", hash = "sha256:34ad8cfc9b877aaa2a8eb86bfe5296a467fffe0619b931a05b181c45f6da59bf"}, - {file = "sentry_sdk-1.40.0-py2.py3-none-any.whl", hash = "sha256:78575620331186d32f34b7ece6edea97ce751f58df822547d3ab85517881a27a"}, + {file = "sentry-sdk-1.40.1.tar.gz", hash = "sha256:1bb9cf4ac317906d20787693b5e7f3e42160a90e8bbf1fc544f91c52fa76b68f"}, + {file = "sentry_sdk-1.40.1-py2.py3-none-any.whl", hash = "sha256:69fc5e7512371547207821d801485f45e3c62db629f02f56f58431a10864ac34"}, ] [package.dependencies] @@ -2866,7 +2943,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure-eval"] +pure-eval = ["asttokens", "executing", "pure_eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] @@ -2928,13 +3005,13 @@ files = [ [[package]] name = "stevedore" -version = "3.5.2" +version = "5.1.0" description = "Manage dynamic plugins for Python applications" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "stevedore-3.5.2-py3-none-any.whl", hash = "sha256:fa2630e3d0ad3e22d4914aff2501445815b9a4467a6edc49387c667a38faf5bf"}, - {file = "stevedore-3.5.2.tar.gz", hash = "sha256:cf99f41fc0d5a4f185ca4d3d42b03be9011b0a1ec1a4ea1a282be1b4b306dcc2"}, + {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, + {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, ] [package.dependencies] @@ -2942,13 +3019,13 @@ pbr = ">=2.0.0,<2.1.0 || >2.1.0" [[package]] name = "sympy" -version = "1.10.1" +version = "1.12" description = "Computer algebra system (CAS) in Python" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "sympy-1.10.1-py3-none-any.whl", hash = "sha256:df75d738930f6fe9ebe7034e59d56698f29e85f443f743e51e47df0caccc2130"}, - {file = "sympy-1.10.1.tar.gz", hash = "sha256:5939eeffdf9e152172601463626c022a2c27e75cf6278de8d401d50c9d58787b"}, + {file = "sympy-1.12-py3-none-any.whl", hash = "sha256:c3588cd4295d0c0f603d0f2ae780587e64e2efeedb3521e46b9bb1d08d184fa5"}, + {file = "sympy-1.12.tar.gz", hash = "sha256:ebf595c8dac3e0fdc4152c51878b498396ec7f30e7a914d6071e674d49420fb8"}, ] [package.dependencies] @@ -3016,13 +3093,13 @@ test = ["mypy", "pytest", "typing-extensions"] [[package]] name = "types-pyopenssl" -version = "23.3.0.0" +version = "24.0.0.20240130" description = "Typing stubs for pyOpenSSL" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "types-pyOpenSSL-23.3.0.0.tar.gz", hash = "sha256:5ffb077fe70b699c88d5caab999ae80e192fe28bf6cda7989b7e79b1e4e2dcd3"}, - {file = "types_pyOpenSSL-23.3.0.0-py3-none-any.whl", hash = "sha256:00171433653265843b7469ddb9f3c86d698668064cc33ef10537822156130ebf"}, + {file = "types-pyOpenSSL-24.0.0.20240130.tar.gz", hash = "sha256:c812e5c1c35249f75ef5935708b2a997d62abf9745be222e5f94b9595472ab25"}, + {file = "types_pyOpenSSL-24.0.0.20240130-py3-none-any.whl", hash = "sha256:24a255458b5b8a7fca8139cf56f2a8ad5a4f1a5f711b73a5bb9cb50dc688fab5"}, ] [package.dependencies] @@ -3041,13 +3118,13 @@ files = [ [[package]] name = "types-redis" -version = "4.6.0.11" +version = "4.6.0.20240106" description = "Typing stubs for redis" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "types-redis-4.6.0.11.tar.gz", hash = "sha256:c8cfc84635183deca2db4a528966c5566445fd3713983f0034fb0f5a09e0890d"}, - {file = "types_redis-4.6.0.11-py3-none-any.whl", hash = "sha256:94fc61118601fb4f79206b33b9f4344acff7ca1d7bba67834987fb0efcf6a770"}, + {file = "types-redis-4.6.0.20240106.tar.gz", hash = "sha256:2b2fa3a78f84559616242d23f86de5f4130dfd6c3b83fb2d8ce3329e503f756e"}, + {file = "types_redis-4.6.0.20240106-py3-none-any.whl", hash = "sha256:912de6507b631934bd225cdac310b04a58def94391003ba83939e5a10e99568d"}, ] [package.dependencies] @@ -3068,6 +3145,20 @@ files = [ [package.dependencies] types-urllib3 = "*" +[[package]] +name = "types-requests" +version = "2.31.0.20240125" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-requests-2.31.0.20240125.tar.gz", hash = "sha256:03a28ce1d7cd54199148e043b2079cdded22d6795d19a2c2a6791a4b2b5e2eb5"}, + {file = "types_requests-2.31.0.20240125-py3-none-any.whl", hash = "sha256:9592a9a4cb92d6d75d9b491a41477272b710e021011a2a3061157e2fb1f1a5d1"}, +] + +[package.dependencies] +urllib3 = ">=2" + [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -3081,13 +3172,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.7.1" -description = "Backported and Experimental Type Hints for Python 3.7+" +version = "4.9.0" +description = "Backported and Experimental Type Hints for Python 3.8+" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"}, - {file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"}, + {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, + {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, ] [[package]] @@ -3139,59 +3230,45 @@ test = ["coverage", "flake8 (>=3.7)", "mypy", "pretend", "pytest"] [[package]] name = "watchdog" -version = "3.0.0" +version = "4.0.0" description = "Filesystem events monitoring" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:336adfc6f5cc4e037d52db31194f7581ff744b67382eb6021c868322e32eef41"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a70a8dcde91be523c35b2bf96196edc5730edb347e374c7de7cd20c43ed95397"}, - {file = "watchdog-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:adfdeab2da79ea2f76f87eb42a3ab1966a5313e5a69a0213a3cc06ef692b0e96"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2b57a1e730af3156d13b7fdddfc23dea6487fceca29fc75c5a868beed29177ae"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7ade88d0d778b1b222adebcc0927428f883db07017618a5e684fd03b83342bd9"}, - {file = "watchdog-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7e447d172af52ad204d19982739aa2346245cc5ba6f579d16dac4bfec226d2e7"}, - {file = "watchdog-3.0.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:9fac43a7466eb73e64a9940ac9ed6369baa39b3bf221ae23493a9ec4d0022674"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:8ae9cda41fa114e28faf86cb137d751a17ffd0316d1c34ccf2235e8a84365c7f"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:25f70b4aa53bd743729c7475d7ec41093a580528b100e9a8c5b5efe8899592fc"}, - {file = "watchdog-3.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4f94069eb16657d2c6faada4624c39464f65c05606af50bb7902e036e3219be3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:7c5f84b5194c24dd573fa6472685b2a27cc5a17fe5f7b6fd40345378ca6812e3"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3aa7f6a12e831ddfe78cdd4f8996af9cf334fd6346531b16cec61c3b3c0d8da0"}, - {file = "watchdog-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:233b5817932685d39a7896b1090353fc8efc1ef99c9c054e46c8002561252fb8"}, - {file = "watchdog-3.0.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:13bbbb462ee42ec3c5723e1205be8ced776f05b100e4737518c67c8325cf6100"}, - {file = "watchdog-3.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:8f3ceecd20d71067c7fd4c9e832d4e22584318983cabc013dbf3f70ea95de346"}, - {file = "watchdog-3.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:c9d8c8ec7efb887333cf71e328e39cffbf771d8f8f95d308ea4125bf5f90ba64"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:0e06ab8858a76e1219e68c7573dfeba9dd1c0219476c5a44d5333b01d7e1743a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:d00e6be486affb5781468457b21a6cbe848c33ef43f9ea4a73b4882e5f188a44"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:c07253088265c363d1ddf4b3cdb808d59a0468ecd017770ed716991620b8f77a"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:5113334cf8cf0ac8cd45e1f8309a603291b614191c9add34d33075727a967709"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:51f90f73b4697bac9c9a78394c3acbbd331ccd3655c11be1a15ae6fe289a8c83"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:ba07e92756c97e3aca0912b5cbc4e5ad802f4557212788e72a72a47ff376950d"}, - {file = "watchdog-3.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:d429c2430c93b7903914e4db9a966c7f2b068dd2ebdd2fa9b9ce094c7d459f33"}, - {file = "watchdog-3.0.0-py3-none-win32.whl", hash = "sha256:3ed7c71a9dccfe838c2f0b6314ed0d9b22e77d268c67e015450a29036a81f60f"}, - {file = "watchdog-3.0.0-py3-none-win_amd64.whl", hash = "sha256:4c9956d27be0bb08fc5f30d9d0179a855436e655f046d288e2bcc11adfae893c"}, - {file = "watchdog-3.0.0-py3-none-win_ia64.whl", hash = "sha256:5d9f3a10e02d7371cd929b5d8f11e87d4bad890212ed3901f9b4d68767bee759"}, - {file = "watchdog-3.0.0.tar.gz", hash = "sha256:4d98a320595da7a7c5a18fc48cb633c2e73cda78f93cac2ef42d42bf609a33f9"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b"}, + {file = "watchdog-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935"}, + {file = "watchdog-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19"}, + {file = "watchdog-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4"}, + {file = "watchdog-4.0.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca"}, + {file = "watchdog-4.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8"}, + {file = "watchdog-4.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b"}, + {file = "watchdog-4.0.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92"}, + {file = "watchdog-4.0.0-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87"}, + {file = "watchdog-4.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269"}, + {file = "watchdog-4.0.0-py3-none-win32.whl", hash = "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c"}, + {file = "watchdog-4.0.0-py3-none-win_amd64.whl", hash = "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245"}, + {file = "watchdog-4.0.0-py3-none-win_ia64.whl", hash = "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7"}, + {file = "watchdog-4.0.0.tar.gz", hash = "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec"}, ] [package.extras] watchmedo = ["PyYAML (>=3.10)"] -[[package]] -name = "websocket-client" -version = "1.6.1" -description = "WebSocket client for Python with low level API options" -optional = false -python-versions = ">=3.7" -files = [ - {file = "websocket-client-1.6.1.tar.gz", hash = "sha256:c951af98631d24f8df89ab1019fc365f2227c0892f12fd150e935607c79dd0dd"}, - {file = "websocket_client-1.6.1-py3-none-any.whl", hash = "sha256:f1f9f2ad5291f0225a49efad77abf9e700b6fef553900623060dad6e26503b9d"}, -] - -[package.extras] -docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] -optional = ["python-socks", "wsaccel"] -test = ["websockets"] - [[package]] name = "wrapt" version = "1.16.0" @@ -3300,18 +3377,18 @@ files = [ [[package]] name = "zipp" -version = "3.15.0" +version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "zipp-3.15.0-py3-none-any.whl", hash = "sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556"}, - {file = "zipp-3.15.0.tar.gz", hash = "sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b"}, + {file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"}, + {file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"}, ] [package.extras] -docs = ["furo", "jaraco.packaging (>=9)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["big-O", "flake8 (<5)", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=1.3)", "pytest-flake8", "pytest-mypy (>=0.9.1)"] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [extras] all = ["aws-encryption-sdk", "aws-xray-sdk", "fastjsonschema", "jsonpath-ng", "pydantic"] @@ -3326,4 +3403,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "1eb623d82065a5ab34897f92712b38bb28e8d316ed307a38ece0427a58d80545" +content-hash = "058f1f2829446f693461297b8e6ac7e572d5cfb11b05a858105a486a1e09e8ab" diff --git a/pyproject.toml b/pyproject.toml index 36767102e12..9ba69af8ef8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,15 +43,14 @@ aws-xray-sdk = { version = "^2.8.0", optional = true } fastjsonschema = { version = "^2.14.5", optional = true } pydantic = { version = "^1.8.2", optional = true } boto3 = { version = "^1.26.164", optional = true } -redis = {version = ">=4.4,<6.0", optional = true} +redis = { version = ">=4.4,<6.0", optional = true } typing-extensions = "^4.6.2" datadog-lambda = { version = ">=4.77,<6.0", optional = true } aws-encryption-sdk = { version = "^3.1.1", optional = true } jsonpath-ng = { version = "^1.6.0", optional = true } -aws-cdk-lib = "^2.126.0" [tool.poetry.dev-dependencies] -coverage = {extras = ["toml"], version = "^7.4"} +coverage = { extras = ["toml"], version = "^7.4" } pytest = "^8.0.0" black = "^23.3" boto3 = "^1.26.164" @@ -66,7 +65,7 @@ xenon = "^0.9.1" mkdocs-git-revision-date-plugin = "^0.3.2" mike = "^1.1.2" pytest-xdist = "^3.5.0" -aws-cdk-lib = "^2.111.0" +aws-cdk-lib = "^2.126.0" "aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" @@ -88,7 +87,7 @@ filelock = "^3.12.2" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.34.24" ijson = "^3.2.2" -typed-ast = { version = "^1.5.5", python = "< 3.8"} +typed-ast = { version = "^1.5.5", python = "< 3.8" } hvac = "^1.2.1" aws-requests-auth = "^0.4.3" datadog-lambda = "^5.85.0" @@ -98,7 +97,13 @@ parser = ["pydantic"] validation = ["fastjsonschema"] tracer = ["aws-xray-sdk"] redis = ["redis"] -all = ["pydantic", "aws-xray-sdk", "fastjsonschema", "aws-encryption-sdk", "jsonpath-ng"] +all = [ + "pydantic", + "aws-xray-sdk", + "fastjsonschema", + "aws-encryption-sdk", + "jsonpath-ng", +] # allow customers to run code locally without emulators (SAM CLI, etc.) aws-sdk = ["boto3"] datadog = ["datadog-lambda"] @@ -114,7 +119,7 @@ ruff = ">=0.0.272,<0.2.1" retry2 = "^0.9.5" pytest-socket = "^0.6.0" types-redis = "^4.6.0.7" -testcontainers = {extras = ["redis"], version = "^3.7.1"} +testcontainers = { extras = ["redis"], version = "^3.7.1" } [tool.coverage.run] source = ["aws_lambda_powertools"] From 78efd998fb8c95b9d8b2c4a4764d345efd31de64 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:09:13 +0100 Subject: [PATCH 0069/2666] chore(deps): bump squidfunk/mkdocs-material from `e0d6c67` to `6a72238` in /docs (#3735) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `e0d6c67` to `6a72238`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 640182ff441..9de94938c2b 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:e0d6c671fa3d5cf332043a5231c6f0cd68f48607e9edf710c2f3a57a74dbdc93 +FROM squidfunk/mkdocs-material@sha256:6a72238e24c73e4cebb1ceddf8603778d25739ffbf480a314628a3d81aee2214 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From 6af6d90a17a699d9d0e0f6d0caab69007ea07867 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:09:52 +0100 Subject: [PATCH 0070/2666] chore(deps-dev): bump sentry-sdk from 1.40.1 to 1.40.2 (#3740) Bumps [sentry-sdk](https://github.com/getsentry/sentry-python) from 1.40.1 to 1.40.2. - [Release notes](https://github.com/getsentry/sentry-python/releases) - [Changelog](https://github.com/getsentry/sentry-python/blob/master/CHANGELOG.md) - [Commits](https://github.com/getsentry/sentry-python/compare/1.40.1...1.40.2) --- updated-dependencies: - dependency-name: sentry-sdk dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simon Thulbourn --- poetry.lock | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/poetry.lock b/poetry.lock index 947f35da799..15eab793176 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1209,6 +1209,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -2486,6 +2497,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2493,8 +2505,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2511,6 +2531,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2518,6 +2539,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2911,13 +2933,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.1" +version = "1.40.2" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.1.tar.gz", hash = "sha256:1bb9cf4ac317906d20787693b5e7f3e42160a90e8bbf1fc544f91c52fa76b68f"}, - {file = "sentry_sdk-1.40.1-py2.py3-none-any.whl", hash = "sha256:69fc5e7512371547207821d801485f45e3c62db629f02f56f58431a10864ac34"}, + {file = "sentry-sdk-1.40.2.tar.gz", hash = "sha256:c98c8e9bb4dc8ff1e67473caf6467acfccf915dadcc26d0efb0d6791a8652610"}, + {file = "sentry_sdk-1.40.2-py2.py3-none-any.whl", hash = "sha256:696ef61a323a207e6a20b018ddc6591adb81c671434c88d1a4f2e95ffa75556c"}, ] [package.dependencies] @@ -3145,20 +3167,6 @@ files = [ [package.dependencies] types-urllib3 = "*" -[[package]] -name = "types-requests" -version = "2.31.0.20240125" -description = "Typing stubs for requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-requests-2.31.0.20240125.tar.gz", hash = "sha256:03a28ce1d7cd54199148e043b2079cdded22d6795d19a2c2a6791a4b2b5e2eb5"}, - {file = "types_requests-2.31.0.20240125-py3-none-any.whl", hash = "sha256:9592a9a4cb92d6d75d9b491a41477272b710e021011a2a3061157e2fb1f1a5d1"}, -] - -[package.dependencies] -urllib3 = ">=2" - [[package]] name = "types-urllib3" version = "1.26.25.14" From 79bf2f335608d9391507e28c8a43de2537c45d0e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:11:17 +0100 Subject: [PATCH 0071/2666] chore(deps-dev): bump black from 23.12.1 to 24.1.1 (#3739) Bumps [black](https://github.com/psf/black) from 23.12.1 to 24.1.1. - [Release notes](https://github.com/psf/black/releases) - [Changelog](https://github.com/psf/black/blob/main/CHANGES.md) - [Commits](https://github.com/psf/black/compare/23.12.1...24.1.1) --- updated-dependencies: - dependency-name: black dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simon Thulbourn --- poetry.lock | 48 ++++++++++++++++++++++++------------------------ pyproject.toml | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/poetry.lock b/poetry.lock index 15eab793176..a1ec91a5657 100644 --- a/poetry.lock +++ b/poetry.lock @@ -284,33 +284,33 @@ yaml = ["PyYAML"] [[package]] name = "black" -version = "23.12.1" +version = "24.1.1" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-23.12.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e0aaf6041986767a5e0ce663c7a2f0e9eaf21e6ff87a5f95cbf3675bfd4c41d2"}, - {file = "black-23.12.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c88b3711d12905b74206227109272673edce0cb29f27e1385f33b0163c414bba"}, - {file = "black-23.12.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a920b569dc6b3472513ba6ddea21f440d4b4c699494d2e972a1753cdc25df7b0"}, - {file = "black-23.12.1-cp310-cp310-win_amd64.whl", hash = "sha256:3fa4be75ef2a6b96ea8d92b1587dd8cb3a35c7e3d51f0738ced0781c3aa3a5a3"}, - {file = "black-23.12.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8d4df77958a622f9b5a4c96edb4b8c0034f8434032ab11077ec6c56ae9f384ba"}, - {file = "black-23.12.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:602cfb1196dc692424c70b6507593a2b29aac0547c1be9a1d1365f0d964c353b"}, - {file = "black-23.12.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c4352800f14be5b4864016882cdba10755bd50805c95f728011bcb47a4afd59"}, - {file = "black-23.12.1-cp311-cp311-win_amd64.whl", hash = "sha256:0808494f2b2df923ffc5723ed3c7b096bd76341f6213989759287611e9837d50"}, - {file = "black-23.12.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:25e57fd232a6d6ff3f4478a6fd0580838e47c93c83eaf1ccc92d4faf27112c4e"}, - {file = "black-23.12.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2d9e13db441c509a3763a7a3d9a49ccc1b4e974a47be4e08ade2a228876500ec"}, - {file = "black-23.12.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d1bd9c210f8b109b1762ec9fd36592fdd528485aadb3f5849b2740ef17e674e"}, - {file = "black-23.12.1-cp312-cp312-win_amd64.whl", hash = "sha256:ae76c22bde5cbb6bfd211ec343ded2163bba7883c7bc77f6b756a1049436fbb9"}, - {file = "black-23.12.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1fa88a0f74e50e4487477bc0bb900c6781dbddfdfa32691e780bf854c3b4a47f"}, - {file = "black-23.12.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a4d6a9668e45ad99d2f8ec70d5c8c04ef4f32f648ef39048d010b0689832ec6d"}, - {file = "black-23.12.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b18fb2ae6c4bb63eebe5be6bd869ba2f14fd0259bda7d18a46b764d8fb86298a"}, - {file = "black-23.12.1-cp38-cp38-win_amd64.whl", hash = "sha256:c04b6d9d20e9c13f43eee8ea87d44156b8505ca8a3c878773f68b4e4812a421e"}, - {file = "black-23.12.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3e1b38b3135fd4c025c28c55ddfc236b05af657828a8a6abe5deec419a0b7055"}, - {file = "black-23.12.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4f0031eaa7b921db76decd73636ef3a12c942ed367d8c3841a0739412b260a54"}, - {file = "black-23.12.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97e56155c6b737854e60a9ab1c598ff2533d57e7506d97af5481141671abf3ea"}, - {file = "black-23.12.1-cp39-cp39-win_amd64.whl", hash = "sha256:dd15245c8b68fe2b6bd0f32c1556509d11bb33aec9b5d0866dd8e2ed3dba09c2"}, - {file = "black-23.12.1-py3-none-any.whl", hash = "sha256:78baad24af0f033958cad29731e27363183e140962595def56423e626f4bee3e"}, - {file = "black-23.12.1.tar.gz", hash = "sha256:4ce3ef14ebe8d9509188014d96af1c456a910d5b5cbf434a09fef7e024b3d0d5"}, + {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, + {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, + {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, + {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, + {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, + {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, + {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, + {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, + {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, + {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, + {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, + {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, + {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, + {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, + {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, + {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, + {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, + {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, + {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, + {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, + {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, + {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, ] [package.dependencies] @@ -3411,4 +3411,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "058f1f2829446f693461297b8e6ac7e572d5cfb11b05a858105a486a1e09e8ab" +content-hash = "a7aae4ce82b15addf96ee3a072dc4133781746e78f5b64973d7ec3a555871c8b" diff --git a/pyproject.toml b/pyproject.toml index 9ba69af8ef8..8a11a223dc9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] coverage = { extras = ["toml"], version = "^7.4" } pytest = "^8.0.0" -black = "^23.3" +black = "^24.1" boto3 = "^1.26.164" isort = "^5.13.2" pytest-cov = "^4.1.0" From 6758f80bee8b770c69126acf989a24ffe56fabc9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 17:14:19 +0100 Subject: [PATCH 0072/2666] chore(deps): bump actions/setup-node from 4.0.1 to 4.0.2 (#3737) Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4.0.1 to 4.0.2. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8...60edb5dd545a775178f52524783378180af0d1f8) --- updated-dependencies: - dependency-name: actions/setup-node dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Simon Thulbourn --- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- .github/workflows/reusable_deploy_v2_sar.yml | 2 +- .github/workflows/run-e2e-tests.yml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index f9a5bded5e0..3dfb4cc1446 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -101,7 +101,7 @@ jobs: - name: Install poetry run: pipx install git+https://github.com/python-poetry/poetry@68b88e5390720a3dd84f02940ec5200bfce39ac6 # v1.5.0 - name: Setup Node.js - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: "16.12" - name: Setup python diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index e0441015fe6..dd7c5384970 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -158,7 +158,7 @@ jobs: aws-region: ${{ matrix.region }} role-to-assume: ${{ secrets.AWS_LAYERS_ROLE_ARN }} - name: Setup Node.js - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: "16.12" - name: Setup python diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml index 8fc0480f319..96c8dd1b6cd 100644 --- a/.github/workflows/reusable_deploy_v2_sar.yml +++ b/.github/workflows/reusable_deploy_v2_sar.yml @@ -111,7 +111,7 @@ jobs: aws-region: ${{ env.AWS_REGION }} role-to-assume: ${{ secrets.AWS_SAR_V2_ROLE_ARN }} - name: Setup Node.js - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: ${{ env.NODE_VERSION }} - name: Download artifact diff --git a/.github/workflows/run-e2e-tests.yml b/.github/workflows/run-e2e-tests.yml index 5780bba255b..bbfeb28c349 100644 --- a/.github/workflows/run-e2e-tests.yml +++ b/.github/workflows/run-e2e-tests.yml @@ -61,7 +61,7 @@ jobs: architecture: "x64" cache: "poetry" - name: Setup Node.js - uses: actions/setup-node@b39b52d1213e96004bfcb1c61a8a6fa8ab84f3e8 # v4.0.1 + uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2 with: node-version: "20.10.0" - name: Install CDK CLI From 9b00d0a690077cc6df227556ad45055b8febc4b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 8 Feb 2024 23:57:40 +0100 Subject: [PATCH 0073/2666] chore(deps-dev): bump ruff from 0.2.0 to 0.2.1 (#3742) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.0 to 0.2.1. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.2.0...v0.2.1) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index a1ec91a5657..f80231a5df1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2875,28 +2875,28 @@ files = [ [[package]] name = "ruff" -version = "0.2.0" +version = "0.2.1" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:638ea3294f800d18bae84a492cb5a245c8d29c90d19a91d8e338937a4c27fca0"}, - {file = "ruff-0.2.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3ff35433fcf4dff6d610738712152df6b7d92351a1bde8e00bd405b08b3d5759"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf9faafbdcf4f53917019f2c230766da437d4fd5caecd12ddb68bb6a17d74399"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8153a3e4128ed770871c47545f1ae7b055023e0c222ff72a759f5a341ee06483"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8a75a98ae989a27090e9c51f763990ad5bbc92d20626d54e9701c7fe597f399"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:87057dd2fdde297130ff99553be8549ca38a2965871462a97394c22ed2dfc19d"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6d232f99d3ab00094ebaf88e0fb7a8ccacaa54cc7fa3b8993d9627a11e6aed7a"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3d3c641f95f435fc6754b05591774a17df41648f0daf3de0d75ad3d9f099ab92"}, - {file = "ruff-0.2.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3826fb34c144ef1e171b323ed6ae9146ab76d109960addca730756dc19dc7b22"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:eceab7d85d09321b4de18b62d38710cf296cb49e98979960a59c6b9307c18cfe"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:30ad74687e1f4a9ff8e513b20b82ccadb6bd796fe5697f1e417189c5cde6be3e"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a7e3818698f8460bd0f8d4322bbe99db8327e9bc2c93c789d3159f5b335f47da"}, - {file = "ruff-0.2.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:edf23041242c48b0d8295214783ef543847ef29e8226d9f69bf96592dba82a83"}, - {file = "ruff-0.2.0-py3-none-win32.whl", hash = "sha256:e155147199c2714ff52385b760fe242bb99ea64b240a9ffbd6a5918eb1268843"}, - {file = "ruff-0.2.0-py3-none-win_amd64.whl", hash = "sha256:ba918e01cdd21e81b07555564f40d307b0caafa9a7a65742e98ff244f5035c59"}, - {file = "ruff-0.2.0-py3-none-win_arm64.whl", hash = "sha256:3fbaff1ba9564a2c5943f8f38bc221f04bac687cc7485e45237579fee7ccda79"}, - {file = "ruff-0.2.0.tar.gz", hash = "sha256:63856b91837606c673537d2889989733d7dffde553828d3b0f0bacfa6def54be"}, + {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dd81b911d28925e7e8b323e8d06951554655021df8dd4ac3045d7212ac4ba080"}, + {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dc586724a95b7d980aa17f671e173df00f0a2eef23f8babbeee663229a938fec"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92db7101ef5bfc18e96777ed7bc7c822d545fa5977e90a585accac43d22f18a"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13471684694d41ae0f1e8e3a7497e14cd57ccb7dd72ae08d56a159d6c9c3e30e"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a11567e20ea39d1f51aebd778685582d4c56ccb082c1161ffc10f79bebe6df35"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:00a818e2db63659570403e44383ab03c529c2b9678ba4ba6c105af7854008105"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be60592f9d218b52f03384d1325efa9d3b41e4c4d55ea022cd548547cc42cd2b"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbd2288890b88e8aab4499e55148805b58ec711053588cc2f0196a44f6e3d855"}, + {file = "ruff-0.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ef052283da7dec1987bba8d8733051c2325654641dfe5877a4022108098683"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7022d66366d6fded4ba3889f73cd791c2d5621b2ccf34befc752cb0df70f5fad"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0a725823cb2a3f08ee743a534cb6935727d9e47409e4ad72c10a3faf042ad5ba"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0034d5b6323e6e8fe91b2a1e55b02d92d0b582d2953a2b37a67a2d7dedbb7acc"}, + {file = "ruff-0.2.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e5cb5526d69bb9143c2e4d2a115d08ffca3d8e0fddc84925a7b54931c96f5c02"}, + {file = "ruff-0.2.1-py3-none-win32.whl", hash = "sha256:6b95ac9ce49b4fb390634d46d6ece32ace3acdd52814671ccaf20b7f60adb232"}, + {file = "ruff-0.2.1-py3-none-win_amd64.whl", hash = "sha256:e3affdcbc2afb6f5bd0eb3130139ceedc5e3f28d206fe49f63073cb9e65988e0"}, + {file = "ruff-0.2.1-py3-none-win_arm64.whl", hash = "sha256:efababa8e12330aa94a53e90a81eb6e2d55f348bc2e71adbf17d9cad23c03ee6"}, + {file = "ruff-0.2.1.tar.gz", hash = "sha256:3b42b5d8677cd0c72b99fcaf068ffc62abb5a19e71b4a3b9cfa50658a0af02f1"}, ] [[package]] @@ -3411,4 +3411,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "a7aae4ce82b15addf96ee3a072dc4133781746e78f5b64973d7ec3a555871c8b" +content-hash = "e89f5744ae45049f03bae49899a58b3a387e69279bc67d1a83376cefe8f3dccd" diff --git a/pyproject.toml b/pyproject.toml index 8a11a223dc9..f92dc913a57 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,7 +115,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.27.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.2.1" +ruff = ">=0.0.272,<0.2.2" retry2 = "^0.9.5" pytest-socket = "^0.6.0" types-redis = "^4.6.0.7" From 9d646c4d07e55ecced385fa420ff38797cbfbc90 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 10:45:56 +0100 Subject: [PATCH 0074/2666] chore(deps-dev): bump pytest-socket from 0.6.0 to 0.7.0 (#3721) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index f80231a5df1..a2c8f22861b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2405,17 +2405,17 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] [[package]] name = "pytest-socket" -version = "0.6.0" +version = "0.7.0" description = "Pytest Plugin to disable socket calls during tests" optional = false -python-versions = ">=3.7,<4.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "pytest_socket-0.6.0-py3-none-any.whl", hash = "sha256:cca72f134ff01e0023c402e78d31b32e68da3efdf3493bf7788f8eba86a6824c"}, - {file = "pytest_socket-0.6.0.tar.gz", hash = "sha256:363c1d67228315d4fc7912f1aabfd570de29d0e3db6217d61db5728adacd7138"}, + {file = "pytest_socket-0.7.0-py3-none-any.whl", hash = "sha256:7e0f4642177d55d317bbd58fc68c6bd9048d6eadb2d46a89307fa9221336ce45"}, + {file = "pytest_socket-0.7.0.tar.gz", hash = "sha256:71ab048cbbcb085c15a4423b73b619a8b35d6a307f46f78ea46be51b1b7e11b3"}, ] [package.dependencies] -pytest = ">=3.6.3" +pytest = ">=6.2.5" [[package]] name = "pytest-xdist" @@ -3411,4 +3411,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "e89f5744ae45049f03bae49899a58b3a387e69279bc67d1a83376cefe8f3dccd" +content-hash = "28e369064057dafc403fc2564caa4e3ac308ac52208cfe853fa35f516976ff24" diff --git a/pyproject.toml b/pyproject.toml index f92dc913a57..d6bc3342d64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,7 +117,7 @@ httpx = ">=0.23.3,<0.27.0" sentry-sdk = "^1.22.2" ruff = ">=0.0.272,<0.2.2" retry2 = "^0.9.5" -pytest-socket = "^0.6.0" +pytest-socket = ">=0.6,<0.8" types-redis = "^4.6.0.7" testcontainers = { extras = ["redis"], version = "^3.7.1" } From 5dc430c2493d230972d549c8c441dcfa391199c5 Mon Sep 17 00:00:00 2001 From: Nico Tonnhofer Date: Fri, 9 Feb 2024 12:53:11 +0100 Subject: [PATCH 0075/2666] fix(typing): make Response headers covariant (#3745) Co-authored-by: Heitor Lessa --- aws_lambda_powertools/event_handler/api_gateway.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py index 9260ede43e9..43b5bf139ea 100644 --- a/aws_lambda_powertools/event_handler/api_gateway.py +++ b/aws_lambda_powertools/event_handler/api_gateway.py @@ -17,6 +17,7 @@ Dict, Generic, List, + Mapping, Match, Optional, Pattern, @@ -200,7 +201,7 @@ def to_dict(self, origin: Optional[str]) -> Dict[str, str]: return {} # The origin matched an allowed origin, so return the CORS headers - headers: Dict[str, str] = { + headers = { "Access-Control-Allow-Origin": origin, "Access-Control-Allow-Headers": ",".join(sorted(self.allow_headers)), } @@ -222,7 +223,7 @@ def __init__( status_code: int, content_type: Optional[str] = None, body: Optional[ResponseT] = None, - headers: Optional[Dict[str, Union[str, List[str]]]] = None, + headers: Optional[Mapping[str, Union[str, List[str]]]] = None, cookies: Optional[List[Cookie]] = None, compress: Optional[bool] = None, ): @@ -237,7 +238,7 @@ def __init__( provided http headers body: Union[str, bytes, None] Optionally set the response body. Note: bytes body will be automatically base64 encoded - headers: dict[str, Union[str, List[str]]] + headers: Mapping[str, Union[str, List[str]]] Optionally set specific http headers. Setting "Content-Type" here would override the `content_type` value. cookies: list[Cookie] Optionally set cookies. @@ -245,7 +246,7 @@ def __init__( self.status_code = status_code self.body = body self.base64_encoded = False - self.headers: Dict[str, Union[str, List[str]]] = headers if headers else {} + self.headers: Dict[str, Union[str, List[str]]] = dict(headers) if headers else {} self.cookies = cookies or [] self.compress = compress self.content_type = content_type @@ -1940,7 +1941,7 @@ def _path_starts_with(path: str, prefix: str): def _not_found(self, method: str) -> ResponseBuilder: """Called when no matching route was found and includes support for the cors preflight response""" - headers: Dict[str, Union[str, List[str]]] = {} + headers = {} if self._cors: logger.debug("CORS is enabled, updating headers.") headers.update(self._cors.to_dict(self.current_event.get_header_value("Origin"))) From c5e7df64ebd880b31643d039a4c4efa9aabcc7c1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:01:08 +0100 Subject: [PATCH 0076/2666] chore(deps-dev): bump hvac from 1.2.1 to 2.1.0 (#3738) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- poetry.lock | 25 ++++++++----------------- pyproject.toml | 2 +- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/poetry.lock b/poetry.lock index a2c8f22861b..09329553a25 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1156,19 +1156,21 @@ socks = ["socksio (==1.*)"] [[package]] name = "hvac" -version = "1.2.1" +version = "2.1.0" description = "HashiCorp Vault API client" optional = false -python-versions = ">=3.6.2,<4.0.0" +python-versions = ">=3.8,<4.0" files = [ - {file = "hvac-1.2.1-py3-none-any.whl", hash = "sha256:cb87f5724be8fd5f57507f5d5a94e6c42d2675128b460bf3186f966e07d4db78"}, - {file = "hvac-1.2.1.tar.gz", hash = "sha256:c786e3dfa1f35239810e5317cccadbe358f49b8c9001a1f2f68b79a250b9f8a1"}, + {file = "hvac-2.1.0-py3-none-any.whl", hash = "sha256:73bc91e58c3fc7c6b8107cdaca9cb71fa0a893dfd80ffbc1c14e20f24c0c29d7"}, + {file = "hvac-2.1.0.tar.gz", hash = "sha256:b48bcda11a4ab0a7b6c47232c7ba7c87fda318ae2d4a7662800c465a78742894"}, ] [package.dependencies] -pyhcl = ">=0.4.4,<0.5.0" requests = ">=2.27.1,<3.0.0" +[package.extras] +parser = ["pyhcl (>=0.4.4,<0.5.0)"] + [[package]] name = "idna" version = "3.6" @@ -2279,17 +2281,6 @@ files = [ plugins = ["importlib-metadata"] windows-terminal = ["colorama (>=0.4.6)"] -[[package]] -name = "pyhcl" -version = "0.4.5" -description = "HCL configuration parser for python" -optional = false -python-versions = "*" -files = [ - {file = "pyhcl-0.4.5-py3-none-any.whl", hash = "sha256:30ee337d330d1f90c9f5ed8f49c468f66c8e6e43192bdc7c6ece1420beb3070c"}, - {file = "pyhcl-0.4.5.tar.gz", hash = "sha256:c47293a51ccdd25e18bb5c8c0ab0ffe355b37c87f8d6f9d3280dc41efd4740bc"}, -] - [[package]] name = "pymdown-extensions" version = "10.7" @@ -3411,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "28e369064057dafc403fc2564caa4e3ac308ac52208cfe853fa35f516976ff24" +content-hash = "e9b5704f5b3140785eacf0670b7ff2ea12e6732baef7f45c5c65c3b5d31d67bb" diff --git a/pyproject.toml b/pyproject.toml index d6bc3342d64..c152995dfeb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -88,7 +88,7 @@ checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.34.24" ijson = "^3.2.2" typed-ast = { version = "^1.5.5", python = "< 3.8" } -hvac = "^1.2.1" +hvac = "^2.1.0" aws-requests-auth = "^0.4.3" datadog-lambda = "^5.85.0" From 52dc1617f9b2d1454433ee4782e82525a647e6f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 13:06:36 +0100 Subject: [PATCH 0077/2666] chore(ci): changelog rebuild (#3744) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Heitor Lessa --- CHANGELOG.md | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e777c9a4daf..45aa708bb97 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,27 +4,37 @@ # Unreleased +## Documentation + +* Add nathan hanks post community ([#3727](https://github.com/aws-powertools/powertools-lambda-python/issues/3727)) + ## Maintenance * **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) * **ci:** enable Redis e2e tests ([#3718](https://github.com/aws-powertools/powertools-lambda-python/issues/3718)) -* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) -* **deps:** bump actions/upload-artifact from 3.1.3 to 4.3.1 ([#3714](https://github.com/aws-powertools/powertools-lambda-python/issues/3714)) -* **deps:** bump actions/download-artifact from 4.1.1 to 4.1.2 ([#3725](https://github.com/aws-powertools/powertools-lambda-python/issues/3725)) -* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) * **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) * **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) +* **deps:** bump actions/download-artifact from 4.1.1 to 4.1.2 ([#3725](https://github.com/aws-powertools/powertools-lambda-python/issues/3725)) +* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) +* **deps:** revert aws-cdk-lib as a runtime dep ([#3730](https://github.com/aws-powertools/powertools-lambda-python/issues/3730)) +* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) +* **deps:** bump actions/upload-artifact from 3.1.3 to 4.3.1 ([#3714](https://github.com/aws-powertools/powertools-lambda-python/issues/3714)) +* **deps:** bump squidfunk/mkdocs-material from `e0d6c67` to `6a72238` in /docs ([#3735](https://github.com/aws-powertools/powertools-lambda-python/issues/3735)) +* **deps:** bump actions/setup-node from 4.0.1 to 4.0.2 ([#3737](https://github.com/aws-powertools/powertools-lambda-python/issues/3737)) * **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) -* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) -* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) -* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) * **deps-dev:** bump mypy from 1.4.1 to 1.8.0 ([#3710](https://github.com/aws-powertools/powertools-lambda-python/issues/3710)) +* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) +* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) +* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) * **deps-dev:** bump pytest from 7.4.4 to 8.0.0 ([#3711](https://github.com/aws-powertools/powertools-lambda-python/issues/3711)) * **deps-dev:** bump types-python-dateutil from 2.8.19.14 to 2.8.19.20240106 ([#3720](https://github.com/aws-powertools/powertools-lambda-python/issues/3720)) -* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) -* **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) * **deps-dev:** bump cfn-lint from 0.83.8 to 0.85.0 ([#3724](https://github.com/aws-powertools/powertools-lambda-python/issues/3724)) * **deps-dev:** bump isort from 5.11.5 to 5.13.2 ([#3723](https://github.com/aws-powertools/powertools-lambda-python/issues/3723)) +* **deps-dev:** bump sentry-sdk from 1.40.1 to 1.40.2 ([#3740](https://github.com/aws-powertools/powertools-lambda-python/issues/3740)) +* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) +* **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) +* **deps-dev:** bump black from 23.12.1 to 24.1.1 ([#3739](https://github.com/aws-powertools/powertools-lambda-python/issues/3739)) +* **deps-dev:** bump ruff from 0.2.0 to 0.2.1 ([#3742](https://github.com/aws-powertools/powertools-lambda-python/issues/3742)) From 45abe7b6451c2e6ad4751fd285bfeddb78b2509f Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:19:23 +0100 Subject: [PATCH 0078/2666] chore(ci): bump version to 2.33.1 (#3746) Co-authored-by: Powertools for AWS Lambda (Python) bot --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index 7cac1198767..776b9b96ce0 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.33.0" +VERSION = "2.33.1" diff --git a/pyproject.toml b/pyproject.toml index c152995dfeb..5efc7e44d5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.33.0" +version = "2.33.1" 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"] From c06a36154b39e4b89b610248f78e19882305fe32 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 9 Feb 2024 14:22:39 +0100 Subject: [PATCH 0079/2666] chore(ci): layer docs update (#3747) Co-authored-by: Powertools for AWS Lambda (Python) bot Co-authored-by: Heitor Lessa --- CHANGELOG.md | 34 +++++----------------------------- docs/index.md | 4 ++-- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45aa708bb97..a432b76beb1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,37 +4,12 @@ # Unreleased -## Documentation - -* Add nathan hanks post community ([#3727](https://github.com/aws-powertools/powertools-lambda-python/issues/3727)) + +## [v2.33.1] - 2024-02-09 ## Maintenance -* **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) -* **ci:** enable Redis e2e tests ([#3718](https://github.com/aws-powertools/powertools-lambda-python/issues/3718)) -* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) -* **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) -* **deps:** bump actions/download-artifact from 4.1.1 to 4.1.2 ([#3725](https://github.com/aws-powertools/powertools-lambda-python/issues/3725)) -* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) -* **deps:** revert aws-cdk-lib as a runtime dep ([#3730](https://github.com/aws-powertools/powertools-lambda-python/issues/3730)) -* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) -* **deps:** bump actions/upload-artifact from 3.1.3 to 4.3.1 ([#3714](https://github.com/aws-powertools/powertools-lambda-python/issues/3714)) -* **deps:** bump squidfunk/mkdocs-material from `e0d6c67` to `6a72238` in /docs ([#3735](https://github.com/aws-powertools/powertools-lambda-python/issues/3735)) -* **deps:** bump actions/setup-node from 4.0.1 to 4.0.2 ([#3737](https://github.com/aws-powertools/powertools-lambda-python/issues/3737)) -* **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) -* **deps-dev:** bump mypy from 1.4.1 to 1.8.0 ([#3710](https://github.com/aws-powertools/powertools-lambda-python/issues/3710)) -* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) -* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) -* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) -* **deps-dev:** bump pytest from 7.4.4 to 8.0.0 ([#3711](https://github.com/aws-powertools/powertools-lambda-python/issues/3711)) -* **deps-dev:** bump types-python-dateutil from 2.8.19.14 to 2.8.19.20240106 ([#3720](https://github.com/aws-powertools/powertools-lambda-python/issues/3720)) -* **deps-dev:** bump cfn-lint from 0.83.8 to 0.85.0 ([#3724](https://github.com/aws-powertools/powertools-lambda-python/issues/3724)) -* **deps-dev:** bump isort from 5.11.5 to 5.13.2 ([#3723](https://github.com/aws-powertools/powertools-lambda-python/issues/3723)) -* **deps-dev:** bump sentry-sdk from 1.40.1 to 1.40.2 ([#3740](https://github.com/aws-powertools/powertools-lambda-python/issues/3740)) -* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) -* **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) -* **deps-dev:** bump black from 23.12.1 to 24.1.1 ([#3739](https://github.com/aws-powertools/powertools-lambda-python/issues/3739)) -* **deps-dev:** bump ruff from 0.2.0 to 0.2.1 ([#3742](https://github.com/aws-powertools/powertools-lambda-python/issues/3742)) +* version bump @@ -4343,7 +4318,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.1...HEAD +[v2.33.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...v2.33.1 [v2.33.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...v2.33.0 [v2.32.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.31.0...v2.32.0 [v2.31.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.30.2...v2.31.0 diff --git a/docs/index.md b/docs/index.md index a5132120490..41c98ab70c5 100644 --- a/docs/index.md +++ b/docs/index.md @@ -85,7 +85,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | @@ -119,7 +119,7 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | From 68bb468101e1d82055d0beb0c369ca5c46a6f2c9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 14:50:25 +0100 Subject: [PATCH 0080/2666] chore(deps-dev): bump cfn-lint from 0.85.0 to 0.85.1 (#3749) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 10 +++++----- pyproject.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 09329553a25..29522a41fc0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -485,17 +485,17 @@ pycparser = "*" [[package]] name = "cfn-lint" -version = "0.85.0" +version = "0.85.1" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" optional = false python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.85.0.tar.gz", hash = "sha256:64d6e8d85cdc573b61add78f9ff95a142a1834edb4793d1291551f6d953f73fe"}, - {file = "cfn_lint-0.85.0-py3-none-any.whl", hash = "sha256:e4849e1779bd1a9f4543617372708a20519b6d7cad5f980e20c6deaa227361a2"}, + {file = "cfn-lint-0.85.1.tar.gz", hash = "sha256:f003603a6f13bcda125c60f5021fc19b96f18a27ebc44498947709cb7627d0d6"}, + {file = "cfn_lint-0.85.1-py3-none-any.whl", hash = "sha256:5d5b31609ded0bc513f1c57c0dc0017ec1613c2b33ef8e74802149bedb01a3de"}, ] [package.dependencies] -aws-sam-translator = ">=1.83.0" +aws-sam-translator = ">=1.84.0" jschema-to-python = ">=1.2.3,<1.3.0" jsonpatch = "*" jsonschema = ">=3.0,<5" @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "e9b5704f5b3140785eacf0670b7ff2ea12e6732baef7f45c5c65c3b5d31d67bb" +content-hash = "b3e88e6b5ac715d3d4b09c4f69a68eaa4846c97a4ce6b4a3fdd72a061f61321d" diff --git a/pyproject.toml b/pyproject.toml index 5efc7e44d5a..7b76284037b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -110,7 +110,7 @@ datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.85.0" +cfn-lint = "0.85.1" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.27.0" From d738be21c3309549e984c3ee15c9244d82ee8430 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Feb 2024 15:42:01 +0100 Subject: [PATCH 0081/2666] chore(deps-dev): bump sentry-sdk from 1.40.2 to 1.40.3 (#3750) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 29522a41fc0..9a90fa62280 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2924,13 +2924,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.2" +version = "1.40.3" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.2.tar.gz", hash = "sha256:c98c8e9bb4dc8ff1e67473caf6467acfccf915dadcc26d0efb0d6791a8652610"}, - {file = "sentry_sdk-1.40.2-py2.py3-none-any.whl", hash = "sha256:696ef61a323a207e6a20b018ddc6591adb81c671434c88d1a4f2e95ffa75556c"}, + {file = "sentry-sdk-1.40.3.tar.gz", hash = "sha256:3c2b027979bb400cd65a47970e64f8cef8acda86b288a27f42a98692505086cd"}, + {file = "sentry_sdk-1.40.3-py2.py3-none-any.whl", hash = "sha256:73383f28311ae55602bb6cc3b013830811135ba5521e41333a6e68f269413502"}, ] [package.dependencies] @@ -2956,7 +2956,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure_eval"] +pure-eval = ["asttokens", "executing", "pure-eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] From d074c5264d9d16580ace4ba8b347e18d517a7d97 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 12:02:25 +0100 Subject: [PATCH 0082/2666] chore(deps-dev): bump mkdocs-material from 9.5.8 to 9.5.9 (#3759) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 9a90fa62280..def2ddd940a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1751,13 +1751,13 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.5.8" +version = "9.5.9" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.8-py3-none-any.whl", hash = "sha256:14563314bbf97da4bfafc69053772341babfaeb3329cde01d3e63cec03997af8"}, - {file = "mkdocs_material-9.5.8.tar.gz", hash = "sha256:2a429213e83f84eda7a588e2b186316d806aac602b7f93990042f7a1f3d3cf65"}, + {file = "mkdocs_material-9.5.9-py3-none-any.whl", hash = "sha256:a5d62b73b3b74349e45472bfadc129c871dd2d4add68d84819580597b2f50d5d"}, + {file = "mkdocs_material-9.5.9.tar.gz", hash = "sha256:635df543c01c25c412d6c22991872267723737d5a2f062490f33b2da1c013c6d"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "b3e88e6b5ac715d3d4b09c4f69a68eaa4846c97a4ce6b4a3fdd72a061f61321d" +content-hash = "1ad5c708f87d4cedb91783c6a36b61f1bb574fc7817e64c0471e57d7b2f08fd4" diff --git a/pyproject.toml b/pyproject.toml index 7b76284037b..3b17e50d8be 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" typing-extensions = "^4.6.2" -mkdocs-material = "^9.2.7" +mkdocs-material = "^9.5.9" filelock = "^3.12.2" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.34.24" From 2faf99f014f200078a99e1da28e509f6cee75869 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 13:18:26 +0100 Subject: [PATCH 0083/2666] chore(deps-dev): bump aws-cdk from 2.126.0 to 2.127.0 (#3761) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed5b64eee4e..16f6f99d71b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.126.0" + "aws-cdk": "^2.127.0" } }, "node_modules/aws-cdk": { - "version": "2.126.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.126.0.tgz", - "integrity": "sha512-hEyy8UCEEUnkieH6JbJBN8XAbvuVZNdBmVQ8wHCqo8RSNqmpwM1qvLiyXV/2JvCqJJ0bl9uBiZ98Ytd5i3wW7g==", + "version": "2.127.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.127.0.tgz", + "integrity": "sha512-0yPiN+/VFVc/NpOryO+1S7b4DBgRSs4JdQ64jhV4QbwaoWZo7KISxdN2cK4pmcVH67BSNCJCjjlf10cYhmMvwA==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index 130e74e8067..228319b5e40 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.126.0" + "aws-cdk": "^2.127.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 93b4ac6f45d21acb3d2bb4d8eb0419bb72baf57e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 13 Feb 2024 15:02:30 +0100 Subject: [PATCH 0084/2666] chore(deps-dev): bump aws-cdk-lib from 2.126.0 to 2.127.0 (#3758) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index def2ddd940a..f03da2f4473 100644 --- a/poetry.lock +++ b/poetry.lock @@ -158,13 +158,13 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.126.0" +version = "2.127.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false python-versions = "~=3.8" files = [ - {file = "aws-cdk-lib-2.126.0.tar.gz", hash = "sha256:291f9a15fb45f1461644ffa2ff360c8c2ed2797ac29082655252de291fa04333"}, - {file = "aws_cdk_lib-2.126.0-py3-none-any.whl", hash = "sha256:8e00c0a3bfe8f5c20d305d149df251b8fbf292aa7e74df0765ba47fdbbec82d6"}, + {file = "aws-cdk-lib-2.127.0.tar.gz", hash = "sha256:ed4ace6dc0ed42cb980b2ff833c685f6fe64b3bfad94676b6ea2ee3dfa161dc8"}, + {file = "aws_cdk_lib-2.127.0-py3-none-any.whl", hash = "sha256:abbb50bd9100cdbcc789d098457f60c842efe0f56f8571345f3603be5cc52b38"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "1ad5c708f87d4cedb91783c6a36b61f1bb574fc7817e64c0471e57d7b2f08fd4" +content-hash = "87ee762b995de6889cebcf87cea2dfcc209fc36044ff933bdb3247caa814a93d" diff --git a/pyproject.toml b/pyproject.toml index 3b17e50d8be..2832d32d4b3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,7 @@ xenon = "^0.9.1" mkdocs-git-revision-date-plugin = "^0.3.2" mike = "^1.1.2" pytest-xdist = "^3.5.0" -aws-cdk-lib = "^2.126.0" +aws-cdk-lib = "^2.127.0" "aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" From f4f9021618ad66fd50bfb8be4bb3fe70b8ba62c3 Mon Sep 17 00:00:00 2001 From: Gerald Leter Date: Tue, 13 Feb 2024 08:25:55 -0600 Subject: [PATCH 0085/2666] feat(feature_flags): add intersect actions for conditions (#3692) Code and docs Co-authored-by: Leandro Damascena Co-authored-by: Simon Thulbourn --- .../utilities/feature_flags/comparators.py | 41 +++++++++++++++++++ .../utilities/feature_flags/feature_flags.py | 6 +++ .../utilities/feature_flags/schema.py | 3 ++ docs/utilities/feature_flags.md | 7 +++- 4 files changed, 55 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/utilities/feature_flags/comparators.py b/aws_lambda_powertools/utilities/feature_flags/comparators.py index 78370f1b5b1..1419dd6dd83 100644 --- a/aws_lambda_powertools/utilities/feature_flags/comparators.py +++ b/aws_lambda_powertools/utilities/feature_flags/comparators.py @@ -4,6 +4,7 @@ from dateutil.tz import gettz from .schema import HOUR_MIN_SEPARATOR, ModuloRangeValues, TimeValues +from .exceptions import SchemaValidationError def _get_now_from_timezone(timezone: Optional[tzinfo]) -> datetime: @@ -82,3 +83,43 @@ def compare_modulo_range(context_value: int, condition_value: Dict) -> bool: end = condition_value.get(ModuloRangeValues.END.value, 1) return start <= context_value % base <= end + + +def compare_any_in_list(key_list, value_list): + if not (isinstance(key_list, list) and isinstance(value_list, list)): + raise SchemaValidationError() + + results = False + for key in key_list: + if key in value_list: + results = True + break + + return results + + +def compare_all_in_list(key_list, value_list): + if not (isinstance(key_list, list) and isinstance(value_list, list)): + raise SchemaValidationError() + + results = True + for key in key_list: + if key not in value_list: + results = False + break + + return results + + +def compare_none_in_list(key_list, value_list): + if not (isinstance(key_list, list) and isinstance(value_list, list)): + raise SchemaValidationError() + + results = True + for key in key_list: + if key in value_list: + results = False + break + + return results + diff --git a/aws_lambda_powertools/utilities/feature_flags/feature_flags.py b/aws_lambda_powertools/utilities/feature_flags/feature_flags.py index 8610d68a8f6..ac4dfef0162 100644 --- a/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +++ b/aws_lambda_powertools/utilities/feature_flags/feature_flags.py @@ -10,6 +10,9 @@ compare_days_of_week, compare_modulo_range, compare_time_range, + compare_all_in_list, + compare_any_in_list, + compare_none_in_list ) from .exceptions import ConfigurationStoreError @@ -63,6 +66,9 @@ def _match_by_action(self, action: str, condition_value: Any, context_value: Any schema.RuleAction.KEY_NOT_IN_VALUE.value: lambda a, b: a not in b, schema.RuleAction.VALUE_IN_KEY.value: lambda a, b: b in a, schema.RuleAction.VALUE_NOT_IN_KEY.value: lambda a, b: b not in a, + schema.RuleAction.ALL_IN_VALUE.value: lambda a, b: compare_all_in_list(a, b), + schema.RuleAction.ANY_IN_VALUE.value: lambda a, b: compare_any_in_list(a, b), + schema.RuleAction.NONE_IN_VALUE.value: lambda a, b: compare_none_in_list(a, b), schema.RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value: lambda a, b: compare_time_range(a, b), schema.RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value: lambda a, b: compare_datetime_range(a, b), schema.RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value: lambda a, b: compare_days_of_week(a, b), diff --git a/aws_lambda_powertools/utilities/feature_flags/schema.py b/aws_lambda_powertools/utilities/feature_flags/schema.py index 0dc5e8d56bc..2ef4b9e29a4 100644 --- a/aws_lambda_powertools/utilities/feature_flags/schema.py +++ b/aws_lambda_powertools/utilities/feature_flags/schema.py @@ -38,6 +38,9 @@ class RuleAction(str, Enum): KEY_NOT_IN_VALUE = "KEY_NOT_IN_VALUE" VALUE_IN_KEY = "VALUE_IN_KEY" VALUE_NOT_IN_KEY = "VALUE_NOT_IN_KEY" + ALL_IN_VALUE = "ALL_IN_VALUE" + ANY_IN_VALUE = "ANY_IN_VALUE" + NONE_IN_VALUE = "NONE_IN_VALUE" SCHEDULE_BETWEEN_TIME_RANGE = "SCHEDULE_BETWEEN_TIME_RANGE" # hour:min 24 hours clock SCHEDULE_BETWEEN_DATETIME_RANGE = "SCHEDULE_BETWEEN_DATETIME_RANGE" # full datetime format, excluding timezone SCHEDULE_BETWEEN_DAYS_OF_WEEK = "SCHEDULE_BETWEEN_DAYS_OF_WEEK" # MONDAY, TUESDAY, .... see TimeValues enum diff --git a/docs/utilities/feature_flags.md b/docs/utilities/feature_flags.md index b68fcc594fb..c33efe30429 100644 --- a/docs/utilities/feature_flags.md +++ b/docs/utilities/feature_flags.md @@ -431,10 +431,13 @@ The `action` configuration can have the following values, where the expressions | **ENDSWITH** | `lambda a, b: a.endswith(b)` | | **KEY_IN_VALUE** | `lambda a, b: a in b` | | **KEY_NOT_IN_VALUE** | `lambda a, b: a not in b` | +| **ANY_IN_VALUE** | `lambda a, b: any of a is in b` | +| **ALL_IN_VALUE** | `lambda a, b: all of a is in b` | +| **NONE_IN_VALUE** | `lambda a, b: none of a is in b` | | **VALUE_IN_KEY** | `lambda a, b: b in a` | | **VALUE_NOT_IN_KEY** | `lambda a, b: b not in a` | -| **SCHEDULE_BETWEEN_TIME_RANGE** | `lambda a, b: b.start <= time(a) <= b.end` | -| **SCHEDULE_BETWEEN_DATETIME_RANGE** | `lambda a, b: b.start <= datetime(a) <= b.end` | +| **SCHEDULE_BETWEEN_TIME_RANGE** | `lambda a, b: b.start <= time(a) <= b.end` | +| **SCHEDULE_BETWEEN_DATETIME_RANGE** | `lambda a, b: b.start <= datetime(a) <= b.end` | | **SCHEDULE_BETWEEN_DAYS_OF_WEEK** | `lambda a, b: day_of_week(a) in b` | | **MODULO_RANGE** | `lambda a, b: b.start <= a % b.base <= b.end` | From ea47f5383a7b677a850964343441324600091a83 Mon Sep 17 00:00:00 2001 From: Henrique Graca <999396+hjgraca@users.noreply.github.com> Date: Wed, 14 Feb 2024 16:07:02 +0000 Subject: [PATCH 0086/2666] docs(homepage): discord flat badge style; remove former devax email (#3768) --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index c1ab7abaf29..b43114f8801 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ [![Build](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/quality_check.yml/badge.svg)](https://github.com/aws-powertools/powertools-lambda-python/actions/workflows/python_build.yml) [![codecov.io](https://codecov.io/github/aws-powertools/powertools-lambda-python/branch/develop/graphs/badge.svg)](https://app.codecov.io/gh/aws-powertools/powertools-lambda-python) -![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET)](https://discord.gg/B8zZKbbyET) +![PythonSupport](https://img.shields.io/static/v1?label=python&message=%203.8|%203.9|%203.10|%203.11|%203.12&color=blue?style=flat-square&logo=python) ![PyPI version](https://badge.fury.io/py/aws-lambda-powertools.svg) ![PyPi monthly downloads](https://img.shields.io/pypi/dm/aws-lambda-powertools) [![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python/badge)](https://api.securityscorecards.dev/projects/github.com/aws-powertools/powertools-lambda-python) [![Join our Discord](https://dcbadge.vercel.app/api/server/B8zZKbbyET?style=flat-square)](https://discord.gg/B8zZKbbyET) Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless [best practices and increase developer velocity](https://docs.powertools.aws.dev/lambda/python/latest/#features). @@ -11,8 +11,6 @@ Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverles **[📜Documentation](https://docs.powertools.aws.dev/lambda/python/)** | **[🐍PyPi](https://pypi.org/project/aws-lambda-powertools/)** | **[Roadmap](https://docs.powertools.aws.dev/lambda/python/latest/roadmap/)** | **[Detailed blog post](https://aws.amazon.com/blogs/opensource/simplifying-serverless-best-practices-with-lambda-powertools/)** -> **An AWS Developer Acceleration (DevAx) initiative by Specialist Solution Architects | ** - ![hero-image](https://user-images.githubusercontent.com/3340292/198254617-d0fdb672-86a6-4988-8a40-adf437135e0a.png) ## Features From 3cce66e5d31b8f9be8c45dbc42a1b573edb6da4c Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 14 Feb 2024 17:14:37 +0100 Subject: [PATCH 0087/2666] docs(roadmap): latest roadmap update; use new grid to de-clutter homepage (#3755) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * docs: key areas over themes; add launch/drop sections Signed-off-by: heitorlessa * docs: add links to launched event handler feat * docs: add last office hours items * docs: link sigv4 mvp until RFC is complete * docs: update feedback email Signed-off-by: heitorlessa * docs: update govcloud items Signed-off-by: heitorlessa * docs: link versioning process * docs: add bedrock * docs: add py3.7 area * docs: update wording on why an item was dropped * docs: add parameters set area * docs: remove python 3.7 banner Signed-off-by: heitorlessa * docs: enable code tab deep linking * docs: draft grids * docs: cleanup grids; fix warnings Signed-off-by: heitorlessa * docs: cleanup support us sections Signed-off-by: heitorlessa * docs: cleanup install Signed-off-by: heitorlessa * docs: major cleanup for layer sections Signed-off-by: heitorlessa * chore: fixed Simon's feedback on bot email Signed-off-by: heitorlessa --------- Signed-off-by: heitorlessa --- .github/actions/create-pr/action.yml | 2 +- .github/workflows/release.yml | 2 +- README.md | 2 +- docs/index.md | 1040 ++++++++++++++------------ docs/overrides/main.html | 2 - docs/roadmap.md | 190 +++-- docs/tutorial/index.md | 2 +- mkdocs.yml | 9 +- 8 files changed, 679 insertions(+), 570 deletions(-) diff --git a/.github/actions/create-pr/action.yml b/.github/actions/create-pr/action.yml index dcf2df738bd..39ba6f60b1f 100644 --- a/.github/actions/create-pr/action.yml +++ b/.github/actions/create-pr/action.yml @@ -64,7 +64,7 @@ runs: name: Git client setup and refresh tip run: | git config user.name "Powertools for AWS Lambda (Python) bot" - git config user.email "aws-lambda-powertools-feedback@amazon.com" + git config user.email "151832416+aws-powertools-bot@users.noreply.github.com" git config pull.rebase true git config remote.origin.url >&- shell: bash diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fac762bdbeb..d9c7b9d8cad 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -273,7 +273,7 @@ jobs: name: Git client setup and refresh tip run: | git config user.name "Powertools for AWS Lambda (Python) bot" - git config user.email "aws-lambda-powertools-feedback@amazon.com" + git config user.email "151832416+aws-powertools-bot@users.noreply.github.com" git config remote.origin.url >&- - name: Create Git Tag diff --git a/README.md b/README.md index b43114f8801..00e217c29c7 100644 --- a/README.md +++ b/README.md @@ -81,7 +81,7 @@ This helps us understand who uses Powertools for AWS Lambda (Python) in a non-in ## Connect * **Powertools for AWS Lambda on Discord**: `#python` - **[Invite link](https://discord.gg/B8zZKbbyET)** -* **Email**: +* **Email**: ## Security disclosures diff --git a/docs/index.md b/docs/index.md index 41c98ab70c5..d31dcbf9396 100644 --- a/docs/index.md +++ b/docs/index.md @@ -7,72 +7,406 @@ description: Powertools for AWS Lambda (Python) Powertools for AWS Lambda (Python) is a developer toolkit to implement Serverless best practices and increase developer velocity. -???+ tip - Powertools for AWS Lambda (Python) is also available for [Java](https://docs.powertools.aws.dev/lambda/java/){target="_blank"}, [TypeScript](https://docs.powertools.aws.dev/lambda/typescript/latest/){target="_blank" }, and [.NET](https://docs.powertools.aws.dev/lambda/dotnet/){target="_blank"} + +
-??? hint "Support this project by becoming a reference customer, sharing your work, or using Layers/SAR :heart:" +- :material-battery-charging:{ .lg .middle } __Features__ - You can choose to support us in three ways: + --- - 1) [**Become a reference customer**](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E){target="_blank"}. This gives us permission to list your company in our documentation. + Adopt one, a few, or all industry practices. **Progressively**. - 2) [**Share your work**](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=community-content&template=share_your_work.yml&title=%5BI+Made+This%5D%3A+%3CTITLE%3E){target="_blank"}. Blog posts, video, sample projects you used Powertools! + [:octicons-arrow-right-24: All features](#features) - 3) Use [**Lambda Layers**](#lambda-layer) or [**SAR**](#sar), if possible. This helps us understand who uses Powertools for AWS Lambda (Python) in a non-intrusive way, and helps us gain future investments for other Powertools for AWS Lambda languages. +- :heart:{ .lg .middle } __Support this project__ - When using Layers, you can add Powertools for AWS Lambda (Python) as a dev dependency (or as part of your virtual env) to not impact the development process. + --- + + Become a public reference customer, share your work, contribute, use Lambda Layers, etc. + + [:octicons-arrow-right-24: Support](#support-powertools-for-aws-lambda-python) + +- :material-file-code:{ .lg .middle } __Available languages__ + + --- + + Powertools for AWS Lambda is also available in other languages + + :octicons-arrow-right-24: [Java](https://docs.powertools.aws.dev/lambda/java/){target="_blank"}, [TypeScript](https://docs.powertools.aws.dev/lambda/typescript/latest/){target="_blank" }, and [.NET](https://docs.powertools.aws.dev/lambda/dotnet/){target="_blank"} + +
## Install -You can install Powertools for AWS Lambda (Python) using one of the following options: +You can install Powertools for AWS Lambda (Python) using your favorite dependency management, or Lambda Layers: -* **Lambda Layer (x86_64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: -* **Lambda Layer (arm64)**: [**arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61**](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: -* **Pip**: **[`pip install "aws-lambda-powertools"`](#){: .copyMe}:clipboard:** +=== "Pip" -!!! question "Looking for Pip signed releases? [Learn more about verifying signed builds](./security.md#verifying-signed-builds)" + You can install [all extra dependencies](#extra-dependencies) at once with the `[all]` extras. -??? question "Using Pip? You might need to install additional dependencies." - [**Tracer**](./core/tracer.md){target="_blank"}, [**Validation**](./utilities/validation.md){target="_blank"} and [**Parser**](./utilities/parser.md){target="_blank"} require additional dependencies. If you prefer to install all of them, use [**`pip install "aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard:. + * **pip**: [**`pip install "aws-lambda-powertools[all]"`**](#){: .copyMe} + * **poetry**: [**`poetry add "aws-lambda-powertools[all]"`**](#){: .copyMe} + * **pdm**: [**`pdm add "aws-lambda-powertools[all]"`**](#){: .copyMe} - For example: + Alternatively, see [extra dependencies](#extra-dependencies) if you want to install only what you need. - * **Tracer**: **[`pip install "aws-lambda-powertools[tracer]"`](#){: .copyMe}:clipboard:** - * **Validation**: **[`pip install "aws-lambda-powertools[validation]"`](#){: .copyMe}:clipboard:** - * **Parser**: **[`pip install "aws-lambda-powertools[parser]"`](#){: .copyMe}:clipboard:** - * **Tracer** and **Parser**: **[`pip install "aws-lambda-powertools[tracer,parser]"`](#){: .copyMe}:clipboard:** +=== "Lambda Layer" -### Local development + You can add our layer both in the [AWS Lambda Console _(under `Layers`)_](https://eu-west-1.console.aws.amazon.com/lambda/home#/add/layer){target="_blank"}, or via your favorite infrastructure as code framework with the ARN value. -!!! info "Using Lambda Layer? Simply add [**`"aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard: as a development dependency." + For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. -Powertools for AWS Lambda (Python) relies on the [AWS SDK bundled in the Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html){target="_blank"}. This helps us achieve an optimal package size and initialization. However, when developing locally, you need to install AWS SDK as a development dependency (not as a production dependency): + * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: -* **Pip**: [**`pip install "aws-lambda-powertools[aws-sdk]"`**](#){: .copyMe}:clipboard: -* **Poetry**: [**`poetry add "aws-lambda-powertools[aws-sdk]" --group dev`**](#){: .copyMe}:clipboard: -* **Pipenv**: [**`pipenv install --dev "aws-lambda-powertools[aws-sdk]"`**](#){: .copyMe}:clipboard: + ???+ note "Code snippets for popular infrastructure as code frameworks" -??? question "Why is that necessary?" - Powertools for AWS Lambda (Python) relies on the AWS SDK being available to use in the target runtime (AWS Lambda). + === "x86_64" - As a result, it affects your favorite IDE in terms of code auto-completion, or running your tests suite locally with no Lambda emulation such as [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html){target="_blank"}. + === "SAM" -**A word about dependency resolution** + ```yaml hl_lines="5" + MyLambdaFunction: + Type: AWS::Serverless::Function + Properties: + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 + ``` -In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependency resolution, it'll either install: + === "Serverless framework" -* **(A)** the SDK version available in [Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html){target="_blank"} -* **(B)** a more up-to-date version if another package you use also depends on `boto3`, for example [Powertools for AWS Lambda (Python) Tracer](core/tracer.md){target="_blank"} + ```yaml hl_lines="5" + functions: + hello: + handler: lambda_function.lambda_handler + layers: + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 + ``` -### Lambda Layer + === "CDK" + + ```python hl_lines="11 16" + from aws_cdk import core, aws_lambda + + class SampleApp(core.Construct): + + def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None: + super().__init__(scope, id_) + + powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( + self, + id="lambda-powertools", + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61" + ) + aws_lambda.Function(self, + 'sample-app-lambda', + runtime=aws_lambda.Runtime.PYTHON_3_9, + layers=[powertools_layer] + # other props... + ) + ``` + + === "Terraform" + + ```terraform hl_lines="9 38" + terraform { + required_version = "~> 1.0.5" + required_providers { + aws = "~> 3.50.0" + } + } + + provider "aws" { + region = "{region}" + } + + resource "aws_iam_role" "iam_for_lambda" { + name = "iam_for_lambda" + + assume_role_policy = < + ? Choose the runtime that you want to use: Python + ? 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:AWSLambdaPowertoolsPythonV2:61 + ❯ amplify push -y + + + # Updating an existing function and add the layer + ❯ amplify update function + ? Select the Lambda function you want to update test2 + 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:AWSLambdaPowertoolsPythonV2:61 + ? Do you want to edit the local lambda function now? No + ``` + + === "arm64" + + === "SAM" + + ```yaml hl_lines="6" + MyLambdaFunction: + Type: AWS::Serverless::Function + Properties: + Architectures: [arm64] + Layers: + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 + ``` + + === "Serverless framework" + + ```yaml hl_lines="6" + functions: + hello: + handler: lambda_function.lambda_handler + architecture: arm64 + layers: + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 + ``` + + === "CDK" + + ```python hl_lines="11 17" + from aws_cdk import core, aws_lambda + + class SampleApp(core.Construct): + + def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None: + super().__init__(scope, id_) + + powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( + self, + id="lambda-powertools", + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61" + ) + aws_lambda.Function(self, + 'sample-app-lambda', + runtime=aws_lambda.Runtime.PYTHON_3_9, + architecture=aws_lambda.Architecture.ARM_64, + layers=[powertools_layer] + # other props... + ) + ``` + + === "Terraform" + + ```terraform hl_lines="9 37" + terraform { + required_version = "~> 1.0.5" + required_providers { + aws = "~> 3.50.0" + } + } -???+ warning "As of now, Container Image deployment (OCI) or inline Lambda functions do not support Lambda Layers." + provider "aws" { + region = "{region}" + } + + resource "aws_iam_role" "iam_for_lambda" { + name = "iam_for_lambda" + + assume_role_policy = < + ? Choose the runtime that you want to use: Python + ? 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:AWSLambdaPowertoolsPythonV2-Arm64:61 + ❯ amplify push -y + + + # Updating an existing function and add the layer + ❯ amplify update function + ? Select the Lambda function you want to update test2 + 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:AWSLambdaPowertoolsPythonV2-Arm64:61 + ? Do you want to edit the local lambda function now? No + ``` + +### Extra dependencies + +The vast majority of [features](#features) rely on standard library and AWS SDK _(boto3)_ only. The following features however require additional dependencies: + +| Feature | Pip | Dependency | +| ------------------- | --------------------------------------------------------------------------------- | ----------------------------------- | +| Tracer | **[`pip install "aws-lambda-powertools[tracer]"`](#){: .copyMe}:clipboard:** | `aws-xray-sdk` | +| Validation | **[`pip install "aws-lambda-powertools[validation]"`](#){: .copyMe}:clipboard:** | `fastjsonschema` | +| Parser | **[`pip install "aws-lambda-powertools[parser]"`](#){: .copyMe}:clipboard:** | `pydantic` | +| Data Masking | **[`pip install "aws-lambda-powertools[datamasking]"`](#){: .copyMe}:clipboard:** | `aws-encryption-sdk`, `jsonpath-ng` | +| Idempotency (Redis) | **[`pip install "aws-lambda-powertools[redis]"`](#){: .copyMe}:clipboard:** | `redis` | + +> New to pip? + +You can use `,` delimiter to install multiple at once: [**`pip install "aws-lambda-powertools[tracer,parser,datamasking"]`**](#){: .copyMe}:clipboard: + +### Local development + +!!! info "Using Lambda Layer? Simply add [**`"aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard: as a development dependency." + +Powertools for AWS Lambda (Python) relies on the [AWS SDK bundled in the Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html){target="_blank"}. This helps us achieve an optimal package size and initialization. However, when developing locally, you need to install AWS SDK as a development dependency to support IDE auto-completion and to run your tests locally: + +- __Pip__: [**`pip install "aws-lambda-powertools[aws-sdk]"`**](#){: .copyMe}:clipboard: +- __Poetry__: [**`poetry add "aws-lambda-powertools[aws-sdk]" --group dev`**](#){: .copyMe}:clipboard: +- __Pdm__: [**`pdm add -dG "aws-lambda-powertools[aws-sdk]"`**](#){: .copyMe}:clipboard: + +__A word about dependency resolution__ -[Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html){target="_blank"} is a .zip file archive that can contain additional code, pre-packaged dependencies, data, or configuration files. Layers promote code sharing and separation of responsibilities so that you can iterate faster on writing business logic. +In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependency resolution, it'll either install: + +- __(A)__ the SDK version available in [Lambda runtime](https://docs.aws.amazon.com/lambda/latest/dg/lambda-python.html){target="_blank"} +- __(B)__ a more up-to-date version if another package you use also depends on `boto3`, for example [Powertools for AWS Lambda (Python) Tracer](core/tracer.md){target="_blank"} -For our Layers, we compile and optimize [all dependencies](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/pyproject.toml#L98){target="_blank"}, and [remove duplicate dependencies already available in the Lambda runtime](https://github.com/awslabs/cdk-aws-lambda-powertools-layer/blob/main/layer/Python/Dockerfile#L36){target="_blank"} to achieve the most optimal size. +### Lambda Layer -You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambda Console](https://docs.aws.amazon.com/lambda/latest/dg/invocation-layers.html#invocation-layers-using){target="_blank"}, or your preferred deployment framework. +[Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html){target="_blank"} is a .zip file archive that can contain additional code, pre-packaged dependencies, data, or configuration files. We compile and optimize [all dependencies](#extra-dependencies), and [remove duplicate dependencies already available in the Lambda runtime](https://github.com/awslabs/cdk-aws-lambda-powertools-layer/blob/main/layer/Python/Dockerfile#L36){target="_blank"} to achieve the most optimal size. ??? note "Note: Click to expand and copy any regional Lambda Layer ARN" @@ -142,326 +476,13 @@ You can include Powertools for AWS Lambda (Python) Lambda Layer using [AWS Lambd | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | -??? note "Note: Click to expand and copy code snippets for popular frameworks" +**Want to inspect the contents of the Layer?** - === "x86_64" +Replace `{region}` with your AWS region, _e.g. `eu-west-1`_. The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. - === "SAM" - - ```yaml hl_lines="5" - MyLambdaFunction: - Type: AWS::Serverless::Function - Properties: - Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 - ``` - - === "Serverless framework" - - ```yaml hl_lines="5" - functions: - hello: - handler: lambda_function.lambda_handler - layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 - ``` - - === "CDK" - - ```python hl_lines="11 16" - from aws_cdk import core, aws_lambda - - class SampleApp(core.Construct): - - def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None: - super().__init__(scope, id_) - - powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( - self, - id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61" - ) - aws_lambda.Function(self, - 'sample-app-lambda', - runtime=aws_lambda.Runtime.PYTHON_3_9, - layers=[powertools_layer] - # other props... - ) - ``` - - === "Terraform" - - ```terraform hl_lines="9 38" - terraform { - required_version = "~> 1.0.5" - required_providers { - aws = "~> 3.50.0" - } - } - - provider "aws" { - region = "{region}" - } - - resource "aws_iam_role" "iam_for_lambda" { - name = "iam_for_lambda" - - assume_role_policy = < - ? Choose the runtime that you want to use: Python - ? 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:AWSLambdaPowertoolsPythonV2:61 - ❯ amplify push -y - - - # Updating an existing function and add the layer - ❯ amplify update function - ? Select the Lambda function you want to update test2 - 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:AWSLambdaPowertoolsPythonV2:61 - ? Do you want to edit the local lambda function now? No - ``` - - === "arm64" - - === "SAM" - - ```yaml hl_lines="6" - MyLambdaFunction: - Type: AWS::Serverless::Function - Properties: - Architectures: [arm64] - Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 - ``` - - === "Serverless framework" - - ```yaml hl_lines="6" - functions: - hello: - handler: lambda_function.lambda_handler - architecture: arm64 - layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 - ``` - - === "CDK" - - ```python hl_lines="11 17" - from aws_cdk import core, aws_lambda - - class SampleApp(core.Construct): - - def __init__(self, scope: core.Construct, id_: str, env: core.Environment) -> None: - super().__init__(scope, id_) - - powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( - self, - id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61" - ) - aws_lambda.Function(self, - 'sample-app-lambda', - runtime=aws_lambda.Runtime.PYTHON_3_9, - architecture=aws_lambda.Architecture.ARM_64, - layers=[powertools_layer] - # other props... - ) - ``` - - === "Terraform" - - ```terraform hl_lines="9 37" - terraform { - required_version = "~> 1.0.5" - required_providers { - aws = "~> 3.50.0" - } - } - - provider "aws" { - region = "{region}" - } - - resource "aws_iam_role" "iam_for_lambda" { - name = "iam_for_lambda" - - assume_role_policy = < - ? Choose the runtime that you want to use: Python - ? 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:AWSLambdaPowertoolsPythonV2-Arm64:61 - ❯ amplify push -y - - - # Updating an existing function and add the layer - ❯ amplify update function - ? Select the Lambda function you want to update test2 - 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:AWSLambdaPowertoolsPythonV2-Arm64:61 - ? Do you want to edit the local lambda function now? No - ``` - -??? question "Want to inspect the contents of the Layer?" - Change {region} to your AWS region, e.g. `eu-west-1` - - ```bash title="AWS CLI" - aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 --region {region} - ``` - - The pre-signed URL to download this Lambda Layer will be within `Location` key. +```bash title="AWS CLI command to download Lambda Layer content" +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 --region {region} +``` #### SAR @@ -469,10 +490,10 @@ Serverless Application Repository (SAR) App deploys a CloudFormation stack with Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to choose a semantic version and deploys a Layer in your target account. -| App | ARN | Description | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | -| [aws-lambda-powertools-python-layer](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer){target="_blank"} | [arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer](#){: .copyMe}:clipboard: | Contains all extra dependencies (e.g: pydantic). | -| [aws-lambda-powertools-python-layer-arm64](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer-arm64){target="_blank"} | [arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer-arm64](#){: .copyMe}:clipboard: | Contains all extra dependencies (e.g: pydantic). For arm64 functions. | +| App | ARN | Description | +| ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------- | +| [**aws-lambda-powertools-python-layer**](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer){target="_blank"} | [arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer](#){: .copyMe}:clipboard: | Contains all extra dependencies (e.g: pydantic). | +| [**aws-lambda-powertools-python-layer-arm64**](https://serverlessrepo.aws.amazon.com/applications/eu-west-1/057560766410/aws-lambda-powertools-python-layer-arm64){target="_blank"} | [arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer-arm64](#){: .copyMe}:clipboard: | Contains all extra dependencies (e.g: pydantic). For arm64 functions. | ??? note "Click to expand and copy SAR code snippets for popular frameworks" @@ -602,78 +623,63 @@ Compared with the [public Layer ARN](#lambda-layer) option, SAR allows you to ch } ``` -??? example "Example: Least-privileged IAM permissions to deploy Layer" - - > Credits to [mwarkentin](https://github.com/mwarkentin){target="_blank" rel="nofollow"} for providing the scoped down IAM permissions. - - The region and the account id for `CloudFormationTransform` and `GetCfnTemplate` are fixed. - - === "template.yml" - - ```yaml hl_lines="21-52" - AWSTemplateFormatVersion: "2010-09-09" - Resources: - PowertoolsLayerIamRole: - Type: "AWS::IAM::Role" - Properties: - AssumeRolePolicyDocument: - Version: "2012-10-17" - Statement: - - Effect: "Allow" - Principal: - Service: - - "cloudformation.amazonaws.com" - Action: - - "sts:AssumeRole" - Path: "/" - PowertoolsLayerIamPolicy: - Type: "AWS::IAM::Policy" - Properties: - PolicyName: PowertoolsLambdaLayerPolicy - PolicyDocument: - Version: "2012-10-17" - Statement: - - Sid: CloudFormationTransform - Effect: Allow - Action: cloudformation:CreateChangeSet - Resource: - - arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31 - - Sid: GetCfnTemplate - Effect: Allow - Action: - - serverlessrepo:CreateCloudFormationTemplate - - serverlessrepo:GetCloudFormationTemplate - Resource: - # this is arn of the Powertools for AWS Lambda (Python) SAR app - - arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer - - Sid: S3AccessLayer - Effect: Allow - Action: - - s3:GetObject - Resource: - # AWS publishes to an external S3 bucket locked down to your account ID - # The below example is us publishing Powertools for AWS Lambda (Python) - # Bucket: awsserverlessrepo-changesets-plntc6bfnfj - # Key: *****/arn:aws:serverlessrepo:eu-west-1:057560766410:applications-aws-lambda-powertools-python-layer-versions-1.10.2/aeeccf50-****-****-****-********* - - arn:aws:s3:::awsserverlessrepo-changesets-*/* - - Sid: GetLayerVersion - Effect: Allow - Action: - - lambda:PublishLayerVersion - - lambda:GetLayerVersion - Resource: - - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:aws-lambda-powertools-python-layer* - Roles: - - Ref: "PowertoolsLayerIamRole" - ``` - -??? note "Click to expand and copy an AWS CLI command to list all versions available in SAR" - - You can fetch available versions via SAR ListApplicationVersions API: - - ```bash title="AWS CLI example" - aws serverlessrepo list-application-versions \ - --application-id arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer + Credits to [mwarkentin](https://github.com/mwarkentin){target="_blank" rel="nofollow"} for providing the scoped down IAM permissions below. + + ```yaml hl_lines="21-52" title="Least-privileged IAM permissions SAM example" + AWSTemplateFormatVersion: "2010-09-09" + Resources: + PowertoolsLayerIamRole: + Type: "AWS::IAM::Role" + Properties: + AssumeRolePolicyDocument: + Version: "2012-10-17" + Statement: + - Effect: "Allow" + Principal: + Service: + - "cloudformation.amazonaws.com" + Action: + - "sts:AssumeRole" + Path: "/" + PowertoolsLayerIamPolicy: + Type: "AWS::IAM::Policy" + Properties: + PolicyName: PowertoolsLambdaLayerPolicy + PolicyDocument: + Version: "2012-10-17" + Statement: + - Sid: CloudFormationTransform + Effect: Allow + Action: cloudformation:CreateChangeSet + Resource: + - arn:aws:cloudformation:us-east-1:aws:transform/Serverless-2016-10-31 + - Sid: GetCfnTemplate + Effect: Allow + Action: + - serverlessrepo:CreateCloudFormationTemplate + - serverlessrepo:GetCloudFormationTemplate + Resource: + # this is arn of the Powertools for AWS Lambda (Python) SAR app + - arn:aws:serverlessrepo:eu-west-1:057560766410:applications/aws-lambda-powertools-python-layer + - Sid: S3AccessLayer + Effect: Allow + Action: + - s3:GetObject + Resource: + # AWS publishes to an external S3 bucket locked down to your account ID + # The below example is us publishing Powertools for AWS Lambda (Python) + # Bucket: awsserverlessrepo-changesets-plntc6bfnfj + # Key: *****/arn:aws:serverlessrepo:eu-west-1:057560766410:applications-aws-lambda-powertools-python-layer-versions-1.10.2/aeeccf50-****-****-****-********* + - arn:aws:s3:::awsserverlessrepo-changesets-*/* + - Sid: GetLayerVersion + Effect: Allow + Action: + - lambda:PublishLayerVersion + - lambda:GetLayerVersion + Resource: + - !Sub arn:aws:lambda:${AWS::Region}:${AWS::AccountId}:layer:aws-lambda-powertools-python-layer* + Roles: + - Ref: "PowertoolsLayerIamRole" ``` ## Quick getting started @@ -688,22 +694,22 @@ Core utilities such as Tracing, Logging, Metrics, and Event Handler will be avai | Utility | Description | | --------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -| [**Tracing**](./core/tracer.md){target="_blank"} | Decorators and utilities to trace Lambda function handlers, and both synchronous and asynchronous functions | -| [**Logger**](./core/logger.md){target="_blank"} | Structured logging made easier, and decorator to enrich structured logging with key Lambda context details | -| [**Metrics**](./core/metrics.md){target="_blank"} | Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF) | -| [**Event handler: AppSync**](./core/event_handler/appsync.md){target="_blank"} | AppSync event handler for Lambda Direct Resolver and Amplify GraphQL Transformer function | -| [**Event handler: API Gateway, ALB and Lambda Function URL**](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) | Amazon API Gateway REST/HTTP API and ALB event handler for Lambda functions invoked using Proxy integration, and Lambda Function URL | -| [**Middleware factory**](./utilities/middleware_factory.md){target="_blank"} | Decorator factory to create your own middleware to run logic before, and after each Lambda invocation | -| [**Parameters**](./utilities/parameters.md){target="_blank"} | Retrieve parameter values from AWS Systems Manager Parameter Store, AWS Secrets Manager, or Amazon DynamoDB, and cache them for a specific amount of time | -| [**Batch processing**](./utilities/batch.md){target="_blank"} | Handle partial failures for AWS SQS batch processing | -| [**Typing**](./utilities/typing.md){target="_blank"} | Static typing classes to speedup development in your IDE | -| [**Validation**](./utilities/validation.md){target="_blank"} | JSON Schema validator for inbound events and responses | -| [**Event source data classes**](./utilities/data_classes.md){target="_blank"} | Data classes describing the schema of common Lambda event triggers | -| [**Parser**](./utilities/parser.md){target="_blank"} | Data parsing and deep validation using Pydantic | -| [**Idempotency**](./utilities/idempotency.md){target="_blank"} | Idempotent Lambda handler | -| [**Data Masking**](./utilities/data_masking.md){target="_blank"} | Protect confidential data with easy removal or encryption | -| [**Feature Flags**](./utilities/feature_flags.md){target="_blank"} | A simple rule engine to evaluate when one or multiple features should be enabled depending on the input | -| [**Streaming**](./utilities/streaming.md){target="_blank"} | Streams datasets larger than the available memory as streaming data. | +| [__Tracing__](./core/tracer.md){target="_blank"} | Decorators and utilities to trace Lambda function handlers, and both synchronous and asynchronous functions | +| [__Logger__](./core/logger.md){target="_blank"} | Structured logging made easier, and decorator to enrich structured logging with key Lambda context details | +| [__Metrics__](./core/metrics.md){target="_blank"} | Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF) | +| [__Event handler: AppSync__](./core/event_handler/appsync.md){target="_blank"} | AppSync event handler for Lambda Direct Resolver and Amplify GraphQL Transformer function | +| [__Event handler: API Gateway, ALB and Lambda Function URL__](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/) | Amazon API Gateway REST/HTTP API and ALB event handler for Lambda functions invoked using Proxy integration, and Lambda Function URL | +| [__Middleware factory__](./utilities/middleware_factory.md){target="_blank"} | Decorator factory to create your own middleware to run logic before, and after each Lambda invocation | +| [__Parameters__](./utilities/parameters.md){target="_blank"} | Retrieve parameter values from AWS Systems Manager Parameter Store, AWS Secrets Manager, or Amazon DynamoDB, and cache them for a specific amount of time | +| [__Batch processing__](./utilities/batch.md){target="_blank"} | Handle partial failures for AWS SQS batch processing | +| [__Typing__](./utilities/typing.md){target="_blank"} | Static typing classes to speedup development in your IDE | +| [__Validation__](./utilities/validation.md){target="_blank"} | JSON Schema validator for inbound events and responses | +| [__Event source data classes__](./utilities/data_classes.md){target="_blank"} | Data classes describing the schema of common Lambda event triggers | +| [__Parser__](./utilities/parser.md){target="_blank"} | Data parsing and deep validation using Pydantic | +| [__Idempotency__](./utilities/idempotency.md){target="_blank"} | Idempotent Lambda handler | +| [__Data Masking__](./utilities/data_masking.md){target="_blank"} | Protect confidential data with easy removal or encryption | +| [__Feature Flags__](./utilities/feature_flags.md){target="_blank"} | A simple rule engine to evaluate when one or multiple features should be enabled depending on the input | +| [__Streaming__](./utilities/streaming.md){target="_blank"} | Streams datasets larger than the available memory as streaming data. | ## Environment variables @@ -712,19 +718,19 @@ Core utilities such as Tracing, Logging, Metrics, and Event Handler will be avai | Environment variable | Description | Utility | Default | | ----------------------------------------- | -------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------- | -| **POWERTOOLS_SERVICE_NAME** | Sets service name used for tracing namespace, metrics dimension and structured logging | All | `"service_undefined"` | -| **POWERTOOLS_METRICS_NAMESPACE** | Sets namespace used for metrics | [Metrics](./core/metrics.md){target="_blank"} | `None` | -| **POWERTOOLS_TRACE_DISABLED** | Explicitly disables tracing | [Tracing](./core/tracer.md){target="_blank"} | `false` | -| **POWERTOOLS_TRACER_CAPTURE_RESPONSE** | Captures Lambda or method return as metadata. | [Tracing](./core/tracer.md){target="_blank"} | `true` | -| **POWERTOOLS_TRACER_CAPTURE_ERROR** | Captures Lambda or method exception as metadata. | [Tracing](./core/tracer.md){target="_blank"} | `true` | -| **POWERTOOLS_TRACE_MIDDLEWARES** | Creates sub-segment for each custom middleware | [Middleware factory](./utilities/middleware_factory.md){target="_blank"} | `false` | -| **POWERTOOLS_LOGGER_LOG_EVENT** | Logs incoming event | [Logging](./core/logger.md){target="_blank"} | `false` | -| **POWERTOOLS_LOGGER_SAMPLE_RATE** | Debug log sampling | [Logging](./core/logger.md){target="_blank"} | `0` | -| **POWERTOOLS_LOG_DEDUPLICATION_DISABLED** | Disables log deduplication filter protection to use Pytest Live Log feature | [Logging](./core/logger.md){target="_blank"} | `false` | -| **POWERTOOLS_PARAMETERS_MAX_AGE** | Adjust how long values are kept in cache (in seconds) | [Parameters](./utilities/parameters.md#adjusting-cache-ttl){target="_blank"} | `5` | -| **POWERTOOLS_PARAMETERS_SSM_DECRYPT** | Sets whether to decrypt or not values retrieved from AWS SSM Parameters Store | [Parameters](./utilities/parameters.md#ssmprovider){target="_blank"} | `false` | -| **POWERTOOLS_DEV** | Increases verbosity across utilities | Multiple; see [POWERTOOLS_DEV effect below](#optimizing-for-non-production-environments) | `false` | -| **POWERTOOLS_LOG_LEVEL** | Sets logging level | [Logging](./core/logger.md){target="_blank"} | `INFO` | +| __POWERTOOLS_SERVICE_NAME__ | Sets service name used for tracing namespace, metrics dimension and structured logging | All | `"service_undefined"` | +| __POWERTOOLS_METRICS_NAMESPACE__ | Sets namespace used for metrics | [Metrics](./core/metrics.md){target="_blank"} | `None` | +| __POWERTOOLS_TRACE_DISABLED__ | Explicitly disables tracing | [Tracing](./core/tracer.md){target="_blank"} | `false` | +| __POWERTOOLS_TRACER_CAPTURE_RESPONSE__ | Captures Lambda or method return as metadata. | [Tracing](./core/tracer.md){target="_blank"} | `true` | +| __POWERTOOLS_TRACER_CAPTURE_ERROR__ | Captures Lambda or method exception as metadata. | [Tracing](./core/tracer.md){target="_blank"} | `true` | +| __POWERTOOLS_TRACE_MIDDLEWARES__ | Creates sub-segment for each custom middleware | [Middleware factory](./utilities/middleware_factory.md){target="_blank"} | `false` | +| __POWERTOOLS_LOGGER_LOG_EVENT__ | Logs incoming event | [Logging](./core/logger.md){target="_blank"} | `false` | +| __POWERTOOLS_LOGGER_SAMPLE_RATE__ | Debug log sampling | [Logging](./core/logger.md){target="_blank"} | `0` | +| __POWERTOOLS_LOG_DEDUPLICATION_DISABLED__ | Disables log deduplication filter protection to use Pytest Live Log feature | [Logging](./core/logger.md){target="_blank"} | `false` | +| __POWERTOOLS_PARAMETERS_MAX_AGE__ | Adjust how long values are kept in cache (in seconds) | [Parameters](./utilities/parameters.md#adjusting-cache-ttl){target="_blank"} | `5` | +| __POWERTOOLS_PARAMETERS_SSM_DECRYPT__ | Sets whether to decrypt or not values retrieved from AWS SSM Parameters Store | [Parameters](./utilities/parameters.md#ssmprovider){target="_blank"} | `false` | +| __POWERTOOLS_DEV__ | Increases verbosity across utilities | Multiple; see [POWERTOOLS_DEV effect below](#optimizing-for-non-production-environments) | `false` | +| __POWERTOOLS_LOG_LEVEL__ | Sets logging level | [Logging](./core/logger.md){target="_blank"} | `INFO` | ### Optimizing for non-production environments @@ -737,9 +743,9 @@ When `POWERTOOLS_DEV` is set to a truthy value (`1`, `true`), it'll have the fol | Utility | Effect | | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| **Logger** | Increase JSON indentation to 4. This will ease local debugging when running functions locally under emulators or direct calls while not affecting unit tests | -| **Event Handler** | Enable full traceback errors in the response, indent request/responses, and CORS in dev mode (`*`). | -| **Tracer** | Future-proof safety to disables tracing operations in non-Lambda environments. This already happens automatically in the Tracer utility. | +| __Logger__ | Increase JSON indentation to 4. This will ease local debugging when running functions locally under emulators or direct calls while not affecting unit tests | +| __Event Handler__ | Enable full traceback errors in the response, indent request/responses, and CORS in dev mode (`*`). | +| __Tracer__ | Future-proof safety to disables tracing operations in non-Lambda environments. This already happens automatically in the Tracer utility. | ## Debug mode @@ -747,42 +753,98 @@ As a best practice for libraries, Powertools module logging statements are suppr When necessary, you can use `POWERTOOLS_DEBUG` environment variable to enable debugging. This will provide additional information on every internal operation. -## How to support Powertools for AWS Lambda (Python)? +## Support Powertools for AWS Lambda (Python) + +There are many ways you can help us gain future investments to improve everyone's experience: + +
+ +- :heart:{ .lg .middle } __Become a public reference__ + + --- + + Add your company name and logo on our [landing page](https://powertools.aws.dev). + + [:octicons-arrow-right-24: GitHub Issue template]((https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E){target="_blank"}) + +- :mega:{ .lg .middle } __Share your work__ + + --- + + Blog posts, video, and sample projects about Powertools for AWS Lambda. + + [:octicons-arrow-right-24: GitHub Issue template](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=community-content&template=share_your_work.yml&title=%5BI+Made+This%5D%3A+%3CTITLE%3E){target="_blank"} + +- :partying_face:{ .lg .middle } __Join the community__ + + --- + + Connect, ask questions, and share what features you use. + + [:octicons-arrow-right-24: Discord invite](https://discord.gg/B8zZKbbyET){target="blank"} + +
### Becoming a reference customer -Knowing which companies are using this library is important to help prioritize the project internally. If your company is using Powertools for AWS Lambda (Python), you can request to have your name and logo added to the README file by raising a [Support Powertools for AWS Lambda (Python) (become a reference)](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E){target="_blank"} issue. +Knowing which companies are using this library is important to help prioritize the project internally. The following companies, among others, use Powertools: + +
+ +[**Capital One**](https://www.capitalone.com/){target="_blank" rel="nofollow"} +{ .card } + +[**CPQi (Exadel Financial Services)**](https://cpqi.com/){target="_blank" rel="nofollow"} +{ .card } + +[**CloudZero**](https://www.cloudzero.com/){target="_blank" rel="nofollow"} +{ .card } + +[**CyberArk**](https://www.cyberark.com/){target="_blank" rel="nofollow"} +{ .card } + +[**globaldatanet**](https://globaldatanet.com/){target="_blank" rel="nofollow"} +{ .card } + +[**IMS**](https://ims.tech/){target="_blank" rel="nofollow"} +{ .card } + +[**Jit Security**](https://www.jit.io/){target="_blank" rel="nofollow"} +{ .card } + +[**Propellor.ai**](https://www.propellor.ai/){target="_blank" rel="nofollow"} +{ .card } + +[**TopSport**](https://www.topsport.com.au/){target="_blank" rel="nofollow"} +{ .card } + +[**Transformity**](https://transformity.tech/){target="_blank" rel="nofollow"} +{ .card } + +[**Trek10**](https://www.trek10.com/){target="_blank" rel="nofollow"} +{ .card } -The following companies, among others, use Powertools: +[**Vertex Pharmaceuticals**](https://www.vrtx.com/){target="_blank" rel="nofollow"} +{ .card } -* [Capital One](https://www.capitalone.com/){target="_blank" rel="nofollow"} -* [CPQi (Exadel Financial Services)](https://cpqi.com/){target="_blank" rel="nofollow"} -* [CloudZero](https://www.cloudzero.com/){target="_blank" rel="nofollow"} -* [CyberArk](https://www.cyberark.com/){target="_blank" rel="nofollow"} -* [globaldatanet](https://globaldatanet.com/){target="_blank" rel="nofollow"} -* [IMS](https://ims.tech/){target="_blank" rel="nofollow"} -* [Jit Security](https://www.jit.io/){target="_blank" rel="nofollow"} -* [Propellor.ai](https://www.propellor.ai/){target="_blank" rel="nofollow"} -* [TopSport](https://www.topsport.com.au/){target="_blank" rel="nofollow"} -* [Transformity](https://transformity.tech/){target="_blank" rel="nofollow"} -* [Trek10](https://www.trek10.com/){target="_blank" rel="nofollow"} -* [Vertex Pharmaceuticals](https://www.vrtx.com/){target="_blank" rel="nofollow"} +[**Alma Media**](https://www.almamedia.fi/en/){target="_blank" rel="nofollow} +{ .card } -### Sharing your work +
-Share what you did with Powertools for AWS Lambda (Python) 💞💞. Blog post, workshops, presentation, sample apps and others. Check out what the community has already shared about Powertools for AWS Lambda (Python) [here](https://docs.powertools.aws.dev/lambda/python/latest/we_made_this/){target="_blank"}. +### Using Lambda Layers -### Using Lambda Layer or SAR +!!! note "Layers help us understand who uses Powertools for AWS Lambda (Python) in a non-intrusive way." -This helps us understand who uses Powertools for AWS Lambda (Python) in a non-intrusive way, and helps us gain future investments for other Powertools for AWS Lambda languages. When [using Layers](https://docs.powertools.aws.dev/lambda/python/latest/#lambda-layer), you can add Powertools for AWS Lambda (Python) as a dev dependency (or as part of your virtual env) to not impact the development process. +When [using Layers](#lambda-layer), you can add Powertools for AWS Lambda (Python) as a dev dependency to not impact the development process. For Layers, we pre-package all dependencies, compile and optimize for storage and both x86 and ARM architecture. ## Tenets These are our core principles to guide our decision making. -* **AWS Lambda only**. We optimise for AWS Lambda function environments and supported runtimes only. Utilities might work with web frameworks and non-Lambda environments, though they are not officially supported. -* **Eases the adoption of best practices**. The main priority of the utilities is to facilitate best practices adoption, as defined in the AWS Well-Architected Serverless Lens; all other functionality is optional. -* **Keep it lean**. Additional dependencies are carefully considered for security and ease of maintenance, and prevent negatively impacting startup time. -* **We strive for backwards compatibility**. New features and changes should keep backwards compatibility. If a breaking change cannot be avoided, the deprecation and migration process should be clearly defined. -* **We work backwards from the community**. We aim to strike a balance of what would work best for 80% of customers. Emerging practices are considered and discussed via Requests for Comment (RFCs) -* **Progressive**. Utilities are designed to be incrementally adoptable for customers at any stage of their Serverless journey. They follow language idioms and their community’s common practices. +- __AWS Lambda only__. We optimise for AWS Lambda function environments and supported runtimes only. Utilities might work with web frameworks and non-Lambda environments, though they are not officially supported. +- __Eases the adoption of best practices__. The main priority of the utilities is to facilitate best practices adoption, as defined in the AWS Well-Architected Serverless Lens; all other functionality is optional. +- __Keep it lean__. Additional dependencies are carefully considered for security and ease of maintenance, and prevent negatively impacting startup time. +- __We strive for backwards compatibility__. New features and changes should keep backwards compatibility. If a breaking change cannot be avoided, the deprecation and migration process should be clearly defined. +- __We work backwards from the community__. We aim to strike a balance of what would work best for 80% of customers. Emerging practices are considered and discussed via Requests for Comment (RFCs) +- __Progressive__. Utilities are designed to be incrementally adoptable for customers at any stage of their Serverless journey. They follow language idioms and their community’s common practices. diff --git a/docs/overrides/main.html b/docs/overrides/main.html index 44935986883..6b741c797cf 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -1,8 +1,6 @@ {% extends "base.html" %} {% block announce %} -

🚨 As of February 8, 2024, AWS Lambda will no longer allow Python 3.7 functions to be updated. Inline with this, Powertools releases will stop supporting it.

-

Please ensure you update your functions to Python 3.8 or later to continue to use the latest version of Powertools for AWS Lambda (Python).

{% endblock %} {% block outdated %} diff --git a/docs/roadmap.md b/docs/roadmap.md index 766733c754c..6395bc344de 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -2,70 +2,66 @@ ## Overview -Our public roadmap outlines the high level direction we are working towards, namely [Themes](#themes). We update this document when our priorities change: security and stability is our top priority. +Our public roadmap outlines the high level direction we are working towards. We update this document when our priorities change: security and stability are our top priority. -!!! info "For most up-to-date information, see our [board of activities](https://github.com/orgs/aws-powertools/projects/3/views/2?query=is%3Aopen+sort%3Aupdated-desc){target="_blank"}." +!!! info "See our [current iteration cycle](https://github.com/orgs/aws-powertools/projects/3/views/14?query=is%3Aopen+sort%3Aupdated-desc){target="_blank"} for the most up-to-date information." -## Themes +## Key areas -Operational Excellence is priority number 1. This means bug fixing, stability, security, customer's support, and governance will take precedence above all else. +Security and operational excellence take precedence above all else. This means bug fixing, stability, customer's support, and internal compliance may delay one or more key areas below. -**What are themes?** +### Amazon Bedrock Agent Event Handler -They are key activities maintainers are focusing on. These are updated periodically and you can find the latest [under Themes in our public board](https://github.com/orgs/aws-powertools/projects/3/views/11?query=is%3Aopen+sort%3Aupdated-desc){target="_blank"}. - -### Observability providers - -We want to extend Tracer, Metrics, and Logger to support any [AWS Lambda certified observability partner](https://go.aws/3HtU6CZ){target="_blank"}, along with OpenTelemetry. - -At launch, we will support Datadog since it's [most requested observability provider](https://github.com/aws-powertools/powertools-lambda-python/issues/1433). OpenTelemetry will be a fast follow-up as we need to decide on a stable solution to cold start penalty. - -!!! tip "Help us identify which observability providers we should integrate next. Open [feature request](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=feature-request%2Ctriage&projects=&template=feature_request.yml&title=Feature+request%3A+TITLE){target="_blank"} or by voting `+1` in existing issues" +Based on [customers](https://github.com/aws-powertools/powertools-lambda-python#connect){target="_blank"} at re:Invent 2023, we will add a new Event Handler resolver to improve authoring and maintenance of Amazon Bedrock Agents. **Major updates** -- [x] [Document how customers can use any provider with Logger](https://docs.powertools.aws.dev/lambda/python/latest/core/logger/#observability-providers) -- [x] [Extend Metrics to add support for any Provider](https://github.com/aws-powertools/powertools-lambda-python/pull/2194) -- [ ] [Extend Tracer to add support for any Provider](https://github.com/aws-powertools/powertools-lambda-python/issues/2030) -- [ ] Investigate alternative solution to OpenTelemetry cold start performance +* [x] [Event Source Data Classes support](https://github.com/aws-powertools/powertools-lambda-python/pull/3262) +* [x] [Pydantic model _(Parser)_ support](https://github.com/aws-powertools/powertools-lambda-python/pull/3286) +* [x] [MVP Event Handler](https://github.com/aws-powertools/powertools-lambda-python/pull/3285) +* [ ] [New feature documentation](https://github.com/aws-powertools/powertools-lambda-python/pull/3602) +* [ ] Video to walkthrough use cases for anyone new to LLM Agents +* [ ] Launch amplifier (_e.g., What's New, Blog post_) -### Sensitive Data Masking +### Setting Parameters and Secrets -Data Masking will be a new utility to mask/unmask sensitive data using encryption providers. It's the second most voted feature request (behind [Observability Providers](#observability-providers)). +As of today, the [Parameters](./utilities/parameters.md){target="_blank"} feature is used to retrieve data, not to create or update existing parameters. Based on community feedback, we plan to enhance Parameters to allow set operations. **Major updates** -- [x] [RFC to agree on design and MVP](https://github.com/aws-powertools/powertools-lambda-python/issues/1858) -- [x] [POC with AWS KMS as the default provider](https://github.com/aws-powertools/powertools-lambda-python/pull/2197) -- [ ] User-guide documentation and include when not to use it (e.g., when to use SNS data policy, CloudWatch Logs data policy) -- [ ] Decide whether to use Encryption SDK to bring their own provider or a simply a contract (e.g., `ItsDangerous`) +* [x] [RFC](https://github.com/aws-powertools/powertools-lambda-python/issues/3040) +* [ ] [MVP](https://github.com/aws-powertools/powertools-lambda-python/pull/2858) -### Revamp Event Handler +### Observability providers -Event Handler provides lightweight routing for both [**REST**: Amazon API Gateway, Amazon Elastic Load Balancer and AWS Lambda Function URL](./core/event_handler/api_gateway.md), and [**GraphQL**: AWS AppSync](./core/event_handler/appsync.md). +We want to extend Tracer, Metrics, and Logger to support any [AWS Lambda certified observability partner](https://go.aws/3HtU6CZ){target="_blank"}, along with OpenTelemetry. -Based on customers feedback, we want to provide middleware authoring support for cross-cutting concerns. For REST APIs, we are also looking into auto-generate OpenAPI Schemas and a SwaggerUI route. For GraphQL, we are working on supporting batch invocations (N+1 problem) along with partial failure support. +At launch, we will support Datadog since it's [most requested observability provider](https://github.com/aws-powertools/powertools-lambda-python/issues/1433). OpenTelemetry will be a fast follow-up as we need to decide on a stable solution to cold start penalty. -**Major updates** +!!! tip "Help us identify which observability providers we should integrate next. Open [feature request](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=feature-request%2Ctriage&projects=&template=feature_request.yml&title=Feature+request%3A+TITLE){target="_blank"} or by voting `+1` in existing issues" -- [x] [Agree on experience for middleware support](https://github.com/aws-powertools/powertools-lambda-python/issues/953#issuecomment-1450223155) -- [x] [RFC to outline initial thoughts on OpenAPI integration](https://github.com/aws-powertools/powertools-lambda-python/issues/2421) -- [x] [MVP for REST middleware](./core/event_handler/api_gateway.md#middleware) -- [ ] [MVP for OpenAPI and SwaggerUI](https://github.com/aws-powertools/powertools-lambda-python/pull/3109) -- [ ] [MVP for AppSync Batch invoke and partial failure support](https://github.com/aws-powertools/powertools-lambda-python/pull/1998) +**Major updates** -### Lambda Layer in release notes +* [x] [Document how customers can use any provider with Logger](https://docs.powertools.aws.dev/lambda/python/latest/core/logger/#observability-providers) +* [x] [Extend Metrics to add support for any Provider](https://github.com/aws-powertools/powertools-lambda-python/pull/2194) +* [ ] [Extend Tracer to add support for any Provider](https://github.com/aws-powertools/powertools-lambda-python/issues/2030) +* [ ] Investigate alternative solution to OpenTelemetry cold start performance -We want to publish a JSON with a map of region and Lambda Layer ARN as a GitHub Release Note asset. +### Revamp Event Handler -As of V2, we prioritize Lambda Layers being available before release notes are out. This is due to X86 and ARM64 compilation for smaller binaries and extra speed. +Event Handler provides lightweight routing for both [**REST**: Amazon API Gateway, Amazon Elastic Load Balancer and AWS Lambda Function URL](./core/event_handler/api_gateway.md), and [**GraphQL**: AWS AppSync](./core/event_handler/appsync.md). -This means we have room to include a JSON map for Lambda Layers and facilitate automation for customers wanting the latest version as soon as it's available. + +Based on customers feedback, we want to provide [middleware authoring support](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#middleware) for cross-cutting concerns. For REST APIs, we are also looking into auto-generate [OpenAPI Schemas](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#data-validation) and a [SwaggerUI route](https://docs.powertools.aws.dev/lambda/python/latest/core/event_handler/api_gateway/#enabling-swaggerui). For GraphQL, we are working on supporting batch invocations (N+1 problem) along with partial failure support. + **Major updates** -- [x] Create secure mechanism to upload signed assets to GitHub Release Notes -- [ ] Create feature request to agree on JSON structure and asset name +* [x] [Agree on experience for middleware support](https://github.com/aws-powertools/powertools-lambda-python/issues/953#issuecomment-1450223155) +* [x] [RFC to outline initial thoughts on OpenAPI integration](https://github.com/aws-powertools/powertools-lambda-python/issues/2421) +* [x] [MVP for REST middleware](./core/event_handler/api_gateway.md#middleware) +* [x] [MVP for OpenAPI and SwaggerUI](https://github.com/aws-powertools/powertools-lambda-python/pull/3109) +* [ ] [MVP for AppSync Batch invoke and partial failure support](https://github.com/aws-powertools/powertools-lambda-python/pull/1998) ### Office hours @@ -77,7 +73,11 @@ Timezones being tricky, we plan to experiment with an afternoon slot in Central **Major updates** -- [ ] Decide whether to use Amazon Chime or Zoom (we had audio setup issues on Discord) +* [x] Decide whether to use Amazon Chime or Zoom (we had audio setup issues on Discord) +* [ ] Experiment running monthly roadmap review as an open call + * [ ] Settle on monthly roadmap review agenda + * [ ] Invite Discord community + * [ ] Update roadmap page with Discord event ### Authentication (SigV4) @@ -87,8 +87,8 @@ Since JWT is a close second, this new utility would cover higher level functions **Major updates** -- [ ] RFC to outline challenges, alternative solutions and desired experience -- [ ] MVP based off RFC +* [ ] RFC to outline challenges, alternative solutions and desired experience +* [ ] [MVP for AWS SigV4](https://github.com/aws-powertools/powertools-lambda-python/pull/2435) ### Enhanced operational metrics @@ -100,43 +100,45 @@ We want to make this easier by extending certain utilities to accept a `metrics` **Major updates** -- [ ] RFC to outline metrics for Batch (_e.g., Failed items, Batch size_) -- [ ] RFC to outline metrics for Feature flags (_e.g., matched rules_) -- [ ] RFC to outline metrics for Event Handler (_e.g., validation errors_ ) -- [ ] RFC to outline metrics for Idempotency (_e.g., cache hit_) +* [ ] RFC to outline metrics for Batch (_e.g., Failed items, Batch size_) +* [ ] RFC to outline metrics for Feature flags (_e.g., matched rules_) +* [ ] RFC to outline metrics for Event Handler (_e.g., validation errors_ ) +* [ ] RFC to outline metrics for Idempotency (_e.g., cache hit_) ### Lambda Layer in GovCloud and China region We want to investigate security and scaling requirements for these special regions, so they're in sync for every release. -!!! note "Help us prioritize it by reaching out to your AWS representatives or [via email](mailto:aws-lambda-powertools-feedback@amazon.com)." +!!! note "Help us prioritize it by reaching out to your AWS representatives or [via email](mailto:aws-powertools-maintainers@amazon.com)." **Major updates** -- [x] Gather agencies and customers name to prioritize it -- [x] Investigate security requirements for special regions -- [ ] Create additional infrastructure for special regions -- [ ] Update CDK Layer construct to include regions +* [x] Gather agencies and customers name to prioritize it +* [x] Investigate security requirements for special regions +* [x] Create additional infrastructure for special regions +* [ ] AppSec review +* [ ] Distribution sign-off +* [ ] Update CDK Layer construct to include regions ### V3 -We are in the process of planning the roadmap for v3. As always, our approach includes providing sufficient advance notice, a comprehensive upgrade guide, and minimizing breaking changes to facilitate a smooth transition (e.g., it took ~7 months from v2 to surpass v1 downloads). +We are in the process of planning the roadmap for v3. As always, [our approach](./versioning.md){target="_blank"} includes providing sufficient advance notice, a comprehensive upgrade guide, and minimizing breaking changes to facilitate a smooth transition (e.g., it took ~7 months from v2 to surpass v1 downloads). For example, these are on our mind but not settled yet until we have a public tracker to discuss what these means in detail. -- **Parser**: Drop Pydantic v1 -- **Parser**: Deserialize Amazon DynamoDB data types automatically (like Event Source Data Classes) -- **Parameters**: Increase default `max_age` for `get_secret` -- **Event Source Data Classes**: Return sane defaults for any property that has `Optional[]` returns -- **Upgrade tool**: Consider building a CST (Concrete Syntax Tree) tool to ease certain upgrade actions like `pyupgrade` and `django-upgrade` -- **Batch**: Stop at first error for Amazon DynamoDB Streams and Amazon Kinesis Data Streams (e.g., `stop_on_failure=True`) +* **Parser**: Drop Pydantic v1 +* **Parser**: Deserialize Amazon DynamoDB data types automatically (like Event Source Data Classes) +* **Parameters**: Increase default `max_age` for `get_secret` +* **Event Source Data Classes**: Return sane defaults for any property that has `Optional[]` returns +* **Upgrade tool**: Consider building a CST (Concrete Syntax Tree) tool to ease certain upgrade actions like `pyupgrade` and `django-upgrade` +* **Batch**: Stop at first error for Amazon DynamoDB Streams and Amazon Kinesis Data Streams (e.g., `stop_on_failure=True`) **Major updates** -- [ ] Create an issue to track breaking changes we consider making -- [ ] Create a v3 branch to allow early experimentation -- [ ] Create workflows to allow pre-releases -- [ ] Create a mechanism to keep ideas for breaking change somewhere regardless of v3 +* [ ] Create an issue to track breaking changes we consider making +* [ ] Create a v3 branch to allow early experimentation +* [ ] Create workflows to allow pre-releases +* [ ] Create a mechanism to keep ideas for breaking change somewhere regardless of v3 ## Roadmap status definition @@ -150,11 +152,11 @@ graph LR Within our [public board](https://github.com/orgs/aws-powertools/projects/3/views/1?query=is%3Aopen+sort%3Aupdated-desc){target="_blank"}, you'll see the following values in the `Status` column: -- **Ideas**. Incoming and existing feature requests that are not being actively considered yet. These will be reviewed when bandwidth permits. -- **Backlog**. Accepted feature requests or enhancements that we want to work on. -- **Working on it**. Features or enhancements we're currently either researching or implementing it. -- **Coming soon**. Any feature, enhancement, or bug fixes that have been merged and are coming in the next release. -- **Shipped**. Features or enhancements that are now available in the most recent release. +* **Ideas**. Incoming and existing feature requests that are not being actively considered yet. These will be reviewed when bandwidth permits. +* **Backlog**. Accepted feature requests or enhancements that we want to work on. +* **Working on it**. Features or enhancements we're currently either researching or implementing it. +* **Coming soon**. Any feature, enhancement, or bug fixes that have been merged and are coming in the next release. +* **Shipped**. Features or enhancements that are now available in the most recent release. > Tasks or issues with empty `Status` will be categorized in upcoming review cycles. @@ -176,12 +178,12 @@ graph LR Our end-to-end mechanism follows four major steps: -- **Feature Request**. Ideas start with a [feature request](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=feature-request%2Ctriage&template=feature_request.yml&title=Feature+request%3A+TITLE){target="_blank"} to outline their use case at a high level. For complex use cases, maintainers might ask for/write a RFC. - - Maintainers review requests based on [project tenets](index.md#tenets){target="_blank"}, customers reaction (👍), and use cases. -- **Request-for-comments (RFC)**. Design proposals use our [RFC issue template](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=RFC%2Ctriage&template=rfc.yml&title=RFC%3A+TITLE){target="_blank"} to describe its implementation, challenges, developer experience, dependencies, and alternative solutions. - - This helps refine the initial idea with community feedback before a decision is made. -- **Decision**. After carefully reviewing and discussing them, maintainers make a final decision on whether to start implementation, defer or reject it, and update everyone with the next steps. -- **Implementation**. For approved features, maintainers give priority to the original authors for implementation unless it is a sensitive task that is best handled by maintainers. +* **Feature Request**. Ideas start with a [feature request](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=feature-request%2Ctriage&template=feature_request.yml&title=Feature+request%3A+TITLE){target="_blank"} to outline their use case at a high level. For complex use cases, maintainers might ask for/write a RFC. + * Maintainers review requests based on [project tenets](index.md#tenets){target="_blank"}, customers reaction (👍), and use cases. +* **Request-for-comments (RFC)**. Design proposals use our [RFC issue template](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=RFC%2Ctriage&template=rfc.yml&title=RFC%3A+TITLE){target="_blank"} to describe its implementation, challenges, developer experience, dependencies, and alternative solutions. + * This helps refine the initial idea with community feedback before a decision is made. +* **Decision**. After carefully reviewing and discussing them, maintainers make a final decision on whether to start implementation, defer or reject it, and update everyone with the next steps. +* **Implementation**. For approved features, maintainers give priority to the original authors for implementation unless it is a sensitive task that is best handled by maintainers. ???+ info "See [Maintainers](https://github.com/aws-powertools/powertools-lambda-python/blob/develop/MAINTAINERS.md){target="_blank"} document to understand how we triage issues and pull requests, labels and governance." @@ -204,3 +206,45 @@ A: Because job zero is security and operational stability, we can't provide spec **Q: How can I provide feedback or ask for more information?** A: For existing features, you can directly comment on issues. For anything else, please open an issue. + +## Launched + +### Sensitive Data Masking + +> [Docs](./utilities/data_masking.md) + +Data Masking will be a new utility to mask/unmask sensitive data using encryption providers. It's the second most voted feature request (behind [Observability Providers](#observability-providers)). + +**Major updates** + +* [x] [RFC to agree on design and MVP](https://github.com/aws-powertools/powertools-lambda-python/issues/1858) +* [x] [POC with AWS KMS as the default provider](https://github.com/aws-powertools/powertools-lambda-python/pull/2197) +* [x] User-guide documentation and include when not to use it (e.g., when to use SNS data policy, CloudWatch Logs data policy) +* [x] Decide whether to use Encryption SDK to bring their own provider or a simply a contract (e.g., `ItsDangerous`) + +### Deprecate Python 3.7 support + +AWS Lambda will officially block updates to Lambda functions using Python 3.7 support. We will drop support as soon as [that is official](https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtimes.html#runtime-support-policy){target="_blank"}. + +**Major updates** + +* [x] [Drop Python 3.7 support](https://github.com/aws-powertools/powertools-lambda-python/pull/3638) +* [x] [Add documentation banner](https://github.com/aws-powertools/powertools-lambda-python/pull/3618) +* [x] [Publish versioning policy docs](https://github.com/aws-powertools/powertools-lambda-python/pull/3682) + +## Dropped + +### Lambda Layer in release notes + +> **Reason**: We are looking at more accessible alternatives based on customer feedback (e.g., AWS System Manager public parameters) + +We want to publish a JSON with a map of region and Lambda Layer ARN as a GitHub Release Note asset. + +As of V2, we prioritize Lambda Layers being available before release notes are out. This is due to X86 and ARM64 compilation for smaller binaries and extra speed. + +This means we have room to include a JSON map for Lambda Layers and facilitate automation for customers wanting the latest version as soon as it's available. + +**Major updates** + +* [x] Create secure mechanism to upload signed assets to GitHub Release Notes +* [ ] Create feature request to agree on JSON structure and asset name diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md index 5442a213562..c5acf22cead 100644 --- a/docs/tutorial/index.md +++ b/docs/tutorial/index.md @@ -1045,4 +1045,4 @@ This requires a change in mindset to ensure operational excellence is part of th Powertools for AWS Lambda (Python) is largely designed to make some of these practices easier to adopt from day 1. ???+ question "Have ideas for other tutorials?" - You can open up a [documentation issue](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=documentation&template=documentation-improvements.md&title=Tutorial%20Suggestion){target="_blank"}, or via e-mail [aws-lambda-powertools-feedback@amazon.com](mailto:aws-lambda-powertools-feedback@amazon.com). + You can open up a [documentation issue](https://github.com/aws-powertools/powertools-lambda-python/issues/new?assignees=&labels=documentation&template=documentation-improvements.md&title=Tutorial%20Suggestion){target="_blank"}, or via e-mail [aws-powertools-maintainers@amazon.com](mailto:aws-powertools-maintainers@amazon.com). diff --git a/mkdocs.yml b/mkdocs.yml index 50fe632539c..fc3373b5c98 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -87,6 +87,7 @@ theme: - navigation.tabs - content.code.annotate - content.code.copy + - content.tabs.link icon: repo: fontawesome/brands/github logo: media/aws-logo-light.svg @@ -98,6 +99,9 @@ markdown_extensions: - abbr - pymdownx.tabbed: alternate_style: true + slugify: !!python/object/apply:pymdownx.slugs.slugify + kwds: + case: lower - pymdownx.highlight: linenums: true - pymdownx.details @@ -112,9 +116,10 @@ markdown_extensions: permalink: true toc_depth: 4 - attr_list + - md_in_html - pymdownx.emoji: - emoji_index: !!python/name:materialx.emoji.twemoji - emoji_generator: !!python/name:materialx.emoji.to_svg + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg - pymdownx.inlinehilite - pymdownx.superfences: custom_fences: From ac4d4d8a7bdb3b0b805ba520fbfe95cbde94ff36 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:20:37 +0100 Subject: [PATCH 0088/2666] chore(deps-dev): bump the boto-typing group with 1 update (#3757) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 12 ++++++------ pyproject.toml | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/poetry.lock b/poetry.lock index f03da2f4473..8a926d29fb1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1897,13 +1897,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-cloudwatch" -version = "1.34.0" -description = "Type annotations for boto3.CloudWatch 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.40" +description = "Type annotations for boto3.CloudWatch 1.34.40 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-cloudwatch-1.34.0.tar.gz", hash = "sha256:cc18aa2b1a89eb4898a6c213db594abf62fe9afca6e8c6bd9aa04b9996193635"}, - {file = "mypy_boto3_cloudwatch-1.34.0-py3-none-any.whl", hash = "sha256:be4a8c90446595c6970898682a5f6eedb4a6b1d2d0b0cbe57ed021c818c48e14"}, + {file = "mypy-boto3-cloudwatch-1.34.40.tar.gz", hash = "sha256:33f0b747389ee5d72fe9319597b8a52395a24f5b9816b0862feec581afb148bc"}, + {file = "mypy_boto3_cloudwatch-1.34.40-py3-none-any.whl", hash = "sha256:9e66e0ab1006cb45ff36df1ab453bdef6ec700d6940466161049dc6efbd3e1b4"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "87ee762b995de6889cebcf87cea2dfcc209fc36044ff933bdb3247caa814a93d" +content-hash = "b2385e6d55e6f7916b5f9efd22c767b1a5db32c69f9660745677a5c1b7da62bc" diff --git a/pyproject.toml b/pyproject.toml index 2832d32d4b3..827cb3072bc 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -72,7 +72,7 @@ aws-cdk-lib = "^2.127.0" pytest-benchmark = "^4.0.0" mypy-boto3-appconfig = "^1.34.0" mypy-boto3-cloudformation = "^1.34.32" -mypy-boto3-cloudwatch = "^1.34.0" +mypy-boto3-cloudwatch = "^1.34.40" mypy-boto3-dynamodb = "^1.34.34" mypy-boto3-lambda = "^1.34.0" mypy-boto3-logs = "^1.34.16" From 285892961e271108bd9e11a4ec936eaaf81de6b9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:25:09 +0100 Subject: [PATCH 0089/2666] chore(deps): bump actions/dependency-review-action from 4.0.0 to 4.1.0 (#3771) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 3fee4d6b427..953b0e18576 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -19,4 +19,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Dependency Review' - uses: actions/dependency-review-action@4901385134134e04cec5fbe5ddfe3b2c5bd5d976 # v4.0.0 + uses: actions/dependency-review-action@80f10bf419f34980065523f5efca7ebed17576aa # v4.1.0 From 4dd4a2f57d434e5bb51b7c848bc44a70b13d84fa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:25:49 +0100 Subject: [PATCH 0090/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3764) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 30 +++++++-------- layer/scripts/layer-balancer/go.sum | 60 ++++++++++++++--------------- 2 files changed, 45 insertions(+), 45 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 4548c3f44f2..6529744574f 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -3,25 +3,25 @@ module layerbalancer go 1.18 require ( - github.com/aws/aws-sdk-go-v2 v1.24.1 - github.com/aws/aws-sdk-go-v2/config v1.26.6 - github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 + github.com/aws/aws-sdk-go-v2 v1.25.0 + github.com/aws/aws-sdk-go-v2/config v1.27.0 + github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 ) require ( - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.16.16 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect - github.com/aws/smithy-go v1.19.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.0 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 // indirect + github.com/aws/smithy-go v1.20.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index ec29fc3ea00..1e9d8aacce7 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -1,33 +1,33 @@ -github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU= -github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4 h1:OCs21ST2LrepDfD3lwlQiOqIGp6JiEUqG84GzTDoyJs= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.5.4/go.mod h1:usURWEKSNNAcAZuzRn/9ZYPT8aZQkR7xcCtunK/LkJo= -github.com/aws/aws-sdk-go-v2/config v1.26.6 h1:Z/7w9bUqlRI0FFQpetVuFYEsjzE3h7fpU6HuGmfPL/o= -github.com/aws/aws-sdk-go-v2/config v1.26.6/go.mod h1:uKU6cnDmYCvJ+pxO9S4cWDb2yWWIH5hra+32hVh1MI4= -github.com/aws/aws-sdk-go-v2/credentials v1.16.16 h1:8q6Rliyv0aUFAVtzaldUEcS+T5gbadPbWdV1WcAddK8= -github.com/aws/aws-sdk-go-v2/credentials v1.16.16/go.mod h1:UHVZrdUsv63hPXFo1H7c5fEneoVo9UXiz36QG1GEPi0= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3 h1:n3GDfwqF2tzEkXlv5cuy4iy7LpKDtqDMcNLfZDu9rls= -github.com/aws/aws-sdk-go-v2/internal/ini v1.7.3/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino= -github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7 h1:YCvhGwdiZ9tKTjoIOE8jLt+3JBK4quAQyhoMCWtxhQc= -github.com/aws/aws-sdk-go-v2/service/lambda v1.49.7/go.mod h1:xqjYGK1M7YTmyfZBW8LVAx7QnefUb/mE5BglUnxtx6E= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.7 h1:eajuO3nykDPdYicLlP3AGgOyVN3MOlFmZv7WGTuJPow= -github.com/aws/aws-sdk-go-v2/service/sso v1.18.7/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0= -github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U= -github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= -github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= +github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ= +github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 h1:2UO6/nT1lCZq1LqM67Oa4tdgP1CvL1sLSxvuD+VrOeE= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0/go.mod h1:5zGj2eA85ClyedTDK+Whsu+w9yimnVIZvhvBKrDquM8= +github.com/aws/aws-sdk-go-v2/config v1.27.0 h1:J5sdGCAHuWKIXLeXiqr8II/adSvetkx0qdZwdbXXpb0= +github.com/aws/aws-sdk-go-v2/config v1.27.0/go.mod h1:cfh8v69nuSUohNFMbIISP2fhmblGmYEOKs5V53HiHnk= +github.com/aws/aws-sdk-go-v2/credentials v1.17.0 h1:lMW2x6sKBsiAJrpi1doOXqWFyEPoE886DTb1X0wb7So= +github.com/aws/aws-sdk-go-v2/credentials v1.17.0/go.mod h1:uT41FIH8cCIxOdUYIL0PYyHlL1NoneDuDSCwg5VE/5o= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 h1:xWCwjjvVz2ojYTP4kBKUuUh9ZrXfcAXpflhOUUeXg1k= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0/go.mod h1:j3fACuqXg4oMTQOR2yY7m0NmJY0yBK4L4sLsRXq1Ins= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 h1:NPs/EqVO+ajwOoq56EfcGKa3L3ruWuazkIw1BqxwOPw= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0/go.mod h1:D+duLy2ylgatV+yTlQ8JTuLfDD0BnFvnQRc+o6tbZ4M= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 h1:ks7KGMVUMoDzcxNWUlEdI+/lokMFD136EL6DWmUOV80= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0/go.mod h1:hL6BWM/d/qz113fVitZjbXR0E+RCTU1+x+1Idyn5NgE= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFlO0KsveiP90IUJh8Xr/cx9US2PqkSroaLc+o8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA= +github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0 h1:fBJs+X3ZOEqpmiSb7as6DBqm7K2RTkbaxYL9RBGCZyE= +github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.0/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 h1:6DL0qu5+315wbsAEEmzK+P9leRwNbkp+lGjPC+CEvb8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3JmwC77mdxIIyPWCdpM= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= +github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= +github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= From a2ba47e82533b4b04844b84745180aa6521e24e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:26:14 +0100 Subject: [PATCH 0091/2666] chore(deps): bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs (#3756) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 9de94938c2b..d972b487853 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:6a72238e24c73e4cebb1ceddf8603778d25739ffbf480a314628a3d81aee2214 +FROM squidfunk/mkdocs-material@sha256:62d36688f2a53f4f6ee11bace3a0fd17eed7f38fa127a8c58f4fee704054e3a6 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From af0a55e1bd9977891249ff5ff9e3b7d4a63278e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:28:03 +0100 Subject: [PATCH 0092/2666] chore(deps-dev): bump sentry-sdk from 1.40.3 to 1.40.4 (#3765) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8a926d29fb1..8e2ebf06c10 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2924,13 +2924,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.3" +version = "1.40.4" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.3.tar.gz", hash = "sha256:3c2b027979bb400cd65a47970e64f8cef8acda86b288a27f42a98692505086cd"}, - {file = "sentry_sdk-1.40.3-py2.py3-none-any.whl", hash = "sha256:73383f28311ae55602bb6cc3b013830811135ba5521e41333a6e68f269413502"}, + {file = "sentry-sdk-1.40.4.tar.gz", hash = "sha256:657abae98b0050a0316f0873d7149f951574ae6212f71d2e3a1c4c88f62d6456"}, + {file = "sentry_sdk-1.40.4-py2.py3-none-any.whl", hash = "sha256:ac5cf56bb897ec47135d239ddeedf7c1c12d406fb031a4c0caa07399ed014d7e"}, ] [package.dependencies] @@ -2956,7 +2956,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure-eval"] +pure-eval = ["asttokens", "executing", "pure_eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] From dab2aee0f79fb7420562de9550fb83b7b45e7ff2 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 09:30:07 +0100 Subject: [PATCH 0093/2666] chore(ci): changelog rebuild (#3772) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> Co-authored-by: Heitor Lessa --- CHANGELOG.md | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a432b76beb1..2a6358627b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,64 @@ # Unreleased +## Documentation + +* **homepage:** discord flat badge style; remove former devax email ([#3768](https://github.com/aws-powertools/powertools-lambda-python/issues/3768)) +* **roadmap:** latest roadmap update; use new grid to de-clutter homepage ([#3755](https://github.com/aws-powertools/powertools-lambda-python/issues/3755)) + +## Features + +* **feature_flags:** add intersect actions for conditions ([#3692](https://github.com/aws-powertools/powertools-lambda-python/issues/3692)) + +## Maintenance + +* **deps-dev:** bump aws-cdk from 2.126.0 to 2.127.0 ([#3761](https://github.com/aws-powertools/powertools-lambda-python/issues/3761)) +* **deps-dev:** bump mkdocs-material from 9.5.8 to 9.5.9 ([#3759](https://github.com/aws-powertools/powertools-lambda-python/issues/3759)) +* **deps-dev:** bump sentry-sdk from 1.40.2 to 1.40.3 ([#3750](https://github.com/aws-powertools/powertools-lambda-python/issues/3750)) +* **deps-dev:** bump cfn-lint from 0.85.0 to 0.85.1 ([#3749](https://github.com/aws-powertools/powertools-lambda-python/issues/3749)) +* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) + ## [v2.33.1] - 2024-02-09 +## Bug Fixes + +* **typing:** make Response headers covariant ([#3745](https://github.com/aws-powertools/powertools-lambda-python/issues/3745)) + +## Documentation + +* Add nathan hanks post community ([#3727](https://github.com/aws-powertools/powertools-lambda-python/issues/3727)) + ## Maintenance * version bump +* **ci:** drop support for Python 3.7 ([#3638](https://github.com/aws-powertools/powertools-lambda-python/issues/3638)) +* **ci:** enable Redis e2e tests ([#3718](https://github.com/aws-powertools/powertools-lambda-python/issues/3718)) +* **deps:** bump actions/setup-node from 4.0.1 to 4.0.2 ([#3737](https://github.com/aws-powertools/powertools-lambda-python/issues/3737)) +* **deps:** bump squidfunk/mkdocs-material from `e0d6c67` to `6a72238` in /docs ([#3735](https://github.com/aws-powertools/powertools-lambda-python/issues/3735)) +* **deps:** bump actions/dependency-review-action from 3.1.5 to 4.0.0 ([#3646](https://github.com/aws-powertools/powertools-lambda-python/issues/3646)) +* **deps:** bump release-drafter/release-drafter from 5.25.0 to 6.0.0 ([#3699](https://github.com/aws-powertools/powertools-lambda-python/issues/3699)) +* **deps:** bump actions/download-artifact from 4.1.1 to 4.1.2 ([#3725](https://github.com/aws-powertools/powertools-lambda-python/issues/3725)) +* **deps:** bump squidfunk/mkdocs-material from `a4a2029` to `e0d6c67` in /docs ([#3708](https://github.com/aws-powertools/powertools-lambda-python/issues/3708)) +* **deps:** bump codecov/codecov-action from 3.1.6 to 4.0.1 ([#3700](https://github.com/aws-powertools/powertools-lambda-python/issues/3700)) +* **deps:** bump actions/download-artifact from 3.0.2 to 4.1.1 ([#3612](https://github.com/aws-powertools/powertools-lambda-python/issues/3612)) +* **deps:** revert aws-cdk-lib as a runtime dep ([#3730](https://github.com/aws-powertools/powertools-lambda-python/issues/3730)) +* **deps:** bump actions/upload-artifact from 3.1.3 to 4.3.1 ([#3714](https://github.com/aws-powertools/powertools-lambda-python/issues/3714)) +* **deps-dev:** bump cfn-lint from 0.83.8 to 0.85.0 ([#3724](https://github.com/aws-powertools/powertools-lambda-python/issues/3724)) +* **deps-dev:** bump httpx from 0.24.1 to 0.26.0 ([#3712](https://github.com/aws-powertools/powertools-lambda-python/issues/3712)) +* **deps-dev:** bump pytest from 7.4.4 to 8.0.0 ([#3711](https://github.com/aws-powertools/powertools-lambda-python/issues/3711)) +* **deps-dev:** bump sentry-sdk from 1.40.1 to 1.40.2 ([#3740](https://github.com/aws-powertools/powertools-lambda-python/issues/3740)) +* **deps-dev:** bump coverage from 7.2.7 to 7.4.1 ([#3713](https://github.com/aws-powertools/powertools-lambda-python/issues/3713)) +* **deps-dev:** bump the boto-typing group with 7 updates ([#3709](https://github.com/aws-powertools/powertools-lambda-python/issues/3709)) +* **deps-dev:** bump types-python-dateutil from 2.8.19.14 to 2.8.19.20240106 ([#3720](https://github.com/aws-powertools/powertools-lambda-python/issues/3720)) +* **deps-dev:** bump mypy from 1.4.1 to 1.8.0 ([#3710](https://github.com/aws-powertools/powertools-lambda-python/issues/3710)) +* **deps-dev:** bump ruff from 0.2.0 to 0.2.1 ([#3742](https://github.com/aws-powertools/powertools-lambda-python/issues/3742)) +* **deps-dev:** bump isort from 5.11.5 to 5.13.2 ([#3723](https://github.com/aws-powertools/powertools-lambda-python/issues/3723)) +* **deps-dev:** bump pytest-socket from 0.6.0 to 0.7.0 ([#3721](https://github.com/aws-powertools/powertools-lambda-python/issues/3721)) +* **deps-dev:** bump ruff from 0.1.15 to 0.2.0 ([#3702](https://github.com/aws-powertools/powertools-lambda-python/issues/3702)) +* **deps-dev:** bump aws-cdk from 2.125.0 to 2.126.0 ([#3701](https://github.com/aws-powertools/powertools-lambda-python/issues/3701)) +* **deps-dev:** bump hvac from 1.2.1 to 2.1.0 ([#3738](https://github.com/aws-powertools/powertools-lambda-python/issues/3738)) +* **deps-dev:** bump black from 23.12.1 to 24.1.1 ([#3739](https://github.com/aws-powertools/powertools-lambda-python/issues/3739)) From e46e32e3ce6a574229920dab2cec01db0de03971 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 15 Feb 2024 10:14:16 +0100 Subject: [PATCH 0094/2666] chore(deps-dev): bump pytest-asyncio from 0.21.1 to 0.23.5 (#3773) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 14 +++++++------- pyproject.toml | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/poetry.lock b/poetry.lock index 8e2ebf06c10..d11bfd17a04 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2323,21 +2323,21 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no [[package]] name = "pytest-asyncio" -version = "0.21.1" +version = "0.23.5" description = "Pytest support for asyncio" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pytest-asyncio-0.21.1.tar.gz", hash = "sha256:40a7eae6dded22c7b604986855ea48400ab15b069ae38116e8c01238e9eeb64d"}, - {file = "pytest_asyncio-0.21.1-py3-none-any.whl", hash = "sha256:8666c1c8ac02631d7c51ba282e0c69a8a452b211ffedf2599099845da5c5c37b"}, + {file = "pytest-asyncio-0.23.5.tar.gz", hash = "sha256:3a048872a9c4ba14c3e90cc1aa20cbc2def7d01c7c8db3777ec281ba9c057675"}, + {file = "pytest_asyncio-0.23.5-py3-none-any.whl", hash = "sha256:4e7093259ba018d58ede7d5315131d21923a60f8a6e9ee266ce1589685c89eac"}, ] [package.dependencies] -pytest = ">=7.0.0" +pytest = ">=7.0.0,<9" [package.extras] docs = ["sphinx (>=5.3)", "sphinx-rtd-theme (>=1.0)"] -testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy (>=0.931)", "pytest-trio (>=0.7.0)"] +testing = ["coverage (>=6.2)", "hypothesis (>=5.7.1)"] [[package]] name = "pytest-benchmark" @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "b2385e6d55e6f7916b5f9efd22c767b1a5db32c69f9660745677a5c1b7da62bc" +content-hash = "21b9c95f6120a15da1da969297f3050cc32643222f2819006995d154d3c5945a" diff --git a/pyproject.toml b/pyproject.toml index 827cb3072bc..9f866c71d3d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,7 +58,7 @@ isort = "^5.13.2" pytest-cov = "^4.1.0" pytest-mock = "^3.11.1" pdoc3 = "^0.10.0" -pytest-asyncio = "^0.21.1" +pytest-asyncio = "^0.23.5" bandit = "^1.7.5" radon = "^6.0.1" xenon = "^0.9.1" From f31ea17c9a6e306ba719d5a90840ca1b18464d8b Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Thu, 15 Feb 2024 10:17:20 +0100 Subject: [PATCH 0095/2666] fix(event-handler): handle aliased parameters e.g., Query(alias="categoryType") (#3766) * fix(event-handler): correctly handle aliased parameters * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * chore: no-op exception suppress Signed-off-by: heitorlessa * fix: use local event, not global to prevent race condition Signed-off-by: heitorlessa * Revert "chore: no-op exception suppress" This reverts commit f79dffcfedf7f5f97509da2e4eb253c559f00f75. --------- Signed-off-by: heitorlessa Co-authored-by: Heitor Lessa Co-authored-by: heitorlessa --- .../middlewares/openapi_validation.py | 2 +- .../test_openapi_validation_middleware.py | 24 ++++++++++++++++++- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py index 54c48189282..25ac97ddf89 100644 --- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py @@ -388,7 +388,7 @@ def _normalize_multi_query_string_with_param(query_string: Optional[Dict[str, st try: # if the target parameter is a scalar, we keep the first value of the query string # regardless if there are more in the payload - query_string[param.name] = query_string[param.name][0] + query_string[param.alias] = query_string[param.alias][0] except KeyError: pass return query_string diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index 07e2a34ac42..be3a13dd656 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from enum import Enum from pathlib import PurePath -from typing import List, Tuple +from typing import List, Optional, Tuple import pytest from pydantic import BaseModel @@ -15,9 +15,11 @@ Response, VPCLatticeResolver, VPCLatticeV2Resolver, + content_types, ) from aws_lambda_powertools.event_handler.openapi.params import Body, Header, Query from aws_lambda_powertools.shared.types import Annotated +from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent from tests.functional.utils import load_event LOAD_GW_EVENT = load_event("apiGatewayProxyEvent.json") @@ -1018,3 +1020,23 @@ def handler3(): # IF expected_error_text is provided, THEN check for its presence in the response body if expected_error_text: assert any(text in result["body"] for text in expected_error_text) + + +def test_validation_with_alias(): + # GIVEN a Http API V2 proxy type event + app = APIGatewayRestResolver(enable_validation=True) + event = load_event("apiGatewayProxyEvent.json") + + class FunkyTown(BaseModel): + parameter: str + + @app.get("/my/path") + def my_path( + parameter: Annotated[Optional[str], Query(alias="parameter1")] = None, + ) -> Response[FunkyTown]: + assert isinstance(app.current_event, APIGatewayProxyEvent) + assert parameter == "value1" + return Response(200, content_types.APPLICATION_JSON, FunkyTown(parameter=parameter)) + + result = app(event, {}) + assert result["statusCode"] == 200 From 884d251bccf6291274c6c4b7aac6e84b3a59446a Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Thu, 15 Feb 2024 10:25:58 +0100 Subject: [PATCH 0096/2666] docs(home): add note about POWERTOOLS_DEV side effects in CloudWatch Logs (#3770) --- docs/index.md | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/docs/index.md b/docs/index.md index d31dcbf9396..2ea2de39794 100644 --- a/docs/index.md +++ b/docs/index.md @@ -734,18 +734,17 @@ Core utilities such as Tracing, Logging, Metrics, and Event Handler will be avai ### Optimizing for non-production environments -Whether you're prototyping locally or against a non-production environment, you can use `POWERTOOLS_DEV` to increase verbosity across multiple utilities. +!!! info "We will emit a warning when this feature is used to help you detect misuse in production." -???+ info - We will emit a warning when `POWERTOOLS_DEV` is enabled to help you detect misuse in production environments. +Whether you're prototyping locally or against a non-production environment, you can use `POWERTOOLS_DEV` to increase verbosity across multiple utilities. When `POWERTOOLS_DEV` is set to a truthy value (`1`, `true`), it'll have the following effects: -| Utility | Effect | -| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| __Logger__ | Increase JSON indentation to 4. This will ease local debugging when running functions locally under emulators or direct calls while not affecting unit tests | -| __Event Handler__ | Enable full traceback errors in the response, indent request/responses, and CORS in dev mode (`*`). | -| __Tracer__ | Future-proof safety to disables tracing operations in non-Lambda environments. This already happens automatically in the Tracer utility. | +| Utility | Effect | +| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| __Logger__ | Increase JSON indentation to 4. This will ease local debugging when running functions locally under emulators or direct calls while not affecting unit tests.

However, Amazon CloudWatch Logs view will degrade as each new line is treated as a new message. | +| __Event Handler__ | Enable full traceback errors in the response, indent request/responses, and CORS in dev mode (`*`). | +| __Tracer__ | Future-proof safety to disables tracing operations in non-Lambda environments. This already happens automatically in the Tracer utility. | ## Debug mode From cc69e5499594567a4e6dfb507b926318667f6901 Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Fri, 16 Feb 2024 03:58:05 -0500 Subject: [PATCH 0097/2666] docs(home): update layer version to 62 for package version 2.33.1 (#3778) --- docs/index.md | 138 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 4 files changed, 72 insertions(+), 72 deletions(-) diff --git a/docs/index.md b/docs/index.md index 2ea2de39794..7aa9a7d956d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,8 +56,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. - * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: - * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: ???+ note "Code snippets for popular infrastructure as code frameworks" @@ -70,7 +70,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 ``` === "Serverless framework" @@ -80,7 +80,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 ``` === "CDK" @@ -96,7 +96,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -145,7 +145,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -198,7 +198,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2:61 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 ❯ amplify push -y @@ -209,7 +209,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2:61 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 ? Do you want to edit the local lambda function now? No ``` @@ -223,7 +223,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 ``` === "Serverless framework" @@ -234,7 +234,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 ``` === "CDK" @@ -250,7 +250,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -300,7 +300,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -356,7 +356,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2-Arm64:61 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 ❯ amplify push -y @@ -367,7 +367,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2-Arm64:61 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 ? Do you want to edit the local lambda function now? No ``` @@ -414,74 +414,74 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:61](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:61](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | **Want to inspect the contents of the Layer?** Replace `{region}` with your AWS region, _e.g. `eu-west-1`_. The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:61 --region {region} +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 --region {region} ``` #### SAR diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 02885ffb3bb..1728dd91e37 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:AWSLambdaPowertoolsPythonV2:61 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 2b9e885f20d..d3c0bb3c720 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,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:AWSLambdaPowertoolsPythonV2:61 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index a7961c7c44b..5abd93f9713 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:AWSLambdaPowertoolsPythonV2:61 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 Resources: CaptureLambdaHandlerExample: From d957228be5f886154cb0b1439f6378b4bfb1471b Mon Sep 17 00:00:00 2001 From: Andrea Amorosi Date: Fri, 16 Feb 2024 18:09:23 +0100 Subject: [PATCH 0098/2666] docs(homepage): remove leftover announcement banner (#3783) --- docs/overrides/main.html | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/overrides/main.html b/docs/overrides/main.html index 6b741c797cf..0af326afb24 100644 --- a/docs/overrides/main.html +++ b/docs/overrides/main.html @@ -1,8 +1,5 @@ {% extends "base.html" %} -{% block announce %} -{% endblock %} - {% block outdated %} You're not viewing the latest version. From b266979ee658dbf7247823a1454637dd0d22e3c0 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Mon, 19 Feb 2024 14:19:08 +0100 Subject: [PATCH 0099/2666] refactor(feature-flags): add intersection tests; structure refinement (#3775) Co-authored-by: Ruben Fonseca --- .../utilities/feature_flags/__init__.py | 1 + .../utilities/feature_flags/comparators.py | 84 ++++-- .../utilities/feature_flags/feature_flags.py | 155 ++++++++-- .../utilities/feature_flags/schema.py | 272 +++++++++++------- ruff.toml | 16 +- .../feature_flags/test_feature_flags.py | 257 +++++++++++++++++ .../feature_flags/test_schema_validation.py | 66 ++++- 7 files changed, 664 insertions(+), 187 deletions(-) diff --git a/aws_lambda_powertools/utilities/feature_flags/__init__.py b/aws_lambda_powertools/utilities/feature_flags/__init__.py index db7dfca5b57..e8d8229c9dc 100644 --- a/aws_lambda_powertools/utilities/feature_flags/__init__.py +++ b/aws_lambda_powertools/utilities/feature_flags/__init__.py @@ -1,4 +1,5 @@ """Advanced feature flags utility""" + from .appconfig import AppConfigStore from .base import StoreProvider from .exceptions import ConfigurationStoreError diff --git a/aws_lambda_powertools/utilities/feature_flags/comparators.py b/aws_lambda_powertools/utilities/feature_flags/comparators.py index 1419dd6dd83..03cb91e649a 100644 --- a/aws_lambda_powertools/utilities/feature_flags/comparators.py +++ b/aws_lambda_powertools/utilities/feature_flags/comparators.py @@ -1,10 +1,11 @@ +from __future__ import annotations + from datetime import datetime, tzinfo from typing import Any, Dict, Optional from dateutil.tz import gettz from .schema import HOUR_MIN_SEPARATOR, ModuloRangeValues, TimeValues -from .exceptions import SchemaValidationError def _get_now_from_timezone(timezone: Optional[tzinfo]) -> datetime: @@ -85,41 +86,64 @@ def compare_modulo_range(context_value: int, condition_value: Dict) -> bool: return start <= context_value % base <= end -def compare_any_in_list(key_list, value_list): - if not (isinstance(key_list, list) and isinstance(value_list, list)): - raise SchemaValidationError() - - results = False - for key in key_list: - if key in value_list: - results = True - break - - return results +def compare_any_in_list(context_value: list, condition_value: list) -> bool: + """Comparator for ANY_IN_VALUE action + + Parameters + ---------- + context_value : list + user-defined context for flag evaluation + condition_value : list + schema value available for condition being evaluated + + Returns + ------- + bool + Whether any list item in context_value is available in condition_value + """ + if not isinstance(context_value, list): + raise ValueError("Context provided must be a list. Unable to compare ANY_IN_VALUE action.") + + return any(key in condition_value for key in context_value) + +def compare_all_in_list(context_value: list, condition_value: list) -> bool: + """Comparator for ALL_IN_VALUE action -def compare_all_in_list(key_list, value_list): - if not (isinstance(key_list, list) and isinstance(value_list, list)): - raise SchemaValidationError() + Parameters + ---------- + context_value : list + user-defined context for flag evaluation + condition_value : list + schema value available for condition being evaluated - results = True - for key in key_list: - if key not in value_list: - results = False - break + Returns + ------- + bool + Whether all list items in context_value are available in condition_value + """ + if not isinstance(context_value, list): + raise ValueError("Context provided must be a list. Unable to compare ALL_IN_VALUE action.") - return results + return all(key in condition_value for key in context_value) -def compare_none_in_list(key_list, value_list): - if not (isinstance(key_list, list) and isinstance(value_list, list)): - raise SchemaValidationError() +def compare_none_in_list(context_value: list, condition_value: list) -> bool: + """Comparator for NONE_IN_VALUE action - results = True - for key in key_list: - if key in value_list: - results = False - break + Parameters + ---------- + context_value : list + user-defined context for flag evaluation + condition_value : list + schema value available for condition being evaluated - return results + Returns + ------- + bool + Whether list items in context_value are **not** available in condition_value + """ + if not isinstance(context_value, list): + raise ValueError("Context provided must be a list. Unable to compare NONE_IN_VALUE action.") + return all(key not in condition_value for key in context_value) diff --git a/aws_lambda_powertools/utilities/feature_flags/feature_flags.py b/aws_lambda_powertools/utilities/feature_flags/feature_flags.py index ac4dfef0162..bd7e19d0efe 100644 --- a/aws_lambda_powertools/utilities/feature_flags/feature_flags.py +++ b/aws_lambda_powertools/utilities/feature_flags/feature_flags.py @@ -1,21 +1,52 @@ +from __future__ import annotations + import logging -from typing import Any, Dict, List, Optional, Union, cast +from typing import Any, Callable, Dict, List, Optional, TypeVar, Union, cast + +from typing_extensions import ParamSpec from ... import Logger from ...shared.types import JSONType from . import schema from .base import StoreProvider from .comparators import ( + compare_all_in_list, + compare_any_in_list, compare_datetime_range, compare_days_of_week, compare_modulo_range, + compare_none_in_list, compare_time_range, - compare_all_in_list, - compare_any_in_list, - compare_none_in_list ) from .exceptions import ConfigurationStoreError +T = TypeVar("T") +P = ParamSpec("P") + +RULE_ACTION_MAPPING = { + schema.RuleAction.EQUALS.value: lambda a, b: a == b, + schema.RuleAction.NOT_EQUALS.value: lambda a, b: a != b, + schema.RuleAction.KEY_GREATER_THAN_VALUE.value: lambda a, b: a > b, + schema.RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value: lambda a, b: a >= b, + schema.RuleAction.KEY_LESS_THAN_VALUE.value: lambda a, b: a < b, + schema.RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value: lambda a, b: a <= b, + schema.RuleAction.STARTSWITH.value: lambda a, b: a.startswith(b), + schema.RuleAction.ENDSWITH.value: lambda a, b: a.endswith(b), + schema.RuleAction.IN.value: lambda a, b: a in b, + schema.RuleAction.NOT_IN.value: lambda a, b: a not in b, + schema.RuleAction.KEY_IN_VALUE.value: lambda a, b: a in b, + schema.RuleAction.KEY_NOT_IN_VALUE.value: lambda a, b: a not in b, + schema.RuleAction.VALUE_IN_KEY.value: lambda a, b: b in a, + schema.RuleAction.VALUE_NOT_IN_KEY.value: lambda a, b: b not in a, + schema.RuleAction.ALL_IN_VALUE.value: lambda a, b: compare_all_in_list(a, b), + schema.RuleAction.ANY_IN_VALUE.value: lambda a, b: compare_any_in_list(a, b), + schema.RuleAction.NONE_IN_VALUE.value: lambda a, b: compare_none_in_list(a, b), + schema.RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value: lambda a, b: compare_time_range(a, b), + schema.RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value: lambda a, b: compare_datetime_range(a, b), + schema.RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value: lambda a, b: compare_days_of_week(a, b), + schema.RuleAction.MODULO_RANGE.value: lambda a, b: compare_modulo_range(a, b), +} + class FeatureFlags: def __init__(self, store: StoreProvider, logger: Optional[Union[logging.Logger, Logger]] = None): @@ -49,37 +80,20 @@ def __init__(self, store: StoreProvider, logger: Optional[Union[logging.Logger, """ self.store = store self.logger = logger or logging.getLogger(__name__) + self._exception_handlers: dict[Exception, Callable] = {} def _match_by_action(self, action: str, condition_value: Any, context_value: Any) -> bool: - mapping_by_action = { - schema.RuleAction.EQUALS.value: lambda a, b: a == b, - schema.RuleAction.NOT_EQUALS.value: lambda a, b: a != b, - schema.RuleAction.KEY_GREATER_THAN_VALUE.value: lambda a, b: a > b, - schema.RuleAction.KEY_GREATER_THAN_OR_EQUAL_VALUE.value: lambda a, b: a >= b, - schema.RuleAction.KEY_LESS_THAN_VALUE.value: lambda a, b: a < b, - schema.RuleAction.KEY_LESS_THAN_OR_EQUAL_VALUE.value: lambda a, b: a <= b, - schema.RuleAction.STARTSWITH.value: lambda a, b: a.startswith(b), - schema.RuleAction.ENDSWITH.value: lambda a, b: a.endswith(b), - schema.RuleAction.IN.value: lambda a, b: a in b, - schema.RuleAction.NOT_IN.value: lambda a, b: a not in b, - schema.RuleAction.KEY_IN_VALUE.value: lambda a, b: a in b, - schema.RuleAction.KEY_NOT_IN_VALUE.value: lambda a, b: a not in b, - schema.RuleAction.VALUE_IN_KEY.value: lambda a, b: b in a, - schema.RuleAction.VALUE_NOT_IN_KEY.value: lambda a, b: b not in a, - schema.RuleAction.ALL_IN_VALUE.value: lambda a, b: compare_all_in_list(a, b), - schema.RuleAction.ANY_IN_VALUE.value: lambda a, b: compare_any_in_list(a, b), - schema.RuleAction.NONE_IN_VALUE.value: lambda a, b: compare_none_in_list(a, b), - schema.RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value: lambda a, b: compare_time_range(a, b), - schema.RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value: lambda a, b: compare_datetime_range(a, b), - schema.RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value: lambda a, b: compare_days_of_week(a, b), - schema.RuleAction.MODULO_RANGE.value: lambda a, b: compare_modulo_range(a, b), - } - try: - func = mapping_by_action.get(action, lambda a, b: False) + func = RULE_ACTION_MAPPING.get(action, lambda a, b: False) return func(context_value, condition_value) except Exception as exc: self.logger.debug(f"caught exception while matching action: action={action}, exception={str(exc)}") + + handler = self._lookup_exception_handler(exc) + if handler: + self.logger.debug("Exception handler found! Delegating response.") + return handler(exc) + return False def _evaluate_conditions( @@ -209,6 +223,22 @@ def evaluate(self, *, name: str, context: Optional[Dict[str, Any]] = None, defau 2. Feature exists but has either no rules or no match, return feature default value 3. Feature doesn't exist in stored schema, encountered an error when fetching -> return default value provided + ┌────────────────────────┐ ┌────────────────────────┐ ┌────────────────────────┐ + │ Feature flags │──────▶ Get Configuration ├───────▶ Evaluate rules │ + └────────────────────────┘ │ │ │ │ + │┌──────────────────────┐│ │┌──────────────────────┐│ + ││ Fetch schema ││ ││ Match rule ││ + │└───────────┬──────────┘│ │└───────────┬──────────┘│ + │ │ │ │ │ │ + │┌───────────▼──────────┐│ │┌───────────▼──────────┐│ + ││ Cache schema ││ ││ Match condition ││ + │└───────────┬──────────┘│ │└───────────┬──────────┘│ + │ │ │ │ │ │ + │┌───────────▼──────────┐│ │┌───────────▼──────────┐│ + ││ Validate schema ││ ││ Match action ││ + │└──────────────────────┘│ │└──────────────────────┘│ + └────────────────────────┘ └────────────────────────┘ + Parameters ---------- name: str @@ -222,6 +252,31 @@ def evaluate(self, *, name: str, context: Optional[Dict[str, Any]] = None, defau or there has been an error when fetching the configuration from the store Can be boolean or any JSON values for non-boolean features. + + Examples + -------- + + ```python + from aws_lambda_powertools.utilities.feature_flags import AppConfigStore, FeatureFlags + from aws_lambda_powertools.utilities.typing import LambdaContext + + app_config = AppConfigStore(environment="dev", application="product-catalogue", name="features") + + feature_flags = FeatureFlags(store=app_config) + + + def lambda_handler(event: dict, context: LambdaContext): + # Get customer's tier from incoming request + ctx = {"tier": event.get("tier", "standard")} + + # Evaluate whether customer's tier has access to premium features + # based on `has_premium_features` rules + has_premium_features: bool = feature_flags.evaluate(name="premium_features", context=ctx, default=False) + if has_premium_features: + # enable premium features + ... + ``` + Returns ------ JSONType @@ -335,3 +390,45 @@ def get_enabled_features(self, *, context: Optional[Dict[str, Any]] = None) -> L features_enabled.append(name) return features_enabled + + def validation_exception_handler(self, exc_class: Exception | list[Exception]): + """Registers function to handle unexpected validation exceptions when evaluating flags. + + It does not override the function of a default flag value in case of network and IAM permissions. + For example, you won't be able to catch ConfigurationStoreError exception. + + Parameters + ---------- + exc_class : Exception | list[Exception] + One or more exceptions to catch + + Examples + -------- + + ```python + feature_flags = FeatureFlags(store=app_config) + + @feature_flags.validation_exception_handler(Exception) # any exception + def catch_exception(exc): + raise TypeError("re-raised") from exc + ``` + """ + + def register_exception_handler(func: Callable[P, T]) -> Callable[P, T]: + if isinstance(exc_class, list): + for exp in exc_class: + self._exception_handlers[exp] = func + else: + self._exception_handlers[exc_class] = func + + return func + + return register_exception_handler + + def _lookup_exception_handler(self, exc: BaseException) -> Callable | None: + # Use "Method Resolution Order" to allow for matching against a base class + # of an exception + for cls in type(exc).__mro__: + if cls in self._exception_handlers: + return self._exception_handlers[cls] # type: ignore[index] # index is correct + return None diff --git a/aws_lambda_powertools/utilities/feature_flags/schema.py b/aws_lambda_powertools/utilities/feature_flags/schema.py index 2ef4b9e29a4..1df16677bd8 100644 --- a/aws_lambda_powertools/utilities/feature_flags/schema.py +++ b/aws_lambda_powertools/utilities/feature_flags/schema.py @@ -1,8 +1,11 @@ +from __future__ import annotations + import logging import re from datetime import datetime from enum import Enum -from typing import Any, Callable, Dict, List, Optional, Union +from functools import lru_cache +from typing import Any, Dict, List, Optional, Union from dateutil import tz @@ -19,9 +22,11 @@ CONDITION_ACTION = "action" FEATURE_DEFAULT_VAL_TYPE_KEY = "boolean_type" TIME_RANGE_FORMAT = "%H:%M" # hour:min 24 hours clock -TIME_RANGE_RE_PATTERN = re.compile(r"2[0-3]:[0-5]\d|[0-1]\d:[0-5]\d") # 24 hour clock +TIME_RANGE_PATTERN = re.compile(r"2[0-3]:[0-5]\d|[0-1]\d:[0-5]\d") # 24 hour clock HOUR_MIN_SEPARATOR = ":" +LOGGER: logging.Logger | Logger = logging.getLogger(__name__) + class RuleAction(str, Enum): EQUALS = "EQUALS" @@ -74,6 +79,11 @@ class TimeValues(Enum): FRIDAY = "FRIDAY" SATURDAY = "SATURDAY" + @classmethod + @lru_cache(maxsize=1) + def days(cls) -> list[str]: + return [day.value for day in cls if day.value not in ["START", "END", "TIMEZONE"]] + class ModuloRangeValues(Enum): """ @@ -188,7 +198,12 @@ class SchemaValidator(BaseValidator): def __init__(self, schema: Dict[str, Any], logger: Optional[Union[logging.Logger, Logger]] = None): self.schema = schema - self.logger = logger or logging.getLogger(__name__) + self.logger = logger or LOGGER + + # Validators are designed for modular testing + # therefore we link the custom logger with global LOGGER + # so custom validators can use them when necessary + SchemaValidator._link_global_logger(self.logger) def validate(self) -> None: self.logger.debug("Validating schema") @@ -198,13 +213,18 @@ def validate(self) -> None: features = FeaturesValidator(schema=self.schema, logger=self.logger) features.validate() + @staticmethod + def _link_global_logger(logger: logging.Logger | Logger): + global LOGGER + LOGGER = logger + class FeaturesValidator(BaseValidator): """Validates each feature and calls RulesValidator to validate its rules""" def __init__(self, schema: Dict, logger: Optional[Union[logging.Logger, Logger]] = None): self.schema = schema - self.logger = logger or logging.getLogger(__name__) + self.logger = logger or LOGGER def validate(self): for name, feature in self.schema.items(): @@ -242,7 +262,7 @@ def __init__( self.feature = feature self.feature_name = next(iter(self.feature)) self.rules: Optional[Dict] = self.feature.get(RULES_KEY) - self.logger = logger or logging.getLogger(__name__) + self.logger = logger or LOGGER self.boolean_feature = boolean_feature def validate(self): @@ -289,7 +309,7 @@ class ConditionsValidator(BaseValidator): def __init__(self, rule: Dict[str, Any], rule_name: str, logger: Optional[Union[logging.Logger, Logger]] = None): self.conditions: List[Dict[str, Any]] = rule.get(CONDITIONS_KEY, {}) self.rule_name = rule_name - self.logger = logger or logging.getLogger(__name__) + self.logger = logger or LOGGER def validate(self): if not self.conditions or not isinstance(self.conditions, list): @@ -325,23 +345,26 @@ def validate_condition_key(condition: Dict[str, Any], rule_name: str): if not key or not isinstance(key, str): raise SchemaValidationError(f"'key' value must be a non empty string, rule={rule_name}") - # time actions need to have very specific keys - # SCHEDULE_BETWEEN_TIME_RANGE => CURRENT_TIME - # SCHEDULE_BETWEEN_DATETIME_RANGE => CURRENT_DATETIME - # SCHEDULE_BETWEEN_DAYS_OF_WEEK => CURRENT_DAY_OF_WEEK action = condition.get(CONDITION_ACTION, "") - if action == RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value and key != TimeKeys.CURRENT_TIME.value: - raise SchemaValidationError( - f"'condition with a 'SCHEDULE_BETWEEN_TIME_RANGE' action must have a 'CURRENT_TIME' condition key, rule={rule_name}", # noqa: E501 - ) - if action == RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value and key != TimeKeys.CURRENT_DATETIME.value: - raise SchemaValidationError( - f"'condition with a 'SCHEDULE_BETWEEN_DATETIME_RANGE' action must have a 'CURRENT_DATETIME' condition key, rule={rule_name}", # noqa: E501 - ) - if action == RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value and key != TimeKeys.CURRENT_DAY_OF_WEEK.value: - raise SchemaValidationError( - f"'condition with a 'SCHEDULE_BETWEEN_DAYS_OF_WEEK' action must have a 'CURRENT_DAY_OF_WEEK' condition key, rule={rule_name}", # noqa: E501 - ) + + # To allow for growth and prevent if/elif chains, we align extra validators based on the action name. + # for example: + # + # SCHEDULE_BETWEEN_DAYS_OF_WEEK_KEY + # - extra validation: `_validate_schedule_between_days_of_week_key` + # + # maintenance: we should split to separate file/classes for better organization, e.g., visitor pattern. + + custom_validator = getattr(ConditionsValidator, f"_validate_{action.lower()}_key", None) + + # ~90% of actions available don't require a custom validator + # logging a debug statement for no-match will increase CPU cycles for most customers + # for that reason only, we invert and log only when extra validation is found. + if custom_validator is None: + return + + LOGGER.debug(f"{action} requires key validation. Running '{custom_validator}' validator.") + custom_validator(key, rule_name) @staticmethod def validate_condition_value(condition: Dict[str, Any], rule_name: str): @@ -350,65 +373,35 @@ def validate_condition_value(condition: Dict[str, Any], rule_name: str): raise SchemaValidationError(f"'value' key must not be null, rule={rule_name}") action = condition.get(CONDITION_ACTION, "") - # time actions need to be parsed to make sure date and time format is valid and timezone is recognized - if action == RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value: - ConditionsValidator._validate_schedule_between_time_and_datetime_ranges( - value, - rule_name, - action, - ConditionsValidator._validate_time_value, - ) - elif action == RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value: - ConditionsValidator._validate_schedule_between_time_and_datetime_ranges( - value, - rule_name, - action, - ConditionsValidator._validate_datetime_value, - ) - elif action == RuleAction.SCHEDULE_BETWEEN_DAYS_OF_WEEK.value: - ConditionsValidator._validate_schedule_between_days_of_week(value, rule_name) - # modulo range condition needs validation on base, start, and end attributes - elif action == RuleAction.MODULO_RANGE.value: - ConditionsValidator._validate_modulo_range(value, rule_name) + # To allow for growth and prevent if/elif chains, we align extra validators based on the action name. + # for example: + # + # SCHEDULE_BETWEEN_DAYS_OF_WEEK_KEY + # - extra validation: `_validate_schedule_between_days_of_week_value` + # + # maintenance: we should split to separate file/classes for better organization, e.g., visitor pattern. - @staticmethod - def _validate_datetime_value(datetime_str: str, rule_name: str): - date = None + custom_validator = getattr(ConditionsValidator, f"_validate_{action.lower()}_value", None) - # We try to parse first with timezone information in order to return the correct error messages - # when a timestamp with timezone is used. Otherwise, the user would get the first error "must be a valid - # ISO8601 time format" which is misleading + # ~90% of actions available don't require a custom validator + # logging a debug statement for no-match will increase CPU cycles for most customers + # for that reason only, we invert and log only when extra validation is found. + if custom_validator is None: + return - try: - # python < 3.11 don't support the Z timezone on datetime.fromisoformat, - # so we replace any Z with the equivalent "+00:00" - # datetime.fromisoformat is orders of magnitude faster than datetime.strptime - date = datetime.fromisoformat(datetime_str.replace("Z", "+00:00")) - except Exception: - raise SchemaValidationError(f"'START' and 'END' must be a valid ISO8601 time format, rule={rule_name}") + LOGGER.debug(f"{action} requires value validation. Running '{custom_validator}' validator.") - # we only allow timezone information to be set via the TIMEZONE field - # this way we can encode DST into the calculation. For instance, Copenhagen is - # UTC+2 during winter, and UTC+1 during summer, which would be impossible to define - # using a single ISO datetime string - if date.tzinfo is not None: - raise SchemaValidationError( - "'START' and 'END' must not include timezone information. Set the timezone using the 'TIMEZONE' " - f"field, rule={rule_name} ", - ) + custom_validator(value, rule_name) @staticmethod - def _validate_time_value(time: str, rule_name: str): - # Using a regex instead of strptime because it's several orders of magnitude faster - match = TIME_RANGE_RE_PATTERN.match(time) - - if not match: + def _validate_schedule_between_days_of_week_key(key: str, rule_name: str): + if key != TimeKeys.CURRENT_DAY_OF_WEEK.value: raise SchemaValidationError( - f"'START' and 'END' must be a valid time format, time_format={TIME_RANGE_FORMAT}, rule={rule_name}", + f"'condition with a 'SCHEDULE_BETWEEN_DAYS_OF_WEEK' action must have a 'CURRENT_DAY_OF_WEEK' condition key, rule={rule_name}", # noqa: E501 ) @staticmethod - def _validate_schedule_between_days_of_week(value: Any, rule_name: str): + def _validate_schedule_between_days_of_week_value(value: dict, rule_name: str): error_str = f"condition with a CURRENT_DAY_OF_WEEK action must have a condition value dictionary with 'DAYS' and 'TIMEZONE' (optional) keys, rule={rule_name}" # noqa: E501 if not isinstance(value, dict): raise SchemaValidationError(error_str) @@ -416,59 +409,70 @@ def _validate_schedule_between_days_of_week(value: Any, rule_name: str): days = value.get(TimeValues.DAYS.value) if not isinstance(days, list) or not value: raise SchemaValidationError(error_str) + + valid_days = TimeValues.days() for day in days: - if not isinstance(day, str) or day not in [ - TimeValues.MONDAY.value, - TimeValues.TUESDAY.value, - TimeValues.WEDNESDAY.value, - TimeValues.THURSDAY.value, - TimeValues.FRIDAY.value, - TimeValues.SATURDAY.value, - TimeValues.SUNDAY.value, - ]: + if not isinstance(day, str) or day not in valid_days: raise SchemaValidationError( f"condition value DAYS must represent a day of the week in 'TimeValues' enum, rule={rule_name}", ) - timezone = value.get(TimeValues.TIMEZONE.value, "UTC") - if not isinstance(timezone, str): - raise SchemaValidationError(error_str) + ConditionsValidator._validate_timezone(timezone=value.get(TimeValues.TIMEZONE.value), rule=rule_name) - # try to see if the timezone string corresponds to any known timezone - if not tz.gettz(timezone): - raise SchemaValidationError(f"'TIMEZONE' value must represent a valid IANA timezone, rule={rule_name}") + @staticmethod + def _validate_schedule_between_time_range_key(key: str, rule_name: str): + if key != TimeKeys.CURRENT_TIME.value: + raise SchemaValidationError( + f"'condition with a 'SCHEDULE_BETWEEN_TIME_RANGE' action must have a 'CURRENT_TIME' condition key, rule={rule_name}", # noqa: E501 + ) @staticmethod - def _validate_schedule_between_time_and_datetime_ranges( - value: Any, - rule_name: str, - action_name: str, - validator: Callable[[str, str], None], - ): - error_str = f"condition with a '{action_name}' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}" # noqa: E501 + def _validate_schedule_between_time_range_value(value: Dict, rule_name: str): if not isinstance(value, dict): - raise SchemaValidationError(error_str) + raise SchemaValidationError( + f"{RuleAction.SCHEDULE_BETWEEN_TIME_RANGE.value} action must have a dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + ) + + start_time = value.get(TimeValues.START.value, "") + end_time = value.get(TimeValues.END.value, "") - start_time = value.get(TimeValues.START.value) - end_time = value.get(TimeValues.END.value) - if not start_time or not end_time: - raise SchemaValidationError(error_str) if not isinstance(start_time, str) or not isinstance(end_time, str): raise SchemaValidationError(f"'START' and 'END' must be a non empty string, rule={rule_name}") - validator(start_time, rule_name) - validator(end_time, rule_name) + # Using a regex instead of strptime because it's several orders of magnitude faster + if not TIME_RANGE_PATTERN.match(start_time) or not TIME_RANGE_PATTERN.match(end_time): + raise SchemaValidationError( + f"'START' and 'END' must be a valid time format, time_format={TIME_RANGE_FORMAT}, rule={rule_name}", + ) - timezone = value.get(TimeValues.TIMEZONE.value, "UTC") - if not isinstance(timezone, str): - raise SchemaValidationError(f"'TIMEZONE' must be a string, rule={rule_name}") + ConditionsValidator._validate_timezone(timezone=value.get(TimeValues.TIMEZONE.value), rule=rule_name) - # try to see if the timezone string corresponds to any known timezone - if not tz.gettz(timezone): - raise SchemaValidationError(f"'TIMEZONE' value must represent a valid IANA timezone, rule={rule_name}") + @staticmethod + def _validate_schedule_between_datetime_range_key(key: str, rule_name: str): + if key != TimeKeys.CURRENT_DATETIME.value: + raise SchemaValidationError( + f"'condition with a 'SCHEDULE_BETWEEN_DATETIME_RANGE' action must have a 'CURRENT_DATETIME' condition key, rule={rule_name}", # noqa: E501 + ) @staticmethod - def _validate_modulo_range(value: Any, rule_name: str): + def _validate_schedule_between_datetime_range_value(value: dict, rule_name: str): + if not isinstance(value, dict): + raise SchemaValidationError( + f"{RuleAction.SCHEDULE_BETWEEN_DATETIME_RANGE.value} action must have a dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + ) + + start_time = value.get(TimeValues.START.value, "") + end_time = value.get(TimeValues.END.value, "") + + if not isinstance(start_time, str) or not isinstance(end_time, str): + raise SchemaValidationError(f"'START' and 'END' must be a non empty string, rule={rule_name}") + + ConditionsValidator._validate_datetime(start_time, rule_name) + ConditionsValidator._validate_datetime(end_time, rule_name) + ConditionsValidator._validate_timezone(timezone=value.get(TimeValues.TIMEZONE.value), rule=rule_name) + + @staticmethod + def _validate_modulo_range_value(value: dict, rule_name: str): error_str = f"condition with a 'MODULO_RANGE' action must have a condition value type dictionary with 'BASE', 'START' and 'END' keys, rule={rule_name}" # noqa: E501 if not isinstance(value, dict): raise SchemaValidationError(error_str) @@ -476,8 +480,10 @@ def _validate_modulo_range(value: Any, rule_name: str): base = value.get(ModuloRangeValues.BASE.value) start = value.get(ModuloRangeValues.START.value) end = value.get(ModuloRangeValues.END.value) + if base is None or start is None or end is None: raise SchemaValidationError(error_str) + if not isinstance(base, int) or not isinstance(start, int) or not isinstance(end, int): raise SchemaValidationError(f"'BASE', 'START' and 'END' must be integers, rule={rule_name}") @@ -485,3 +491,55 @@ def _validate_modulo_range(value: Any, rule_name: str): raise SchemaValidationError( f"condition with 'MODULO_RANGE' action must satisfy 0 <= START <= END <= BASE-1, rule={rule_name}", ) + + @staticmethod + def _validate_all_in_value_value(value: list, rule_name: str): + if not (isinstance(value, list)): + raise SchemaValidationError(f"ALL_IN_VALUE action must have a list value, rule={rule_name}") + + @staticmethod + def _validate_any_in_value_value(value: list, rule_name: str): + if not (isinstance(value, list)): + raise SchemaValidationError(f"ANY_IN_VALUE action must have a list value, rule={rule_name}") + + @staticmethod + def _validate_none_in_value_value(value: list, rule_name: str): + if not (isinstance(value, list)): + raise SchemaValidationError(f"NONE_IN_VALUE action must have a list value, rule={rule_name}") + + @staticmethod + def _validate_datetime(datetime_str: str, rule_name: str): + date = None + + # We try to parse first with timezone information in order to return the correct error messages + # when a timestamp with timezone is used. Otherwise, the user would get the first error "must be a valid + # ISO8601 time format" which is misleading + + try: + # python < 3.11 don't support the Z timezone on datetime.fromisoformat, + # so we replace any Z with the equivalent "+00:00" + # datetime.fromisoformat is orders of magnitude faster than datetime.strptime + date = datetime.fromisoformat(datetime_str.replace("Z", "+00:00")) + except Exception: + raise SchemaValidationError(f"'START' and 'END' must be a valid ISO8601 time format, rule={rule_name}") + + # we only allow timezone information to be set via the TIMEZONE field + # this way we can encode DST into the calculation. For instance, Copenhagen is + # UTC+2 during winter, and UTC+1 during summer, which would be impossible to define + # using a single ISO datetime string + if date.tzinfo is not None: + raise SchemaValidationError( + "'START' and 'END' must not include timezone information. Set the timezone using the 'TIMEZONE' " + f"field, rule={rule_name} ", + ) + + @staticmethod + def _validate_timezone(rule: str, timezone: str | None = None): + timezone = timezone or "UTC" + + if not isinstance(timezone, str): + raise SchemaValidationError(f"'TIMEZONE' must be a string, rule={str}") + + # try to see if the timezone string corresponds to any known timezone + if not tz.gettz(timezone): + raise SchemaValidationError(f"'TIMEZONE' value must represent a valid IANA timezone, rule={rule}") diff --git a/ruff.toml b/ruff.toml index 553a8c47b3d..374a183541b 100644 --- a/ruff.toml +++ b/ruff.toml @@ -1,5 +1,5 @@ # Enable rules. -select = [ +lint.select = [ "A", # flake8-builtins - https://beta.ruff.rs/docs/rules/#flake8-builtins-a "B", # flake8-bugbear-b - https://beta.ruff.rs/docs/rules/#flake8-bugbear-b "C4", # flake8-comprehensions - https://beta.ruff.rs/docs/rules/#flake8-comprehensions-c4 @@ -28,7 +28,7 @@ select = [ ] # Ignore specific rules -ignore = [ +lint.ignore = [ "W291", # https://beta.ruff.rs/docs/rules/trailing-whitespace/ "PLR0913", # https://beta.ruff.rs/docs/rules/too-many-arguments/ "PLR2004", #https://beta.ruff.rs/docs/rules/magic-value-comparison/ @@ -60,28 +60,28 @@ line-length = 120 fix = true -fixable = ["I", "COM812", "W"] +lint.fixable = ["I", "COM812", "W"] # See: https://github.com/astral-sh/ruff/issues/128 -typing-modules = [ +lint.typing-modules = [ "aws_lambda_powertools.utilities.parser.types", "aws_lambda_powertools.shared.types", ] -[mccabe] +[lint.mccabe] # Maximum cyclomatic complexity max-complexity = 15 -[pylint] +[lint.pylint] # Maximum number of nested blocks max-branches = 15 # Maximum number of if statements in a function max-statements = 70 -[isort] +[lint.isort] split-on-trailing-comma = true -[per-file-ignores] +[lint.per-file-ignores] # Ignore specific rules for specific files "tests/e2e/utils/data_builder/__init__.py" = ["F401"] "tests/e2e/utils/data_fetcher/__init__.py" = ["F401"] diff --git a/tests/functional/feature_flags/test_feature_flags.py b/tests/functional/feature_flags/test_feature_flags.py index 12adaa4525b..cc6aa60aaac 100644 --- a/tests/functional/feature_flags/test_feature_flags.py +++ b/tests/functional/feature_flags/test_feature_flags.py @@ -1410,3 +1410,260 @@ def test_get_all_enabled_features_non_boolean_truthy_defaults(mocker, config): feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) enabled_list: List[str] = feature_flags.get_enabled_features(context={"tenant_id": "6", "username": "a"}) assert enabled_list == expected_value + + +def test_flags_any_in_value_match(mocker, config): + expected_value = True + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.ANY_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Gerald"]}, + default=False, + ) + assert toggle == expected_value + + +def test_flags_any_in_value_no_match(mocker, config): + expected_value = False + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.ANY_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Simon"]}, + default=False, + ) + assert toggle == expected_value + + +def test_flags_all_in_value_match(mocker, config): + expected_value = True + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.ALL_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Gerald"]}, + default=False, + ) + + assert toggle == expected_value + + +def test_flags_all_in_value_no_match(mocker, config): + expected_value = False + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.ALL_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Gerald", "Simon"]}, + default=False, + ) + + assert toggle == expected_value + + +def test_flags_none_in_value_match(mocker, config): + expected_value = True + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.NONE_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Rubao"]}, + default=False, + ) + + assert toggle == expected_value + + +def test_flags_none_in_value_no_match(mocker, config): + expected_value = False + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.NONE_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": ["Heitor"]}, + default=False, + ) + + assert toggle == expected_value + + +@pytest.mark.parametrize( + "intersection_action", + [ + RuleAction.ALL_IN_VALUE.value, + RuleAction.ANY_IN_VALUE.value, + RuleAction.NONE_IN_VALUE.value, + ], +) +def test_intersection_non_list_value(mocker, config, intersection_action): + # GIVEN a schema with list intersection action + expected_value = False + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": intersection_action, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + + # WHEN a context value isn't a list + toggle = feature_flags.evaluate( + name="my_feature", + context={"tenant_id": "not a list value"}, + default=False, + ) + + # THEN TypeError should be swallowed and use default value + assert toggle == expected_value + + +def test_exception_handler(mocker, config): + # GIVEN a schema with list intersection action + expected_value = False + mocked_app_config_schema = { + "my_feature": { + "default": False, + "rules": { + "tenant_id is in allowed list": { + "when_match": expected_value, + "conditions": [ + { + "action": RuleAction.ANY_IN_VALUE.value, + "key": "tenant_id", + "value": ["Łukasz", "Gerald", "Leandro", "Heitor"], + }, + ], + }, + }, + }, + } + + feature_flags = init_feature_flags(mocker, mocked_app_config_schema, config) + + @feature_flags.validation_exception_handler(ValueError) + def catch_exception(exc): + raise TypeError("re-raised") + + # WHEN a context value isn't a list + # THEN exception handler should be able to intercept and raise, instead of returning `False` + with pytest.raises(TypeError): + feature_flags.evaluate( + name="my_feature", + context={"tenant_id": "not a list value"}, + default=False, + ) diff --git a/tests/functional/feature_flags/test_schema_validation.py b/tests/functional/feature_flags/test_schema_validation.py index 654cfbcab40..45b4c7dbeda 100644 --- a/tests/functional/feature_flags/test_schema_validation.py +++ b/tests/functional/feature_flags/test_schema_validation.py @@ -1,8 +1,8 @@ -import logging import re -import pytest # noqa: F401 +import pytest +from aws_lambda_powertools.logging.logger import Logger # noqa: F401 from aws_lambda_powertools.utilities.feature_flags.exceptions import ( SchemaValidationError, ) @@ -24,8 +24,6 @@ TimeValues, ) -logger = logging.getLogger(__name__) - EMPTY_SCHEMA = {"": ""} @@ -441,7 +439,7 @@ def test_validate_time_condition_between_time_range_invalid_condition_value(): # THEN raise SchemaValidationError with pytest.raises( SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_TIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + match=f"SCHEDULE_BETWEEN_TIME_RANGE action must have a dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 ): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -460,7 +458,7 @@ def test_validate_time_condition_between_time_range_invalid_condition_value_no_s # THEN raise SchemaValidationError with pytest.raises( SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_TIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + match="'START' and 'END' must be a valid time format", ): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -477,10 +475,7 @@ def test_validate_time_condition_between_time_range_invalid_condition_value_no_e # WHEN calling validate_condition # THEN raise SchemaValidationError - with pytest.raises( - SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_TIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 - ): + with pytest.raises(SchemaValidationError, match="'START' and 'END' must be a valid time format"): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -649,7 +644,7 @@ def test_a_validate_time_condition_between_datetime_range_invalid_condition_valu # THEN raise SchemaValidationError with pytest.raises( SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_DATETIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + match=f"SCHEDULE_BETWEEN_DATETIME_RANGE action must have a dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 ): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -668,7 +663,7 @@ def test_validate_time_condition_between_datetime_range_invalid_condition_value_ # THEN raise SchemaValidationError with pytest.raises( SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_DATETIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + match=f"'START' and 'END' must be a valid ISO8601 time format, rule={rule_name}", ): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -687,7 +682,7 @@ def test_validate_time_condition_between_datetime_range_invalid_condition_value_ # THEN raise SchemaValidationError with pytest.raises( SchemaValidationError, - match=f"condition with a 'SCHEDULE_BETWEEN_DATETIME_RANGE' action must have a condition value type dictionary with 'START' and 'END' keys, rule={rule_name}", # noqa: E501 + match="'START' and 'END' must not include timezone information.*", ): ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) @@ -1032,3 +1027,48 @@ def test_validate_modulo_range_condition_valid(): # WHEN calling validate_condition # THEN nothing is raised ConditionsValidator.validate_condition_value(condition=condition, rule_name="dummy") + + +def test_validate_any_in_value_condition_invalid_value(): + # GIVEN a schema with a ANY_IN_VALUE action with non-list value + condition = { + CONDITION_ACTION: RuleAction.ANY_IN_VALUE.value, + CONDITION_VALUE: "Gerald", + } + + rule_name = "non-list value for ANY_IN_VALUE" + + # WHEN calling validate_condition + # THEN raise SchemaValidationError + with pytest.raises(SchemaValidationError, match="ANY_IN_VALUE action must have a list"): + ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) + + +def test_validate_all_in_value_condition_invalid_value(): + # GIVEN a schema with a ANY_IN_VALUE action with non-list value + condition = { + CONDITION_ACTION: RuleAction.ALL_IN_VALUE.value, + CONDITION_VALUE: "Leandro", + } + + rule_name = "non-list value for ALL_IN_VALUE" + + # WHEN calling validate_condition + # THEN raise SchemaValidationError + with pytest.raises(SchemaValidationError, match="ALL_IN_VALUE action must have a list"): + ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) + + +def test_validate_none_in_value_condition_invalid_value(): + # GIVEN a schema with a ANY_IN_VALUE action with non-list value + condition = { + CONDITION_ACTION: RuleAction.NONE_IN_VALUE.value, + CONDITION_VALUE: "Heitor", + } + + rule_name = "non-list value for NONE_IN_VALUE" + + # WHEN calling validate_condition + # THEN raise SchemaValidationError + with pytest.raises(SchemaValidationError, match="NONE_IN_VALUE action must have a list"): + ConditionsValidator.validate_condition_value(condition=condition, rule_name=rule_name) From 72b1fbaa5c7af520dd3a9a10a47c3dccb68a462c Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Mon, 19 Feb 2024 14:50:41 +0100 Subject: [PATCH 0100/2666] fix(event-handler): swagger schema respects api stage (#3796) --- .../event_handler/api_gateway.py | 8 +++++- .../event_handler/test_openapi_swagger.py | 27 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py index 43b5bf139ea..271c767c060 100644 --- a/aws_lambda_powertools/event_handler/api_gateway.py +++ b/aws_lambda_powertools/event_handler/api_gateway.py @@ -1692,7 +1692,13 @@ def swagger_handler(): body=escaped_spec, ) - body = generate_swagger_html(escaped_spec, path, swagger_js, swagger_css, swagger_base_url) + body = generate_swagger_html( + escaped_spec, + f"{base_path}{path}", + swagger_js, + swagger_css, + swagger_base_url, + ) return Response( status_code=200, diff --git a/tests/functional/event_handler/test_openapi_swagger.py b/tests/functional/event_handler/test_openapi_swagger.py index 27fca16f2fa..45e908742b4 100644 --- a/tests/functional/event_handler/test_openapi_swagger.py +++ b/tests/functional/event_handler/test_openapi_swagger.py @@ -73,3 +73,30 @@ def test_openapi_swagger_json_view_with_custom_path(): assert result["multiValueHeaders"]["Content-Type"] == ["application/json"] assert isinstance(json.loads(result["body"]), Dict) assert "OpenAPI JSON View" in result["body"] + + +def test_openapi_swagger_with_rest_api_default_stage(): + app = APIGatewayRestResolver(enable_validation=True) + app.enable_swagger() + + event = load_event("apiGatewayProxyEvent.json") + event["path"] = "/swagger" + event["requestContext"]["stage"] = "$default" + + result = app(event, {}) + assert result["statusCode"] == 200 + assert "ui.specActions.updateUrl('/swagger?format=json')" in result["body"] + + +def test_openapi_swagger_with_rest_api_stage(): + app = APIGatewayRestResolver(enable_validation=True) + app.enable_swagger() + + event = load_event("apiGatewayProxyEvent.json") + event["path"] = "/swagger" + event["requestContext"]["stage"] = "prod" + event["requestContext"]["path"] = "/prod/swagger" + + result = app(event, {}) + assert result["statusCode"] == 200 + assert "ui.specActions.updateUrl('/prod/swagger?format=json')" in result["body"] From f8bb6d450c01688564799f71b07005119f9d1d61 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:55:09 +0100 Subject: [PATCH 0101/2666] chore(deps-dev): bump cfn-lint from 0.85.1 to 0.85.2 (#3786) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index d11bfd17a04..ef3b917024a 100644 --- a/poetry.lock +++ b/poetry.lock @@ -485,13 +485,13 @@ pycparser = "*" [[package]] name = "cfn-lint" -version = "0.85.1" +version = "0.85.2" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" optional = false python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.85.1.tar.gz", hash = "sha256:f003603a6f13bcda125c60f5021fc19b96f18a27ebc44498947709cb7627d0d6"}, - {file = "cfn_lint-0.85.1-py3-none-any.whl", hash = "sha256:5d5b31609ded0bc513f1c57c0dc0017ec1613c2b33ef8e74802149bedb01a3de"}, + {file = "cfn-lint-0.85.2.tar.gz", hash = "sha256:f8a5cc55daeaaa747b8d776dcf62fe1b6bfb8cb46ae60950cbe627601facccd7"}, + {file = "cfn_lint-0.85.2-py3-none-any.whl", hash = "sha256:e7a0aafb9ad93dbe5db54cbefca92a94f2d173309218273ef997ecb048125d89"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "21b9c95f6120a15da1da969297f3050cc32643222f2819006995d154d3c5945a" +content-hash = "1105ced678bbe323249face75352d5819d494699eb6a557c4b64957385d63384" diff --git a/pyproject.toml b/pyproject.toml index 9f866c71d3d..d7d7127a460 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -110,7 +110,7 @@ datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.85.1" +cfn-lint = "0.85.2" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.27.0" From 493a1ca9172e28e0f3224a1060b6434507b64463 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:55:41 +0100 Subject: [PATCH 0102/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update (#3784) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 2 +- layer/scripts/layer-balancer/go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 6529744574f..9b8086a86b2 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/aws/aws-sdk-go-v2 v1.25.0 github.com/aws/aws-sdk-go-v2/config v1.27.0 - github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0 + github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index 1e9d8aacce7..c763e4db53f 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -18,8 +18,8 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFl github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA= -github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0 h1:fBJs+X3ZOEqpmiSb7as6DBqm7K2RTkbaxYL9RBGCZyE= -github.com/aws/aws-sdk-go-v2/service/lambda v1.50.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= +github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0 h1:bbwCi7z7SIHl/aZ0bXHU7WS9fmYiNIQxSBes5bgOF7Q= +github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM= github.com/aws/aws-sdk-go-v2/service/sso v1.19.0/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 h1:6DL0qu5+315wbsAEEmzK+P9leRwNbkp+lGjPC+CEvb8= From 4a6602a476971c13ef8bf0c84c7d44de304d91f9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 14:56:44 +0100 Subject: [PATCH 0103/2666] chore(deps-dev): bump aws-cdk from 2.127.0 to 2.128.0 (#3776) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Heitor Lessa --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 16f6f99d71b..35371ce0b22 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.127.0" + "aws-cdk": "^2.128.0" } }, "node_modules/aws-cdk": { - "version": "2.127.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.127.0.tgz", - "integrity": "sha512-0yPiN+/VFVc/NpOryO+1S7b4DBgRSs4JdQ64jhV4QbwaoWZo7KISxdN2cK4pmcVH67BSNCJCjjlf10cYhmMvwA==", + "version": "2.128.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.128.0.tgz", + "integrity": "sha512-epOAr/0WKqmyaKqBc7N0Ky5++93pu+v6yVN9jNOa4JYkAkGbeTS3vR9bj/W0o94jnlgWevG3HNHr83jtRvw/4A==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index 228319b5e40..510bb9132ea 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.127.0" + "aws-cdk": "^2.128.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 48f705f1ce1a290e2c3aae581706b33e5dc6fa45 Mon Sep 17 00:00:00 2001 From: Ran Isenberg <60175085+ran-isenberg@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:56:56 +0200 Subject: [PATCH 0104/2666] docs(feature_flags): fix incorrect line markers and envelope name (#3792) Co-authored-by: Ran Isenberg --- docs/utilities/feature_flags.md | 4 ++-- examples/feature_flags/src/extracting_envelope.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/utilities/feature_flags.md b/docs/utilities/feature_flags.md index c33efe30429..57069681a72 100644 --- a/docs/utilities/feature_flags.md +++ b/docs/utilities/feature_flags.md @@ -178,7 +178,7 @@ You can use `get_enabled_features` method for scenarios where you need a list of === "getting_all_enabled_features.py" - ```python hl_lines="2 9 26" + ```python hl_lines="4 9 11 28" --8<-- "examples/feature_flags/src/getting_all_enabled_features.py" ``` @@ -472,7 +472,7 @@ For this to work, you need to use a JMESPath expression via the `envelope` param === "extracting_envelope.py" - ```python hl_lines="7" + ```python hl_lines="10" --8<-- "examples/feature_flags/src/extracting_envelope.py" ``` diff --git a/examples/feature_flags/src/extracting_envelope.py b/examples/feature_flags/src/extracting_envelope.py index 74111157704..44935314dd5 100644 --- a/examples/feature_flags/src/extracting_envelope.py +++ b/examples/feature_flags/src/extracting_envelope.py @@ -6,8 +6,8 @@ app_config = AppConfigStore( environment="dev", application="product-catalogue", - name="features", - envelope="feature_flags", + name="feature_flags", + envelope="features", ) feature_flags = FeatureFlags(store=app_config) From 25859fb0578e29b1ee15c9b75062e7e8da5d62aa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:00:55 +0100 Subject: [PATCH 0105/2666] chore(deps-dev): bump the boto-typing group with 2 updates (#3797) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 20 ++++++++++---------- pyproject.toml | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/poetry.lock b/poetry.lock index ef3b917024a..3ed6842c20d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1925,13 +1925,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-lambda" -version = "1.34.0" -description = "Type annotations for boto3.Lambda 1.34.0 service generated with mypy-boto3-builder 7.21.0" +version = "1.34.44" +description = "Type annotations for boto3.Lambda 1.34.44 service generated with mypy-boto3-builder 7.23.1" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "mypy-boto3-lambda-1.34.0.tar.gz", hash = "sha256:e74c0ce548da747a8c6e643c39dad8aa54d67e057f57740ec780a7e565590627"}, - {file = "mypy_boto3_lambda-1.34.0-py3-none-any.whl", hash = "sha256:109a7e126e84d6da6cacf8ab5c7c6f2be022417fe7bfb7f9b019767d7034f73b"}, + {file = "mypy-boto3-lambda-1.34.44.tar.gz", hash = "sha256:b465e00c33267ceffdf3040c9562755d73aee21902a16d9b84294f7f0e378ab9"}, + {file = "mypy_boto3_lambda-1.34.44-py3-none-any.whl", hash = "sha256:0ef2063a00fad20a4fc096720a8c5c43b08a133cf27738ba9b1c70ea71b271b9"}, ] [package.dependencies] @@ -1967,13 +1967,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-secretsmanager" -version = "1.34.17" -description = "Type annotations for boto3.SecretsManager 1.34.17 service generated with mypy-boto3-builder 7.23.1" +version = "1.34.43" +description = "Type annotations for boto3.SecretsManager 1.34.43 service generated with mypy-boto3-builder 7.23.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-boto3-secretsmanager-1.34.17.tar.gz", hash = "sha256:a547932d99c3f711b27b9ea1c38fc063050910c0bf6c8eb346abd96ace61668e"}, - {file = "mypy_boto3_secretsmanager-1.34.17-py3-none-any.whl", hash = "sha256:0dbd1cdbe7992324c3414cccf0256e3905827bbf1f6a8d58c255635f6a2b4bfb"}, + {file = "mypy-boto3-secretsmanager-1.34.43.tar.gz", hash = "sha256:abbf560775c2fe0dc383b7f70c16a1bf753d9b3ffc0caa5e35447e685783a68b"}, + {file = "mypy_boto3_secretsmanager-1.34.43-py3-none-any.whl", hash = "sha256:64e9df58f71072f0a912ecaca626683f4536da078caa204ac07928c4b1481b8b"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "1105ced678bbe323249face75352d5819d494699eb6a557c4b64957385d63384" +content-hash = "d7520f397e06b8a02efec43c68687473aa32202a2d16da4ede5cecf01e11ddca" diff --git a/pyproject.toml b/pyproject.toml index d7d7127a460..d4111ac4020 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,9 +74,9 @@ mypy-boto3-appconfig = "^1.34.0" mypy-boto3-cloudformation = "^1.34.32" mypy-boto3-cloudwatch = "^1.34.40" mypy-boto3-dynamodb = "^1.34.34" -mypy-boto3-lambda = "^1.34.0" +mypy-boto3-lambda = "^1.34.44" mypy-boto3-logs = "^1.34.16" -mypy-boto3-secretsmanager = "^1.34.17" +mypy-boto3-secretsmanager = "^1.34.43" mypy-boto3-ssm = "^1.34.32" mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" From 212b37feda6089b1b14f57fa777bf27878d2515c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:28:37 +0100 Subject: [PATCH 0106/2666] chore(deps-dev): bump aws-cdk-lib from 2.127.0 to 2.128.0 (#3777) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 3ed6842c20d..95118cd53ed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -158,13 +158,13 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.127.0" +version = "2.128.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false python-versions = "~=3.8" files = [ - {file = "aws-cdk-lib-2.127.0.tar.gz", hash = "sha256:ed4ace6dc0ed42cb980b2ff833c685f6fe64b3bfad94676b6ea2ee3dfa161dc8"}, - {file = "aws_cdk_lib-2.127.0-py3-none-any.whl", hash = "sha256:abbb50bd9100cdbcc789d098457f60c842efe0f56f8571345f3603be5cc52b38"}, + {file = "aws-cdk-lib-2.128.0.tar.gz", hash = "sha256:796459062daa0dbe0581925874db121d4c220295c6c35e73dedfe39e82ca301f"}, + {file = "aws_cdk_lib-2.128.0-py3-none-any.whl", hash = "sha256:49170b21cb738d30d67f7aa361b78ba3a8b711f8dd15523cbfe64710f9386553"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "d7520f397e06b8a02efec43c68687473aa32202a2d16da4ede5cecf01e11ddca" +content-hash = "e8d75b05c3a926caf77267d46696fc0eb838f3d276387af45337cad5b28eb467" diff --git a/pyproject.toml b/pyproject.toml index d4111ac4020..6cde26293d1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,7 @@ xenon = "^0.9.1" mkdocs-git-revision-date-plugin = "^0.3.2" mike = "^1.1.2" pytest-xdist = "^3.5.0" -aws-cdk-lib = "^2.127.0" +aws-cdk-lib = "^2.128.0" "aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" From f8098e23c6afba6d859ec7347d4469b67b8cc5f0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 15:32:08 +0100 Subject: [PATCH 0107/2666] chore(ci): changelog rebuild (#3794) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> Co-authored-by: Heitor Lessa --- CHANGELOG.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2a6358627b9..1d862bcdb86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,8 +4,15 @@ # Unreleased +## Bug Fixes + +* **event-handler:** handle aliased parameters e.g., Query(alias="categoryType") ([#3766](https://github.com/aws-powertools/powertools-lambda-python/issues/3766)) + ## Documentation +* **home:** update layer version to 62 for package version 2.33.1 ([#3778](https://github.com/aws-powertools/powertools-lambda-python/issues/3778)) +* **home:** add note about POWERTOOLS_DEV side effects in CloudWatch Logs ([#3770](https://github.com/aws-powertools/powertools-lambda-python/issues/3770)) +* **homepage:** remove leftover announcement banner ([#3783](https://github.com/aws-powertools/powertools-lambda-python/issues/3783)) * **homepage:** discord flat badge style; remove former devax email ([#3768](https://github.com/aws-powertools/powertools-lambda-python/issues/3768)) * **roadmap:** latest roadmap update; use new grid to de-clutter homepage ([#3755](https://github.com/aws-powertools/powertools-lambda-python/issues/3755)) @@ -15,11 +22,17 @@ ## Maintenance +* **deps:** bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs ([#3756](https://github.com/aws-powertools/powertools-lambda-python/issues/3756)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3764](https://github.com/aws-powertools/powertools-lambda-python/issues/3764)) +* **deps:** bump actions/dependency-review-action from 4.0.0 to 4.1.0 ([#3771](https://github.com/aws-powertools/powertools-lambda-python/issues/3771)) +* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) +* **deps-dev:** bump the boto-typing group with 1 update ([#3757](https://github.com/aws-powertools/powertools-lambda-python/issues/3757)) * **deps-dev:** bump aws-cdk from 2.126.0 to 2.127.0 ([#3761](https://github.com/aws-powertools/powertools-lambda-python/issues/3761)) * **deps-dev:** bump mkdocs-material from 9.5.8 to 9.5.9 ([#3759](https://github.com/aws-powertools/powertools-lambda-python/issues/3759)) * **deps-dev:** bump sentry-sdk from 1.40.2 to 1.40.3 ([#3750](https://github.com/aws-powertools/powertools-lambda-python/issues/3750)) * **deps-dev:** bump cfn-lint from 0.85.0 to 0.85.1 ([#3749](https://github.com/aws-powertools/powertools-lambda-python/issues/3749)) -* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) +* **deps-dev:** bump sentry-sdk from 1.40.3 to 1.40.4 ([#3765](https://github.com/aws-powertools/powertools-lambda-python/issues/3765)) +* **deps-dev:** bump pytest-asyncio from 0.21.1 to 0.23.5 ([#3773](https://github.com/aws-powertools/powertools-lambda-python/issues/3773)) From 770f0233a5c7c70a3421cef87f469bd4abdeb73e Mon Sep 17 00:00:00 2001 From: Ran Isenberg <60175085+ran-isenberg@users.noreply.github.com> Date: Mon, 19 Feb 2024 16:34:35 +0200 Subject: [PATCH 0108/2666] docs(we-made-this): add reinvent 2023 session (#3790) Co-authored-by: Ran Isenberg --- docs/we_made_this.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/we_made_this.md b/docs/we_made_this.md index d57a0b7325c..a9150a2bc08 100644 --- a/docs/we_made_this.md +++ b/docs/we_made_this.md @@ -140,7 +140,17 @@ Feature flags can improve your CI/CD process by enabling capabilities otherwise In this talk, you will learn the added value of using feature flags as part of your CI/CD process and how AWS Lambda Powertools can help with that. - +#### AWS re:invent 2023 - OPN305 - The Pragmatic Serverless Python Developer + +> **Author: Heitor Lessa & Ran Isenberg** + +Are you developing AWS Lambda functions with Python? Always looking for tools to make you more productive? What if you could hear directly from practitioners? + +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. + + ## Workshops @@ -170,6 +180,15 @@ This handler embodies Serverless best practices and has all the bells and whistl :material-github: [github.com/ran-isenberg/aws-lambda-handler-cookbook](https://github.com/ran-isenberg/aws-lambda-handler-cookbook){:target="_blank"} +> **Author: [Ran Isenberg & Heitor Lessa](mailto:ran.isenberg@ranthebuilder.cloud) [:material-twitter:](https://twitter.com/IsenbergRan){target="_blank" rel="nofollow"} [:material-linkedin:](https://www.linkedin.com/in/ranisenberg/){target="_blank" rel="nofollow"}** + +This project 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. + +It is based on the AWS Lambda handler cookbook project and served as the examples for the AWS re:invent 2023 +session: OPN305 - The pragmatic serverless python developer. + +:material-github: [https://github.com/ran-isenberg/serverless-python-demo](https://github.com/ran-isenberg/serverless-python-demo){:target="_blank"} + ### Serverless Transactional Message App > **Author: [Santiago Garcia Arango](mailto:san99tiago@gmail.com) [:material-web:](https://san99tiago.com/){target="_blank" rel="nofollow"} [:material-linkedin:](https://www.linkedin.com/in/san99tiago/){target="_blank" rel="nofollow"}** From 36905b583a9de922f30f1802985d2c64ad1136ef Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Mon, 19 Feb 2024 17:23:40 +0100 Subject: [PATCH 0109/2666] fix(event-handler): multi-value query string and validation of scalar parameters (#3795) --- .../middlewares/openapi_validation.py | 23 +- .../utilities/data_classes/alb_event.py | 4 +- .../data_classes/api_gateway_proxy_event.py | 14 +- .../data_classes/bedrock_agent_event.py | 4 - .../utilities/data_classes/common.py | 14 +- .../utilities/data_classes/vpc_lattice.py | 26 +- tests/functional/event_handler/conftest.py | 32 ++ .../test_openapi_validation_middleware.py | 368 +++++++++++------- 8 files changed, 287 insertions(+), 198 deletions(-) diff --git a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py index 25ac97ddf89..241a9972953 100644 --- a/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py +++ b/aws_lambda_powertools/event_handler/middlewares/openapi_validation.py @@ -368,7 +368,10 @@ def _get_embed_body( return received_body, field_alias_omitted -def _normalize_multi_query_string_with_param(query_string: Optional[Dict[str, str]], params: Sequence[ModelField]): +def _normalize_multi_query_string_with_param( + query_string: Dict[str, List[str]], + params: Sequence[ModelField], +) -> Dict[str, Any]: """ Extract and normalize resolved_query_string_parameters @@ -383,15 +386,15 @@ def _normalize_multi_query_string_with_param(query_string: Optional[Dict[str, st ------- A dictionary containing the processed multi_query_string_parameters. """ - if query_string: - for param in filter(is_scalar_field, params): - try: - # if the target parameter is a scalar, we keep the first value of the query string - # regardless if there are more in the payload - query_string[param.alias] = query_string[param.alias][0] - except KeyError: - pass - return query_string + resolved_query_string: Dict[str, Any] = query_string + for param in filter(is_scalar_field, params): + try: + # if the target parameter is a scalar, we keep the first value of the query string + # regardless if there are more in the payload + resolved_query_string[param.alias] = query_string[param.alias][0] + except KeyError: + pass + return resolved_query_string def _normalize_multi_header_values_with_param(headers: Optional[Dict[str, str]], params: Sequence[ModelField]): diff --git a/aws_lambda_powertools/utilities/data_classes/alb_event.py b/aws_lambda_powertools/utilities/data_classes/alb_event.py index 98f37b4f415..1ec2535850b 100644 --- a/aws_lambda_powertools/utilities/data_classes/alb_event.py +++ b/aws_lambda_powertools/utilities/data_classes/alb_event.py @@ -36,11 +36,11 @@ def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueQueryStringParameters") @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: + def resolved_query_string_parameters(self) -> Dict[str, List[str]]: if self.multi_value_query_string_parameters: return self.multi_value_query_string_parameters - return self.query_string_parameters + return super().resolved_query_string_parameters @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index c37bd22ca53..ff24e908d1a 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -119,11 +119,11 @@ def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: return self.get("multiValueQueryStringParameters") @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: + def resolved_query_string_parameters(self) -> Dict[str, List[str]]: if self.multi_value_query_string_parameters: return self.multi_value_query_string_parameters - return self.query_string_parameters + return super().resolved_query_string_parameters @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: @@ -318,16 +318,6 @@ def http_method(self) -> str: def header_serializer(self): return HttpApiHeadersSerializer() - @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, Any]]: - if self.query_string_parameters is not None: - query_string = { - key: value.split(",") if "," in value else value for key, value in self.query_string_parameters.items() - } - return query_string - - return {} - @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: if self.headers is not None: diff --git a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py index 0fa97036a3e..399c435b3ec 100644 --- a/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py +++ b/aws_lambda_powertools/utilities/data_classes/bedrock_agent_event.py @@ -109,10 +109,6 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]: # together with the other parameters. So we just return all parameters here. return {x["name"]: x["value"] for x in self["parameters"]} if self.get("parameters") else None - @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: - return self.query_string_parameters - @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: return {} diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 25fb5a4c170..067706140fd 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -104,7 +104,7 @@ def query_string_parameters(self) -> Optional[Dict[str, str]]: return self.get("queryStringParameters") @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: + def resolved_query_string_parameters(self) -> Dict[str, List[str]]: """ This property determines the appropriate query string parameter to be used as a trusted source for validating OpenAPI. @@ -112,7 +112,11 @@ def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: This is necessary because different resolvers use different formats to encode multi query string parameters. """ - return self.query_string_parameters + if self.query_string_parameters is not None: + query_string = {key: value.split(",") for key, value in self.query_string_parameters.items()} + return query_string + + return {} @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: @@ -186,8 +190,7 @@ def get_header_value( name: str, default_value: str, case_sensitive: Optional[bool] = False, - ) -> str: - ... + ) -> str: ... @overload def get_header_value( @@ -195,8 +198,7 @@ def get_header_value( name: str, default_value: Optional[str] = None, case_sensitive: Optional[bool] = False, - ) -> Optional[str]: - ... + ) -> Optional[str]: ... def get_header_value( self, diff --git a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py index 15144e41d7d..f997d4b3f04 100644 --- a/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/data_classes/vpc_lattice.py @@ -73,8 +73,7 @@ def get_header_value( name: str, default_value: str, case_sensitive: Optional[bool] = False, - ) -> str: - ... + ) -> str: ... @overload def get_header_value( @@ -82,8 +81,7 @@ def get_header_value( name: str, default_value: Optional[str] = None, case_sensitive: Optional[bool] = False, - ) -> Optional[str]: - ... + ) -> Optional[str]: ... def get_header_value( self, @@ -140,10 +138,6 @@ def query_string_parameters(self) -> Dict[str, str]: """The request query string parameters.""" return self["query_string_parameters"] - @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: - return self.query_string_parameters - @property def resolved_headers_field(self) -> Optional[Dict[str, Any]]: if self.headers is not None: @@ -255,17 +249,21 @@ def path(self) -> str: @property def request_context(self) -> vpcLatticeEventV2RequestContext: - """he VPC Lattice v2 Event request context.""" + """The VPC Lattice v2 Event request context.""" return vpcLatticeEventV2RequestContext(self["requestContext"]) @property def query_string_parameters(self) -> Optional[Dict[str, str]]: - """The request query string parameters.""" - return self.get("queryStringParameters") + """The request query string parameters. - @property - def resolved_query_string_parameters(self) -> Optional[Dict[str, str]]: - return self.query_string_parameters + For VPC Lattice V2, the queryStringParameters will contain a Dict[str, List[str]] + so to keep compatibility with existing utilities, we merge all the values with a comma. + """ + params = self.get("queryStringParameters") + if params: + return {key: ",".join(value) for key, value in params.items()} + else: + return None @property def resolved_headers_field(self) -> Optional[Dict[str, str]]: diff --git a/tests/functional/event_handler/conftest.py b/tests/functional/event_handler/conftest.py index c7a4ac6e500..5c2bdb7729a 100644 --- a/tests/functional/event_handler/conftest.py +++ b/tests/functional/event_handler/conftest.py @@ -2,6 +2,8 @@ import pytest +from tests.functional.utils import load_event + @pytest.fixture def json_dump(): @@ -39,3 +41,33 @@ def validation_schema(): @pytest.fixture def raw_event(): return {"message": "hello hello", "username": "blah blah"} + + +@pytest.fixture +def gw_event(): + return load_event("apiGatewayProxyEvent.json") + + +@pytest.fixture +def gw_event_http(): + return load_event("apiGatewayProxyV2Event.json") + + +@pytest.fixture +def gw_event_alb(): + return load_event("albMultiValueQueryStringEvent.json") + + +@pytest.fixture +def gw_event_lambda_url(): + return load_event("lambdaFunctionUrlEventWithHeaders.json") + + +@pytest.fixture +def gw_event_vpc_lattice(): + return load_event("vpcLatticeV2EventWithHeaders.json") + + +@pytest.fixture +def gw_event_vpc_lattice_v1(): + return load_event("vpcLatticeEvent.json") diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index be3a13dd656..a9396644b98 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -15,22 +15,12 @@ Response, VPCLatticeResolver, VPCLatticeV2Resolver, - content_types, ) from aws_lambda_powertools.event_handler.openapi.params import Body, Header, Query from aws_lambda_powertools.shared.types import Annotated -from aws_lambda_powertools.utilities.data_classes import APIGatewayProxyEvent -from tests.functional.utils import load_event -LOAD_GW_EVENT = load_event("apiGatewayProxyEvent.json") -LOAD_GW_EVENT_HTTP = load_event("apiGatewayProxyV2Event.json") -LOAD_GW_EVENT_ALB = load_event("albMultiValueQueryStringEvent.json") -LOAD_GW_EVENT_LAMBDA_URL = load_event("lambdaFunctionUrlEventWithHeaders.json") -LOAD_GW_EVENT_VPC_LATTICE = load_event("vpcLatticeV2EventWithHeaders.json") -LOAD_GW_EVENT_VPC_LATTICE_V1 = load_event("vpcLatticeEvent.json") - -def test_validate_scalars(): +def test_validate_scalars(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -40,22 +30,22 @@ def handler(user_id: int): print(user_id) # sending a number - LOAD_GW_EVENT["path"] = "/users/123" + gw_event["path"] = "/users/123" # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 # sending a string - LOAD_GW_EVENT["path"] = "/users/abc" + gw_event["path"] = "/users/abc" # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) -def test_validate_scalars_with_default(): +def test_validate_scalars_with_default(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -65,22 +55,22 @@ def handler(user_id: int = 123): print(user_id) # sending a number - LOAD_GW_EVENT["path"] = "/users/123" + gw_event["path"] = "/users/123" # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 # sending a string - LOAD_GW_EVENT["path"] = "/users/abc" + gw_event["path"] = "/users/abc" # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) -def test_validate_scalars_with_default_and_optional(): +def test_validate_scalars_with_default_and_optional(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -90,22 +80,22 @@ def handler(user_id: int = 123, include_extra: bool = False): print(user_id) # sending a number - LOAD_GW_EVENT["path"] = "/users/123" + gw_event["path"] = "/users/123" # THEN the handler should be invoked and return 200 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 # sending a string - LOAD_GW_EVENT["path"] = "/users/abc" + gw_event["path"] = "/users/abc" # THEN the handler should be invoked and return 422 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert any(text in result["body"] for text in ["type_error.integer", "int_parsing"]) -def test_validate_return_type(): +def test_validate_return_type(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -114,16 +104,16 @@ def test_validate_return_type(): def handler() -> int: return 123 - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be 123 - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert result["body"] == "123" -def test_validate_return_list(): +def test_validate_return_list(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -132,16 +122,16 @@ def test_validate_return_list(): def handler() -> List[int]: return [123, 234] - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be [123, 234] - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == [123, 234] -def test_validate_return_tuple(): +def test_validate_return_tuple(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -152,16 +142,16 @@ def test_validate_return_tuple(): def handler() -> Tuple: return sample_tuple - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be a tuple - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == [1, 2, 3] -def test_validate_return_purepath(): +def test_validate_return_purepath(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -173,16 +163,16 @@ def test_validate_return_purepath(): def handler() -> str: return sample_path.as_posix() - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be a string - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert result["body"] == sample_path.as_posix() -def test_validate_return_enum(): +def test_validate_return_enum(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -194,16 +184,16 @@ class Model(Enum): def handler() -> Model: return Model.name.value - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be a string - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert result["body"] == "powertools" -def test_validate_return_dataclass(): +def test_validate_return_dataclass(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -217,16 +207,16 @@ class Model: def handler() -> Model: return Model(name="John", age=30) - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be a JSON object - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == {"name": "John", "age": 30} -def test_validate_return_model(): +def test_validate_return_model(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -239,16 +229,16 @@ class Model(BaseModel): def handler() -> Model: return Model(name="John", age=30) - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 200 # THEN the body must be a JSON object - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == {"name": "John", "age": 30} -def test_validate_invalid_return_model(): +def test_validate_invalid_return_model(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -261,16 +251,16 @@ class Model(BaseModel): def handler() -> Model: return {"name": "John"} # type: ignore - LOAD_GW_EVENT["path"] = "/" + gw_event["path"] = "/" # THEN the handler should be invoked and return 422 # THEN the body must be a dict - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert "missing" in result["body"] -def test_validate_body_param(): +def test_validate_body_param(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -283,18 +273,18 @@ class Model(BaseModel): def handler(user: Model) -> Model: return user - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = json.dumps({"name": "John", "age": 30}) + gw_event["httpMethod"] = "POST" + gw_event["path"] = "/" + gw_event["body"] = json.dumps({"name": "John", "age": 30}) # THEN the handler should be invoked and return 200 # THEN the body must be a JSON object - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == {"name": "John", "age": 30} -def test_validate_body_param_with_stripped_headers(): +def test_validate_body_param_with_stripped_headers(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -308,19 +298,19 @@ class Model(BaseModel): def handler(user: Model) -> Model: return user - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["headers"] = {"Content-type": " application/json "} - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = json.dumps({"name": "John", "age": 30}) + gw_event["httpMethod"] = "POST" + gw_event["headers"] = {"Content-type": " application/json "} + gw_event["path"] = "/" + gw_event["body"] = json.dumps({"name": "John", "age": 30}) # THEN the handler should be invoked and return 200 # THEN the body must be a JSON object - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == {"name": "John", "age": 30} -def test_validate_body_param_with_invalid_date(): +def test_validate_body_param_with_invalid_date(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -333,18 +323,18 @@ class Model(BaseModel): def handler(user: Model) -> Model: return user - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = "{" # invalid JSON + gw_event["httpMethod"] = "POST" + gw_event["path"] = "/" + gw_event["body"] = "{" # invalid JSON # THEN the handler should be invoked and return 422 # THEN the body must have the "json_invalid" error message - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert "json_invalid" in result["body"] -def test_validate_embed_body_param(): +def test_validate_embed_body_param(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -357,24 +347,24 @@ class Model(BaseModel): def handler(user: Annotated[Model, Body(embed=True)]) -> Model: return user - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = json.dumps({"name": "John", "age": 30}) + gw_event["httpMethod"] = "POST" + gw_event["path"] = "/" + gw_event["body"] = json.dumps({"name": "John", "age": 30}) # THEN the handler should be invoked and return 422 # THEN the body must be a dict - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert "missing" in result["body"] # THEN the handler should be invoked and return 200 # THEN the body must be a dict - LOAD_GW_EVENT["body"] = json.dumps({"user": {"name": "John", "age": 30}}) - result = app(LOAD_GW_EVENT, {}) + gw_event["body"] = json.dumps({"user": {"name": "John", "age": 30}}) + result = app(gw_event, {}) assert result["statusCode"] == 200 -def test_validate_response_return(): +def test_validate_response_return(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -387,18 +377,18 @@ class Model(BaseModel): def handler(user: Model) -> Response[Model]: return Response(body=user, status_code=200, content_type="application/json") - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = json.dumps({"name": "John", "age": 30}) + gw_event["httpMethod"] = "POST" + gw_event["path"] = "/" + gw_event["body"] = json.dumps({"name": "John", "age": 30}) # THEN the handler should be invoked and return 200 # THEN the body must be a dict - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 200 assert json.loads(result["body"]) == {"name": "John", "age": 30} -def test_validate_response_invalid_return(): +def test_validate_response_invalid_return(gw_event): # GIVEN an APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) @@ -411,13 +401,13 @@ class Model(BaseModel): def handler(user: Model) -> Response[Model]: return Response(body=user, status_code=200) - LOAD_GW_EVENT["httpMethod"] = "POST" - LOAD_GW_EVENT["path"] = "/" - LOAD_GW_EVENT["body"] = json.dumps({}) + gw_event["httpMethod"] = "POST" + gw_event["path"] = "/" + gw_event["body"] = json.dumps({}) # THEN the handler should be invoked and return 422 # THEN the body should have the word missing - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == 422 assert "missing" in result["body"] @@ -431,12 +421,17 @@ def handler(user: Model) -> Response[Model]: ("handler3_without_query_params", 200, None), ], ) -def test_validation_query_string_with_api_rest_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_query_string_with_api_rest_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event, +): # GIVEN a APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) - LOAD_GW_EVENT["httpMethod"] = "GET" - LOAD_GW_EVENT["path"] = "/users" + gw_event["httpMethod"] = "GET" + gw_event["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -455,8 +450,8 @@ def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): # Define handler3 without params if handler_func == "handler3_without_query_params": - LOAD_GW_EVENT["queryStringParameters"] = None - LOAD_GW_EVENT["multiValueQueryStringParameters"] = None + gw_event["queryStringParameters"] = None + gw_event["multiValueQueryStringParameters"] = None @app.get("/users") def handler3(): @@ -464,7 +459,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -480,13 +475,18 @@ def handler3(): ("handler3_without_query_params", 200, None), ], ) -def test_validation_query_string_with_api_http_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_query_string_with_api_http_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_http, +): # GIVEN a APIGatewayHttpResolver with validation enabled app = APIGatewayHttpResolver(enable_validation=True) - LOAD_GW_EVENT_HTTP["rawPath"] = "/users" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + gw_event_http["rawPath"] = "/users" + gw_event_http["requestContext"]["http"]["method"] = "GET" + gw_event_http["requestContext"]["http"]["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -505,7 +505,7 @@ def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): # Define handler3 without params if handler_func == "handler3_without_query_params": - LOAD_GW_EVENT_HTTP["queryStringParameters"] = None + gw_event_http["queryStringParameters"] = None @app.get("/users") def handler3(): @@ -513,7 +513,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_HTTP, {}) + result = app(gw_event_http, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -529,13 +529,18 @@ def handler3(): ("handler3_without_query_params", 200, None), ], ) -def test_validation_query_string_with_alb_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_query_string_with_alb_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_alb, +): # GIVEN a ALBResolver with validation enabled app = ALBResolver(enable_validation=True) - LOAD_GW_EVENT_ALB["path"] = "/users" - # WHEN a handler is defined with various parameters and routes + gw_event_alb["path"] = "/users" + # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params if handler_func == "handler1_with_correct_params": @@ -552,7 +557,7 @@ def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): # Define handler3 without params if handler_func == "handler3_without_query_params": - LOAD_GW_EVENT_HTTP["multiValueQueryStringParameters"] = None + gw_event_alb["multiValueQueryStringParameters"] = None @app.get("/users") def handler3(): @@ -560,7 +565,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_ALB, {}) + result = app(gw_event_alb, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -576,13 +581,18 @@ def handler3(): ("handler3_without_query_params", 200, None), ], ) -def test_validation_query_string_with_lambda_url_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_query_string_with_lambda_url_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_lambda_url, +): # GIVEN a LambdaFunctionUrlResolver with validation enabled app = LambdaFunctionUrlResolver(enable_validation=True) - LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + gw_event_lambda_url["rawPath"] = "/users" + gw_event_lambda_url["requestContext"]["http"]["method"] = "GET" + gw_event_lambda_url["requestContext"]["http"]["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -601,7 +611,7 @@ def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): # Define handler3 without params if handler_func == "handler3_without_query_params": - LOAD_GW_EVENT_LAMBDA_URL["queryStringParameters"] = None + gw_event_lambda_url["queryStringParameters"] = None @app.get("/users") def handler3(): @@ -609,7 +619,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + result = app(gw_event_lambda_url, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -625,11 +635,16 @@ def handler3(): ("handler3_without_query_params", 200, None), ], ) -def test_validation_query_string_with_vpc_lattice_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_query_string_with_vpc_lattice_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_vpc_lattice, +): # GIVEN a VPCLatticeV2Resolver with validation enabled app = VPCLatticeV2Resolver(enable_validation=True) - LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" + gw_event_vpc_lattice["path"] = "/users" # WHEN a handler is defined with various parameters and routes @@ -649,7 +664,7 @@ def handler2(parameter1: Annotated[List[int], Query()], parameter2: str): # Define handler3 without params if handler_func == "handler3_without_query_params": - LOAD_GW_EVENT_VPC_LATTICE["queryStringParameters"] = None + gw_event_vpc_lattice["queryStringParameters"] = None @app.get("/users") def handler3(): @@ -657,7 +672,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + result = app(gw_event_vpc_lattice, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -675,12 +690,17 @@ def handler3(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_api_rest_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_api_rest_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event, +): # GIVEN a APIGatewayRestResolver with validation enabled app = APIGatewayRestResolver(enable_validation=True) - LOAD_GW_EVENT["httpMethod"] = "GET" - LOAD_GW_EVENT["path"] = "/users" + gw_event["httpMethod"] = "GET" + gw_event["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -709,8 +729,8 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT["headers"] = None - LOAD_GW_EVENT["multiValueHeaders"] = None + gw_event["headers"] = None + gw_event["multiValueHeaders"] = None @app.get("/users") def handler4(): @@ -718,7 +738,7 @@ def handler4(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT, {}) + result = app(gw_event, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -735,13 +755,18 @@ def handler4(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_http_rest_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_http_rest_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_http, +): # GIVEN a APIGatewayHttpResolver with validation enabled app = APIGatewayHttpResolver(enable_validation=True) - LOAD_GW_EVENT_HTTP["rawPath"] = "/users" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_HTTP["requestContext"]["http"]["path"] = "/users" + gw_event_http["rawPath"] = "/users" + gw_event_http["requestContext"]["http"]["method"] = "GET" + gw_event_http["requestContext"]["http"]["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -770,7 +795,7 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT_HTTP["headers"] = None + gw_event_http["headers"] = None @app.get("/users") def handler4(): @@ -778,7 +803,7 @@ def handler4(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_HTTP, {}) + result = app(gw_event_http, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -795,11 +820,16 @@ def handler4(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_alb_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_alb_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_alb, +): # GIVEN a ALBResolver with validation enabled app = ALBResolver(enable_validation=True) - LOAD_GW_EVENT_ALB["path"] = "/users" + gw_event_alb["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -828,7 +858,7 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT_ALB["multiValueHeaders"] = None + gw_event_alb["multiValueHeaders"] = None @app.get("/users") def handler4(): @@ -836,7 +866,7 @@ def handler4(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_ALB, {}) + result = app(gw_event_alb, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -853,13 +883,18 @@ def handler4(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_lambda_url_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_lambda_url_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_lambda_url, +): # GIVEN a LambdaFunctionUrlResolver with validation enabled app = LambdaFunctionUrlResolver(enable_validation=True) - LOAD_GW_EVENT_LAMBDA_URL["rawPath"] = "/users" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["method"] = "GET" - LOAD_GW_EVENT_LAMBDA_URL["requestContext"]["http"]["path"] = "/users" + gw_event_lambda_url["rawPath"] = "/users" + gw_event_lambda_url["requestContext"]["http"]["method"] = "GET" + gw_event_lambda_url["requestContext"]["http"]["path"] = "/users" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -888,7 +923,7 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT_LAMBDA_URL["headers"] = None + gw_event_lambda_url["headers"] = None @app.get("/users") def handler4(): @@ -896,7 +931,7 @@ def handler4(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_LAMBDA_URL, {}) + result = app(gw_event_lambda_url, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -913,12 +948,17 @@ def handler4(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_vpc_lattice_v1_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_vpc_lattice_v1_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_vpc_lattice_v1, +): # GIVEN a VPCLatticeResolver with validation enabled app = VPCLatticeResolver(enable_validation=True) - LOAD_GW_EVENT_VPC_LATTICE_V1["raw_path"] = "/users" - LOAD_GW_EVENT_VPC_LATTICE_V1["method"] = "GET" + gw_event_vpc_lattice_v1["raw_path"] = "/users" + gw_event_vpc_lattice_v1["method"] = "GET" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -947,7 +987,7 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT_VPC_LATTICE_V1["headers"] = None + gw_event_vpc_lattice_v1["headers"] = None @app.get("/users") def handler4(): @@ -955,7 +995,7 @@ def handler4(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_VPC_LATTICE_V1, {}) + result = app(gw_event_vpc_lattice_v1, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -972,12 +1012,17 @@ def handler4(): ("handler4_without_header_params", 200, None), ], ) -def test_validation_header_with_vpc_lattice_v2_resolver(handler_func, expected_status_code, expected_error_text): +def test_validation_header_with_vpc_lattice_v2_resolver( + handler_func, + expected_status_code, + expected_error_text, + gw_event_vpc_lattice, +): # GIVEN a VPCLatticeV2Resolver with validation enabled app = VPCLatticeV2Resolver(enable_validation=True) - LOAD_GW_EVENT_VPC_LATTICE["path"] = "/users" - LOAD_GW_EVENT_VPC_LATTICE["method"] = "GET" + gw_event_vpc_lattice["path"] = "/users" + gw_event_vpc_lattice["method"] = "GET" # WHEN a handler is defined with various parameters and routes # Define handler1 with correct params @@ -1006,7 +1051,7 @@ def handler3( # Define handler4 without params if handler_func == "handler4_without_header_params": - LOAD_GW_EVENT_VPC_LATTICE["headers"] = None + gw_event_vpc_lattice["headers"] = None @app.get("/users") def handler3(): @@ -1014,7 +1059,7 @@ def handler3(): # THEN the handler should be invoked with the expected result # AND the status code should match the expected_status_code - result = app(LOAD_GW_EVENT_VPC_LATTICE, {}) + result = app(gw_event_vpc_lattice, {}) assert result["statusCode"] == expected_status_code # IF expected_error_text is provided, THEN check for its presence in the response body @@ -1022,21 +1067,44 @@ def handler3(): assert any(text in result["body"] for text in expected_error_text) -def test_validation_with_alias(): - # GIVEN a Http API V2 proxy type event +def test_validation_with_alias(gw_event): + # GIVEN a REST API V2 proxy type event app = APIGatewayRestResolver(enable_validation=True) - event = load_event("apiGatewayProxyEvent.json") - class FunkyTown(BaseModel): - parameter: str + # GIVEN that it has a multiple parameters called "parameter1" + gw_event["queryStringParameters"] = { + "parameter1": "value1,value2", + } @app.get("/my/path") def my_path( parameter: Annotated[Optional[str], Query(alias="parameter1")] = None, - ) -> Response[FunkyTown]: - assert isinstance(app.current_event, APIGatewayProxyEvent) + ) -> str: assert parameter == "value1" - return Response(200, content_types.APPLICATION_JSON, FunkyTown(parameter=parameter)) + return parameter + + result = app(gw_event, {}) + assert result["statusCode"] == 200 + - result = app(event, {}) +def test_validation_with_http_single_param(gw_event_http): + # GIVEN a HTTP API V2 proxy type event + app = APIGatewayHttpResolver(enable_validation=True) + + # GIVEN that it has a single parameter called "parameter2" + gw_event_http["queryStringParameters"] = { + "parameter1": "value1,value2", + "parameter2": "value", + } + + # WHEN a handler is defined with a single parameter + @app.post("/my/path") + def my_path( + parameter2: str, + ) -> str: + assert parameter2 == "value" + return parameter2 + + # THEN the handler should be invoked and return 200 + result = app(gw_event_http, {}) assert result["statusCode"] == 200 From c83c1f58cd64f2e0f2d60982e1901136f36526c6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:07:34 +0100 Subject: [PATCH 0110/2666] chore(deps-dev): bump sentry-sdk from 1.40.4 to 1.40.5 (#3805) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index 95118cd53ed..a8b083dce98 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2924,13 +2924,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.4" +version = "1.40.5" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.4.tar.gz", hash = "sha256:657abae98b0050a0316f0873d7149f951574ae6212f71d2e3a1c4c88f62d6456"}, - {file = "sentry_sdk-1.40.4-py2.py3-none-any.whl", hash = "sha256:ac5cf56bb897ec47135d239ddeedf7c1c12d406fb031a4c0caa07399ed014d7e"}, + {file = "sentry-sdk-1.40.5.tar.gz", hash = "sha256:d2dca2392cc5c9a2cc9bb874dd7978ebb759682fe4fe889ee7e970ee8dd1c61e"}, + {file = "sentry_sdk-1.40.5-py2.py3-none-any.whl", hash = "sha256:d188b407c9bacbe2a50a824e1f8fb99ee1aeb309133310488c570cb6d7056643"}, ] [package.dependencies] @@ -2956,7 +2956,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure_eval"] +pure-eval = ["asttokens", "executing", "pure-eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] From 7d19a295ffea2aad2eaf7c59014fd572be1478d1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:08:05 +0100 Subject: [PATCH 0111/2666] chore(deps-dev): bump mkdocs-material from 9.5.9 to 9.5.10 (#3803) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index a8b083dce98..e414dfe6832 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1751,13 +1751,13 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.5.9" +version = "9.5.10" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.9-py3-none-any.whl", hash = "sha256:a5d62b73b3b74349e45472bfadc129c871dd2d4add68d84819580597b2f50d5d"}, - {file = "mkdocs_material-9.5.9.tar.gz", hash = "sha256:635df543c01c25c412d6c22991872267723737d5a2f062490f33b2da1c013c6d"}, + {file = "mkdocs_material-9.5.10-py3-none-any.whl", hash = "sha256:3c6c46b57d2ee3c8890e6e0406e68b6863cf65768f0f436990a742702d198442"}, + {file = "mkdocs_material-9.5.10.tar.gz", hash = "sha256:6ad626dbb31070ebbaedff813323a16a406629620e04b96458f16e6e9c7008fe"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "e8d75b05c3a926caf77267d46696fc0eb838f3d276387af45337cad5b28eb467" +content-hash = "922e1cbb0d5854660e1f8f608942e7beff86fe8abbbe7e8fa53b6498d8db9da9" diff --git a/pyproject.toml b/pyproject.toml index 6cde26293d1..ff7b4a6c935 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" typing-extensions = "^4.6.2" -mkdocs-material = "^9.5.9" +mkdocs-material = "^9.5.10" filelock = "^3.12.2" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.34.24" From 7c19e4b0ea757b9ae9f2ef88b70eba413342f398 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:08:34 +0100 Subject: [PATCH 0112/2666] chore(deps): bump squidfunk/mkdocs-material from `62d3668` to `43b898a` in /docs (#3801) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index d972b487853..4445acc55c7 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:62d36688f2a53f4f6ee11bace3a0fd17eed7f38fa127a8c58f4fee704054e3a6 +FROM squidfunk/mkdocs-material@sha256:43b898a5520bbe5ee0080568c002491cd8fcd2269e64f7ad2ba4c9c419acb866 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From ff0f0dee28af0b8160b597f2878efe8c504d86f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:09:08 +0100 Subject: [PATCH 0113/2666] chore(deps-dev): bump types-redis from 4.6.0.20240106 to 4.6.0.20240218 (#3804) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/poetry.lock b/poetry.lock index e414dfe6832..4fc593cbade 100644 --- a/poetry.lock +++ b/poetry.lock @@ -3131,13 +3131,13 @@ files = [ [[package]] name = "types-redis" -version = "4.6.0.20240106" +version = "4.6.0.20240218" description = "Typing stubs for redis" optional = false python-versions = ">=3.8" files = [ - {file = "types-redis-4.6.0.20240106.tar.gz", hash = "sha256:2b2fa3a78f84559616242d23f86de5f4130dfd6c3b83fb2d8ce3329e503f756e"}, - {file = "types_redis-4.6.0.20240106-py3-none-any.whl", hash = "sha256:912de6507b631934bd225cdac310b04a58def94391003ba83939e5a10e99568d"}, + {file = "types-redis-4.6.0.20240218.tar.gz", hash = "sha256:5103d7e690e5c74c974a161317b2d59ac2303cf8bef24175b04c2a4c3486cb39"}, + {file = "types_redis-4.6.0.20240218-py3-none-any.whl", hash = "sha256:dc9c45a068240e33a04302aec5655cf41e80f91eecffccbb2df215b2f6fc375d"}, ] [package.dependencies] From c135ceca8d26862d14db5be5feaa71a30465e2f8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Feb 2024 23:09:59 +0100 Subject: [PATCH 0114/2666] chore(deps): bump actions/dependency-review-action from 4.1.0 to 4.1.2 (#3800) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 953b0e18576..7275680c834 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -19,4 +19,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Dependency Review' - uses: actions/dependency-review-action@80f10bf419f34980065523f5efca7ebed17576aa # v4.1.0 + uses: actions/dependency-review-action@be8bc500ee15e96754d2a6f2d34be14e945a46f3 # v4.1.2 From 6695932eee5eb94856d3c4cb2b3f1cc1599e71dd Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Tue, 20 Feb 2024 10:32:49 +0100 Subject: [PATCH 0115/2666] fix(ci): create one layer artifact per region & merge (#3808) --- .github/workflows/publish_v2_layer.yml | 7 ++++--- .github/workflows/reusable_deploy_v2_layer_stack.yml | 5 ++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 3dfb4cc1446..ab6a59a09a8 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -257,11 +257,12 @@ jobs: integrity_hash: ${{ inputs.source_code_integrity_hash }} artifact_name: ${{ inputs.source_code_artifact_name }} - - name: Download CDK layer artifact + - name: Download CDK layer artifacts uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 with: - name: cdk-layer-stack - path: cdk-layer-stack/ + path: cdk-layer-stack + pattern: cdk-layer-stack-* # merge all Layer artifacts created per region earlier (reusable_deploy_v2_layer_stack.yml; step "Save Layer ARN artifact") + merge-multiple: true - name: Replace layer versions in documentation run: | ls -la cdk-layer-stack/ diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index dd7c5384970..c022ac06c0d 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -193,16 +193,15 @@ jobs: run: | mkdir cdk-layer-stack jq -r -c '.LayerV2Stack.LatestLayerArn' cdk-outputs.json > cdk-layer-stack/${{ matrix.region }}-layer-version.txt - jq -r -c '.LayerV2Stack.LatestLayerArm64Arn' cdk-outputs.json >> cdk-layer-stack/${{ matrix.region }}-layer-version.txt + jq -r -c '.LayerV2Stack.LatestLayerArm64Arn' cdk-outputs.json > cdk-layer-stack/${{ matrix.region }}-layer-version.txt cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt - name: Save Layer ARN artifact if: ${{ inputs.stage == 'PROD' }} uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1 with: - name: cdk-layer-stack + name: cdk-layer-stack-${{ matrix.region }} path: ./layer/cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting. if-no-files-found: error retention-days: 1 - overwrite: true - name: CDK Deploy Canary run: npx cdk deploy --app cdk.out --context region=${{ matrix.region }} --parameters DeployStage="${{ inputs.stage }}" --parameters HasARM64Support=${{ matrix.has_arm64_support }} 'CanaryV2Stack' --require-approval never --verbose From 66358cbb208c530b868bc1f159f12455d94195a2 Mon Sep 17 00:00:00 2001 From: Ran Isenberg <60175085+ran-isenberg@users.noreply.github.com> Date: Tue, 20 Feb 2024 11:39:49 +0200 Subject: [PATCH 0116/2666] docs(we-made-this): add swagger post (#3799) Co-authored-by: Ran Isenberg --- docs/we_made_this.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/we_made_this.md b/docs/we_made_this.md index a9150a2bc08..ea51f65c3d2 100644 --- a/docs/we_made_this.md +++ b/docs/we_made_this.md @@ -39,6 +39,8 @@ A collection of articles explaining in detail how Lambda Powertools helps with a * [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"} +* [Serverless API Documentation with Powertools for AWS](https://www.ranthebuilder.cloud/post/serverless-open-api-documentation-with-aws-powertools){:target="_blank"} + ### Making all your APIs idempotent > **Author: [Michael Walmsley](https://twitter.com/walmsles){target="_blank" rel="nofollow"}** :material-twitter: From 3a547509badd601cfb62dcb3775ae47ebb3f1090 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:58:26 +0100 Subject: [PATCH 0117/2666] chore(ci): changelog rebuild (#3806) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d862bcdb86..2fc9e714fbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,15 +6,23 @@ ## Bug Fixes +* **event-handler:** multi-value query string and validation of scalar parameters ([#3795](https://github.com/aws-powertools/powertools-lambda-python/issues/3795)) +* **event-handler:** swagger schema respects api stage ([#3796](https://github.com/aws-powertools/powertools-lambda-python/issues/3796)) * **event-handler:** handle aliased parameters e.g., Query(alias="categoryType") ([#3766](https://github.com/aws-powertools/powertools-lambda-python/issues/3766)) +## Code Refactoring + +* **feature-flags:** add intersection tests; structure refinement ([#3775](https://github.com/aws-powertools/powertools-lambda-python/issues/3775)) + ## Documentation +* **feature_flags:** fix incorrect line markers and envelope name ([#3792](https://github.com/aws-powertools/powertools-lambda-python/issues/3792)) * **home:** update layer version to 62 for package version 2.33.1 ([#3778](https://github.com/aws-powertools/powertools-lambda-python/issues/3778)) * **home:** add note about POWERTOOLS_DEV side effects in CloudWatch Logs ([#3770](https://github.com/aws-powertools/powertools-lambda-python/issues/3770)) -* **homepage:** remove leftover announcement banner ([#3783](https://github.com/aws-powertools/powertools-lambda-python/issues/3783)) * **homepage:** discord flat badge style; remove former devax email ([#3768](https://github.com/aws-powertools/powertools-lambda-python/issues/3768)) +* **homepage:** remove leftover announcement banner ([#3783](https://github.com/aws-powertools/powertools-lambda-python/issues/3783)) * **roadmap:** latest roadmap update; use new grid to de-clutter homepage ([#3755](https://github.com/aws-powertools/powertools-lambda-python/issues/3755)) +* **we-made-this:** add reinvent 2023 session ([#3790](https://github.com/aws-powertools/powertools-lambda-python/issues/3790)) ## Features @@ -22,17 +30,27 @@ ## Maintenance -* **deps:** bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs ([#3756](https://github.com/aws-powertools/powertools-lambda-python/issues/3756)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3764](https://github.com/aws-powertools/powertools-lambda-python/issues/3764)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3784](https://github.com/aws-powertools/powertools-lambda-python/issues/3784)) * **deps:** bump actions/dependency-review-action from 4.0.0 to 4.1.0 ([#3771](https://github.com/aws-powertools/powertools-lambda-python/issues/3771)) -* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3764](https://github.com/aws-powertools/powertools-lambda-python/issues/3764)) +* **deps:** bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs ([#3756](https://github.com/aws-powertools/powertools-lambda-python/issues/3756)) +* **deps:** bump squidfunk/mkdocs-material from `62d3668` to `43b898a` in /docs ([#3801](https://github.com/aws-powertools/powertools-lambda-python/issues/3801)) +* **deps:** bump actions/dependency-review-action from 4.1.0 to 4.1.2 ([#3800](https://github.com/aws-powertools/powertools-lambda-python/issues/3800)) +* **deps-dev:** bump cfn-lint from 0.85.1 to 0.85.2 ([#3786](https://github.com/aws-powertools/powertools-lambda-python/issues/3786)) +* **deps-dev:** bump pytest-asyncio from 0.21.1 to 0.23.5 ([#3773](https://github.com/aws-powertools/powertools-lambda-python/issues/3773)) +* **deps-dev:** bump aws-cdk from 2.127.0 to 2.128.0 ([#3776](https://github.com/aws-powertools/powertools-lambda-python/issues/3776)) +* **deps-dev:** bump sentry-sdk from 1.40.3 to 1.40.4 ([#3765](https://github.com/aws-powertools/powertools-lambda-python/issues/3765)) +* **deps-dev:** bump the boto-typing group with 2 updates ([#3797](https://github.com/aws-powertools/powertools-lambda-python/issues/3797)) +* **deps-dev:** bump aws-cdk-lib from 2.127.0 to 2.128.0 ([#3777](https://github.com/aws-powertools/powertools-lambda-python/issues/3777)) +* **deps-dev:** bump mkdocs-material from 9.5.9 to 9.5.10 ([#3803](https://github.com/aws-powertools/powertools-lambda-python/issues/3803)) * **deps-dev:** bump the boto-typing group with 1 update ([#3757](https://github.com/aws-powertools/powertools-lambda-python/issues/3757)) +* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) * **deps-dev:** bump aws-cdk from 2.126.0 to 2.127.0 ([#3761](https://github.com/aws-powertools/powertools-lambda-python/issues/3761)) * **deps-dev:** bump mkdocs-material from 9.5.8 to 9.5.9 ([#3759](https://github.com/aws-powertools/powertools-lambda-python/issues/3759)) * **deps-dev:** bump sentry-sdk from 1.40.2 to 1.40.3 ([#3750](https://github.com/aws-powertools/powertools-lambda-python/issues/3750)) * **deps-dev:** bump cfn-lint from 0.85.0 to 0.85.1 ([#3749](https://github.com/aws-powertools/powertools-lambda-python/issues/3749)) -* **deps-dev:** bump sentry-sdk from 1.40.3 to 1.40.4 ([#3765](https://github.com/aws-powertools/powertools-lambda-python/issues/3765)) -* **deps-dev:** bump pytest-asyncio from 0.21.1 to 0.23.5 ([#3773](https://github.com/aws-powertools/powertools-lambda-python/issues/3773)) +* **deps-dev:** bump types-redis from 4.6.0.20240106 to 4.6.0.20240218 ([#3804](https://github.com/aws-powertools/powertools-lambda-python/issues/3804)) +* **deps-dev:** bump sentry-sdk from 1.40.4 to 1.40.5 ([#3805](https://github.com/aws-powertools/powertools-lambda-python/issues/3805)) From 539cb788a8c2074f10e7fd377c7492c356ccb3b2 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Tue, 20 Feb 2024 17:14:14 +0100 Subject: [PATCH 0118/2666] chore(tests): increase idempotency coverage with nested payload tampering tests (#3809) --- .../payload_tampering_validation_handler.py | 17 ++++ tests/e2e/idempotency/infrastructure.py | 1 + .../idempotency/test_idempotency_dynamodb.py | 35 +++++++- .../idempotency/test_idempotency.py | 84 +++++++++++++++++-- tests/functional/idempotency/utils.py | 31 +++++++ 5 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 tests/e2e/idempotency/handlers/payload_tampering_validation_handler.py diff --git a/tests/e2e/idempotency/handlers/payload_tampering_validation_handler.py b/tests/e2e/idempotency/handlers/payload_tampering_validation_handler.py new file mode 100644 index 00000000000..dacb6ce63e0 --- /dev/null +++ b/tests/e2e/idempotency/handlers/payload_tampering_validation_handler.py @@ -0,0 +1,17 @@ +import os +import uuid + +from aws_lambda_powertools.utilities.idempotency import ( + DynamoDBPersistenceLayer, + IdempotencyConfig, + idempotent, +) + +TABLE_NAME = os.getenv("IdempotencyTable", "") +persistence_layer = DynamoDBPersistenceLayer(table_name=TABLE_NAME) +config = IdempotencyConfig(event_key_jmespath='["refund_id", "customer_id"]', payload_validation_jmespath="details") + + +@idempotent(config=config, persistence_store=persistence_layer) +def lambda_handler(event, context): + return {"request": str(uuid.uuid4())} diff --git a/tests/e2e/idempotency/infrastructure.py b/tests/e2e/idempotency/infrastructure.py index 692e0e8ce81..d42cc67d40d 100644 --- a/tests/e2e/idempotency/infrastructure.py +++ b/tests/e2e/idempotency/infrastructure.py @@ -17,6 +17,7 @@ def create_resources(self): table.grant_read_write_data(functions["ParallelExecutionHandler"]) table.grant_read_write_data(functions["FunctionThreadSafetyHandler"]) table.grant_read_write_data(functions["OptionalIdempotencyKeyHandler"]) + table.grant_read_write_data(functions["PayloadTamperingValidationHandler"]) def _create_dynamodb_table(self) -> Table: table = dynamodb.Table( diff --git a/tests/e2e/idempotency/test_idempotency_dynamodb.py b/tests/e2e/idempotency/test_idempotency_dynamodb.py index 1d61cb69f9f..fdd1b79259b 100644 --- a/tests/e2e/idempotency/test_idempotency_dynamodb.py +++ b/tests/e2e/idempotency/test_idempotency_dynamodb.py @@ -1,10 +1,14 @@ import json +from copy import deepcopy from time import sleep import pytest from tests.e2e.utils import data_fetcher -from tests.e2e.utils.data_fetcher.common import GetLambdaResponseOptions, get_lambda_response_in_parallel +from tests.e2e.utils.data_fetcher.common import ( + GetLambdaResponseOptions, + get_lambda_response_in_parallel, +) @pytest.fixture @@ -32,6 +36,11 @@ def optional_idempotency_key_fn_arn(infrastructure: dict) -> str: return infrastructure.get("OptionalIdempotencyKeyHandlerArn", "") +@pytest.fixture +def payload_tampering_validation_fn_arn(infrastructure: dict) -> str: + return infrastructure.get("PayloadTamperingValidationHandlerArn", "") + + @pytest.fixture def idempotency_table_name(infrastructure: dict) -> str: return infrastructure.get("DynamoDBTable", "") @@ -186,3 +195,27 @@ def test_optional_idempotency_key(optional_idempotency_key_fn_arn: str): assert first_execution_response != second_execution_response assert first_execution_response != third_execution_response assert second_execution_response != third_execution_response + + +@pytest.mark.xdist_group(name="idempotency") +def test_payload_tampering_validation(payload_tampering_validation_fn_arn: str): + # GIVEN a transaction with the idempotency key on refund and customer IDs + transaction = { + "refund_id": "ffd11882-d476-4598-bbf1-643f2be5addf", + "customer_id": "9e9fc440-9e65-49b5-9e71-1382ea1b1658", + "details": {"company_name": "Parker, Johnson and Rath", "currency": "Turkish Lira"}, + } + + # AND a second transaction with the exact idempotency key but different currency + tampered_transaction = deepcopy(transaction) + tampered_transaction["details"]["currency"] = "Euro" + + # WHEN we make both requests to a Lambda Function that enabled payload validation + data_fetcher.get_lambda_response(lambda_arn=payload_tampering_validation_fn_arn, payload=json.dumps(transaction)) + + # THEN we should receive a payload validation error in the second request + with pytest.raises(RuntimeError, match="Payload does not match stored record"): + data_fetcher.get_lambda_response( + lambda_arn=payload_tampering_validation_fn_arn, + payload=json.dumps(tampered_transaction), + ) diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index f5b441e5e91..03cfc850f5c 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -8,6 +8,7 @@ from botocore import stub from botocore.config import Config from pydantic import BaseModel +from pytest import FixtureRequest from aws_lambda_powertools.utilities.data_classes import ( APIGatewayProxyEventV2, @@ -38,11 +39,18 @@ BasePersistenceLayer, DataRecord, ) -from aws_lambda_powertools.utilities.idempotency.serialization.custom_dict import CustomDictSerializer -from aws_lambda_powertools.utilities.idempotency.serialization.dataclass import DataclassSerializer -from aws_lambda_powertools.utilities.idempotency.serialization.pydantic import PydanticSerializer +from aws_lambda_powertools.utilities.idempotency.serialization.custom_dict import ( + CustomDictSerializer, +) +from aws_lambda_powertools.utilities.idempotency.serialization.dataclass import ( + DataclassSerializer, +) +from aws_lambda_powertools.utilities.idempotency.serialization.pydantic import ( + PydanticSerializer, +) from aws_lambda_powertools.utilities.validation import envelopes, validator from tests.functional.idempotency.utils import ( + build_idempotency_put_item_response_stub, build_idempotency_put_item_stub, build_idempotency_update_item_stub, hash_idempotency_key, @@ -406,6 +414,8 @@ def test_idempotent_lambda_already_completed_with_validation_bad_payload( Test idempotent decorator where event with matching event key has already been successfully processed """ + # GIVEN an idempotent record already exists for the same transaction + # and payload validation was enabled ('validation' key) stubber = stub.Stubber(persistence_store.client) ddb_response = { "Item": { @@ -423,8 +433,11 @@ def test_idempotent_lambda_already_completed_with_validation_bad_payload( def lambda_handler(event, context): return lambda_response + # WHEN the subsequent request is the same but validated field is tampered + lambda_apigw_event["requestContext"]["accountId"] += "1" # Alter the request payload + + # THEN we should raise with pytest.raises(IdempotencyValidationError): - lambda_apigw_event["requestContext"]["accountId"] += "1" # Alter the request payload lambda_handler(lambda_apigw_event, lambda_context) stubber.assert_no_pending_responses() @@ -1172,11 +1185,9 @@ def _put_record(self, data_record: DataRecord) -> None: 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 _get_record(self, idempotency_key) -> DataRecord: ... - def _delete_record(self, data_record: DataRecord) -> None: - ... + def _delete_record(self, data_record: DataRecord) -> None: ... def test_idempotent_lambda_event_source(lambda_context): @@ -1860,3 +1871,60 @@ def lambda_handler(event, context): stubber.assert_no_pending_responses() stubber.deactivate() + + +def test_idempotency_payload_validation_with_tampering_nested_object( + persistence_store: DynamoDBPersistenceLayer, + timestamp_future, + lambda_context, + request: FixtureRequest, +): + # GIVEN an idempotency config with a compound idempotency key (refund, customer_id) + # AND with payload validation key to prevent tampering + + validation_key = "details" + idempotency_config = IdempotencyConfig( + event_key_jmespath='["refund_id", "customer_id"]', + payload_validation_jmespath=validation_key, + use_local_cache=False, + ) + + # AND a previous transaction already processed in the persistent store + transaction = { + "refund_id": "ffd11882-d476-4598-bbf1-643f2be5addf", + "customer_id": "9e9fc440-9e65-49b5-9e71-1382ea1b1658", + "details": [ + { + "company_name": "Parker, Johnson and Rath", + "currency": "Turkish Lira", + }, + ], + } + + stubber = stub.Stubber(persistence_store.client) + ddb_response = build_idempotency_put_item_response_stub( + data=transaction, + expiration=timestamp_future, + status="COMPLETED", + request=request, + validation_data=transaction[validation_key], + ) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) + stubber.activate() + + # AND an upcoming tampered transaction + tampered_transaction = copy.deepcopy(transaction) + tampered_transaction["details"][0]["currency"] = "Euro" + + @idempotent(config=idempotency_config, persistence_store=persistence_store) + def lambda_handler(event, context): + return event + + # WHEN the tampered request is made + # THEN we should raise + with pytest.raises(IdempotencyValidationError): + lambda_handler(tampered_transaction, lambda_context) + + stubber.assert_no_pending_responses() + stubber.deactivate() diff --git a/tests/functional/idempotency/utils.py b/tests/functional/idempotency/utils.py index 60f28b075b6..c396e40957c 100644 --- a/tests/functional/idempotency/utils.py +++ b/tests/functional/idempotency/utils.py @@ -1,7 +1,11 @@ +from __future__ import annotations + import hashlib +import json from typing import Any, Dict from botocore import stub +from pytest import FixtureRequest from tests.functional.utils import json_serialize @@ -75,3 +79,30 @@ def build_idempotency_update_item_stub( "TableName": "TEST_TABLE", "UpdateExpression": "SET #response_data = :response_data, #expiry = :expiry, #status = :status", } + + +def build_idempotency_key_id(data: Dict, request: FixtureRequest): + return f"test-func.{request.function.__module__}.{request.function.__qualname__}..lambda_handler#{hash_idempotency_key(data)}" # noqa: E501 + + +def build_idempotency_put_item_response_stub( + data: Dict, + expiration: int, + status: str, + request: FixtureRequest, + validation_data: Any | None, +): + response = { + "Item": { + "id": {"S": build_idempotency_key_id(data, request)}, + "expiration": {"N": expiration}, + "data": {"S": json.dumps(data)}, + "status": {"S": status}, + "validation": {"S": hash_idempotency_key(validation_data)}, + }, + } + + if validation_data is not None: + response["Item"]["validation"] = {"S": hash_idempotency_key(validation_data)} + + return response From 31d830b69fbbac6ab098a09c248f859a5cd113d6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:56:06 +0100 Subject: [PATCH 0119/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates (#3814) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 12 ++++++------ layer/scripts/layer-balancer/go.sum | 24 ++++++++++++------------ 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 9b8086a86b2..0f3727c91e3 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -4,24 +4,24 @@ go 1.18 require ( github.com/aws/aws-sdk-go-v2 v1.25.0 - github.com/aws/aws-sdk-go-v2/config v1.27.0 - github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0 + github.com/aws/aws-sdk-go-v2/config v1.27.1 + github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 ) require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.0 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.1 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.19.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.27.1 // indirect github.com/aws/smithy-go v1.20.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index c763e4db53f..fa8ccfa9f7f 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -2,10 +2,10 @@ github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBW github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 h1:2UO6/nT1lCZq1LqM67Oa4tdgP1CvL1sLSxvuD+VrOeE= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0/go.mod h1:5zGj2eA85ClyedTDK+Whsu+w9yimnVIZvhvBKrDquM8= -github.com/aws/aws-sdk-go-v2/config v1.27.0 h1:J5sdGCAHuWKIXLeXiqr8II/adSvetkx0qdZwdbXXpb0= -github.com/aws/aws-sdk-go-v2/config v1.27.0/go.mod h1:cfh8v69nuSUohNFMbIISP2fhmblGmYEOKs5V53HiHnk= -github.com/aws/aws-sdk-go-v2/credentials v1.17.0 h1:lMW2x6sKBsiAJrpi1doOXqWFyEPoE886DTb1X0wb7So= -github.com/aws/aws-sdk-go-v2/credentials v1.17.0/go.mod h1:uT41FIH8cCIxOdUYIL0PYyHlL1NoneDuDSCwg5VE/5o= +github.com/aws/aws-sdk-go-v2/config v1.27.1 h1:oxvGd/cielb+oumJkQmXI0i5tQCRqfdCHV58AfE0pGY= +github.com/aws/aws-sdk-go-v2/config v1.27.1/go.mod h1:SpmaZYWeTF91NQcnnp2AScnZawBWwdkYCupHRNIhVSQ= +github.com/aws/aws-sdk-go-v2/credentials v1.17.1 h1:H4WlK2OnVotRmbVgS8Ww2Z4B3/dDHxDS7cW6EiCECN4= +github.com/aws/aws-sdk-go-v2/credentials v1.17.1/go.mod h1:qTfT/OIE9RAVirZDq0PcEYOOM4Pkmf1Hrk1iInKRS4k= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 h1:xWCwjjvVz2ojYTP4kBKUuUh9ZrXfcAXpflhOUUeXg1k= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0/go.mod h1:j3fACuqXg4oMTQOR2yY7m0NmJY0yBK4L4sLsRXq1Ins= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 h1:NPs/EqVO+ajwOoq56EfcGKa3L3ruWuazkIw1BqxwOPw= @@ -18,14 +18,14 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFl github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA= -github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0 h1:bbwCi7z7SIHl/aZ0bXHU7WS9fmYiNIQxSBes5bgOF7Q= -github.com/aws/aws-sdk-go-v2/service/lambda v1.51.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= -github.com/aws/aws-sdk-go-v2/service/sso v1.19.0 h1:u6OkVDxtBPnxPkZ9/63ynEe+8kHbtS5IfaC4PzVxzWM= -github.com/aws/aws-sdk-go-v2/service/sso v1.19.0/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0 h1:6DL0qu5+315wbsAEEmzK+P9leRwNbkp+lGjPC+CEvb8= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.0/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M= -github.com/aws/aws-sdk-go-v2/service/sts v1.27.0 h1:cjTRjh700H36MQ8M0LnDn33W3JmwC77mdxIIyPWCdpM= -github.com/aws/aws-sdk-go-v2/service/sts v1.27.0/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= +github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0 h1:RYN5WmLgyqgexDSeRjNBczKF35ik4D4ydQwujTUn2I8= +github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.1 h1:GokXLGW3JkH/XzEVp1jDVRxty1eNGB7emkjDG1qxGK8= +github.com/aws/aws-sdk-go-v2/service/sso v1.19.1/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1 h1:2oxSGiYNxTHsuRuPD9McWvcvR6s61G3ssZLyQzcxQL0= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.1 h1:QFT2KUWaVwwGi5/2sQNBOViFpLSkZmiyiHUxE2k6sOU= +github.com/aws/aws-sdk-go-v2/service/sts v1.27.1/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= From 849866625d288b710e0ffd1b01a3988a21d0b407 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:56:31 +0100 Subject: [PATCH 0120/2666] chore(deps): bump actions/dependency-review-action from 4.1.2 to 4.1.3 (#3813) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/dependency-review.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml index 7275680c834..4537173ac39 100644 --- a/.github/workflows/dependency-review.yml +++ b/.github/workflows/dependency-review.yml @@ -19,4 +19,4 @@ jobs: - name: 'Checkout Repository' uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - name: 'Dependency Review' - uses: actions/dependency-review-action@be8bc500ee15e96754d2a6f2d34be14e945a46f3 # v4.1.2 + uses: actions/dependency-review-action@9129d7d40b8c12c1ed0f60400d00c92d437adcce # v4.1.3 From 683017610508d28c7d6674f8f737b577c1348a63 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:57:00 +0100 Subject: [PATCH 0121/2666] chore(deps-dev): bump pytest from 8.0.0 to 8.0.1 (#3812) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 4fc593cbade..73f59fe4379 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2301,13 +2301,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.0.0" +version = "8.0.1" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.0-py3-none-any.whl", hash = "sha256:50fb9cbe836c3f20f0dfa99c565201fb75dc54c8d76373cd1bde06b06657bdb6"}, - {file = "pytest-8.0.0.tar.gz", hash = "sha256:249b1b0864530ba251b7438274c4d251c58d868edaaec8762893ad4a0d71c36c"}, + {file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"}, + {file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "922e1cbb0d5854660e1f8f608942e7beff86fe8abbbe7e8fa53b6498d8db9da9" +content-hash = "e7d6c9d13e4dc00d43ae34d68ec69620a4529f90edbf6eee9984a36ad276fd8f" diff --git a/pyproject.toml b/pyproject.toml index ff7b4a6c935..798d78fbe6d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -51,7 +51,7 @@ jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] coverage = { extras = ["toml"], version = "^7.4" } -pytest = "^8.0.0" +pytest = "^8.0.1" black = "^24.1" boto3 = "^1.26.164" isort = "^5.13.2" From 4d5310de017b228a854ee82fa6613f8525110a42 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 08:57:23 +0100 Subject: [PATCH 0122/2666] chore(deps-dev): bump coverage from 7.4.1 to 7.4.2 (#3811) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 106 ++++++++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 53 deletions(-) diff --git a/poetry.lock b/poetry.lock index 73f59fe4379..d2c07ddab5e 100644 --- a/poetry.lock +++ b/poetry.lock @@ -659,63 +659,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.4.1" +version = "7.4.2" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:077d366e724f24fc02dbfe9d946534357fda71af9764ff99d73c3c596001bbd7"}, - {file = "coverage-7.4.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0193657651f5399d433c92f8ae264aff31fc1d066deee4b831549526433f3f61"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d17bbc946f52ca67adf72a5ee783cd7cd3477f8f8796f59b4974a9b59cacc9ee"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a3277f5fa7483c927fe3a7b017b39351610265308f5267ac6d4c2b64cc1d8d25"}, - {file = "coverage-7.4.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dceb61d40cbfcf45f51e59933c784a50846dc03211054bd76b421a713dcdf19"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:6008adeca04a445ea6ef31b2cbaf1d01d02986047606f7da266629afee982630"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:c61f66d93d712f6e03369b6a7769233bfda880b12f417eefdd4f16d1deb2fc4c"}, - {file = "coverage-7.4.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b9bb62fac84d5f2ff523304e59e5c439955fb3b7f44e3d7b2085184db74d733b"}, - {file = "coverage-7.4.1-cp310-cp310-win32.whl", hash = "sha256:f86f368e1c7ce897bf2457b9eb61169a44e2ef797099fb5728482b8d69f3f016"}, - {file = "coverage-7.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:869b5046d41abfea3e381dd143407b0d29b8282a904a19cb908fa24d090cc018"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:b8ffb498a83d7e0305968289441914154fb0ef5d8b3157df02a90c6695978295"}, - {file = "coverage-7.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3cacfaefe6089d477264001f90f55b7881ba615953414999c46cc9713ff93c8c"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d6850e6e36e332d5511a48a251790ddc545e16e8beaf046c03985c69ccb2676"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18e961aa13b6d47f758cc5879383d27b5b3f3dcd9ce8cdbfdc2571fe86feb4dd"}, - {file = "coverage-7.4.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfd1e1b9f0898817babf840b77ce9fe655ecbe8b1b327983df485b30df8cc011"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:6b00e21f86598b6330f0019b40fb397e705135040dbedc2ca9a93c7441178e74"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:536d609c6963c50055bab766d9951b6c394759190d03311f3e9fcf194ca909e1"}, - {file = "coverage-7.4.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:7ac8f8eb153724f84885a1374999b7e45734bf93a87d8df1e7ce2146860edef6"}, - {file = "coverage-7.4.1-cp311-cp311-win32.whl", hash = "sha256:f3771b23bb3675a06f5d885c3630b1d01ea6cac9e84a01aaf5508706dba546c5"}, - {file = "coverage-7.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:9d2f9d4cc2a53b38cabc2d6d80f7f9b7e3da26b2f53d48f05876fef7956b6968"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f68ef3660677e6624c8cace943e4765545f8191313a07288a53d3da188bd8581"}, - {file = "coverage-7.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23b27b8a698e749b61809fb637eb98ebf0e505710ec46a8aa6f1be7dc0dc43a6"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e3424c554391dc9ef4a92ad28665756566a28fecf47308f91841f6c49288e66"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e0860a348bf7004c812c8368d1fc7f77fe8e4c095d661a579196a9533778e156"}, - {file = "coverage-7.4.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fe558371c1bdf3b8fa03e097c523fb9645b8730399c14fe7721ee9c9e2a545d3"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3468cc8720402af37b6c6e7e2a9cdb9f6c16c728638a2ebc768ba1ef6f26c3a1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:02f2edb575d62172aa28fe00efe821ae31f25dc3d589055b3fb64d51e52e4ab1"}, - {file = "coverage-7.4.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ca6e61dc52f601d1d224526360cdeab0d0712ec104a2ce6cc5ccef6ed9a233bc"}, - {file = "coverage-7.4.1-cp312-cp312-win32.whl", hash = "sha256:ca7b26a5e456a843b9b6683eada193fc1f65c761b3a473941efe5a291f604c74"}, - {file = "coverage-7.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:85ccc5fa54c2ed64bd91ed3b4a627b9cce04646a659512a051fa82a92c04a448"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8bdb0285a0202888d19ec6b6d23d5990410decb932b709f2b0dfe216d031d218"}, - {file = "coverage-7.4.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:918440dea04521f499721c039863ef95433314b1db00ff826a02580c1f503e45"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:379d4c7abad5afbe9d88cc31ea8ca262296480a86af945b08214eb1a556a3e4d"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b094116f0b6155e36a304ff912f89bbb5067157aff5f94060ff20bbabdc8da06"}, - {file = "coverage-7.4.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2f5968608b1fe2a1d00d01ad1017ee27efd99b3437e08b83ded9b7af3f6f766"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:10e88e7f41e6197ea0429ae18f21ff521d4f4490aa33048f6c6f94c6045a6a75"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a4a3907011d39dbc3e37bdc5df0a8c93853c369039b59efa33a7b6669de04c60"}, - {file = "coverage-7.4.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6d224f0c4c9c98290a6990259073f496fcec1b5cc613eecbd22786d398ded3ad"}, - {file = "coverage-7.4.1-cp38-cp38-win32.whl", hash = "sha256:23f5881362dcb0e1a92b84b3c2809bdc90db892332daab81ad8f642d8ed55042"}, - {file = "coverage-7.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:a07f61fc452c43cd5328b392e52555f7d1952400a1ad09086c4a8addccbd138d"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8e738a492b6221f8dcf281b67129510835461132b03024830ac0e554311a5c54"}, - {file = "coverage-7.4.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:46342fed0fff72efcda77040b14728049200cbba1279e0bf1188f1f2078c1d70"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9641e21670c68c7e57d2053ddf6c443e4f0a6e18e547e86af3fad0795414a628"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb2c2688ed93b027eb0d26aa188ada34acb22dceea256d76390eea135083950"}, - {file = "coverage-7.4.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d12c923757de24e4e2110cf8832d83a886a4cf215c6e61ed506006872b43a6d1"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0491275c3b9971cdbd28a4595c2cb5838f08036bca31765bad5e17edf900b2c7"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8dfc5e195bbef80aabd81596ef52a1277ee7143fe419efc3c4d8ba2754671756"}, - {file = "coverage-7.4.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:1a78b656a4d12b0490ca72651fe4d9f5e07e3c6461063a9b6265ee45eb2bdd35"}, - {file = "coverage-7.4.1-cp39-cp39-win32.whl", hash = "sha256:f90515974b39f4dea2f27c0959688621b46d96d5a626cf9c53dbc653a895c05c"}, - {file = "coverage-7.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:64e723ca82a84053dd7bfcc986bdb34af8d9da83c521c19d6b472bc6880e191a"}, - {file = "coverage-7.4.1-pp38.pp39.pp310-none-any.whl", hash = "sha256:32a8d985462e37cfdab611a6f95b09d7c091d07668fdc26e47a725ee575fe166"}, - {file = "coverage-7.4.1.tar.gz", hash = "sha256:1ed4b95480952b1a26d863e546fa5094564aa0065e1e5f0d4d0041f293251d04"}, + {file = "coverage-7.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf54c3e089179d9d23900e3efc86d46e4431188d9a657f345410eecdd0151f50"}, + {file = "coverage-7.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fe6e43c8b510719b48af7db9631b5fbac910ade4bd90e6378c85ac5ac706382c"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b98c89db1b150d851a7840142d60d01d07677a18f0f46836e691c38134ed18b"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5f9683be6a5b19cd776ee4e2f2ffb411424819c69afab6b2db3a0a364ec6642"}, + {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78cdcbf7b9cb83fe047ee09298e25b1cd1636824067166dc97ad0543b079d22f"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2599972b21911111114100d362aea9e70a88b258400672626efa2b9e2179609c"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ef00d31b7569ed3cb2036f26565f1984b9fc08541731ce01012b02a4c238bf03"}, + {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:20a875bfd8c282985c4720c32aa05056f77a68e6d8bbc5fe8632c5860ee0b49b"}, + {file = "coverage-7.4.2-cp310-cp310-win32.whl", hash = "sha256:b3f2b1eb229f23c82898eedfc3296137cf1f16bb145ceab3edfd17cbde273fb7"}, + {file = "coverage-7.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7df95fdd1432a5d2675ce630fef5f239939e2b3610fe2f2b5bf21fa505256fa3"}, + {file = "coverage-7.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8ddbd158e069dded57738ea69b9744525181e99974c899b39f75b2b29a624e2"}, + {file = "coverage-7.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81a5fb41b0d24447a47543b749adc34d45a2cf77b48ca74e5bf3de60a7bd9edc"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2412e98e70f16243be41d20836abd5f3f32edef07cbf8f407f1b6e1ceae783ac"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb79414c15c6f03f56cc68fa06994f047cf20207c31b5dad3f6bab54a0f66ef"}, + {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf89ab85027427d351f1de918aff4b43f4eb5f33aff6835ed30322a86ac29c9e"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a178b7b1ac0f1530bb28d2e51f88c0bab3e5949835851a60dda80bff6052510c"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:06fe398145a2e91edaf1ab4eee66149c6776c6b25b136f4a86fcbbb09512fd10"}, + {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:18cac867950943fe93d6cd56a67eb7dcd2d4a781a40f4c1e25d6f1ed98721a55"}, + {file = "coverage-7.4.2-cp311-cp311-win32.whl", hash = "sha256:f72cdd2586f9a769570d4b5714a3837b3a59a53b096bb954f1811f6a0afad305"}, + {file = "coverage-7.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:d779a48fac416387dd5673fc5b2d6bd903ed903faaa3247dc1865c65eaa5a93e"}, + {file = "coverage-7.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:adbdfcda2469d188d79771d5696dc54fab98a16d2ef7e0875013b5f56a251047"}, + {file = "coverage-7.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ac4bab32f396b03ebecfcf2971668da9275b3bb5f81b3b6ba96622f4ef3f6e17"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:006d220ba2e1a45f1de083d5022d4955abb0aedd78904cd5a779b955b019ec73"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3733545eb294e5ad274abe131d1e7e7de4ba17a144505c12feca48803fea5f64"}, + {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a9e754aa250fe61f0f99986399cec086d7e7a01dd82fd863a20af34cbce962"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2ed37e16cf35c8d6e0b430254574b8edd242a367a1b1531bd1adc99c6a5e00fe"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b953275d4edfab6cc0ed7139fa773dfb89e81fee1569a932f6020ce7c6da0e8f"}, + {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32b4ab7e6c924f945cbae5392832e93e4ceb81483fd6dc4aa8fb1a97b9d3e0e1"}, + {file = "coverage-7.4.2-cp312-cp312-win32.whl", hash = "sha256:f5df76c58977bc35a49515b2fbba84a1d952ff0ec784a4070334dfbec28a2def"}, + {file = "coverage-7.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:34423abbaad70fea9d0164add189eabaea679068ebdf693baa5c02d03e7db244"}, + {file = "coverage-7.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b11f9c6587668e495cc7365f85c93bed34c3a81f9f08b0920b87a89acc13469"}, + {file = "coverage-7.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:51593a1f05c39332f623d64d910445fdec3d2ac2d96b37ce7f331882d5678ddf"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69f1665165ba2fe7614e2f0c1aed71e14d83510bf67e2ee13df467d1c08bf1e8"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3c8bbb95a699c80a167478478efe5e09ad31680931ec280bf2087905e3b95ec"}, + {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:175f56572f25e1e1201d2b3e07b71ca4d201bf0b9cb8fad3f1dfae6a4188de86"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8562ca91e8c40864942615b1d0b12289d3e745e6b2da901d133f52f2d510a1e3"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a1ef0f173e1a19738f154fb3644f90d0ada56fe6c9b422f992b04266c55d5a"}, + {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f40ac873045db4fd98a6f40387d242bde2708a3f8167bd967ccd43ad46394ba2"}, + {file = "coverage-7.4.2-cp38-cp38-win32.whl", hash = "sha256:d1b750a8409bec61caa7824bfd64a8074b6d2d420433f64c161a8335796c7c6b"}, + {file = "coverage-7.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b4ae777bebaed89e3a7e80c4a03fac434a98a8abb5251b2a957d38fe3fd30088"}, + {file = "coverage-7.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ff7f92ae5a456101ca8f48387fd3c56eb96353588e686286f50633a611afc95"}, + {file = "coverage-7.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:861d75402269ffda0b33af94694b8e0703563116b04c681b1832903fac8fd647"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3507427d83fa961cbd73f11140f4a5ce84208d31756f7238d6257b2d3d868405"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf711d517e21fb5bc429f5c4308fbc430a8585ff2a43e88540264ae87871e36a"}, + {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c00e54f0bd258ab25e7f731ca1d5144b0bf7bec0051abccd2bdcff65fa3262c9"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f8e845d894e39fb53834da826078f6dc1a933b32b1478cf437007367efaf6f6a"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:840456cb1067dc350af9080298c7c2cfdddcedc1cb1e0b30dceecdaf7be1a2d3"}, + {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c11ca2df2206a4e3e4c4567f52594637392ed05d7c7fb73b4ea1c658ba560265"}, + {file = "coverage-7.4.2-cp39-cp39-win32.whl", hash = "sha256:3ff5bdb08d8938d336ce4088ca1a1e4b6c8cd3bef8bb3a4c0eb2f37406e49643"}, + {file = "coverage-7.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:ac9e95cefcf044c98d4e2c829cd0669918585755dd9a92e28a1a7012322d0a95"}, + {file = "coverage-7.4.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:f593a4a90118d99014517c2679e04a4ef5aee2d81aa05c26c734d271065efcb6"}, + {file = "coverage-7.4.2.tar.gz", hash = "sha256:1a5ee18e3a8d766075ce9314ed1cb695414bae67df6a4b0805f5137d93d6f1cb"}, ] [package.dependencies] From 7c992d8379c6a859d1cd0b442886ebf2c4ef04c2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:05:45 +0100 Subject: [PATCH 0123/2666] chore(deps-dev): bump the boto-typing group with 2 updates (#3810) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 18 +++++++++--------- pyproject.toml | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/poetry.lock b/poetry.lock index d2c07ddab5e..ed61e6005aa 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1911,13 +1911,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-dynamodb" -version = "1.34.34" -description = "Type annotations for boto3.DynamoDB 1.34.34 service generated with mypy-boto3-builder 7.23.1" +version = "1.34.46" +description = "Type annotations for boto3.DynamoDB 1.34.46 service generated with mypy-boto3-builder 7.23.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-boto3-dynamodb-1.34.34.tar.gz", hash = "sha256:023b0284027ab5f4e5c912dfae86583c62b0e6c8b1d34fad8c6fba37f9baf17b"}, - {file = "mypy_boto3_dynamodb-1.34.34-py3-none-any.whl", hash = "sha256:fb5e49ec0632ff9c15be3ce25302cdd7a917ffa0a80c49f30e3a136ecc9601f0"}, + {file = "mypy-boto3-dynamodb-1.34.46.tar.gz", hash = "sha256:126da0a29ca48502cfa9a26e3024341233d8419f7e03273cea17af7d38e724bd"}, + {file = "mypy_boto3_dynamodb-1.34.46-py3-none-any.whl", hash = "sha256:1af7c80a0891edac29e5b70441122f6803eb772a3b7b498396eec30368232541"}, ] [package.dependencies] @@ -1925,13 +1925,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-lambda" -version = "1.34.44" -description = "Type annotations for boto3.Lambda 1.34.44 service generated with mypy-boto3-builder 7.23.1" +version = "1.34.46" +description = "Type annotations for boto3.Lambda 1.34.46 service generated with mypy-boto3-builder 7.23.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-boto3-lambda-1.34.44.tar.gz", hash = "sha256:b465e00c33267ceffdf3040c9562755d73aee21902a16d9b84294f7f0e378ab9"}, - {file = "mypy_boto3_lambda-1.34.44-py3-none-any.whl", hash = "sha256:0ef2063a00fad20a4fc096720a8c5c43b08a133cf27738ba9b1c70ea71b271b9"}, + {file = "mypy-boto3-lambda-1.34.46.tar.gz", hash = "sha256:275297944c5e36a170b37ce70229f21db6dd3561606799f18d96e36ac5df6876"}, + {file = "mypy_boto3_lambda-1.34.46-py3-none-any.whl", hash = "sha256:a12232002e04ee06b413b47068bc6bb085aeaa3693d28e9bf0efd76fa6953a0b"}, ] [package.dependencies] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "e7d6c9d13e4dc00d43ae34d68ec69620a4529f90edbf6eee9984a36ad276fd8f" +content-hash = "42e66a612a154043f82e8f5d1ad5054d7d91cd9b536dad5c4fc3b710be3b973d" diff --git a/pyproject.toml b/pyproject.toml index 798d78fbe6d..17c88621713 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,8 +73,8 @@ pytest-benchmark = "^4.0.0" mypy-boto3-appconfig = "^1.34.0" mypy-boto3-cloudformation = "^1.34.32" mypy-boto3-cloudwatch = "^1.34.40" -mypy-boto3-dynamodb = "^1.34.34" -mypy-boto3-lambda = "^1.34.44" +mypy-boto3-dynamodb = "^1.34.46" +mypy-boto3-lambda = "^1.34.46" mypy-boto3-logs = "^1.34.16" mypy-boto3-secretsmanager = "^1.34.43" mypy-boto3-ssm = "^1.34.32" From 8f1aa913e9f6cd5db683b057112821ae77496d66 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:56:55 +0100 Subject: [PATCH 0124/2666] chore(ci): layer docs update (#3817) * chore(ci): layer docs update * fix: manual correction for x86 version Signed-off-by: heitorlessa --------- Signed-off-by: heitorlessa Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> Co-authored-by: heitorlessa --- CHANGELOG.md | 51 +++--------------- docs/index.md | 142 +++++++++++++++++++++++++------------------------- 2 files changed, 77 insertions(+), 116 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fc9e714fbf..9bc6d9f3e49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,53 +4,13 @@ # Unreleased -## Bug Fixes - -* **event-handler:** multi-value query string and validation of scalar parameters ([#3795](https://github.com/aws-powertools/powertools-lambda-python/issues/3795)) -* **event-handler:** swagger schema respects api stage ([#3796](https://github.com/aws-powertools/powertools-lambda-python/issues/3796)) -* **event-handler:** handle aliased parameters e.g., Query(alias="categoryType") ([#3766](https://github.com/aws-powertools/powertools-lambda-python/issues/3766)) - -## Code Refactoring - -* **feature-flags:** add intersection tests; structure refinement ([#3775](https://github.com/aws-powertools/powertools-lambda-python/issues/3775)) - -## Documentation - -* **feature_flags:** fix incorrect line markers and envelope name ([#3792](https://github.com/aws-powertools/powertools-lambda-python/issues/3792)) -* **home:** update layer version to 62 for package version 2.33.1 ([#3778](https://github.com/aws-powertools/powertools-lambda-python/issues/3778)) -* **home:** add note about POWERTOOLS_DEV side effects in CloudWatch Logs ([#3770](https://github.com/aws-powertools/powertools-lambda-python/issues/3770)) -* **homepage:** discord flat badge style; remove former devax email ([#3768](https://github.com/aws-powertools/powertools-lambda-python/issues/3768)) -* **homepage:** remove leftover announcement banner ([#3783](https://github.com/aws-powertools/powertools-lambda-python/issues/3783)) -* **roadmap:** latest roadmap update; use new grid to de-clutter homepage ([#3755](https://github.com/aws-powertools/powertools-lambda-python/issues/3755)) -* **we-made-this:** add reinvent 2023 session ([#3790](https://github.com/aws-powertools/powertools-lambda-python/issues/3790)) - -## Features - -* **feature_flags:** add intersect actions for conditions ([#3692](https://github.com/aws-powertools/powertools-lambda-python/issues/3692)) + +## [v2.34.0] - 2024-02-21 ## Maintenance -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3784](https://github.com/aws-powertools/powertools-lambda-python/issues/3784)) -* **deps:** bump actions/dependency-review-action from 4.0.0 to 4.1.0 ([#3771](https://github.com/aws-powertools/powertools-lambda-python/issues/3771)) -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3764](https://github.com/aws-powertools/powertools-lambda-python/issues/3764)) -* **deps:** bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs ([#3756](https://github.com/aws-powertools/powertools-lambda-python/issues/3756)) -* **deps:** bump squidfunk/mkdocs-material from `62d3668` to `43b898a` in /docs ([#3801](https://github.com/aws-powertools/powertools-lambda-python/issues/3801)) -* **deps:** bump actions/dependency-review-action from 4.1.0 to 4.1.2 ([#3800](https://github.com/aws-powertools/powertools-lambda-python/issues/3800)) -* **deps-dev:** bump cfn-lint from 0.85.1 to 0.85.2 ([#3786](https://github.com/aws-powertools/powertools-lambda-python/issues/3786)) -* **deps-dev:** bump pytest-asyncio from 0.21.1 to 0.23.5 ([#3773](https://github.com/aws-powertools/powertools-lambda-python/issues/3773)) -* **deps-dev:** bump aws-cdk from 2.127.0 to 2.128.0 ([#3776](https://github.com/aws-powertools/powertools-lambda-python/issues/3776)) -* **deps-dev:** bump sentry-sdk from 1.40.3 to 1.40.4 ([#3765](https://github.com/aws-powertools/powertools-lambda-python/issues/3765)) -* **deps-dev:** bump the boto-typing group with 2 updates ([#3797](https://github.com/aws-powertools/powertools-lambda-python/issues/3797)) -* **deps-dev:** bump aws-cdk-lib from 2.127.0 to 2.128.0 ([#3777](https://github.com/aws-powertools/powertools-lambda-python/issues/3777)) -* **deps-dev:** bump mkdocs-material from 9.5.9 to 9.5.10 ([#3803](https://github.com/aws-powertools/powertools-lambda-python/issues/3803)) -* **deps-dev:** bump the boto-typing group with 1 update ([#3757](https://github.com/aws-powertools/powertools-lambda-python/issues/3757)) -* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) -* **deps-dev:** bump aws-cdk from 2.126.0 to 2.127.0 ([#3761](https://github.com/aws-powertools/powertools-lambda-python/issues/3761)) -* **deps-dev:** bump mkdocs-material from 9.5.8 to 9.5.9 ([#3759](https://github.com/aws-powertools/powertools-lambda-python/issues/3759)) -* **deps-dev:** bump sentry-sdk from 1.40.2 to 1.40.3 ([#3750](https://github.com/aws-powertools/powertools-lambda-python/issues/3750)) -* **deps-dev:** bump cfn-lint from 0.85.0 to 0.85.1 ([#3749](https://github.com/aws-powertools/powertools-lambda-python/issues/3749)) -* **deps-dev:** bump types-redis from 4.6.0.20240106 to 4.6.0.20240218 ([#3804](https://github.com/aws-powertools/powertools-lambda-python/issues/3804)) -* **deps-dev:** bump sentry-sdk from 1.40.4 to 1.40.5 ([#3805](https://github.com/aws-powertools/powertools-lambda-python/issues/3805)) +* version bump +* **deps-dev:** bump coverage from 7.4.1 to 7.4.2 ([#3811](https://github.com/aws-powertools/powertools-lambda-python/issues/3811)) @@ -4401,7 +4361,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.1...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.0...HEAD +[v2.34.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.1...v2.34.0 [v2.33.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...v2.33.1 [v2.33.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...v2.33.0 [v2.32.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.31.0...v2.32.0 diff --git a/docs/index.md b/docs/index.md index 7aa9a7d956d..24a2e586514 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,8 +56,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. - * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: - * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: ???+ note "Code snippets for popular infrastructure as code frameworks" @@ -70,7 +70,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 ``` === "Serverless framework" @@ -80,7 +80,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 ``` === "CDK" @@ -96,7 +96,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -145,7 +145,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -198,7 +198,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2:62 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 ❯ amplify push -y @@ -209,7 +209,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2:62 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 ? Do you want to edit the local lambda function now? No ``` @@ -223,7 +223,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 ``` === "Serverless framework" @@ -234,7 +234,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 ``` === "CDK" @@ -250,7 +250,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -300,7 +300,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -356,7 +356,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2-Arm64:62 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 ❯ amplify push -y @@ -367,7 +367,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2-Arm64:62 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 ? Do you want to edit the local lambda function now? No ``` @@ -414,74 +414,74 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:62](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:62](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | **Want to inspect the contents of the Layer?** Replace `{region}` with your AWS region, _e.g. `eu-west-1`_. The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:62 --region {region} +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 --region {region} ``` #### SAR From 3d3a2b3b6c8076447cacf816ab4d31ad26fc6ab3 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 21 Feb 2024 09:57:10 +0100 Subject: [PATCH 0125/2666] fix(ci): revert layer version bump write-only back to append (#3818) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * chore: revert append operation on ARM layers instead of overwrite --------- Signed-off-by: heitorlessa --- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index c022ac06c0d..48cc012cacd 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -193,7 +193,7 @@ jobs: run: | mkdir cdk-layer-stack jq -r -c '.LayerV2Stack.LatestLayerArn' cdk-outputs.json > cdk-layer-stack/${{ matrix.region }}-layer-version.txt - jq -r -c '.LayerV2Stack.LatestLayerArm64Arn' cdk-outputs.json > cdk-layer-stack/${{ matrix.region }}-layer-version.txt + jq -r -c '.LayerV2Stack.LatestLayerArm64Arn' cdk-outputs.json >> cdk-layer-stack/${{ matrix.region }}-layer-version.txt cat cdk-layer-stack/${{ matrix.region }}-layer-version.txt - name: Save Layer ARN artifact if: ${{ inputs.stage == 'PROD' }} From 40cd127076151355bbb8d3d39ddc90dc3c45922b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:03:52 +0100 Subject: [PATCH 0126/2666] chore(deps-dev): bump ruff from 0.2.1 to 0.2.2 (#3802) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index ed61e6005aa..304f615e2b3 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2866,28 +2866,28 @@ files = [ [[package]] name = "ruff" -version = "0.2.1" +version = "0.2.2" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:dd81b911d28925e7e8b323e8d06951554655021df8dd4ac3045d7212ac4ba080"}, - {file = "ruff-0.2.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:dc586724a95b7d980aa17f671e173df00f0a2eef23f8babbeee663229a938fec"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c92db7101ef5bfc18e96777ed7bc7c822d545fa5977e90a585accac43d22f18a"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:13471684694d41ae0f1e8e3a7497e14cd57ccb7dd72ae08d56a159d6c9c3e30e"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a11567e20ea39d1f51aebd778685582d4c56ccb082c1161ffc10f79bebe6df35"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:00a818e2db63659570403e44383ab03c529c2b9678ba4ba6c105af7854008105"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:be60592f9d218b52f03384d1325efa9d3b41e4c4d55ea022cd548547cc42cd2b"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fbd2288890b88e8aab4499e55148805b58ec711053588cc2f0196a44f6e3d855"}, - {file = "ruff-0.2.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3ef052283da7dec1987bba8d8733051c2325654641dfe5877a4022108098683"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7022d66366d6fded4ba3889f73cd791c2d5621b2ccf34befc752cb0df70f5fad"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0a725823cb2a3f08ee743a534cb6935727d9e47409e4ad72c10a3faf042ad5ba"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:0034d5b6323e6e8fe91b2a1e55b02d92d0b582d2953a2b37a67a2d7dedbb7acc"}, - {file = "ruff-0.2.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e5cb5526d69bb9143c2e4d2a115d08ffca3d8e0fddc84925a7b54931c96f5c02"}, - {file = "ruff-0.2.1-py3-none-win32.whl", hash = "sha256:6b95ac9ce49b4fb390634d46d6ece32ace3acdd52814671ccaf20b7f60adb232"}, - {file = "ruff-0.2.1-py3-none-win_amd64.whl", hash = "sha256:e3affdcbc2afb6f5bd0eb3130139ceedc5e3f28d206fe49f63073cb9e65988e0"}, - {file = "ruff-0.2.1-py3-none-win_arm64.whl", hash = "sha256:efababa8e12330aa94a53e90a81eb6e2d55f348bc2e71adbf17d9cad23c03ee6"}, - {file = "ruff-0.2.1.tar.gz", hash = "sha256:3b42b5d8677cd0c72b99fcaf068ffc62abb5a19e71b4a3b9cfa50658a0af02f1"}, + {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"}, + {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"}, + {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"}, + {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"}, + {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"}, + {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"}, + {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"}, + {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"}, ] [[package]] @@ -3402,4 +3402,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "42e66a612a154043f82e8f5d1ad5054d7d91cd9b536dad5c4fc3b710be3b973d" +content-hash = "0821ad77813a84c73ab4555ef83a1cf91454feda418d8086c208361138eaebf5" diff --git a/pyproject.toml b/pyproject.toml index 17c88621713..8555682b218 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,7 +115,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.27.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.2.2" +ruff = ">=0.0.272,<0.2.3" retry2 = "^0.9.5" pytest-socket = ">=0.6,<0.8" types-redis = "^4.6.0.7" From fc3df7ad3317b93d76f32d42a2fd0364dcb522f7 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 21 Feb 2024 10:27:44 +0100 Subject: [PATCH 0127/2666] fix(ci): inject PR_LABELS env for PR Label automation (#3819) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * fix(ci): inject PR_LABELS env Signed-off-by: heitorlessa * chore: init PR_LABELS env with default to prevent failure (no labels) Signed-off-by: heitorlessa --------- Signed-off-by: heitorlessa --- .github/scripts/constants.js | 3 +++ .github/scripts/label_pr_based_on_title.js | 5 ++--- .github/workflows/label_pr_on_title.yml | 1 + 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/scripts/constants.js b/.github/scripts/constants.js index ce4ed8ddeef..8bfe5571974 100644 --- a/.github/scripts/constants.js +++ b/.github/scripts/constants.js @@ -18,6 +18,9 @@ module.exports = Object.freeze({ /** @type {string} */ "PR_IS_MERGED": process.env.PR_IS_MERGED || "false", + /** @type {string} */ + "PR_LABELS": process.env.PR_LABELS || "", + /** @type {string} */ "LABEL_BLOCK": "do-not-merge", diff --git a/.github/scripts/label_pr_based_on_title.js b/.github/scripts/label_pr_based_on_title.js index e2e208c2d78..02f77f448b8 100644 --- a/.github/scripts/label_pr_based_on_title.js +++ b/.github/scripts/label_pr_based_on_title.js @@ -1,4 +1,4 @@ -const { PR_NUMBER, PR_TITLE } = require("./constants") +const { PR_NUMBER, PR_TITLE, PR_LABELS } = require("./constants") module.exports = async ({github, context, core}) => { const FEAT_REGEX = /feat(\((.+)\))?(:.+)/ @@ -18,10 +18,9 @@ module.exports = async ({github, context, core}) => { } // get PR labels from env - const prLabels = process.env.PR_LABELS.replaceAll("\"", "").split(","); + const prLabels = PR_LABELS.replaceAll("\"", "").split(","); const labelKeys = Object.keys(labels); - // Maintenance: We should keep track of modified PRs in case their titles change let miss = 0; try { for (const label in labels) { diff --git a/.github/workflows/label_pr_on_title.yml b/.github/workflows/label_pr_on_title.yml index a56588da95d..2a03f56e4c4 100644 --- a/.github/workflows/label_pr_on_title.yml +++ b/.github/workflows/label_pr_on_title.yml @@ -56,6 +56,7 @@ jobs: env: PR_NUMBER: ${{ needs.get_pr_details.outputs.prNumber }} PR_TITLE: ${{ needs.get_pr_details.outputs.prTitle }} + PR_LABELS: ${{ needs.get_pr_details.outputs.prLabels }} with: github-token: ${{ secrets.GITHUB_TOKEN }} # This safely runs in our base repo, not on fork From 36f4779b6693a47acf0cc91984f8645c61ad17df Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:29:14 +0100 Subject: [PATCH 0128/2666] chore(ci): bump version to 2.34.0 (#3816) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index 776b9b96ce0..4df200c6942 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.33.1" +VERSION = "2.34.0" diff --git a/pyproject.toml b/pyproject.toml index 8555682b218..6ead60c13e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.33.1" +version = "2.34.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"] From 8ed384d6b58819843bcd9df8caeefa9e7001e450 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 10:32:58 +0100 Subject: [PATCH 0129/2666] chore(ci): changelog rebuild (#3820) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9bc6d9f3e49..3c651e625a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,74 @@ # Unreleased +## Bug Fixes + +* **ci:** inject PR_LABELS env for PR Label automation ([#3819](https://github.com/aws-powertools/powertools-lambda-python/issues/3819)) +* **ci:** revert layer version bump write-only back to append ([#3818](https://github.com/aws-powertools/powertools-lambda-python/issues/3818)) + +## Maintenance + +* **deps-dev:** bump ruff from 0.2.1 to 0.2.2 ([#3802](https://github.com/aws-powertools/powertools-lambda-python/issues/3802)) +* **deps-dev:** bump the boto-typing group with 2 updates ([#3810](https://github.com/aws-powertools/powertools-lambda-python/issues/3810)) + ## [v2.34.0] - 2024-02-21 +## Bug Fixes + +* **ci:** create one layer artifact per region & merge ([#3808](https://github.com/aws-powertools/powertools-lambda-python/issues/3808)) +* **event-handler:** multi-value query string and validation of scalar parameters ([#3795](https://github.com/aws-powertools/powertools-lambda-python/issues/3795)) +* **event-handler:** swagger schema respects api stage ([#3796](https://github.com/aws-powertools/powertools-lambda-python/issues/3796)) +* **event-handler:** handle aliased parameters e.g., Query(alias="categoryType") ([#3766](https://github.com/aws-powertools/powertools-lambda-python/issues/3766)) + +## Code Refactoring + +* **feature-flags:** add intersection tests; structure refinement ([#3775](https://github.com/aws-powertools/powertools-lambda-python/issues/3775)) + +## Documentation + +* **feature_flags:** fix incorrect line markers and envelope name ([#3792](https://github.com/aws-powertools/powertools-lambda-python/issues/3792)) +* **home:** update layer version to 62 for package version 2.33.1 ([#3778](https://github.com/aws-powertools/powertools-lambda-python/issues/3778)) +* **home:** add note about POWERTOOLS_DEV side effects in CloudWatch Logs ([#3770](https://github.com/aws-powertools/powertools-lambda-python/issues/3770)) +* **homepage:** discord flat badge style; remove former devax email ([#3768](https://github.com/aws-powertools/powertools-lambda-python/issues/3768)) +* **homepage:** remove leftover announcement banner ([#3783](https://github.com/aws-powertools/powertools-lambda-python/issues/3783)) +* **roadmap:** latest roadmap update; use new grid to de-clutter homepage ([#3755](https://github.com/aws-powertools/powertools-lambda-python/issues/3755)) +* **we-made-this:** add swagger post ([#3799](https://github.com/aws-powertools/powertools-lambda-python/issues/3799)) +* **we-made-this:** add reinvent 2023 session ([#3790](https://github.com/aws-powertools/powertools-lambda-python/issues/3790)) + +## Features + +* **feature_flags:** add intersect actions for conditions ([#3692](https://github.com/aws-powertools/powertools-lambda-python/issues/3692)) + ## Maintenance * version bump +* **deps:** bump actions/dependency-review-action from 4.1.2 to 4.1.3 ([#3813](https://github.com/aws-powertools/powertools-lambda-python/issues/3813)) +* **deps:** bump actions/dependency-review-action from 4.1.0 to 4.1.2 ([#3800](https://github.com/aws-powertools/powertools-lambda-python/issues/3800)) +* **deps:** bump actions/dependency-review-action from 4.0.0 to 4.1.0 ([#3771](https://github.com/aws-powertools/powertools-lambda-python/issues/3771)) +* **deps:** bump squidfunk/mkdocs-material from `62d3668` to `43b898a` in /docs ([#3801](https://github.com/aws-powertools/powertools-lambda-python/issues/3801)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3764](https://github.com/aws-powertools/powertools-lambda-python/issues/3764)) +* **deps:** bump squidfunk/mkdocs-material from `6a72238` to `62d3668` in /docs ([#3756](https://github.com/aws-powertools/powertools-lambda-python/issues/3756)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 2 updates ([#3814](https://github.com/aws-powertools/powertools-lambda-python/issues/3814)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 1 update ([#3784](https://github.com/aws-powertools/powertools-lambda-python/issues/3784)) +* **deps-dev:** bump pytest from 8.0.0 to 8.0.1 ([#3812](https://github.com/aws-powertools/powertools-lambda-python/issues/3812)) +* **deps-dev:** bump aws-cdk from 2.127.0 to 2.128.0 ([#3776](https://github.com/aws-powertools/powertools-lambda-python/issues/3776)) +* **deps-dev:** bump the boto-typing group with 2 updates ([#3797](https://github.com/aws-powertools/powertools-lambda-python/issues/3797)) +* **deps-dev:** bump cfn-lint from 0.85.1 to 0.85.2 ([#3786](https://github.com/aws-powertools/powertools-lambda-python/issues/3786)) +* **deps-dev:** bump pytest-asyncio from 0.21.1 to 0.23.5 ([#3773](https://github.com/aws-powertools/powertools-lambda-python/issues/3773)) +* **deps-dev:** bump aws-cdk-lib from 2.127.0 to 2.128.0 ([#3777](https://github.com/aws-powertools/powertools-lambda-python/issues/3777)) +* **deps-dev:** bump sentry-sdk from 1.40.3 to 1.40.4 ([#3765](https://github.com/aws-powertools/powertools-lambda-python/issues/3765)) +* **deps-dev:** bump sentry-sdk from 1.40.4 to 1.40.5 ([#3805](https://github.com/aws-powertools/powertools-lambda-python/issues/3805)) +* **deps-dev:** bump mkdocs-material from 9.5.9 to 9.5.10 ([#3803](https://github.com/aws-powertools/powertools-lambda-python/issues/3803)) +* **deps-dev:** bump types-redis from 4.6.0.20240106 to 4.6.0.20240218 ([#3804](https://github.com/aws-powertools/powertools-lambda-python/issues/3804)) +* **deps-dev:** bump the boto-typing group with 1 update ([#3757](https://github.com/aws-powertools/powertools-lambda-python/issues/3757)) +* **deps-dev:** bump aws-cdk-lib from 2.126.0 to 2.127.0 ([#3758](https://github.com/aws-powertools/powertools-lambda-python/issues/3758)) +* **deps-dev:** bump aws-cdk from 2.126.0 to 2.127.0 ([#3761](https://github.com/aws-powertools/powertools-lambda-python/issues/3761)) +* **deps-dev:** bump mkdocs-material from 9.5.8 to 9.5.9 ([#3759](https://github.com/aws-powertools/powertools-lambda-python/issues/3759)) +* **deps-dev:** bump sentry-sdk from 1.40.2 to 1.40.3 ([#3750](https://github.com/aws-powertools/powertools-lambda-python/issues/3750)) +* **deps-dev:** bump cfn-lint from 0.85.0 to 0.85.1 ([#3749](https://github.com/aws-powertools/powertools-lambda-python/issues/3749)) * **deps-dev:** bump coverage from 7.4.1 to 7.4.2 ([#3811](https://github.com/aws-powertools/powertools-lambda-python/issues/3811)) +* **tests:** increase idempotency coverage with nested payload tampering tests ([#3809](https://github.com/aws-powertools/powertools-lambda-python/issues/3809)) From 812ab3fb82319639c3a71fadef27cb426050cb30 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 21 Feb 2024 11:57:34 +0100 Subject: [PATCH 0130/2666] fix(idempotency): validate before saving to cache (#3822) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * refactor: validate before saving to cache * fix: use multiprocess LIB to allow local functions by using dill over pickle * chore: add test to prevent regression Signed-off-by: heitorlessa --------- Signed-off-by: heitorlessa --- .../utilities/idempotency/persistence/base.py | 3 +- .../idempotency/persistence/dynamodb.py | 2 +- poetry.lock | 63 ++++++++++++------- pyproject.toml | 1 + .../persistence/test_redis_layer.py | 31 ++++----- .../idempotency/test_idempotency.py | 58 +++++++++++++++++ 6 files changed, 118 insertions(+), 40 deletions(-) diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/base.py b/aws_lambda_powertools/utilities/idempotency/persistence/base.py index 335c7ecc9fb..95736634ca6 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/base.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/base.py @@ -1,6 +1,7 @@ """ Persistence layers supporting idempotency """ + import datetime import hashlib import json @@ -383,9 +384,9 @@ def get_record(self, data: Dict[str, Any]) -> Optional[DataRecord]: record = self._get_record(idempotency_key=idempotency_key) + self._validate_payload(data_payload=data, stored_data_record=record) self._save_to_cache(data_record=record) - self._validate_payload(data_payload=data, stored_data_record=record) return record @abstractmethod diff --git a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py index 6cb86121092..f34ed65adb7 100644 --- a/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py +++ b/aws_lambda_powertools/utilities/idempotency/persistence/dynamodb.py @@ -259,10 +259,10 @@ def _put_record(self, data_record: DataRecord) -> None: f"expiry_timestamp: {old_data_record.expiry_timestamp}, " f"and in_progress_expiry_timestamp: {old_data_record.in_progress_expiry_timestamp}", ) - self._save_to_cache(data_record=old_data_record) try: self._validate_payload(data_payload=data_record, stored_data_record=old_data_record) + self._save_to_cache(data_record=old_data_record) except IdempotencyValidationError as idempotency_validation_error: raise idempotency_validation_error from exc diff --git a/poetry.lock b/poetry.lock index 304f615e2b3..01e0cfc9acb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -957,6 +957,21 @@ files = [ [package.dependencies] packaging = "*" +[[package]] +name = "dill" +version = "0.3.8" +description = "serialize all of Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, + {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, +] + +[package.extras] +graph = ["objgraph (>=1.7.2)"] +profile = ["gprof2dot (>=2022.7.29)"] + [[package]] name = "docker" version = "7.0.0" @@ -1211,17 +1226,6 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, - {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, - {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1806,6 +1810,30 @@ docs = ["sphinx"] gmpy = ["gmpy2 (>=2.1.0a4)"] tests = ["pytest (>=4.6)"] +[[package]] +name = "multiprocess" +version = "0.70.16" +description = "better multiprocessing and multithreading in Python" +optional = false +python-versions = ">=3.8" +files = [ + {file = "multiprocess-0.70.16-pp310-pypy310_pp73-macosx_10_13_x86_64.whl", hash = "sha256:476887be10e2f59ff183c006af746cb6f1fd0eadcfd4ef49e605cbe2659920ee"}, + {file = "multiprocess-0.70.16-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d951bed82c8f73929ac82c61f01a7b5ce8f3e5ef40f5b52553b4f547ce2b08ec"}, + {file = "multiprocess-0.70.16-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37b55f71c07e2d741374998c043b9520b626a8dddc8b3129222ca4f1a06ef67a"}, + {file = "multiprocess-0.70.16-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba8c31889abf4511c7308a8c52bb4a30b9d590e7f58523302ba00237702ca054"}, + {file = "multiprocess-0.70.16-pp39-pypy39_pp73-macosx_10_13_x86_64.whl", hash = "sha256:0dfd078c306e08d46d7a8d06fb120313d87aa43af60d66da43ffff40b44d2f41"}, + {file = "multiprocess-0.70.16-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:e7b9d0f307cd9bd50851afaac0dba2cb6c44449efff697df7c7645f7d3f2be3a"}, + {file = "multiprocess-0.70.16-py310-none-any.whl", hash = "sha256:c4a9944c67bd49f823687463660a2d6daae94c289adff97e0f9d696ba6371d02"}, + {file = "multiprocess-0.70.16-py311-none-any.whl", hash = "sha256:af4cabb0dac72abfb1e794fa7855c325fd2b55a10a44628a3c1ad3311c04127a"}, + {file = "multiprocess-0.70.16-py312-none-any.whl", hash = "sha256:fc0544c531920dde3b00c29863377f87e1632601092ea2daca74e4beb40faa2e"}, + {file = "multiprocess-0.70.16-py38-none-any.whl", hash = "sha256:a71d82033454891091a226dfc319d0cfa8019a4e888ef9ca910372a446de4435"}, + {file = "multiprocess-0.70.16-py39-none-any.whl", hash = "sha256:a0bafd3ae1b732eac64be2e72038231c1ba97724b60b09400d68f229fcc2fbf3"}, + {file = "multiprocess-0.70.16.tar.gz", hash = "sha256:161af703d4652a0e1410be6abccecde4a7ddffd19341be0a7011b94aeb171ac1"}, +] + +[package.dependencies] +dill = ">=0.3.8" + [[package]] name = "mypy" version = "1.8.0" @@ -2488,7 +2516,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2496,16 +2523,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2522,7 +2541,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2530,7 +2548,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3402,4 +3419,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "0821ad77813a84c73ab4555ef83a1cf91454feda418d8086c208361138eaebf5" +content-hash = "7544a7f25c243f30b245750ebc98ff1bbd96fbb814aad24735f71c51c0742574" diff --git a/pyproject.toml b/pyproject.toml index 6ead60c13e8..e4593993549 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,6 +120,7 @@ retry2 = "^0.9.5" pytest-socket = ">=0.6,<0.8" types-redis = "^4.6.0.7" testcontainers = { extras = ["redis"], version = "^3.7.1" } +multiprocess = "^0.70.16" [tool.coverage.run] source = ["aws_lambda_powertools"] diff --git a/tests/functional/idempotency/persistence/test_redis_layer.py b/tests/functional/idempotency/persistence/test_redis_layer.py index 75db55dba55..13df84b559a 100644 --- a/tests/functional/idempotency/persistence/test_redis_layer.py +++ b/tests/functional/idempotency/persistence/test_redis_layer.py @@ -1,36 +1,33 @@ # ruff: noqa import copy +import datetime import json import time as t +from unittest import mock import pytest -from unittest.mock import patch - -from aws_lambda_powertools.utilities.idempotency.persistence.redis import ( - RedisCachePersistenceLayer, -) -import datetime +from multiprocess import Lock, Manager, Process -from aws_lambda_powertools.utilities.idempotency.persistence.base import ( - STATUS_CONSTANTS, - DataRecord, -) - -from unittest import mock -from multiprocessing import Process, Manager, Lock from aws_lambda_powertools.utilities.idempotency.exceptions import ( IdempotencyAlreadyInProgressError, IdempotencyItemAlreadyExistsError, IdempotencyItemNotFoundError, - IdempotencyPersistenceConnectionError, IdempotencyPersistenceConfigError, + IdempotencyPersistenceConnectionError, IdempotencyPersistenceConsistencyError, IdempotencyValidationError, ) from aws_lambda_powertools.utilities.idempotency.idempotency import ( + IdempotencyConfig, idempotent, idempotent_function, - IdempotencyConfig, +) +from aws_lambda_powertools.utilities.idempotency.persistence.base import ( + STATUS_CONSTANTS, + DataRecord, +) +from aws_lambda_powertools.utilities.idempotency.persistence.redis import ( + RedisCachePersistenceLayer, ) redis_badhost = "badhost" @@ -557,6 +554,7 @@ def test_redis_orphan_record_race_condition(lambda_context): port="63005", mock_latency_ms=50, ) + manager = Manager() # use a thread safe dict redis_client.expire_dict = manager.dict() @@ -576,11 +574,13 @@ def lambda_handler(event, context): # run handler for the first time to create a valid record in cache lambda_handler(mock_event, lambda_context) + # modify the cache expiration to create the orphan record for key, item in redis_client.cache.items(): json_dict = json.loads(item) json_dict["expiration"] = int(t.time()) - 4000 redis_client.cache[key] = json.dumps(json_dict).encode() + # Given orphan idempotency record with same payload already in Redis # When running two lambda handler at the same time redis_client.cache["exec_count"] = 0 @@ -590,6 +590,7 @@ def lambda_handler(event, context): p2.start() p1.join() p2.join() + # Then only one handler will actually run assert redis_client.cache["exec_count"] == 1 diff --git a/tests/functional/idempotency/test_idempotency.py b/tests/functional/idempotency/test_idempotency.py index 03cfc850f5c..2591cf8e043 100644 --- a/tests/functional/idempotency/test_idempotency.py +++ b/tests/functional/idempotency/test_idempotency.py @@ -9,6 +9,7 @@ from botocore.config import Config from pydantic import BaseModel from pytest import FixtureRequest +from pytest_mock import MockerFixture from aws_lambda_powertools.utilities.data_classes import ( APIGatewayProxyEventV2, @@ -1928,3 +1929,60 @@ def lambda_handler(event, context): stubber.assert_no_pending_responses() stubber.deactivate() + + +def test_idempotency_cache_with_payload_tampering( + persistence_store: DynamoDBPersistenceLayer, + timestamp_future, + lambda_context, + request: FixtureRequest, + mocker: MockerFixture, +): + # GIVEN an idempotency config with a compound idempotency key (refund, customer_id) + # AND with payload validation key to prevent tampering + + cache_spy = mocker.spy(persistence_store, "_save_to_cache") + + validation_key = "amount" + idempotency_config = IdempotencyConfig( + event_key_jmespath='["refund_id", "customer_id"]', + payload_validation_jmespath=validation_key, + use_local_cache=True, + ) + + # AND a previous transaction already processed in the persistent store + transaction = { + "refund_id": "ffd11882-d476-4598-bbf1-643f2be5addf", + "customer_id": "9e9fc440-9e65-49b5-9e71-1382ea1b1658", + "amount": 100, + } + + stubber = stub.Stubber(persistence_store.client) + ddb_response = build_idempotency_put_item_response_stub( + data=transaction, + expiration=timestamp_future, + status="COMPLETED", + request=request, + validation_data=transaction[validation_key], + ) + + stubber.add_client_error("put_item", "ConditionalCheckFailedException", modeled_fields=ddb_response) + stubber.activate() + + # AND an upcoming tampered transaction + tampered_transaction = copy.deepcopy(transaction) + tampered_transaction["amount"] = 10_000 + + @idempotent(config=idempotency_config, persistence_store=persistence_store) + def lambda_handler(event, context): + return event + + # WHEN the tampered request is made + with pytest.raises(IdempotencyValidationError): + lambda_handler(tampered_transaction, lambda_context) + + stubber.assert_no_pending_responses() + stubber.deactivate() + + # THEN we should not cache a transaction that failed validation + assert cache_spy.call_count == 0 From b89f9adf4a6f506a8489ec584e2bcb08f4dc7a51 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Wed, 21 Feb 2024 19:35:17 +0100 Subject: [PATCH 0131/2666] fix(event-handler): return dict on missing multi_value_headers (#3824) * fix(parameters): make cache aware of single vs multiple calls Signed-off-by: heitorlessa * chore: cleanup, add test for single and nested Signed-off-by: heitorlessa * fix(event-handler): return dict on missing multi_value_headers Signed-off-by: heitorlessa * chore: default dict for multi query strings too Signed-off-by: heitorlessa * revert: path_parameters and stage_variables unrelated to the issue --------- Signed-off-by: heitorlessa --- .../data_classes/api_gateway_proxy_event.py | 6 +++--- .../test_openapi_validation_middleware.py | 20 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py index ff24e908d1a..b8ef9c08045 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_proxy_event.py @@ -112,11 +112,11 @@ def resource(self) -> str: @property def multi_value_headers(self) -> Dict[str, List[str]]: - return self["multiValueHeaders"] + return self.get("multiValueHeaders") or {} @property - def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: - return self.get("multiValueQueryStringParameters") + def multi_value_query_string_parameters(self) -> Dict[str, List[str]]: + return self.get("multiValueQueryStringParameters") or {} @property def resolved_query_string_parameters(self) -> Dict[str, List[str]]: diff --git a/tests/functional/event_handler/test_openapi_validation_middleware.py b/tests/functional/event_handler/test_openapi_validation_middleware.py index a9396644b98..da83f6f92f1 100644 --- a/tests/functional/event_handler/test_openapi_validation_middleware.py +++ b/tests/functional/event_handler/test_openapi_validation_middleware.py @@ -1108,3 +1108,23 @@ def my_path( # THEN the handler should be invoked and return 200 result = app(gw_event_http, {}) assert result["statusCode"] == 200 + + +def test_validate_with_minimal_event(): + # GIVEN an APIGatewayRestResolver with validation enabled + app = APIGatewayRestResolver(enable_validation=True) + + # WHEN a handler is defined with a default scalar parameter + @app.get("/users/") + def handler(user_id: int = 123): + print(user_id) + + minimal_event = { + "path": "/users/123", + "httpMethod": "GET", + "requestContext": {"requestId": "227b78aa-779d-47d4-a48e-ce62120393b8"}, # correlation ID + } + + # THEN the handler should be invoked and return 200 + result = app(minimal_event, {}) + assert result["statusCode"] == 200 From f956fa340e6050cf802291a56c67e52bf409fb71 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:07:11 +0100 Subject: [PATCH 0132/2666] chore(ci): layer docs update (#3826) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 12 ++- docs/index.md | 142 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 5 files changed, 81 insertions(+), 79 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c651e625a8..8ad6f577c49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,16 @@ # Unreleased + + +## [v2.34.1] - 2024-02-21 ## Bug Fixes -* **ci:** inject PR_LABELS env for PR Label automation ([#3819](https://github.com/aws-powertools/powertools-lambda-python/issues/3819)) -* **ci:** revert layer version bump write-only back to append ([#3818](https://github.com/aws-powertools/powertools-lambda-python/issues/3818)) +* **event-handler:** return dict on missing multi_value_headers ([#3824](https://github.com/aws-powertools/powertools-lambda-python/issues/3824)) ## Maintenance -* **deps-dev:** bump ruff from 0.2.1 to 0.2.2 ([#3802](https://github.com/aws-powertools/powertools-lambda-python/issues/3802)) -* **deps-dev:** bump the boto-typing group with 2 updates ([#3810](https://github.com/aws-powertools/powertools-lambda-python/issues/3810)) +* version bump @@ -4422,7 +4423,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.0...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.1...HEAD +[v2.34.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.0...v2.34.1 [v2.34.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.1...v2.34.0 [v2.33.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...v2.33.1 [v2.33.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.32.0...v2.33.0 diff --git a/docs/index.md b/docs/index.md index 24a2e586514..8324f90dfe7 100644 --- a/docs/index.md +++ b/docs/index.md @@ -56,8 +56,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. - * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: - * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: ???+ note "Code snippets for popular infrastructure as code frameworks" @@ -70,7 +70,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 ``` === "Serverless framework" @@ -80,7 +80,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 ``` === "CDK" @@ -96,7 +96,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -145,7 +145,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -198,7 +198,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2:63 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 ❯ amplify push -y @@ -209,7 +209,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2:63 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 ? Do you want to edit the local lambda function now? No ``` @@ -223,7 +223,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 ``` === "Serverless framework" @@ -234,7 +234,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 ``` === "CDK" @@ -250,7 +250,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -300,7 +300,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -356,7 +356,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2-Arm64:63 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 ❯ amplify push -y @@ -367,7 +367,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2-Arm64:63 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 ? Do you want to edit the local lambda function now? No ``` @@ -414,74 +414,74 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:63](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:63](#){: .copyMe}:clipboard: | + | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | **Want to inspect the contents of the Layer?** Replace `{region}` with your AWS region, _e.g. `eu-west-1`_. The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:63 --region {region} +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 --region {region} ``` #### SAR diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 1728dd91e37..9da3442fd67 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:AWSLambdaPowertoolsPythonV2:62 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index d3c0bb3c720..6b49b380f78 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,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:AWSLambdaPowertoolsPythonV2:62 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index 5abd93f9713..76336609d19 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:AWSLambdaPowertoolsPythonV2:62 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 Resources: CaptureLambdaHandlerExample: From a7d14df87fc1775b031f8d4487c4f07788d5e170 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 21 Feb 2024 20:07:36 +0100 Subject: [PATCH 0133/2666] chore(ci): bump version to 2.34.1 (#3825) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index 4df200c6942..6a91b14cb8f 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.34.0" +VERSION = "2.34.1" diff --git a/pyproject.toml b/pyproject.toml index e4593993549..791435821e5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.34.0" +version = "2.34.1" 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"] From e1055f9d6ed9fb1c8f3f83be87b2f396be0505b2 Mon Sep 17 00:00:00 2001 From: Heitor Lessa Date: Thu, 22 Feb 2024 15:44:31 +0100 Subject: [PATCH 0134/2666] docs(install): make minimum install the default option then extra (#3834) --- docs/index.md | 169 ++++++++++++++++++++++++-------------------------- 1 file changed, 82 insertions(+), 87 deletions(-) diff --git a/docs/index.md b/docs/index.md index 8324f90dfe7..955cd5068bc 100644 --- a/docs/index.md +++ b/docs/index.md @@ -42,13 +42,24 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc === "Pip" - You can install [all extra dependencies](#extra-dependencies) at once with the `[all]` extras. + Most features use Python standard library and the AWS SDK _(boto3)_ that are available in the AWS Lambda runtime. - * **pip**: [**`pip install "aws-lambda-powertools[all]"`**](#){: .copyMe} - * **poetry**: [**`poetry add "aws-lambda-powertools[all]"`**](#){: .copyMe} - * **pdm**: [**`pdm add "aws-lambda-powertools[all]"`**](#){: .copyMe} + * **pip**: **`pip install "aws-lambda-powertools"`**{: .copyMe}:clipboard: + * **poetry**: **`poetry add "aws-lambda-powertools"`**{: .copyMe}:clipboard: + * **pdm**: **`pdm add "aws-lambda-powertools"`**{: .copyMe}:clipboard: - Alternatively, see [extra dependencies](#extra-dependencies) if you want to install only what you need. + ### Extra dependencies + + However, you will need additional dependencies if you are using any of the features below: + + | Feature | Install | Default dependency | + | ------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | + | **[Tracer](./core/tracer.md#install)** | **`pip install "aws-lambda-powertools[tracer]"`**{.copyMe}:clipboard: | `aws-xray-sdk` | + | **[Validation](./utilities/validation.md#install)** | **`pip install "aws-lambda-powertools[validation]"`**{.copyMe}:clipboard: | `fastjsonschema` | + | **[Parser](./utilities/parser.md#install)** | **`pip install "aws-lambda-powertools[parser]"`**{.copyMe}:clipboard: | `pydantic` _(v1)_; [v2 is possible](./utilities/parser.md#using-pydantic-v2) | + | **[Data Masking](./utilities/data_masking.md#install)** | **`pip install "aws-lambda-powertools[datamasking]"`**{.copyMe}:clipboard: | `aws-encryption-sdk`, `jsonpath-ng` | + | **All extra dependencies at once** | **`pip install "aws-lambda-powertools[all]"`**{.copyMe}:clipboard: | + | **Two or more extra dependencies only, not all** | **`pip install "aws-lambda-powertools[tracer,parser,datamasking"]`**{.copyMe}:clipboard: | === "Lambda Layer" @@ -56,8 +67,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. - * **x86 architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: - * **ARM architecture**: [__arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64__](# "Replace {region} with your AWS region, e.g., eu-west-1"){: .copyMe}:clipboard: + * x86 architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64__{: .copyMe}:clipboard: + * ARM architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64__{: .copyMe}:clipboard: ???+ note "Code snippets for popular infrastructure as code frameworks" @@ -371,22 +382,6 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? Do you want to edit the local lambda function now? No ``` -### Extra dependencies - -The vast majority of [features](#features) rely on standard library and AWS SDK _(boto3)_ only. The following features however require additional dependencies: - -| Feature | Pip | Dependency | -| ------------------- | --------------------------------------------------------------------------------- | ----------------------------------- | -| Tracer | **[`pip install "aws-lambda-powertools[tracer]"`](#){: .copyMe}:clipboard:** | `aws-xray-sdk` | -| Validation | **[`pip install "aws-lambda-powertools[validation]"`](#){: .copyMe}:clipboard:** | `fastjsonschema` | -| Parser | **[`pip install "aws-lambda-powertools[parser]"`](#){: .copyMe}:clipboard:** | `pydantic` | -| Data Masking | **[`pip install "aws-lambda-powertools[datamasking]"`](#){: .copyMe}:clipboard:** | `aws-encryption-sdk`, `jsonpath-ng` | -| Idempotency (Redis) | **[`pip install "aws-lambda-powertools[redis]"`](#){: .copyMe}:clipboard:** | `redis` | - -> New to pip? - -You can use `,` delimiter to install multiple at once: [**`pip install "aws-lambda-powertools[tracer,parser,datamasking"]`**](#){: .copyMe}:clipboard: - ### Local development !!! info "Using Lambda Layer? Simply add [**`"aws-lambda-powertools[all]"`**](#){: .copyMe}:clipboard: as a development dependency." @@ -406,82 +401,82 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen ### Lambda Layer -[Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html){target="_blank"} is a .zip file archive that can contain additional code, pre-packaged dependencies, data, or configuration files. We compile and optimize [all dependencies](#extra-dependencies), and [remove duplicate dependencies already available in the Lambda runtime](https://github.com/awslabs/cdk-aws-lambda-powertools-layer/blob/main/layer/Python/Dockerfile#L36){target="_blank"} to achieve the most optimal size. +[Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html){target="_blank"} is a .zip file archive that can contain additional code, pre-packaged dependencies, data, or configuration files. We compile and optimize [all dependencies](#install), and remove duplicate dependencies [already available in the Lambda runtime](https://github.com/aws-powertools/powertools-lambda-layer-cdk/blob/d24716744f7d1f37617b4998c992c4c067e19e64/layer/Python/Dockerfile#L36){target="_blank"} to achieve the most optimal size. -??? note "Note: Click to expand and copy any regional Lambda Layer ARN" +??? note "Click to expand and copy any regional Lambda Layer ARN" === "x86_64" - | Region | Layer ARN | - | ---------------- | ---------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `ca-west-1` | [arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64](#){: .copyMe}:clipboard: | + | Region | Layer ARN | + | -------------------- | --------------------------------------------------------------------------------------------------------- | + | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | === "arm64" - | Region | Layer ARN | - | ---------------- | ---------------------------------------------------------------------------------------------------------------- | - | `af-south-1` | [arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-east-1` | [arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-south-1` | [arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-south-2` | [arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `ca-central-1` | [arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-central-1` | [arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-central-2` | [arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-north-1` | [arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-south-1` | [arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-south-2` | [arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-west-1` | [arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-west-2` | [arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `eu-west-3` | [arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `il-central-1` | [arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `me-central-1` | [arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `me-south-1` | [arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `sa-east-1` | [arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `us-east-1` | [arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `us-east-2` | [arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `us-west-1` | [arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | - | `us-west-2` | [arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64](#){: .copyMe}:clipboard: | + | Region | Layer ARN | + | -------------------- | --------------------------------------------------------------------------------------------------------------- | + | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | **Want to inspect the contents of the Layer?** -Replace `{region}` with your AWS region, _e.g. `eu-west-1`_. The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. +The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. The CLI output will also contain the Powertools for AWS Lambda version it contains. ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 --region {region} +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 --region eu-west-1 ``` #### SAR From 7f30b470d435c1ff50a846d90bf18f231298826f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:39:34 +0100 Subject: [PATCH 0135/2666] chore(deps-dev): bump the boto-typing group with 1 update (#3836) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 32 +++++++++++++++++++++++++++----- pyproject.toml | 2 +- 2 files changed, 28 insertions(+), 6 deletions(-) diff --git a/poetry.lock b/poetry.lock index 01e0cfc9acb..042d365962d 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1226,6 +1226,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -2009,13 +2020,13 @@ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.12\""} [[package]] name = "mypy-boto3-ssm" -version = "1.34.32" -description = "Type annotations for boto3.SSM 1.34.32 service generated with mypy-boto3-builder 7.23.1" +version = "1.34.47" +description = "Type annotations for boto3.SSM 1.34.47 service generated with mypy-boto3-builder 7.23.1" optional = false python-versions = ">=3.8" files = [ - {file = "mypy-boto3-ssm-1.34.32.tar.gz", hash = "sha256:1d78f8bfb85d4bfb820046b7c864b75e2ef1a04ea7fed88b4d6d6abf252077e6"}, - {file = "mypy_boto3_ssm-1.34.32-py3-none-any.whl", hash = "sha256:185e46fa5996843e34a5c7fb5e2129df57a37fca3187daa1ab81996d5633c772"}, + {file = "mypy-boto3-ssm-1.34.47.tar.gz", hash = "sha256:be70cc32f9a07e6701746ebe65fba14d59c3f24a8511d275fd8322c9365f2270"}, + {file = "mypy_boto3_ssm-1.34.47-py3-none-any.whl", hash = "sha256:6517b1dc01e3ffe48a251c91e2a7fb6801223baf4a8cf1600411f9e132422297"}, ] [package.dependencies] @@ -2516,6 +2527,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2523,8 +2535,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2541,6 +2561,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2548,6 +2569,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3419,4 +3441,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "7544a7f25c243f30b245750ebc98ff1bbd96fbb814aad24735f71c51c0742574" +content-hash = "d9242ecb699568de69b718031fd7928d070ed6ed33dd906ee68bdb78f335ad7e" diff --git a/pyproject.toml b/pyproject.toml index 791435821e5..57f0a6193de 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -77,7 +77,7 @@ mypy-boto3-dynamodb = "^1.34.46" mypy-boto3-lambda = "^1.34.46" mypy-boto3-logs = "^1.34.16" mypy-boto3-secretsmanager = "^1.34.43" -mypy-boto3-ssm = "^1.34.32" +mypy-boto3-ssm = "^1.34.47" mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" From 9ccc1db8ab8275bd199a6ea5897ec7cc48fbcab4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:39:54 +0100 Subject: [PATCH 0136/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3835) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 28 +++++++-------- layer/scripts/layer-balancer/go.sum | 56 ++++++++++++++--------------- 2 files changed, 42 insertions(+), 42 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 0f3727c91e3..2fbc28ebab6 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -3,25 +3,25 @@ module layerbalancer go 1.18 require ( - github.com/aws/aws-sdk-go-v2 v1.25.0 - github.com/aws/aws-sdk-go-v2/config v1.27.1 - github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0 + github.com/aws/aws-sdk-go-v2 v1.25.1 + github.com/aws/aws-sdk-go-v2/config v1.27.3 + github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 ) require ( - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.1 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.19.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.27.1 // indirect - github.com/aws/smithy-go v1.20.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 // indirect + github.com/aws/smithy-go v1.20.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index fa8ccfa9f7f..df406c29c42 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -1,33 +1,33 @@ -github.com/aws/aws-sdk-go-v2 v1.25.0 h1:sv7+1JVJxOu/dD/sz/csHX7jFqmP001TIY7aytBWDSQ= -github.com/aws/aws-sdk-go-v2 v1.25.0/go.mod h1:G104G1Aho5WqF+SR3mDIobTABQzpYV0WxMsKxlMggOA= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0 h1:2UO6/nT1lCZq1LqM67Oa4tdgP1CvL1sLSxvuD+VrOeE= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.0/go.mod h1:5zGj2eA85ClyedTDK+Whsu+w9yimnVIZvhvBKrDquM8= -github.com/aws/aws-sdk-go-v2/config v1.27.1 h1:oxvGd/cielb+oumJkQmXI0i5tQCRqfdCHV58AfE0pGY= -github.com/aws/aws-sdk-go-v2/config v1.27.1/go.mod h1:SpmaZYWeTF91NQcnnp2AScnZawBWwdkYCupHRNIhVSQ= -github.com/aws/aws-sdk-go-v2/credentials v1.17.1 h1:H4WlK2OnVotRmbVgS8Ww2Z4B3/dDHxDS7cW6EiCECN4= -github.com/aws/aws-sdk-go-v2/credentials v1.17.1/go.mod h1:qTfT/OIE9RAVirZDq0PcEYOOM4Pkmf1Hrk1iInKRS4k= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0 h1:xWCwjjvVz2ojYTP4kBKUuUh9ZrXfcAXpflhOUUeXg1k= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.0/go.mod h1:j3fACuqXg4oMTQOR2yY7m0NmJY0yBK4L4sLsRXq1Ins= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0 h1:NPs/EqVO+ajwOoq56EfcGKa3L3ruWuazkIw1BqxwOPw= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.0/go.mod h1:D+duLy2ylgatV+yTlQ8JTuLfDD0BnFvnQRc+o6tbZ4M= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0 h1:ks7KGMVUMoDzcxNWUlEdI+/lokMFD136EL6DWmUOV80= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.0/go.mod h1:hL6BWM/d/qz113fVitZjbXR0E+RCTU1+x+1Idyn5NgE= +github.com/aws/aws-sdk-go-v2 v1.25.1 h1:P7hU6A5qEdmajGwvae/zDkOq+ULLC9tQBTwqqiwFGpI= +github.com/aws/aws-sdk-go-v2 v1.25.1/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= +github.com/aws/aws-sdk-go-v2/config v1.27.3 h1:0PRdb/q5a77HVYj+2rvPiCObfMfl/pWhwa5cs3cnl3c= +github.com/aws/aws-sdk-go-v2/config v1.27.3/go.mod h1:WeRAr9ENap9NAegbfNsLqGQd8ERz5ypdIUx4j0/ZgKI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.3 h1:dDM5wrgwOL5gTZ0Gv/bvewPldjBcJywoaO5ClERrOGE= +github.com/aws/aws-sdk-go-v2/credentials v1.17.3/go.mod h1:G96Nuaw9qJS+s3OnK8RW8VEKEOjXi8H5Jk4lC/ZyZbw= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 h1:lk1ZZFbdb24qpOwVC1AwYNrswUjAxeyey6kFBVANudQ= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1/go.mod h1:/xJ6x1NehNGCX4tvGzzj2bq5TBOT/Yxq+qbL9Jpx2Vk= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 h1:evvi7FbTAoFxdP/mixmP7LIYzQWAmzBcwNB/es9XPNc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1/go.mod h1:rH61DT6FDdikhPghymripNUCsf+uVF4Cnk4c4DBKH64= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 h1:RAnaIrbxPtlXNVI/OIlh1sidTQ3e1qM6LRjs7N0bE0I= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1/go.mod h1:nbgAGkH5lk0RZRMh6A4K/oG6Xj11eC/1CyDow+DUAFI= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0 h1:a33HuFlO0KsveiP90IUJh8Xr/cx9US2PqkSroaLc+o8= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.0/go.mod h1:SxIkWpByiGbhbHYTo9CMTUnx2G4p4ZQMrDPcRRy//1c= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0 h1:SHN/umDLTmFTmYfI+gkanz6da3vK8Kvj/5wkqnTHbuA= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.0/go.mod h1:l8gPU5RYGOFHJqWEpPMoRTP0VoaWQSkJdKo+hwWnnDA= -github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0 h1:RYN5WmLgyqgexDSeRjNBczKF35ik4D4ydQwujTUn2I8= -github.com/aws/aws-sdk-go-v2/service/lambda v1.52.0/go.mod h1:yEO3Ejj0qBhdIDlRYQ8O9+gB5CAUKyaYYiFBkvGX8ZA= -github.com/aws/aws-sdk-go-v2/service/sso v1.19.1 h1:GokXLGW3JkH/XzEVp1jDVRxty1eNGB7emkjDG1qxGK8= -github.com/aws/aws-sdk-go-v2/service/sso v1.19.1/go.mod h1:YqbU3RS/pkDVu+v+Nwxvn0i1WB0HkNWEePWbmODEbbs= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1 h1:2oxSGiYNxTHsuRuPD9McWvcvR6s61G3ssZLyQzcxQL0= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.22.1/go.mod h1:olUAyg+FaoFaL/zFaeQQONjOZ9HXoxgvI/c7mQTYz7M= -github.com/aws/aws-sdk-go-v2/service/sts v1.27.1 h1:QFT2KUWaVwwGi5/2sQNBOViFpLSkZmiyiHUxE2k6sOU= -github.com/aws/aws-sdk-go-v2/service/sts v1.27.1/go.mod h1:nXfOBMWPokIbOY+Gi7a1psWMSvskUCemZzI+SMB7Akc= -github.com/aws/smithy-go v1.20.0 h1:6+kZsCXZwKxZS9RfISnPc4EXlHoyAkm2hPuM8X2BrrQ= -github.com/aws/smithy-go v1.20.0/go.mod h1:uo5RKksAl4PzhqaAbjd4rLgFoq5koTsQKYuGe7dklGc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 h1:cVP8mng1RjDyI3JN/AXFCn5FHNlsBaBH0/MBtG1bg0o= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1/go.mod h1:C8sQjoyAsdfjC7hpy4+S6B92hnFzx0d0UAyHicaOTIE= +github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0 h1:EPsyL8kIjSQnShTQXZIWYTPVWSgWpG7ZtQRoJuqqf6Y= +github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0/go.mod h1:4eq2dibHpzftx3fHVaHLjw7ab/DlUM2GddPb0Vxg7+8= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 h1:6YL8G91QZ52KlPrLkEgEez5kejIVwChVCgND3qgY5j0= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.0/go.mod h1:x6/tCd1o/AOKQR+iYnjrzhJxD+w0xRN34asGPaSV7ew= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 h1:+DqIa5Ll7W311QLUvGFDdVit9uC4G0VioDdw08cXcow= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0/go.mod h1:lZB123q0SVQ3dfIbEOcGzhQHrwVBcHVReNS9tm20oU4= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 h1:F7tQr61zYnTaeY50Rn4jwfVQbtcqJuBRwN/nGGNwzb0= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.0/go.mod h1:ozhhG9/NB5c9jcmhGq6tX9dpp21LYdmRWRQVppASim4= +github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= +github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= From ad2b5ff64e1c9bc3a8f19736880bbcee941280a7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:40:16 +0100 Subject: [PATCH 0137/2666] chore(ci): changelog rebuild (#3837) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ad6f577c49..15c830b4184 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,16 +4,28 @@ # Unreleased +## Documentation + +* **install:** make minimum install the default option then extra ([#3834](https://github.com/aws-powertools/powertools-lambda-python/issues/3834)) + +## Maintenance + + ## [v2.34.1] - 2024-02-21 ## Bug Fixes +* **ci:** inject PR_LABELS env for PR Label automation ([#3819](https://github.com/aws-powertools/powertools-lambda-python/issues/3819)) +* **ci:** revert layer version bump write-only back to append ([#3818](https://github.com/aws-powertools/powertools-lambda-python/issues/3818)) * **event-handler:** return dict on missing multi_value_headers ([#3824](https://github.com/aws-powertools/powertools-lambda-python/issues/3824)) +* **idempotency:** validate before saving to cache ([#3822](https://github.com/aws-powertools/powertools-lambda-python/issues/3822)) ## Maintenance * version bump +* **deps-dev:** bump ruff from 0.2.1 to 0.2.2 ([#3802](https://github.com/aws-powertools/powertools-lambda-python/issues/3802)) +* **deps-dev:** bump the boto-typing group with 2 updates ([#3810](https://github.com/aws-powertools/powertools-lambda-python/issues/3810)) From 3d85dab60b01a179f790100cefde220e45aacf76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:40:34 +0100 Subject: [PATCH 0138/2666] chore(deps-dev): bump aws-cdk from 2.128.0 to 2.129.0 (#3831) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 35371ce0b22..48be10df3dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.128.0" + "aws-cdk": "^2.129.0" } }, "node_modules/aws-cdk": { - "version": "2.128.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.128.0.tgz", - "integrity": "sha512-epOAr/0WKqmyaKqBc7N0Ky5++93pu+v6yVN9jNOa4JYkAkGbeTS3vR9bj/W0o94jnlgWevG3HNHr83jtRvw/4A==", + "version": "2.129.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.129.0.tgz", + "integrity": "sha512-Gh/dG2aY0cvlLumYUXalg28/knVI/TrN6NZMBpRWe4gGJe/RH5JROIVB2GOEMMajkew9EiFH0ZeoC+pQ57diaQ==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index 510bb9132ea..b98f638c991 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.128.0" + "aws-cdk": "^2.129.0" }, "dependencies": { "package-lock.json": "^1.0.0" From c27d2973660f185cd9d3feaed9a44fc157eaac04 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:42:03 +0100 Subject: [PATCH 0139/2666] chore(deps-dev): bump aws-cdk-lib from 2.128.0 to 2.130.0 (#3838) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 042d365962d..535652f8e95 100644 --- a/poetry.lock +++ b/poetry.lock @@ -158,13 +158,13 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "aws-cdk-lib" -version = "2.128.0" +version = "2.130.0" description = "Version 2 of the AWS Cloud Development Kit library" optional = false python-versions = "~=3.8" files = [ - {file = "aws-cdk-lib-2.128.0.tar.gz", hash = "sha256:796459062daa0dbe0581925874db121d4c220295c6c35e73dedfe39e82ca301f"}, - {file = "aws_cdk_lib-2.128.0-py3-none-any.whl", hash = "sha256:49170b21cb738d30d67f7aa361b78ba3a8b711f8dd15523cbfe64710f9386553"}, + {file = "aws-cdk-lib-2.130.0.tar.gz", hash = "sha256:b9ed68a5fd7f5b9056da58bd122c9c3faa6af1e92f4b6aff181a2ee57625aad1"}, + {file = "aws_cdk_lib-2.130.0-py3-none-any.whl", hash = "sha256:03a98770dd58caa002ded8d2dcdd3f6f7451a95f86c8dba3b5f2b70e659429b3"}, ] [package.dependencies] @@ -3441,4 +3441,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "d9242ecb699568de69b718031fd7928d070ed6ed33dd906ee68bdb78f335ad7e" +content-hash = "69166703da187933336c2adb871526c2be6b410bffd4879d9b04336709a8144d" diff --git a/pyproject.toml b/pyproject.toml index 57f0a6193de..03973d68c40 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -65,7 +65,7 @@ xenon = "^0.9.1" mkdocs-git-revision-date-plugin = "^0.3.2" mike = "^1.1.2" pytest-xdist = "^3.5.0" -aws-cdk-lib = "^2.128.0" +aws-cdk-lib = "^2.130.0" "aws-cdk.aws-apigatewayv2-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-integrations-alpha" = "^2.38.1-alpha.0" "aws-cdk.aws-apigatewayv2-authorizers-alpha" = "^2.38.1-alpha.0" From 8499227138b5bc8eefb70bcab5d5df95f9c12ad2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:47:15 +0100 Subject: [PATCH 0140/2666] chore(deps): bump cryptography from 42.0.2 to 42.0.4 (#3827) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/poetry.lock b/poetry.lock index 535652f8e95..c5177f001c1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -726,43 +726,43 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "42.0.2" +version = "42.0.4" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.2-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:701171f825dcab90969596ce2af253143b93b08f1a716d4b2a9d2db5084ef7be"}, - {file = "cryptography-42.0.2-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:61321672b3ac7aade25c40449ccedbc6db72c7f5f0fdf34def5e2f8b51ca530d"}, - {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ea2c3ffb662fec8bbbfce5602e2c159ff097a4631d96235fcf0fb00e59e3ece4"}, - {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b15c678f27d66d247132cbf13df2f75255627bcc9b6a570f7d2fd08e8c081d2"}, - {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:8e88bb9eafbf6a4014d55fb222e7360eef53e613215085e65a13290577394529"}, - {file = "cryptography-42.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:a047682d324ba56e61b7ea7c7299d51e61fd3bca7dad2ccc39b72bd0118d60a1"}, - {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:36d4b7c4be6411f58f60d9ce555a73df8406d484ba12a63549c88bd64f7967f1"}, - {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:a00aee5d1b6c20620161984f8ab2ab69134466c51f58c052c11b076715e72929"}, - {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b97fe7d7991c25e6a31e5d5e795986b18fbbb3107b873d5f3ae6dc9a103278e9"}, - {file = "cryptography-42.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5fa82a26f92871eca593b53359c12ad7949772462f887c35edaf36f87953c0e2"}, - {file = "cryptography-42.0.2-cp37-abi3-win32.whl", hash = "sha256:4b063d3413f853e056161eb0c7724822a9740ad3caa24b8424d776cebf98e7ee"}, - {file = "cryptography-42.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:841ec8af7a8491ac76ec5a9522226e287187a3107e12b7d686ad354bb78facee"}, - {file = "cryptography-42.0.2-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:55d1580e2d7e17f45d19d3b12098e352f3a37fe86d380bf45846ef257054b242"}, - {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28cb2c41f131a5758d6ba6a0504150d644054fd9f3203a1e8e8d7ac3aea7f73a"}, - {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9097a208875fc7bbeb1286d0125d90bdfed961f61f214d3f5be62cd4ed8a446"}, - {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:44c95c0e96b3cb628e8452ec060413a49002a247b2b9938989e23a2c8291fc90"}, - {file = "cryptography-42.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2f9f14185962e6a04ab32d1abe34eae8a9001569ee4edb64d2304bf0d65c53f3"}, - {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:09a77e5b2e8ca732a19a90c5bca2d124621a1edb5438c5daa2d2738bfeb02589"}, - {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:ad28cff53f60d99a928dfcf1e861e0b2ceb2bc1f08a074fdd601b314e1cc9e0a"}, - {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:130c0f77022b2b9c99d8cebcdd834d81705f61c68e91ddd614ce74c657f8b3ea"}, - {file = "cryptography-42.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa3dec4ba8fb6e662770b74f62f1a0c7d4e37e25b58b2bf2c1be4c95372b4a33"}, - {file = "cryptography-42.0.2-cp39-abi3-win32.whl", hash = "sha256:3dbd37e14ce795b4af61b89b037d4bc157f2cb23e676fa16932185a04dfbf635"}, - {file = "cryptography-42.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:8a06641fb07d4e8f6c7dda4fc3f8871d327803ab6542e33831c7ccfdcb4d0ad6"}, - {file = "cryptography-42.0.2-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:087887e55e0b9c8724cf05361357875adb5c20dec27e5816b653492980d20380"}, - {file = "cryptography-42.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:a7ef8dd0bf2e1d0a27042b231a3baac6883cdd5557036f5e8df7139255feaac6"}, - {file = "cryptography-42.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4383b47f45b14459cab66048d384614019965ba6c1a1a141f11b5a551cace1b2"}, - {file = "cryptography-42.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:fbeb725c9dc799a574518109336acccaf1303c30d45c075c665c0793c2f79a7f"}, - {file = "cryptography-42.0.2-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:320948ab49883557a256eab46149df79435a22d2fefd6a66fe6946f1b9d9d008"}, - {file = "cryptography-42.0.2-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5ef9bc3d046ce83c4bbf4c25e1e0547b9c441c01d30922d812e887dc5f125c12"}, - {file = "cryptography-42.0.2-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:52ed9ebf8ac602385126c9a2fe951db36f2cb0c2538d22971487f89d0de4065a"}, - {file = "cryptography-42.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:141e2aa5ba100d3788c0ad7919b288f89d1fe015878b9659b307c9ef867d3a65"}, - {file = "cryptography-42.0.2.tar.gz", hash = "sha256:e0ec52ba3c7f1b7d813cd52649a5b3ef1fc0d433219dc8c93827c57eab6cf888"}, + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449"}, + {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b"}, + {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824"}, + {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b"}, + {file = "cryptography-42.0.4-cp37-abi3-win32.whl", hash = "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925"}, + {file = "cryptography-42.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923"}, + {file = "cryptography-42.0.4-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9"}, + {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929"}, + {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0"}, + {file = "cryptography-42.0.4-cp39-abi3-win32.whl", hash = "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129"}, + {file = "cryptography-42.0.4-cp39-abi3-win_amd64.whl", hash = "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f8907fcf57392cd917892ae83708761c6ff3c37a8e835d7246ff0ad251d9298"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:12d341bd42cdb7d4937b0cabbdf2a94f949413ac4504904d0cdbdce4a22cbf88"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1cdcdbd117681c88d717437ada72bdd5be9de117f96e3f4d50dab3f59fd9ab20"}, + {file = "cryptography-42.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0e89f7b84f421c56e7ff69f11c441ebda73b8a8e6488d322ef71746224c20fce"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f1e85a178384bf19e36779d91ff35c7617c885da487d689b05c1366f9933ad74"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d2a27aca5597c8a71abbe10209184e1a8e91c1fd470b5070a2ea60cafec35bcd"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4e36685cb634af55e0677d435d425043967ac2f3790ec652b2b88ad03b85c27b"}, + {file = "cryptography-42.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f47be41843200f7faec0683ad751e5ef11b9a56a220d57f300376cd8aba81660"}, + {file = "cryptography-42.0.4.tar.gz", hash = "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb"}, ] [package.dependencies] From 1da309d9b3dc61ac1d83884e177468cfa217b179 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:48:48 +0100 Subject: [PATCH 0141/2666] chore(deps-dev): bump httpx from 0.26.0 to 0.27.0 (#3828) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index c5177f001c1..d1db6d3924c 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1147,13 +1147,13 @@ trio = ["trio (>=0.22.0,<0.23.0)"] [[package]] name = "httpx" -version = "0.26.0" +version = "0.27.0" description = "The next generation HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpx-0.26.0-py3-none-any.whl", hash = "sha256:8915f5a3627c4d47b73e8202457cb28f1266982d1159bd5779d86a80c0eab1cd"}, - {file = "httpx-0.26.0.tar.gz", hash = "sha256:451b55c30d5185ea6b23c2c793abf9bb237d2a7dfb901ced6ff69ad37ec1dfaf"}, + {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, + {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, ] [package.dependencies] @@ -3441,4 +3441,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "69166703da187933336c2adb871526c2be6b410bffd4879d9b04336709a8144d" +content-hash = "b0ec65e9e8df6741a33ed6b9e1dd616d4ddc1e0e36f0a95408f3931723e93818" diff --git a/pyproject.toml b/pyproject.toml index 03973d68c40..e10d2d44d44 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,7 +113,7 @@ datamasking = ["aws-encryption-sdk", "jsonpath-ng"] cfn-lint = "0.85.2" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" -httpx = ">=0.23.3,<0.27.0" +httpx = ">=0.23.3,<0.28.0" sentry-sdk = "^1.22.2" ruff = ">=0.0.272,<0.2.3" retry2 = "^0.9.5" From 75b1639d400a95d4d4bf6c0fcf216f21bab78adf Mon Sep 17 00:00:00 2001 From: Nico Tonnhofer Date: Fri, 23 Feb 2024 12:07:31 +0100 Subject: [PATCH 0142/2666] fix(typing): ensure return type is a str when default_value is set (#3840) --- .../api_gateway_authorizer_event.py | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py b/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py index 32d933ecf27..0b1aec43e8a 100644 --- a/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py +++ b/aws_lambda_powertools/utilities/data_classes/api_gateway_authorizer_event.py @@ -1,6 +1,6 @@ import enum import re -from typing import Any, Dict, List, Optional +from typing import Any, Dict, List, Optional, overload from aws_lambda_powertools.utilities.data_classes.common import ( BaseRequestContext, @@ -162,6 +162,22 @@ def stage_variables(self) -> Dict[str, str]: def request_context(self) -> BaseRequestContext: return BaseRequestContext(self._data) + @overload + def get_header_value( + self, + name: str, + default_value: str, + case_sensitive: Optional[bool] = False, + ) -> str: ... + + @overload + def get_header_value( + self, + name: str, + default_value: Optional[str] = None, + case_sensitive: Optional[bool] = False, + ) -> Optional[str]: ... + def get_header_value( self, name: str, From 4cf85d07091ef65bafa60bd893a97263c1822d18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:11:54 +0100 Subject: [PATCH 0143/2666] chore(deps): bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates (#3844) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- layer/scripts/layer-balancer/go.mod | 22 +++++++-------- layer/scripts/layer-balancer/go.sum | 44 ++++++++++++++--------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/layer/scripts/layer-balancer/go.mod b/layer/scripts/layer-balancer/go.mod index 2fbc28ebab6..59a36641b67 100644 --- a/layer/scripts/layer-balancer/go.mod +++ b/layer/scripts/layer-balancer/go.mod @@ -3,25 +3,25 @@ module layerbalancer go 1.18 require ( - github.com/aws/aws-sdk-go-v2 v1.25.1 - github.com/aws/aws-sdk-go-v2/config v1.27.3 - github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0 + github.com/aws/aws-sdk-go-v2 v1.25.2 + github.com/aws/aws-sdk-go-v2/config v1.27.4 + github.com/aws/aws-sdk-go-v2/service/lambda v1.53.1 golang.org/x/exp v0.0.0-20230321023759-10a507213a29 golang.org/x/sync v0.6.0 ) require ( github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.17.3 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.17.4 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 // indirect github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 // indirect github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 // indirect github.com/aws/smithy-go v1.20.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect ) diff --git a/layer/scripts/layer-balancer/go.sum b/layer/scripts/layer-balancer/go.sum index df406c29c42..eba81ec995b 100644 --- a/layer/scripts/layer-balancer/go.sum +++ b/layer/scripts/layer-balancer/go.sum @@ -1,31 +1,31 @@ -github.com/aws/aws-sdk-go-v2 v1.25.1 h1:P7hU6A5qEdmajGwvae/zDkOq+ULLC9tQBTwqqiwFGpI= -github.com/aws/aws-sdk-go-v2 v1.25.1/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= +github.com/aws/aws-sdk-go-v2 v1.25.2 h1:/uiG1avJRgLGiQM9X3qJM8+Qa6KRGK5rRPuXE0HUM+w= +github.com/aws/aws-sdk-go-v2 v1.25.2/go.mod h1:Evoc5AsmtveRt1komDwIsjHFyrP5tDuF1D1U+6z6pNo= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1 h1:gTK2uhtAPtFcdRRJilZPx8uJLL2J85xK11nKtWL0wfU= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.1/go.mod h1:sxpLb+nZk7tIfCWChfd+h4QwHNUR57d8hA1cleTkjJo= -github.com/aws/aws-sdk-go-v2/config v1.27.3 h1:0PRdb/q5a77HVYj+2rvPiCObfMfl/pWhwa5cs3cnl3c= -github.com/aws/aws-sdk-go-v2/config v1.27.3/go.mod h1:WeRAr9ENap9NAegbfNsLqGQd8ERz5ypdIUx4j0/ZgKI= -github.com/aws/aws-sdk-go-v2/credentials v1.17.3 h1:dDM5wrgwOL5gTZ0Gv/bvewPldjBcJywoaO5ClERrOGE= -github.com/aws/aws-sdk-go-v2/credentials v1.17.3/go.mod h1:G96Nuaw9qJS+s3OnK8RW8VEKEOjXi8H5Jk4lC/ZyZbw= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1 h1:lk1ZZFbdb24qpOwVC1AwYNrswUjAxeyey6kFBVANudQ= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.1/go.mod h1:/xJ6x1NehNGCX4tvGzzj2bq5TBOT/Yxq+qbL9Jpx2Vk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1 h1:evvi7FbTAoFxdP/mixmP7LIYzQWAmzBcwNB/es9XPNc= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.1/go.mod h1:rH61DT6FDdikhPghymripNUCsf+uVF4Cnk4c4DBKH64= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1 h1:RAnaIrbxPtlXNVI/OIlh1sidTQ3e1qM6LRjs7N0bE0I= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.1/go.mod h1:nbgAGkH5lk0RZRMh6A4K/oG6Xj11eC/1CyDow+DUAFI= +github.com/aws/aws-sdk-go-v2/config v1.27.4 h1:AhfWb5ZwimdsYTgP7Od8E9L1u4sKmDW2ZVeLcf2O42M= +github.com/aws/aws-sdk-go-v2/config v1.27.4/go.mod h1:zq2FFXK3A416kiukwpsd+rD4ny6JC7QSkp4QdN1Mp2g= +github.com/aws/aws-sdk-go-v2/credentials v1.17.4 h1:h5Vztbd8qLppiPwX+y0Q6WiwMZgpd9keKe2EAENgAuI= +github.com/aws/aws-sdk-go-v2/credentials v1.17.4/go.mod h1:+30tpwrkOgvkJL1rUZuRLoxcJwtI/OkeBLYnHxJtVe0= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2 h1:AK0J8iYBFeUk2Ax7O8YpLtFsfhdOByh2QIkHmigpRYk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.15.2/go.mod h1:iRlGzMix0SExQEviAyptRWRGdYNo3+ufW/lCzvKVTUc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2 h1:bNo4LagzUKbjdxE0tIcR9pMzLR2U/Tgie1Hq1HQ3iH8= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.2/go.mod h1:wRQv0nN6v9wDXuWThpovGQjqF1HFdcgWjporw14lS8k= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2 h1:EtOU5jsPdIQNP+6Q2C5e3d65NKT1PeCiQk+9OdzO12Q= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.2/go.mod h1:tyF5sKccmDz0Bv4NrstEr+/9YkSPJHrcO7UsUKf7pWM= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1 h1:cVP8mng1RjDyI3JN/AXFCn5FHNlsBaBH0/MBtG1bg0o= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.1/go.mod h1:C8sQjoyAsdfjC7hpy4+S6B92hnFzx0d0UAyHicaOTIE= -github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0 h1:EPsyL8kIjSQnShTQXZIWYTPVWSgWpG7ZtQRoJuqqf6Y= -github.com/aws/aws-sdk-go-v2/service/lambda v1.53.0/go.mod h1:4eq2dibHpzftx3fHVaHLjw7ab/DlUM2GddPb0Vxg7+8= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.0 h1:6YL8G91QZ52KlPrLkEgEez5kejIVwChVCgND3qgY5j0= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.0/go.mod h1:x6/tCd1o/AOKQR+iYnjrzhJxD+w0xRN34asGPaSV7ew= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0 h1:+DqIa5Ll7W311QLUvGFDdVit9uC4G0VioDdw08cXcow= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.0/go.mod h1:lZB123q0SVQ3dfIbEOcGzhQHrwVBcHVReNS9tm20oU4= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.0 h1:F7tQr61zYnTaeY50Rn4jwfVQbtcqJuBRwN/nGGNwzb0= -github.com/aws/aws-sdk-go-v2/service/sts v1.28.0/go.mod h1:ozhhG9/NB5c9jcmhGq6tX9dpp21LYdmRWRQVppASim4= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2 h1:5ffmXjPtwRExp1zc7gENLgCPyHFbhEPwVTkTiH9niSk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.2/go.mod h1:Ru7vg1iQ7cR4i7SZ/JTLYN9kaXtbL69UdgG0OQWQxW0= +github.com/aws/aws-sdk-go-v2/service/lambda v1.53.1 h1:UP4ijiKqXUneKAHGd5Z8AnuFadzXwzasUXmrUyY/Lx0= +github.com/aws/aws-sdk-go-v2/service/lambda v1.53.1/go.mod h1:j7LmUBmzv17DtxTqO7DQ/HTnyfFB9ouspZo5C9WWxzk= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.1 h1:utEGkfdQ4L6YW/ietH7111ZYglLJvS+sLriHJ1NBJEQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.20.1/go.mod h1:RsYqzYr2F2oPDdpy+PdhephuZxTfjHQe7SOBcZGoAU8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1 h1:9/GylMS45hGGFCcMrUZDVayQE1jYSIN6da9jo7RAYIw= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.1/go.mod h1:YjAPFn4kGFqKC54VsHs5fn5B6d+PCY2tziEa3U/GB5Y= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.1 h1:3I2cBEYgKhrWlwyZgfpSO2BpaMY1LHPqXYk/QGlu2ew= +github.com/aws/aws-sdk-go-v2/service/sts v1.28.1/go.mod h1:uQ7YYKZt3adCRrdCBREm1CD3efFLOUNH77MrUCvx5oA= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= From 52d46caa0e8d210b7902d06f6321e75f511d917f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:12:26 +0100 Subject: [PATCH 0144/2666] chore(deps): bump codecov/codecov-action from 4.0.1 to 4.0.2 (#3842) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/quality_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index fe5616711c6..8332bdb0ae0 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@e0b68c6749509c5f83f984dd99a76a1c1a231044 # 4.0.1 + uses: codecov/codecov-action@0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1 # 4.0.2 with: file: ./coverage.xml env_vars: PYTHON From c3cc8a07c856b89e5dce42b02a162975b1509ee5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:12:37 +0100 Subject: [PATCH 0145/2666] chore(deps-dev): bump aws-cdk from 2.129.0 to 2.130.0 (#3843) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 8 ++++---- package.json | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 48be10df3dc..a57b4eb6603 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,13 +11,13 @@ "package-lock.json": "^1.0.0" }, "devDependencies": { - "aws-cdk": "^2.129.0" + "aws-cdk": "^2.130.0" } }, "node_modules/aws-cdk": { - "version": "2.129.0", - "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.129.0.tgz", - "integrity": "sha512-Gh/dG2aY0cvlLumYUXalg28/knVI/TrN6NZMBpRWe4gGJe/RH5JROIVB2GOEMMajkew9EiFH0ZeoC+pQ57diaQ==", + "version": "2.130.0", + "resolved": "https://registry.npmjs.org/aws-cdk/-/aws-cdk-2.130.0.tgz", + "integrity": "sha512-MsjGzQ2kZv0FEfXvpW7FTJRnefew0GrYt9M2SMN2Yn45+yjugGl2X8to416kABeFz1OFqW56hq8Y5BiLuFDVLQ==", "dev": true, "bin": { "cdk": "bin/cdk" diff --git a/package.json b/package.json index b98f638c991..f89a748346b 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "aws-lambda-powertools-python-e2e", "version": "1.0.0", "devDependencies": { - "aws-cdk": "^2.129.0" + "aws-cdk": "^2.130.0" }, "dependencies": { "package-lock.json": "^1.0.0" From 5b1ead90f769f89eee5bec0412728f91e7dc2fd1 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 09:12:49 +0100 Subject: [PATCH 0146/2666] chore(ci): changelog rebuild (#3851) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 15c830b4184..8c33f4b0382 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,22 @@ # Unreleased +## Bug Fixes + +* **typing:** ensure return type is a str when default_value is set ([#3840](https://github.com/aws-powertools/powertools-lambda-python/issues/3840)) + ## Documentation * **install:** make minimum install the default option then extra ([#3834](https://github.com/aws-powertools/powertools-lambda-python/issues/3834)) ## Maintenance +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3835](https://github.com/aws-powertools/powertools-lambda-python/issues/3835)) +* **deps:** bump cryptography from 42.0.2 to 42.0.4 ([#3827](https://github.com/aws-powertools/powertools-lambda-python/issues/3827)) +* **deps-dev:** bump httpx from 0.26.0 to 0.27.0 ([#3828](https://github.com/aws-powertools/powertools-lambda-python/issues/3828)) +* **deps-dev:** bump aws-cdk from 2.128.0 to 2.129.0 ([#3831](https://github.com/aws-powertools/powertools-lambda-python/issues/3831)) +* **deps-dev:** bump the boto-typing group with 1 update ([#3836](https://github.com/aws-powertools/powertools-lambda-python/issues/3836)) +* **deps-dev:** bump aws-cdk-lib from 2.128.0 to 2.130.0 ([#3838](https://github.com/aws-powertools/powertools-lambda-python/issues/3838)) From 9cd21aa4edebf013526bd8787a79388cda3469d6 Mon Sep 17 00:00:00 2001 From: Tony Sherman <100969281+TonySherman@users.noreply.github.com> Date: Mon, 26 Feb 2024 07:14:05 -0500 Subject: [PATCH 0147/2666] feat(event-source): add function to get multi-value query string params by name (#3846) Co-authored-by: Heitor Lessa Co-authored-by: heitorlessa --- .../utilities/data_classes/alb_event.py | 4 +-- .../utilities/data_classes/common.py | 30 ++++++++++++++++++ .../data_classes/shared_functions.py | 31 +++++++++++++++++-- .../src/accessing_request_details.py | 5 ++- tests/unit/data_classes/test_alb_event.py | 4 ++- tests/unit/test_data_classes.py | 19 ++++++++++++ 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/aws_lambda_powertools/utilities/data_classes/alb_event.py b/aws_lambda_powertools/utilities/data_classes/alb_event.py index 1ec2535850b..a1ee3424a94 100644 --- a/aws_lambda_powertools/utilities/data_classes/alb_event.py +++ b/aws_lambda_powertools/utilities/data_classes/alb_event.py @@ -32,8 +32,8 @@ def request_context(self) -> ALBEventRequestContext: return ALBEventRequestContext(self._data) @property - def multi_value_query_string_parameters(self) -> Optional[Dict[str, List[str]]]: - return self.get("multiValueQueryStringParameters") + def multi_value_query_string_parameters(self) -> Dict[str, List[str]]: + return self.get("multiValueQueryStringParameters") or {} @property def resolved_query_string_parameters(self) -> Dict[str, List[str]]: diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 067706140fd..41fbe5cd0de 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -7,6 +7,7 @@ from aws_lambda_powertools.shared.headers_serializer import BaseHeadersSerializer from aws_lambda_powertools.utilities.data_classes.shared_functions import ( get_header_value, + get_multi_value_query_string_values, get_query_string_value, ) @@ -103,6 +104,10 @@ def headers(self) -> Dict[str, str]: def query_string_parameters(self) -> Optional[Dict[str, str]]: return self.get("queryStringParameters") + @property + def multi_value_query_string_parameters(self) -> Dict[str, List[str]]: + return self.get("multiValueQueryStringParameters") or {} + @property def resolved_query_string_parameters(self) -> Dict[str, List[str]]: """ @@ -184,6 +189,31 @@ def get_query_string_value(self, name: str, default_value: Optional[str] = None) default_value=default_value, ) + def get_multi_value_query_string_values( + self, + name: str, + default_values: Optional[List[str]] = None, + ) ->List[str]: + """Get multi-value query string parameter values by name + + Parameters + ---------- + name: str + Multi-Value query string parameter name + default_values: List[str], optional + Default values is no values are found by name + Returns + ------- + List[str], optional + List of query string values + + """ + return get_multi_value_query_string_values( + multi_value_query_string_parameters=self.multi_value_query_string_parameters, + name=name, + default_values=default_values, + ) + @overload def get_header_value( self, diff --git a/aws_lambda_powertools/utilities/data_classes/shared_functions.py b/aws_lambda_powertools/utilities/data_classes/shared_functions.py index 594ea35bea7..43a3aad281b 100644 --- a/aws_lambda_powertools/utilities/data_classes/shared_functions.py +++ b/aws_lambda_powertools/utilities/data_classes/shared_functions.py @@ -1,7 +1,7 @@ from __future__ import annotations import base64 -from typing import Any +from typing import Any, Dict def base64_decode(value: str) -> str: @@ -63,7 +63,7 @@ def get_header_value( def get_query_string_value( - query_string_parameters: dict[str, str] | None, + query_string_parameters: Dict[str, str] | None, name: str, default_value: str | None = None, ) -> str | None: @@ -84,3 +84,30 @@ def get_query_string_value( """ params = query_string_parameters return default_value if params is None else params.get(name, default_value) + + +def get_multi_value_query_string_values( + multi_value_query_string_parameters: Dict[str, list[str]] | None, + name: str, + default_values: list[str] | None = None, +) -> list[str]: + """ + Retrieves the values of a multi-value string parameters specified by the given name. + + Parameters + ---------- + name: str + The name of the query string parameter to retrieve. + default_value: list[str], optional + The default value to return if the parameter is not found. Defaults to None. + + Returns + ------- + List[str]. optional + The values of the query string parameter if found, or the default values if not found. + """ + + default = default_values or [] + params = multi_value_query_string_parameters or {} + + return params.get(name) or default diff --git a/examples/event_handler_rest/src/accessing_request_details.py b/examples/event_handler_rest/src/accessing_request_details.py index 9929b601db0..037b76daa66 100644 --- a/examples/event_handler_rest/src/accessing_request_details.py +++ b/examples/event_handler_rest/src/accessing_request_details.py @@ -1,4 +1,4 @@ -from typing import Optional +from typing import List, Optional import requests from requests import Response @@ -20,6 +20,9 @@ def get_todos(): # alternatively _: Optional[str] = app.current_event.query_string_parameters.get("id") + # or multi-value query string parameters; ?category="red"&?category="blue" + _: List[str] = app.current_event.get_multi_value_query_string_values(name="category") + # Payload _: Optional[str] = app.current_event.body # raw str | None diff --git a/tests/unit/data_classes/test_alb_event.py b/tests/unit/data_classes/test_alb_event.py index c55af8e91ef..47048ab9407 100644 --- a/tests/unit/data_classes/test_alb_event.py +++ b/tests/unit/data_classes/test_alb_event.py @@ -11,7 +11,9 @@ def test_alb_event(): assert parsed_event.path == raw_event["path"] assert parsed_event.query_string_parameters == raw_event["queryStringParameters"] assert parsed_event.headers == raw_event["headers"] - assert parsed_event.multi_value_query_string_parameters == raw_event.get("multiValueQueryStringParameters") + + assert parsed_event.multi_value_query_string_parameters == raw_event.get("multiValueQueryStringParameters", {}) + assert parsed_event.multi_value_headers == raw_event.get("multiValueHeaders") assert parsed_event.body == raw_event["body"] assert parsed_event.is_base64_encoded == raw_event["isBase64Encoded"] diff --git a/tests/unit/test_data_classes.py b/tests/unit/test_data_classes.py index c810f653f5b..c8f0c1fc932 100644 --- a/tests/unit/test_data_classes.py +++ b/tests/unit/test_data_classes.py @@ -259,6 +259,25 @@ def test_base_proxy_event_get_query_string_value(): assert value is None +def test_base_proxy_event_get_multi_value_query_string_values(): + default_values = ["default_1", "default_2"] + set_values = ["value_1", "value_2"] + + event = BaseProxyEvent({}) + values = event.get_multi_value_query_string_values("test", default_values) + assert values == default_values + + event._data["multiValueQueryStringParameters"] = {"test": set_values} + values = event.get_multi_value_query_string_values("test", default_values) + assert values == set_values + + values = event.get_multi_value_query_string_values("unknown", default_values) + assert values == default_values + + values = event.get_multi_value_query_string_values("unknown") + assert values == [] + + def test_base_proxy_event_get_header_value(): default_value = "default" set_value = "value" From 7e820114505b9fc8d7cde4954dd85f06294ddfa4 Mon Sep 17 00:00:00 2001 From: Leandro Damascena Date: Mon, 26 Feb 2024 10:27:56 -0300 Subject: [PATCH 0148/2666] chore(ci): remove aws-encryption-sdk from Lambda layer due to cffi being tied to python version (#3853) Co-authored-by: Cavalcante Damascena --- Makefile | 4 +- docs/utilities/data_masking.md | 2 +- poetry.lock | 715 +++++++++--------- pyproject.toml | 2 - .../utils/lambda_layer/powertools_layer.py | 2 +- 5 files changed, 357 insertions(+), 368 deletions(-) diff --git a/Makefile b/Makefile index 7fa170b28c6..2c5c3223509 100644 --- a/Makefile +++ b/Makefile @@ -8,13 +8,13 @@ dev: pip install --upgrade pip pre-commit poetry poetry config --local virtualenvs.in-project true @$(MAKE) dev-version-plugin - poetry install --extras "all redis" + poetry install --extras "all redis datamasking" pre-commit install dev-gitpod: pip install --upgrade pip poetry @$(MAKE) dev-version-plugin - poetry install --extras "all redis" + poetry install --extras "all redis datamasking" pre-commit install format: diff --git a/docs/utilities/data_masking.md b/docs/utilities/data_masking.md index 5c30edc6bff..b44847a3a2f 100644 --- a/docs/utilities/data_masking.md +++ b/docs/utilities/data_masking.md @@ -73,7 +73,7 @@ graph LR ### Install -!!! note "This is not necessary if you're installing Powertools for AWS Lambda (Python) via [Lambda Layer/SAR](../index.md#lambda-layer){target="_blank"}" +!!! info "Our Lambda layer does not include the aws-encryption-sdk. Please install it as a dependency in your project to use this utility." Add `aws-lambda-powertools[datamasking]` as a dependency in your preferred tool: _e.g._, _requirements.txt_, _pyproject.toml_. This will install the [AWS Encryption SDK](https://docs.aws.amazon.com/encryption-sdk/latest/developer-guide/introduction.html){target="_blank"}. diff --git a/poetry.lock b/poetry.lock index d1db6d3924c..678896ba721 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,14 +1,14 @@ -# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. [[package]] name = "anyio" -version = "4.2.0" +version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" optional = false python-versions = ">=3.8" files = [ - {file = "anyio-4.2.0-py3-none-any.whl", hash = "sha256:745843b39e829e108e518c489b31dc757de7d2131d53fac32bd8df268227bfee"}, - {file = "anyio-4.2.0.tar.gz", hash = "sha256:e1875bb4b4e2de1669f4bc7869b6d3f54231cdced71605e6e64c9be77e3be50f"}, + {file = "anyio-4.3.0-py3-none-any.whl", hash = "sha256:048e05d0f6caeed70d731f3db756d35dcc1f35747c8c403364a8332c630441b8"}, + {file = "anyio-4.3.0.tar.gz", hash = "sha256:f75253795a87df48568485fd18cdd2a3fa5c4f7c5be8e5e36637733fce06fed6"}, ] [package.dependencies] @@ -209,13 +209,13 @@ requests = ">=0.14.0" [[package]] name = "aws-sam-translator" -version = "1.84.0" +version = "1.85.0" description = "AWS SAM Translator is a library that transform SAM templates into AWS CloudFormation templates" optional = false python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "aws-sam-translator-1.84.0.tar.gz", hash = "sha256:dbfd5669b5ef4bd7bc7af4775eec2ce4db61a2c2a17d721e67b51cf6a6dd63f9"}, - {file = "aws_sam_translator-1.84.0-py3-none-any.whl", hash = "sha256:a24f43e80095c79258a1f1c7a0b8169f55daf0b2bc237d5b9010b02ba86fa3bb"}, + {file = "aws-sam-translator-1.85.0.tar.gz", hash = "sha256:e41938affa128fb5bde5e1989b260bf539a96369bba3faf316ce66651351df39"}, + {file = "aws_sam_translator-1.85.0-py3-none-any.whl", hash = "sha256:e8c69a4db7279421ff6c3579cd4d43395fe9b6781f50416528e984be68e25481"}, ] [package.dependencies] @@ -284,33 +284,33 @@ yaml = ["PyYAML"] [[package]] name = "black" -version = "24.1.1" +version = "24.2.0" description = "The uncompromising code formatter." optional = false python-versions = ">=3.8" files = [ - {file = "black-24.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2588021038bd5ada078de606f2a804cadd0a3cc6a79cb3e9bb3a8bf581325a4c"}, - {file = "black-24.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1a95915c98d6e32ca43809d46d932e2abc5f1f7d582ffbe65a5b4d1588af7445"}, - {file = "black-24.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fa6a0e965779c8f2afb286f9ef798df770ba2b6cee063c650b96adec22c056a"}, - {file = "black-24.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:5242ecd9e990aeb995b6d03dc3b2d112d4a78f2083e5a8e86d566340ae80fec4"}, - {file = "black-24.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fc1ec9aa6f4d98d022101e015261c056ddebe3da6a8ccfc2c792cbe0349d48b7"}, - {file = "black-24.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0269dfdea12442022e88043d2910429bed717b2d04523867a85dacce535916b8"}, - {file = "black-24.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3d64db762eae4a5ce04b6e3dd745dcca0fb9560eb931a5be97472e38652a161"}, - {file = "black-24.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:5d7b06ea8816cbd4becfe5f70accae953c53c0e53aa98730ceccb0395520ee5d"}, - {file = "black-24.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e2c8dfa14677f90d976f68e0c923947ae68fa3961d61ee30976c388adc0b02c8"}, - {file = "black-24.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a21725862d0e855ae05da1dd25e3825ed712eaaccef6b03017fe0853a01aa45e"}, - {file = "black-24.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07204d078e25327aad9ed2c64790d681238686bce254c910de640c7cc4fc3aa6"}, - {file = "black-24.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a83fe522d9698d8f9a101b860b1ee154c1d25f8a82ceb807d319f085b2627c5b"}, - {file = "black-24.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:08b34e85170d368c37ca7bf81cf67ac863c9d1963b2c1780c39102187ec8dd62"}, - {file = "black-24.1.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7258c27115c1e3b5de9ac6c4f9957e3ee2c02c0b39222a24dc7aa03ba0e986f5"}, - {file = "black-24.1.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40657e1b78212d582a0edecafef133cf1dd02e6677f539b669db4746150d38f6"}, - {file = "black-24.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e298d588744efda02379521a19639ebcd314fba7a49be22136204d7ed1782717"}, - {file = "black-24.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34afe9da5056aa123b8bfda1664bfe6fb4e9c6f311d8e4a6eb089da9a9173bf9"}, - {file = "black-24.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:854c06fb86fd854140f37fb24dbf10621f5dab9e3b0c29a690ba595e3d543024"}, - {file = "black-24.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3897ae5a21ca132efa219c029cce5e6bfc9c3d34ed7e892113d199c0b1b444a2"}, - {file = "black-24.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:ecba2a15dfb2d97105be74bbfe5128bc5e9fa8477d8c46766505c1dda5883aac"}, - {file = "black-24.1.1-py3-none-any.whl", hash = "sha256:5cdc2e2195212208fbcae579b931407c1fa9997584f0a415421748aeafff1168"}, - {file = "black-24.1.1.tar.gz", hash = "sha256:48b5760dcbfe5cf97fd4fba23946681f3a81514c6ab8a45b50da67ac8fbc6c7b"}, + {file = "black-24.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6981eae48b3b33399c8757036c7f5d48a535b962a7c2310d19361edeef64ce29"}, + {file = "black-24.2.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d533d5e3259720fdbc1b37444491b024003e012c5173f7d06825a77508085430"}, + {file = "black-24.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61a0391772490ddfb8a693c067df1ef5227257e72b0e4108482b8d41b5aee13f"}, + {file = "black-24.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:992e451b04667116680cb88f63449267c13e1ad134f30087dec8527242e9862a"}, + {file = "black-24.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:163baf4ef40e6897a2a9b83890e59141cc8c2a98f2dda5080dc15c00ee1e62cd"}, + {file = "black-24.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e37c99f89929af50ffaf912454b3e3b47fd64109659026b678c091a4cd450fb2"}, + {file = "black-24.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f9de21bafcba9683853f6c96c2d515e364aee631b178eaa5145fc1c61a3cc92"}, + {file = "black-24.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:9db528bccb9e8e20c08e716b3b09c6bdd64da0dd129b11e160bf082d4642ac23"}, + {file = "black-24.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d84f29eb3ee44859052073b7636533ec995bd0f64e2fb43aeceefc70090e752b"}, + {file = "black-24.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e08fb9a15c914b81dd734ddd7fb10513016e5ce7e6704bdd5e1251ceee51ac9"}, + {file = "black-24.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:810d445ae6069ce64030c78ff6127cd9cd178a9ac3361435708b907d8a04c693"}, + {file = "black-24.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ba15742a13de85e9b8f3239c8f807723991fbfae24bad92d34a2b12e81904982"}, + {file = "black-24.2.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e53a8c630f71db01b28cd9602a1ada68c937cbf2c333e6ed041390d6968faf4"}, + {file = "black-24.2.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:93601c2deb321b4bad8f95df408e3fb3943d85012dddb6121336b8e24a0d1218"}, + {file = "black-24.2.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0057f800de6acc4407fe75bb147b0c2b5cbb7c3ed110d3e5999cd01184d53b0"}, + {file = "black-24.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:faf2ee02e6612577ba0181f4347bcbcf591eb122f7841ae5ba233d12c39dcb4d"}, + {file = "black-24.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:057c3dc602eaa6fdc451069bd027a1b2635028b575a6c3acfd63193ced20d9c8"}, + {file = "black-24.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:08654d0797e65f2423f850fc8e16a0ce50925f9337fb4a4a176a7aa4026e63f8"}, + {file = "black-24.2.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ca610d29415ee1a30a3f30fab7a8f4144e9d34c89a235d81292a1edb2b55f540"}, + {file = "black-24.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:4dd76e9468d5536abd40ffbc7a247f83b2324f0c050556d9c371c2b9a9a95e31"}, + {file = "black-24.2.0-py3-none-any.whl", hash = "sha256:e8a6ae970537e67830776488bca52000eaa37fa63b9988e8c487458d9cd5ace6"}, + {file = "black-24.2.0.tar.gz", hash = "sha256:bce4f25c27c3435e4dace4815bcb2008b87e167e3bf4ee47ccdc5ce906eb4894"}, ] [package.dependencies] @@ -330,17 +330,17 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.34.36" +version = "1.34.49" description = "The AWS SDK for Python" optional = false python-versions = ">= 3.8" files = [ - {file = "boto3-1.34.36-py3-none-any.whl", hash = "sha256:1e38a4ea4bb8bc66fbb858abb411820709fda5d6c5604c2da0f696653d49c684"}, - {file = "boto3-1.34.36.tar.gz", hash = "sha256:7ec36deb7ccc9c4943510692303cf93883ef61dc2c79f8bd4d75ee42209559d3"}, + {file = "boto3-1.34.49-py3-none-any.whl", hash = "sha256:ce8d1de03024f52a1810e8d71ad4dba3a5b9bb48b35567191500e3432a9130b4"}, + {file = "boto3-1.34.49.tar.gz", hash = "sha256:96b9dc85ce8d52619b56ca7b1ac1423eaf0af5ce132904bcc8aa81396eec2abf"}, ] [package.dependencies] -botocore = ">=1.34.36,<1.35.0" +botocore = ">=1.34.49,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -349,13 +349,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.36" +version = "1.34.49" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">= 3.8" files = [ - {file = "botocore-1.34.36-py3-none-any.whl", hash = "sha256:3f39ae0165f1a27f621fc91a46fb59f87e819671fad106c230dadcc724892f70"}, - {file = "botocore-1.34.36.tar.gz", hash = "sha256:89c3dc15b6ffae146029df636d51b9952740051204c444ec765286b081c917bc"}, + {file = "botocore-1.34.49-py3-none-any.whl", hash = "sha256:4ed9d7603a04b5bb5bd5de63b513bc2c8a7e8b1cd0088229c5ceb461161f43b6"}, + {file = "botocore-1.34.49.tar.gz", hash = "sha256:d89410bc60673eaff1699f3f1fdcb0e3a5e1f7a6a048c0d88c3ce5c3549433ec"}, ] [package.dependencies] @@ -659,63 +659,63 @@ typeguard = ">=2.13.3,<2.14.0" [[package]] name = "coverage" -version = "7.4.2" +version = "7.4.3" description = "Code coverage measurement for Python" optional = false python-versions = ">=3.8" files = [ - {file = "coverage-7.4.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bf54c3e089179d9d23900e3efc86d46e4431188d9a657f345410eecdd0151f50"}, - {file = "coverage-7.4.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fe6e43c8b510719b48af7db9631b5fbac910ade4bd90e6378c85ac5ac706382c"}, - {file = "coverage-7.4.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b98c89db1b150d851a7840142d60d01d07677a18f0f46836e691c38134ed18b"}, - {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5f9683be6a5b19cd776ee4e2f2ffb411424819c69afab6b2db3a0a364ec6642"}, - {file = "coverage-7.4.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78cdcbf7b9cb83fe047ee09298e25b1cd1636824067166dc97ad0543b079d22f"}, - {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:2599972b21911111114100d362aea9e70a88b258400672626efa2b9e2179609c"}, - {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ef00d31b7569ed3cb2036f26565f1984b9fc08541731ce01012b02a4c238bf03"}, - {file = "coverage-7.4.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:20a875bfd8c282985c4720c32aa05056f77a68e6d8bbc5fe8632c5860ee0b49b"}, - {file = "coverage-7.4.2-cp310-cp310-win32.whl", hash = "sha256:b3f2b1eb229f23c82898eedfc3296137cf1f16bb145ceab3edfd17cbde273fb7"}, - {file = "coverage-7.4.2-cp310-cp310-win_amd64.whl", hash = "sha256:7df95fdd1432a5d2675ce630fef5f239939e2b3610fe2f2b5bf21fa505256fa3"}, - {file = "coverage-7.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a8ddbd158e069dded57738ea69b9744525181e99974c899b39f75b2b29a624e2"}, - {file = "coverage-7.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:81a5fb41b0d24447a47543b749adc34d45a2cf77b48ca74e5bf3de60a7bd9edc"}, - {file = "coverage-7.4.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2412e98e70f16243be41d20836abd5f3f32edef07cbf8f407f1b6e1ceae783ac"}, - {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ddb79414c15c6f03f56cc68fa06994f047cf20207c31b5dad3f6bab54a0f66ef"}, - {file = "coverage-7.4.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf89ab85027427d351f1de918aff4b43f4eb5f33aff6835ed30322a86ac29c9e"}, - {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a178b7b1ac0f1530bb28d2e51f88c0bab3e5949835851a60dda80bff6052510c"}, - {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:06fe398145a2e91edaf1ab4eee66149c6776c6b25b136f4a86fcbbb09512fd10"}, - {file = "coverage-7.4.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:18cac867950943fe93d6cd56a67eb7dcd2d4a781a40f4c1e25d6f1ed98721a55"}, - {file = "coverage-7.4.2-cp311-cp311-win32.whl", hash = "sha256:f72cdd2586f9a769570d4b5714a3837b3a59a53b096bb954f1811f6a0afad305"}, - {file = "coverage-7.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:d779a48fac416387dd5673fc5b2d6bd903ed903faaa3247dc1865c65eaa5a93e"}, - {file = "coverage-7.4.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:adbdfcda2469d188d79771d5696dc54fab98a16d2ef7e0875013b5f56a251047"}, - {file = "coverage-7.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ac4bab32f396b03ebecfcf2971668da9275b3bb5f81b3b6ba96622f4ef3f6e17"}, - {file = "coverage-7.4.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:006d220ba2e1a45f1de083d5022d4955abb0aedd78904cd5a779b955b019ec73"}, - {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3733545eb294e5ad274abe131d1e7e7de4ba17a144505c12feca48803fea5f64"}, - {file = "coverage-7.4.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:42a9e754aa250fe61f0f99986399cec086d7e7a01dd82fd863a20af34cbce962"}, - {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:2ed37e16cf35c8d6e0b430254574b8edd242a367a1b1531bd1adc99c6a5e00fe"}, - {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:b953275d4edfab6cc0ed7139fa773dfb89e81fee1569a932f6020ce7c6da0e8f"}, - {file = "coverage-7.4.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:32b4ab7e6c924f945cbae5392832e93e4ceb81483fd6dc4aa8fb1a97b9d3e0e1"}, - {file = "coverage-7.4.2-cp312-cp312-win32.whl", hash = "sha256:f5df76c58977bc35a49515b2fbba84a1d952ff0ec784a4070334dfbec28a2def"}, - {file = "coverage-7.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:34423abbaad70fea9d0164add189eabaea679068ebdf693baa5c02d03e7db244"}, - {file = "coverage-7.4.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:5b11f9c6587668e495cc7365f85c93bed34c3a81f9f08b0920b87a89acc13469"}, - {file = "coverage-7.4.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:51593a1f05c39332f623d64d910445fdec3d2ac2d96b37ce7f331882d5678ddf"}, - {file = "coverage-7.4.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69f1665165ba2fe7614e2f0c1aed71e14d83510bf67e2ee13df467d1c08bf1e8"}, - {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3c8bbb95a699c80a167478478efe5e09ad31680931ec280bf2087905e3b95ec"}, - {file = "coverage-7.4.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:175f56572f25e1e1201d2b3e07b71ca4d201bf0b9cb8fad3f1dfae6a4188de86"}, - {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:8562ca91e8c40864942615b1d0b12289d3e745e6b2da901d133f52f2d510a1e3"}, - {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:d9a1ef0f173e1a19738f154fb3644f90d0ada56fe6c9b422f992b04266c55d5a"}, - {file = "coverage-7.4.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:f40ac873045db4fd98a6f40387d242bde2708a3f8167bd967ccd43ad46394ba2"}, - {file = "coverage-7.4.2-cp38-cp38-win32.whl", hash = "sha256:d1b750a8409bec61caa7824bfd64a8074b6d2d420433f64c161a8335796c7c6b"}, - {file = "coverage-7.4.2-cp38-cp38-win_amd64.whl", hash = "sha256:b4ae777bebaed89e3a7e80c4a03fac434a98a8abb5251b2a957d38fe3fd30088"}, - {file = "coverage-7.4.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3ff7f92ae5a456101ca8f48387fd3c56eb96353588e686286f50633a611afc95"}, - {file = "coverage-7.4.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:861d75402269ffda0b33af94694b8e0703563116b04c681b1832903fac8fd647"}, - {file = "coverage-7.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3507427d83fa961cbd73f11140f4a5ce84208d31756f7238d6257b2d3d868405"}, - {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf711d517e21fb5bc429f5c4308fbc430a8585ff2a43e88540264ae87871e36a"}, - {file = "coverage-7.4.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c00e54f0bd258ab25e7f731ca1d5144b0bf7bec0051abccd2bdcff65fa3262c9"}, - {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f8e845d894e39fb53834da826078f6dc1a933b32b1478cf437007367efaf6f6a"}, - {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:840456cb1067dc350af9080298c7c2cfdddcedc1cb1e0b30dceecdaf7be1a2d3"}, - {file = "coverage-7.4.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c11ca2df2206a4e3e4c4567f52594637392ed05d7c7fb73b4ea1c658ba560265"}, - {file = "coverage-7.4.2-cp39-cp39-win32.whl", hash = "sha256:3ff5bdb08d8938d336ce4088ca1a1e4b6c8cd3bef8bb3a4c0eb2f37406e49643"}, - {file = "coverage-7.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:ac9e95cefcf044c98d4e2c829cd0669918585755dd9a92e28a1a7012322d0a95"}, - {file = "coverage-7.4.2-pp38.pp39.pp310-none-any.whl", hash = "sha256:f593a4a90118d99014517c2679e04a4ef5aee2d81aa05c26c734d271065efcb6"}, - {file = "coverage-7.4.2.tar.gz", hash = "sha256:1a5ee18e3a8d766075ce9314ed1cb695414bae67df6a4b0805f5137d93d6f1cb"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8580b827d4746d47294c0e0b92854c85a92c2227927433998f0d3320ae8a71b6"}, + {file = "coverage-7.4.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:718187eeb9849fc6cc23e0d9b092bc2348821c5e1a901c9f8975df0bc785bfd4"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:767b35c3a246bcb55b8044fd3a43b8cd553dd1f9f2c1eeb87a302b1f8daa0524"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ae7f19afe0cce50039e2c782bff379c7e347cba335429678450b8fe81c4ef96d"}, + {file = "coverage-7.4.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba3a8aaed13770e970b3df46980cb068d1c24af1a1968b7818b69af8c4347efb"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:ee866acc0861caebb4f2ab79f0b94dbfbdbfadc19f82e6e9c93930f74e11d7a0"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:506edb1dd49e13a2d4cac6a5173317b82a23c9d6e8df63efb4f0380de0fbccbc"}, + {file = "coverage-7.4.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fd6545d97c98a192c5ac995d21c894b581f1fd14cf389be90724d21808b657e2"}, + {file = "coverage-7.4.3-cp310-cp310-win32.whl", hash = "sha256:f6a09b360d67e589236a44f0c39218a8efba2593b6abdccc300a8862cffc2f94"}, + {file = "coverage-7.4.3-cp310-cp310-win_amd64.whl", hash = "sha256:18d90523ce7553dd0b7e23cbb28865db23cddfd683a38fb224115f7826de78d0"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cbbe5e739d45a52f3200a771c6d2c7acf89eb2524890a4a3aa1a7fa0695d2a47"}, + {file = "coverage-7.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:489763b2d037b164846ebac0cbd368b8a4ca56385c4090807ff9fad817de4113"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:451f433ad901b3bb00184d83fd83d135fb682d780b38af7944c9faeecb1e0bfe"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fcc66e222cf4c719fe7722a403888b1f5e1682d1679bd780e2b26c18bb648cdc"}, + {file = "coverage-7.4.3-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b3ec74cfef2d985e145baae90d9b1b32f85e1741b04cd967aaf9cfa84c1334f3"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:abbbd8093c5229c72d4c2926afaee0e6e3140de69d5dcd918b2921f2f0c8baba"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:35eb581efdacf7b7422af677b92170da4ef34500467381e805944a3201df2079"}, + {file = "coverage-7.4.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8249b1c7334be8f8c3abcaaa996e1e4927b0e5a23b65f5bf6cfe3180d8ca7840"}, + {file = "coverage-7.4.3-cp311-cp311-win32.whl", hash = "sha256:cf30900aa1ba595312ae41978b95e256e419d8a823af79ce670835409fc02ad3"}, + {file = "coverage-7.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:18c7320695c949de11a351742ee001849912fd57e62a706d83dfc1581897fa2e"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:b51bfc348925e92a9bd9b2e48dad13431b57011fd1038f08316e6bf1df107d10"}, + {file = "coverage-7.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d6cdecaedea1ea9e033d8adf6a0ab11107b49571bbb9737175444cea6eb72328"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3b2eccb883368f9e972e216c7b4c7c06cabda925b5f06dde0650281cb7666a30"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6c00cdc8fa4e50e1cc1f941a7f2e3e0f26cb2a1233c9696f26963ff58445bac7"}, + {file = "coverage-7.4.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9a4a8dd3dcf4cbd3165737358e4d7dfbd9d59902ad11e3b15eebb6393b0446e"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:062b0a75d9261e2f9c6d071753f7eef0fc9caf3a2c82d36d76667ba7b6470003"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:ebe7c9e67a2d15fa97b77ea6571ce5e1e1f6b0db71d1d5e96f8d2bf134303c1d"}, + {file = "coverage-7.4.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:c0a120238dd71c68484f02562f6d446d736adcc6ca0993712289b102705a9a3a"}, + {file = "coverage-7.4.3-cp312-cp312-win32.whl", hash = "sha256:37389611ba54fd6d278fde86eb2c013c8e50232e38f5c68235d09d0a3f8aa352"}, + {file = "coverage-7.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:d25b937a5d9ffa857d41be042b4238dd61db888533b53bc76dc082cb5a15e914"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:28ca2098939eabab044ad68850aac8f8db6bf0b29bc7f2887d05889b17346454"}, + {file = "coverage-7.4.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:280459f0a03cecbe8800786cdc23067a8fc64c0bd51dc614008d9c36e1659d7e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6c0cdedd3500e0511eac1517bf560149764b7d8e65cb800d8bf1c63ebf39edd2"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9a9babb9466fe1da12417a4aed923e90124a534736de6201794a3aea9d98484e"}, + {file = "coverage-7.4.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dec9de46a33cf2dd87a5254af095a409ea3bf952d85ad339751e7de6d962cde6"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:16bae383a9cc5abab9bb05c10a3e5a52e0a788325dc9ba8499e821885928968c"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2c854ce44e1ee31bda4e318af1dbcfc929026d12c5ed030095ad98197eeeaed0"}, + {file = "coverage-7.4.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ce8c50520f57ec57aa21a63ea4f325c7b657386b3f02ccaedeccf9ebe27686e1"}, + {file = "coverage-7.4.3-cp38-cp38-win32.whl", hash = "sha256:708a3369dcf055c00ddeeaa2b20f0dd1ce664eeabde6623e516c5228b753654f"}, + {file = "coverage-7.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:1bf25fbca0c8d121a3e92a2a0555c7e5bc981aee5c3fdaf4bb7809f410f696b9"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3b253094dbe1b431d3a4ac2f053b6d7ede2664ac559705a704f621742e034f1f"}, + {file = "coverage-7.4.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77fbfc5720cceac9c200054b9fab50cb2a7d79660609200ab83f5db96162d20c"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6679060424faa9c11808598504c3ab472de4531c571ab2befa32f4971835788e"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4af154d617c875b52651dd8dd17a31270c495082f3d55f6128e7629658d63765"}, + {file = "coverage-7.4.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8640f1fde5e1b8e3439fe482cdc2b0bb6c329f4bb161927c28d2e8879c6029ee"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:69b9f6f66c0af29642e73a520b6fed25ff9fd69a25975ebe6acb297234eda501"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:0842571634f39016a6c03e9d4aba502be652a6e4455fadb73cd3a3a49173e38f"}, + {file = "coverage-7.4.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a78ed23b08e8ab524551f52953a8a05d61c3a760781762aac49f8de6eede8c45"}, + {file = "coverage-7.4.3-cp39-cp39-win32.whl", hash = "sha256:c0524de3ff096e15fcbfe8f056fdb4ea0bf497d584454f344d59fce069d3e6e9"}, + {file = "coverage-7.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:0209a6369ccce576b43bb227dc8322d8ef9e323d089c6f3f26a597b09cb4d2aa"}, + {file = "coverage-7.4.3-pp38.pp39.pp310-none-any.whl", hash = "sha256:7cbde573904625509a3f37b6fecea974e363460b556a627c60dc2f47e2fffa51"}, + {file = "coverage-7.4.3.tar.gz", hash = "sha256:276f6077a5c61447a48d133ed13e759c09e62aff0dc84274a68dc18660104d52"}, ] [package.dependencies] @@ -726,43 +726,43 @@ toml = ["tomli"] [[package]] name = "cryptography" -version = "42.0.4" +version = "42.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." optional = false python-versions = ">=3.7" files = [ - {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:ffc73996c4fca3d2b6c1c8c12bfd3ad00def8621da24f547626bf06441400449"}, - {file = "cryptography-42.0.4-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:db4b65b02f59035037fde0998974d84244a64c3265bdef32a827ab9b63d61b18"}, - {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad9c385ba8ee025bb0d856714f71d7840020fe176ae0229de618f14dae7a6e2"}, - {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69b22ab6506a3fe483d67d1ed878e1602bdd5912a134e6202c1ec672233241c1"}, - {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e09469a2cec88fb7b078e16d4adec594414397e8879a4341c6ace96013463d5b"}, - {file = "cryptography-42.0.4-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3e970a2119507d0b104f0a8e281521ad28fc26f2820687b3436b8c9a5fcf20d1"}, - {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:e53dc41cda40b248ebc40b83b31516487f7db95ab8ceac1f042626bc43a2f992"}, - {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c3a5cbc620e1e17009f30dd34cb0d85c987afd21c41a74352d1719be33380885"}, - {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:6bfadd884e7280df24d26f2186e4e07556a05d37393b0f220a840b083dc6a824"}, - {file = "cryptography-42.0.4-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:01911714117642a3f1792c7f376db572aadadbafcd8d75bb527166009c9f1d1b"}, - {file = "cryptography-42.0.4-cp37-abi3-win32.whl", hash = "sha256:fb0cef872d8193e487fc6bdb08559c3aa41b659a7d9be48b2e10747f47863925"}, - {file = "cryptography-42.0.4-cp37-abi3-win_amd64.whl", hash = "sha256:c1f25b252d2c87088abc8bbc4f1ecbf7c919e05508a7e8628e6875c40bc70923"}, - {file = "cryptography-42.0.4-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:15a1fb843c48b4a604663fa30af60818cd28f895572386e5f9b8a665874c26e7"}, - {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1327f280c824ff7885bdeef8578f74690e9079267c1c8bd7dc5cc5aa065ae52"}, - {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ffb03d419edcab93b4b19c22ee80c007fb2d708429cecebf1dd3258956a563a"}, - {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:1df6fcbf60560d2113b5ed90f072dc0b108d64750d4cbd46a21ec882c7aefce9"}, - {file = "cryptography-42.0.4-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:44a64043f743485925d3bcac548d05df0f9bb445c5fcca6681889c7c3ab12764"}, - {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:3c6048f217533d89f2f8f4f0fe3044bf0b2090453b7b73d0b77db47b80af8dff"}, - {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:6d0fbe73728c44ca3a241eff9aefe6496ab2656d6e7a4ea2459865f2e8613257"}, - {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:887623fe0d70f48ab3f5e4dbf234986b1329a64c066d719432d0698522749929"}, - {file = "cryptography-42.0.4-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:ce8613beaffc7c14f091497346ef117c1798c202b01153a8cc7b8e2ebaaf41c0"}, - {file = "cryptography-42.0.4-cp39-abi3-win32.whl", hash = "sha256:810bcf151caefc03e51a3d61e53335cd5c7316c0a105cc695f0959f2c638b129"}, - {file = "cryptography-42.0.4-cp39-abi3-win_amd64.whl", hash = "sha256:a0298bdc6e98ca21382afe914c642620370ce0470a01e1bef6dd9b5354c36854"}, - {file = "cryptography-42.0.4-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5f8907fcf57392cd917892ae83708761c6ff3c37a8e835d7246ff0ad251d9298"}, - {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:12d341bd42cdb7d4937b0cabbdf2a94f949413ac4504904d0cdbdce4a22cbf88"}, - {file = "cryptography-42.0.4-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:1cdcdbd117681c88d717437ada72bdd5be9de117f96e3f4d50dab3f59fd9ab20"}, - {file = "cryptography-42.0.4-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:0e89f7b84f421c56e7ff69f11c441ebda73b8a8e6488d322ef71746224c20fce"}, - {file = "cryptography-42.0.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f1e85a178384bf19e36779d91ff35c7617c885da487d689b05c1366f9933ad74"}, - {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d2a27aca5597c8a71abbe10209184e1a8e91c1fd470b5070a2ea60cafec35bcd"}, - {file = "cryptography-42.0.4-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:4e36685cb634af55e0677d435d425043967ac2f3790ec652b2b88ad03b85c27b"}, - {file = "cryptography-42.0.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:f47be41843200f7faec0683ad751e5ef11b9a56a220d57f300376cd8aba81660"}, - {file = "cryptography-42.0.4.tar.gz", hash = "sha256:831a4b37accef30cccd34fcb916a5d7b5be3cbbe27268a02832c3e450aea39cb"}, + {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_universal2.whl", hash = "sha256:a30596bae9403a342c978fb47d9b0ee277699fa53bbafad14706af51fe543d16"}, + {file = "cryptography-42.0.5-cp37-abi3-macosx_10_12_x86_64.whl", hash = "sha256:b7ffe927ee6531c78f81aa17e684e2ff617daeba7f189f911065b2ea2d526dec"}, + {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2424ff4c4ac7f6b8177b53c17ed5d8fa74ae5955656867f5a8affaca36a27abb"}, + {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:329906dcc7b20ff3cad13c069a78124ed8247adcac44b10bea1130e36caae0b4"}, + {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:b03c2ae5d2f0fc05f9a2c0c997e1bc18c8229f392234e8a0194f202169ccd278"}, + {file = "cryptography-42.0.5-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f8837fe1d6ac4a8052a9a8ddab256bc006242696f03368a4009be7ee3075cdb7"}, + {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:0270572b8bd2c833c3981724b8ee9747b3ec96f699a9665470018594301439ee"}, + {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:b8cac287fafc4ad485b8a9b67d0ee80c66bf3574f655d3b97ef2e1082360faf1"}, + {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:16a48c23a62a2f4a285699dba2e4ff2d1cff3115b9df052cdd976a18856d8e3d"}, + {file = "cryptography-42.0.5-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:2bce03af1ce5a5567ab89bd90d11e7bbdff56b8af3acbbec1faded8f44cb06da"}, + {file = "cryptography-42.0.5-cp37-abi3-win32.whl", hash = "sha256:b6cd2203306b63e41acdf39aa93b86fb566049aeb6dc489b70e34bcd07adca74"}, + {file = "cryptography-42.0.5-cp37-abi3-win_amd64.whl", hash = "sha256:98d8dc6d012b82287f2c3d26ce1d2dd130ec200c8679b6213b3c73c08b2b7940"}, + {file = "cryptography-42.0.5-cp39-abi3-macosx_10_12_universal2.whl", hash = "sha256:5e6275c09d2badf57aea3afa80d975444f4be8d3bc58f7f80d2a484c6f9485c8"}, + {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4985a790f921508f36f81831817cbc03b102d643b5fcb81cd33df3fa291a1a1"}, + {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7cde5f38e614f55e28d831754e8a3bacf9ace5d1566235e39d91b35502d6936e"}, + {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:7367d7b2eca6513681127ebad53b2582911d1736dc2ffc19f2c3ae49997496bc"}, + {file = "cryptography-42.0.5-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:cd2030f6650c089aeb304cf093f3244d34745ce0cfcc39f20c6fbfe030102e2a"}, + {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a2913c5375154b6ef2e91c10b5720ea6e21007412f6437504ffea2109b5a33d7"}, + {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:c41fb5e6a5fe9ebcd58ca3abfeb51dffb5d83d6775405305bfa8715b76521922"}, + {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:3eaafe47ec0d0ffcc9349e1708be2aaea4c6dd4978d76bf6eb0cb2c13636c6fc"}, + {file = "cryptography-42.0.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1b95b98b0d2af784078fa69f637135e3c317091b615cd0905f8b8a087e86fa30"}, + {file = "cryptography-42.0.5-cp39-abi3-win32.whl", hash = "sha256:1f71c10d1e88467126f0efd484bd44bca5e14c664ec2ede64c32f20875c0d413"}, + {file = "cryptography-42.0.5-cp39-abi3-win_amd64.whl", hash = "sha256:a011a644f6d7d03736214d38832e030d8268bcff4a41f728e6030325fea3e400"}, + {file = "cryptography-42.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:9481ffe3cf013b71b2428b905c4f7a9a4f76ec03065b05ff499bb5682a8d9ad8"}, + {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ba334e6e4b1d92442b75ddacc615c5476d4ad55cc29b15d590cc6b86efa487e2"}, + {file = "cryptography-42.0.5-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:ba3e4a42397c25b7ff88cdec6e2a16c2be18720f317506ee25210f6d31925f9c"}, + {file = "cryptography-42.0.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:111a0d8553afcf8eb02a4fea6ca4f59d48ddb34497aa8706a6cf536f1a5ec576"}, + {file = "cryptography-42.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:cd65d75953847815962c84a4654a84850b2bb4aed3f26fadcc1c13892e1e29f6"}, + {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:e807b3188f9eb0eaa7bbb579b462c5ace579f1cedb28107ce8b48a9f7ad3679e"}, + {file = "cryptography-42.0.5-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f12764b8fffc7a123f641d7d049d382b73f96a34117e0b637b80643169cec8ac"}, + {file = "cryptography-42.0.5-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:37dd623507659e08be98eec89323469e8c7b4c1407c85112634ae3dbdb926fdd"}, + {file = "cryptography-42.0.5.tar.gz", hash = "sha256:6fe07eec95dfd477eb9530aef5bead34fec819b3aaf6c5bd6d20565da607bfe1"}, ] [package.dependencies] @@ -832,71 +832,71 @@ six = "*" [[package]] name = "ddtrace" -version = "2.5.2" +version = "2.6.5" description = "Datadog APM client library" optional = false python-versions = ">=3.7" files = [ - {file = "ddtrace-2.5.2-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:f918538a6adb33696be653d343ee318b16ea977376d9b7214d14fe97c42e9bd9"}, - {file = "ddtrace-2.5.2-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:f56735eb636d3ab2f7224f261d3a6bd43f884e9901d68407d485ea65f3dc0f46"}, - {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72d21fe6842a8d80c8765dd699153a2475ae2d49e82e10f9668eadb08b454040"}, - {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a6e48caf63506d7ac3df7caa955b6258de91c1a1f55149506ab8ac36143770b9"}, - {file = "ddtrace-2.5.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc3f26e04ba7521f6885d871fd6266fedc0a7ccf2637b85579c058927404bad7"}, - {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:15d78b0cd5d2090c063031d76e933b8b24e043d524a6091a751cf57b0fab025f"}, - {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:ee76beaf87695f2204b0c2c2a3664b39f3483b7a8447b28e5e2bcc899861b3eb"}, - {file = "ddtrace-2.5.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:8840f0e82d6dca3888bd06e7ab0ca6d39009f3cd3475028d8bc03c939127afc2"}, - {file = "ddtrace-2.5.2-cp310-cp310-win32.whl", hash = "sha256:a34ccab0c8991c5fc5252d5cd6e88852cd7f77c8bf838de84e70b4a3bfacaad4"}, - {file = "ddtrace-2.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:ffa4f5779c7000fe5960156bd15339184355b30a661b0955799cae50da5d03a7"}, - {file = "ddtrace-2.5.2-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:ea2740a3d61876cb07b271af444e98cdc8b730497cfcddbc3794c7a7441b8d15"}, - {file = "ddtrace-2.5.2-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:62e775ba9d2a2b5f952a6609029e965057bdd852ccd6e53b55c0f82ae83aa542"}, - {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30186112f156a564efda5e2018240b55baee7664897ca5fc35c452d032a77185"}, - {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9dccdc69de364cffc2b892280724c78cb54db151452a0b6d1b4a89b6f060c44"}, - {file = "ddtrace-2.5.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa2543c2303ab325af7794f2a8a420133cd9222e70bfbce3869da146fc5e2ba"}, - {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:aa2e64f79ada9f2fd5307cd0eba726d8585e47b0282fb9463aaa4b267265e94a"}, - {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:37b4d55a5be59530e6e5761a36d727aee812be69c81b00ee0182eb62be6f3b75"}, - {file = "ddtrace-2.5.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:6d97f990d2322a23e82203cc5a2aa694fb0d42541a44bb120390e6598a63e5f5"}, - {file = "ddtrace-2.5.2-cp311-cp311-win32.whl", hash = "sha256:5d3f1bc3ce87fbcf2256197178179ef681df720ebbc39b0559bda00247744533"}, - {file = "ddtrace-2.5.2-cp311-cp311-win_amd64.whl", hash = "sha256:a50057085b0972e695bb1ef3042f6cd6a1a3b12111fac4985942f2dbbcf8ac2f"}, - {file = "ddtrace-2.5.2-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:b923b099b9a1e50f01ce8bcd4d11e3255a48c71f3e6314dd9a482baed0a87ed6"}, - {file = "ddtrace-2.5.2-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:512d3975b1657c706ca9c84373e5fce323f6fc94bfac33c30876ad8d55e0ea71"}, - {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c54bc474c70151d5a141061b6c20a1efabdf458e4239c790d45fa12a13b8e7d"}, - {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5fb2bbd38dc46ba6a7ea1031c4751b1ca888be5fac8a42049ebc2517707c00d"}, - {file = "ddtrace-2.5.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:caa6fb6bcfb3810d8f0882e489e7d2ef4dd3a92b452cfdd8d1fd4703dc496b17"}, - {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:3f4eed40d978352c7371804ecb68bbe9e55967bb904bd03b0568554e0b6b92cf"}, - {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:57606af5380888e2e7cc67b7c4fa5e1bc51d29c48f004b4be0cbe1b319fddc75"}, - {file = "ddtrace-2.5.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ee8d0259a004964a8eddb394aa84a5754435d4270cd2041e6559c9e68fa49141"}, - {file = "ddtrace-2.5.2-cp312-cp312-win32.whl", hash = "sha256:4df564e620ec7e657fcdb0d5bf1231aa1357bf49b736f0d9e9f6df17a23fc569"}, - {file = "ddtrace-2.5.2-cp312-cp312-win_amd64.whl", hash = "sha256:637f16af1c84566bde044798312c67bc5676df949632ab02e740440558f2a598"}, - {file = "ddtrace-2.5.2-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:d24841a9390f3e169edcaf1ca5ac80599062e66dee43a510decb25e779b6f7b4"}, - {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:49aa4e0210862e829e09569de2e2f34ac17c5e246567c5b6662ec21e2a06d938"}, - {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:985738fe875b11f05dfa2b1f21a619d499344eb740f63e01d6eae1fb29eb949b"}, - {file = "ddtrace-2.5.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8814321822e4afc95ac86fbc476dc20d78dd4b1d510c02606459df4580093d18"}, - {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ad6c0ae7baff9d00c689834aec0627274d681ed1d2a8ae627348a6191e8d32ec"}, - {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:aa596f2e80c525a2310e605bfa3fa6ba6790b2ae90c02e47ceee0e62ceae17a6"}, - {file = "ddtrace-2.5.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:6bdfae9fa03af334820678196a4895450d0b6bd9f1b5119d42ddbd327a55fcce"}, - {file = "ddtrace-2.5.2-cp37-cp37m-win32.whl", hash = "sha256:227bb0391d310e0d5a54505c7ab59f9692a5db91dc492373489bc45726980e1d"}, - {file = "ddtrace-2.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6e55c4738b58b4452933204305243e19000f6f283af93bf51b63382100cb8f21"}, - {file = "ddtrace-2.5.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:4d9e7a9e26c38ae1e368f5d820e78459ff2d39689f40d4a3db185ddb3686c383"}, - {file = "ddtrace-2.5.2-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:c361ea11b442b04d8e011528205ed65b926d71d18f38d372270204eabf49b068"}, - {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5aafd86eeea622cd0e8cf6b63632efc67a52a32317d2a376382ef6170d383c9f"}, - {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ff039635470ba483ed448baaf6337d85a731b17af62fef06dfa811f761f374f"}, - {file = "ddtrace-2.5.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20f1cb3bea1170410d603f9d557918c24d4d8783659c03817daea6352d9f37f9"}, - {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:7351500241eb24c7d789b371a6860ca2b0e2db1ff9d317089153b562a3a461e1"}, - {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:a2cfc6ee800890556e404b94d13680c83952efa5d3dafa72ef8cb08a8782f874"}, - {file = "ddtrace-2.5.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:96a791f03b62ebdb9f3e635a0e93711149123a8fc1c1c152be0d1cdb5d8e6359"}, - {file = "ddtrace-2.5.2-cp38-cp38-win32.whl", hash = "sha256:6c61e72abec3f2f6b46e53712a32a971de1b6a9be657d5ebeff1334f6146babc"}, - {file = "ddtrace-2.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:b93d8b536f5fc45a72bb2785051dc729f4d581ef2d69ed10bccae6a7487477b2"}, - {file = "ddtrace-2.5.2-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:38cbcb7b4ff1371480b29228d2b8e570e7d7b386a7632b96f9600135ec3eb9db"}, - {file = "ddtrace-2.5.2-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a270d128c6067f52a76ecbb658fae3f4d3bd4888baa9e6159ff82b6de14c53be"}, - {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e59f3958016fcec5eb16abd7979a9ec4d850733e2a03b878b096277fc092784"}, - {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:066403f0e00a8de09c8187037befe7463d1fab5d8178b62a07c2542792710d14"}, - {file = "ddtrace-2.5.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbcbf24bca8497f1412ec438fbdc94847aef9e86092ffd4f8626bbe6d278d33"}, - {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:d34f8da809e2783770a6c88396b3653fb12a4196e9b5f16b8c10f37bbf2b7b31"}, - {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9eaca41664dd0c2bd7257fe2e91c7e46718b20591bfaa0b5c01c39b599115f88"}, - {file = "ddtrace-2.5.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8f4b67e02ba5c316711719dcfc15e94f47684e7af1785289d016a29a2c664827"}, - {file = "ddtrace-2.5.2-cp39-cp39-win32.whl", hash = "sha256:9bbd675d73aae6516e02a86cb830778771dafb0e182d5a122270ccd82ee77eed"}, - {file = "ddtrace-2.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:e93f3f5d3d57beb492b04286c758be65495908bd313df6f56865ad7af222e49e"}, - {file = "ddtrace-2.5.2.tar.gz", hash = "sha256:5addeb19eea5ebdc23c493e5635f4c8737795b48ba637117a1895f31b900985f"}, + {file = "ddtrace-2.6.5-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:04b0849a7017401ac05b1706e6ba52a04b142e454ed28d57f55620ec511077a8"}, + {file = "ddtrace-2.6.5-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:765386e0f13603e4747a7530b6f96dc0b524dcae80d22b2599bbe32db0f0db7b"}, + {file = "ddtrace-2.6.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6212e5fe2b8d16ee8d63b5992276cd48b3d8904364598d67735072a02c9c9d61"}, + {file = "ddtrace-2.6.5-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5d732dbcc9f95f6133aff77d9a185a6d624ed3650764cb305244ad08da7a58f7"}, + {file = "ddtrace-2.6.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0ebda479f5ee2ad139e2af23e7c1295fbbf0612a618ffed1fa0feee22a3c265c"}, + {file = "ddtrace-2.6.5-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:098db83b90725a612889d9228dc4047ed82ba2078c9bd2e026c334f7ef6d8d82"}, + {file = "ddtrace-2.6.5-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1e9dde12dc9f9864eda2936b73580d61d089559c8908d967aad0ac5a3e5d3f6d"}, + {file = "ddtrace-2.6.5-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:3975099aa4ade5728b90d79b15bfe2aec84ea134f1ce746ac66fd05d38a232b6"}, + {file = "ddtrace-2.6.5-cp310-cp310-win32.whl", hash = "sha256:ca386c616073542f5fe5333864184e5714cb7685f83cfd659ce9bb241e634361"}, + {file = "ddtrace-2.6.5-cp310-cp310-win_amd64.whl", hash = "sha256:c4978637d6018e1fbd3abe2176d459d783052a5a8f946fccdd62e80ebbaf7d7a"}, + {file = "ddtrace-2.6.5-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:5b17c78ba62a2ed0fe095f96aeb5952baf36a5a449ec667a00aa84943e9a51c9"}, + {file = "ddtrace-2.6.5-cp311-cp311-macosx_11_0_x86_64.whl", hash = "sha256:5bb9ba523affeea2ecdc9420bdd6b3393b4e15728eb6b5bc18619fc6ebe80db7"}, + {file = "ddtrace-2.6.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0eafd0be4b50f4208f948451468e64973136a282fd08e1567d65ba77e7927ab7"}, + {file = "ddtrace-2.6.5-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d846c0209fd6354098e841857b7f96d38ec87ba4933460abce0a0222d678920"}, + {file = "ddtrace-2.6.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82037fcd43c23a3616c723041fae15b4ac1cd90489d92a05d265f83d11d6a478"}, + {file = "ddtrace-2.6.5-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:585b8c5ce46a1abfdeb4b07a15ef5d8a929bd7719bfdaa6e7f7cdda0daec61e2"}, + {file = "ddtrace-2.6.5-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:67083e775f8d77404184217735fcc8181104130c657e8c12ae1fe04749164ccc"}, + {file = "ddtrace-2.6.5-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dacd18d2ffbbfb2d63bd0dc840f40f5dbdeb6dfed9ace61a719dc42b3edf26c2"}, + {file = "ddtrace-2.6.5-cp311-cp311-win32.whl", hash = "sha256:ee385ec24d1a8c5cd3b832b754ff88837dcce1a9ed6b0119da789bd00eaf7483"}, + {file = "ddtrace-2.6.5-cp311-cp311-win_amd64.whl", hash = "sha256:341331b0698d149e98a0b7dd557af878c5a4b16f531cecec7f7a09f88abed87c"}, + {file = "ddtrace-2.6.5-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:cb28b497bd6aceae95e7142f13d8571be960c2e884a63780d2c84fcc7688edeb"}, + {file = "ddtrace-2.6.5-cp312-cp312-macosx_11_0_x86_64.whl", hash = "sha256:078d6760e41b12647215ce547ac632687e20c16f4472eae7eb43644a4cca9e68"}, + {file = "ddtrace-2.6.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:678094a0626c4b1fc3cad2c9e938158f39faabcb094867bb0603b9a4c5d360d0"}, + {file = "ddtrace-2.6.5-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4276b9ba782268473741f7b6f9a53407b4f3922c41f5e96bfe60d001d0a17ba9"}, + {file = "ddtrace-2.6.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e4459e582951235e4053db725cf11643dfa117d5f22932b34c0f76a5d6d22f3f"}, + {file = "ddtrace-2.6.5-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:af060a53d7e8ee53a0755355d16d4e45b09db44cf3494716b6097b71a615be95"}, + {file = "ddtrace-2.6.5-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:1a22f0cd53c1d467feb1a174a1ab9d5d02c0fecca4a2f11834683eb70f3cad80"}, + {file = "ddtrace-2.6.5-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:40882fc48888f9322ccfc9e6162e8a3e4b2eb898f240ca3cd1826ca68508db8b"}, + {file = "ddtrace-2.6.5-cp312-cp312-win32.whl", hash = "sha256:4817772cd7f7b06f180241815587ba6236ac3afafdd1930038d773adf2be3d48"}, + {file = "ddtrace-2.6.5-cp312-cp312-win_amd64.whl", hash = "sha256:69a8f71818ef017fe049119ac57e890294cadaead8402508399f94a9962731a0"}, + {file = "ddtrace-2.6.5-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:4dd0a1d2bbee33e1f7128290ba01ecf659a8c40007d89824f35a9fdebdde6f76"}, + {file = "ddtrace-2.6.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0fe5fd5479bd0126551e3370d7b13484490a6874069e518ab4b5be1e8e9c8ecb"}, + {file = "ddtrace-2.6.5-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3b82ddfe13c5ccc1ef3ec6e379d686f04bf387b8bd6ab6d674b6188698fd37e"}, + {file = "ddtrace-2.6.5-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b691a5d8cdc3af7c38d6cf4a34be781d7868854e6a5efd84ea856f3ba81e9aef"}, + {file = "ddtrace-2.6.5-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1ddec7e5f1f0a2066574affd9198f6c348bc559752a5bf063792aa9c2b5fced8"}, + {file = "ddtrace-2.6.5-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:a086420b0d0d2a5fb4358dc2d03b85b6c022949cad89043f0a96c82996280594"}, + {file = "ddtrace-2.6.5-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:71485ff240b0ba110662ec8628c1c320266e44945568c72b9cded4365406a028"}, + {file = "ddtrace-2.6.5-cp37-cp37m-win32.whl", hash = "sha256:bee1ca5e3f61743b8197435dd1d1427887ad676084d67b3b1bb1a2055dd682d2"}, + {file = "ddtrace-2.6.5-cp37-cp37m-win_amd64.whl", hash = "sha256:6509de90ca1dc472e2a70dbe699c12659086e21bc733237a3e503f5b1948ab7a"}, + {file = "ddtrace-2.6.5-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7f2cbbad82df0d6bc9390fc1fd4f8f589f1e1c37a96059493c99189855ed0882"}, + {file = "ddtrace-2.6.5-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:0f52f9d3a8ebdb21c7ac9b48cca9f13ecb55db3c58a459279804f8b7990cc432"}, + {file = "ddtrace-2.6.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:944d85bada913503cf85972ab818bccf19d974ff8a31f34a84232e5bf256254f"}, + {file = "ddtrace-2.6.5-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7374f3888be2be3ee1b90935da0a192e001c43accb7b35d7858fc4bd7345d6a"}, + {file = "ddtrace-2.6.5-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32129805c54348d4285e8e8618f8bf31e38bdad8b261ba6cfa9d63886c8b0819"}, + {file = "ddtrace-2.6.5-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:5d90aef6c9429633b17bd9b16f7a3712657119b8caf870486df82a5adafd7a78"}, + {file = "ddtrace-2.6.5-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:02351e7eb23bf4ca962ad704d976ce52a33286a01bdb8e514a334c541bec4e1c"}, + {file = "ddtrace-2.6.5-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:33d0676debceeac53459f54ad79ae0a2efcfe7f2d512624ad7241a453368fc21"}, + {file = "ddtrace-2.6.5-cp38-cp38-win32.whl", hash = "sha256:1d581c4c9e2beba054bdaec04f2cd267713af309244bb8227c5e277e019dd429"}, + {file = "ddtrace-2.6.5-cp38-cp38-win_amd64.whl", hash = "sha256:672c42f99e7098cad3e46df80649d8b510e9baef62bb094b90dad22d8e0bde7d"}, + {file = "ddtrace-2.6.5-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:dbfdfc55d28b3fec547634bdfacce200934bc73a75d73ff2101c7c0b4cd51233"}, + {file = "ddtrace-2.6.5-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:ea8c9b99a979b392df41183b3879f9981440cafe47b926f73866892fc4bb8af1"}, + {file = "ddtrace-2.6.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0995e5d6ef3082adc2f8657f07518127eee84074ff7101582c5f2a3e6813ca49"}, + {file = "ddtrace-2.6.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aed320f14742188ce8e7697aee9445a6034ececb5fbdc468e8d5bf92a2ed5125"}, + {file = "ddtrace-2.6.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1c345752a9758d50f5daa43d700284f5a47d3e73faf69abdfadd20ef65511e0"}, + {file = "ddtrace-2.6.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5679167188adfb769414b91ddf810319bbe2fa2f64db7dc0b02d67775b74c802"}, + {file = "ddtrace-2.6.5-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8d6974459ab84b310ada4325b4178e435ae1476397f33999baf10d9a45d6d2b0"}, + {file = "ddtrace-2.6.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:32f283b9168fafe82a0d95dac516991951992e08c8aa67e67ebca20c5348555c"}, + {file = "ddtrace-2.6.5-cp39-cp39-win32.whl", hash = "sha256:34cc4f978494ffb7304613b9ae8f0e1d847376ea6ddc6b5db98a5af717cddd64"}, + {file = "ddtrace-2.6.5-cp39-cp39-win_amd64.whl", hash = "sha256:65d6ab3565a8fbff1bc8ebff717d0ac88a69055404597c294ac515610af93bab"}, + {file = "ddtrace-2.6.5.tar.gz", hash = "sha256:a04e6b8931300bc258fcfaa21a99707d5c307518162fe84538e1ee7ed9c970df"}, ] [package.dependencies] @@ -1098,20 +1098,20 @@ smmap = ">=3.0.1,<6" [[package]] name = "gitpython" -version = "3.1.41" +version = "3.1.42" description = "GitPython is a Python library used to interact with Git repositories" optional = false python-versions = ">=3.7" files = [ - {file = "GitPython-3.1.41-py3-none-any.whl", hash = "sha256:c36b6634d069b3f719610175020a9aed919421c87552185b085e04fbbdb10b7c"}, - {file = "GitPython-3.1.41.tar.gz", hash = "sha256:ed66e624884f76df22c8e16066d567aaa5a37d5b5fa19db2c6df6f7156db9048"}, + {file = "GitPython-3.1.42-py3-none-any.whl", hash = "sha256:1bf9cd7c9e7255f77778ea54359e54ac22a72a5b51288c457c881057b7bb9ecd"}, + {file = "GitPython-3.1.42.tar.gz", hash = "sha256:2d99869e0fef71a73cbd242528105af1d6c1b108c60dfabd994bf292f76c3ceb"}, ] [package.dependencies] gitdb = ">=4.0.1,<5" [package.extras] -test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar", "sumtypes"] +test = ["black", "coverage[toml]", "ddt (>=1.1.1,!=1.4.3)", "mock", "mypy", "pre-commit", "pytest (>=7.3.1)", "pytest-cov", "pytest-instafail", "pytest-mock", "pytest-sugar"] [[package]] name = "h11" @@ -1126,13 +1126,13 @@ files = [ [[package]] name = "httpcore" -version = "1.0.2" +version = "1.0.4" description = "A minimal low-level HTTP client." optional = false python-versions = ">=3.8" files = [ - {file = "httpcore-1.0.2-py3-none-any.whl", hash = "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7"}, - {file = "httpcore-1.0.2.tar.gz", hash = "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535"}, + {file = "httpcore-1.0.4-py3-none-any.whl", hash = "sha256:ac418c1db41bade2ad53ae2f3834a3a0f5ae76b56cf5aa497d2d033384fc7d73"}, + {file = "httpcore-1.0.4.tar.gz", hash = "sha256:cb2839ccfcba0d2d3c1131d3c3e26dfc327326fbe7a5dc0dbfe9f6c9151bb022"}, ] [package.dependencies] @@ -1143,7 +1143,7 @@ h11 = ">=0.13,<0.15" asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.23.0)"] +trio = ["trio (>=0.22.0,<0.25.0)"] [[package]] name = "httpx" @@ -1226,17 +1226,6 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, - {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, - {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, - {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, - {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, - {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -1316,13 +1305,13 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs [[package]] name = "importlib-resources" -version = "6.1.1" +version = "6.1.2" description = "Read resources from Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "importlib_resources-6.1.1-py3-none-any.whl", hash = "sha256:e8bf90d8213b486f428c9c39714b920041cb02c184686a3dee24905aaa8105d6"}, - {file = "importlib_resources-6.1.1.tar.gz", hash = "sha256:3893a00122eafde6894c59914446a512f728a0c1a45f9bb9b63721b6bacf0b4a"}, + {file = "importlib_resources-6.1.2-py3-none-any.whl", hash = "sha256:9a0a862501dc38b68adebc82970140c9e4209fc99601782925178f8386339938"}, + {file = "importlib_resources-6.1.2.tar.gz", hash = "sha256:308abf8474e2dba5f867d279237cd4076482c3de7104a40b41426370e891549b"}, ] [package.dependencies] @@ -1330,7 +1319,7 @@ zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"] -testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-ruff", "zipp (>=3.17)"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)", "zipp (>=3.17)"] [[package]] name = "iniconfig" @@ -1451,19 +1440,18 @@ ply = "*" [[package]] name = "jsonpickle" -version = "3.0.2" +version = "3.0.3" description = "Python library for serializing any arbitrary object graph into JSON" optional = false python-versions = ">=3.7" files = [ - {file = "jsonpickle-3.0.2-py3-none-any.whl", hash = "sha256:4a8442d97ca3f77978afa58068768dba7bff2dbabe79a9647bc3cdafd4ef019f"}, - {file = "jsonpickle-3.0.2.tar.gz", hash = "sha256:e37abba4bfb3ca4a4647d28bb9f4706436f7b46c8a8333b4a718abafa8e46b37"}, + {file = "jsonpickle-3.0.3-py3-none-any.whl", hash = "sha256:e8d6dcc58f6722bea0321cd328fbda81c582461185688a535df02be0f699afb4"}, + {file = "jsonpickle-3.0.3.tar.gz", hash = "sha256:5691f44495327858ab3a95b9c440a79b41e35421be1a6e09a47b6c9b9421fd06"}, ] [package.extras] -docs = ["jaraco.packaging (>=3.2)", "rst.linker (>=1.9)", "sphinx"] -testing = ["ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-black-multipy", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-flake8 (>=1.1.1)", "scikit-learn", "sqlalchemy"] -testing-libs = ["simplejson", "ujson"] +docs = ["furo", "jaraco.packaging (>=9)", "rst.linker (>=1.9)", "sphinx"] +testing = ["ecdsa", "feedparser", "gmpy2", "numpy", "pandas", "pymongo", "pytest (>=3.5,!=3.7.3)", "pytest-checkdocs (>=1.2.3)", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-ruff", "scikit-learn", "simplejson", "sqlalchemy", "ujson"] [[package]] name = "jsonpointer" @@ -1766,13 +1754,13 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.5.10" +version = "9.5.11" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.10-py3-none-any.whl", hash = "sha256:3c6c46b57d2ee3c8890e6e0406e68b6863cf65768f0f436990a742702d198442"}, - {file = "mkdocs_material-9.5.10.tar.gz", hash = "sha256:6ad626dbb31070ebbaedff813323a16a406629620e04b96458f16e6e9c7008fe"}, + {file = "mkdocs_material-9.5.11-py3-none-any.whl", hash = "sha256:788ee0f3e036dca2dc20298d65e480297d348a44c9d7b2ee05c5262983e66072"}, + {file = "mkdocs_material-9.5.11.tar.gz", hash = "sha256:7af7f8af0dea16175558f3fb9245d26c83a17199baa5f157755e63d7437bf971"}, ] [package.dependencies] @@ -2077,13 +2065,13 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] [[package]] name = "opentelemetry-api" -version = "1.22.0" +version = "1.23.0" description = "OpenTelemetry Python API" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "opentelemetry_api-1.22.0-py3-none-any.whl", hash = "sha256:43621514301a7e9f5d06dd8013a1b450f30c2e9372b8e30aaeb4562abf2ce034"}, - {file = "opentelemetry_api-1.22.0.tar.gz", hash = "sha256:15ae4ca925ecf9cfdfb7a709250846fbb08072260fca08ade78056c502b86bed"}, + {file = "opentelemetry_api-1.23.0-py3-none-any.whl", hash = "sha256:cc03ea4025353048aadb9c64919099663664672ea1c6be6ddd8fee8e4cd5e774"}, + {file = "opentelemetry_api-1.23.0.tar.gz", hash = "sha256:14a766548c8dd2eb4dfc349739eb4c3893712a0daa996e5dbf945f9da665da9d"}, ] [package.dependencies] @@ -2202,22 +2190,22 @@ files = [ [[package]] name = "protobuf" -version = "4.25.2" +version = "4.25.3" description = "" optional = false python-versions = ">=3.8" files = [ - {file = "protobuf-4.25.2-cp310-abi3-win32.whl", hash = "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6"}, - {file = "protobuf-4.25.2-cp310-abi3-win_amd64.whl", hash = "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9"}, - {file = "protobuf-4.25.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d"}, - {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62"}, - {file = "protobuf-4.25.2-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020"}, - {file = "protobuf-4.25.2-cp38-cp38-win32.whl", hash = "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61"}, - {file = "protobuf-4.25.2-cp38-cp38-win_amd64.whl", hash = "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62"}, - {file = "protobuf-4.25.2-cp39-cp39-win32.whl", hash = "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3"}, - {file = "protobuf-4.25.2-cp39-cp39-win_amd64.whl", hash = "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0"}, - {file = "protobuf-4.25.2-py3-none-any.whl", hash = "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830"}, - {file = "protobuf-4.25.2.tar.gz", hash = "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e"}, + {file = "protobuf-4.25.3-cp310-abi3-win32.whl", hash = "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa"}, + {file = "protobuf-4.25.3-cp310-abi3-win_amd64.whl", hash = "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8"}, + {file = "protobuf-4.25.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_aarch64.whl", hash = "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019"}, + {file = "protobuf-4.25.3-cp37-abi3-manylinux2014_x86_64.whl", hash = "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d"}, + {file = "protobuf-4.25.3-cp38-cp38-win32.whl", hash = "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2"}, + {file = "protobuf-4.25.3-cp38-cp38-win_amd64.whl", hash = "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4"}, + {file = "protobuf-4.25.3-cp39-cp39-win32.whl", hash = "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4"}, + {file = "protobuf-4.25.3-cp39-cp39-win_amd64.whl", hash = "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c"}, + {file = "protobuf-4.25.3-py3-none-any.whl", hash = "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9"}, + {file = "protobuf-4.25.3.tar.gz", hash = "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c"}, ] [[package]] @@ -2340,13 +2328,13 @@ extra = ["pygments (>=2.12)"] [[package]] name = "pytest" -version = "8.0.1" +version = "8.0.2" description = "pytest: simple powerful testing with Python" optional = false python-versions = ">=3.8" files = [ - {file = "pytest-8.0.1-py3-none-any.whl", hash = "sha256:3e4f16fe1c0a9dc9d9389161c127c3edc5d810c38d6793042fb81d9f48a59fca"}, - {file = "pytest-8.0.1.tar.gz", hash = "sha256:267f6563751877d772019b13aacbe4e860d73fe8f651f28112e9ac37de7513ae"}, + {file = "pytest-8.0.2-py3-none-any.whl", hash = "sha256:edfaaef32ce5172d5466b5127b42e0d6d35ebbe4453f0e3505d96afd93f6b096"}, + {file = "pytest-8.0.2.tar.gz", hash = "sha256:d4051d623a2e0b7e51960ba963193b09ce6daeb9759a451844a21e4ddedfc1bd"}, ] [package.dependencies] @@ -2527,7 +2515,6 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, - {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2535,16 +2522,8 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, - {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, - {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, - {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, - {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, - {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, - {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2561,7 +2540,6 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, - {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2569,7 +2547,6 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, - {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -2797,110 +2774,110 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] [[package]] name = "rpds-py" -version = "0.17.1" +version = "0.18.0" description = "Python bindings to Rust's persistent data structures (rpds)" optional = false python-versions = ">=3.8" files = [ - {file = "rpds_py-0.17.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d"}, - {file = "rpds_py-0.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9"}, - {file = "rpds_py-0.17.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394"}, - {file = "rpds_py-0.17.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59"}, - {file = "rpds_py-0.17.1-cp310-none-win32.whl", hash = "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d"}, - {file = "rpds_py-0.17.1-cp310-none-win_amd64.whl", hash = "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6"}, - {file = "rpds_py-0.17.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b"}, - {file = "rpds_py-0.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8"}, - {file = "rpds_py-0.17.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd"}, - {file = "rpds_py-0.17.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea"}, - {file = "rpds_py-0.17.1-cp311-none-win32.whl", hash = "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518"}, - {file = "rpds_py-0.17.1-cp311-none-win_amd64.whl", hash = "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf"}, - {file = "rpds_py-0.17.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf"}, - {file = "rpds_py-0.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9"}, - {file = "rpds_py-0.17.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253"}, - {file = "rpds_py-0.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23"}, - {file = "rpds_py-0.17.1-cp312-none-win32.whl", hash = "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1"}, - {file = "rpds_py-0.17.1-cp312-none-win_amd64.whl", hash = "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3"}, - {file = "rpds_py-0.17.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d"}, - {file = "rpds_py-0.17.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae"}, - {file = "rpds_py-0.17.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde"}, - {file = "rpds_py-0.17.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6"}, - {file = "rpds_py-0.17.1-cp38-none-win32.whl", hash = "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a"}, - {file = "rpds_py-0.17.1-cp38-none-win_amd64.whl", hash = "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb"}, - {file = "rpds_py-0.17.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a"}, - {file = "rpds_py-0.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256"}, - {file = "rpds_py-0.17.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772"}, - {file = "rpds_py-0.17.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b"}, - {file = "rpds_py-0.17.1-cp39-none-win32.whl", hash = "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f"}, - {file = "rpds_py-0.17.1-cp39-none-win_amd64.whl", hash = "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6"}, - {file = "rpds_py-0.17.1-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb"}, - {file = "rpds_py-0.17.1-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296"}, - {file = "rpds_py-0.17.1-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68"}, - {file = "rpds_py-0.17.1.tar.gz", hash = "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e"}, + {file = "rpds_py-0.18.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1"}, + {file = "rpds_py-0.18.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e"}, + {file = "rpds_py-0.18.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88"}, + {file = "rpds_py-0.18.0-cp310-none-win32.whl", hash = "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337"}, + {file = "rpds_py-0.18.0-cp310-none-win_amd64.whl", hash = "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4"}, + {file = "rpds_py-0.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5"}, + {file = "rpds_py-0.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b"}, + {file = "rpds_py-0.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836"}, + {file = "rpds_py-0.18.0-cp311-none-win32.whl", hash = "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1"}, + {file = "rpds_py-0.18.0-cp311-none-win_amd64.whl", hash = "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0"}, + {file = "rpds_py-0.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3"}, + {file = "rpds_py-0.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f"}, + {file = "rpds_py-0.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7"}, + {file = "rpds_py-0.18.0-cp312-none-win32.whl", hash = "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98"}, + {file = "rpds_py-0.18.0-cp312-none-win_amd64.whl", hash = "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e"}, + {file = "rpds_py-0.18.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d"}, + {file = "rpds_py-0.18.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c"}, + {file = "rpds_py-0.18.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594"}, + {file = "rpds_py-0.18.0-cp38-none-win32.whl", hash = "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e"}, + {file = "rpds_py-0.18.0-cp38-none-win_amd64.whl", hash = "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33"}, + {file = "rpds_py-0.18.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9"}, + {file = "rpds_py-0.18.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024"}, + {file = "rpds_py-0.18.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20"}, + {file = "rpds_py-0.18.0-cp39-none-win32.whl", hash = "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7"}, + {file = "rpds_py-0.18.0-cp39-none-win_amd64.whl", hash = "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984"}, + {file = "rpds_py-0.18.0-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_10_12_x86_64.whl", hash = "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da"}, + {file = "rpds_py-0.18.0-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432"}, + {file = "rpds_py-0.18.0-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f"}, + {file = "rpds_py-0.18.0.tar.gz", hash = "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d"}, ] [[package]] @@ -3008,19 +2985,19 @@ tornado = ["tornado (>=5)"] [[package]] name = "setuptools" -version = "69.0.3" +version = "69.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" optional = false python-versions = ">=3.8" files = [ - {file = "setuptools-69.0.3-py3-none-any.whl", hash = "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05"}, - {file = "setuptools-69.0.3.tar.gz", hash = "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78"}, + {file = "setuptools-69.1.1-py3-none-any.whl", hash = "sha256:02fa291a0471b3a18b2b2481ed902af520c69e8ae0919c13da936542754b4c56"}, + {file = "setuptools-69.1.1.tar.gz", hash = "sha256:5c0806c7d9af348e6dd3777b4f4dbb42c7ad85b190104837488eab9a7c945cf8"}, ] [package.extras] docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"] -testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] -testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] +testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pip (>=19.1)", "pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-home (>=0.5)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff (>=0.2.1)", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"] +testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.2)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"] [[package]] name = "six" @@ -3046,24 +3023,24 @@ files = [ [[package]] name = "sniffio" -version = "1.3.0" +version = "1.3.1" description = "Sniff out which async library your code is running under" optional = false python-versions = ">=3.7" files = [ - {file = "sniffio-1.3.0-py3-none-any.whl", hash = "sha256:eecefdce1e5bbfb7ad2eeaabf7c1eeb404d7757c379bd1f7e5cce9d8bf425384"}, - {file = "sniffio-1.3.0.tar.gz", hash = "sha256:e60305c5e5d314f5389259b7f22aaa33d8f7dee49763119234af3755c55b9101"}, + {file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"}, + {file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"}, ] [[package]] name = "stevedore" -version = "5.1.0" +version = "5.2.0" description = "Manage dynamic plugins for Python applications" optional = false python-versions = ">=3.8" files = [ - {file = "stevedore-5.1.0-py3-none-any.whl", hash = "sha256:8cc040628f3cea5d7128f2e76cf486b2251a4e543c7b938f58d9a377f6694a2d"}, - {file = "stevedore-5.1.0.tar.gz", hash = "sha256:a54534acf9b89bc7ed264807013b505bf07f74dbe4bcfa37d32bd063870b087c"}, + {file = "stevedore-5.2.0-py3-none-any.whl", hash = "sha256:1c15d95766ca0569cad14cb6272d4d31dae66b011a929d7c18219c176ea1b5c9"}, + {file = "stevedore-5.2.0.tar.gz", hash = "sha256:46b93ca40e1114cea93d738a6c1e365396981bb6bb78c27045b7587c9473544d"}, ] [package.dependencies] @@ -3197,6 +3174,20 @@ files = [ [package.dependencies] types-urllib3 = "*" +[[package]] +name = "types-requests" +version = "2.31.0.20240218" +description = "Typing stubs for requests" +optional = false +python-versions = ">=3.8" +files = [ + {file = "types-requests-2.31.0.20240218.tar.gz", hash = "sha256:f1721dba8385958f504a5386240b92de4734e047a08a40751c1654d1ac3349c5"}, + {file = "types_requests-2.31.0.20240218-py3-none-any.whl", hash = "sha256:a82807ec6ddce8f00fe0e949da6d6bc1fbf1715420218a9640d695f70a9e5a9b"}, +] + +[package.dependencies] +urllib3 = ">=2" + [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -3210,13 +3201,13 @@ files = [ [[package]] name = "typing-extensions" -version = "4.9.0" +version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" files = [ - {file = "typing_extensions-4.9.0-py3-none-any.whl", hash = "sha256:af72aea155e91adfc61c3ae9e0e342dbc0cba726d6cba4b6c72c1f34e47291cd"}, - {file = "typing_extensions-4.9.0.tar.gz", hash = "sha256:23478f88c37f27d76ac8aee6c905017a143b0b1b886c3c9f66bc2fd94f9f5783"}, + {file = "typing_extensions-4.10.0-py3-none-any.whl", hash = "sha256:69b1a937c3a517342112fb4c6df7e72fc39a38e7891a5730ed4985b5214b5475"}, + {file = "typing_extensions-4.10.0.tar.gz", hash = "sha256:b0abd7c89e8fb96f98db18d86106ff1d90ab692004eb746cf6eda2682f91b3cb"}, ] [[package]] @@ -3429,7 +3420,7 @@ docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.link testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"] [extras] -all = ["aws-encryption-sdk", "aws-xray-sdk", "fastjsonschema", "jsonpath-ng", "pydantic"] +all = ["aws-xray-sdk", "fastjsonschema", "pydantic"] aws-sdk = ["boto3"] datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] @@ -3441,4 +3432,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "b0ec65e9e8df6741a33ed6b9e1dd616d4ddc1e0e36f0a95408f3931723e93818" +content-hash = "ff8aabf1c8d72613c8b43d6f85bd1127acfbc2f4d6ad7cc352e4f87ebaf6222a" diff --git a/pyproject.toml b/pyproject.toml index e10d2d44d44..2f0e1b8c47d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -101,8 +101,6 @@ all = [ "pydantic", "aws-xray-sdk", "fastjsonschema", - "aws-encryption-sdk", - "jsonpath-ng", ] # allow customers to run code locally without emulators (SAM CLI, etc.) aws-sdk = ["boto3"] diff --git a/tests/e2e/utils/lambda_layer/powertools_layer.py b/tests/e2e/utils/lambda_layer/powertools_layer.py index 0bc1dbe97c7..695c2019391 100644 --- a/tests/e2e/utils/lambda_layer/powertools_layer.py +++ b/tests/e2e/utils/lambda_layer/powertools_layer.py @@ -19,7 +19,7 @@ class LocalLambdaPowertoolsLayer(BaseLocalLambdaLayer): def __init__(self, output_dir: Path = CDK_OUT_PATH, architecture: Architecture = Architecture.X86_64): super().__init__(output_dir) - self.package = f"{SOURCE_CODE_ROOT_PATH}[all,redis]" + self.package = f"{SOURCE_CODE_ROOT_PATH}[all,redis,datamasking]" self.platform_args = self._resolve_platform(architecture) self.build_args = f"{self.platform_args} --only-binary=:all: --upgrade" From 6ac1d9b6b3c77cb05224259cbbb00dbb2885d758 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:03:09 +0100 Subject: [PATCH 0149/2666] chore(ci): layer docs update (#3855) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 20 ++-- docs/index.md | 142 ++++++++++++++--------------- examples/logger/sam/template.yaml | 2 +- examples/metrics/sam/template.yaml | 2 +- examples/tracer/sam/template.yaml | 2 +- 5 files changed, 80 insertions(+), 88 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8c33f4b0382..d82ed6a408b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,22 +4,13 @@ # Unreleased -## Bug Fixes - -* **typing:** ensure return type is a str when default_value is set ([#3840](https://github.com/aws-powertools/powertools-lambda-python/issues/3840)) - -## Documentation - -* **install:** make minimum install the default option then extra ([#3834](https://github.com/aws-powertools/powertools-lambda-python/issues/3834)) + +## [v2.34.2] - 2024-02-26 ## Maintenance -* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3835](https://github.com/aws-powertools/powertools-lambda-python/issues/3835)) -* **deps:** bump cryptography from 42.0.2 to 42.0.4 ([#3827](https://github.com/aws-powertools/powertools-lambda-python/issues/3827)) -* **deps-dev:** bump httpx from 0.26.0 to 0.27.0 ([#3828](https://github.com/aws-powertools/powertools-lambda-python/issues/3828)) -* **deps-dev:** bump aws-cdk from 2.128.0 to 2.129.0 ([#3831](https://github.com/aws-powertools/powertools-lambda-python/issues/3831)) -* **deps-dev:** bump the boto-typing group with 1 update ([#3836](https://github.com/aws-powertools/powertools-lambda-python/issues/3836)) -* **deps-dev:** bump aws-cdk-lib from 2.128.0 to 2.130.0 ([#3838](https://github.com/aws-powertools/powertools-lambda-python/issues/3838)) +* version bump +* **ci:** remove aws-encryption-sdk from Lambda layer due to cffi being tied to python version ([#3853](https://github.com/aws-powertools/powertools-lambda-python/issues/3853)) @@ -4445,7 +4436,8 @@ * Merge pull request [#5](https://github.com/aws-powertools/powertools-lambda-python/issues/5) from jfuss/feat/python38 -[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.1...HEAD +[Unreleased]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.2...HEAD +[v2.34.2]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.1...v2.34.2 [v2.34.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.34.0...v2.34.1 [v2.34.0]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.1...v2.34.0 [v2.33.1]: https://github.com/aws-powertools/powertools-lambda-python/compare/v2.33.0...v2.33.1 diff --git a/docs/index.md b/docs/index.md index 955cd5068bc..4b333d030b8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -67,8 +67,8 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc For the latter, make sure to replace `{region}` with your AWS region, e.g., `eu-west-1`. - * x86 architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64__{: .copyMe}:clipboard: - * ARM architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64__{: .copyMe}:clipboard: + * x86 architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65__{: .copyMe}:clipboard: + * ARM architecture: __arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65__{: .copyMe}:clipboard: ???+ note "Code snippets for popular infrastructure as code frameworks" @@ -81,7 +81,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Type: AWS::Serverless::Function Properties: Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 ``` === "Serverless framework" @@ -91,7 +91,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc hello: handler: lambda_function.lambda_handler layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 ``` === "CDK" @@ -107,7 +107,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -156,7 +156,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:64"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65"] source_code_hash = filebase64sha256("lambda_function_payload.zip") } @@ -209,7 +209,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2:64 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 ❯ amplify push -y @@ -220,7 +220,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2:64 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 ? Do you want to edit the local lambda function now? No ``` @@ -234,7 +234,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc Properties: Architectures: [arm64] Layers: - - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65 ``` === "Serverless framework" @@ -245,7 +245,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc handler: lambda_function.lambda_handler architecture: arm64 layers: - - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64 + - arn:aws:lambda:${aws:region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65 ``` === "CDK" @@ -261,7 +261,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc powertools_layer = aws_lambda.LayerVersion.from_layer_version_arn( self, id="lambda-powertools", - layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64" + layer_version_arn=f"arn:aws:lambda:{env.region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65" ) aws_lambda.Function(self, 'sample-app-lambda', @@ -311,7 +311,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc role = aws_iam_role.iam_for_lambda.arn handler = "index.test" runtime = "python3.9" - layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64"] + layers = ["arn:aws:lambda:{region}:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65"] architectures = ["arm64"] source_code_hash = filebase64sha256("lambda_function_payload.zip") @@ -367,7 +367,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc ? 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:AWSLambdaPowertoolsPythonV2-Arm64:64 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65 ❯ amplify push -y @@ -378,7 +378,7 @@ You can install Powertools for AWS Lambda (Python) using your favorite dependenc - 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:AWSLambdaPowertoolsPythonV2-Arm64:64 + ? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65 ? Do you want to edit the local lambda function now? No ``` @@ -409,74 +409,74 @@ In this context, `[aws-sdk]` is an alias to the `boto3` package. Due to dependen | Region | Layer ARN | | -------------------- | --------------------------------------------------------------------------------------------------------- | - | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | - | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:64**{: .copyMe}:clipboard: | + | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ap-southeast-4`** | **arn:aws:lambda:ap-southeast-4:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`ca-west-1`** | **arn:aws:lambda:ca-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | + | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2:65**{: .copyMe}:clipboard: | === "arm64" | Region | Layer ARN | | -------------------- | --------------------------------------------------------------------------------------------------------------- | - | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | - | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:64**{: .copyMe}:clipboard: | + | **`af-south-1`** | **arn:aws:lambda:af-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-east-1`** | **arn:aws:lambda:ap-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-northeast-1`** | **arn:aws:lambda:ap-northeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-northeast-2`** | **arn:aws:lambda:ap-northeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-northeast-3`** | **arn:aws:lambda:ap-northeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-south-1`** | **arn:aws:lambda:ap-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-south-2`** | **arn:aws:lambda:ap-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-southeast-1`** | **arn:aws:lambda:ap-southeast-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-southeast-2`** | **arn:aws:lambda:ap-southeast-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ap-southeast-3`** | **arn:aws:lambda:ap-southeast-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`ca-central-1`** | **arn:aws:lambda:ca-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-central-1`** | **arn:aws:lambda:eu-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-central-2`** | **arn:aws:lambda:eu-central-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-north-1`** | **arn:aws:lambda:eu-north-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-south-1`** | **arn:aws:lambda:eu-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-south-2`** | **arn:aws:lambda:eu-south-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-west-1`** | **arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-west-2`** | **arn:aws:lambda:eu-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`eu-west-3`** | **arn:aws:lambda:eu-west-3:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`il-central-1`** | **arn:aws:lambda:il-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`me-central-1`** | **arn:aws:lambda:me-central-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`me-south-1`** | **arn:aws:lambda:me-south-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`sa-east-1`** | **arn:aws:lambda:sa-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`us-east-1`** | **arn:aws:lambda:us-east-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`us-east-2`** | **arn:aws:lambda:us-east-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`us-west-1`** | **arn:aws:lambda:us-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | + | **`us-west-2`** | **arn:aws:lambda:us-west-2:017000801446:layer:AWSLambdaPowertoolsPythonV2-Arm64:65**{: .copyMe}:clipboard: | **Want to inspect the contents of the Layer?** The pre-signed URL to download this Lambda Layer will be within `Location` key in the CLI output. The CLI output will also contain the Powertools for AWS Lambda version it contains. ```bash title="AWS CLI command to download Lambda Layer content" -aws lambda get-layer-version-by-arn --arn arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:64 --region eu-west-1 +aws lambda get-layer-version-by-arn --arn arn:aws:lambda:eu-west-1:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 --region eu-west-1 ``` #### SAR diff --git a/examples/logger/sam/template.yaml b/examples/logger/sam/template.yaml index 9da3442fd67..7065010103d 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:AWSLambdaPowertoolsPythonV2:64 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 Resources: LoggerLambdaHandlerExample: diff --git a/examples/metrics/sam/template.yaml b/examples/metrics/sam/template.yaml index 6b49b380f78..2dc069d8d3e 100644 --- a/examples/metrics/sam/template.yaml +++ b/examples/metrics/sam/template.yaml @@ -15,7 +15,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:AWSLambdaPowertoolsPythonV2:64 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 Resources: CaptureLambdaHandlerExample: diff --git a/examples/tracer/sam/template.yaml b/examples/tracer/sam/template.yaml index 76336609d19..d4b6b4e1c10 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:AWSLambdaPowertoolsPythonV2:64 + - !Sub arn:aws:lambda:${AWS::Region}:017000801446:layer:AWSLambdaPowertoolsPythonV2:65 Resources: CaptureLambdaHandlerExample: From 8f55f63f44213dadc11cba388593dde3bac1c30b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 26 Feb 2024 17:03:22 +0100 Subject: [PATCH 0150/2666] chore(ci): bump version to 2.34.2 (#3854) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- aws_lambda_powertools/shared/version.py | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/aws_lambda_powertools/shared/version.py b/aws_lambda_powertools/shared/version.py index 6a91b14cb8f..c733e9bcae0 100644 --- a/aws_lambda_powertools/shared/version.py +++ b/aws_lambda_powertools/shared/version.py @@ -1,3 +1,3 @@ """Exposes version constant to avoid circular dependencies.""" -VERSION = "2.34.1" +VERSION = "2.34.2" diff --git a/pyproject.toml b/pyproject.toml index 2f0e1b8c47d..0df5354c4f3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "aws_lambda_powertools" -version = "2.34.1" +version = "2.34.2" 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"] From d139c83e09ace18e54f4ec9576f67d85d31177be Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:35:18 -0300 Subject: [PATCH 0151/2666] chore(deps): bump squidfunk/mkdocs-material from `43b898a` to `49d1bfd` in /docs (#3857) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `43b898a` to `49d1bfd`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 4445acc55c7..20e558ca6cf 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:43b898a5520bbe5ee0080568c002491cd8fcd2269e64f7ad2ba4c9c419acb866 +FROM squidfunk/mkdocs-material@sha256:49d1bfdaf457c5ac20a93ff59a5b57b762ace5606fc564ac2e195abf315f14ee # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From 92ea28f3e4a37c283fe8e4377f1af1396da406f2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:36:06 -0300 Subject: [PATCH 0152/2666] chore(deps): bump codecov/codecov-action from 4.0.2 to 4.1.0 (#3856) Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 4.0.2 to 4.1.0. - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1...54bcd8715eee62d40e33596ef5e8f0f48dbbccab) --- updated-dependencies: - dependency-name: codecov/codecov-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- .github/workflows/quality_check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/quality_check.yml b/.github/workflows/quality_check.yml index 8332bdb0ae0..2a203d5989f 100644 --- a/.github/workflows/quality_check.yml +++ b/.github/workflows/quality_check.yml @@ -71,7 +71,7 @@ jobs: - name: Complexity baseline run: make complexity-baseline - name: Upload coverage to Codecov - uses: codecov/codecov-action@0cfda1dd0a4ad9efc75517f399d859cd1ea4ced1 # 4.0.2 + uses: codecov/codecov-action@54bcd8715eee62d40e33596ef5e8f0f48dbbccab # 4.1.0 with: file: ./coverage.xml env_vars: PYTHON From 51705b8c98165320457f02773f12bb8d9a2baefa Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 08:37:38 -0300 Subject: [PATCH 0153/2666] chore(ci): changelog rebuild (#3858) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d82ed6a408b..51cc89274f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,13 +4,37 @@ # Unreleased +## Maintenance + + ## [v2.34.2] - 2024-02-26 +## Bug Fixes + +* **typing:** ensure return type is a str when default_value is set ([#3840](https://github.com/aws-powertools/powertools-lambda-python/issues/3840)) + +## Documentation + +* **install:** make minimum install the default option then extra ([#3834](https://github.com/aws-powertools/powertools-lambda-python/issues/3834)) + +## Features + +* **event-source:** add function to get multi-value query string params by name ([#3846](https://github.com/aws-powertools/powertools-lambda-python/issues/3846)) + ## Maintenance * version bump * **ci:** remove aws-encryption-sdk from Lambda layer due to cffi being tied to python version ([#3853](https://github.com/aws-powertools/powertools-lambda-python/issues/3853)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3844](https://github.com/aws-powertools/powertools-lambda-python/issues/3844)) +* **deps:** bump cryptography from 42.0.2 to 42.0.4 ([#3827](https://github.com/aws-powertools/powertools-lambda-python/issues/3827)) +* **deps:** bump codecov/codecov-action from 4.0.1 to 4.0.2 ([#3842](https://github.com/aws-powertools/powertools-lambda-python/issues/3842)) +* **deps:** bump the layer-balancer group in /layer/scripts/layer-balancer with 3 updates ([#3835](https://github.com/aws-powertools/powertools-lambda-python/issues/3835)) +* **deps-dev:** bump httpx from 0.26.0 to 0.27.0 ([#3828](https://github.com/aws-powertools/powertools-lambda-python/issues/3828)) +* **deps-dev:** bump aws-cdk from 2.128.0 to 2.129.0 ([#3831](https://github.com/aws-powertools/powertools-lambda-python/issues/3831)) +* **deps-dev:** bump the boto-typing group with 1 update ([#3836](https://github.com/aws-powertools/powertools-lambda-python/issues/3836)) +* **deps-dev:** bump aws-cdk from 2.129.0 to 2.130.0 ([#3843](https://github.com/aws-powertools/powertools-lambda-python/issues/3843)) +* **deps-dev:** bump aws-cdk-lib from 2.128.0 to 2.130.0 ([#3838](https://github.com/aws-powertools/powertools-lambda-python/issues/3838)) From 6c7dc6f06b577b41358ed81f00c4fb71a3de266b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:49:45 +0100 Subject: [PATCH 0154/2666] chore(deps-dev): bump black from 24.1.1 to 24.2.0 (#3760) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena Co-authored-by: Cavalcante Damascena --- aws_lambda_powertools/logging/__init__.py | 1 + aws_lambda_powertools/logging/logger.py | 6 +-- aws_lambda_powertools/metrics/__init__.py | 1 + .../middleware_factory/__init__.py | 1 + aws_lambda_powertools/shared/functions.py | 9 ++--- aws_lambda_powertools/tracing/__init__.py | 1 - aws_lambda_powertools/tracing/tracer.py | 6 +-- aws_lambda_powertools/utilities/batch/base.py | 11 ++++-- .../utilities/batch/exceptions.py | 1 + .../utilities/data_classes/common.py | 2 +- .../utilities/data_masking/base.py | 12 ++---- .../provider/kms/aws_encryption_sdk.py | 1 - .../utilities/idempotency/exceptions.py | 1 - .../utilities/idempotency/idempotency.py | 1 + .../idempotency/serialization/base.py | 1 + .../utilities/parameters/appconfig.py | 1 - .../utilities/parameters/base.py | 7 ++-- .../utilities/parameters/dynamodb.py | 1 - .../utilities/parameters/secrets.py | 1 - .../utilities/parameters/ssm.py | 37 +++++++------------ .../utilities/parser/__init__.py | 1 + .../utilities/parser/parser.py | 6 +-- .../utilities/serialization.py | 1 + poetry.lock | 26 ++++++------- pyproject.toml | 2 +- .../event_handler/test_api_gateway.py | 33 ++++++----------- tests/functional/test_logger.py | 6 +-- .../test_logger_powertools_formatter.py | 1 + tests/functional/test_utilities_parameters.py | 3 +- tests/unit/parser/test_kinesis.py | 3 +- tests/unit/test_tracing.py | 3 +- 31 files changed, 76 insertions(+), 111 deletions(-) diff --git a/aws_lambda_powertools/logging/__init__.py b/aws_lambda_powertools/logging/__init__.py index 0456b202ffa..2c9532ef540 100644 --- a/aws_lambda_powertools/logging/__init__.py +++ b/aws_lambda_powertools/logging/__init__.py @@ -1,5 +1,6 @@ """Logging utility """ + from .logger import Logger __all__ = ["Logger"] diff --git a/aws_lambda_powertools/logging/logger.py b/aws_lambda_powertools/logging/logger.py index ab159061bff..1e21d6680af 100644 --- a/aws_lambda_powertools/logging/logger.py +++ b/aws_lambda_powertools/logging/logger.py @@ -345,8 +345,7 @@ def inject_lambda_context( log_event: Optional[bool] = None, correlation_id_path: Optional[str] = None, clear_state: Optional[bool] = False, - ) -> AnyCallableT: - ... + ) -> AnyCallableT: ... @overload def inject_lambda_context( @@ -355,8 +354,7 @@ def inject_lambda_context( log_event: Optional[bool] = None, correlation_id_path: Optional[str] = None, clear_state: Optional[bool] = False, - ) -> Callable[[AnyCallableT], AnyCallableT]: - ... + ) -> Callable[[AnyCallableT], AnyCallableT]: ... def inject_lambda_context( self, diff --git a/aws_lambda_powertools/metrics/__init__.py b/aws_lambda_powertools/metrics/__init__.py index b8c94478816..cafd348b8ec 100644 --- a/aws_lambda_powertools/metrics/__init__.py +++ b/aws_lambda_powertools/metrics/__init__.py @@ -1,5 +1,6 @@ """CloudWatch Embedded Metric Format utility """ + from aws_lambda_powertools.metrics.base import MetricResolution, MetricUnit, single_metric from aws_lambda_powertools.metrics.exceptions import ( MetricResolutionError, diff --git a/aws_lambda_powertools/middleware_factory/__init__.py b/aws_lambda_powertools/middleware_factory/__init__.py index 9d57d843ec2..b44d49d6987 100644 --- a/aws_lambda_powertools/middleware_factory/__init__.py +++ b/aws_lambda_powertools/middleware_factory/__init__.py @@ -1,4 +1,5 @@ """ Utilities to enhance middlewares """ + from .factory import lambda_handler_decorator __all__ = ["lambda_handler_decorator"] diff --git a/aws_lambda_powertools/shared/functions.py b/aws_lambda_powertools/shared/functions.py index 9765f55c025..ee274498260 100644 --- a/aws_lambda_powertools/shared/functions.py +++ b/aws_lambda_powertools/shared/functions.py @@ -57,18 +57,15 @@ def resolve_max_age(env: str, choice: Optional[int]) -> int: @overload -def resolve_env_var_choice(env: Optional[str], choice: float) -> float: - ... +def resolve_env_var_choice(env: Optional[str], choice: float) -> float: ... @overload -def resolve_env_var_choice(env: Optional[str], choice: str) -> str: - ... +def resolve_env_var_choice(env: Optional[str], choice: str) -> str: ... @overload -def resolve_env_var_choice(env: Optional[str], choice: Optional[str]) -> str: - ... +def resolve_env_var_choice(env: Optional[str], choice: Optional[str]) -> str: ... def resolve_env_var_choice( diff --git a/aws_lambda_powertools/tracing/__init__.py b/aws_lambda_powertools/tracing/__init__.py index f45ac1fb73e..1031ae4aec6 100644 --- a/aws_lambda_powertools/tracing/__init__.py +++ b/aws_lambda_powertools/tracing/__init__.py @@ -1,7 +1,6 @@ """Tracing utility """ - from .extensions import aiohttp_trace_config from .tracer import Tracer diff --git a/aws_lambda_powertools/tracing/tracer.py b/aws_lambda_powertools/tracing/tracer.py index 3004e5505c8..b30467188f9 100644 --- a/aws_lambda_powertools/tracing/tracer.py +++ b/aws_lambda_powertools/tracing/tracer.py @@ -345,8 +345,7 @@ def decorate(event, context, **kwargs): # see #465 @overload - def capture_method(self, method: "AnyCallableT") -> "AnyCallableT": - ... # pragma: no cover + def capture_method(self, method: "AnyCallableT") -> "AnyCallableT": ... # pragma: no cover @overload def capture_method( @@ -354,8 +353,7 @@ def capture_method( method: None = None, capture_response: Optional[bool] = None, capture_error: Optional[bool] = None, - ) -> Callable[["AnyCallableT"], "AnyCallableT"]: - ... # pragma: no cover + ) -> Callable[["AnyCallableT"], "AnyCallableT"]: ... # pragma: no cover def capture_method( self, diff --git a/aws_lambda_powertools/utilities/batch/base.py b/aws_lambda_powertools/utilities/batch/base.py index a158eafdad0..569467f2248 100644 --- a/aws_lambda_powertools/utilities/batch/base.py +++ b/aws_lambda_powertools/utilities/batch/base.py @@ -339,12 +339,15 @@ def _collect_dynamodb_failures(self): return failures @overload - def _to_batch_type(self, record: dict, event_type: EventType, model: "BatchTypeModels") -> "BatchTypeModels": - ... # pragma: no cover + def _to_batch_type( + self, + record: dict, + event_type: EventType, + model: "BatchTypeModels", + ) -> "BatchTypeModels": ... # pragma: no cover @overload - def _to_batch_type(self, record: dict, event_type: EventType) -> EventSourceDataClassTypes: - ... # pragma: no cover + def _to_batch_type(self, record: dict, event_type: EventType) -> EventSourceDataClassTypes: ... # pragma: no cover def _to_batch_type(self, record: dict, event_type: EventType, model: Optional["BatchTypeModels"] = None): if model is not None: diff --git a/aws_lambda_powertools/utilities/batch/exceptions.py b/aws_lambda_powertools/utilities/batch/exceptions.py index 89659e42bf8..a3eefbb9cea 100644 --- a/aws_lambda_powertools/utilities/batch/exceptions.py +++ b/aws_lambda_powertools/utilities/batch/exceptions.py @@ -1,6 +1,7 @@ """ Batch processing exceptions """ + from __future__ import annotations import traceback diff --git a/aws_lambda_powertools/utilities/data_classes/common.py b/aws_lambda_powertools/utilities/data_classes/common.py index 41fbe5cd0de..104993deae8 100644 --- a/aws_lambda_powertools/utilities/data_classes/common.py +++ b/aws_lambda_powertools/utilities/data_classes/common.py @@ -193,7 +193,7 @@ def get_multi_value_query_string_values( self, name: str, default_values: Optional[List[str]] = None, - ) ->List[str]: + ) -> List[str]: """Get multi-value query string parameter values by name Parameters diff --git a/aws_lambda_powertools/utilities/data_masking/base.py b/aws_lambda_powertools/utilities/data_masking/base.py index c2557dcef24..5274aac3b8a 100644 --- a/aws_lambda_powertools/utilities/data_masking/base.py +++ b/aws_lambda_powertools/utilities/data_masking/base.py @@ -85,20 +85,16 @@ def decrypt( ) @overload - def erase(self, data, fields: None) -> str: - ... + def erase(self, data, fields: None) -> str: ... @overload - def erase(self, data: list, fields: list[str]) -> list[str]: - ... + def erase(self, data: list, fields: list[str]) -> list[str]: ... @overload - def erase(self, data: tuple, fields: list[str]) -> tuple[str]: - ... + def erase(self, data: tuple, fields: list[str]) -> tuple[str]: ... @overload - def erase(self, data: dict, fields: list[str]) -> dict: - ... + def erase(self, data: dict, fields: list[str]) -> dict: ... def erase(self, data: Sequence | Mapping, fields: list[str] | None = None) -> str | list[str] | tuple[str] | dict: return self._apply_action(data=data, fields=fields, action=self.provider.erase) diff --git a/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py b/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py index bbdbb0bad6f..657a812337f 100644 --- a/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py +++ b/aws_lambda_powertools/utilities/data_masking/provider/kms/aws_encryption_sdk.py @@ -105,7 +105,6 @@ def decrypt(self, data: str, provider_options: dict | None = None, **encryption_ class KMSKeyProvider: - """ The KMSKeyProvider is responsible for assembling an AWS Key Management Service (KMS) client, a caching mechanism, and a keyring for secure key management and data encryption. diff --git a/aws_lambda_powertools/utilities/idempotency/exceptions.py b/aws_lambda_powertools/utilities/idempotency/exceptions.py index 55ec662799e..27f319a5266 100644 --- a/aws_lambda_powertools/utilities/idempotency/exceptions.py +++ b/aws_lambda_powertools/utilities/idempotency/exceptions.py @@ -2,7 +2,6 @@ Idempotency errors """ - from typing import Optional, Union from aws_lambda_powertools.utilities.idempotency.persistence.datarecord import DataRecord diff --git a/aws_lambda_powertools/utilities/idempotency/idempotency.py b/aws_lambda_powertools/utilities/idempotency/idempotency.py index 94306dfa2c5..9593655b3cd 100644 --- a/aws_lambda_powertools/utilities/idempotency/idempotency.py +++ b/aws_lambda_powertools/utilities/idempotency/idempotency.py @@ -1,6 +1,7 @@ """ Primary interface for idempotent Lambda functions utility """ + import functools import logging import os diff --git a/aws_lambda_powertools/utilities/idempotency/serialization/base.py b/aws_lambda_powertools/utilities/idempotency/serialization/base.py index 45317bd0315..ba41b23dbe4 100644 --- a/aws_lambda_powertools/utilities/idempotency/serialization/base.py +++ b/aws_lambda_powertools/utilities/idempotency/serialization/base.py @@ -1,6 +1,7 @@ """ Serialization for supporting idempotency """ + from abc import ABC, abstractmethod from typing import Any, Dict diff --git a/aws_lambda_powertools/utilities/parameters/appconfig.py b/aws_lambda_powertools/utilities/parameters/appconfig.py index d5a9b7856e4..b29d256a0a0 100644 --- a/aws_lambda_powertools/utilities/parameters/appconfig.py +++ b/aws_lambda_powertools/utilities/parameters/appconfig.py @@ -2,7 +2,6 @@ AWS App Config configuration retrieval and caching utility """ - import os from typing import TYPE_CHECKING, Any, Dict, Optional, Union diff --git a/aws_lambda_powertools/utilities/parameters/base.py b/aws_lambda_powertools/utilities/parameters/base.py index 710634636d0..5ce06589613 100644 --- a/aws_lambda_powertools/utilities/parameters/base.py +++ b/aws_lambda_powertools/utilities/parameters/base.py @@ -1,6 +1,7 @@ """ Base for Parameter providers """ + from __future__ import annotations import base64 @@ -372,8 +373,7 @@ def transform_value( transform: TransformOptions, raise_on_transform_error: bool = False, key: str = "", -) -> Dict[str, Any]: - ... +) -> Dict[str, Any]: ... @overload @@ -382,8 +382,7 @@ def transform_value( transform: TransformOptions, raise_on_transform_error: bool = False, key: str = "", -) -> Optional[Union[str, bytes, Dict[str, Any]]]: - ... +) -> Optional[Union[str, bytes, Dict[str, Any]]]: ... def transform_value( diff --git a/aws_lambda_powertools/utilities/parameters/dynamodb.py b/aws_lambda_powertools/utilities/parameters/dynamodb.py index d6c82fd3293..e008e3b62db 100644 --- a/aws_lambda_powertools/utilities/parameters/dynamodb.py +++ b/aws_lambda_powertools/utilities/parameters/dynamodb.py @@ -2,7 +2,6 @@ Amazon DynamoDB parameter retrieval and caching utility """ - from typing import TYPE_CHECKING, Dict, Optional import boto3 diff --git a/aws_lambda_powertools/utilities/parameters/secrets.py b/aws_lambda_powertools/utilities/parameters/secrets.py index dc7bc2b0053..beb4bb80846 100644 --- a/aws_lambda_powertools/utilities/parameters/secrets.py +++ b/aws_lambda_powertools/utilities/parameters/secrets.py @@ -2,7 +2,6 @@ AWS Secrets Manager parameter retrieval and caching utility """ - import os from typing import TYPE_CHECKING, Any, Dict, Optional, Union diff --git a/aws_lambda_powertools/utilities/parameters/ssm.py b/aws_lambda_powertools/utilities/parameters/ssm.py index 7df0e66c027..1be07e7c9f0 100644 --- a/aws_lambda_powertools/utilities/parameters/ssm.py +++ b/aws_lambda_powertools/utilities/parameters/ssm.py @@ -1,6 +1,7 @@ """ AWS SSM Parameter retrieval and caching utility """ + from __future__ import annotations import os @@ -553,8 +554,7 @@ def get_parameter( force_fetch: bool = False, max_age: Optional[int] = None, **sdk_options, -) -> str: - ... +) -> str: ... @overload @@ -565,8 +565,7 @@ def get_parameter( force_fetch: bool = False, max_age: Optional[int] = None, **sdk_options, -) -> dict: - ... +) -> dict: ... @overload @@ -577,8 +576,7 @@ def get_parameter( force_fetch: bool = False, max_age: Optional[int] = None, **sdk_options, -) -> Union[str, dict, bytes]: - ... +) -> Union[str, dict, bytes]: ... @overload @@ -589,8 +587,7 @@ def get_parameter( force_fetch: bool = False, max_age: Optional[int] = None, **sdk_options, -) -> bytes: - ... +) -> bytes: ... def get_parameter( @@ -683,8 +680,7 @@ def get_parameters( max_age: Optional[int] = None, raise_on_transform_error: bool = False, **sdk_options, -) -> Dict[str, str]: - ... +) -> Dict[str, str]: ... @overload @@ -697,8 +693,7 @@ def get_parameters( max_age: Optional[int] = None, raise_on_transform_error: bool = False, **sdk_options, -) -> Dict[str, dict]: - ... +) -> Dict[str, dict]: ... @overload @@ -711,8 +706,7 @@ def get_parameters( max_age: Optional[int] = None, raise_on_transform_error: bool = False, **sdk_options, -) -> Dict[str, bytes]: - ... +) -> Dict[str, bytes]: ... @overload @@ -725,8 +719,7 @@ def get_parameters( max_age: Optional[int] = None, raise_on_transform_error: bool = False, **sdk_options, -) -> Union[Dict[str, bytes], Dict[str, dict], Dict[str, str]]: - ... +) -> Union[Dict[str, bytes], Dict[str, dict], Dict[str, str]]: ... def get_parameters( @@ -825,8 +818,7 @@ def get_parameters_by_name( decrypt: Optional[bool] = None, max_age: Optional[int] = None, raise_on_error: bool = True, -) -> Dict[str, str]: - ... +) -> Dict[str, str]: ... @overload @@ -836,8 +828,7 @@ def get_parameters_by_name( decrypt: Optional[bool] = None, max_age: Optional[int] = None, raise_on_error: bool = True, -) -> Dict[str, bytes]: - ... +) -> Dict[str, bytes]: ... @overload @@ -847,8 +838,7 @@ def get_parameters_by_name( decrypt: Optional[bool] = None, max_age: Optional[int] = None, raise_on_error: bool = True, -) -> Dict[str, Dict[str, Any]]: - ... +) -> Dict[str, Dict[str, Any]]: ... @overload @@ -858,8 +848,7 @@ def get_parameters_by_name( decrypt: Optional[bool] = None, max_age: Optional[int] = None, raise_on_error: bool = True, -) -> Union[Dict[str, str], Dict[str, dict]]: - ... +) -> Union[Dict[str, str], Dict[str, dict]]: ... def get_parameters_by_name( diff --git a/aws_lambda_powertools/utilities/parser/__init__.py b/aws_lambda_powertools/utilities/parser/__init__.py index 1bc67934b13..ad19168bb29 100644 --- a/aws_lambda_powertools/utilities/parser/__init__.py +++ b/aws_lambda_powertools/utilities/parser/__init__.py @@ -1,5 +1,6 @@ """Advanced event_parser utility """ + from . import envelopes from .envelopes import BaseEnvelope from .parser import event_parser, parse diff --git a/aws_lambda_powertools/utilities/parser/parser.py b/aws_lambda_powertools/utilities/parser/parser.py index 91d2763f4ec..a9a89db8a6a 100644 --- a/aws_lambda_powertools/utilities/parser/parser.py +++ b/aws_lambda_powertools/utilities/parser/parser.py @@ -104,13 +104,11 @@ def handler(event: Order, context: LambdaContext): @overload -def parse(event: Dict[str, Any], model: Type[Model]) -> Model: - ... # pragma: no cover +def parse(event: Dict[str, Any], model: Type[Model]) -> Model: ... # pragma: no cover @overload -def parse(event: Dict[str, Any], model: Type[Model], envelope: Type[Envelope]) -> Model: - ... # pragma: no cover +def parse(event: Dict[str, Any], model: Type[Model], envelope: Type[Envelope]) -> Model: ... # pragma: no cover def parse(event: Dict[str, Any], model: Type[Model], envelope: Optional[Type[Envelope]] = None): diff --git a/aws_lambda_powertools/utilities/serialization.py b/aws_lambda_powertools/utilities/serialization.py index ef76eec70e2..cb5289ae4af 100644 --- a/aws_lambda_powertools/utilities/serialization.py +++ b/aws_lambda_powertools/utilities/serialization.py @@ -1,4 +1,5 @@ """Standalone functions to serialize/deserialize common data structures""" + import base64 import json from typing import Any, Callable diff --git a/poetry.lock b/poetry.lock index 678896ba721..1fc250f11ce 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.0 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. [[package]] name = "anyio" @@ -330,17 +330,17 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "boto3" -version = "1.34.49" +version = "1.34.50" description = "The AWS SDK for Python" optional = false python-versions = ">= 3.8" files = [ - {file = "boto3-1.34.49-py3-none-any.whl", hash = "sha256:ce8d1de03024f52a1810e8d71ad4dba3a5b9bb48b35567191500e3432a9130b4"}, - {file = "boto3-1.34.49.tar.gz", hash = "sha256:96b9dc85ce8d52619b56ca7b1ac1423eaf0af5ce132904bcc8aa81396eec2abf"}, + {file = "boto3-1.34.50-py3-none-any.whl", hash = "sha256:8d709365231234bc4f0ca98fdf33a25eeebf78072853c6aa3d259f0f5cf09877"}, + {file = "boto3-1.34.50.tar.gz", hash = "sha256:290952be7899560039cb0042e8a2354f61a7dead0d0ca8bea6ba901930df0468"}, ] [package.dependencies] -botocore = ">=1.34.49,<1.35.0" +botocore = ">=1.34.50,<1.35.0" jmespath = ">=0.7.1,<2.0.0" s3transfer = ">=0.10.0,<0.11.0" @@ -349,13 +349,13 @@ crt = ["botocore[crt] (>=1.21.0,<2.0a0)"] [[package]] name = "botocore" -version = "1.34.49" +version = "1.34.50" description = "Low-level, data-driven core of boto 3." optional = false python-versions = ">= 3.8" files = [ - {file = "botocore-1.34.49-py3-none-any.whl", hash = "sha256:4ed9d7603a04b5bb5bd5de63b513bc2c8a7e8b1cd0088229c5ceb461161f43b6"}, - {file = "botocore-1.34.49.tar.gz", hash = "sha256:d89410bc60673eaff1699f3f1fdcb0e3a5e1f7a6a048c0d88c3ce5c3549433ec"}, + {file = "botocore-1.34.50-py3-none-any.whl", hash = "sha256:fda510559dbe796eefdb59561cc81be1b99afba3dee53fd23db9a3d587adc0ab"}, + {file = "botocore-1.34.50.tar.gz", hash = "sha256:33ab82cb96c4bb684f0dbafb071808e4817d83debc88b223e7d988256370c6d7"}, ] [package.dependencies] @@ -2940,13 +2940,13 @@ pbr = "*" [[package]] name = "sentry-sdk" -version = "1.40.5" +version = "1.40.6" description = "Python client for Sentry (https://sentry.io)" optional = false python-versions = "*" files = [ - {file = "sentry-sdk-1.40.5.tar.gz", hash = "sha256:d2dca2392cc5c9a2cc9bb874dd7978ebb759682fe4fe889ee7e970ee8dd1c61e"}, - {file = "sentry_sdk-1.40.5-py2.py3-none-any.whl", hash = "sha256:d188b407c9bacbe2a50a824e1f8fb99ee1aeb309133310488c570cb6d7056643"}, + {file = "sentry-sdk-1.40.6.tar.gz", hash = "sha256:f143f3fb4bb57c90abef6e2ad06b5f6f02b2ca13e4060ec5c0549c7a9ccce3fa"}, + {file = "sentry_sdk-1.40.6-py2.py3-none-any.whl", hash = "sha256:becda09660df63e55f307570e9817c664392655a7328bbc414b507e9cb874c67"}, ] [package.dependencies] @@ -2972,7 +2972,7 @@ huey = ["huey (>=2)"] loguru = ["loguru (>=0.5)"] opentelemetry = ["opentelemetry-distro (>=0.35b0)"] opentelemetry-experimental = ["opentelemetry-distro (>=0.40b0,<1.0)", "opentelemetry-instrumentation-aiohttp-client (>=0.40b0,<1.0)", "opentelemetry-instrumentation-django (>=0.40b0,<1.0)", "opentelemetry-instrumentation-fastapi (>=0.40b0,<1.0)", "opentelemetry-instrumentation-flask (>=0.40b0,<1.0)", "opentelemetry-instrumentation-requests (>=0.40b0,<1.0)", "opentelemetry-instrumentation-sqlite3 (>=0.40b0,<1.0)", "opentelemetry-instrumentation-urllib (>=0.40b0,<1.0)"] -pure-eval = ["asttokens", "executing", "pure-eval"] +pure-eval = ["asttokens", "executing", "pure_eval"] pymongo = ["pymongo (>=3.1)"] pyspark = ["pyspark (>=2.4.4)"] quart = ["blinker (>=1.1)", "quart (>=0.16.1)"] @@ -3432,4 +3432,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "ff8aabf1c8d72613c8b43d6f85bd1127acfbc2f4d6ad7cc352e4f87ebaf6222a" +content-hash = "56925f0c4bf816e507650c4f78ea418822a2afb8a9f6d6d7828127811a9a8223" diff --git a/pyproject.toml b/pyproject.toml index 0df5354c4f3..ac571066035 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ jsonpath-ng = { version = "^1.6.0", optional = true } [tool.poetry.dev-dependencies] coverage = { extras = ["toml"], version = "^7.4" } pytest = "^8.0.1" -black = "^24.1" +black = "^24.2" boto3 = "^1.26.164" isort = "^5.13.2" pytest-cov = "^4.1.0" diff --git a/tests/functional/event_handler/test_api_gateway.py b/tests/functional/event_handler/test_api_gateway.py index 9c98faff062..fa166bac77e 100644 --- a/tests/functional/event_handler/test_api_gateway.py +++ b/tests/functional/event_handler/test_api_gateway.py @@ -716,16 +716,13 @@ def test_cors_preflight(): app = ApiGatewayResolver(cors=CORSConfig()) @app.get("/foo") - def foo_cors(): - ... + def foo_cors(): ... @app.route(method="delete", rule="/foo") - def foo_delete_cors(): - ... + def foo_delete_cors(): ... @app.post("/foo", cors=False) - def post_no_cors(): - ... + def post_no_cors(): ... # WHEN calling the handler result = app({"path": "/foo", "httpMethod": "OPTIONS", "headers": {"Origin": "http://example.org"}}, None) @@ -756,8 +753,7 @@ def custom_preflight(): ) @app.route(method="CUSTOM", rule="/some-call", cors=True) - def custom_method(): - ... + def custom_method(): ... # AND the request includes an origin headers = {"Origin": "https://example.org"} @@ -1094,8 +1090,7 @@ def pay_foo(): raise ValueError("should not be matching") @app.get("/foo") - def foo(): - ... + def foo(): ... # WHEN calling handler response = app({"httpMethod": "GET", "path": path}, None) @@ -1116,8 +1111,7 @@ def test_remove_prefix_by_regex(path: str): app = ApiGatewayResolver(strip_prefixes=[re.compile(r"/(dev|stg)")]) @app.get("/foo") - def foo(): - ... + def foo(): ... response = app({"httpMethod": "GET", "path": path}, None) @@ -1128,8 +1122,7 @@ def test_empty_path_when_using_regexes(): app = ApiGatewayResolver(strip_prefixes=[re.compile(r"/(dev|stg)")]) @app.get("/") - def foo(): - ... + def foo(): ... response = app({"httpMethod": "GET", "path": "/dev"}, None) @@ -1151,8 +1144,7 @@ def test_ignore_invalid(prefix): app = ApiGatewayResolver(strip_prefixes=prefix) @app.get("/foo/status") - def foo(): - ... + def foo(): ... # WHEN calling handler response = app({"httpMethod": "GET", "path": "/foo/status"}, None) @@ -1473,8 +1465,7 @@ def handle_validation_error(ex: RequestValidationError): ) @app.get("/my/path") - def get_lambda(param: int): - ... + def get_lambda(param: int): ... # WHEN calling the event handler # AND a RequestValidationError is raised @@ -1502,8 +1493,7 @@ def handle_validation_error(ex: RequestValidationError): ) @app.get("/my/path") - def get_lambda(param: int): - ... + def get_lambda(param: int): ... # WHEN calling the event handler # AND a RequestValidationError is raised @@ -1519,8 +1509,7 @@ def test_data_validation_error(): app = ApiGatewayResolver(enable_validation=True) @app.get("/my/path") - def get_lambda(param: int): - ... + def get_lambda(param: int): ... # WHEN calling the event handler # AND a RequestValidationError is raised diff --git a/tests/functional/test_logger.py b/tests/functional/test_logger.py index fc6e5b98ee8..d9e3b8d4e37 100644 --- a/tests/functional/test_logger.py +++ b/tests/functional/test_logger.py @@ -575,8 +575,7 @@ def test_logger_set_correlation_id_path_custom_functions(lambda_context, stdout, logger = Logger(service=service_name, stream=stdout) @logger.inject_lambda_context(correlation_id_path="Records[*].powertools_json(body).id") - def handler(event, context): - ... + def handler(event, context): ... # WHEN handler is called request_id = "xxx-111-222" @@ -719,8 +718,7 @@ def handler(event, context): def test_logger_custom_formatter_has_standard_and_custom_keys(stdout, service_name, lambda_context): - class CustomFormatter(LambdaPowertoolsFormatter): - ... + class CustomFormatter(LambdaPowertoolsFormatter): ... # GIVEN a Logger is initialized with a custom formatter logger = Logger(service=service_name, stream=stdout, logger_formatter=CustomFormatter(), my_key="value") diff --git a/tests/functional/test_logger_powertools_formatter.py b/tests/functional/test_logger_powertools_formatter.py index 62f3f36c025..b9113485a47 100644 --- a/tests/functional/test_logger_powertools_formatter.py +++ b/tests/functional/test_logger_powertools_formatter.py @@ -1,4 +1,5 @@ """aws_lambda_logging tests.""" + import io import json import os diff --git a/tests/functional/test_utilities_parameters.py b/tests/functional/test_utilities_parameters.py index 2ee544f87c8..5ff043f7ed3 100644 --- a/tests/functional/test_utilities_parameters.py +++ b/tests/functional/test_utilities_parameters.py @@ -655,8 +655,7 @@ class TestProvider(BaseProvider): def _get(self, name: str, **kwargs) -> str: return mock_value - def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]: - ... + def _get_multiple(self, path: str, **kwargs) -> Dict[str, str]: ... monkeypatch.setitem(parameters.base.DEFAULT_PROVIDERS, "ssm", TestProvider()) monkeypatch.setitem(parameters.base.DEFAULT_PROVIDERS, "secrets", TestProvider()) diff --git a/tests/unit/parser/test_kinesis.py b/tests/unit/parser/test_kinesis.py index e8b1ae87378..730759f1230 100644 --- a/tests/unit/parser/test_kinesis.py +++ b/tests/unit/parser/test_kinesis.py @@ -94,8 +94,7 @@ def test_kinesis_stream_event_cloudwatch_logs_data_extraction(): def test_kinesis_stream_event_cloudwatch_logs_data_extraction_fails_with_custom_model(): # GIVEN a custom model replaces Kinesis Record Data bytes - class DummyModel(BaseModel): - ... + class DummyModel(BaseModel): ... raw_event = load_event("kinesisStreamCloudWatchLogsEvent.json") stream_data = KinesisDataStreamModel(**raw_event) diff --git a/tests/unit/test_tracing.py b/tests/unit/test_tracing.py index fdb7310495b..7b09bcde885 100644 --- a/tests/unit/test_tracing.py +++ b/tests/unit/test_tracing.py @@ -48,8 +48,7 @@ def in_subsegment(self, *args, **kwargs): def patch(self, *args, **kwargs): return self.patch_mock(*args, **kwargs) - def patch_all(self): - ... + def patch_all(self): ... return CustomProvider From d7b65cec3ac406df8c84f94f7fef9b3d54f1c942 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 08:40:49 +0100 Subject: [PATCH 0155/2666] chore(ci): changelog rebuild (#3865) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 51cc89274f6..3b13a1e394b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ ## Maintenance +* **deps:** bump codecov/codecov-action from 4.0.2 to 4.1.0 ([#3856](https://github.com/aws-powertools/powertools-lambda-python/issues/3856)) +* **deps:** bump squidfunk/mkdocs-material from `43b898a` to `49d1bfd` in /docs ([#3857](https://github.com/aws-powertools/powertools-lambda-python/issues/3857)) +* **deps-dev:** bump black from 24.1.1 to 24.2.0 ([#3760](https://github.com/aws-powertools/powertools-lambda-python/issues/3760)) From fc2784fcd26624cd71f16d9975a3bc324b24a00a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 08:41:12 +0100 Subject: [PATCH 0156/2666] chore(deps): bump docker/setup-buildx-action from 3.0.0 to 3.1.0 (#3864) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_v2_layer.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index ab6a59a09a8..99c54e4c110 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -124,7 +124,7 @@ jobs: - name: Set up Docker Buildx id: builder - uses: docker/setup-buildx-action@f95db51fddba0c2d1ec667646a06c2ce06100226 # v3.0.0 + uses: docker/setup-buildx-action@0d103c3126aa41d772a8362f6aa67afac040f80c # v3.1.0 with: install: true driver: docker From 5a278361710ce47dc5c95a465c2c1d7df29a8f60 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 08:41:51 +0100 Subject: [PATCH 0157/2666] chore(deps): bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.12 (#3863) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index d9c7b9d8cad..eafb6752f68 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -237,12 +237,12 @@ jobs: - name: Upload to PyPi prod if: ${{ !inputs.skip_pypi }} - uses: pypa/gh-action-pypi-publish@2f6f737ca5f74c637829c0f5c3acd0e29ea5e8bf # v1.8.11 + uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06 # v1.8.12 # PyPi test maintenance affected us numerous times, leaving for history purposes # - name: Upload to PyPi test # if: ${{ !inputs.skip_pypi }} - # uses: pypa/gh-action-pypi-publish@2f6f737ca5f74c637829c0f5c3acd0e29ea5e8bf # v1.8.11 + # uses: pypa/gh-action-pypi-publish@e53eb8b103ffcb59469888563dc324e3c8ba6f06 # v1.8.12 # with: # repository-url: https://test.pypi.org/legacy/ From 1ff8c2e04817fd968fcc427947567705ec90771b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 08:42:13 +0100 Subject: [PATCH 0158/2666] chore(deps): bump actions/download-artifact from 4.1.2 to 4.1.3 (#3862) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish_v2_layer.yml | 2 +- .github/workflows/reusable_deploy_v2_layer_stack.yml | 2 +- .github/workflows/reusable_deploy_v2_sar.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/publish_v2_layer.yml b/.github/workflows/publish_v2_layer.yml index 99c54e4c110..d32e30441e7 100644 --- a/.github/workflows/publish_v2_layer.yml +++ b/.github/workflows/publish_v2_layer.yml @@ -258,7 +258,7 @@ jobs: artifact_name: ${{ inputs.source_code_artifact_name }} - name: Download CDK layer artifacts - uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 + uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 with: path: cdk-layer-stack pattern: cdk-layer-stack-* # merge all Layer artifacts created per region earlier (reusable_deploy_v2_layer_stack.yml; step "Save Layer ARN artifact") diff --git a/.github/workflows/reusable_deploy_v2_layer_stack.yml b/.github/workflows/reusable_deploy_v2_layer_stack.yml index 48cc012cacd..e0e147bb88c 100644 --- a/.github/workflows/reusable_deploy_v2_layer_stack.yml +++ b/.github/workflows/reusable_deploy_v2_layer_stack.yml @@ -180,7 +180,7 @@ jobs: - name: install deps run: poetry install - name: Download artifact - uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 + uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 with: name: ${{ inputs.artefact-name }} path: layer diff --git a/.github/workflows/reusable_deploy_v2_sar.yml b/.github/workflows/reusable_deploy_v2_sar.yml index 96c8dd1b6cd..5a2995fe697 100644 --- a/.github/workflows/reusable_deploy_v2_sar.yml +++ b/.github/workflows/reusable_deploy_v2_sar.yml @@ -115,7 +115,7 @@ jobs: with: node-version: ${{ env.NODE_VERSION }} - name: Download artifact - uses: actions/download-artifact@eaceaf801fd36c7dee90939fad912460b18a1ffe # v4.1.2 + uses: actions/download-artifact@87c55149d96e628cc2ef7e6fc2aab372015aec85 # v4.1.3 with: name: ${{ inputs.artefact-name }} - name: Unzip artefact From 8fea97e247fb77dfbe2ba7b0b307e2c2398d9127 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 28 Feb 2024 08:42:45 +0100 Subject: [PATCH 0159/2666] chore(deps-dev): bump cfn-lint from 0.85.2 to 0.85.3 (#3861) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 48 ++++++++++++++++++++++++++++-------------------- pyproject.toml | 2 +- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/poetry.lock b/poetry.lock index 1fc250f11ce..b7664843942 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.8.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.7.1 and should not be changed by hand. [[package]] name = "anyio" @@ -485,17 +485,17 @@ pycparser = "*" [[package]] name = "cfn-lint" -version = "0.85.2" +version = "0.85.3" description = "Checks CloudFormation templates for practices and behaviour that could potentially be improved" optional = false python-versions = ">=3.8, <=4.0, !=4.0" files = [ - {file = "cfn-lint-0.85.2.tar.gz", hash = "sha256:f8a5cc55daeaaa747b8d776dcf62fe1b6bfb8cb46ae60950cbe627601facccd7"}, - {file = "cfn_lint-0.85.2-py3-none-any.whl", hash = "sha256:e7a0aafb9ad93dbe5db54cbefca92a94f2d173309218273ef997ecb048125d89"}, + {file = "cfn-lint-0.85.3.tar.gz", hash = "sha256:efed015205051664285f0aedac106209c80f8b251b231fce93d0911db0e07cec"}, + {file = "cfn_lint-0.85.3-py3-none-any.whl", hash = "sha256:53121526fe50c04a3551379fd835417d7c05959280df8869e12070946af977a3"}, ] [package.dependencies] -aws-sam-translator = ">=1.84.0" +aws-sam-translator = ">=1.85.0" jschema-to-python = ">=1.2.3,<1.3.0" jsonpatch = "*" jsonschema = ">=3.0,<5" @@ -1226,6 +1226,17 @@ files = [ {file = "ijson-3.2.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:4a3a6a2fbbe7550ffe52d151cf76065e6b89cfb3e9d0463e49a7e322a25d0426"}, {file = "ijson-3.2.3-cp311-cp311-win32.whl", hash = "sha256:6a4db2f7fb9acfb855c9ae1aae602e4648dd1f88804a0d5cfb78c3639bcf156c"}, {file = "ijson-3.2.3-cp311-cp311-win_amd64.whl", hash = "sha256:ccd6be56335cbb845f3d3021b1766299c056c70c4c9165fb2fbe2d62258bae3f"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:055b71bbc37af5c3c5861afe789e15211d2d3d06ac51ee5a647adf4def19c0ea"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c075a547de32f265a5dd139ab2035900fef6653951628862e5cdce0d101af557"}, + {file = "ijson-3.2.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:457f8a5fc559478ac6b06b6d37ebacb4811f8c5156e997f0d87d708b0d8ab2ae"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9788f0c915351f41f0e69ec2618b81ebfcf9f13d9d67c6d404c7f5afda3e4afb"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa234ab7a6a33ed51494d9d2197fb96296f9217ecae57f5551a55589091e7853"}, + {file = "ijson-3.2.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bdd0dc5da4f9dc6d12ab6e8e0c57d8b41d3c8f9ceed31a99dae7b2baf9ea769a"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:c6beb80df19713e39e68dc5c337b5c76d36ccf69c30b79034634e5e4c14d6904"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a2973ce57afb142d96f35a14e9cfec08308ef178a2c76b8b5e1e98f3960438bf"}, + {file = "ijson-3.2.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:105c314fd624e81ed20f925271ec506523b8dd236589ab6c0208b8707d652a0e"}, + {file = "ijson-3.2.3-cp312-cp312-win32.whl", hash = "sha256:ac44781de5e901ce8339352bb5594fcb3b94ced315a34dbe840b4cff3450e23b"}, + {file = "ijson-3.2.3-cp312-cp312-win_amd64.whl", hash = "sha256:0567e8c833825b119e74e10a7c29761dc65fcd155f5d4cb10f9d3b8916ef9912"}, {file = "ijson-3.2.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:eeb286639649fb6bed37997a5e30eefcacddac79476d24128348ec890b2a0ccb"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:396338a655fb9af4ac59dd09c189885b51fa0eefc84d35408662031023c110d1"}, {file = "ijson-3.2.3-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e0243d166d11a2a47c17c7e885debf3b19ed136be2af1f5d1c34212850236ac"}, @@ -2515,6 +2526,7 @@ files = [ {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d"}, {file = "PyYAML-6.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515"}, + {file = "PyYAML-6.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:326c013efe8048858a6d312ddd31d56e468118ad4cdeda36c719bf5bb6192290"}, {file = "PyYAML-6.0.1-cp310-cp310-win32.whl", hash = "sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924"}, {file = "PyYAML-6.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d"}, {file = "PyYAML-6.0.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007"}, @@ -2522,8 +2534,16 @@ files = [ {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc"}, {file = "PyYAML-6.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673"}, + {file = "PyYAML-6.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e7d73685e87afe9f3b36c799222440d6cf362062f78be1013661b00c5c6f678b"}, {file = "PyYAML-6.0.1-cp311-cp311-win32.whl", hash = "sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741"}, {file = "PyYAML-6.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:855fb52b0dc35af121542a76b9a84f8d1cd886ea97c84703eaa6d88e37a2ad28"}, + {file = "PyYAML-6.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40df9b996c2b73138957fe23a16a4f0ba614f4c0efce1e9406a184b6d07fa3a9"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a08c6f0fe150303c1c6b71ebcd7213c2858041a7e01975da3a99aed1e7a378ef"}, + {file = "PyYAML-6.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6c22bec3fbe2524cde73d7ada88f6566758a8f7227bfbf93a408a9d86bcc12a0"}, + {file = "PyYAML-6.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8d4e9c88387b0f5c7d5f281e55304de64cf7f9c0021a3525bd3b1c542da3b0e4"}, + {file = "PyYAML-6.0.1-cp312-cp312-win32.whl", hash = "sha256:d483d2cdf104e7c9fa60c544d92981f12ad66a457afae824d146093b8c294c54"}, + {file = "PyYAML-6.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:0d3304d8c0adc42be59c5f8a4d9e3d7379e6955ad754aa9d6ab7a398b59dd1df"}, {file = "PyYAML-6.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98"}, {file = "PyYAML-6.0.1-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c"}, @@ -2540,6 +2560,7 @@ files = [ {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696"}, {file = "PyYAML-6.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735"}, + {file = "PyYAML-6.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:49a183be227561de579b4a36efbb21b3eab9651dd81b1858589f796549873dd6"}, {file = "PyYAML-6.0.1-cp38-cp38-win32.whl", hash = "sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206"}, {file = "PyYAML-6.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62"}, {file = "PyYAML-6.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8"}, @@ -2547,6 +2568,7 @@ files = [ {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0"}, {file = "PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c"}, + {file = "PyYAML-6.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:04ac92ad1925b2cff1db0cfebffb6ffc43457495c9b3c39d3fcae417d7125dc5"}, {file = "PyYAML-6.0.1-cp39-cp39-win32.whl", hash = "sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c"}, {file = "PyYAML-6.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486"}, {file = "PyYAML-6.0.1.tar.gz", hash = "sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43"}, @@ -3174,20 +3196,6 @@ files = [ [package.dependencies] types-urllib3 = "*" -[[package]] -name = "types-requests" -version = "2.31.0.20240218" -description = "Typing stubs for requests" -optional = false -python-versions = ">=3.8" -files = [ - {file = "types-requests-2.31.0.20240218.tar.gz", hash = "sha256:f1721dba8385958f504a5386240b92de4734e047a08a40751c1654d1ac3349c5"}, - {file = "types_requests-2.31.0.20240218-py3-none-any.whl", hash = "sha256:a82807ec6ddce8f00fe0e949da6d6bc1fbf1715420218a9640d695f70a9e5a9b"}, -] - -[package.dependencies] -urllib3 = ">=2" - [[package]] name = "types-urllib3" version = "1.26.25.14" @@ -3432,4 +3440,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "56925f0c4bf816e507650c4f78ea418822a2afb8a9f6d6d7828127811a9a8223" +content-hash = "ece3c7775abde457734456c5b53735244493ae2fdd21c0b007326a12524542f0" diff --git a/pyproject.toml b/pyproject.toml index ac571066035..a814689e5ee 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -108,7 +108,7 @@ datadog = ["datadog-lambda"] datamasking = ["aws-encryption-sdk", "jsonpath-ng"] [tool.poetry.group.dev.dependencies] -cfn-lint = "0.85.2" +cfn-lint = "0.85.3" mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.28.0" From 55b02fc7c7bb36a1bfbd9038e558664b5e3477fe Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:47:43 +0100 Subject: [PATCH 0160/2666] chore(deps): bump redis from 5.0.1 to 5.0.2 (#3867) Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/poetry.lock b/poetry.lock index b7664843942..55cf61709ef 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2608,17 +2608,17 @@ toml = ["tomli (>=2.0.1)"] [[package]] name = "redis" -version = "5.0.1" +version = "5.0.2" description = "Python client for Redis database and key-value store" optional = false python-versions = ">=3.7" files = [ - {file = "redis-5.0.1-py3-none-any.whl", hash = "sha256:ed4802971884ae19d640775ba3b03aa2e7bd5e8fb8dfaed2decce4d0fc48391f"}, - {file = "redis-5.0.1.tar.gz", hash = "sha256:0dab495cd5753069d3bc650a0dde8a8f9edde16fc5691b689a566eda58100d0f"}, + {file = "redis-5.0.2-py3-none-any.whl", hash = "sha256:4caa8e1fcb6f3c0ef28dba99535101d80934b7d4cd541bbb47f4a3826ee472d1"}, + {file = "redis-5.0.2.tar.gz", hash = "sha256:3f82cc80d350e93042c8e6e7a5d0596e4dd68715babffba79492733e1f367037"}, ] [package.dependencies] -async-timeout = {version = ">=4.0.2", markers = "python_full_version <= \"3.11.2\""} +async-timeout = ">=4.0.3" [package.extras] hiredis = ["hiredis (>=1.0.0)"] From d5cd0b98561f0871a1511e32c2c19d85c651cd48 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:35:28 -0300 Subject: [PATCH 0161/2666] chore(deps-dev): bump ruff from 0.2.2 to 0.3.0 (#3871) Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.2 to 0.3.0. - [Release notes](https://github.com/astral-sh/ruff/releases) - [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md) - [Commits](https://github.com/astral-sh/ruff/compare/v0.2.2...v0.3.0) --- updated-dependencies: - dependency-name: ruff dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 38 +++++++++++++++++++------------------- pyproject.toml | 2 +- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/poetry.lock b/poetry.lock index 55cf61709ef..37fd20009a0 100644 --- a/poetry.lock +++ b/poetry.lock @@ -2904,28 +2904,28 @@ files = [ [[package]] name = "ruff" -version = "0.2.2" +version = "0.3.0" description = "An extremely fast Python linter and code formatter, written in Rust." optional = false python-versions = ">=3.7" files = [ - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:0a9efb032855ffb3c21f6405751d5e147b0c6b631e3ca3f6b20f917572b97eb6"}, - {file = "ruff-0.2.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:d450b7fbff85913f866a5384d8912710936e2b96da74541c82c1b458472ddb39"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ecd46e3106850a5c26aee114e562c329f9a1fbe9e4821b008c4404f64ff9ce73"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e22676a5b875bd72acd3d11d5fa9075d3a5f53b877fe7b4793e4673499318ba"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1695700d1e25a99d28f7a1636d85bafcc5030bba9d0578c0781ba1790dbcf51c"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b0c232af3d0bd8f521806223723456ffebf8e323bd1e4e82b0befb20ba18388e"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f63d96494eeec2fc70d909393bcd76c69f35334cdbd9e20d089fb3f0640216ca"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6a61ea0ff048e06de273b2e45bd72629f470f5da8f71daf09fe481278b175001"}, - {file = "ruff-0.2.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5e1439c8f407e4f356470e54cdecdca1bd5439a0673792dbe34a2b0a551a2fe3"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:940de32dc8853eba0f67f7198b3e79bc6ba95c2edbfdfac2144c8235114d6726"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:0c126da55c38dd917621552ab430213bdb3273bb10ddb67bc4b761989210eb6e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3b65494f7e4bed2e74110dac1f0d17dc8e1f42faaa784e7c58a98e335ec83d7e"}, - {file = "ruff-0.2.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1ec49be4fe6ddac0503833f3ed8930528e26d1e60ad35c2446da372d16651ce9"}, - {file = "ruff-0.2.2-py3-none-win32.whl", hash = "sha256:d920499b576f6c68295bc04e7b17b6544d9d05f196bb3aac4358792ef6f34325"}, - {file = "ruff-0.2.2-py3-none-win_amd64.whl", hash = "sha256:cc9a91ae137d687f43a44c900e5d95e9617cb37d4c989e462980ba27039d239d"}, - {file = "ruff-0.2.2-py3-none-win_arm64.whl", hash = "sha256:c9d15fc41e6054bfc7200478720570078f0b41c9ae4f010bcc16bd6f4d1aacdd"}, - {file = "ruff-0.2.2.tar.gz", hash = "sha256:e62ed7f36b3068a30ba39193a14274cd706bc486fad521276458022f7bccb31d"}, + {file = "ruff-0.3.0-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:7deb528029bacf845bdbb3dbb2927d8ef9b4356a5e731b10eef171e3f0a85944"}, + {file = "ruff-0.3.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:e1e0d4381ca88fb2b73ea0766008e703f33f460295de658f5467f6f229658c19"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f7dbba46e2827dfcb0f0cc55fba8e96ba7c8700e0a866eb8cef7d1d66c25dcb"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:23dbb808e2f1d68eeadd5f655485e235c102ac6f12ad31505804edced2a5ae77"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3ef655c51f41d5fa879f98e40c90072b567c666a7114fa2d9fe004dffba00932"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:d0d3d7ef3d4f06433d592e5f7d813314a34601e6c5be8481cccb7fa760aa243e"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b08b356d06a792e49a12074b62222f9d4ea2a11dca9da9f68163b28c71bf1dd4"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9343690f95710f8cf251bee1013bf43030072b9f8d012fbed6ad702ef70d360a"}, + {file = "ruff-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a1f3ed501a42f60f4dedb7805fa8d4534e78b4e196f536bac926f805f0743d49"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:cc30a9053ff2f1ffb505a585797c23434d5f6c838bacfe206c0e6cf38c921a1e"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5da894a29ec018a8293d3d17c797e73b374773943e8369cfc50495573d396933"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:755c22536d7f1889be25f2baf6fedd019d0c51d079e8417d4441159f3bcd30c2"}, + {file = "ruff-0.3.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:dd73fe7f4c28d317855da6a7bc4aa29a1500320818dd8f27df95f70a01b8171f"}, + {file = "ruff-0.3.0-py3-none-win32.whl", hash = "sha256:19eacceb4c9406f6c41af806418a26fdb23120dfe53583df76d1401c92b7c14b"}, + {file = "ruff-0.3.0-py3-none-win_amd64.whl", hash = "sha256:128265876c1d703e5f5e5a4543bd8be47c73a9ba223fd3989d4aa87dd06f312f"}, + {file = "ruff-0.3.0-py3-none-win_arm64.whl", hash = "sha256:e3a4a6d46aef0a84b74fcd201a4401ea9a6cd85614f6a9435f2d33dd8cefbf83"}, + {file = "ruff-0.3.0.tar.gz", hash = "sha256:0886184ba2618d815067cf43e005388967b67ab9c80df52b32ec1152ab49f53a"}, ] [[package]] @@ -3440,4 +3440,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "ece3c7775abde457734456c5b53735244493ae2fdd21c0b007326a12524542f0" +content-hash = "9d73fe7ddd436b010e719accba90c18d5e4bd45cf2cfa395dca4434b1971b380" diff --git a/pyproject.toml b/pyproject.toml index a814689e5ee..80aad3112c5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -113,7 +113,7 @@ mypy = "^1.1.1" types-python-dateutil = "^2.8.19.6" httpx = ">=0.23.3,<0.28.0" sentry-sdk = "^1.22.2" -ruff = ">=0.0.272,<0.2.3" +ruff = ">=0.0.272,<0.3.1" retry2 = "^0.9.5" pytest-socket = ">=0.6,<0.8" types-redis = "^4.6.0.7" From 242842fb9b804c2a0c2fd7121f09ea711b2fab7a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:41:18 -0300 Subject: [PATCH 0162/2666] chore(deps-dev): bump mkdocs-material from 9.5.11 to 9.5.12 (#3870) Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.11 to 9.5.12. - [Release notes](https://github.com/squidfunk/mkdocs-material/releases) - [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG) - [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.11...9.5.12) --- updated-dependencies: - dependency-name: mkdocs-material dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- poetry.lock | 8 ++++---- pyproject.toml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/poetry.lock b/poetry.lock index 37fd20009a0..3b239a37abb 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1765,13 +1765,13 @@ mkdocs = ">=0.17" [[package]] name = "mkdocs-material" -version = "9.5.11" +version = "9.5.12" description = "Documentation that simply works" optional = false python-versions = ">=3.8" files = [ - {file = "mkdocs_material-9.5.11-py3-none-any.whl", hash = "sha256:788ee0f3e036dca2dc20298d65e480297d348a44c9d7b2ee05c5262983e66072"}, - {file = "mkdocs_material-9.5.11.tar.gz", hash = "sha256:7af7f8af0dea16175558f3fb9245d26c83a17199baa5f157755e63d7437bf971"}, + {file = "mkdocs_material-9.5.12-py3-none-any.whl", hash = "sha256:d6f0c269f015e48c76291cdc79efb70f7b33bbbf42d649cfe475522ebee61b1f"}, + {file = "mkdocs_material-9.5.12.tar.gz", hash = "sha256:5f69cef6a8aaa4050b812f72b1094fda3d079b9a51cf27a247244c03ec455e97"}, ] [package.dependencies] @@ -3440,4 +3440,4 @@ validation = ["fastjsonschema"] [metadata] lock-version = "2.0" python-versions = ">=3.8,<4.0.0" -content-hash = "9d73fe7ddd436b010e719accba90c18d5e4bd45cf2cfa395dca4434b1971b380" +content-hash = "cec3ac63218a9aaf58eb4c96187bb72bf12b357049be61da99c5c60887eaaa63" diff --git a/pyproject.toml b/pyproject.toml index 80aad3112c5..ed6fe378e75 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -82,7 +82,7 @@ mypy-boto3-s3 = "^1.34.14" mypy-boto3-xray = "^1.34.0" types-requests = "^2.31.0" typing-extensions = "^4.6.2" -mkdocs-material = "^9.5.10" +mkdocs-material = "^9.5.12" filelock = "^3.12.2" checksumdir = "^1.2.0" mypy-boto3-appconfigdata = "^1.34.24" From 2bf23c8a03aa53b0ab0b3a200e85ab6fbcce90e7 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 29 Feb 2024 17:43:53 -0300 Subject: [PATCH 0163/2666] chore(deps): bump squidfunk/mkdocs-material from `49d1bfd` to `7be068b` in /docs (#3872) chore(deps): bump squidfunk/mkdocs-material in /docs Bumps squidfunk/mkdocs-material from `49d1bfd` to `7be068b`. --- updated-dependencies: - dependency-name: squidfunk/mkdocs-material dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Leandro Damascena --- docs/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Dockerfile b/docs/Dockerfile index 20e558ca6cf..a20dbc149cf 100644 --- a/docs/Dockerfile +++ b/docs/Dockerfile @@ -1,5 +1,5 @@ # v9.1.18 -FROM squidfunk/mkdocs-material@sha256:49d1bfdaf457c5ac20a93ff59a5b57b762ace5606fc564ac2e195abf315f14ee +FROM squidfunk/mkdocs-material@sha256:7be068b884750631488cd29cff0101a234971dfd7473276d050736b1cd1dac35 # pip-compile --generate-hashes --output-file=requirements.txt requirements.in COPY requirements.txt /tmp/ RUN pip install --require-hashes -r /tmp/requirements.txt From 57fc5d5b8ceda238d2080254e1f64793bdcbcd3b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 1 Mar 2024 08:06:45 -0300 Subject: [PATCH 0164/2666] chore(ci): changelog rebuild (#3873) Co-authored-by: Powertools for AWS Lambda (Python) bot <151832416+aws-powertools-bot@users.noreply.github.com> --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b13a1e394b..438f986d52a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,9 +6,17 @@ ## Maintenance +* **deps:** bump redis from 5.0.1 to 5.0.2 ([#3867](https://github.com/aws-powertools/powertools-lambda-python/issues/3867)) * **deps:** bump codecov/codecov-action from 4.0.2 to 4.1.0 ([#3856](https://github.com/aws-powertools/powertools-lambda-python/issues/3856)) +* **deps:** bump actions/download-artifact from 4.1.2 to 4.1.3 ([#3862](https://github.com/aws-powertools/powertools-lambda-python/issues/3862)) +* **deps:** bump pypa/gh-action-pypi-publish from 1.8.11 to 1.8.12 ([#3863](https://github.com/aws-powertools/powertools-lambda-python/issues/3863)) * **deps:** bump squidfunk/mkdocs-material from `43b898a` to `49d1bfd` in /docs ([#3857](https://github.com/aws-powertools/powertools-lambda-python/issues/3857)) +* **deps:** bump docker/setup-buildx-action from 3.0.0 to 3.1.0 ([#3864](https://github.com/aws-powertools/powertools-lambda-python/issues/3864)) +* **deps:** bump squidfunk/mkdocs-material from `49d1bfd` to `7be068b` in /docs ([#3872](https://github.com/aws-powertools/powertools-lambda-python/issues/3872)) * **deps-dev:** bump black from 24.1.1 to 24.2.0 ([#3760](https://github.com/aws-powertools/powertools-lambda-python/issues/3760)) +* **deps-dev:** bump cfn-lint from 0.85.2 to 0.85.3 ([#3861](https://github.com/aws-powertools/powertools-lambda-python/issues/3861)) +* **deps-dev:** bump ruff from 0.2.2 to 0.3.0 ([#3871](https://github.com/aws-powertools/powertools-lambda-python/issues/3871)) +* **deps-dev:** bump mkdocs-material from 9.5.11 to 9.5.12 ([#3870](https://github.com/aws-powertools/powertools-lambda-python/issues/3870)) From 579662e45c0d43ebe0685e34af56cacf13b08e18 Mon Sep 17 00:00:00 2001 From: Ruben Fonseca Date: Fri, 1 Mar 2024 15:08:06 +0100 Subject: [PATCH 0165/2666] fix(event_handler): OpenAPI schema version respects Pydantic version (#3860) * fix(event_handler): OpenAPI schema version respects Pydantic version * fix: types * chore: add docs on pydantic version * chore: moved loading of pydantic to improve performance * chore: improve performance again * chore: update Swagger-UI to 5.x * chore: add links to pydantic openapi schemas * chore: change default OpenAPI version * Adding nofollow for external links --------- Co-authored-by: Leandro Damascena Co-authored-by: Cavalcante Damascena --- .../event_handler/api_gateway.py | 15 +++ .../event_handler/openapi/constants.py | 2 +- .../event_handler/openapi/models.py | 6 +- .../swagger_ui/swagger-ui-bundle.min.js | 20 ++-- .../openapi/swagger_ui/swagger-ui.min.css | 8 +- docs/core/event_handler/api_gateway.md | 29 +++-- tests/functional/event_handler/conftest.py | 43 +++++++ .../event_handler/test_openapi_encoders.py | 9 -- .../test_openapi_schema_pydantic_v1.py | 112 ++++++++++++++++++ .../test_openapi_schema_pydantic_v2.py | 112 ++++++++++++++++++ 10 files changed, 315 insertions(+), 41 deletions(-) create mode 100644 tests/functional/event_handler/test_openapi_schema_pydantic_v1.py create mode 100644 tests/functional/event_handler/test_openapi_schema_pydantic_v2.py diff --git a/aws_lambda_powertools/event_handler/api_gateway.py b/aws_lambda_powertools/event_handler/api_gateway.py index 271c767c060..342d6227dd3 100644 --- a/aws_lambda_powertools/event_handler/api_gateway.py +++ b/aws_lambda_powertools/event_handler/api_gateway.py @@ -1455,10 +1455,25 @@ def get_openapi_schema( get_definitions, ) from aws_lambda_powertools.event_handler.openapi.models import OpenAPI, PathItem, Server, Tag + from aws_lambda_powertools.event_handler.openapi.pydantic_loader import PYDANTIC_V2 from aws_lambda_powertools.event_handler.openapi.types import ( COMPONENT_REF_TEMPLATE, ) + # Pydantic V2 has no support for OpenAPI schema 3.0 + if PYDANTIC_V2 and not openapi_version.startswith("3.1"): + warnings.warn( + "You are using Pydantic v2, which is incompatible with OpenAPI schema 3.0. Forcing OpenAPI 3.1", + stacklevel=2, + ) + openapi_version = "3.1.0" + elif not PYDANTIC_V2 and not openapi_version.startswith("3.0"): + warnings.warn( + "You are using Pydantic v1, which is incompatible with OpenAPI schema 3.1. Forcing OpenAPI 3.0", + stacklevel=2, + ) + openapi_version = "3.0.3" + # Start with the bare minimum required for a valid OpenAPI schema info: Dict[str, Any] = {"title": title, "version": version} diff --git a/aws_lambda_powertools/event_handler/openapi/constants.py b/aws_lambda_powertools/event_handler/openapi/constants.py index e41063f5282..dc326b68abb 100644 --- a/aws_lambda_powertools/event_handler/openapi/constants.py +++ b/aws_lambda_powertools/event_handler/openapi/constants.py @@ -1,2 +1,2 @@ DEFAULT_API_VERSION = "1.0.0" -DEFAULT_OPENAPI_VERSION = "3.0.0" +DEFAULT_OPENAPI_VERSION = "3.0.3" diff --git a/aws_lambda_powertools/event_handler/openapi/models.py b/aws_lambda_powertools/event_handler/openapi/models.py index e886e30d396..ace398ec532 100644 --- a/aws_lambda_powertools/event_handler/openapi/models.py +++ b/aws_lambda_powertools/event_handler/openapi/models.py @@ -45,7 +45,6 @@ class Config: # https://swagger.io/specification/#info-object class Info(BaseModel): title: str - summary: Optional[str] = None description: Optional[str] = None termsOfService: Optional[str] = None contact: Optional[Contact] = None @@ -53,12 +52,13 @@ class Info(BaseModel): version: str if PYDANTIC_V2: - model_config = {"extra": "allow"} + summary: Optional[str] = None + model_config = {"extra": "ignore"} else: class Config: - extra = "allow" + extra = "ignore" # https://swagger.io/specification/#server-variable-object diff --git a/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js b/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js index bdeaba02de0..bc1d328090c 100644 --- a/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js +++ b/aws_lambda_powertools/event_handler/openapi/swagger_ui/swagger-ui-bundle.min.js @@ -1,8 +1,12 @@ -/** - * Skipped minification because the original files appears to be already minified. - * Original file: /npm/swagger-ui-dist@4.19.1/swagger-ui-bundle.js - * - * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files - */ -/*! For license information please see swagger-ui-bundle.js.LICENSE.txt */ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.SwaggerUIBundle=t():e.SwaggerUIBundle=t()}(this,(()=>(()=>{var e={17967:(e,t)=>{"use strict";t.N=void 0;var n=/^([^\w]*)(javascript|data|vbscript)/im,r=/&#(\w+)(^\w|;)?/g,o=/&(newline|tab);/gi,a=/[\u0000-\u001F\u007F-\u009F\u2000-\u200D\uFEFF]/gim,i=/^.+(:|:)/gim,s=[".","/"];t.N=function(e){var t,l=(t=e||"",t.replace(r,(function(e,t){return String.fromCharCode(t)}))).replace(o,"").replace(a,"").trim();if(!l)return"about:blank";if(function(e){return s.indexOf(e[0])>-1}(l))return l;var u=l.match(i);if(!u)return l;var c=u[0];return n.test(c)?"about:blank":l}},53795:(e,t,n)=>{"use strict";n.d(t,{Z:()=>T});var r=n(23101),o=n.n(r),a=n(61125),i=n.n(a),s=n(11882),l=n.n(s),u=n(97606),c=n.n(u),p=n(67294),f=n(43393);function h(e){return h="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},h(e)}function d(e,t){for(var n=0;n1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=function(e,t){return function(n){if("string"==typeof n)return(0,f.is)(t[n],e[n]);if(Array.isArray(n))return(0,f.is)(x(t,n),x(e,n));throw new TypeError("Invalid key: expected Array or string: "+n)}}(t,n),o=e||Object.keys(function(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:{};return!_(this.updateOnProps,this.props,e,"updateOnProps")||!_(this.updateOnStates,this.state,t,"updateOnStates")}}],r&&d(n.prototype,r),o&&d(n,o),t}(p.Component);var A=n(23930),C=n.n(A),k=n(45697),O=n.n(k);const j=e=>{const t=e.replace(/~1/g,"/").replace(/~0/g,"~");try{return decodeURIComponent(t)}catch{return t}};class T extends S{constructor(){super(...arguments),i()(this,"getModelName",(e=>-1!==l()(e).call(e,"#/definitions/")?j(e.replace(/^.*#\/definitions\//,"")):-1!==l()(e).call(e,"#/components/schemas/")?j(e.replace(/^.*#\/components\/schemas\//,"")):void 0)),i()(this,"getRefSchema",(e=>{let{specSelectors:t}=this.props;return t.findDefinition(e)}))}render(){let{getComponent:e,getConfigs:t,specSelectors:r,schema:a,required:i,name:s,isRef:l,specPath:u,displayName:c,includeReadOnly:f,includeWriteOnly:h}=this.props;const d=e("ObjectModel"),m=e("ArrayModel"),g=e("PrimitiveModel");let y="object",v=a&&a.get("$$ref");if(!s&&v&&(s=this.getModelName(v)),!a&&v&&(a=this.getRefSchema(s)),!a)return p.createElement("span",{className:"model model-title"},p.createElement("span",{className:"model-title__text"},c||s),p.createElement("img",{src:n(2517),height:"20px",width:"20px"}));const b=r.isOAS3()&&a.get("deprecated");switch(l=void 0!==l?l:!!v,y=a&&a.get("type")||y,y){case"object":return p.createElement(d,o()({className:"object"},this.props,{specPath:u,getConfigs:t,schema:a,name:s,deprecated:b,isRef:l,includeReadOnly:f,includeWriteOnly:h}));case"array":return p.createElement(m,o()({className:"array"},this.props,{getConfigs:t,schema:a,name:s,deprecated:b,required:i,includeReadOnly:f,includeWriteOnly:h}));default:return p.createElement(g,o()({},this.props,{getComponent:e,getConfigs:t,schema:a,name:s,deprecated:b,required:i}))}}}i()(T,"propTypes",{schema:c()(C()).isRequired,getComponent:O().func.isRequired,getConfigs:O().func.isRequired,specSelectors:O().object.isRequired,name:O().string,displayName:O().string,isRef:O().bool,required:O().bool,expandDepth:O().number,depth:O().number,specPath:C().list.isRequired,includeReadOnly:O().bool,includeWriteOnly:O().bool})},5623:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(61125),o=n.n(r),a=n(28222),i=n.n(a),s=n(67294),l=n(84564),u=n.n(l),c=n(90242),p=n(27504);class f extends s.Component{constructor(e,t){super(e,t),o()(this,"getDefinitionUrl",(()=>{let{specSelectors:e}=this.props;return new(u())(e.url(),p.Z.location).toString()}));let{getConfigs:n}=e,{validatorUrl:r}=n();this.state={url:this.getDefinitionUrl(),validatorUrl:void 0===r?"https://validator.swagger.io/validator":r}}UNSAFE_componentWillReceiveProps(e){let{getConfigs:t}=e,{validatorUrl:n}=t();this.setState({url:this.getDefinitionUrl(),validatorUrl:void 0===n?"https://validator.swagger.io/validator":n})}render(){let{getConfigs:e}=this.props,{spec:t}=e(),n=(0,c.Nm)(this.state.validatorUrl);return"object"==typeof t&&i()(t).length?null:this.state.url&&(0,c.hW)(this.state.validatorUrl)&&(0,c.hW)(this.state.url)?s.createElement("span",{className:"float-right"},s.createElement("a",{target:"_blank",rel:"noopener noreferrer",href:`${n}/debug?url=${encodeURIComponent(this.state.url)}`},s.createElement(h,{src:`${n}?url=${encodeURIComponent(this.state.url)}`,alt:"Online validator badge"}))):null}}class h extends s.Component{constructor(e){super(e),this.state={loaded:!1,error:!1}}componentDidMount(){const e=new Image;e.onload=()=>{this.setState({loaded:!0})},e.onerror=()=>{this.setState({error:!0})},e.src=this.props.src}UNSAFE_componentWillReceiveProps(e){if(e.src!==this.props.src){const t=new Image;t.onload=()=>{this.setState({loaded:!0})},t.onerror=()=>{this.setState({error:!0})},t.src=e.src}}render(){return this.state.error?s.createElement("img",{alt:"Error"}):this.state.loaded?s.createElement("img",{src:this.props.src,alt:this.props.alt}):null}}},94994:(e,t,n)=>{"use strict";n.d(t,{Z:()=>ye,s:()=>ve});var r=n(67294),o=n(89927);function a(e,t){if(Array.prototype.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n=0;n--)!0===t(e[n])&&e.splice(n,1)}function s(e){throw new Error("Unhandled case for value: '".concat(e,"'"))}var l=function(){function e(e){void 0===e&&(e={}),this.tagName="",this.attrs={},this.innerHTML="",this.whitespaceRegex=/\s+/,this.tagName=e.tagName||"",this.attrs=e.attrs||{},this.innerHTML=e.innerHtml||e.innerHTML||""}return e.prototype.setTagName=function(e){return this.tagName=e,this},e.prototype.getTagName=function(){return this.tagName||""},e.prototype.setAttr=function(e,t){return this.getAttrs()[e]=t,this},e.prototype.getAttr=function(e){return this.getAttrs()[e]},e.prototype.setAttrs=function(e){return Object.assign(this.getAttrs(),e),this},e.prototype.getAttrs=function(){return this.attrs||(this.attrs={})},e.prototype.setClass=function(e){return this.setAttr("class",e)},e.prototype.addClass=function(e){for(var t,n=this.getClass(),r=this.whitespaceRegex,o=n?n.split(r):[],i=e.split(r);t=i.shift();)-1===a(o,t)&&o.push(t);return this.getAttrs().class=o.join(" "),this},e.prototype.removeClass=function(e){for(var t,n=this.getClass(),r=this.whitespaceRegex,o=n?n.split(r):[],i=e.split(r);o.length&&(t=i.shift());){var s=a(o,t);-1!==s&&o.splice(s,1)}return this.getAttrs().class=o.join(" "),this},e.prototype.getClass=function(){return this.getAttrs().class||""},e.prototype.hasClass=function(e){return-1!==(" "+this.getClass()+" ").indexOf(" "+e+" ")},e.prototype.setInnerHTML=function(e){return this.innerHTML=e,this},e.prototype.setInnerHtml=function(e){return this.setInnerHTML(e)},e.prototype.getInnerHTML=function(){return this.innerHTML||""},e.prototype.getInnerHtml=function(){return this.getInnerHTML()},e.prototype.toAnchorString=function(){var e=this.getTagName(),t=this.buildAttrsStr();return["<",e,t=t?" "+t:"",">",this.getInnerHtml(),""].join("")},e.prototype.buildAttrsStr=function(){if(!this.attrs)return"";var e=this.getAttrs(),t=[];for(var n in e)e.hasOwnProperty(n)&&t.push(n+'="'+e[n]+'"');return t.join(" ")},e}();var u=function(){function e(e){void 0===e&&(e={}),this.newWindow=!1,this.truncate={},this.className="",this.newWindow=e.newWindow||!1,this.truncate=e.truncate||{},this.className=e.className||""}return e.prototype.build=function(e){return new l({tagName:"a",attrs:this.createAttrs(e),innerHtml:this.processAnchorText(e.getAnchorText())})},e.prototype.createAttrs=function(e){var t={href:e.getAnchorHref()},n=this.createCssClass(e);return n&&(t.class=n),this.newWindow&&(t.target="_blank",t.rel="noopener noreferrer"),this.truncate&&this.truncate.length&&this.truncate.length=s)return l.host.length==t?(l.host.substr(0,t-o)+n).substr(0,s+r):i(c,s).substr(0,s+r);var p="";if(l.path&&(p+="/"+l.path),l.query&&(p+="?"+l.query),p){if((c+p).length>=s)return(c+p).length==t?(c+p).substr(0,t):(c+i(p,s-c.length)).substr(0,s+r);c+=p}if(l.fragment){var f="#"+l.fragment;if((c+f).length>=s)return(c+f).length==t?(c+f).substr(0,t):(c+i(f,s-c.length)).substr(0,s+r);c+=f}if(l.scheme&&l.host){var h=l.scheme+"://";if((c+h).length0&&(d=c.substr(-1*Math.floor(s/2))),(c.substr(0,Math.ceil(s/2))+n+d).substr(0,s+r)}(e,n):"middle"===r?function(e,t,n){if(e.length<=t)return e;var r,o;null==n?(n="…",r=8,o=3):(r=n.length,o=n.length);var a=t-o,i="";return a>0&&(i=e.substr(-1*Math.floor(a/2))),(e.substr(0,Math.ceil(a/2))+n+i).substr(0,a+r)}(e,n):function(e,t,n){return function(e,t,n){var r;return e.length>t&&(null==n?(n="…",r=3):r=n.length,e=e.substring(0,t-r)+n),e}(e,t,n)}(e,n)},e}(),c=function(){function e(e){this.__jsduckDummyDocProp=null,this.matchedText="",this.offset=0,this.tagBuilder=e.tagBuilder,this.matchedText=e.matchedText,this.offset=e.offset}return e.prototype.getMatchedText=function(){return this.matchedText},e.prototype.setOffset=function(e){this.offset=e},e.prototype.getOffset=function(){return this.offset},e.prototype.getCssClassSuffixes=function(){return[this.getType()]},e.prototype.buildTag=function(){return this.tagBuilder.build(this)},e}(),p=function(e,t){return p=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)Object.prototype.hasOwnProperty.call(t,n)&&(e[n]=t[n])},p(e,t)};function f(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function n(){this.constructor=e}p(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}var h=function(){return h=Object.assign||function(e){for(var t,n=1,r=arguments.length;n-1},e.isValidUriScheme=function(e){var t=e.match(this.uriSchemeRegex),n=t&&t[0].toLowerCase();return"javascript:"!==n&&"vbscript:"!==n},e.urlMatchDoesNotHaveProtocolOrDot=function(e,t){return!(!e||t&&this.hasFullProtocolRegex.test(t)||-1!==e.indexOf("."))},e.urlMatchDoesNotHaveAtLeastOneWordChar=function(e,t){return!(!e||!t)&&(!this.hasFullProtocolRegex.test(t)&&!this.hasWordCharAfterProtocolRegex.test(e))},e.hasFullProtocolRegex=/^[A-Za-z][-.+A-Za-z0-9]*:\/\//,e.uriSchemeRegex=/^[A-Za-z][-.+A-Za-z0-9]*:/,e.hasWordCharAfterProtocolRegex=new RegExp(":[^\\s]*?["+k+"]"),e.ipRegex=/[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?\.[0-9][0-9]?[0-9]?(:[0-9]*)?\/?$/,e}(),V=(d=new RegExp("[/?#](?:["+I+"\\-+&@#/%=~_()|'$*\\[\\]{}?!:,.;^✓]*["+I+"\\-+&@#/%=~_()|'$*\\[\\]{}✓])?"),new RegExp(["(?:","(",/(?:[A-Za-z][-.+A-Za-z0-9]{0,63}:(?![A-Za-z][-.+A-Za-z0-9]{0,63}:\/\/)(?!\d+\/?)(?:\/\/)?)/.source,D(2),")","|","(","(//)?",/(?:www\.)/.source,D(6),")","|","(","(//)?",D(10)+"\\.",B.source,"(?![-"+T+"])",")",")","(?::[0-9]+)?","(?:"+d.source+")?"].join(""),"gi")),W=new RegExp("["+I+"]"),H=function(e){function t(t){var n=e.call(this,t)||this;return n.stripPrefix={scheme:!0,www:!0},n.stripTrailingSlash=!0,n.decodePercentEncoding=!0,n.matcherRegex=V,n.wordCharRegExp=W,n.stripPrefix=t.stripPrefix,n.stripTrailingSlash=t.stripTrailingSlash,n.decodePercentEncoding=t.decodePercentEncoding,n}return f(t,e),t.prototype.parseMatches=function(e){for(var t,n=this.matcherRegex,r=this.stripPrefix,o=this.stripTrailingSlash,a=this.decodePercentEncoding,i=this.tagBuilder,s=[],l=function(){var n=t[0],l=t[1],c=t[4],p=t[5],f=t[9],h=t.index,d=p||f,m=e.charAt(h-1);if(!$.isValid(n,l))return"continue";if(h>0&&"@"===m)return"continue";if(h>0&&d&&u.wordCharRegExp.test(m))return"continue";if(/\?$/.test(n)&&(n=n.substr(0,n.length-1)),u.matchHasUnbalancedClosingParen(n))n=n.substr(0,n.length-1);else{var g=u.matchHasInvalidCharAfterTld(n,l);g>-1&&(n=n.substr(0,g))}var y=["http://","https://"].find((function(e){return!!l&&-1!==l.indexOf(e)}));if(y){var v=n.indexOf(y);n=n.substr(v),l=l.substr(v),h+=v}var w=l?"scheme":c?"www":"tld",E=!!l;s.push(new b({tagBuilder:i,matchedText:n,offset:h,urlMatchType:w,url:n,protocolUrlMatch:E,protocolRelativeMatch:!!d,stripPrefix:r,stripTrailingSlash:o,decodePercentEncoding:a}))},u=this;null!==(t=n.exec(e));)l();return s},t.prototype.matchHasUnbalancedClosingParen=function(e){var t,n=e.charAt(e.length-1);if(")"===n)t="(";else if("]"===n)t="[";else{if("}"!==n)return!1;t="{"}for(var r=0,o=0,a=e.length-1;o-1&&a-i<=140){var o=e.slice(i,a),s=new g({tagBuilder:t,matchedText:o,offset:i,serviceName:n,hashtag:o.slice(1)});r.push(s)}}},t}(w),G=["twitter","facebook","instagram","tiktok"],Z=new RegExp("".concat(/(?:(?:(?:(\+)?\d{1,3}[-\040.]?)?\(?\d{3}\)?[-\040.]?\d{3}[-\040.]?\d{4})|(?:(\+)(?:9[976]\d|8[987530]\d|6[987]\d|5[90]\d|42\d|3[875]\d|2[98654321]\d|9[8543210]|8[6421]|6[6543210]|5[87654321]|4[987654310]|3[9643210]|2[70]|7|1)[-\040.]?(?:\d[-\040.]?){6,12}\d+))([,;]+[0-9]+#?)*/.source,"|").concat(/(0([1-9]{1}-?[1-9]\d{3}|[1-9]{2}-?\d{3}|[1-9]{2}\d{1}-?\d{2}|[1-9]{2}\d{2}-?\d{1})-?\d{4}|0[789]0-?\d{4}-?\d{4}|050-?\d{4}-?\d{4})/.source),"g"),Y=function(e){function t(){var t=null!==e&&e.apply(this,arguments)||this;return t.matcherRegex=Z,t}return f(t,e),t.prototype.parseMatches=function(e){for(var t,n=this.matcherRegex,r=this.tagBuilder,o=[];null!==(t=n.exec(e));){var a=t[0],i=a.replace(/[^0-9,;#]/g,""),s=!(!t[1]&&!t[2]),l=0==t.index?"":e.substr(t.index-1,1),u=e.substr(t.index+a.length,1),c=!l.match(/\d/)&&!u.match(/\d/);this.testMatch(t[3])&&this.testMatch(a)&&c&&o.push(new v({tagBuilder:r,matchedText:a,offset:t.index,number:i,plusSign:s}))}return o},t.prototype.testMatch=function(e){return _.test(e)},t}(w),Q=new RegExp("@[_".concat(I,"]{1,50}(?![_").concat(I,"])"),"g"),X=new RegExp("@[_.".concat(I,"]{1,30}(?![_").concat(I,"])"),"g"),ee=new RegExp("@[-_.".concat(I,"]{1,50}(?![-_").concat(I,"])"),"g"),te=new RegExp("@[_.".concat(I,"]{1,23}[_").concat(I,"](?![_").concat(I,"])"),"g"),ne=new RegExp("[^"+I+"]"),re=function(e){function t(t){var n=e.call(this,t)||this;return n.serviceName="twitter",n.matcherRegexes={twitter:Q,instagram:X,soundcloud:ee,tiktok:te},n.nonWordCharRegex=ne,n.serviceName=t.serviceName,n}return f(t,e),t.prototype.parseMatches=function(e){var t,n=this.serviceName,r=this.matcherRegexes[this.serviceName],o=this.nonWordCharRegex,a=this.tagBuilder,i=[];if(!r)return i;for(;null!==(t=r.exec(e));){var s=t.index,l=e.charAt(s-1);if(0===s||o.test(l)){var u=t[0].replace(/\.+$/g,""),c=u.slice(1);i.push(new y({tagBuilder:a,matchedText:u,offset:s,serviceName:n,mention:c}))}}return i},t}(w);function oe(e,t){for(var n,r=t.onOpenTag,o=t.onCloseTag,a=t.onText,i=t.onComment,l=t.onDoctype,u=new ae,c=0,p=e.length,f=0,d=0,m=u;c"===e?(m=new ae(h(h({},m),{name:H()})),W()):E.test(e)||x.test(e)||":"===e||$()}function w(e){">"===e?$():E.test(e)?f=3:$()}function _(e){S.test(e)||("/"===e?f=12:">"===e?W():"<"===e?V():"="===e||A.test(e)||C.test(e)?$():f=5)}function k(e){S.test(e)?f=6:"/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?V():A.test(e)&&$()}function O(e){S.test(e)||("/"===e?f=12:"="===e?f=7:">"===e?W():"<"===e?V():A.test(e)?$():f=5)}function j(e){S.test(e)||('"'===e?f=8:"'"===e?f=9:/[>=`]/.test(e)?$():"<"===e?V():f=10)}function T(e){'"'===e&&(f=11)}function I(e){"'"===e&&(f=11)}function N(e){S.test(e)?f=4:">"===e?W():"<"===e&&V()}function P(e){S.test(e)?f=4:"/"===e?f=12:">"===e?W():"<"===e?V():(f=4,c--)}function R(e){">"===e?(m=new ae(h(h({},m),{isClosing:!0})),W()):f=4}function M(t){"--"===e.substr(c,2)?(c+=2,m=new ae(h(h({},m),{type:"comment"})),f=14):"DOCTYPE"===e.substr(c,7).toUpperCase()?(c+=7,m=new ae(h(h({},m),{type:"doctype"})),f=20):$()}function D(e){"-"===e?f=15:">"===e?$():f=16}function L(e){"-"===e?f=18:">"===e?$():f=16}function B(e){"-"===e&&(f=17)}function F(e){f="-"===e?18:16}function z(e){">"===e?W():"!"===e?f=19:"-"===e||(f=16)}function U(e){"-"===e?f=17:">"===e?W():f=16}function q(e){">"===e?W():"<"===e&&V()}function $(){f=0,m=u}function V(){f=1,m=new ae({idx:c})}function W(){var t=e.slice(d,m.idx);t&&a(t,d),"comment"===m.type?i(m.idx):"doctype"===m.type?l(m.idx):(m.isOpening&&r(m.name,m.idx),m.isClosing&&o(m.name,m.idx)),$(),d=c+1}function H(){var t=m.idx+(m.isClosing?2:1);return e.slice(t,c).toLowerCase()}d=0&&r++},onText:function(e,n){if(0===r){var a=function(e,t){if(!t.global)throw new Error("`splitRegex` must have the 'g' flag set");for(var n,r=[],o=0;n=t.exec(e);)r.push(e.substring(o,n.index)),r.push(n[0]),o=n.index+n[0].length;return r.push(e.substring(o)),r}(e,/( | |<|<|>|>|"|"|')/gi),i=n;a.forEach((function(e,n){if(n%2==0){var r=t.parseText(e,i);o.push.apply(o,r)}i+=e.length}))}},onCloseTag:function(e){n.indexOf(e)>=0&&(r=Math.max(r-1,0))},onComment:function(e){},onDoctype:function(e){}}),o=this.compactMatches(o),o=this.removeUnwantedMatches(o)},e.prototype.compactMatches=function(e){e.sort((function(e,t){return e.getOffset()-t.getOffset()}));for(var t=0;to?t:t+1;e.splice(i,1);continue}if(e[t+1].getOffset()/g,">"));for(var t=this.parse(e),n=[],r=0,o=0,a=t.length;o/i.test(e)}function ue(){var e=[],t=new ie({stripPrefix:!1,url:!0,email:!0,replaceFn:function(t){switch(t.getType()){case"url":e.push({text:t.matchedText,url:t.getUrl()});break;case"email":e.push({text:t.matchedText,url:"mailto:"+t.getEmail().replace(/^mailto:/i,"")})}return!1}});return{links:e,autolinker:t}}function ce(e){var t,n,r,o,a,i,s,l,u,c,p,f,h,d,m=e.tokens,g=null;for(n=0,r=m.length;n=0;t--)if("link_close"!==(a=o[t]).type){if("htmltag"===a.type&&(d=a.content,/^\s]/i.test(d)&&p>0&&p--,le(a.content)&&p++),!(p>0)&&"text"===a.type&&se.test(a.content)){if(g||(f=(g=ue()).links,h=g.autolinker),i=a.content,f.length=0,h.link(i),!f.length)continue;for(s=[],c=a.level,l=0;l({useUnsafeMarkdown:!1})};const ye=ge;function ve(e){let{useUnsafeMarkdown:t=!1}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const n=t,r=t?[]:["style","class"];return t&&!ve.hasWarnedAboutDeprecation&&(console.warn("useUnsafeMarkdown display configuration parameter is deprecated since >3.26.0 and will be removed in v4.0.0."),ve.hasWarnedAboutDeprecation=!0),he().sanitize(e,{ADD_ATTR:["target"],FORBID_TAGS:["style","form"],ALLOW_DATA_ATTR:n,FORBID_ATTR:r})}ve.hasWarnedAboutDeprecation=!1},45308:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>f});var r,o=n(86),a=n.n(o),i=n(8712),s=n.n(i),l=n(90242),u=n(27621);const c=n(95102),p={},f=p;a()(r=s()(c).call(c)).call(r,(function(e){if("./index.js"===e)return;let t=c(e);p[(0,l.Zl)(e)]=t.default?t.default:t})),p.SafeRender=u.default},55812:(e,t,n)=>{"use strict";n.r(t),n.d(t,{AUTHORIZE:()=>f,AUTHORIZE_OAUTH2:()=>m,CONFIGURE_AUTH:()=>y,LOGOUT:()=>h,PRE_AUTHORIZE_OAUTH2:()=>d,RESTORE_AUTHORIZATION:()=>v,SHOW_AUTH_POPUP:()=>p,VALIDATE:()=>g,authPopup:()=>M,authorize:()=>w,authorizeAccessCodeWithBasicAuthentication:()=>T,authorizeAccessCodeWithFormParams:()=>j,authorizeApplication:()=>O,authorizeOauth2:()=>A,authorizeOauth2WithPersistOption:()=>C,authorizePassword:()=>k,authorizeRequest:()=>I,authorizeWithPersistOption:()=>E,configureAuth:()=>N,logout:()=>x,logoutWithPersistOption:()=>_,persistAuthorizationIfNeeded:()=>R,preAuthorizeImplicit:()=>S,restoreAuthorization:()=>P,showDefinitions:()=>b});var r=n(35627),o=n.n(r),a=n(76986),i=n.n(a),s=n(84564),l=n.n(s),u=n(27504),c=n(90242);const p="show_popup",f="authorize",h="logout",d="pre_authorize_oauth2",m="authorize_oauth2",g="validate",y="configure_auth",v="restore_authorization";function b(e){return{type:p,payload:e}}function w(e){return{type:f,payload:e}}const E=e=>t=>{let{authActions:n}=t;n.authorize(e),n.persistAuthorizationIfNeeded()};function x(e){return{type:h,payload:e}}const _=e=>t=>{let{authActions:n}=t;n.logout(e),n.persistAuthorizationIfNeeded()},S=e=>t=>{let{authActions:n,errActions:r}=t,{auth:a,token:i,isValid:s}=e,{schema:l,name:c}=a,p=l.get("flow");delete u.Z.swaggerUIRedirectOauth2,"accessCode"===p||s||r.newAuthErr({authId:c,source:"auth",level:"warning",message:"Authorization may be unsafe, passed state was changed in server Passed state wasn't returned from auth server"}),i.error?r.newAuthErr({authId:c,source:"auth",level:"error",message:o()(i)}):n.authorizeOauth2WithPersistOption({auth:a,token:i})};function A(e){return{type:m,payload:e}}const C=e=>t=>{let{authActions:n}=t;n.authorizeOauth2(e),n.persistAuthorizationIfNeeded()},k=e=>t=>{let{authActions:n}=t,{schema:r,name:o,username:a,password:s,passwordType:l,clientId:u,clientSecret:p}=e,f={grant_type:"password",scope:e.scopes.join(" "),username:a,password:s},h={};switch(l){case"request-body":!function(e,t,n){t&&i()(e,{client_id:t});n&&i()(e,{client_secret:n})}(f,u,p);break;case"basic":h.Authorization="Basic "+(0,c.r3)(u+":"+p);break;default:console.warn(`Warning: invalid passwordType ${l} was passed, not including client id and secret`)}return n.authorizeRequest({body:(0,c.GZ)(f),url:r.get("tokenUrl"),name:o,headers:h,query:{},auth:e})};const O=e=>t=>{let{authActions:n}=t,{schema:r,scopes:o,name:a,clientId:i,clientSecret:s}=e,l={Authorization:"Basic "+(0,c.r3)(i+":"+s)},u={grant_type:"client_credentials",scope:o.join(" ")};return n.authorizeRequest({body:(0,c.GZ)(u),name:a,url:r.get("tokenUrl"),auth:e,headers:l})},j=e=>{let{auth:t,redirectUrl:n}=e;return e=>{let{authActions:r}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={grant_type:"authorization_code",code:t.code,client_id:i,client_secret:s,redirect_uri:n,code_verifier:l};return r.authorizeRequest({body:(0,c.GZ)(u),name:a,url:o.get("tokenUrl"),auth:t})}},T=e=>{let{auth:t,redirectUrl:n}=e;return e=>{let{authActions:r}=e,{schema:o,name:a,clientId:i,clientSecret:s,codeVerifier:l}=t,u={Authorization:"Basic "+(0,c.r3)(i+":"+s)},p={grant_type:"authorization_code",code:t.code,client_id:i,redirect_uri:n,code_verifier:l};return r.authorizeRequest({body:(0,c.GZ)(p),name:a,url:o.get("tokenUrl"),auth:t,headers:u})}},I=e=>t=>{let n,{fn:r,getConfigs:a,authActions:s,errActions:u,oas3Selectors:c,specSelectors:p,authSelectors:f}=t,{body:h,query:d={},headers:m={},name:g,url:y,auth:v}=e,{additionalQueryStringParams:b}=f.getConfigs()||{};if(p.isOAS3()){let e=c.serverEffectiveValue(c.selectedServer());n=l()(y,e,!0)}else n=l()(y,p.url(),!0);"object"==typeof b&&(n.query=i()({},n.query,b));const w=n.toString();let E=i()({Accept:"application/json, text/plain, */*","Content-Type":"application/x-www-form-urlencoded","X-Requested-With":"XMLHttpRequest"},m);r.fetch({url:w,method:"post",headers:E,query:d,body:h,requestInterceptor:a().requestInterceptor,responseInterceptor:a().responseInterceptor}).then((function(e){let t=JSON.parse(e.data),n=t&&(t.error||""),r=t&&(t.parseError||"");e.ok?n||r?u.newAuthErr({authId:g,level:"error",source:"auth",message:o()(t)}):s.authorizeOauth2WithPersistOption({auth:v,token:t}):u.newAuthErr({authId:g,level:"error",source:"auth",message:e.statusText})})).catch((e=>{let t=new Error(e).message;if(e.response&&e.response.data){const n=e.response.data;try{const e="string"==typeof n?JSON.parse(n):n;e.error&&(t+=`, error: ${e.error}`),e.error_description&&(t+=`, description: ${e.error_description}`)}catch(e){}}u.newAuthErr({authId:g,level:"error",source:"auth",message:t})}))};function N(e){return{type:y,payload:e}}function P(e){return{type:v,payload:e}}const R=()=>e=>{let{authSelectors:t,getConfigs:n}=e;if(!n().persistAuthorization)return;const r=t.authorized().toJS();localStorage.setItem("authorized",o()(r))},M=(e,t)=>()=>{u.Z.swaggerUIRedirectOauth2=t,u.Z.open(e)}},53779:(e,t,n)=>{"use strict";n.r(t),n.d(t,{loaded:()=>r});const r=(e,t)=>n=>{const{getConfigs:r,authActions:o}=t,a=r();if(e(n),a.persistAuthorization){const e=localStorage.getItem("authorized");e&&o.restoreAuthorization({authorized:JSON.parse(e)})}}},93705:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p,preauthorizeApiKey:()=>h,preauthorizeBasic:()=>f});var r=n(11189),o=n.n(r),a=n(43962),i=n(55812),s=n(60035),l=n(60489),u=n(53779),c=n(22849);function p(){return{afterLoad(e){this.rootInjects=this.rootInjects||{},this.rootInjects.initOAuth=e.authActions.configureAuth,this.rootInjects.preauthorizeApiKey=o()(h).call(h,null,e),this.rootInjects.preauthorizeBasic=o()(f).call(f,null,e)},statePlugins:{auth:{reducers:a.default,actions:i,selectors:s,wrapActions:{authorize:c.authorize,logout:c.logout}},configs:{wrapActions:{loaded:u.loaded}},spec:{wrapActions:{execute:l.execute}}}}}function f(e,t,n,r){const{authActions:{authorize:o},specSelectors:{specJson:a,isOAS3:i}}=e,s=i()?["components","securitySchemes"]:["securityDefinitions"],l=a().getIn([...s,t]);return l?o({[t]:{value:{username:n,password:r},schema:l.toJS()}}):null}function h(e,t,n){const{authActions:{authorize:r},specSelectors:{specJson:o,isOAS3:a}}=e,i=a()?["components","securitySchemes"]:["securityDefinitions"],s=o().getIn([...i,t]);return s?r({[t]:{value:n,schema:s.toJS()}}):null}},43962:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(86),o=n.n(r),a=n(76986),i=n.n(a),s=n(43393),l=n(90242),u=n(55812);const c={[u.SHOW_AUTH_POPUP]:(e,t)=>{let{payload:n}=t;return e.set("showDefinitions",n)},[u.AUTHORIZE]:(e,t)=>{var n;let{payload:r}=t,a=(0,s.fromJS)(r),i=e.get("authorized")||(0,s.Map)();return o()(n=a.entrySeq()).call(n,(t=>{let[n,r]=t;if(!(0,l.Wl)(r.getIn))return e.set("authorized",i);let o=r.getIn(["schema","type"]);if("apiKey"===o||"http"===o)i=i.set(n,r);else if("basic"===o){let e=r.getIn(["value","username"]),t=r.getIn(["value","password"]);i=i.setIn([n,"value"],{username:e,header:"Basic "+(0,l.r3)(e+":"+t)}),i=i.setIn([n,"schema"],r.get("schema"))}})),e.set("authorized",i)},[u.AUTHORIZE_OAUTH2]:(e,t)=>{let n,{payload:r}=t,{auth:o,token:a}=r;o.token=i()({},a),n=(0,s.fromJS)(o);let l=e.get("authorized")||(0,s.Map)();return l=l.set(n.get("name"),n),e.set("authorized",l)},[u.LOGOUT]:(e,t)=>{let{payload:n}=t,r=e.get("authorized").withMutations((e=>{o()(n).call(n,(t=>{e.delete(t)}))}));return e.set("authorized",r)},[u.CONFIGURE_AUTH]:(e,t)=>{let{payload:n}=t;return e.set("configs",n)},[u.RESTORE_AUTHORIZATION]:(e,t)=>{let{payload:n}=t;return e.set("authorized",(0,s.fromJS)(n.authorized))}}},60035:(e,t,n)=>{"use strict";n.r(t),n.d(t,{authorized:()=>x,definitionsForRequirements:()=>E,definitionsToAuthorize:()=>b,getConfigs:()=>S,getDefinitionsByNames:()=>w,isAuthorized:()=>_,shownDefinitions:()=>v});var r=n(86),o=n.n(r),a=n(51679),i=n.n(a),s=n(14418),l=n.n(s),u=n(11882),c=n.n(u),p=n(97606),f=n.n(p),h=n(28222),d=n.n(h),m=n(20573),g=n(43393);const y=e=>e,v=(0,m.P1)(y,(e=>e.get("showDefinitions"))),b=(0,m.P1)(y,(()=>e=>{var t;let{specSelectors:n}=e,r=n.securityDefinitions()||(0,g.Map)({}),a=(0,g.List)();return o()(t=r.entrySeq()).call(t,(e=>{let[t,n]=e,r=(0,g.Map)();r=r.set(t,n),a=a.push(r)})),a})),w=(e,t)=>e=>{var n;let{specSelectors:r}=e;console.warn("WARNING: getDefinitionsByNames is deprecated and will be removed in the next major version.");let a=r.securityDefinitions(),i=(0,g.List)();return o()(n=t.valueSeq()).call(n,(e=>{var t;let n=(0,g.Map)();o()(t=e.entrySeq()).call(t,(e=>{let t,[r,i]=e,s=a.get(r);var l;"oauth2"===s.get("type")&&i.size&&(t=s.get("scopes"),o()(l=t.keySeq()).call(l,(e=>{i.contains(e)||(t=t.delete(e))})),s=s.set("allowedScopes",t));n=n.set(r,s)})),i=i.push(n)})),i},E=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,g.List)();return e=>{let{authSelectors:n}=e;const r=n.definitionsToAuthorize()||(0,g.List)();let a=(0,g.List)();return o()(r).call(r,(e=>{let n=i()(t).call(t,(t=>t.get(e.keySeq().first())));n&&(o()(e).call(e,((t,r)=>{if("oauth2"===t.get("type")){const i=n.get(r);let s=t.get("scopes");var a;if(g.List.isList(i)&&g.Map.isMap(s))o()(a=s.keySeq()).call(a,(e=>{i.contains(e)||(s=s.delete(e))})),e=e.set(r,t.set("scopes",s))}})),a=a.push(e))})),a}},x=(0,m.P1)(y,(e=>e.get("authorized")||(0,g.Map)())),_=(e,t)=>e=>{var n;let{authSelectors:r}=e,o=r.authorized();return g.List.isList(t)?!!l()(n=t.toJS()).call(n,(e=>{var t,n;return-1===c()(t=f()(n=d()(e)).call(n,(e=>!!o.get(e)))).call(t,!1)})).length:null},S=(0,m.P1)(y,(e=>e.get("configs")))},60489:(e,t,n)=>{"use strict";n.r(t),n.d(t,{execute:()=>r});const r=(e,t)=>{let{authSelectors:n,specSelectors:r}=t;return t=>{let{path:o,method:a,operation:i,extras:s}=t,l={authorized:n.authorized()&&n.authorized().toJS(),definitions:r.securityDefinitions()&&r.securityDefinitions().toJS(),specSecurity:r.security()&&r.security().toJS()};return e({path:o,method:a,operation:i,securities:l,...s})}}},22849:(e,t,n)=>{"use strict";n.r(t),n.d(t,{authorize:()=>u,logout:()=>c});var r=n(3665),o=n.n(r),a=n(58309),i=n.n(a),s=n(86),l=n.n(s);const u=(e,t)=>n=>{e(n);if(t.getConfigs().persistAuthorization)try{const[{schema:e,value:t}]=o()(n),r="apiKey"===e.get("type"),a="cookie"===e.get("in");r&&a&&(document.cookie=`${e.get("name")}=${t}; SameSite=None; Secure`)}catch(e){console.error("Error persisting cookie based apiKey in document.cookie.",e)}},c=(e,t)=>n=>{const r=t.getConfigs(),o=t.authSelectors.authorized();try{r.persistAuthorization&&i()(n)&&l()(n).call(n,(e=>{const t=o.get(e,{}),n="apiKey"===t.getIn(["schema","type"]),r="cookie"===t.getIn(["schema","in"]);if(n&&r){const e=t.getIn(["schema","name"]);document.cookie=`${e}=; Max-Age=-99999999`}}))}catch(e){console.error("Error deleting cookie based apiKey from document.cookie.",e)}e(n)}},70714:(e,t,n)=>{"use strict";n.r(t),n.d(t,{TOGGLE_CONFIGS:()=>o,UPDATE_CONFIGS:()=>r,loaded:()=>s,toggle:()=>i,update:()=>a});const r="configs_update",o="configs_toggle";function a(e,t){return{type:r,payload:{[e]:t}}}function i(e){return{type:o,payload:e}}const s=()=>()=>{}},92256:(e,t,n)=>{"use strict";n.r(t),n.d(t,{parseYamlConfig:()=>o});var r=n(1272);const o=(e,t)=>{try{return r.ZP.load(e)}catch(e){return t&&t.errActions.newThrownErr(new Error(e)),{}}}},46709:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(92256),o=n(70714),a=n(22698),i=n(69018),s=n(37743);const l={getLocalConfig:()=>(0,r.parseYamlConfig)('---\nurl: "https://petstore.swagger.io/v2/swagger.json"\ndom_id: "#swagger-ui"\nvalidatorUrl: "https://validator.swagger.io/validator"\n')};function u(){return{statePlugins:{spec:{actions:a,selectors:l},configs:{reducers:s.default,actions:o,selectors:i}}}}},37743:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(43393),o=n(70714);const a={[o.UPDATE_CONFIGS]:(e,t)=>e.merge((0,r.fromJS)(t.payload)),[o.TOGGLE_CONFIGS]:(e,t)=>{const n=t.payload,r=e.get(n);return e.set(n,!r)}}},69018:(e,t,n)=>{"use strict";n.r(t),n.d(t,{get:()=>a});var r=n(58309),o=n.n(r);const a=(e,t)=>e.getIn(o()(t)?t:[t])},22698:(e,t,n)=>{"use strict";n.r(t),n.d(t,{downloadConfig:()=>o,getConfigByUrl:()=>a});var r=n(92256);const o=e=>t=>{const{fn:{fetch:n}}=t;return n(e)},a=(e,t)=>n=>{let{specActions:o}=n;if(e)return o.downloadConfig(e).then(a,a);function a(n){n instanceof Error||n.status>=400?(o.updateLoadingStatus("failedConfig"),o.updateLoadingStatus("failedConfig"),o.updateUrl(""),console.error(n.statusText+" "+e.url),t(null)):t((0,r.parseYamlConfig)(n.text))}}},31970:(e,t,n)=>{"use strict";n.r(t),n.d(t,{setHash:()=>r});const r=e=>e?history.pushState(null,null,`#${e}`):window.location.hash=""},34980:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(41599),o=n(60877),a=n(34584);function i(){return[r.default,{statePlugins:{configs:{wrapActions:{loaded:(e,t)=>function(){e(...arguments);const n=decodeURIComponent(window.location.hash);t.layoutActions.parseDeepLinkHash(n)}}}},wrapComponents:{operation:o.default,OperationTag:a.default}}]}},41599:(e,t,n)=>{"use strict";n.r(t),n.d(t,{clearScrollTo:()=>S,default:()=>A,parseDeepLinkHash:()=>E,readyToScroll:()=>x,scrollTo:()=>w,scrollToElement:()=>_,show:()=>b});var r=n(58309),o=n.n(r),a=n(24278),i=n.n(a),s=n(97606),l=n.n(s),u=n(11882),c=n.n(u),p=n(31970),f=n(45172),h=n.n(f),d=n(90242),m=n(43393),g=n.n(m);const y="layout_scroll_to",v="layout_clear_scroll",b=(e,t)=>{let{getConfigs:n,layoutSelectors:r}=t;return function(){for(var t=arguments.length,a=new Array(t),i=0;i({type:y,payload:o()(e)?e:[e]}),E=e=>t=>{let{layoutActions:n,layoutSelectors:r,getConfigs:o}=t;if(o().deepLinking&&e){var a;let t=i()(e).call(e,1);"!"===t[0]&&(t=i()(t).call(t,1)),"/"===t[0]&&(t=i()(t).call(t,1));const o=l()(a=t.split("/")).call(a,(e=>e||"")),s=r.isShownKeyFromUrlHashArray(o),[u,p="",f=""]=s;if("operations"===u){const e=r.isShownKeyFromUrlHashArray([p]);c()(p).call(p,"_")>-1&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),n.show(l()(e).call(e,(e=>e.replace(/_/g," "))),!0)),n.show(e,!0)}(c()(p).call(p,"_")>-1||c()(f).call(f,"_")>-1)&&(console.warn("Warning: escaping deep link whitespace with `_` will be unsupported in v4.0, use `%20` instead."),n.show(l()(s).call(s,(e=>e.replace(/_/g," "))),!0)),n.show(s,!0),n.scrollTo(s)}},x=(e,t)=>n=>{const r=n.layoutSelectors.getScrollToKey();g().is(r,(0,m.fromJS)(e))&&(n.layoutActions.scrollToElement(t),n.layoutActions.clearScrollTo())},_=(e,t)=>n=>{try{t=t||n.fn.getScrollParent(e),h().createScroller(t).to(e)}catch(e){console.error(e)}},S=()=>({type:v});const A={fn:{getScrollParent:function(e,t){const n=document.documentElement;let r=getComputedStyle(e);const o="absolute"===r.position,a=t?/(auto|scroll|hidden)/:/(auto|scroll)/;if("fixed"===r.position)return n;for(let t=e;t=t.parentElement;)if(r=getComputedStyle(t),(!o||"static"!==r.position)&&a.test(r.overflow+r.overflowY+r.overflowX))return t;return n}},statePlugins:{layout:{actions:{scrollToElement:_,scrollTo:w,clearScrollTo:S,readyToScroll:x,parseDeepLinkHash:E},selectors:{getScrollToKey:e=>e.get("scrollToKey"),isShownKeyFromUrlHashArray(e,t){const[n,r]=t;return r?["operations",n,r]:n?["operations-tag",n]:[]},urlHashArrayFromIsShownKey(e,t){let[n,r,o]=t;return"operations"==n?[r,o]:"operations-tag"==n?[r]:[]}},reducers:{[y]:(e,t)=>e.set("scrollToKey",g().fromJS(t.payload)),[v]:e=>e.delete("scrollToKey")},wrapActions:{show:b}}}}},34584:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(61125),o=n.n(r),a=n(67294);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{tag:n}=this.props,r=["operations-tag",n];t.layoutActions.readyToScroll(r,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},60877:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(61125),o=n.n(r),a=n(67294);n(23930);const i=(e,t)=>class extends a.Component{constructor(){super(...arguments),o()(this,"onLoad",(e=>{const{operation:n}=this.props,{tag:r,operationId:o}=n.toObject();let{isShownKey:a}=n.toObject();a=a||["operations",r,o],t.layoutActions.readyToScroll(a,e)}))}render(){return a.createElement("span",{ref:this.onLoad},a.createElement(e,this.props))}}},48011:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>d});var r=n(76986),o=n.n(r),a=n(63460),i=n.n(a),s=n(11882),l=n.n(s),u=n(35627),c=n.n(u),p=n(20573),f=n(43393),h=n(27504);function d(e){let{fn:t}=e;return{statePlugins:{spec:{actions:{download:e=>n=>{let{errActions:r,specSelectors:a,specActions:s,getConfigs:l}=n,{fetch:u}=t;const c=l();function p(t){if(t instanceof Error||t.status>=400)return s.updateLoadingStatus("failed"),r.newThrownErr(o()(new Error((t.message||t.statusText)+" "+e),{source:"fetch"})),void(!t.status&&t instanceof Error&&function(){try{let t;if("URL"in h.Z?t=new(i())(e):(t=document.createElement("a"),t.href=e),"https:"!==t.protocol&&"https:"===h.Z.location.protocol){const e=o()(new Error(`Possible mixed-content issue? The page was loaded over https:// but a ${t.protocol}// URL was specified. Check that you are not attempting to load mixed content.`),{source:"fetch"});return void r.newThrownErr(e)}if(t.origin!==h.Z.location.origin){const e=o()(new Error(`Possible cross-origin (CORS) issue? The URL origin (${t.origin}) does not match the page (${h.Z.location.origin}). Check the server returns the correct 'Access-Control-Allow-*' headers.`),{source:"fetch"});r.newThrownErr(e)}}catch(e){return}}());s.updateLoadingStatus("success"),s.updateSpec(t.text),a.url()!==e&&s.updateUrl(e)}e=e||a.url(),s.updateLoadingStatus("loading"),r.clear({source:"fetch"}),u({url:e,loadSpec:!0,requestInterceptor:c.requestInterceptor||(e=>e),responseInterceptor:c.responseInterceptor||(e=>e),credentials:"same-origin",headers:{Accept:"application/json,*/*"}}).then(p,p)},updateLoadingStatus:e=>{let t=[null,"loading","failed","success","failedConfig"];return-1===l()(t).call(t,e)&&console.error(`Error: ${e} is not one of ${c()(t)}`),{type:"spec_update_loading_status",payload:e}}},reducers:{spec_update_loading_status:(e,t)=>"string"==typeof t.payload?e.set("loadingStatus",t.payload):e},selectors:{loadingStatus:(0,p.P1)((e=>e||(0,f.Map)()),(e=>e.get("loadingStatus")||null))}}}}}},34966:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CLEAR:()=>u,CLEAR_BY:()=>c,NEW_AUTH_ERR:()=>l,NEW_SPEC_ERR:()=>i,NEW_SPEC_ERR_BATCH:()=>s,NEW_THROWN_ERR:()=>o,NEW_THROWN_ERR_BATCH:()=>a,clear:()=>g,clearBy:()=>y,newAuthErr:()=>m,newSpecErr:()=>h,newSpecErrBatch:()=>d,newThrownErr:()=>p,newThrownErrBatch:()=>f});var r=n(7710);const o="err_new_thrown_err",a="err_new_thrown_err_batch",i="err_new_spec_err",s="err_new_spec_err_batch",l="err_new_auth_err",u="err_clear",c="err_clear_by";function p(e){return{type:o,payload:(0,r.serializeError)(e)}}function f(e){return{type:a,payload:e}}function h(e){return{type:i,payload:e}}function d(e){return{type:s,payload:e}}function m(e){return{type:l,payload:e}}function g(){return{type:u,payload:arguments.length>0&&void 0!==arguments[0]?arguments[0]:{}}}function y(){return{type:c,payload:arguments.length>0&&void 0!==arguments[0]?arguments[0]:()=>!0}}},56982:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(14418),o=n.n(r),a=n(97606),i=n.n(a),s=n(54061),l=n.n(s);const u=[n(2392),n(21835)];function c(e){var t;let n={jsSpec:{}},r=l()(u,((e,t)=>{try{let r=t.transform(e,n);return o()(r).call(r,(e=>!!e))}catch(t){return console.error("Transformer error:",t),e}}),e);return i()(t=o()(r).call(r,(e=>!!e))).call(t,(e=>(!e.get("line")&&e.get("path"),e)))}},2392:(e,t,n)=>{"use strict";n.r(t),n.d(t,{transform:()=>p});var r=n(97606),o=n.n(r),a=n(11882),i=n.n(a),s=n(24278),l=n.n(s),u=n(24282),c=n.n(u);function p(e){return o()(e).call(e,(e=>{var t;let n="is not of a type(s)",r=i()(t=e.get("message")).call(t,n);if(r>-1){var o,a;let t=l()(o=e.get("message")).call(o,r+19).split(",");return e.set("message",l()(a=e.get("message")).call(a,0,r)+function(e){return c()(e).call(e,((e,t,n,r)=>n===r.length-1&&r.length>1?e+"or "+t:r[n+1]&&r.length>2?e+t+", ":r[n+1]?e+t+" ":e+t),"should be a")}(t))}return e}))}},21835:(e,t,n)=>{"use strict";n.r(t),n.d(t,{transform:()=>r});n(97606),n(11882),n(27361),n(43393);function r(e,t){let{jsSpec:n}=t;return e}},77793:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(93527),o=n(34966),a=n(87667);function i(e){return{statePlugins:{err:{reducers:(0,r.default)(e),actions:o,selectors:a}}}}},93527:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>y});var r=n(76986),o=n.n(r),a=n(97606),i=n.n(a),s=n(39022),l=n.n(s),u=n(14418),c=n.n(u),p=n(2250),f=n.n(p),h=n(34966),d=n(43393),m=n(56982);let g={line:0,level:"error",message:"Unknown error"};function y(){return{[h.NEW_THROWN_ERR]:(e,t)=>{let{payload:n}=t,r=o()(g,n,{type:"thrown"});return e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(r)))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_THROWN_ERR_BATCH]:(e,t)=>{let{payload:n}=t;return n=i()(n).call(n,(e=>(0,d.fromJS)(o()(g,e,{type:"thrown"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(n))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR]:(e,t)=>{let{payload:n}=t,r=(0,d.fromJS)(n);return r=r.set("type","spec"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(r)).sortBy((e=>e.get("line"))))).update("errors",(e=>(0,m.default)(e)))},[h.NEW_SPEC_ERR_BATCH]:(e,t)=>{let{payload:n}=t;return n=i()(n).call(n,(e=>(0,d.fromJS)(o()(g,e,{type:"spec"})))),e.update("errors",(e=>{var t;return l()(t=e||(0,d.List)()).call(t,(0,d.fromJS)(n))})).update("errors",(e=>(0,m.default)(e)))},[h.NEW_AUTH_ERR]:(e,t)=>{let{payload:n}=t,r=(0,d.fromJS)(o()({},n));return r=r.set("type","auth"),e.update("errors",(e=>(e||(0,d.List)()).push((0,d.fromJS)(r)))).update("errors",(e=>(0,m.default)(e)))},[h.CLEAR]:(e,t)=>{var n;let{payload:r}=t;if(!r||!e.get("errors"))return e;let o=c()(n=e.get("errors")).call(n,(e=>{var t;return f()(t=e.keySeq()).call(t,(t=>{const n=e.get(t),o=r[t];return!o||n!==o}))}));return e.merge({errors:o})},[h.CLEAR_BY]:(e,t)=>{var n;let{payload:r}=t;if(!r||"function"!=typeof r)return e;let o=c()(n=e.get("errors")).call(n,(e=>r(e)));return e.merge({errors:o})}}}},87667:(e,t,n)=>{"use strict";n.r(t),n.d(t,{allErrors:()=>a,lastError:()=>i});var r=n(43393),o=n(20573);const a=(0,o.P1)((e=>e),(e=>e.get("errors",(0,r.List)()))),i=(0,o.P1)(a,(e=>e.last()))},49978:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4309);function o(){return{fn:{opsFilter:r.default}}}},4309:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(14418),o=n.n(r),a=n(11882),i=n.n(a);function s(e,t){return o()(e).call(e,((e,n)=>-1!==i()(n).call(n,t)))}},25474:(e,t,n)=>{"use strict";n.r(t),n.d(t,{SHOW:()=>s,UPDATE_FILTER:()=>a,UPDATE_LAYOUT:()=>o,UPDATE_MODE:()=>i,changeMode:()=>p,show:()=>c,updateFilter:()=>u,updateLayout:()=>l});var r=n(90242);const o="layout_update_layout",a="layout_update_filter",i="layout_update_mode",s="layout_show";function l(e){return{type:o,payload:e}}function u(e){return{type:a,payload:e}}function c(e){let t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return e=(0,r.AF)(e),{type:s,payload:{thing:e,shown:t}}}function p(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";return e=(0,r.AF)(e),{type:i,payload:{thing:e,mode:t}}}},26821:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(5672),o=n(25474),a=n(4400),i=n(28989);function s(){return{statePlugins:{layout:{reducers:r.default,actions:o,selectors:a},spec:{wrapSelectors:i}}}}},5672:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(39022),o=n.n(r),a=n(43393),i=n(25474);const s={[i.UPDATE_LAYOUT]:(e,t)=>e.set("layout",t.payload),[i.UPDATE_FILTER]:(e,t)=>e.set("filter",t.payload),[i.SHOW]:(e,t)=>{const n=t.payload.shown,r=(0,a.fromJS)(t.payload.thing);return e.update("shown",(0,a.fromJS)({}),(e=>e.set(r,n)))},[i.UPDATE_MODE]:(e,t)=>{var n;let r=t.payload.thing,a=t.payload.mode;return e.setIn(o()(n=["modes"]).call(n,r),(a||"")+"")}}},4400:(e,t,n)=>{"use strict";n.r(t),n.d(t,{current:()=>i,currentFilter:()=>s,isShown:()=>l,showSummary:()=>c,whatMode:()=>u});var r=n(20573),o=n(90242),a=n(43393);const i=e=>e.get("layout"),s=e=>e.get("filter"),l=(e,t,n)=>(t=(0,o.AF)(t),e.get("shown",(0,a.fromJS)({})).get((0,a.fromJS)(t),n)),u=function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"";return t=(0,o.AF)(t),e.getIn(["modes",...t],n)},c=(0,r.P1)((e=>e),(e=>!l(e,"editor")))},28989:(e,t,n)=>{"use strict";n.r(t),n.d(t,{taggedOperations:()=>a});var r=n(24278),o=n.n(r);const a=(e,t)=>function(n){for(var r=arguments.length,a=new Array(r>1?r-1:0),i=1;i=0&&(s=o()(s).call(s,0,f)),s}},9150:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(11189),o=n.n(r);function a(e){let{configs:t}=e;const n={debug:0,info:1,log:2,warn:3,error:4},r=e=>n[e]||-1;let{logLevel:a}=t,i=r(a);function s(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),o=1;o=i&&console[e](...n)}return s.warn=o()(s).call(s,null,"warn"),s.error=o()(s).call(s,null,"error"),s.info=o()(s).call(s,null,"info"),s.debug=o()(s).call(s,null,"debug"),{rootInjects:{log:s}}}},67002:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CLEAR_REQUEST_BODY_VALIDATE_ERROR:()=>f,CLEAR_REQUEST_BODY_VALUE:()=>h,SET_REQUEST_BODY_VALIDATE_ERROR:()=>p,UPDATE_ACTIVE_EXAMPLES_MEMBER:()=>s,UPDATE_REQUEST_BODY_INCLUSION:()=>i,UPDATE_REQUEST_BODY_VALUE:()=>o,UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG:()=>a,UPDATE_REQUEST_CONTENT_TYPE:()=>l,UPDATE_RESPONSE_CONTENT_TYPE:()=>u,UPDATE_SELECTED_SERVER:()=>r,UPDATE_SERVER_VARIABLE_VALUE:()=>c,clearRequestBodyValidateError:()=>_,clearRequestBodyValue:()=>A,initRequestBodyValidateError:()=>S,setActiveExamplesMember:()=>v,setRequestBodyInclusion:()=>y,setRequestBodyValidateError:()=>x,setRequestBodyValue:()=>m,setRequestContentType:()=>b,setResponseContentType:()=>w,setRetainRequestBodyValueFlag:()=>g,setSelectedServer:()=>d,setServerVariableValue:()=>E});const r="oas3_set_servers",o="oas3_set_request_body_value",a="oas3_set_request_body_retain_flag",i="oas3_set_request_body_inclusion",s="oas3_set_active_examples_member",l="oas3_set_request_content_type",u="oas3_set_response_content_type",c="oas3_set_server_variable_value",p="oas3_set_request_body_validate_error",f="oas3_clear_request_body_validate_error",h="oas3_clear_request_body_value";function d(e,t){return{type:r,payload:{selectedServerUrl:e,namespace:t}}}function m(e){let{value:t,pathMethod:n}=e;return{type:o,payload:{value:t,pathMethod:n}}}const g=e=>{let{value:t,pathMethod:n}=e;return{type:a,payload:{value:t,pathMethod:n}}};function y(e){let{value:t,pathMethod:n,name:r}=e;return{type:i,payload:{value:t,pathMethod:n,name:r}}}function v(e){let{name:t,pathMethod:n,contextType:r,contextName:o}=e;return{type:s,payload:{name:t,pathMethod:n,contextType:r,contextName:o}}}function b(e){let{value:t,pathMethod:n}=e;return{type:l,payload:{value:t,pathMethod:n}}}function w(e){let{value:t,path:n,method:r}=e;return{type:u,payload:{value:t,path:n,method:r}}}function E(e){let{server:t,namespace:n,key:r,val:o}=e;return{type:c,payload:{server:t,namespace:n,key:r,val:o}}}const x=e=>{let{path:t,method:n,validationErrors:r}=e;return{type:p,payload:{path:t,method:n,validationErrors:r}}},_=e=>{let{path:t,method:n}=e;return{type:f,payload:{path:t,method:n}}},S=e=>{let{pathMethod:t}=e;return{type:f,payload:{path:t[0],method:t[1]}}},A=e=>{let{pathMethod:t}=e;return{type:h,payload:{pathMethod:t}}}},73723:(e,t,n)=>{"use strict";n.r(t),n.d(t,{definitionsToAuthorize:()=>f});var r=n(86),o=n.n(r),a=n(14418),i=n.n(a),s=n(24282),l=n.n(s),u=n(20573),c=n(43393),p=n(7779);const f=(h=(0,u.P1)((e=>e),(e=>{let{specSelectors:t}=e;return t.securityDefinitions()}),((e,t)=>{var n;let r=(0,c.List)();return t?(o()(n=t.entrySeq()).call(n,(e=>{let[t,n]=e;const a=n.get("type");var s;if("oauth2"===a&&o()(s=n.get("flows").entrySeq()).call(s,(e=>{let[o,a]=e,s=(0,c.fromJS)({flow:o,authorizationUrl:a.get("authorizationUrl"),tokenUrl:a.get("tokenUrl"),scopes:a.get("scopes"),type:n.get("type"),description:n.get("description")});r=r.push(new c.Map({[t]:i()(s).call(s,(e=>void 0!==e))}))})),"http"!==a&&"apiKey"!==a||(r=r.push(new c.Map({[t]:n}))),"openIdConnect"===a&&n.get("openIdConnectData")){let e=n.get("openIdConnectData"),a=e.get("grant_types_supported")||["authorization_code","implicit"];o()(a).call(a,(o=>{var a;let s=e.get("scopes_supported")&&l()(a=e.get("scopes_supported")).call(a,((e,t)=>e.set(t,"")),new c.Map),u=(0,c.fromJS)({flow:o,authorizationUrl:e.get("authorization_endpoint"),tokenUrl:e.get("token_endpoint"),scopes:s,type:"oauth2",openIdConnectUrl:n.get("openIdConnectUrl")});r=r.push(new c.Map({[t]:i()(u).call(u,(e=>void 0!==e))}))}))}})),r):r})),(e,t)=>function(){const n=t.getSystem().specSelectors.specJson();for(var r=arguments.length,o=new Array(r),a=0;a{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(23101),o=n.n(r),a=n(97606),i=n.n(a),s=n(67294),l=(n(23930),n(43393));const u=e=>{var t;let{callbacks:n,getComponent:r,specPath:a}=e;const u=r("OperationContainer",!0);if(!n)return s.createElement("span",null,"No callbacks");let c=i()(t=n.entrySeq()).call(t,(t=>{var n;let[r,c]=t;return s.createElement("div",{key:r},s.createElement("h2",null,r),i()(n=c.entrySeq()).call(n,(t=>{var n;let[c,p]=t;return"$$ref"===c?null:s.createElement("div",{key:c},i()(n=p.entrySeq()).call(n,(t=>{let[n,i]=t;if("$$ref"===n)return null;let p=(0,l.fromJS)({operation:i});return s.createElement(u,o()({},e,{op:p,key:n,tag:"callbacks",method:n,path:c,specPath:a.push(r,c,n),allowTryItOut:!1}))})))})))}));return s.createElement("div",null,c)}},86775:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>f});var r=n(61125),o=n.n(r),a=n(76986),i=n.n(a),s=n(14418),l=n.n(s),u=n(97606),c=n.n(u),p=n(67294);class f extends p.Component{constructor(e,t){super(e,t),o()(this,"onChange",(e=>{let{onChange:t}=this.props,{value:n,name:r}=e.target,o=i()({},this.state.value);r?o[r]=n:o=n,this.setState({value:o},(()=>t(this.state)))}));let{name:n,schema:r}=this.props,a=this.getValue();this.state={name:n,schema:r,value:a}}getValue(){let{name:e,authorized:t}=this.props;return t&&t.getIn([e,"value"])}render(){var e;let{schema:t,getComponent:n,errSelectors:r,name:o}=this.props;const a=n("Input"),i=n("Row"),s=n("Col"),u=n("authError"),f=n("Markdown",!0),h=n("JumpToPath",!0),d=(t.get("scheme")||"").toLowerCase();let m=this.getValue(),g=l()(e=r.allErrors()).call(e,(e=>e.get("authId")===o));if("basic"===d){var y;let e=m?m.get("username"):null;return p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Basic)",p.createElement(h,{path:["securityDefinitions",o]})),e&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Username:"),e?p.createElement("code",null," ",e," "):p.createElement(s,null,p.createElement(a,{type:"text",required:"required",name:"username","aria-label":"auth-basic-username",onChange:this.onChange,autoFocus:!0}))),p.createElement(i,null,p.createElement("label",null,"Password:"),e?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{autoComplete:"new-password",name:"password",type:"password","aria-label":"auth-basic-password",onChange:this.onChange}))),c()(y=g.valueSeq()).call(y,((e,t)=>p.createElement(u,{error:e,key:t}))))}var v;return"bearer"===d?p.createElement("div",null,p.createElement("h4",null,p.createElement("code",null,o||t.get("name")),"  (http, Bearer)",p.createElement(h,{path:["securityDefinitions",o]})),m&&p.createElement("h6",null,"Authorized"),p.createElement(i,null,p.createElement(f,{source:t.get("description")})),p.createElement(i,null,p.createElement("label",null,"Value:"),m?p.createElement("code",null," ****** "):p.createElement(s,null,p.createElement(a,{type:"text","aria-label":"auth-bearer-value",onChange:this.onChange,autoFocus:!0}))),c()(v=g.valueSeq()).call(v,((e,t)=>p.createElement(u,{error:e,key:t})))):p.createElement("div",null,p.createElement("em",null,p.createElement("b",null,o)," HTTP authentication: unsupported scheme ",`'${d}'`))}}},76467:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(33427),o=n(42458),a=n(15757),i=n(56617),s=n(9928),l=n(45327),u=n(86775),c=n(96796);const p={Callbacks:r.default,HttpAuth:u.default,RequestBody:o.default,Servers:i.default,ServersContainer:s.default,RequestBodyEditor:l.default,OperationServers:c.default,operationLink:a.default}},15757:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(35627),o=n.n(r),a=n(97606),i=n.n(a),s=n(67294);n(23930);class l extends s.Component{render(){const{link:e,name:t,getComponent:n}=this.props,r=n("Markdown",!0);let a=e.get("operationId")||e.get("operationRef"),l=e.get("parameters")&&e.get("parameters").toJS(),u=e.get("description");return s.createElement("div",{className:"operation-link"},s.createElement("div",{className:"description"},s.createElement("b",null,s.createElement("code",null,t)),u?s.createElement(r,{source:u}):null),s.createElement("pre",null,"Operation `",a,"`",s.createElement("br",null),s.createElement("br",null),"Parameters ",function(e,t){var n;if("string"!=typeof t)return"";return i()(n=t.split("\n")).call(n,((t,n)=>n>0?Array(e+1).join(" ")+t:t)).join("\n")}(0,o()(l,null,2))||"{}",s.createElement("br",null)))}}const u=l},96796:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(61125),o=n.n(r),a=n(67294);n(23930);class i extends a.Component{constructor(){super(...arguments),o()(this,"setSelectedServer",(e=>{const{path:t,method:n}=this.props;return this.forceUpdate(),this.props.setSelectedServer(e,`${t}:${n}`)})),o()(this,"setServerVariableValue",(e=>{const{path:t,method:n}=this.props;return this.forceUpdate(),this.props.setServerVariableValue({...e,namespace:`${t}:${n}`})})),o()(this,"getSelectedServer",(()=>{const{path:e,method:t}=this.props;return this.props.getSelectedServer(`${e}:${t}`)})),o()(this,"getServerVariable",((e,t)=>{const{path:n,method:r}=this.props;return this.props.getServerVariable({namespace:`${n}:${r}`,server:e},t)})),o()(this,"getEffectiveServerValue",(e=>{const{path:t,method:n}=this.props;return this.props.getEffectiveServerValue({server:e,namespace:`${t}:${n}`})}))}render(){const{operationServers:e,pathServers:t,getComponent:n}=this.props;if(!e&&!t)return null;const r=n("Servers"),o=e||t,i=e?"operation":"path";return a.createElement("div",{className:"opblock-section operation-servers"},a.createElement("div",{className:"opblock-section-header"},a.createElement("div",{className:"tab-header"},a.createElement("h4",{className:"opblock-title"},"Servers"))),a.createElement("div",{className:"opblock-description-wrapper"},a.createElement("h4",{className:"message"},"These ",i,"-level options override the global server options."),a.createElement(r,{servers:o,currentServer:this.getSelectedServer(),setSelectedServer:this.setSelectedServer,setServerVariableValue:this.setServerVariableValue,getServerVariable:this.getServerVariable,getEffectiveServerValue:this.getEffectiveServerValue})))}}},45327:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(61125),o=n.n(r),a=n(67294),i=n(94184),s=n.n(i),l=n(90242);const u=Function.prototype;class c extends a.PureComponent{constructor(e,t){super(e,t),o()(this,"applyDefaultValue",(e=>{const{onChange:t,defaultValue:n}=e||this.props;return this.setState({value:n}),t(n)})),o()(this,"onChange",(e=>{this.props.onChange((0,l.Pz)(e))})),o()(this,"onDomChange",(e=>{const t=e.target.value;this.setState({value:t},(()=>this.onChange(t)))})),this.state={value:(0,l.Pz)(e.value)||e.defaultValue},e.onChange(e.value)}UNSAFE_componentWillReceiveProps(e){this.props.value!==e.value&&e.value!==this.state.value&&this.setState({value:(0,l.Pz)(e.value)}),!e.value&&e.defaultValue&&this.state.value&&this.applyDefaultValue(e)}render(){let{getComponent:e,errors:t}=this.props,{value:n}=this.state,r=t.size>0;const o=e("TextArea");return a.createElement("div",{className:"body-param"},a.createElement(o,{className:s()("body-param__text",{invalid:r}),title:t.size?t.join(", "):"",value:n,onChange:this.onDomChange}))}}o()(c,"defaultProps",{onChange:u,userHasEditedBody:!1})},42458:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>g,getDefaultRequestBodyValue:()=>m});var r=n(97606),o=n.n(r),a=n(11882),i=n.n(a),s=n(58118),l=n.n(s),u=n(58309),c=n.n(u),p=n(67294),f=(n(23930),n(43393)),h=n(90242),d=n(2518);const m=(e,t,n)=>{const r=e.getIn(["content",t]),o=r.get("schema").toJS(),a=void 0!==r.get("examples"),i=r.get("example"),s=a?r.getIn(["examples",n,"value"]):i,l=(0,h.xi)(o,t,{includeWriteOnly:!0},s);return(0,h.Pz)(l)},g=e=>{let{userHasEditedBody:t,requestBody:n,requestBodyValue:r,requestBodyInclusionSetting:a,requestBodyErrors:s,getComponent:u,getConfigs:g,specSelectors:y,fn:v,contentType:b,isExecute:w,specPath:E,onChange:x,onChangeIncludeEmpty:_,activeExamplesKey:S,updateActiveExamplesKey:A,setRetainRequestBodyValueFlag:C}=e;const k=e=>{x(e.target.files[0])},O=e=>{let t={key:e,shouldDispatchInit:!1,defaultValue:!0};return"no value"===a.get(e,"no value")&&(t.shouldDispatchInit=!0),t},j=u("Markdown",!0),T=u("modelExample"),I=u("RequestBodyEditor"),N=u("highlightCode"),P=u("ExamplesSelectValueRetainer"),R=u("Example"),M=u("ParameterIncludeEmpty"),{showCommonExtensions:D}=g(),L=n&&n.get("description")||null,B=n&&n.get("content")||new f.OrderedMap;b=b||B.keySeq().first()||"";const F=B.get(b,(0,f.OrderedMap)()),z=F.get("schema",(0,f.OrderedMap)()),U=F.get("examples",null),q=null==U?void 0:o()(U).call(U,((e,t)=>{var r;const o=null===(r=e)||void 0===r?void 0:r.get("value",null);return o&&(e=e.set("value",m(n,b,t),o)),e}));if(s=f.List.isList(s)?s:(0,f.List)(),!F.size)return null;const $="object"===F.getIn(["schema","type"]),V="binary"===F.getIn(["schema","format"]),W="base64"===F.getIn(["schema","format"]);if("application/octet-stream"===b||0===i()(b).call(b,"image/")||0===i()(b).call(b,"audio/")||0===i()(b).call(b,"video/")||V||W){const e=u("Input");return w?p.createElement(e,{type:"file",onChange:k}):p.createElement("i",null,"Example values are not available for ",p.createElement("code",null,b)," media types.")}if($&&("application/x-www-form-urlencoded"===b||0===i()(b).call(b,"multipart/"))&&z.get("properties",(0,f.OrderedMap)()).size>0){var H;const e=u("JsonSchemaForm"),t=u("ParameterExt"),n=z.get("properties",(0,f.OrderedMap)());return r=f.Map.isMap(r)?r:(0,f.OrderedMap)(),p.createElement("div",{className:"table-container"},L&&p.createElement(j,{source:L}),p.createElement("table",null,p.createElement("tbody",null,f.Map.isMap(n)&&o()(H=n.entrySeq()).call(H,(n=>{var i,d;let[m,g]=n;if(g.get("readOnly"))return;let y=D?(0,h.po)(g):null;const b=l()(i=z.get("required",(0,f.List)())).call(i,m),E=g.get("type"),S=g.get("format"),A=g.get("description"),C=r.getIn([m,"value"]),k=r.getIn([m,"errors"])||s,T=a.get(m)||!1,I=g.has("default")||g.has("example")||g.hasIn(["items","example"])||g.hasIn(["items","default"]),N=g.has("enum")&&(1===g.get("enum").size||b),P=I||N;let R="";"array"!==E||P||(R=[]),("object"===E||P)&&(R=(0,h.xi)(g,!1,{includeWriteOnly:!0})),"string"!=typeof R&&"object"===E&&(R=(0,h.Pz)(R)),"string"==typeof R&&"array"===E&&(R=JSON.parse(R));const L="string"===E&&("binary"===S||"base64"===S);return p.createElement("tr",{key:m,className:"parameters","data-property-name":m},p.createElement("td",{className:"parameters-col_name"},p.createElement("div",{className:b?"parameter__name required":"parameter__name"},m,b?p.createElement("span",null," *"):null),p.createElement("div",{className:"parameter__type"},E,S&&p.createElement("span",{className:"prop-format"},"($",S,")"),D&&y.size?o()(d=y.entrySeq()).call(d,(e=>{let[n,r]=e;return p.createElement(t,{key:`${n}-${r}`,xKey:n,xVal:r})})):null),p.createElement("div",{className:"parameter__deprecated"},g.get("deprecated")?"deprecated":null)),p.createElement("td",{className:"parameters-col_description"},p.createElement(j,{source:A}),w?p.createElement("div",null,p.createElement(e,{fn:v,dispatchInitialValue:!L,schema:g,description:m,getComponent:u,value:void 0===C?R:C,required:b,errors:k,onChange:e=>{x(e,[m])}}),b?null:p.createElement(M,{onChange:e=>_(m,e),isIncluded:T,isIncludedOptions:O(m),isDisabled:c()(C)?0!==C.length:!(0,h.O2)(C)})):null))})))))}const J=m(n,b,S);let K=null;return(0,d.O)(J)&&(K="json"),p.createElement("div",null,L&&p.createElement(j,{source:L}),q?p.createElement(P,{userHasEditedBody:t,examples:q,currentKey:S,currentUserInputValue:r,onSelect:e=>{A(e)},updateValue:x,defaultToFirstExample:!0,getComponent:u,setRetainRequestBodyValueFlag:C}):null,w?p.createElement("div",null,p.createElement(I,{value:r,errors:s,defaultValue:J,onChange:x,getComponent:u})):p.createElement(T,{getComponent:u,getConfigs:g,specSelectors:y,expandDepth:1,isExecute:w,schema:F.get("schema"),specPath:E.push("content",b),example:p.createElement(N,{className:"body-param__example",getConfigs:g,language:K,value:(0,h.Pz)(r)||J}),includeWriteOnly:!0}),q?p.createElement(R,{example:q.get(S),getComponent:u,getConfigs:g}):null)}},9928:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294);class o extends r.Component{render(){const{specSelectors:e,oas3Selectors:t,oas3Actions:n,getComponent:o}=this.props,a=e.servers(),i=o("Servers");return a&&a.size?r.createElement("div",null,r.createElement("span",{className:"servers-title"},"Servers"),r.createElement(i,{servers:a,currentServer:t.selectedServer(),setSelectedServer:n.setSelectedServer,setServerVariableValue:n.setServerVariableValue,getServerVariable:t.serverVariableValue,getEffectiveServerValue:t.serverEffectiveValue})):null}}},56617:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(61125),o=n.n(r),a=n(51679),i=n.n(a),s=n(97606),l=n.n(s),u=n(67294),c=n(43393);n(23930);class p extends u.Component{constructor(){super(...arguments),o()(this,"onServerChange",(e=>{this.setServer(e.target.value)})),o()(this,"onServerVariableValueChange",(e=>{let{setServerVariableValue:t,currentServer:n}=this.props,r=e.target.getAttribute("data-variable"),o=e.target.value;"function"==typeof t&&t({server:n,key:r,val:o})})),o()(this,"setServer",(e=>{let{setSelectedServer:t}=this.props;t(e)}))}componentDidMount(){var e;let{servers:t,currentServer:n}=this.props;n||this.setServer(null===(e=t.first())||void 0===e?void 0:e.get("url"))}UNSAFE_componentWillReceiveProps(e){let{servers:t,setServerVariableValue:n,getServerVariable:r}=e;if(this.props.currentServer!==e.currentServer||this.props.servers!==e.servers){var o;let a=i()(t).call(t,(t=>t.get("url")===e.currentServer)),s=i()(o=this.props.servers).call(o,(e=>e.get("url")===this.props.currentServer))||(0,c.OrderedMap)();if(!a)return this.setServer(t.first().get("url"));let u=s.get("variables")||(0,c.OrderedMap)(),p=(i()(u).call(u,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default"),f=a.get("variables")||(0,c.OrderedMap)(),h=(i()(f).call(f,(e=>e.get("default")))||(0,c.OrderedMap)()).get("default");l()(f).call(f,((t,o)=>{r(e.currentServer,o)&&p===h||n({server:e.currentServer,key:o,val:t.get("default")||""})}))}}render(){var e,t;let{servers:n,currentServer:r,getServerVariable:o,getEffectiveServerValue:a}=this.props,s=(i()(n).call(n,(e=>e.get("url")===r))||(0,c.OrderedMap)()).get("variables")||(0,c.OrderedMap)(),p=0!==s.size;return u.createElement("div",{className:"servers"},u.createElement("label",{htmlFor:"servers"},u.createElement("select",{onChange:this.onServerChange,value:r},l()(e=n.valueSeq()).call(e,(e=>u.createElement("option",{value:e.get("url"),key:e.get("url")},e.get("url"),e.get("description")&&` - ${e.get("description")}`))).toArray())),p?u.createElement("div",null,u.createElement("div",{className:"computed-url"},"Computed URL:",u.createElement("code",null,a(r))),u.createElement("h4",null,"Server variables"),u.createElement("table",null,u.createElement("tbody",null,l()(t=s.entrySeq()).call(t,(e=>{var t;let[n,a]=e;return u.createElement("tr",{key:n},u.createElement("td",null,n),u.createElement("td",null,a.get("enum")?u.createElement("select",{"data-variable":n,onChange:this.onServerVariableValueChange},l()(t=a.get("enum")).call(t,(e=>u.createElement("option",{selected:e===o(r,n),key:e,value:e},e)))):u.createElement("input",{type:"text",value:o(r,n)||"",onChange:this.onServerVariableValueChange,"data-variable":n})))}))))):null)}}},7779:(e,t,n)=>{"use strict";n.r(t),n.d(t,{OAS3ComponentWrapFactory:()=>c,isOAS3:()=>l,isSwagger2:()=>u});var r=n(23101),o=n.n(r),a=n(27043),i=n.n(a),s=n(67294);function l(e){const t=e.get("openapi");return"string"==typeof t&&(i()(t).call(t,"3.0.")&&t.length>4)}function u(e){const t=e.get("swagger");return"string"==typeof t&&i()(t).call(t,"2.0")}function c(e){return(t,n)=>r=>{if(n&&n.specSelectors&&n.specSelectors.specJson){return l(n.specSelectors.specJson())?s.createElement(e,o()({},r,n,{Ori:t})):s.createElement(t,r)}return console.warn("OAS3 wrapper: couldn't get spec"),null}}},97451:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(92044),o=n(73723),a=n(91741),i=n(76467),s=n(37761),l=n(67002),u=n(5065),c=n(62109);function p(){return{components:i.default,wrapComponents:s.default,statePlugins:{spec:{wrapSelectors:r,selectors:a},auth:{wrapSelectors:o},oas3:{actions:l,reducers:c.default,selectors:u}}}}},62109:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>p});var r=n(8712),o=n.n(r),a=n(86),i=n.n(a),s=n(24282),l=n.n(s),u=n(43393),c=n(67002);const p={[c.UPDATE_SELECTED_SERVER]:(e,t)=>{let{payload:{selectedServerUrl:n,namespace:r}}=t;const o=r?[r,"selectedServer"]:["selectedServer"];return e.setIn(o,n)},[c.UPDATE_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{value:n,pathMethod:r}}=t,[a,s]=r;if(!u.Map.isMap(n))return e.setIn(["requestData",a,s,"bodyValue"],n);let l,c=e.getIn(["requestData",a,s,"bodyValue"])||(0,u.Map)();u.Map.isMap(c)||(c=(0,u.Map)());const[...p]=o()(n).call(n);return i()(p).call(p,(e=>{let t=n.getIn([e]);c.has(e)&&u.Map.isMap(t)||(l=c.setIn([e,"value"],t))})),e.setIn(["requestData",a,s,"bodyValue"],l)},[c.UPDATE_REQUEST_BODY_VALUE_RETAIN_FLAG]:(e,t)=>{let{payload:{value:n,pathMethod:r}}=t,[o,a]=r;return e.setIn(["requestData",o,a,"retainBodyValue"],n)},[c.UPDATE_REQUEST_BODY_INCLUSION]:(e,t)=>{let{payload:{value:n,pathMethod:r,name:o}}=t,[a,i]=r;return e.setIn(["requestData",a,i,"bodyInclusion",o],n)},[c.UPDATE_ACTIVE_EXAMPLES_MEMBER]:(e,t)=>{let{payload:{name:n,pathMethod:r,contextType:o,contextName:a}}=t,[i,s]=r;return e.setIn(["examples",i,s,o,a,"activeExample"],n)},[c.UPDATE_REQUEST_CONTENT_TYPE]:(e,t)=>{let{payload:{value:n,pathMethod:r}}=t,[o,a]=r;return e.setIn(["requestData",o,a,"requestContentType"],n)},[c.UPDATE_RESPONSE_CONTENT_TYPE]:(e,t)=>{let{payload:{value:n,path:r,method:o}}=t;return e.setIn(["requestData",r,o,"responseContentType"],n)},[c.UPDATE_SERVER_VARIABLE_VALUE]:(e,t)=>{let{payload:{server:n,namespace:r,key:o,val:a}}=t;const i=r?[r,"serverVariableValues",n,o]:["serverVariableValues",n,o];return e.setIn(i,a)},[c.SET_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:n,method:r,validationErrors:o}}=t,a=[];if(a.push("Required field is not provided"),o.missingBodyValue)return e.setIn(["requestData",n,r,"errors"],(0,u.fromJS)(a));if(o.missingRequiredKeys&&o.missingRequiredKeys.length>0){const{missingRequiredKeys:t}=o;return e.updateIn(["requestData",n,r,"bodyValue"],(0,u.fromJS)({}),(e=>l()(t).call(t,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)(a))),e)))}return console.warn("unexpected result: SET_REQUEST_BODY_VALIDATE_ERROR"),e},[c.CLEAR_REQUEST_BODY_VALIDATE_ERROR]:(e,t)=>{let{payload:{path:n,method:r}}=t;const a=e.getIn(["requestData",n,r,"bodyValue"]);if(!u.Map.isMap(a))return e.setIn(["requestData",n,r,"errors"],(0,u.fromJS)([]));const[...i]=o()(a).call(a);return i?e.updateIn(["requestData",n,r,"bodyValue"],(0,u.fromJS)({}),(e=>l()(i).call(i,((e,t)=>e.setIn([t,"errors"],(0,u.fromJS)([]))),e))):e},[c.CLEAR_REQUEST_BODY_VALUE]:(e,t)=>{let{payload:{pathMethod:n}}=t,[r,o]=n;const a=e.getIn(["requestData",r,o,"bodyValue"]);return a?u.Map.isMap(a)?e.setIn(["requestData",r,o,"bodyValue"],(0,u.Map)()):e.setIn(["requestData",r,o,"bodyValue"],""):e}}},5065:(e,t,n)=>{"use strict";n.r(t),n.d(t,{activeExamplesMember:()=>_,hasUserEditedBody:()=>w,requestBodyErrors:()=>x,requestBodyInclusionSetting:()=>E,requestBodyValue:()=>y,requestContentType:()=>S,responseContentType:()=>A,selectDefaultRequestBodyValue:()=>b,selectedServer:()=>g,serverEffectiveValue:()=>O,serverVariableValue:()=>C,serverVariables:()=>k,shouldRetainRequestBodyValue:()=>v,validateBeforeExecute:()=>j,validateShallowRequired:()=>I});var r=n(97606),o=n.n(r),a=n(86),i=n.n(a),s=n(28222),l=n.n(s),u=n(11882),c=n.n(u),p=n(43393),f=n(7779),h=n(42458),d=n(90242);const m=e=>function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o{const o=n.getSystem().specSelectors.specJson();if((0,f.isOAS3)(o)){const o=e(t,...r);return"function"==typeof o?o(n):o}return null}};const g=m(((e,t)=>{const n=t?[t,"selectedServer"]:["selectedServer"];return e.getIn(n)||""})),y=m(((e,t,n)=>e.getIn(["requestData",t,n,"bodyValue"])||null)),v=m(((e,t,n)=>e.getIn(["requestData",t,n,"retainBodyValue"])||!1)),b=(e,t,n)=>e=>{const{oas3Selectors:r,specSelectors:o}=e.getSystem(),a=o.specJson();if((0,f.isOAS3)(a)){const e=r.requestContentType(t,n);if(e)return(0,h.getDefaultRequestBodyValue)(o.specResolvedSubtree(["paths",t,n,"requestBody"]),e,r.activeExamplesMember(t,n,"requestBody","requestBody"))}return null},w=m(((e,t,n)=>e=>{const{oas3Selectors:r,specSelectors:o}=e.getSystem();let a=!1;const i=r.requestContentType(t,n);let s=r.requestBodyValue(t,n);const l=o.specResolvedSubtree(["paths",t,n,"requestBody"]);if(!l)return!1;if(p.Map.isMap(s)&&(s=(0,d.Pz)(s.mapEntries((e=>p.Map.isMap(e[1])?[e[0],e[1].get("value")]:e)).toJS())),p.List.isList(s)&&(s=(0,d.Pz)(s)),i){const e=(0,h.getDefaultRequestBodyValue)(l,i,r.activeExamplesMember(t,n,"requestBody","requestBody"));a=!!s&&s!==e}return a})),E=m(((e,t,n)=>e.getIn(["requestData",t,n,"bodyInclusion"])||(0,p.Map)())),x=m(((e,t,n)=>e.getIn(["requestData",t,n,"errors"])||null)),_=m(((e,t,n,r,o)=>e.getIn(["examples",t,n,r,o,"activeExample"])||null)),S=m(((e,t,n)=>e.getIn(["requestData",t,n,"requestContentType"])||null)),A=m(((e,t,n)=>e.getIn(["requestData",t,n,"responseContentType"])||null)),C=m(((e,t,n)=>{let r;if("string"!=typeof t){const{server:e,namespace:o}=t;r=o?[o,"serverVariableValues",e,n]:["serverVariableValues",e,n]}else{r=["serverVariableValues",t,n]}return e.getIn(r)||null})),k=m(((e,t)=>{let n;if("string"!=typeof t){const{server:e,namespace:r}=t;n=r?[r,"serverVariableValues",e]:["serverVariableValues",e]}else{n=["serverVariableValues",t]}return e.getIn(n)||(0,p.OrderedMap)()})),O=m(((e,t)=>{var n,r;if("string"!=typeof t){const{server:o,namespace:a}=t;r=o,n=a?e.getIn([a,"serverVariableValues",r]):e.getIn(["serverVariableValues",r])}else r=t,n=e.getIn(["serverVariableValues",r]);n=n||(0,p.OrderedMap)();let a=r;return o()(n).call(n,((e,t)=>{a=a.replace(new RegExp(`{${t}}`,"g"),e)})),a})),j=(T=(e,t)=>((e,t)=>(t=t||[],!!e.getIn(["requestData",...t,"bodyValue"])))(e,t),function(){for(var e=arguments.length,t=new Array(e),n=0;n{const n=e.getSystem().specSelectors.specJson();let r=[...t][1]||[];return!n.getIn(["paths",...r,"requestBody","required"])||T(...t)}});var T;const I=(e,t)=>{var n;let{oas3RequiredRequestBodyContentType:r,oas3RequestContentType:o,oas3RequestBodyValue:a}=t,s=[];if(!p.Map.isMap(a))return s;let u=[];return i()(n=l()(r.requestContentType)).call(n,(e=>{if(e===o){let t=r.requestContentType[e];i()(t).call(t,(e=>{c()(u).call(u,e)<0&&u.push(e)}))}})),i()(u).call(u,(e=>{a.getIn([e,"value"])||s.push(e)})),s}},91741:(e,t,n)=>{"use strict";n.r(t),n.d(t,{isSwagger2:()=>p,servers:()=>u});var r=n(20573),o=n(43393),a=n(7779);const i=e=>e||(0,o.Map)(),s=(0,r.P1)(i,(e=>e.get("json",(0,o.Map)()))),l=(0,r.P1)(i,(e=>e.get("resolved",(0,o.Map)()))),u=(c=(0,r.P1)((e=>{let t=l(e);return t.count()<1&&(t=s(e)),t}),(e=>e.getIn(["servers"])||(0,o.Map)())),()=>function(e){const t=e.getSystem().specSelectors.specJson();if((0,a.isOAS3)(t)){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o()=>{const e=t.getSystem().specSelectors.specJson();return(0,a.isSwagger2)(e)}},92044:(e,t,n)=>{"use strict";n.r(t),n.d(t,{basePath:()=>y,consumes:()=>v,definitions:()=>h,hasHost:()=>d,host:()=>g,isOAS3:()=>x,isSwagger2:()=>_,produces:()=>b,schemes:()=>w,securityDefinitions:()=>m,servers:()=>E});var r=n(20573),o=n(33881),a=n(43393),i=n(7779);function s(e){return(t,n)=>function(){const r=n.getSystem().specSelectors.specJson();return(0,i.isOAS3)(r)?e(...arguments):t(...arguments)}}const l=e=>e||(0,a.Map)(),u=s((0,r.P1)((()=>null))),c=(0,r.P1)(l,(e=>e.get("json",(0,a.Map)()))),p=(0,r.P1)(l,(e=>e.get("resolved",(0,a.Map)()))),f=e=>{let t=p(e);return t.count()<1&&(t=c(e)),t},h=s((0,r.P1)(f,(e=>{const t=e.getIn(["components","schemas"]);return a.Map.isMap(t)?t:(0,a.Map)()}))),d=s((e=>f(e).hasIn(["servers",0]))),m=s((0,r.P1)(o.specJsonWithResolvedSubtrees,(e=>e.getIn(["components","securitySchemes"])||null))),g=u,y=u,v=u,b=u,w=u,E=s((0,r.P1)(f,(e=>e.getIn(["servers"])||(0,a.Map)()))),x=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isOAS3)(a.Map.isMap(e)?e:(0,a.Map)())},_=(e,t)=>()=>{const e=t.getSystem().specSelectors.specJson();return(0,i.isSwagger2)(a.Map.isMap(e)?e:(0,a.Map)())}},70356:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294);const o=(0,n(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...n}=e;const{schema:o,getComponent:a,errSelectors:i,authorized:s,onAuthChange:l,name:u}=n,c=a("HttpAuth");return"http"===o.get("type")?r.createElement(c,{key:u,schema:o,name:u,errSelectors:i,authorized:s,getComponent:a,onChange:l}):r.createElement(t,n)}))},37761:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(22460),o=n(70356),a=n(69487),i=n(50058),s=n(53499),l=n(90287);const u={Markdown:r.default,AuthItem:o.default,JsonSchema_string:l.default,VersionStamp:a.default,model:s.default,onlineValidatorBadge:i.default}},90287:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294);const o=(0,n(7779).OAS3ComponentWrapFactory)((e=>{let{Ori:t,...n}=e;const{schema:o,getComponent:a,errors:i,onChange:s}=n,l=o&&o.get?o.get("format"):null,u=o&&o.get?o.get("type"):null,c=a("Input");return u&&"string"===u&&l&&("binary"===l||"base64"===l)?r.createElement(c,{type:"file",className:i.length?"invalid":"",title:i.length?i:"",onChange:e=>{s(e.target.files[0])},disabled:t.isDisabled}):r.createElement(t,n)}))},22460:(e,t,n)=>{"use strict";n.r(t),n.d(t,{Markdown:()=>f,default:()=>h});var r=n(81607),o=n.n(r),a=n(67294),i=n(94184),s=n.n(i),l=n(89927),u=n(7779),c=n(94994);const p=new l._("commonmark");p.block.ruler.enable(["table"]),p.set({linkTarget:"_blank"});const f=e=>{let{source:t,className:n="",getConfigs:r}=e;if("string"!=typeof t)return null;if(t){const{useUnsafeMarkdown:e}=r(),i=p.render(t),l=(0,c.s)(i,{useUnsafeMarkdown:e});let u;return"string"==typeof l&&(u=o()(l).call(l)),a.createElement("div",{dangerouslySetInnerHTML:{__html:u},className:s()(n,"renderedMarkdown")})}return null};f.defaultProps={getConfigs:()=>({useUnsafeMarkdown:!1})};const h=(0,u.OAS3ComponentWrapFactory)(f)},53499:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(23101),o=n.n(r),a=n(67294),i=n(7779),s=n(53795);class l extends a.Component{render(){let{getConfigs:e,schema:t}=this.props,n=["model-box"],r=null;return!0===t.get("deprecated")&&(n.push("deprecated"),r=a.createElement("span",{className:"model-deprecated-warning"},"Deprecated:")),a.createElement("div",{className:n.join(" ")},r,a.createElement(s.Z,o()({},this.props,{getConfigs:e,depth:1,expandDepth:this.props.expandDepth||0})))}}const u=(0,i.OAS3ComponentWrapFactory)(l)},50058:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>a});var r=n(7779),o=n(5623);const a=(0,r.OAS3ComponentWrapFactory)(o.Z)},69487:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294);const o=(0,n(7779).OAS3ComponentWrapFactory)((e=>{const{Ori:t}=e;return r.createElement("span",null,r.createElement(t,e),r.createElement("small",{className:"version-stamp"},r.createElement("pre",{className:"version"},"OAS3")))}))},28560:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(87198),o=n.n(r);let a=!1;function i(){return{statePlugins:{spec:{wrapActions:{updateSpec:e=>function(){return a=!0,e(...arguments)},updateJsonSpec:(e,t)=>function(){const n=t.getConfigs().onComplete;return a&&"function"==typeof n&&(o()(n,0),a=!1),e(...arguments)}}}}}}},92135:(e,t,n)=>{"use strict";n.r(t),n.d(t,{requestSnippetGenerator_curl_bash:()=>A,requestSnippetGenerator_curl_cmd:()=>C,requestSnippetGenerator_curl_powershell:()=>S});var r=n(11882),o=n.n(r),a=n(81607),i=n.n(a),s=n(35627),l=n.n(s),u=n(97606),c=n.n(u),p=n(12196),f=n.n(p),h=n(74386),d=n.n(h),m=n(58118),g=n.n(m),y=n(27504),v=n(43393);const b=e=>{var t;const n="_**[]";return o()(e).call(e,n)<0?e:i()(t=e.split(n)[0]).call(t)},w=e=>"-d "===e||/^[_\/-]/g.test(e)?e:"'"+e.replace(/'/g,"'\\''")+"'",E=e=>"-d "===(e=e.replace(/\^/g,"^^").replace(/\\"/g,'\\\\"').replace(/"/g,'""').replace(/\n/g,"^\n"))?e.replace(/-d /g,"-d ^\n"):/^[_\/-]/g.test(e)?e:'"'+e+'"',x=e=>"-d "===e?e:/\n/.test(e)?'@"\n'+e.replace(/"/g,'\\"').replace(/`/g,"``").replace(/\$/,"`$")+'\n"@':/^[_\/-]/g.test(e)?e:"'"+e.replace(/"/g,'""').replace(/'/g,"''")+"'";const _=function(e,t,n){let r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:"",o=!1,a="";const i=function(){for(var e=arguments.length,n=new Array(e),r=0;ra+=` ${n}`,p=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:1;return a+=f()(" ").call(" ",e)};let h=e.get("headers");if(a+="curl"+r,e.has("curlOptions")&&i(...e.get("curlOptions")),i("-X",e.get("method")),u(),p(),s(`${e.get("url")}`),h&&h.size)for(let t of d()(m=e.get("headers")).call(m)){var m;u(),p();let[e,n]=t;s("-H",`${e}: ${n}`),o=o||/^content-type$/i.test(e)&&/^multipart\/form-data$/i.test(n)}const w=e.get("body");var E;if(w)if(o&&g()(E=["POST","PUT","PATCH"]).call(E,e.get("method")))for(let[e,t]of w.entrySeq()){let n=b(e);u(),p(),s("-F"),t instanceof y.Z.File?i(`${n}=@${t.name}${t.type?`;type=${t.type}`:""}`):i(`${n}=${t}`)}else if(w instanceof y.Z.File)u(),p(),s(`--data-binary '@${w.name}'`);else{u(),p(),s("-d ");let t=w;v.Map.isMap(t)?s(function(e){let t=[];for(let[n,r]of e.get("body").entrySeq()){let e=b(n);r instanceof y.Z.File?t.push(` "${e}": {\n "name": "${r.name}"${r.type?`,\n "type": "${r.type}"`:""}\n }`):t.push(` "${e}": ${l()(r,null,2).replace(/(\r\n|\r|\n)/g,"\n ")}`)}return`{\n${t.join(",\n")}\n}`}(e)):("string"!=typeof t&&(t=l()(t)),s(t))}else w||"POST"!==e.get("method")||(u(),p(),s("-d ''"));return a},S=e=>_(e,x,"`\n",".exe"),A=e=>_(e,w,"\\\n"),C=e=>_(e,E,"^\n")},86575:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>i});var r=n(92135),o=n(4669),a=n(84206);const i=()=>({components:{RequestSnippets:a.default},fn:r,statePlugins:{requestSnippets:{selectors:o}}})},84206:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>w});var r=n(14418),o=n.n(r),a=n(25110),i=n.n(a),s=n(86),l=n.n(s),u=n(97606),c=n.n(u),p=n(67294),f=n(27361),h=n.n(f),d=n(23560),m=n.n(d),g=n(74855),y=n(33424);const v={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(250, 250, 250)",paddingBottom:"0",paddingTop:"0",border:"1px solid rgb(51, 51, 51)",borderRadius:"4px 4px 0 0",boxShadow:"none",borderBottom:"none"},b={cursor:"pointer",lineHeight:1,display:"inline-flex",backgroundColor:"rgb(51, 51, 51)",boxShadow:"none",border:"1px solid rgb(51, 51, 51)",paddingBottom:"0",paddingTop:"0",borderRadius:"4px 4px 0 0",marginTop:"-5px",marginRight:"-5px",marginLeft:"-5px",zIndex:"9999",borderBottom:"none"},w=e=>{var t,n;let{request:r,requestSnippetsSelectors:a,getConfigs:s}=e;const u=m()(s)?s():null,f=!1!==h()(u,"syntaxHighlight")&&h()(u,"syntaxHighlight.activated",!0),d=(0,p.useRef)(null),[w,E]=(0,p.useState)(null===(t=a.getSnippetGenerators())||void 0===t?void 0:t.keySeq().first()),[x,_]=(0,p.useState)(null==a?void 0:a.getDefaultExpanded());(0,p.useEffect)((()=>{}),[]),(0,p.useEffect)((()=>{var e;const t=o()(e=i()(d.current.childNodes)).call(e,(e=>{var t;return!!e.nodeType&&(null===(t=e.classList)||void 0===t?void 0:t.contains("curl-command"))}));return l()(t).call(t,(e=>e.addEventListener("mousewheel",j,{passive:!1}))),()=>{l()(t).call(t,(e=>e.removeEventListener("mousewheel",j)))}}),[r]);const S=a.getSnippetGenerators(),A=S.get(w),C=A.get("fn")(r),k=()=>{_(!x)},O=e=>e===w?b:v,j=e=>{const{target:t,deltaY:n}=e,{scrollHeight:r,offsetHeight:o,scrollTop:a}=t;r>o&&(0===a&&n<0||o+a>=r&&n>0)&&e.preventDefault()},T=f?p.createElement(y.d3,{language:A.get("syntax"),className:"curl microlight",style:(0,y.C2)(h()(u,"syntaxHighlight.theme"))},C):p.createElement("textarea",{readOnly:!0,className:"curl",value:C});return p.createElement("div",{className:"request-snippets",ref:d},p.createElement("div",{style:{width:"100%",display:"flex",justifyContent:"flex-start",alignItems:"center",marginBottom:"15px"}},p.createElement("h4",{onClick:()=>k(),style:{cursor:"pointer"}},"Snippets"),p.createElement("button",{onClick:()=>k(),style:{border:"none",background:"none"},title:x?"Collapse operation":"Expand operation"},p.createElement("svg",{className:"arrow",width:"10",height:"10"},p.createElement("use",{href:x?"#large-arrow-down":"#large-arrow",xlinkHref:x?"#large-arrow-down":"#large-arrow"})))),x&&p.createElement("div",{className:"curl-command"},p.createElement("div",{style:{paddingLeft:"15px",paddingRight:"10px",width:"100%",display:"flex"}},c()(n=S.entrySeq()).call(n,(e=>{let[t,n]=e;return p.createElement("div",{style:O(t),className:"btn",key:t,onClick:()=>(e=>{w!==e&&E(e)})(t)},p.createElement("h4",{style:t===w?{color:"white"}:{}},n.get("title")))}))),p.createElement("div",{className:"copy-to-clipboard"},p.createElement(g.CopyToClipboard,{text:C},p.createElement("button",null))),p.createElement("div",null,T)))}},4669:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getActiveLanguage:()=>d,getDefaultExpanded:()=>m,getGenerators:()=>f,getSnippetGenerators:()=>h});var r=n(14418),o=n.n(r),a=n(58118),i=n.n(a),s=n(97606),l=n.n(s),u=n(20573),c=n(43393);const p=e=>e||(0,c.Map)(),f=(0,u.P1)(p,(e=>{const t=e.get("languages"),n=e.get("generators",(0,c.Map)());return!t||t.isEmpty()?n:o()(n).call(n,((e,n)=>i()(t).call(t,n)))})),h=e=>t=>{var n,r;let{fn:a}=t;return o()(n=l()(r=f(e)).call(r,((e,t)=>{const n=(e=>a[`requestSnippetGenerator_${e}`])(t);return"function"!=typeof n?null:e.set("fn",n)}))).call(n,(e=>e))},d=(0,u.P1)(p,(e=>e.get("activeLanguage"))),m=(0,u.P1)(p,(e=>e.get("defaultExpanded")))},36195:(e,t,n)=>{"use strict";n.r(t),n.d(t,{ErrorBoundary:()=>i,default:()=>s});var r=n(67294),o=n(56189),a=n(29403);class i extends r.Component{static getDerivedStateFromError(e){return{hasError:!0,error:e}}constructor(){super(...arguments),this.state={hasError:!1,error:null}}componentDidCatch(e,t){this.props.fn.componentDidCatch(e,t)}render(){const{getComponent:e,targetName:t,children:n}=this.props;if(this.state.hasError){const n=e("Fallback");return r.createElement(n,{name:t})}return n}}i.defaultProps={targetName:"this component",getComponent:()=>a.default,fn:{componentDidCatch:o.componentDidCatch},children:null};const s=i},29403:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(67294);const o=e=>{let{name:t}=e;return r.createElement("div",{className:"fallback"},"😱 ",r.createElement("i",null,"Could not render ","t"===t?"this component":t,", see the console."))}},56189:(e,t,n)=>{"use strict";n.r(t),n.d(t,{componentDidCatch:()=>i,withErrorBoundary:()=>s});var r=n(23101),o=n.n(r),a=n(67294);const i=console.error,s=e=>t=>{const{getComponent:n,fn:r}=e(),i=n("ErrorBoundary"),s=r.getDisplayName(t);class l extends a.Component{render(){return a.createElement(i,{targetName:s,getComponent:n,fn:r},a.createElement(t,o()({},this.props,this.context)))}}var u;return l.displayName=`WithErrorBoundary(${s})`,(u=t).prototype&&u.prototype.isReactComponent&&(l.prototype.mapStateToProps=t.prototype.mapStateToProps),l}},27621:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>c});var r=n(47475),o=n.n(r),a=n(7287),i=n.n(a),s=n(36195),l=n(29403),u=n(56189);const c=function(){let{componentList:e=[],fullOverride:t=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return n=>{var r;let{getSystem:a}=n;const c=t?e:["App","BaseLayout","VersionPragmaFilter","InfoContainer","ServersContainer","SchemesContainer","AuthorizeBtnContainer","FilterContainer","Operations","OperationContainer","parameters","responses","OperationServers","Models","ModelWrapper",...e],p=i()(c,o()(r=Array(c.length)).call(r,((e,t)=>{let{fn:n}=t;return n.withErrorBoundary(e)})));return{fn:{componentDidCatch:u.componentDidCatch,withErrorBoundary:(0,u.withErrorBoundary)(a)},components:{ErrorBoundary:s.default,Fallback:l.default},wrapComponents:p}}}},57050:(e,t,n)=>{"use strict";n.r(t),n.d(t,{createXMLExample:()=>U,inferSchema:()=>z,memoizedCreateXMLExample:()=>V,memoizedSampleFromSchema:()=>W,sampleFromSchema:()=>q,sampleFromSchemaGeneric:()=>F});var r=n(11882),o=n.n(r),a=n(86),i=n.n(a),s=n(58309),l=n.n(s),u=n(58118),c=n.n(u),p=n(92039),f=n.n(p),h=n(24278),d=n.n(h),m=n(51679),g=n.n(m),y=n(39022),v=n.n(y),b=n(97606),w=n.n(b),E=n(35627),x=n.n(E),_=n(53479),S=n.n(_),A=n(14419),C=n.n(A),k=n(41609),O=n.n(k),j=n(90242),T=n(60314);const I={string:e=>e.pattern?(e=>{try{return new(C())(e).gen()}catch(e){return"string"}})(e.pattern):"string",string_email:()=>"user@example.com","string_date-time":()=>(new Date).toISOString(),string_date:()=>(new Date).toISOString().substring(0,10),string_uuid:()=>"3fa85f64-5717-4562-b3fc-2c963f66afa6",string_hostname:()=>"example.com",string_ipv4:()=>"198.51.100.42",string_ipv6:()=>"2001:0db8:5b96:0000:0000:426f:8e17:642a",number:()=>0,number_float:()=>0,integer:()=>0,boolean:e=>"boolean"!=typeof e.default||e.default},N=e=>{e=(0,j.mz)(e);let{type:t,format:n}=e,r=I[`${t}_${n}`]||I[t];return(0,j.Wl)(r)?r(e):"Unknown Type: "+e.type},P=e=>(0,j.XV)(e,"$$ref",(e=>"string"==typeof e&&o()(e).call(e,"#")>-1)),R=["maxProperties","minProperties"],M=["minItems","maxItems"],D=["minimum","maximum","exclusiveMinimum","exclusiveMaximum"],L=["minLength","maxLength"],B=function(e,t){var n;let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};var a;(i()(n=["example","default","enum","xml","type",...R,...M,...D,...L]).call(n,(n=>(n=>{void 0===t[n]&&void 0!==e[n]&&(t[n]=e[n])})(n))),void 0!==e.required&&l()(e.required))&&(void 0!==t.required&&t.required.length||(t.required=[]),i()(a=e.required).call(a,(e=>{var n;c()(n=t.required).call(n,e)||t.required.push(e)})));if(e.properties){t.properties||(t.properties={});let n=(0,j.mz)(e.properties);for(let a in n){var s;if(Object.prototype.hasOwnProperty.call(n,a))if(!n[a]||!n[a].deprecated)if(!n[a]||!n[a].readOnly||r.includeReadOnly)if(!n[a]||!n[a].writeOnly||r.includeWriteOnly)if(!t.properties[a])t.properties[a]=n[a],!e.required&&l()(e.required)&&-1!==o()(s=e.required).call(s,a)&&(t.required?t.required.push(a):t.required=[a])}}return e.items&&(t.items||(t.items={}),t.items=B(e.items,t.items,r)),t},F=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:void 0,r=arguments.length>3&&void 0!==arguments[3]&&arguments[3];e&&(0,j.Wl)(e.toJS)&&(e=e.toJS());let a=void 0!==n||e&&void 0!==e.example||e&&void 0!==e.default;const s=!a&&e&&e.oneOf&&e.oneOf.length>0,u=!a&&e&&e.anyOf&&e.anyOf.length>0;if(!a&&(s||u)){const n=(0,j.mz)(s?e.oneOf[0]:e.anyOf[0]);if(B(n,e,t),!e.xml&&n.xml&&(e.xml=n.xml),void 0!==e.example&&void 0!==n.example)a=!0;else if(n.properties){e.properties||(e.properties={});let r=(0,j.mz)(n.properties);for(let a in r){var p;if(Object.prototype.hasOwnProperty.call(r,a))if(!r[a]||!r[a].deprecated)if(!r[a]||!r[a].readOnly||t.includeReadOnly)if(!r[a]||!r[a].writeOnly||t.includeWriteOnly)if(!e.properties[a])e.properties[a]=r[a],!n.required&&l()(n.required)&&-1!==o()(p=n.required).call(p,a)&&(e.required?e.required.push(a):e.required=[a])}}}const h={};let{xml:m,type:y,example:b,properties:E,additionalProperties:x,items:_}=e||{},{includeReadOnly:S,includeWriteOnly:A}=t;m=m||{};let C,{name:k,prefix:T,namespace:I}=m,L={};if(r&&(k=k||"notagname",C=(T?T+":":"")+k,I)){h[T?"xmlns:"+T:"xmlns"]=I}r&&(L[C]=[]);const z=t=>f()(t).call(t,(t=>Object.prototype.hasOwnProperty.call(e,t)));e&&!y&&(E||x||z(R)?y="object":_||z(M)?y="array":z(D)?(y="number",e.type="number"):a||e.enum||(y="string",e.type="string"));const U=t=>{var n,r,o,a,i;null!==(null===(n=e)||void 0===n?void 0:n.maxItems)&&void 0!==(null===(r=e)||void 0===r?void 0:r.maxItems)&&(t=d()(t).call(t,0,null===(i=e)||void 0===i?void 0:i.maxItems));if(null!==(null===(o=e)||void 0===o?void 0:o.minItems)&&void 0!==(null===(a=e)||void 0===a?void 0:a.minItems)){let n=0;for(;t.length<(null===(s=e)||void 0===s?void 0:s.minItems);){var s;t.push(t[n++%t.length])}}return t},q=(0,j.mz)(E);let $,V=0;const W=()=>e&&null!==e.maxProperties&&void 0!==e.maxProperties&&V>=e.maxProperties,H=t=>!e||null===e.maxProperties||void 0===e.maxProperties||!W()&&(!(t=>{var n;return!(e&&e.required&&e.required.length&&c()(n=e.required).call(n,t))})(t)||e.maxProperties-V-(()=>{if(!e||!e.required)return 0;let t=0;var n,o;return r?i()(n=e.required).call(n,(e=>t+=void 0===L[e]?0:1)):i()(o=e.required).call(o,(e=>{var n;return t+=void 0===(null===(n=L[C])||void 0===n?void 0:g()(n).call(n,(t=>void 0!==t[e])))?0:1})),e.required.length-t})()>0);if($=r?function(n){let o=arguments.length>1&&void 0!==arguments[1]?arguments[1]:void 0;if(e&&q[n]){if(q[n].xml=q[n].xml||{},q[n].xml.attribute){const e=l()(q[n].enum)?q[n].enum[0]:void 0,t=q[n].example,r=q[n].default;return void(h[q[n].xml.name||n]=void 0!==t?t:void 0!==r?r:void 0!==e?e:N(q[n]))}q[n].xml.name=q[n].xml.name||n}else q[n]||!1===x||(q[n]={xml:{name:n}});let a=F(e&&q[n]||void 0,t,o,r);var i;H(n)&&(V++,l()(a)?L[C]=v()(i=L[C]).call(i,a):L[C].push(a))}:(n,o)=>{if(H(n)){if(Object.prototype.hasOwnProperty.call(e,"discriminator")&&e.discriminator&&Object.prototype.hasOwnProperty.call(e.discriminator,"mapping")&&e.discriminator.mapping&&Object.prototype.hasOwnProperty.call(e,"$$ref")&&e.$$ref&&e.discriminator.propertyName===n){for(let t in e.discriminator.mapping)if(-1!==e.$$ref.search(e.discriminator.mapping[t])){L[n]=t;break}}else L[n]=F(q[n],t,o,r);V++}},a){let o;if(o=P(void 0!==n?n:void 0!==b?b:e.default),!r){if("number"==typeof o&&"string"===y)return`${o}`;if("string"!=typeof o||"string"===y)return o;try{return JSON.parse(o)}catch(e){return o}}if(e||(y=l()(o)?"array":typeof o),"array"===y){if(!l()(o)){if("string"==typeof o)return o;o=[o]}const n=e?e.items:void 0;n&&(n.xml=n.xml||m||{},n.xml.name=n.xml.name||m.name);let a=w()(o).call(o,(e=>F(n,t,e,r)));return a=U(a),m.wrapped?(L[C]=a,O()(h)||L[C].push({_attr:h})):L=a,L}if("object"===y){if("string"==typeof o)return o;for(let t in o)Object.prototype.hasOwnProperty.call(o,t)&&(e&&q[t]&&q[t].readOnly&&!S||e&&q[t]&&q[t].writeOnly&&!A||(e&&q[t]&&q[t].xml&&q[t].xml.attribute?h[q[t].xml.name||t]=o[t]:$(t,o[t])));return O()(h)||L[C].push({_attr:h}),L}return L[C]=O()(h)?o:[{_attr:h},o],L}if("object"===y){for(let e in q)Object.prototype.hasOwnProperty.call(q,e)&&(q[e]&&q[e].deprecated||q[e]&&q[e].readOnly&&!S||q[e]&&q[e].writeOnly&&!A||$(e));if(r&&h&&L[C].push({_attr:h}),W())return L;if(!0===x)r?L[C].push({additionalProp:"Anything can be here"}):L.additionalProp1={},V++;else if(x){const n=(0,j.mz)(x),o=F(n,t,void 0,r);if(r&&n.xml&&n.xml.name&&"notagname"!==n.xml.name)L[C].push(o);else{const t=null!==e.minProperties&&void 0!==e.minProperties&&VF(B(_,e,t),t,void 0,r)));else if(l()(_.oneOf)){var G;n=w()(G=_.oneOf).call(G,(e=>F(B(_,e,t),t,void 0,r)))}else{if(!(!r||r&&m.wrapped))return F(_,t,void 0,r);n=[F(_,t,void 0,r)]}return n=U(n),r&&m.wrapped?(L[C]=n,O()(h)||L[C].push({_attr:h}),L):n}let Z;if(e&&l()(e.enum))Z=(0,j.AF)(e.enum)[0];else{if(!e)return;if(Z=N(e),"number"==typeof Z){let t=e.minimum;null!=t&&(e.exclusiveMinimum&&t++,Z=t);let n=e.maximum;null!=n&&(e.exclusiveMaximum&&n--,Z=n)}if("string"==typeof Z&&(null!==e.maxLength&&void 0!==e.maxLength&&(Z=d()(Z).call(Z,0,e.maxLength)),null!==e.minLength&&void 0!==e.minLength)){let t=0;for(;Z.length(e.schema&&(e=e.schema),e.properties&&(e.type="object"),e),U=(e,t,n)=>{const r=F(e,t,n,!0);if(r)return"string"==typeof r?r:S()(r,{declaration:!0,indent:"\t"})},q=(e,t,n)=>F(e,t,n,!1),$=(e,t,n)=>[e,x()(t),x()(n)],V=(0,T.Z)(U,$),W=(0,T.Z)(q,$)},8883:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(57050);function o(){return{fn:r}}},51228:(e,t,n)=>{"use strict";n.r(t),n.d(t,{CLEAR_REQUEST:()=>Q,CLEAR_RESPONSE:()=>Y,CLEAR_VALIDATE_PARAMS:()=>X,LOG_REQUEST:()=>Z,SET_MUTATED_REQUEST:()=>G,SET_REQUEST:()=>K,SET_RESPONSE:()=>J,SET_SCHEME:()=>re,UPDATE_EMPTY_PARAM_INCLUSION:()=>W,UPDATE_JSON:()=>$,UPDATE_OPERATION_META_VALUE:()=>ee,UPDATE_PARAM:()=>V,UPDATE_RESOLVED:()=>te,UPDATE_RESOLVED_SUBTREE:()=>ne,UPDATE_SPEC:()=>U,UPDATE_URL:()=>q,VALIDATE_PARAMS:()=>H,changeConsumesValue:()=>xe,changeParam:()=>me,changeParamByIdentity:()=>ge,changeProducesValue:()=>_e,clearRequest:()=>Ie,clearResponse:()=>Te,clearValidateParams:()=>Ee,execute:()=>je,executeRequest:()=>Oe,invalidateResolvedSubtreeCache:()=>ve,logRequest:()=>ke,parseToJson:()=>ue,requestResolvedSubtree:()=>de,resolveSpec:()=>pe,setMutatedRequest:()=>Ce,setRequest:()=>Ae,setResponse:()=>Se,setScheme:()=>Ne,updateEmptyParamInclusion:()=>we,updateJsonSpec:()=>le,updateResolved:()=>ie,updateResolvedSubtree:()=>ye,updateSpec:()=>ae,updateUrl:()=>se,validateParams:()=>be});var r=n(58309),o=n.n(r),a=n(97606),i=n.n(a),s=n(96718),l=n.n(s),u=n(24282),c=n.n(u),p=n(2250),f=n.n(p),h=n(6226),d=n.n(h),m=n(14418),g=n.n(m),y=n(3665),v=n.n(y),b=n(11882),w=n.n(b),E=n(86),x=n.n(E),_=n(28222),S=n.n(_),A=n(76986),C=n.n(A),k=n(70586),O=n.n(k),j=n(1272),T=n(43393),I=n(84564),N=n.n(I),P=n(7710),R=n(47037),M=n.n(R),D=n(23279),L=n.n(D),B=n(36968),F=n.n(B),z=n(90242);const U="spec_update_spec",q="spec_update_url",$="spec_update_json",V="spec_update_param",W="spec_update_empty_param_inclusion",H="spec_validate_param",J="spec_set_response",K="spec_set_request",G="spec_set_mutated_request",Z="spec_log_request",Y="spec_clear_response",Q="spec_clear_request",X="spec_clear_validate_param",ee="spec_update_operation_meta_value",te="spec_update_resolved",ne="spec_update_resolved_subtree",re="set_scheme",oe=e=>M()(e)?e:"";function ae(e){const t=oe(e).replace(/\t/g," ");if("string"==typeof e)return{type:U,payload:t}}function ie(e){return{type:te,payload:e}}function se(e){return{type:q,payload:e}}function le(e){return{type:$,payload:e}}const ue=e=>t=>{let{specActions:n,specSelectors:r,errActions:o}=t,{specStr:a}=r,i=null;try{e=e||a(),o.clear({source:"parser"}),i=j.ZP.load(e,{schema:j.A8})}catch(e){return console.error(e),o.newSpecErr({source:"parser",level:"error",message:e.reason,line:e.mark&&e.mark.line?e.mark.line+1:void 0})}return i&&"object"==typeof i?n.updateJsonSpec(i):{}};let ce=!1;const pe=(e,t)=>n=>{let{specActions:r,specSelectors:a,errActions:s,fn:{fetch:u,resolve:c,AST:p={}},getConfigs:f}=n;ce||(console.warn("specActions.resolveSpec is deprecated since v3.10.0 and will be removed in v4.0.0; use requestResolvedSubtree instead!"),ce=!0);const{modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}=f();void 0===e&&(e=a.specJson()),void 0===t&&(t=a.url());let y=p.getLineNumberForPath?p.getLineNumberForPath:()=>{},v=a.specStr();return c({fetch:u,spec:e,baseDoc:t,modelPropertyMacro:h,parameterMacro:d,requestInterceptor:m,responseInterceptor:g}).then((e=>{let{spec:t,errors:n}=e;if(s.clear({type:"thrown"}),o()(n)&&n.length>0){let e=i()(n).call(n,(e=>(console.error(e),e.line=e.fullPath?y(v,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));s.newThrownErrBatch(e)}return r.updateResolved(t)}))};let fe=[];const he=L()((async()=>{const e=fe.system;if(!e)return void console.error("debResolveSubtrees: don't have a system to operate on, aborting.");const{errActions:t,errSelectors:n,fn:{resolveSubtree:r,fetch:a,AST:s={}},specSelectors:u,specActions:p}=e;if(!r)return void console.error("Error: Swagger-Client did not provide a `resolveSubtree` method, doing nothing.");let h=s.getLineNumberForPath?s.getLineNumberForPath:()=>{};const m=u.specStr(),{modelPropertyMacro:y,parameterMacro:b,requestInterceptor:w,responseInterceptor:E}=e.getConfigs();try{var x=await c()(fe).call(fe,(async(e,s)=>{const{resultMap:c,specWithCurrentSubtrees:p}=await e,{errors:x,spec:_}=await r(p,s,{baseDoc:u.url(),modelPropertyMacro:y,parameterMacro:b,requestInterceptor:w,responseInterceptor:E});if(n.allErrors().size&&t.clearBy((e=>{var t;return"thrown"!==e.get("type")||"resolver"!==e.get("source")||!f()(t=e.get("fullPath")).call(t,((e,t)=>e===s[t]||void 0===s[t]))})),o()(x)&&x.length>0){let e=i()(x).call(x,(e=>(e.line=e.fullPath?h(m,e.fullPath):null,e.path=e.fullPath?e.fullPath.join("."):null,e.level="error",e.type="thrown",e.source="resolver",l()(e,"message",{enumerable:!0,value:e.message}),e)));t.newThrownErrBatch(e)}var S,A;_&&u.isOAS3()&&"components"===s[0]&&"securitySchemes"===s[1]&&await d().all(i()(S=g()(A=v()(_)).call(A,(e=>"openIdConnect"===e.type))).call(S,(async e=>{const t={url:e.openIdConnectUrl,requestInterceptor:w,responseInterceptor:E};try{const n=await a(t);n instanceof Error||n.status>=400?console.error(n.statusText+" "+t.url):e.openIdConnectData=JSON.parse(n.text)}catch(e){console.error(e)}})));return F()(c,s,_),F()(p,s,_),{resultMap:c,specWithCurrentSubtrees:p}}),d().resolve({resultMap:(u.specResolvedSubtree([])||(0,T.Map)()).toJS(),specWithCurrentSubtrees:u.specJson().toJS()}));delete fe.system,fe=[]}catch(e){console.error(e)}p.updateResolvedSubtree([],x.resultMap)}),35),de=e=>t=>{var n;w()(n=i()(fe).call(fe,(e=>e.join("@@")))).call(n,e.join("@@"))>-1||(fe.push(e),fe.system=t,he())};function me(e,t,n,r,o){return{type:V,payload:{path:e,value:r,paramName:t,paramIn:n,isXml:o}}}function ge(e,t,n,r){return{type:V,payload:{path:e,param:t,value:n,isXml:r}}}const ye=(e,t)=>({type:ne,payload:{path:e,value:t}}),ve=()=>({type:ne,payload:{path:[],value:(0,T.Map)()}}),be=(e,t)=>({type:H,payload:{pathMethod:e,isOAS3:t}}),we=(e,t,n,r)=>({type:W,payload:{pathMethod:e,paramName:t,paramIn:n,includeEmptyValue:r}});function Ee(e){return{type:X,payload:{pathMethod:e}}}function xe(e,t){return{type:ee,payload:{path:e,value:t,key:"consumes_value"}}}function _e(e,t){return{type:ee,payload:{path:e,value:t,key:"produces_value"}}}const Se=(e,t,n)=>({payload:{path:e,method:t,res:n},type:J}),Ae=(e,t,n)=>({payload:{path:e,method:t,req:n},type:K}),Ce=(e,t,n)=>({payload:{path:e,method:t,req:n},type:G}),ke=e=>({payload:e,type:Z}),Oe=e=>t=>{let{fn:n,specActions:r,specSelectors:a,getConfigs:s,oas3Selectors:l}=t,{pathName:u,method:c,operation:p}=e,{requestInterceptor:f,responseInterceptor:h}=s(),d=p.toJS();var m,y;p&&p.get("parameters")&&x()(m=g()(y=p.get("parameters")).call(y,(e=>e&&!0===e.get("allowEmptyValue")))).call(m,(t=>{if(a.parameterInclusionSettingFor([u,c],t.get("name"),t.get("in"))){e.parameters=e.parameters||{};const n=(0,z.cz)(t,e.parameters);(!n||n&&0===n.size)&&(e.parameters[t.get("name")]="")}}));if(e.contextUrl=N()(a.url()).toString(),d&&d.operationId?e.operationId=d.operationId:d&&u&&c&&(e.operationId=n.opId(d,u,c)),a.isOAS3()){const t=`${u}:${c}`;e.server=l.selectedServer(t)||l.selectedServer();const n=l.serverVariables({server:e.server,namespace:t}).toJS(),r=l.serverVariables({server:e.server}).toJS();e.serverVariables=S()(n).length?n:r,e.requestContentType=l.requestContentType(u,c),e.responseContentType=l.responseContentType(u,c)||"*/*";const a=l.requestBodyValue(u,c),s=l.requestBodyInclusionSetting(u,c);var v;if(a&&a.toJS)e.requestBody=g()(v=i()(a).call(a,(e=>T.Map.isMap(e)?e.get("value"):e))).call(v,((e,t)=>(o()(e)?0!==e.length:!(0,z.O2)(e))||s.get(t))).toJS();else e.requestBody=a}let b=C()({},e);b=n.buildRequest(b),r.setRequest(e.pathName,e.method,b);e.requestInterceptor=async t=>{let n=await f.apply(void 0,[t]),o=C()({},n);return r.setMutatedRequest(e.pathName,e.method,o),n},e.responseInterceptor=h;const w=O()();return n.execute(e).then((t=>{t.duration=O()()-w,r.setResponse(e.pathName,e.method,t)})).catch((t=>{"Failed to fetch"===t.message&&(t.name="",t.message='**Failed to fetch.** \n**Possible Reasons:** \n - CORS \n - Network Failure \n - URL scheme must be "http" or "https" for CORS request.'),r.setResponse(e.pathName,e.method,{error:!0,err:(0,P.serializeError)(t)})}))},je=function(){let{path:e,method:t,...n}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return r=>{let{fn:{fetch:o},specSelectors:a,specActions:i}=r,s=a.specJsonWithResolvedSubtrees().toJS(),l=a.operationScheme(e,t),{requestContentType:u,responseContentType:c}=a.contentTypeValues([e,t]).toJS(),p=/xml/i.test(u),f=a.parameterValues([e,t],p).toJS();return i.executeRequest({...n,fetch:o,spec:s,pathName:e,method:t,parameters:f,requestContentType:u,scheme:l,responseContentType:c})}};function Te(e,t){return{type:Y,payload:{path:e,method:t}}}function Ie(e,t){return{type:Q,payload:{path:e,method:t}}}function Ne(e,t,n){return{type:re,payload:{scheme:e,path:t,method:n}}}},37038:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>s});var r=n(20032),o=n(51228),a=n(33881),i=n(77508);function s(){return{statePlugins:{spec:{wrapActions:i,reducers:r.default,actions:o,selectors:a}}}}},20032:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>d});var r=n(24282),o=n.n(r),a=n(97606),i=n.n(a),s=n(76986),l=n.n(s),u=n(43393),c=n(90242),p=n(27504),f=n(33881),h=n(51228);const d={[h.UPDATE_SPEC]:(e,t)=>"string"==typeof t.payload?e.set("spec",t.payload):e,[h.UPDATE_URL]:(e,t)=>e.set("url",t.payload+""),[h.UPDATE_JSON]:(e,t)=>e.set("json",(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED]:(e,t)=>e.setIn(["resolved"],(0,c.oG)(t.payload)),[h.UPDATE_RESOLVED_SUBTREE]:(e,t)=>{const{value:n,path:r}=t.payload;return e.setIn(["resolvedSubtrees",...r],(0,c.oG)(n))},[h.UPDATE_PARAM]:(e,t)=>{let{payload:n}=t,{path:r,paramName:o,paramIn:a,param:i,value:s,isXml:l}=n,u=i?(0,c.V9)(i):`${a}.${o}`;const p=l?"value_xml":"value";return e.setIn(["meta","paths",...r,"parameters",u,p],s)},[h.UPDATE_EMPTY_PARAM_INCLUSION]:(e,t)=>{let{payload:n}=t,{pathMethod:r,paramName:o,paramIn:a,includeEmptyValue:i}=n;if(!o||!a)return console.warn("Warning: UPDATE_EMPTY_PARAM_INCLUSION could not generate a paramKey."),e;const s=`${a}.${o}`;return e.setIn(["meta","paths",...r,"parameter_inclusions",s],i)},[h.VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:n,isOAS3:r}}=t;const a=(0,f.specJsonWithResolvedSubtrees)(e).getIn(["paths",...n]),i=(0,f.parameterValues)(e,n).toJS();return e.updateIn(["meta","paths",...n,"parameters"],(0,u.fromJS)({}),(t=>{var s;return o()(s=a.get("parameters",(0,u.List)())).call(s,((t,o)=>{const a=(0,c.cz)(o,i),s=(0,f.parameterInclusionSettingFor)(e,n,o.get("name"),o.get("in")),l=(0,c.Ik)(o,a,{bypassRequiredCheck:s,isOAS3:r});return t.setIn([(0,c.V9)(o),"errors"],(0,u.fromJS)(l))}),t)}))},[h.CLEAR_VALIDATE_PARAMS]:(e,t)=>{let{payload:{pathMethod:n}}=t;return e.updateIn(["meta","paths",...n,"parameters"],(0,u.fromJS)([]),(e=>i()(e).call(e,(e=>e.set("errors",(0,u.fromJS)([]))))))},[h.SET_RESPONSE]:(e,t)=>{let n,{payload:{res:r,path:o,method:a}}=t;n=r.error?l()({error:!0,name:r.err.name,message:r.err.message,statusCode:r.err.statusCode},r.err.response):r,n.headers=n.headers||{};let i=e.setIn(["responses",o,a],(0,c.oG)(n));return p.Z.Blob&&r.data instanceof p.Z.Blob&&(i=i.setIn(["responses",o,a,"text"],r.data)),i},[h.SET_REQUEST]:(e,t)=>{let{payload:{req:n,path:r,method:o}}=t;return e.setIn(["requests",r,o],(0,c.oG)(n))},[h.SET_MUTATED_REQUEST]:(e,t)=>{let{payload:{req:n,path:r,method:o}}=t;return e.setIn(["mutatedRequests",r,o],(0,c.oG)(n))},[h.UPDATE_OPERATION_META_VALUE]:(e,t)=>{let{payload:{path:n,value:r,key:o}}=t,a=["paths",...n],i=["meta","paths",...n];return e.getIn(["json",...a])||e.getIn(["resolved",...a])||e.getIn(["resolvedSubtrees",...a])?e.setIn([...i,o],(0,u.fromJS)(r)):e},[h.CLEAR_RESPONSE]:(e,t)=>{let{payload:{path:n,method:r}}=t;return e.deleteIn(["responses",n,r])},[h.CLEAR_REQUEST]:(e,t)=>{let{payload:{path:n,method:r}}=t;return e.deleteIn(["requests",n,r])},[h.SET_SCHEME]:(e,t)=>{let{payload:{scheme:n,path:r,method:o}}=t;return r&&o?e.setIn(["scheme",r,o],n):r||o?void 0:e.setIn(["scheme","_defaultScheme"],n)}}},33881:(e,t,n)=>{"use strict";n.r(t),n.d(t,{allowTryItOutFor:()=>pe,basePath:()=>Y,canExecuteScheme:()=>Ce,consumes:()=>W,consumesOptionsFor:()=>Se,contentTypeValues:()=>Ee,currentProducesFor:()=>xe,definitions:()=>Z,externalDocs:()=>z,findDefinition:()=>G,getOAS3RequiredRequestBodyContentType:()=>je,getParameter:()=>ge,hasHost:()=>ye,host:()=>Q,info:()=>F,isMediaTypeSchemaPropertiesEqual:()=>Te,isOAS3:()=>B,lastError:()=>O,mutatedRequestFor:()=>ce,mutatedRequests:()=>se,operationScheme:()=>Ae,operationWithMeta:()=>me,operations:()=>V,operationsWithRootInherited:()=>ee,operationsWithTags:()=>re,parameterInclusionSettingFor:()=>he,parameterValues:()=>ve,parameterWithMeta:()=>de,parameterWithMetaByIdentity:()=>fe,parametersIncludeIn:()=>be,parametersIncludeType:()=>we,paths:()=>$,produces:()=>H,producesOptionsFor:()=>_e,requestFor:()=>ue,requests:()=>ie,responseFor:()=>le,responses:()=>ae,schemes:()=>X,security:()=>J,securityDefinitions:()=>K,semver:()=>q,spec:()=>L,specJson:()=>N,specJsonWithResolvedSubtrees:()=>D,specResolved:()=>P,specResolvedSubtree:()=>R,specSource:()=>I,specStr:()=>T,tagDetails:()=>ne,taggedOperations:()=>oe,tags:()=>te,url:()=>j,validateBeforeExecute:()=>Oe,validationErrors:()=>ke,version:()=>U});var r=n(24278),o=n.n(r),a=n(86),i=n.n(a),s=n(11882),l=n.n(s),u=n(97606),c=n.n(u),p=n(14418),f=n.n(p),h=n(51679),d=n.n(h),m=n(24282),g=n.n(m),y=n(2578),v=n.n(y),b=n(92039),w=n.n(b),E=n(58309),x=n.n(E),_=n(20573),S=n(90242),A=n(43393);const C=["get","put","post","delete","options","head","patch","trace"],k=e=>e||(0,A.Map)(),O=(0,_.P1)(k,(e=>e.get("lastError"))),j=(0,_.P1)(k,(e=>e.get("url"))),T=(0,_.P1)(k,(e=>e.get("spec")||"")),I=(0,_.P1)(k,(e=>e.get("specSource")||"not-editor")),N=(0,_.P1)(k,(e=>e.get("json",(0,A.Map)()))),P=(0,_.P1)(k,(e=>e.get("resolved",(0,A.Map)()))),R=(e,t)=>e.getIn(["resolvedSubtrees",...t],void 0),M=(e,t)=>A.Map.isMap(e)&&A.Map.isMap(t)?t.get("$$ref")?t:(0,A.OrderedMap)().mergeWith(M,e,t):t,D=(0,_.P1)(k,(e=>(0,A.OrderedMap)().mergeWith(M,e.get("json"),e.get("resolvedSubtrees")))),L=e=>N(e),B=(0,_.P1)(L,(()=>!1)),F=(0,_.P1)(L,(e=>Ie(e&&e.get("info")))),z=(0,_.P1)(L,(e=>Ie(e&&e.get("externalDocs")))),U=(0,_.P1)(F,(e=>e&&e.get("version"))),q=(0,_.P1)(U,(e=>{var t;return o()(t=/v?([0-9]*)\.([0-9]*)\.([0-9]*)/i.exec(e)).call(t,1)})),$=(0,_.P1)(D,(e=>e.get("paths"))),V=(0,_.P1)($,(e=>{if(!e||e.size<1)return(0,A.List)();let t=(0,A.List)();return e&&i()(e)?(i()(e).call(e,((e,n)=>{if(!e||!i()(e))return{};i()(e).call(e,((e,r)=>{l()(C).call(C,r)<0||(t=t.push((0,A.fromJS)({path:n,method:r,operation:e,id:`${r}-${n}`})))}))})),t):(0,A.List)()})),W=(0,_.P1)(L,(e=>(0,A.Set)(e.get("consumes")))),H=(0,_.P1)(L,(e=>(0,A.Set)(e.get("produces")))),J=(0,_.P1)(L,(e=>e.get("security",(0,A.List)()))),K=(0,_.P1)(L,(e=>e.get("securityDefinitions"))),G=(e,t)=>{const n=e.getIn(["resolvedSubtrees","definitions",t],null),r=e.getIn(["json","definitions",t],null);return n||r||null},Z=(0,_.P1)(L,(e=>{const t=e.get("definitions");return A.Map.isMap(t)?t:(0,A.Map)()})),Y=(0,_.P1)(L,(e=>e.get("basePath"))),Q=(0,_.P1)(L,(e=>e.get("host"))),X=(0,_.P1)(L,(e=>e.get("schemes",(0,A.Map)()))),ee=(0,_.P1)(V,W,H,((e,t,n)=>c()(e).call(e,(e=>e.update("operation",(e=>{if(e){if(!A.Map.isMap(e))return;return e.withMutations((e=>(e.get("consumes")||e.update("consumes",(e=>(0,A.Set)(e).merge(t))),e.get("produces")||e.update("produces",(e=>(0,A.Set)(e).merge(n))),e)))}return(0,A.Map)()})))))),te=(0,_.P1)(L,(e=>{const t=e.get("tags",(0,A.List)());return A.List.isList(t)?f()(t).call(t,(e=>A.Map.isMap(e))):(0,A.List)()})),ne=(e,t)=>{var n;let r=te(e)||(0,A.List)();return d()(n=f()(r).call(r,A.Map.isMap)).call(n,(e=>e.get("name")===t),(0,A.Map)())},re=(0,_.P1)(ee,te,((e,t)=>g()(e).call(e,((e,t)=>{let n=(0,A.Set)(t.getIn(["operation","tags"]));return n.count()<1?e.update("default",(0,A.List)(),(e=>e.push(t))):g()(n).call(n,((e,n)=>e.update(n,(0,A.List)(),(e=>e.push(t)))),e)}),g()(t).call(t,((e,t)=>e.set(t.get("name"),(0,A.List)())),(0,A.OrderedMap)())))),oe=e=>t=>{var n;let{getConfigs:r}=t,{tagsSorter:o,operationsSorter:a}=r();return c()(n=re(e).sortBy(((e,t)=>t),((e,t)=>{let n="function"==typeof o?o:S.wh.tagsSorter[o];return n?n(e,t):null}))).call(n,((t,n)=>{let r="function"==typeof a?a:S.wh.operationsSorter[a],o=r?v()(t).call(t,r):t;return(0,A.Map)({tagDetails:ne(e,n),operations:o})}))},ae=(0,_.P1)(k,(e=>e.get("responses",(0,A.Map)()))),ie=(0,_.P1)(k,(e=>e.get("requests",(0,A.Map)()))),se=(0,_.P1)(k,(e=>e.get("mutatedRequests",(0,A.Map)()))),le=(e,t,n)=>ae(e).getIn([t,n],null),ue=(e,t,n)=>ie(e).getIn([t,n],null),ce=(e,t,n)=>se(e).getIn([t,n],null),pe=()=>!0,fe=(e,t,n)=>{const r=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),o=e.getIn(["meta","paths",...t,"parameters"],(0,A.OrderedMap)()),a=c()(r).call(r,(e=>{const t=o.get(`${n.get("in")}.${n.get("name")}`),r=o.get(`${n.get("in")}.${n.get("name")}.hash-${n.hashCode()}`);return(0,A.OrderedMap)().merge(e,t,r)}));return d()(a).call(a,(e=>e.get("in")===n.get("in")&&e.get("name")===n.get("name")),(0,A.OrderedMap)())},he=(e,t,n,r)=>{const o=`${r}.${n}`;return e.getIn(["meta","paths",...t,"parameter_inclusions",o],!1)},de=(e,t,n,r)=>{const o=D(e).getIn(["paths",...t,"parameters"],(0,A.OrderedMap)()),a=d()(o).call(o,(e=>e.get("in")===r&&e.get("name")===n),(0,A.OrderedMap)());return fe(e,t,a)},me=(e,t,n)=>{var r;const o=D(e).getIn(["paths",t,n],(0,A.OrderedMap)()),a=e.getIn(["meta","paths",t,n],(0,A.OrderedMap)()),i=c()(r=o.get("parameters",(0,A.List)())).call(r,(r=>fe(e,[t,n],r)));return(0,A.OrderedMap)().merge(o,a).set("parameters",i)};function ge(e,t,n,r){t=t||[];let o=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([]));return d()(o).call(o,(e=>A.Map.isMap(e)&&e.get("name")===n&&e.get("in")===r))||(0,A.Map)()}const ye=(0,_.P1)(L,(e=>{const t=e.get("host");return"string"==typeof t&&t.length>0&&"/"!==t[0]}));function ve(e,t,n){t=t||[];let r=me(e,...t).get("parameters",(0,A.List)());return g()(r).call(r,((e,t)=>{let r=n&&"body"===t.get("in")?t.get("value_xml"):t.get("value");return e.set((0,S.V9)(t,{allowHashes:!1}),r)}),(0,A.fromJS)({}))}function be(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("in")===t))}function we(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";if(A.List.isList(e))return w()(e).call(e,(e=>A.Map.isMap(e)&&e.get("type")===t))}function Ee(e,t){t=t||[];let n=D(e).getIn(["paths",...t],(0,A.fromJS)({})),r=e.getIn(["meta","paths",...t],(0,A.fromJS)({})),o=xe(e,t);const a=n.get("parameters")||new A.List,i=r.get("consumes_value")?r.get("consumes_value"):we(a,"file")?"multipart/form-data":we(a,"formData")?"application/x-www-form-urlencoded":void 0;return(0,A.fromJS)({requestContentType:i,responseContentType:o})}function xe(e,t){t=t||[];const n=D(e).getIn(["paths",...t],null);if(null===n)return;const r=e.getIn(["meta","paths",...t,"produces_value"],null),o=n.getIn(["produces",0],null);return r||o||"application/json"}function _e(e,t){t=t||[];const n=D(e),r=n.getIn(["paths",...t],null);if(null===r)return;const[o]=t,a=r.get("produces",null),i=n.getIn(["paths",o,"produces"],null),s=n.getIn(["produces"],null);return a||i||s}function Se(e,t){t=t||[];const n=D(e),r=n.getIn(["paths",...t],null);if(null===r)return;const[o]=t,a=r.get("consumes",null),i=n.getIn(["paths",o,"consumes"],null),s=n.getIn(["consumes"],null);return a||i||s}const Ae=(e,t,n)=>{let r=e.get("url").match(/^([a-z][a-z0-9+\-.]*):/),o=x()(r)?r[1]:null;return e.getIn(["scheme",t,n])||e.getIn(["scheme","_defaultScheme"])||o||""},Ce=(e,t,n)=>{var r;return l()(r=["http","https"]).call(r,Ae(e,t,n))>-1},ke=(e,t)=>{t=t||[];let n=e.getIn(["meta","paths",...t,"parameters"],(0,A.fromJS)([]));const r=[];return i()(n).call(n,(e=>{let t=e.get("errors");t&&t.count()&&i()(t).call(t,(e=>r.push(e)))})),r},Oe=(e,t)=>0===ke(e,t).length,je=(e,t)=>{var n;let r={requestBody:!1,requestContentType:{}},o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody"],(0,A.fromJS)([]));return o.size<1||(o.getIn(["required"])&&(r.requestBody=o.getIn(["required"])),i()(n=o.getIn(["content"]).entrySeq()).call(n,(e=>{const t=e[0];if(e[1].getIn(["schema","required"])){const n=e[1].getIn(["schema","required"]).toJS();r.requestContentType[t]=n}}))),r},Te=(e,t,n,r)=>{if((n||r)&&n===r)return!0;let o=e.getIn(["resolvedSubtrees","paths",...t,"requestBody","content"],(0,A.fromJS)([]));if(o.size<2||!n||!r)return!1;let a=o.getIn([n,"schema","properties"],(0,A.fromJS)([])),i=o.getIn([r,"schema","properties"],(0,A.fromJS)([]));return!!a.equals(i)};function Ie(e){return A.Map.isMap(e)?e:new A.Map}},77508:(e,t,n)=>{"use strict";n.r(t),n.d(t,{executeRequest:()=>p,updateJsonSpec:()=>c,updateSpec:()=>u,validateParams:()=>f});var r=n(28222),o=n.n(r),a=n(86),i=n.n(a),s=n(27361),l=n.n(s);const u=(e,t)=>{let{specActions:n}=t;return function(){e(...arguments),n.parseToJson(...arguments)}},c=(e,t)=>{let{specActions:n}=t;return function(){for(var t=arguments.length,r=new Array(t),a=0;a{l()(u,[e]).$ref&&n.requestResolvedSubtree(["paths",e])})),n.requestResolvedSubtree(["components","securitySchemes"])}},p=(e,t)=>{let{specActions:n}=t;return t=>(n.logRequest(t),e(t))},f=(e,t)=>{let{specSelectors:n}=t;return t=>e(t,n.isOAS3())}},34852:(e,t,n)=>{"use strict";n.r(t),n.d(t,{loaded:()=>r});const r=(e,t)=>function(){e(...arguments);const n=t.getConfigs().withCredentials;void 0!==n&&(t.fn.fetch.withCredentials="string"==typeof n?"true"===n:!!n)}},74370:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>rn});var r={};n.r(r),n.d(r,{JsonPatchError:()=>G,_areEquals:()=>ae,applyOperation:()=>ee,applyPatch:()=>te,applyReducer:()=>ne,deepClone:()=>Z,getValueByPointer:()=>X,validate:()=>oe,validator:()=>re});var o={};n.r(o),n.d(o,{compare:()=>he,generate:()=>pe,observe:()=>ce,unobserve:()=>ue});var a={};n.r(a),n.d(a,{cookie:()=>Ft,header:()=>Bt,path:()=>Mt,query:()=>Dt});var i=n(58826),s=n.n(i);const l="application/json, application/yaml";function u(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};const{requestInterceptor:n,responseInterceptor:r}=t,o=e.withCredentials?"include":"same-origin";return t=>e({url:t,loadSpec:!0,requestInterceptor:n,responseInterceptor:r,headers:{Accept:l},credentials:o}).then((e=>e.body))}n(31905);var c=n(80129),p=n.n(c),f=n(1272);const h="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window,{FormData:d,Blob:m,File:g}=h,y=e=>":/?#[]@!$&'()*+,;=".indexOf(e)>-1,v=e=>/^[a-z0-9\-._~]+$/i.test(e);function b(e){let{escape:t}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return"number"==typeof e&&(e=e.toString()),"string"==typeof e&&e.length&&t?n?JSON.parse(e):[...e].map((e=>{if(v(e))return e;if(y(e)&&"unsafe"===t)return e;const n=new TextEncoder;return Array.from(n.encode(e)).map((e=>`0${e.toString(16).toUpperCase()}`.slice(-2))).map((e=>`%${e}`)).join("")})).join(""):e}function w(e){const{value:t}=e;return Array.isArray(t)?function(e){let{key:t,value:n,style:r,explode:o,escape:a}=e;const i=e=>b(e,{escape:a});if("simple"===r)return n.map((e=>i(e))).join(",");if("label"===r)return`.${n.map((e=>i(e))).join(".")}`;if("matrix"===r)return n.map((e=>i(e))).reduce(((e,n)=>!e||o?`${e||""};${t}=${n}`:`${e},${n}`),"");if("form"===r){const e=o?`&${t}=`:",";return n.map((e=>i(e))).join(e)}if("spaceDelimited"===r){const e=o?`${t}=`:"";return n.map((e=>i(e))).join(` ${e}`)}if("pipeDelimited"===r){const e=o?`${t}=`:"";return n.map((e=>i(e))).join(`|${e}`)}return}(e):"object"==typeof t?function(e){let{key:t,value:n,style:r,explode:o,escape:a}=e;const i=e=>b(e,{escape:a}),s=Object.keys(n);if("simple"===r)return s.reduce(((e,t)=>{const r=i(n[t]);return`${e?`${e},`:""}${t}${o?"=":","}${r}`}),"");if("label"===r)return s.reduce(((e,t)=>{const r=i(n[t]);return`${e?`${e}.`:"."}${t}${o?"=":"."}${r}`}),"");if("matrix"===r&&o)return s.reduce(((e,t)=>`${e?`${e};`:";"}${t}=${i(n[t])}`),"");if("matrix"===r)return s.reduce(((e,r)=>{const o=i(n[r]);return`${e?`${e},`:`;${t}=`}${r},${o}`}),"");if("form"===r)return s.reduce(((e,t)=>{const r=i(n[t]);return`${e?`${e}${o?"&":","}`:""}${t}${o?"=":","}${r}`}),"");return}(e):function(e){let{key:t,value:n,style:r,escape:o}=e;const a=e=>b(e,{escape:o});if("simple"===r)return a(n);if("label"===r)return`.${a(n)}`;if("matrix"===r)return`;${t}=${a(n)}`;if("form"===r)return a(n);if("deepObject"===r)return a(n,{},!0);return}(e)}const E=(e,t)=>{t.body=e},x={serializeRes:A,mergeInQueryOrForm:R};async function _(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};"object"==typeof e&&(t=e,e=t.url),t.headers=t.headers||{},x.mergeInQueryOrForm(t),t.headers&&Object.keys(t.headers).forEach((e=>{const n=t.headers[e];"string"==typeof n&&(t.headers[e]=n.replace(/\n+/g," "))})),t.requestInterceptor&&(t=await t.requestInterceptor(t)||t);const n=t.headers["content-type"]||t.headers["Content-Type"];let r;/multipart\/form-data/i.test(n)&&t.body instanceof d&&(delete t.headers["content-type"],delete t.headers["Content-Type"]);try{r=await(t.userFetch||fetch)(t.url,t),r=await x.serializeRes(r,e,t),t.responseInterceptor&&(r=await t.responseInterceptor(r)||r)}catch(e){if(!r)throw e;const t=new Error(r.statusText||`response status is ${r.status}`);throw t.status=r.status,t.statusCode=r.status,t.responseError=e,t}if(!r.ok){const e=new Error(r.statusText||`response status is ${r.status}`);throw e.status=r.status,e.statusCode=r.status,e.response=r,e}return r}const S=function(){return/(json|xml|yaml|text)\b/.test(arguments.length>0&&void 0!==arguments[0]?arguments[0]:"")};function A(e,t){let{loadSpec:n=!1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const r={ok:e.ok,url:e.url||t,status:e.status,statusText:e.statusText,headers:C(e.headers)},o=r.headers["content-type"],a=n||S(o);return(a?e.text:e.blob||e.buffer).call(e).then((e=>{if(r.text=e,r.data=e,a)try{const t=function(e,t){return t&&(0===t.indexOf("application/json")||t.indexOf("+json")>0)?JSON.parse(e):f.ZP.load(e)}(e,o);r.body=t,r.obj=t}catch(e){r.parseError=e}return r}))}function C(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};return"function"!=typeof e.entries?{}:Array.from(e.entries()).reduce(((e,t)=>{let[n,r]=t;return e[n]=function(e){return e.includes(", ")?e.split(", "):e}(r),e}),{})}function k(e,t){return t||"undefined"==typeof navigator||(t=navigator),t&&"ReactNative"===t.product?!(!e||"object"!=typeof e||"string"!=typeof e.uri):void 0!==g&&e instanceof g||(void 0!==m&&e instanceof m||(!!ArrayBuffer.isView(e)||null!==e&&"object"==typeof e&&"function"==typeof e.pipe))}function O(e,t){return Array.isArray(e)&&e.some((e=>k(e,t)))}const j={form:",",spaceDelimited:"%20",pipeDelimited:"|"},T={csv:",",ssv:"%20",tsv:"%09",pipes:"|"};function I(e,t){let n=arguments.length>2&&void 0!==arguments[2]&&arguments[2];const{collectionFormat:r,allowEmptyValue:o,serializationOption:a,encoding:i}=t,s="object"!=typeof t||Array.isArray(t)?t:t.value,l=n?e=>e.toString():e=>encodeURIComponent(e),u=l(e);if(void 0===s&&o)return[[u,""]];if(k(s)||O(s))return[[u,s]];if(a)return N(e,s,n,a);if(i){if([typeof i.style,typeof i.explode,typeof i.allowReserved].some((e=>"undefined"!==e))){const{style:t,explode:r,allowReserved:o}=i;return N(e,s,n,{style:t,explode:r,allowReserved:o})}if(i.contentType){if("application/json"===i.contentType){return[[u,l("string"==typeof s?s:JSON.stringify(s))]]}return[[u,l(s.toString())]]}return"object"!=typeof s?[[u,l(s)]]:Array.isArray(s)&&s.every((e=>"object"!=typeof e))?[[u,s.map(l).join(",")]]:[[u,l(JSON.stringify(s))]]}return"object"!=typeof s?[[u,l(s)]]:Array.isArray(s)?"multi"===r?[[u,s.map(l)]]:[[u,s.map(l).join(T[r||"csv"])]]:[[u,""]]}function N(e,t,n,r){const o=r.style||"form",a=void 0===r.explode?"form"===o:r.explode,i=!n&&(r&&r.allowReserved?"unsafe":"reserved"),s=e=>b(e,{escape:i}),l=n?e=>e:e=>b(e,{escape:i});return"object"!=typeof t?[[l(e),s(t)]]:Array.isArray(t)?a?[[l(e),t.map(s)]]:[[l(e),t.map(s).join(j[o])]]:"deepObject"===o?Object.keys(t).map((n=>[l(`${e}[${n}]`),s(t[n])])):a?Object.keys(t).map((e=>[l(e),s(t[e])])):[[l(e),Object.keys(t).map((e=>[`${l(e)},${s(t[e])}`])).join(",")]]}function P(e){const t=Object.keys(e).reduce(((t,n)=>{for(const[r,o]of I(n,e[n]))t[r]=o;return t}),{});return p().stringify(t,{encode:!1,indices:!1})||""}function R(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};const{url:t="",query:n,form:r}=e;if(r){const t=Object.keys(r).some((e=>{const{value:t}=r[e];return k(t)||O(t)})),n=e.headers["content-type"]||e.headers["Content-Type"];if(t||/multipart\/form-data/i.test(n)){const t=(o=e.form,Object.entries(o).reduce(((e,t)=>{let[n,r]=t;for(const[t,o]of I(n,r,!0))if(Array.isArray(o))for(const n of o)if(ArrayBuffer.isView(n)){const r=new m([n]);e.append(t,r)}else e.append(t,n);else if(ArrayBuffer.isView(o)){const n=new m([o]);e.append(t,n)}else e.append(t,o);return e}),new d));E(t,e)}else e.body=P(r);delete e.form}var o;if(n){const[r,o]=t.split("?");let a="";if(o){const e=p().parse(o);Object.keys(n).forEach((t=>delete e[t])),a=p().stringify(e,{encode:!0})}const i=function(){for(var e=arguments.length,t=new Array(e),n=0;ne)).join("&");return r?`?${r}`:""}(a,P(n));e.url=r+i,delete e.query}return e}const M=e=>{const{baseDoc:t,url:n}=e;return t||n||""},D=e=>{const{fetch:t,http:n}=e;return t||n||_};var L,B=(L=function(e,t){return L=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])},L(e,t)},function(e,t){function n(){this.constructor=e}L(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}),F=Object.prototype.hasOwnProperty;function z(e,t){return F.call(e,t)}function U(e){if(Array.isArray(e)){for(var t=new Array(e.length),n=0;n=48&&t<=57))return!1;n++}return!0}function V(e){return-1===e.indexOf("/")&&-1===e.indexOf("~")?e:e.replace(/~/g,"~0").replace(/\//g,"~1")}function W(e){return e.replace(/~1/g,"/").replace(/~0/g,"~")}function H(e){if(void 0===e)return!0;if(e)if(Array.isArray(e)){for(var t=0,n=e.length;t0&&"constructor"==s[u-1]))throw new TypeError("JSON-Patch: modifying `__proto__` or `constructor/prototype` prop is banned for security reasons, if this was on purpose, please set `banPrototypeModifications` flag false and pass it to this function. More info in fast-json-patch README");if(n&&void 0===p&&(void 0===l[f]?p=s.slice(0,u).join("/"):u==c-1&&(p=t.path),void 0!==p&&h(t,0,e,p)),u++,Array.isArray(l)){if("-"===f)f=l.length;else{if(n&&!$(f))throw new G("Expected an unsigned base-10 integer value, making the new referenced value the array element with the zero-based index","OPERATION_PATH_ILLEGAL_ARRAY_INDEX",a,t,e);$(f)&&(f=~~f)}if(u>=c){if(n&&"add"===t.op&&f>l.length)throw new G("The specified index MUST NOT be greater than the number of elements in the array","OPERATION_VALUE_OUT_OF_BOUNDS",a,t,e);if(!1===(i=Q[t.op].call(t,l,f,e)).test)throw new G("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}}else if(u>=c){if(!1===(i=Y[t.op].call(t,l,f,e)).test)throw new G("Test operation failed","TEST_OPERATION_FAILED",a,t,e);return i}if(l=l[f],n&&u0)throw new G('Operation `path` property must start with "/"',"OPERATION_PATH_INVALID",t,e,n);if(("move"===e.op||"copy"===e.op)&&"string"!=typeof e.from)throw new G("Operation `from` property is not present (applicable in `move` and `copy` operations)","OPERATION_FROM_REQUIRED",t,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&void 0===e.value)throw new G("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_REQUIRED",t,e,n);if(("add"===e.op||"replace"===e.op||"test"===e.op)&&H(e.value))throw new G("Operation `value` property is not present (applicable in `add`, `replace` and `test` operations)","OPERATION_VALUE_CANNOT_CONTAIN_UNDEFINED",t,e,n);if(n)if("add"==e.op){var o=e.path.split("/").length,a=r.split("/").length;if(o!==a+1&&o!==a)throw new G("Cannot perform an `add` operation at the desired path","OPERATION_PATH_CANNOT_ADD",t,e,n)}else if("replace"===e.op||"remove"===e.op||"_get"===e.op){if(e.path!==r)throw new G("Cannot perform the operation at a path that does not exist","OPERATION_PATH_UNRESOLVABLE",t,e,n)}else if("move"===e.op||"copy"===e.op){var i=oe([{op:"_get",path:e.from,value:void 0}],n);if(i&&"OPERATION_PATH_UNRESOLVABLE"===i.name)throw new G("Cannot perform the operation from a path that does not exist","OPERATION_FROM_UNRESOLVABLE",t,e,n)}}function oe(e,t,n){try{if(!Array.isArray(e))throw new G("Patch sequence must be an array","SEQUENCE_NOT_AN_ARRAY");if(t)te(q(t),q(e),n||!0);else{n=n||re;for(var r=0;r0&&(e.patches=[],e.callback&&e.callback(r)),r}function fe(e,t,n,r,o){if(t!==e){"function"==typeof t.toJSON&&(t=t.toJSON());for(var a=U(t),i=U(e),s=!1,l=i.length-1;l>=0;l--){var u=e[p=i[l]];if(!z(t,p)||void 0===t[p]&&void 0!==u&&!1===Array.isArray(t))Array.isArray(e)===Array.isArray(t)?(o&&n.push({op:"test",path:r+"/"+V(p),value:q(u)}),n.push({op:"remove",path:r+"/"+V(p)}),s=!0):(o&&n.push({op:"test",path:r,value:e}),n.push({op:"replace",path:r,value:t}),!0);else{var c=t[p];"object"==typeof u&&null!=u&&"object"==typeof c&&null!=c&&Array.isArray(u)===Array.isArray(c)?fe(u,c,n,r+"/"+V(p),o):u!==c&&(!0,o&&n.push({op:"test",path:r+"/"+V(p),value:q(u)}),n.push({op:"replace",path:r+"/"+V(p),value:q(c)}))}}if(s||a.length!=i.length)for(l=0;lvoid 0!==t&&e?e[t]:e),e)},applyPatch:function(e,t,n){if(n=n||{},"merge"===(t=s()(s()({},t),{},{path:t.path&&ye(t.path)})).op){const n=Ie(e,t.path);Object.assign(n,t.value),te(e,[ve(t.path,n)])}else if("mergeDeep"===t.op){const n=Ie(e,t.path),r=me()(n,t.value);e=te(e,[ve(t.path,r)]).newDocument}else if("add"===t.op&&""===t.path&&Ae(t.value)){te(e,Object.keys(t.value).reduce(((e,n)=>(e.push({op:"add",path:`/${ye(n)}`,value:t.value[n]}),e)),[]))}else if("replace"===t.op&&""===t.path){let{value:r}=t;n.allowMetaPatches&&t.meta&&je(t)&&(Array.isArray(t.value)||Ae(t.value))&&(r=s()(s()({},r),t.meta)),e=r}else if(te(e,[t]),n.allowMetaPatches&&t.meta&&je(t)&&(Array.isArray(t.value)||Ae(t.value))){const n=Ie(e,t.path),r=s()(s()({},n),t.meta);te(e,[ve(t.path,r)])}return e},parentPathMatch:function(e,t){if(!Array.isArray(t))return!1;for(let n=0,r=t.length;n(e+"").replace(/~/g,"~0").replace(/\//g,"~1"))).join("/")}`:e}function ve(e,t,n){return{op:"replace",path:e,value:t,meta:n}}function be(e,t,n){return Se(_e(e.filter(je).map((e=>t(e.value,n,e.path)))||[]))}function we(e,t,n){return n=n||[],Array.isArray(e)?e.map(((e,r)=>we(e,t,n.concat(r)))):Ae(e)?Object.keys(e).map((r=>we(e[r],t,n.concat(r)))):t(e,n[n.length-1],n)}function Ee(e,t,n){let r=[];if((n=n||[]).length>0){const o=t(e,n[n.length-1],n);o&&(r=r.concat(o))}if(Array.isArray(e)){const o=e.map(((e,r)=>Ee(e,t,n.concat(r))));o&&(r=r.concat(o))}else if(Ae(e)){const o=Object.keys(e).map((r=>Ee(e[r],t,n.concat(r))));o&&(r=r.concat(o))}return r=_e(r),r}function xe(e){return Array.isArray(e)?e:[e]}function _e(e){return[].concat(...e.map((e=>Array.isArray(e)?_e(e):e)))}function Se(e){return e.filter((e=>void 0!==e))}function Ae(e){return e&&"object"==typeof e}function Ce(e){return e&&"function"==typeof e}function ke(e){if(Te(e)){const{op:t}=e;return"add"===t||"remove"===t||"replace"===t}return!1}function Oe(e){return ke(e)||Te(e)&&"mutation"===e.type}function je(e){return Oe(e)&&("add"===e.op||"replace"===e.op||"merge"===e.op||"mergeDeep"===e.op)}function Te(e){return e&&"object"==typeof e}function Ie(e,t){try{return X(e,t)}catch(e){return console.error(e),{}}}var Ne=n(8575);function Pe(e,t){function n(){Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack;for(var e=arguments.length,n=new Array(e),r=0;r-1&&-1===Le.indexOf(n)||Be.indexOf(r)>-1||Fe.some((e=>r.indexOf(e)>-1))}function Ue(e,t){const[n,r]=e.split("#"),o=Ne.resolve(n||"",t||"");return r?`${o}#${r}`:o}const qe=/^([a-z]+:\/\/|\/\/)/i,$e=Pe("JSONRefError",(function(e,t,n){this.originalError=n,Object.assign(this,t||{})})),Ve={},We=new WeakMap,He=[e=>"paths"===e[0]&&"responses"===e[3]&&"examples"===e[5],e=>"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"example"===e[7],e=>"paths"===e[0]&&"responses"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9],e=>"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"example"===e[6],e=>"paths"===e[0]&&"requestBody"===e[3]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8],e=>"paths"===e[0]&&"parameters"===e[2]&&"example"===e[4],e=>"paths"===e[0]&&"parameters"===e[3]&&"example"===e[5],e=>"paths"===e[0]&&"parameters"===e[2]&&"examples"===e[4]&&"value"===e[6],e=>"paths"===e[0]&&"parameters"===e[3]&&"examples"===e[5]&&"value"===e[7],e=>"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"example"===e[6],e=>"paths"===e[0]&&"parameters"===e[2]&&"content"===e[4]&&"examples"===e[6]&&"value"===e[8],e=>"paths"===e[0]&&"parameters"===e[3]&&"content"===e[4]&&"example"===e[7],e=>"paths"===e[0]&&"parameters"===e[3]&&"content"===e[5]&&"examples"===e[7]&&"value"===e[9]],Je={key:"$ref",plugin:(e,t,n,r)=>{const o=r.getInstance(),a=n.slice(0,-1);if(ze(a)||(e=>He.some((t=>t(e))))(a))return;const{baseDoc:i}=r.getContext(n);if("string"!=typeof e)return new $e("$ref: must be a string (JSON-Ref)",{$ref:e,baseDoc:i,fullPath:n});const s=Qe(e),l=s[0],u=s[1]||"";let c,p,f;try{c=i||l?Ze(l,i):null}catch(t){return Ye(t,{pointer:u,$ref:e,basePath:c,fullPath:n})}if(function(e,t,n,r){let o=We.get(r);o||(o={},We.set(r,o));const a=function(e){if(0===e.length)return"";return`/${e.map(ot).join("/")}`}(n),i=`${t||""}#${e}`,s=a.replace(/allOf\/\d+\/?/g,""),l=r.contextTree.get([]).baseDoc;if(t===l&&it(s,e))return!0;let u="";const c=n.some((e=>(u=`${u}/${ot(e)}`,o[u]&&o[u].some((e=>it(e,i)||it(i,e))))));if(c)return!0;return void(o[s]=(o[s]||[]).concat(i))}(u,c,a,r)&&!o.useCircularStructures){const t=Ue(e,c);return e===t?null:ge.replace(n,t)}if(null==c?(f=nt(u),p=r.get(f),void 0===p&&(p=new $e(`Could not resolve reference: ${e}`,{pointer:u,$ref:e,baseDoc:i,fullPath:n}))):(p=Xe(c,u),p=null!=p.__value?p.__value:p.catch((t=>{throw Ye(t,{pointer:u,$ref:e,baseDoc:i,fullPath:n})}))),p instanceof Error)return[ge.remove(n),p];const h=Ue(e,c),d=ge.replace(a,p,{$$ref:h});if(c&&c!==i)return[d,ge.context(a,{baseDoc:c})];try{if(!function(e,t){const n=[e];return t.path.reduce(((e,t)=>(n.push(e[t]),e[t])),e),r(t.value);function r(e){return ge.isObject(e)&&(n.indexOf(e)>=0||Object.keys(e).some((t=>r(e[t]))))}}(r.state,d)||o.useCircularStructures)return d}catch(e){return null}}},Ke=Object.assign(Je,{docCache:Ve,absoluteify:Ze,clearCache:function(e){void 0!==e?delete Ve[e]:Object.keys(Ve).forEach((e=>{delete Ve[e]}))},JSONRefError:$e,wrapError:Ye,getDoc:et,split:Qe,extractFromDoc:Xe,fetchJSON:function(e){return fetch(e,{headers:{Accept:l},loadSpec:!0}).then((e=>e.text())).then((e=>f.ZP.load(e)))},extract:tt,jsonPointerToArray:nt,unescapeJsonPointerToken:rt}),Ge=Ke;function Ze(e,t){if(!qe.test(e)){if(!t)throw new $e(`Tried to resolve a relative URL, without having a basePath. path: '${e}' basePath: '${t}'`);return Ne.resolve(t,e)}return e}function Ye(e,t){let n;return n=e&&e.response&&e.response.body?`${e.response.body.code} ${e.response.body.message}`:e.message,new $e(`Could not resolve reference: ${n}`,t,e)}function Qe(e){return(e+"").split("#")}function Xe(e,t){const n=Ve[e];if(n&&!ge.isPromise(n))try{const e=tt(t,n);return Object.assign(Promise.resolve(e),{__value:e})}catch(e){return Promise.reject(e)}return et(e).then((e=>tt(t,e)))}function et(e){const t=Ve[e];return t?ge.isPromise(t)?t:Promise.resolve(t):(Ve[e]=Ke.fetchJSON(e).then((t=>(Ve[e]=t,t))),Ve[e])}function tt(e,t){const n=nt(e);if(n.length<1)return t;const r=ge.getIn(t,n);if(void 0===r)throw new $e(`Could not resolve pointer: ${e} does not exist in document`,{pointer:e});return r}function nt(e){if("string"!=typeof e)throw new TypeError("Expected a string, got a "+typeof e);return"/"===e[0]&&(e=e.substr(1)),""===e?[]:e.split("/").map(rt)}function rt(e){if("string"!=typeof e)return e;return new URLSearchParams(`=${e.replace(/~1/g,"/").replace(/~0/g,"~")}`).get("")}function ot(e){return new URLSearchParams([["",e.replace(/~/g,"~0").replace(/\//g,"~1")]]).toString().slice(1)}const at=e=>!e||"/"===e||"#"===e;function it(e,t){if(at(t))return!0;const n=e.charAt(t.length),r=t.slice(-1);return 0===e.indexOf(t)&&(!n||"/"===n||"#"===n)&&"#"!==r}const st={key:"allOf",plugin:(e,t,n,r,o)=>{if(o.meta&&o.meta.$$ref)return;const a=n.slice(0,-1);if(ze(a))return;if(!Array.isArray(e)){const e=new TypeError("allOf must be an array");return e.fullPath=n,e}let i=!1,l=o.value;if(a.forEach((e=>{l&&(l=l[e])})),l=s()({},l),0===Object.keys(l).length)return;delete l.allOf;const u=[];return u.push(r.replace(a,{})),e.forEach(((e,t)=>{if(!r.isObject(e)){if(i)return null;i=!0;const e=new TypeError("Elements in allOf must be objects");return e.fullPath=n,u.push(e)}u.push(r.mergeDeep(a,e));const o=function(e,t){let{specmap:n,getBaseUrlForNodePath:r=(e=>n.getContext([...t,...e]).baseDoc),targetKeys:o=["$ref","$$ref"]}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const a=[];return Me()(e).forEach((function(){if(o.includes(this.key)&&"string"==typeof this.node){const e=this.path,o=t.concat(this.path),i=Ue(this.node,r(e));a.push(n.replace(o,i))}})),a}(e,n.slice(0,-1),{getBaseUrlForNodePath:e=>r.getContext([...n,t,...e]).baseDoc,specmap:r});u.push(...o)})),l.example&&u.push(r.remove([].concat(a,"example"))),u.push(r.mergeDeep(a,l)),l.$$ref||u.push(r.remove([].concat(a,"$$ref"))),u}},lt={key:"parameters",plugin:(e,t,n,r)=>{if(Array.isArray(e)&&e.length){const t=Object.assign([],e),o=n.slice(0,-1),a=s()({},ge.getIn(r.spec,o));for(let o=0;o{const o=s()({},e);for(const t in e)try{o[t].default=r.modelPropertyMacro(o[t])}catch(e){const t=new Error(e);return t.fullPath=n,t}return ge.replace(n,o)}};class ct{constructor(e){this.root=pt(e||{})}set(e,t){const n=this.getParent(e,!0);if(!n)return void ft(this.root,t,null);const r=e[e.length-1],{children:o}=n;o[r]?ft(o[r],t,n):o[r]=pt(t,n)}get(e){if((e=e||[]).length<1)return this.root.value;let t,n,r=this.root;for(let o=0;o{if(!e)return e;const{children:r}=e;return!r[n]&&t&&(r[n]=pt(null,e)),r[n]}),this.root)}}function pt(e,t){return ft({children:{}},e,t)}function ft(e,t,n){return e.value=t||{},e.protoValue=n?s()(s()({},n.protoValue),e.value):e.value,Object.keys(e.children).forEach((t=>{const n=e.children[t];e.children[t]=ft(n,n.value,e)})),e}const ht=()=>{};class dt{static getPluginName(e){return e.pluginName}static getPatchesOfType(e,t){return e.filter(t)}constructor(e){Object.assign(this,{spec:"",debugLevel:"info",plugins:[],pluginHistory:{},errors:[],mutations:[],promisedPatches:[],state:{},patches:[],context:{},contextTree:new ct,showDebug:!1,allPatches:[],pluginProp:"specMap",libMethods:Object.assign(Object.create(this),ge,{getInstance:()=>this}),allowMetaPatches:!1},e),this.get=this._get.bind(this),this.getContext=this._getContext.bind(this),this.hasRun=this._hasRun.bind(this),this.wrappedPlugins=this.plugins.map(this.wrapPlugin.bind(this)).filter(ge.isFunction),this.patches.push(ge.add([],this.spec)),this.patches.push(ge.context([],this.context)),this.updatePatches(this.patches)}debug(e){if(this.debugLevel===e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r1?t-1:0),r=1;r!Array.isArray(e)||e.every(((e,n)=>e===t[n]));return function*(r,o){const a={};for(const e of r.filter(ge.isAdditiveMutation))yield*i(e.value,e.path,e);function*i(r,s,l){if(ge.isObject(r)){const u=s.length-1,c=s[u],p=s.indexOf("properties"),f="properties"===c&&u===p,h=o.allowMetaPatches&&a[r.$$ref];for(const u of Object.keys(r)){const c=r[u],p=s.concat(u),d=ge.isObject(c),m=r.$$ref;if(h||d&&(o.allowMetaPatches&&m&&(a[m]=!0),yield*i(c,p,l)),!f&&u===e.key){const r=t(n,s);n&&!r||(yield e.plugin(c,u,p,o,l))}}}else e.key===s[s.length-1]&&(yield e.plugin(r,e.key,s,o))}}}(e)),Object.assign(r.bind(o),{pluginName:e.name||t,isGenerator:ge.isGenerator(r)})}nextPlugin(){return this.wrappedPlugins.find((e=>this.getMutationsForPlugin(e).length>0))}nextPromisedPatch(){if(this.promisedPatches.length>0)return Promise.race(this.promisedPatches.map((e=>e.value)))}getPluginHistory(e){const t=this.constructor.getPluginName(e);return this.pluginHistory[t]||[]}getPluginRunCount(e){return this.getPluginHistory(e).length}getPluginHistoryTip(e){const t=this.getPluginHistory(e);return t&&t[t.length-1]||{}}getPluginMutationIndex(e){const t=this.getPluginHistoryTip(e).mutationIndex;return"number"!=typeof t?-1:t}updatePluginHistory(e,t){const n=this.constructor.getPluginName(e);this.pluginHistory[n]=this.pluginHistory[n]||[],this.pluginHistory[n].push(t)}updatePatches(e){ge.normalizeArray(e).forEach((e=>{if(e instanceof Error)this.errors.push(e);else try{if(!ge.isObject(e))return void this.debug("updatePatches","Got a non-object patch",e);if(this.showDebug&&this.allPatches.push(e),ge.isPromise(e.value))return this.promisedPatches.push(e),void this.promisedPatchThen(e);if(ge.isContextPatch(e))return void this.setContext(e.path,e.value);if(ge.isMutation(e))return void this.updateMutations(e)}catch(e){console.error(e),this.errors.push(e)}}))}updateMutations(e){"object"==typeof e.value&&!Array.isArray(e.value)&&this.allowMetaPatches&&(e.value=s()({},e.value));const t=ge.applyPatch(this.state,e,{allowMetaPatches:this.allowMetaPatches});t&&(this.mutations.push(e),this.state=t)}removePromisedPatch(e){const t=this.promisedPatches.indexOf(e);t<0?this.debug("Tried to remove a promisedPatch that isn't there!"):this.promisedPatches.splice(t,1)}promisedPatchThen(e){return e.value=e.value.then((t=>{const n=s()(s()({},e),{},{value:t});this.removePromisedPatch(e),this.updatePatches(n)})).catch((t=>{this.removePromisedPatch(e),this.updatePatches(t)})),e.value}getMutations(e,t){return e=e||0,"number"!=typeof t&&(t=this.mutations.length),this.mutations.slice(e,t)}getCurrentMutations(){return this.getMutationsForPlugin(this.getCurrentPlugin())}getMutationsForPlugin(e){const t=this.getPluginMutationIndex(e);return this.getMutations(t+1)}getCurrentPlugin(){return this.currentPlugin}getLib(){return this.libMethods}_get(e){return ge.getIn(this.state,e)}_getContext(e){return this.contextTree.get(e)}setContext(e,t){return this.contextTree.set(e,t)}_hasRun(e){return this.getPluginRunCount(this.getCurrentPlugin())>(e||0)}dispatch(){const e=this,t=this.nextPlugin();if(!t){const e=this.nextPromisedPatch();if(e)return e.then((()=>this.dispatch())).catch((()=>this.dispatch()));const t={spec:this.state,errors:this.errors};return this.showDebug&&(t.patches=this.allPatches),Promise.resolve(t)}if(e.pluginCount=e.pluginCount||{},e.pluginCount[t]=(e.pluginCount[t]||0)+1,e.pluginCount[t]>100)return Promise.resolve({spec:e.state,errors:e.errors.concat(new Error("We've reached a hard limit of 100 plugin runs"))});if(t!==this.currentPlugin&&this.promisedPatches.length){const e=this.promisedPatches.map((e=>e.value));return Promise.all(e.map((e=>e.then(ht,ht)))).then((()=>this.dispatch()))}return function(){e.currentPlugin=t;const r=e.getCurrentMutations(),o=e.mutations.length-1;try{if(t.isGenerator)for(const o of t(r,e.getLib()))n(o);else{n(t(r,e.getLib()))}}catch(e){console.error(e),n([Object.assign(Object.create(e),{plugin:t})])}finally{e.updatePluginHistory(t,{mutationIndex:o})}return e.dispatch()}();function n(n){n&&(n=ge.fullyNormalizeArray(n),e.updatePatches(n,t))}}}const mt={refs:Ge,allOf:st,parameters:lt,properties:ut};var gt=n(32454);function yt(e){const{spec:t}=e,{paths:n}=t,r={};if(!n||t.$$normalized)return e;for(const e in n){const o=n[e];if(null==o||!["object","function"].includes(typeof o))continue;const a=o.parameters;for(const n in o){const i=o[n];if(null==i||!["object","function"].includes(typeof i))continue;const s=(0,gt.Z)(i,e,n);if(s){r[s]?r[s].push(i):r[s]=[i];const e=r[s];if(e.length>1)e.forEach(((e,t)=>{e.__originalOperationId=e.__originalOperationId||e.operationId,e.operationId=`${s}${t+1}`}));else if(void 0!==i.operationId){const t=e[0];t.__originalOperationId=t.__originalOperationId||i.operationId,t.operationId=s}}if("parameters"!==n){const e=[],n={};for(const r in t)"produces"!==r&&"consumes"!==r&&"security"!==r||(n[r]=t[r],e.push(n));if(a&&(n.parameters=a,e.push(n)),e.length)for(const t of e)for(const e in t)if(i[e]){if("parameters"===e)for(const n of t[e]){i[e].some((e=>e.name&&e.name===n.name||e.$ref&&e.$ref===n.$ref||e.$$ref&&e.$$ref===n.$$ref||e===n))||i[e].push(n)}}else i[e]=t[e]}}}return t.$$normalized=!0,e}async function vt(e){const{spec:t,mode:n,allowMetaPatches:r=!0,pathDiscriminator:o,modelPropertyMacro:a,parameterMacro:i,requestInterceptor:s,responseInterceptor:l,skipNormalization:c,useCircularStructures:p}=e,f=M(e),h=D(e);return function(e){f&&(mt.refs.docCache[f]=e);mt.refs.fetchJSON=u(h,{requestInterceptor:s,responseInterceptor:l});const t=[mt.refs];"function"==typeof i&&t.push(mt.parameters);"function"==typeof a&&t.push(mt.properties);"strict"!==n&&t.push(mt.allOf);return(d={spec:e,context:{baseDoc:f},plugins:t,allowMetaPatches:r,pathDiscriminator:o,parameterMacro:i,modelPropertyMacro:a,useCircularStructures:p},new dt(d).dispatch()).then(c?async e=>e:yt);var d}(t)}const bt={name:"generic",match:()=>!0,normalize(e){let{spec:t}=e;const{spec:n}=yt({spec:t});return n},resolve:async e=>vt(e)};const wt=e=>{try{const{openapi:t}=e;return"string"==typeof t&&/^3\.0\.([0123])(?:-rc[012])?$/.test(t)}catch{return!1}},Et=e=>wt(e)||(e=>{try{const{openapi:t}=e;return"string"==typeof t&&/^3\.1\.(?:[1-9]\d*|0)$/.test(t)}catch{return!1}})(e),xt={name:"openapi-2",match(e){let{spec:t}=e;return(e=>{try{const{swagger:t}=e;return"2.0"===t}catch{return!1}})(t)},normalize(e){let{spec:t}=e;const{spec:n}=yt({spec:t});return n},resolve:async e=>async function(e){return vt(e)}(e)};const _t={name:"openapi-3-0",match(e){let{spec:t}=e;return wt(t)},normalize(e){let{spec:t}=e;const{spec:n}=yt({spec:t});return n},resolve:async e=>async function(e){return vt(e)}(e)},St=(At={strategies:[_t,xt,bt]},async e=>(async e=>{const{spec:t,requestInterceptor:n,responseInterceptor:r}=e,o=M(e),a=D(e),i=t||await u(a,{requestInterceptor:n,responseInterceptor:r})(o),l=s()(s()({},e),{},{spec:i});return e.strategies.find((e=>e.match(l))).resolve(l)})(s()(s()({},At),e)));var At,Ct=n(88436),kt=n.n(Ct),Ot=n(27361),jt=n.n(Ot),Tt=n(76489);function It(e){return"[object Object]"===Object.prototype.toString.call(e)}function Nt(e){var t,n;return!1!==It(e)&&(void 0===(t=e.constructor)||!1!==It(n=t.prototype)&&!1!==n.hasOwnProperty("isPrototypeOf"))}const Pt={body:function(e){let{req:t,value:n}=e;t.body=n},header:function(e){let{req:t,parameter:n,value:r}=e;t.headers=t.headers||{},void 0!==r&&(t.headers[n.name]=r)},query:function(e){let{req:t,value:n,parameter:r}=e;t.query=t.query||{},!1===n&&"boolean"===r.type&&(n="false");0===n&&["number","integer"].indexOf(r.type)>-1&&(n="0");if(n)t.query[r.name]={collectionFormat:r.collectionFormat,value:n};else if(r.allowEmptyValue&&void 0!==n){const e=r.name;t.query[e]=t.query[e]||{},t.query[e].allowEmptyValue=!0}},path:function(e){let{req:t,value:n,parameter:r}=e;t.url=t.url.split(`{${r.name}}`).join(encodeURIComponent(n))},formData:function(e){let{req:t,value:n,parameter:r}=e;(n||r.allowEmptyValue)&&(t.form=t.form||{},t.form[r.name]={value:n,allowEmptyValue:r.allowEmptyValue,collectionFormat:r.collectionFormat})}};function Rt(e,t){return t.includes("application/json")?"string"==typeof e?e:JSON.stringify(e):e.toString()}function Mt(e){let{req:t,value:n,parameter:r}=e;const{name:o,style:a,explode:i,content:s}=r;if(s){const e=Object.keys(s)[0];return void(t.url=t.url.split(`{${o}}`).join(b(Rt(n,e),{escape:!0})))}const l=w({key:r.name,value:n,style:a||"simple",explode:i||!1,escape:!0});t.url=t.url.split(`{${o}}`).join(l)}function Dt(e){let{req:t,value:n,parameter:r}=e;if(t.query=t.query||{},r.content){const e=Rt(n,Object.keys(r.content)[0]);if(e)t.query[r.name]=e;else if(r.allowEmptyValue&&void 0!==n){const e=r.name;t.query[e]=t.query[e]||{},t.query[e].allowEmptyValue=!0}}else if(!1===n&&(n="false"),0===n&&(n="0"),n){const{style:e,explode:o,allowReserved:a}=r;t.query[r.name]={value:n,serializationOption:{style:e,explode:o,allowReserved:a}}}else if(r.allowEmptyValue&&void 0!==n){const e=r.name;t.query[e]=t.query[e]||{},t.query[e].allowEmptyValue=!0}}const Lt=["accept","authorization","content-type"];function Bt(e){let{req:t,parameter:n,value:r}=e;if(t.headers=t.headers||{},!(Lt.indexOf(n.name.toLowerCase())>-1))if(n.content){const e=Object.keys(n.content)[0];t.headers[n.name]=Rt(r,e)}else void 0!==r&&(t.headers[n.name]=w({key:n.name,value:r,style:n.style||"simple",explode:void 0!==n.explode&&n.explode,escape:!1}))}function Ft(e){let{req:t,parameter:n,value:r}=e;t.headers=t.headers||{};const o=typeof r;if(n.content){const e=Object.keys(n.content)[0];t.headers.Cookie=`${n.name}=${Rt(r,e)}`}else if("undefined"!==o){const e="object"===o&&!Array.isArray(r)&&n.explode?"":`${n.name}=`;t.headers.Cookie=e+w({key:n.name,value:r,escape:!1,style:n.style||"form",explode:void 0!==n.explode&&n.explode})}}const zt="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:window,{btoa:Ut}=zt,qt=Ut;function $t(e,t){const{operation:n,requestBody:r,securities:o,spec:a,attachContentTypeForEmptyPayload:i}=e;let{requestContentType:l}=e;t=function(e){let{request:t,securities:n={},operation:r={},spec:o}=e;const a=s()({},t),{authorized:i={}}=n,l=r.security||o.security||[],u=i&&!!Object.keys(i).length,c=jt()(o,["components","securitySchemes"])||{};if(a.headers=a.headers||{},a.query=a.query||{},!Object.keys(n).length||!u||!l||Array.isArray(r.security)&&!r.security.length)return t;return l.forEach((e=>{Object.keys(e).forEach((e=>{const t=i[e],n=c[e];if(!t)return;const r=t.value||t,{type:o}=n;if(t)if("apiKey"===o)"query"===n.in&&(a.query[n.name]=r),"header"===n.in&&(a.headers[n.name]=r),"cookie"===n.in&&(a.cookies[n.name]=r);else if("http"===o){if(/^basic$/i.test(n.scheme)){const e=r.username||"",t=r.password||"",n=qt(`${e}:${t}`);a.headers.Authorization=`Basic ${n}`}/^bearer$/i.test(n.scheme)&&(a.headers.Authorization=`Bearer ${r}`)}else if("oauth2"===o||"openIdConnect"===o){const e=t.token||{},r=e[n["x-tokenName"]||"access_token"];let o=e.token_type;o&&"bearer"!==o.toLowerCase()||(o="Bearer"),a.headers.Authorization=`${o} ${r}`}}))})),a}({request:t,securities:o,operation:n,spec:a});const u=n.requestBody||{},c=Object.keys(u.content||{}),p=l&&c.indexOf(l)>-1;if(r||i){if(l&&p)t.headers["Content-Type"]=l;else if(!l){const e=c[0];e&&(t.headers["Content-Type"]=e,l=e)}}else l&&p&&(t.headers["Content-Type"]=l);if(!e.responseContentType&&n.responses){const e=Object.entries(n.responses).filter((e=>{let[t,n]=e;const r=parseInt(t,10);return r>=200&&r<300&&Nt(n.content)})).reduce(((e,t)=>{let[,n]=t;return e.concat(Object.keys(n.content))}),[]);e.length>0&&(t.headers.accept=e.join(", "))}if(r)if(l){if(c.indexOf(l)>-1)if("application/x-www-form-urlencoded"===l||"multipart/form-data"===l)if("object"==typeof r){const e=(u.content[l]||{}).encoding||{};t.form={},Object.keys(r).forEach((n=>{t.form[n]={value:r[n],encoding:e[n]||{}}}))}else t.form=r;else t.body=r}else t.body=r;return t}function Vt(e,t){const{spec:n,operation:r,securities:o,requestContentType:a,responseContentType:i,attachContentTypeForEmptyPayload:l}=e;if(t=function(e){let{request:t,securities:n={},operation:r={},spec:o}=e;const a=s()({},t),{authorized:i={},specSecurity:l=[]}=n,u=r.security||l,c=i&&!!Object.keys(i).length,p=o.securityDefinitions;if(a.headers=a.headers||{},a.query=a.query||{},!Object.keys(n).length||!c||!u||Array.isArray(r.security)&&!r.security.length)return t;return u.forEach((e=>{Object.keys(e).forEach((e=>{const t=i[e];if(!t)return;const{token:n}=t,r=t.value||t,o=p[e],{type:s}=o,l=o["x-tokenName"]||"access_token",u=n&&n[l];let c=n&&n.token_type;if(t)if("apiKey"===s){const e="query"===o.in?"query":"headers";a[e]=a[e]||{},a[e][o.name]=r}else if("basic"===s)if(r.header)a.headers.authorization=r.header;else{const e=r.username||"",t=r.password||"";r.base64=qt(`${e}:${t}`),a.headers.authorization=`Basic ${r.base64}`}else"oauth2"===s&&u&&(c=c&&"bearer"!==c.toLowerCase()?c:"Bearer",a.headers.authorization=`${c} ${u}`)}))})),a}({request:t,securities:o,operation:r,spec:n}),t.body||t.form||l)a?t.headers["Content-Type"]=a:Array.isArray(r.consumes)?[t.headers["Content-Type"]]=r.consumes:Array.isArray(n.consumes)?[t.headers["Content-Type"]]=n.consumes:r.parameters&&r.parameters.filter((e=>"file"===e.type)).length?t.headers["Content-Type"]="multipart/form-data":r.parameters&&r.parameters.filter((e=>"formData"===e.in)).length&&(t.headers["Content-Type"]="application/x-www-form-urlencoded");else if(a){const e=r.parameters&&r.parameters.filter((e=>"body"===e.in)).length>0,n=r.parameters&&r.parameters.filter((e=>"formData"===e.in)).length>0;(e||n)&&(t.headers["Content-Type"]=a)}return!i&&Array.isArray(r.produces)&&r.produces.length>0&&(t.headers.accept=r.produces.join(", ")),t}function Wt(e,t){return`${t.toLowerCase()}-${e}`}const Ht=["http","fetch","spec","operationId","pathName","method","parameters","securities"],Jt=e=>Array.isArray(e)?e:[],Kt=Pe("OperationNotFoundError",(function(e,t,n){this.originalError=n,Object.assign(this,t||{})})),Gt=(e,t)=>t.filter((t=>t.name===e)),Zt=e=>{const t={};e.forEach((e=>{t[e.in]||(t[e.in]={}),t[e.in][e.name]=e}));const n=[];return Object.keys(t).forEach((e=>{Object.keys(t[e]).forEach((r=>{n.push(t[e][r])}))})),n},Yt={buildRequest:Xt};function Qt(e){let{http:t,fetch:n,spec:r,operationId:o,pathName:a,method:i,parameters:l,securities:u}=e,c=kt()(e,Ht);const p=t||n||_;a&&i&&!o&&(o=Wt(a,i));const f=Yt.buildRequest(s()({spec:r,operationId:o,parameters:l,securities:u,http:p},c));return f.body&&(Nt(f.body)||Array.isArray(f.body))&&(f.body=JSON.stringify(f.body)),p(f)}function Xt(e){const{spec:t,operationId:n,responseContentType:r,scheme:o,requestInterceptor:i,responseInterceptor:l,contextUrl:u,userFetch:c,server:p,serverVariables:f,http:h,signal:d}=e;let{parameters:m,parameterBuilders:g}=e;const y=Et(t);g||(g=y?a:Pt);let v={url:"",credentials:h&&h.withCredentials?"include":"same-origin",headers:{},cookies:{}};d&&(v.signal=d),i&&(v.requestInterceptor=i),l&&(v.responseInterceptor=l),c&&(v.userFetch=c);const b=function(e,t){return e&&e.paths?function(e,t){return function(e,t,n){if(!e||"object"!=typeof e||!e.paths||"object"!=typeof e.paths)return null;const{paths:r}=e;for(const o in r)for(const a in r[o]){if("PARAMETERS"===a.toUpperCase())continue;const i=r[o][a];if(!i||"object"!=typeof i)continue;const s={spec:e,pathName:o,method:a.toUpperCase(),operation:i},l=t(s);if(n&&l)return s}}(e,t,!0)||null}(e,(e=>{let{pathName:n,method:r,operation:o}=e;if(!o||"object"!=typeof o)return!1;const a=o.operationId;return[(0,gt.Z)(o,n,r),Wt(n,r),a].some((e=>e&&e===t))})):null}(t,n);if(!b)throw new Kt(`Operation ${n} not found`);const{operation:w={},method:E,pathName:x}=b;if(v.url+=function(e){const t=Et(e.spec);return t?function(e){let{spec:t,pathName:n,method:r,server:o,contextUrl:a,serverVariables:i={}}=e;const s=jt()(t,["paths",n,(r||"").toLowerCase(),"servers"])||jt()(t,["paths",n,"servers"])||jt()(t,["servers"]);let l="",u=null;if(o&&s&&s.length){const e=s.map((e=>e.url));e.indexOf(o)>-1&&(l=o,u=s[e.indexOf(o)])}!l&&s&&s.length&&(l=s[0].url,[u]=s);if(l.indexOf("{")>-1){(function(e){const t=[],n=/{([^}]+)}/g;let r;for(;r=n.exec(e);)t.push(r[1]);return t})(l).forEach((e=>{if(u.variables&&u.variables[e]){const t=u.variables[e],n=i[e]||t.default,r=new RegExp(`{${e}}`,"g");l=l.replace(r,n)}}))}return function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"";const n=e&&t?Ne.parse(Ne.resolve(t,e)):Ne.parse(e),r=Ne.parse(t),o=en(n.protocol)||en(r.protocol)||"",a=n.host||r.host,i=n.pathname||"";let s;s=o&&a?`${o}://${a+i}`:i;return"/"===s[s.length-1]?s.slice(0,-1):s}(l,a)}(e):function(e){let{spec:t,scheme:n,contextUrl:r=""}=e;const o=Ne.parse(r),a=Array.isArray(t.schemes)?t.schemes[0]:null,i=n||a||en(o.protocol)||"http",s=t.host||o.host||"",l=t.basePath||"";let u;u=i&&s?`${i}://${s+l}`:l;return"/"===u[u.length-1]?u.slice(0,-1):u}(e)}({spec:t,scheme:o,contextUrl:u,server:p,serverVariables:f,pathName:x,method:E}),!n)return delete v.cookies,v;v.url+=x,v.method=`${E}`.toUpperCase(),m=m||{};const _=t.paths[x]||{};r&&(v.headers.accept=r);const S=Zt([].concat(Jt(w.parameters)).concat(Jt(_.parameters)));S.forEach((e=>{const n=g[e.in];let r;if("body"===e.in&&e.schema&&e.schema.properties&&(r=m),r=e&&e.name&&m[e.name],void 0===r?r=e&&e.name&&m[`${e.in}.${e.name}`]:Gt(e.name,S).length>1&&console.warn(`Parameter '${e.name}' is ambiguous because the defined spec has more than one parameter with the name: '${e.name}' and the passed-in parameter values did not define an 'in' value.`),null!==r){if(void 0!==e.default&&void 0===r&&(r=e.default),void 0===r&&e.required&&!e.allowEmptyValue)throw new Error(`Required parameter ${e.name} is not provided`);if(y&&e.schema&&"object"===e.schema.type&&"string"==typeof r)try{r=JSON.parse(r)}catch(e){throw new Error("Could not parse object parameter value string as JSON")}n&&n({req:v,parameter:e,value:r,operation:w,spec:t})}}));const A=s()(s()({},e),{},{operation:w});if(v=y?$t(A,v):Vt(A,v),v.cookies&&Object.keys(v.cookies).length){const e=Object.keys(v.cookies).reduce(((e,t)=>{const n=v.cookies[t];return e+(e?"&":"")+Tt.serialize(t,n)}),"");v.headers.Cookie=e}return v.cookies&&delete v.cookies,R(v),v}const en=e=>e?e.replace(/\W/g,""):null;const tn=(e=>async function(t,n){let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};return async function(e,t){let n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};const{returnEntireTree:r,baseDoc:o,requestInterceptor:a,responseInterceptor:i,parameterMacro:l,modelPropertyMacro:u,useCircularStructures:c,strategies:p}=n,f={spec:e,pathDiscriminator:t,baseDoc:o,requestInterceptor:a,responseInterceptor:i,parameterMacro:l,modelPropertyMacro:u,useCircularStructures:c,strategies:p},h=p.find((e=>e.match(f))).normalize(f),d=await St(s()(s()({},f),{},{spec:h,allowMetaPatches:!0,skipNormalization:!0}));return!r&&Array.isArray(t)&&t.length&&(d.spec=jt()(d.spec,t)||null),d}(t,n,s()(s()({},e),r))})({strategies:[_t,xt,bt]});var nn=n(34852);function rn(e){let{configs:t,getConfigs:n}=e;return{fn:{fetch:(r=_,o=t.preFetch,a=t.postFetch,a=a||(e=>e),o=o||(e=>e),e=>("string"==typeof e&&(e={url:e}),x.mergeInQueryOrForm(e),e=o(e),a(r(e)))),buildRequest:Xt,execute:Qt,resolve:St,resolveSubtree:function(e,t,r){if(void 0===r){const e=n();r={modelPropertyMacro:e.modelPropertyMacro,parameterMacro:e.parameterMacro,requestInterceptor:e.requestInterceptor,responseInterceptor:e.responseInterceptor}}for(var o=arguments.length,a=new Array(o>3?o-3:0),i=3;i{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(90242);function o(){return{fn:{shallowEqualKeys:r.be}}}},48347:(e,t,n)=>{"use strict";n.r(t),n.d(t,{getDisplayName:()=>r});const r=e=>e.displayName||e.name||"Component"},73420:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>u});var r=n(35627),o=n.n(r),a=n(90242),i=n(11092),s=n(48347),l=n(60314);const u=e=>{let{getComponents:t,getStore:n,getSystem:r}=e;const u=(c=(0,i.getComponent)(r,n,t),(0,a.HP)(c,(function(){for(var e=arguments.length,t=new Array(e),n=0;n(0,l.Z)(e,(function(){for(var e=arguments.length,t=new Array(e),n=0;n{"use strict";n.r(t),n.d(t,{getComponent:()=>Q,render:()=>Y,withMappedContainer:()=>Z});var r=n(23101),o=n.n(r),a=n(28222),i=n.n(a),s=n(67294),l=n(73935),u=n(97779),c=n(61688),p=n(52798);let f=function(e){e()};const h=()=>f,d=(0,s.createContext)(null);let m=null;var g=n(87462),y=n(63366),v=n(8679),b=n.n(v),w=n(59864);const E=["initMapStateToProps","initMapDispatchToProps","initMergeProps"];function x(e,t,n,r,{areStatesEqual:o,areOwnPropsEqual:a,areStatePropsEqual:i}){let s,l,u,c,p,f=!1;function h(f,h){const d=!a(h,l),m=!o(f,s,h,l);return s=f,l=h,d&&m?(u=e(s,l),t.dependsOnOwnProps&&(c=t(r,l)),p=n(u,c,l),p):d?(e.dependsOnOwnProps&&(u=e(s,l)),t.dependsOnOwnProps&&(c=t(r,l)),p=n(u,c,l),p):m?function(){const t=e(s,l),r=!i(t,u);return u=t,r&&(p=n(u,c,l)),p}():p}return function(o,a){return f?h(o,a):(s=o,l=a,u=e(s,l),c=t(r,l),p=n(u,c,l),f=!0,p)}}function _(e){return function(t){const n=e(t);function r(){return n}return r.dependsOnOwnProps=!1,r}}function S(e){return e.dependsOnOwnProps?Boolean(e.dependsOnOwnProps):1!==e.length}function A(e,t){return function(t,{displayName:n}){const r=function(e,t){return r.dependsOnOwnProps?r.mapToProps(e,t):r.mapToProps(e,void 0)};return r.dependsOnOwnProps=!0,r.mapToProps=function(t,n){r.mapToProps=e,r.dependsOnOwnProps=S(e);let o=r(t,n);return"function"==typeof o&&(r.mapToProps=o,r.dependsOnOwnProps=S(o),o=r(t,n)),o},r}}function C(e,t){return(n,r)=>{throw new Error(`Invalid value of type ${typeof e} for ${t} argument when connecting component ${r.wrappedComponentName}.`)}}function k(e,t,n){return(0,g.Z)({},n,e,t)}const O={notify(){},get:()=>[]};function j(e,t){let n,r=O;function o(){i.onStateChange&&i.onStateChange()}function a(){n||(n=t?t.addNestedSub(o):e.subscribe(o),r=function(){const e=h();let t=null,n=null;return{clear(){t=null,n=null},notify(){e((()=>{let e=t;for(;e;)e.callback(),e=e.next}))},get(){let e=[],n=t;for(;n;)e.push(n),n=n.next;return e},subscribe(e){let r=!0,o=n={callback:e,next:null,prev:n};return o.prev?o.prev.next=o:t=o,function(){r&&null!==t&&(r=!1,o.next?o.next.prev=o.prev:n=o.prev,o.prev?o.prev.next=o.next:t=o.next)}}}}())}const i={addNestedSub:function(e){return a(),r.subscribe(e)},notifyNestedSubs:function(){r.notify()},handleChangeWrapper:o,isSubscribed:function(){return Boolean(n)},trySubscribe:a,tryUnsubscribe:function(){n&&(n(),n=void 0,r.clear(),r=O)},getListeners:()=>r};return i}const T=!("undefined"==typeof window||void 0===window.document||void 0===window.document.createElement)?s.useLayoutEffect:s.useEffect;function I(e,t){return e===t?0!==e||0!==t||1/e==1/t:e!=e&&t!=t}function N(e,t){if(I(e,t))return!0;if("object"!=typeof e||null===e||"object"!=typeof t||null===t)return!1;const n=Object.keys(e),r=Object.keys(t);if(n.length!==r.length)return!1;for(let r=0;r{throw new Error("uSES not initialized!")};const M=[null,null];function D(e,t,n,r,o,a){e.current=r,n.current=!1,o.current&&(o.current=null,a())}function L(e,t){return e===t}const B=function(e,t,n,{pure:r,areStatesEqual:o=L,areOwnPropsEqual:a=N,areStatePropsEqual:i=N,areMergedPropsEqual:l=N,forwardRef:u=!1,context:c=d}={}){const p=c,f=function(e){return e?"function"==typeof e?A(e):C(e,"mapStateToProps"):_((()=>({})))}(e),h=function(e){return e&&"object"==typeof e?_((t=>function(e,t){const n={};for(const r in e){const o=e[r];"function"==typeof o&&(n[r]=(...e)=>t(o(...e)))}return n}(e,t))):e?"function"==typeof e?A(e):C(e,"mapDispatchToProps"):_((e=>({dispatch:e})))}(t),m=function(e){return e?"function"==typeof e?function(e){return function(t,{displayName:n,areMergedPropsEqual:r}){let o,a=!1;return function(t,n,i){const s=e(t,n,i);return a?r(s,o)||(o=s):(a=!0,o=s),o}}}(e):C(e,"mergeProps"):()=>k}(n),v=Boolean(e);return e=>{const t=e.displayName||e.name||"Component",n=`Connect(${t})`,r={shouldHandleStateChanges:v,displayName:n,wrappedComponentName:t,WrappedComponent:e,initMapStateToProps:f,initMapDispatchToProps:h,initMergeProps:m,areStatesEqual:o,areStatePropsEqual:i,areOwnPropsEqual:a,areMergedPropsEqual:l};function c(t){const[n,o,a]=(0,s.useMemo)((()=>{const{reactReduxForwardedRef:e}=t,n=(0,y.Z)(t,P);return[t.context,e,n]}),[t]),i=(0,s.useMemo)((()=>n&&n.Consumer&&(0,w.isContextConsumer)(s.createElement(n.Consumer,null))?n:p),[n,p]),l=(0,s.useContext)(i),u=Boolean(t.store)&&Boolean(t.store.getState)&&Boolean(t.store.dispatch),c=Boolean(l)&&Boolean(l.store);const f=u?t.store:l.store,h=c?l.getServerState:f.getState,d=(0,s.useMemo)((()=>function(e,t){let{initMapStateToProps:n,initMapDispatchToProps:r,initMergeProps:o}=t,a=(0,y.Z)(t,E);return x(n(e,a),r(e,a),o(e,a),e,a)}(f.dispatch,r)),[f]),[m,b]=(0,s.useMemo)((()=>{if(!v)return M;const e=j(f,u?void 0:l.subscription),t=e.notifyNestedSubs.bind(e);return[e,t]}),[f,u,l]),_=(0,s.useMemo)((()=>u?l:(0,g.Z)({},l,{subscription:m})),[u,l,m]),S=(0,s.useRef)(),A=(0,s.useRef)(a),C=(0,s.useRef)(),k=(0,s.useRef)(!1),O=((0,s.useRef)(!1),(0,s.useRef)(!1)),I=(0,s.useRef)();T((()=>(O.current=!0,()=>{O.current=!1})),[]);const N=(0,s.useMemo)((()=>()=>C.current&&a===A.current?C.current:d(f.getState(),a)),[f,a]),L=(0,s.useMemo)((()=>e=>m?function(e,t,n,r,o,a,i,s,l,u,c){if(!e)return()=>{};let p=!1,f=null;const h=()=>{if(p||!s.current)return;const e=t.getState();let n,h;try{n=r(e,o.current)}catch(e){h=e,f=e}h||(f=null),n===a.current?i.current||u():(a.current=n,l.current=n,i.current=!0,c())};return n.onStateChange=h,n.trySubscribe(),h(),()=>{if(p=!0,n.tryUnsubscribe(),n.onStateChange=null,f)throw f}}(v,f,m,d,A,S,k,O,C,b,e):()=>{}),[m]);var B,F,z;let U;B=D,F=[A,S,k,a,C,b],T((()=>B(...F)),z);try{U=R(L,N,h?()=>d(h(),a):N)}catch(e){throw I.current&&(e.message+=`\nThe error may be correlated with this previous error:\n${I.current.stack}\n\n`),e}T((()=>{I.current=void 0,C.current=void 0,S.current=U}));const q=(0,s.useMemo)((()=>s.createElement(e,(0,g.Z)({},U,{ref:o}))),[o,e,U]);return(0,s.useMemo)((()=>v?s.createElement(i.Provider,{value:_},q):q),[i,q,_])}const d=s.memo(c);if(d.WrappedComponent=e,d.displayName=c.displayName=n,u){const t=s.forwardRef((function(e,t){return s.createElement(d,(0,g.Z)({},e,{reactReduxForwardedRef:t}))}));return t.displayName=n,t.WrappedComponent=e,b()(t,e)}return b()(d,e)}};const F=function({store:e,context:t,children:n,serverState:r}){const o=(0,s.useMemo)((()=>{const t=j(e);return{store:e,subscription:t,getServerState:r?()=>r:void 0}}),[e,r]),a=(0,s.useMemo)((()=>e.getState()),[e]);T((()=>{const{subscription:t}=o;return t.onStateChange=t.notifyNestedSubs,t.trySubscribe(),a!==e.getState()&&t.notifyNestedSubs(),()=>{t.tryUnsubscribe(),t.onStateChange=void 0}}),[o,a]);const i=t||d;return s.createElement(i.Provider,{value:o},n)};var z,U;z=p.useSyncExternalStoreWithSelector,m=z,(e=>{R=e})(c.useSyncExternalStore),U=l.unstable_batchedUpdates,f=U;var q=n(57557),$=n.n(q),V=n(6557),W=n.n(V);const H=e=>t=>{const{fn:n}=e();class r extends s.Component{render(){return s.createElement(t,o()({},e(),this.props,this.context))}}return r.displayName=`WithSystem(${n.getDisplayName(t)})`,r},J=(e,t)=>n=>{const{fn:r}=e();class a extends s.Component{render(){return s.createElement(F,{store:t},s.createElement(n,o()({},this.props,this.context)))}}return a.displayName=`WithRoot(${r.getDisplayName(n)})`,a},K=(e,t,n)=>(0,u.qC)(n?J(e,n):W(),B(((n,r)=>{var o;const a={...r,...e()},i=(null===(o=t.prototype)||void 0===o?void 0:o.mapStateToProps)||(e=>({state:e}));return i(n,a)})),H(e))(t),G=(e,t,n,r)=>{for(const o in t){const a=t[o];"function"==typeof a&&a(n[o],r[o],e())}},Z=(e,t,n)=>(t,r)=>{const{fn:o}=e(),a=n(t,"root");class l extends s.Component{constructor(t,n){super(t,n),G(e,r,t,{})}UNSAFE_componentWillReceiveProps(t){G(e,r,t,this.props)}render(){const e=$()(this.props,r?i()(r):[]);return s.createElement(a,e)}}return l.displayName=`WithMappedContainer(${o.getDisplayName(a)})`,l},Y=(e,t,n,r)=>o=>{const a=n(e,t,r)("App","root");l.render(s.createElement(a,null),o)},Q=(e,t,n)=>function(r,o){let a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};if("string"!=typeof r)throw new TypeError("Need a string, to fetch a component. Was given a "+typeof r);const i=n(r);return i?o?"root"===o?K(e,i,t()):K(e,i):i:(a.failSilently||e().log.warn("Could not find component:",r),null)}},33424:(e,t,n)=>{"use strict";n.d(t,{d3:()=>D,C2:()=>ee});var r=n(28222),o=n.n(r),a=n(58118),i=n.n(a),s=n(63366);function l(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n1&&void 0!==arguments[1]?arguments[1]:{},n=arguments.length>2?arguments[2]:void 0;return function(e){if(0===e.length||1===e.length)return e;var t,n,r=e.join(".");return m[r]||(m[r]=0===(n=(t=e).length)||1===n?t:2===n?[t[0],t[1],"".concat(t[0],".").concat(t[1]),"".concat(t[1],".").concat(t[0])]:3===n?[t[0],t[1],t[2],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0])]:n>=4?[t[0],t[1],t[2],t[3],"".concat(t[0],".").concat(t[1]),"".concat(t[0],".").concat(t[2]),"".concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[0]),"".concat(t[1],".").concat(t[2]),"".concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[1]),"".concat(t[2],".").concat(t[3]),"".concat(t[3],".").concat(t[0]),"".concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[0]),"".concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[0],".").concat(t[1],".").concat(t[2],".").concat(t[3]),"".concat(t[0],".").concat(t[1],".").concat(t[3],".").concat(t[2]),"".concat(t[0],".").concat(t[2],".").concat(t[1],".").concat(t[3]),"".concat(t[0],".").concat(t[2],".").concat(t[3],".").concat(t[1]),"".concat(t[0],".").concat(t[3],".").concat(t[1],".").concat(t[2]),"".concat(t[0],".").concat(t[3],".").concat(t[2],".").concat(t[1]),"".concat(t[1],".").concat(t[0],".").concat(t[2],".").concat(t[3]),"".concat(t[1],".").concat(t[0],".").concat(t[3],".").concat(t[2]),"".concat(t[1],".").concat(t[2],".").concat(t[0],".").concat(t[3]),"".concat(t[1],".").concat(t[2],".").concat(t[3],".").concat(t[0]),"".concat(t[1],".").concat(t[3],".").concat(t[0],".").concat(t[2]),"".concat(t[1],".").concat(t[3],".").concat(t[2],".").concat(t[0]),"".concat(t[2],".").concat(t[0],".").concat(t[1],".").concat(t[3]),"".concat(t[2],".").concat(t[0],".").concat(t[3],".").concat(t[1]),"".concat(t[2],".").concat(t[1],".").concat(t[0],".").concat(t[3]),"".concat(t[2],".").concat(t[1],".").concat(t[3],".").concat(t[0]),"".concat(t[2],".").concat(t[3],".").concat(t[0],".").concat(t[1]),"".concat(t[2],".").concat(t[3],".").concat(t[1],".").concat(t[0]),"".concat(t[3],".").concat(t[0],".").concat(t[1],".").concat(t[2]),"".concat(t[3],".").concat(t[0],".").concat(t[2],".").concat(t[1]),"".concat(t[3],".").concat(t[1],".").concat(t[0],".").concat(t[2]),"".concat(t[3],".").concat(t[1],".").concat(t[2],".").concat(t[0]),"".concat(t[3],".").concat(t[2],".").concat(t[0],".").concat(t[1]),"".concat(t[3],".").concat(t[2],".").concat(t[1],".").concat(t[0])]:void 0),m[r]}(e.filter((function(e){return"token"!==e}))).reduce((function(e,t){return d(d({},e),n[t])}),t)}function y(e){return e.join(" ")}function v(e){var t=e.node,n=e.stylesheet,r=e.style,o=void 0===r?{}:r,a=e.useInlineStyles,i=e.key,s=t.properties,l=t.type,u=t.tagName,c=t.value;if("text"===l)return c;if(u){var h,m=function(e,t){var n=0;return function(r){return n+=1,r.map((function(r,o){return v({node:r,stylesheet:e,useInlineStyles:t,key:"code-segment-".concat(n,"-").concat(o)})}))}}(n,a);if(a){var b=Object.keys(n).reduce((function(e,t){return t.split(".").forEach((function(t){e.includes(t)||e.push(t)})),e}),[]),w=s.className&&s.className.includes("token")?["token"]:[],E=s.className&&w.concat(s.className.filter((function(e){return!b.includes(e)})));h=d(d({},s),{},{className:y(E)||void 0,style:g(s.className,Object.assign({},s.style,o),n)})}else h=d(d({},s),{},{className:y(s.className)});var x=m(t.children);return p.createElement(u,(0,f.Z)({key:i},h),x)}}const b=function(e,t){return-1!==e.listLanguages().indexOf(t)};var w=["language","children","style","customStyle","codeTagProps","useInlineStyles","showLineNumbers","showInlineLineNumbers","startingLineNumber","lineNumberContainerStyle","lineNumberStyle","wrapLines","wrapLongLines","lineProps","renderer","PreTag","CodeTag","code","astGenerator"];function E(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function x(e){for(var t=1;t1&&void 0!==arguments[1]?arguments[1]:[],n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],r=0;r2&&void 0!==arguments[2]?arguments[2]:[];return t||u.length>0?function(e,t){return k({children:e,lineNumber:t,lineNumberStyle:s,largestLineNumber:i,showInlineLineNumbers:o,lineProps:n,className:arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],showLineNumbers:r,wrapLongLines:l})}(e,a,u):function(e,t){if(r&&t&&o){var n=C(s,t,i);e.unshift(A(t,n))}return e}(e,a)}for(var m=function(){var e=c[h],t=e.children[0].value;if(t.match(_)){var n=t.split("\n");n.forEach((function(t,o){var i=r&&p.length+a,s={type:"text",value:"".concat(t,"\n")};if(0===o){var l=d(c.slice(f+1,h).concat(k({children:[s],className:e.properties.className})),i);p.push(l)}else if(o===n.length-1){var u=c[h+1]&&c[h+1].children&&c[h+1].children[0],m={type:"text",value:"".concat(t)};if(u){var g=k({children:[m],className:e.properties.className});c.splice(h+1,0,g)}else{var y=d([m],i,e.properties.className);p.push(y)}}else{var v=d([s],i,e.properties.className);p.push(v)}})),f=h}h++};h=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}(e,w);$=$||N;var W=d?p.createElement(S,{containerStyle:E,codeStyle:u.style||{},numberStyle:A,startingLineNumber:v,codeString:q}):null,H=o.hljs||o['pre[class*="language-"]']||{backgroundColor:"#fff"},J=I($)?"hljs":"prismjs",K=f?Object.assign({},V,{style:Object.assign({},H,i)}):Object.assign({},V,{className:V.className?"".concat(J," ").concat(V.className):J,style:Object.assign({},i)});if(u.style=x(x({},u.style),{},O?{whiteSpace:"pre-wrap"}:{whiteSpace:"pre"}),!$)return p.createElement(B,K,W,p.createElement(z,u,q));(void 0===C&&D||O)&&(C=!0),D=D||T;var G=[{type:"text",value:q}],Z=function(e){var t=e.astGenerator,n=e.language,r=e.code,o=e.defaultCodeValue;if(I(t)){var a=b(t,n);return"text"===n?{value:o,language:"text"}:a?t.highlight(n,r):t.highlightAuto(r)}try{return n&&"text"!==n?{value:t.highlight(r,n)}:{value:o}}catch(e){return{value:o}}}({astGenerator:$,language:t,code:q,defaultCodeValue:G});null===Z.language&&(Z.value=G);var Y=j(Z,C,M,d,g,v,Z.value.length+v,A,O);return p.createElement(B,K,p.createElement(z,u,!g&&W,D({rows:Y,stylesheet:o,useInlineStyles:f})))});M.registerLanguage=R.registerLanguage;const D=M;var L=n(96344);const B=n.n(L)();var F=n(82026);const z=n.n(F)();var U=n(42157);const q=n.n(U)();var $=n(61519);const V=n.n($)();var W=n(54587);const H=n.n(W)();var J=n(30786);const K=n.n(J)();var G=n(66336);const Z=n.n(G)(),Y={hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#333",color:"white"},"hljs-name":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-code":{fontStyle:"italic",color:"#888"},"hljs-emphasis":{fontStyle:"italic"},"hljs-tag":{color:"#62c8f3"},"hljs-variable":{color:"#ade5fc"},"hljs-template-variable":{color:"#ade5fc"},"hljs-selector-id":{color:"#ade5fc"},"hljs-selector-class":{color:"#ade5fc"},"hljs-string":{color:"#a2fca2"},"hljs-bullet":{color:"#d36363"},"hljs-type":{color:"#ffa"},"hljs-title":{color:"#ffa"},"hljs-section":{color:"#ffa"},"hljs-attribute":{color:"#ffa"},"hljs-quote":{color:"#ffa"},"hljs-built_in":{color:"#ffa"},"hljs-builtin-name":{color:"#ffa"},"hljs-number":{color:"#d36363"},"hljs-symbol":{color:"#d36363"},"hljs-keyword":{color:"#fcc28c"},"hljs-selector-tag":{color:"#fcc28c"},"hljs-literal":{color:"#fcc28c"},"hljs-comment":{color:"#888"},"hljs-deletion":{color:"#333",backgroundColor:"#fc9b9b"},"hljs-regexp":{color:"#c6b4f0"},"hljs-link":{color:"#c6b4f0"},"hljs-meta":{color:"#fc9b9b"},"hljs-addition":{backgroundColor:"#a2fca2",color:"#333"}};D.registerLanguage("json",z),D.registerLanguage("js",B),D.registerLanguage("xml",q),D.registerLanguage("yaml",H),D.registerLanguage("http",K),D.registerLanguage("bash",V),D.registerLanguage("powershell",Z),D.registerLanguage("javascript",B);const Q={agate:Y,arta:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#222",color:"#aaa"},"hljs-subst":{color:"#aaa"},"hljs-section":{color:"#fff",fontWeight:"bold"},"hljs-comment":{color:"#444"},"hljs-quote":{color:"#444"},"hljs-meta":{color:"#444"},"hljs-string":{color:"#ffcc33"},"hljs-symbol":{color:"#ffcc33"},"hljs-bullet":{color:"#ffcc33"},"hljs-regexp":{color:"#ffcc33"},"hljs-number":{color:"#00cc66"},"hljs-addition":{color:"#00cc66"},"hljs-built_in":{color:"#32aaee"},"hljs-builtin-name":{color:"#32aaee"},"hljs-literal":{color:"#32aaee"},"hljs-type":{color:"#32aaee"},"hljs-template-variable":{color:"#32aaee"},"hljs-attribute":{color:"#32aaee"},"hljs-link":{color:"#32aaee"},"hljs-keyword":{color:"#6644aa"},"hljs-selector-tag":{color:"#6644aa"},"hljs-name":{color:"#6644aa"},"hljs-selector-id":{color:"#6644aa"},"hljs-selector-class":{color:"#6644aa"},"hljs-title":{color:"#bb1166"},"hljs-variable":{color:"#bb1166"},"hljs-deletion":{color:"#bb1166"},"hljs-template-tag":{color:"#bb1166"},"hljs-doctag":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"},"hljs-emphasis":{fontStyle:"italic"}},monokai:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#272822",color:"#ddd"},"hljs-tag":{color:"#f92672"},"hljs-keyword":{color:"#f92672",fontWeight:"bold"},"hljs-selector-tag":{color:"#f92672",fontWeight:"bold"},"hljs-literal":{color:"#f92672",fontWeight:"bold"},"hljs-strong":{color:"#f92672"},"hljs-name":{color:"#f92672"},"hljs-code":{color:"#66d9ef"},"hljs-class .hljs-title":{color:"white"},"hljs-attribute":{color:"#bf79db"},"hljs-symbol":{color:"#bf79db"},"hljs-regexp":{color:"#bf79db"},"hljs-link":{color:"#bf79db"},"hljs-string":{color:"#a6e22e"},"hljs-bullet":{color:"#a6e22e"},"hljs-subst":{color:"#a6e22e"},"hljs-title":{color:"#a6e22e",fontWeight:"bold"},"hljs-section":{color:"#a6e22e",fontWeight:"bold"},"hljs-emphasis":{color:"#a6e22e"},"hljs-type":{color:"#a6e22e",fontWeight:"bold"},"hljs-built_in":{color:"#a6e22e"},"hljs-builtin-name":{color:"#a6e22e"},"hljs-selector-attr":{color:"#a6e22e"},"hljs-selector-pseudo":{color:"#a6e22e"},"hljs-addition":{color:"#a6e22e"},"hljs-variable":{color:"#a6e22e"},"hljs-template-tag":{color:"#a6e22e"},"hljs-template-variable":{color:"#a6e22e"},"hljs-comment":{color:"#75715e"},"hljs-quote":{color:"#75715e"},"hljs-deletion":{color:"#75715e"},"hljs-meta":{color:"#75715e"},"hljs-doctag":{fontWeight:"bold"},"hljs-selector-id":{fontWeight:"bold"}},nord:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#2E3440",color:"#D8DEE9"},"hljs-subst":{color:"#D8DEE9"},"hljs-selector-tag":{color:"#81A1C1"},"hljs-selector-id":{color:"#8FBCBB",fontWeight:"bold"},"hljs-selector-class":{color:"#8FBCBB"},"hljs-selector-attr":{color:"#8FBCBB"},"hljs-selector-pseudo":{color:"#88C0D0"},"hljs-addition":{backgroundColor:"rgba(163, 190, 140, 0.5)"},"hljs-deletion":{backgroundColor:"rgba(191, 97, 106, 0.5)"},"hljs-built_in":{color:"#8FBCBB"},"hljs-type":{color:"#8FBCBB"},"hljs-class":{color:"#8FBCBB"},"hljs-function":{color:"#88C0D0"},"hljs-function > .hljs-title":{color:"#88C0D0"},"hljs-keyword":{color:"#81A1C1"},"hljs-literal":{color:"#81A1C1"},"hljs-symbol":{color:"#81A1C1"},"hljs-number":{color:"#B48EAD"},"hljs-regexp":{color:"#EBCB8B"},"hljs-string":{color:"#A3BE8C"},"hljs-title":{color:"#8FBCBB"},"hljs-params":{color:"#D8DEE9"},"hljs-bullet":{color:"#81A1C1"},"hljs-code":{color:"#8FBCBB"},"hljs-emphasis":{fontStyle:"italic"},"hljs-formula":{color:"#8FBCBB"},"hljs-strong":{fontWeight:"bold"},"hljs-link:hover":{textDecoration:"underline"},"hljs-quote":{color:"#4C566A"},"hljs-comment":{color:"#4C566A"},"hljs-doctag":{color:"#8FBCBB"},"hljs-meta":{color:"#5E81AC"},"hljs-meta-keyword":{color:"#5E81AC"},"hljs-meta-string":{color:"#A3BE8C"},"hljs-attr":{color:"#8FBCBB"},"hljs-attribute":{color:"#D8DEE9"},"hljs-builtin-name":{color:"#81A1C1"},"hljs-name":{color:"#81A1C1"},"hljs-section":{color:"#88C0D0"},"hljs-tag":{color:"#81A1C1"},"hljs-variable":{color:"#D8DEE9"},"hljs-template-variable":{color:"#D8DEE9"},"hljs-template-tag":{color:"#5E81AC"},"abnf .hljs-attribute":{color:"#88C0D0"},"abnf .hljs-symbol":{color:"#EBCB8B"},"apache .hljs-attribute":{color:"#88C0D0"},"apache .hljs-section":{color:"#81A1C1"},"arduino .hljs-built_in":{color:"#88C0D0"},"aspectj .hljs-meta":{color:"#D08770"},"aspectj > .hljs-title":{color:"#88C0D0"},"bnf .hljs-attribute":{color:"#8FBCBB"},"clojure .hljs-name":{color:"#88C0D0"},"clojure .hljs-symbol":{color:"#EBCB8B"},"coq .hljs-built_in":{color:"#88C0D0"},"cpp .hljs-meta-string":{color:"#8FBCBB"},"css .hljs-built_in":{color:"#88C0D0"},"css .hljs-keyword":{color:"#D08770"},"diff .hljs-meta":{color:"#8FBCBB"},"ebnf .hljs-attribute":{color:"#8FBCBB"},"glsl .hljs-built_in":{color:"#88C0D0"},"groovy .hljs-meta:not(:first-child)":{color:"#D08770"},"haxe .hljs-meta":{color:"#D08770"},"java .hljs-meta":{color:"#D08770"},"ldif .hljs-attribute":{color:"#8FBCBB"},"lisp .hljs-name":{color:"#88C0D0"},"lua .hljs-built_in":{color:"#88C0D0"},"moonscript .hljs-built_in":{color:"#88C0D0"},"nginx .hljs-attribute":{color:"#88C0D0"},"nginx .hljs-section":{color:"#5E81AC"},"pf .hljs-built_in":{color:"#88C0D0"},"processing .hljs-built_in":{color:"#88C0D0"},"scss .hljs-keyword":{color:"#81A1C1"},"stylus .hljs-keyword":{color:"#81A1C1"},"swift .hljs-meta":{color:"#D08770"},"vim .hljs-built_in":{color:"#88C0D0",fontStyle:"italic"},"yaml .hljs-meta":{color:"#D08770"}},obsidian:{hljs:{display:"block",overflowX:"auto",padding:"0.5em",background:"#282b2e",color:"#e0e2e4"},"hljs-keyword":{color:"#93c763",fontWeight:"bold"},"hljs-selector-tag":{color:"#93c763",fontWeight:"bold"},"hljs-literal":{color:"#93c763",fontWeight:"bold"},"hljs-selector-id":{color:"#93c763"},"hljs-number":{color:"#ffcd22"},"hljs-attribute":{color:"#668bb0"},"hljs-code":{color:"white"},"hljs-class .hljs-title":{color:"white"},"hljs-section":{color:"white",fontWeight:"bold"},"hljs-regexp":{color:"#d39745"},"hljs-link":{color:"#d39745"},"hljs-meta":{color:"#557182"},"hljs-tag":{color:"#8cbbad"},"hljs-name":{color:"#8cbbad",fontWeight:"bold"},"hljs-bullet":{color:"#8cbbad"},"hljs-subst":{color:"#8cbbad"},"hljs-emphasis":{color:"#8cbbad"},"hljs-type":{color:"#8cbbad",fontWeight:"bold"},"hljs-built_in":{color:"#8cbbad"},"hljs-selector-attr":{color:"#8cbbad"},"hljs-selector-pseudo":{color:"#8cbbad"},"hljs-addition":{color:"#8cbbad"},"hljs-variable":{color:"#8cbbad"},"hljs-template-tag":{color:"#8cbbad"},"hljs-template-variable":{color:"#8cbbad"},"hljs-string":{color:"#ec7600"},"hljs-symbol":{color:"#ec7600"},"hljs-comment":{color:"#818e96"},"hljs-quote":{color:"#818e96"},"hljs-deletion":{color:"#818e96"},"hljs-selector-class":{color:"#A082BD"},"hljs-doctag":{fontWeight:"bold"},"hljs-title":{fontWeight:"bold"},"hljs-strong":{fontWeight:"bold"}},"tomorrow-night":{"hljs-comment":{color:"#969896"},"hljs-quote":{color:"#969896"},"hljs-variable":{color:"#cc6666"},"hljs-template-variable":{color:"#cc6666"},"hljs-tag":{color:"#cc6666"},"hljs-name":{color:"#cc6666"},"hljs-selector-id":{color:"#cc6666"},"hljs-selector-class":{color:"#cc6666"},"hljs-regexp":{color:"#cc6666"},"hljs-deletion":{color:"#cc6666"},"hljs-number":{color:"#de935f"},"hljs-built_in":{color:"#de935f"},"hljs-builtin-name":{color:"#de935f"},"hljs-literal":{color:"#de935f"},"hljs-type":{color:"#de935f"},"hljs-params":{color:"#de935f"},"hljs-meta":{color:"#de935f"},"hljs-link":{color:"#de935f"},"hljs-attribute":{color:"#f0c674"},"hljs-string":{color:"#b5bd68"},"hljs-symbol":{color:"#b5bd68"},"hljs-bullet":{color:"#b5bd68"},"hljs-addition":{color:"#b5bd68"},"hljs-title":{color:"#81a2be"},"hljs-section":{color:"#81a2be"},"hljs-keyword":{color:"#b294bb"},"hljs-selector-tag":{color:"#b294bb"},hljs:{display:"block",overflowX:"auto",background:"#1d1f21",color:"#c5c8c6",padding:"0.5em"},"hljs-emphasis":{fontStyle:"italic"},"hljs-strong":{fontWeight:"bold"}}},X=o()(Q),ee=e=>i()(X).call(X,e)?Q[e]:(console.warn(`Request style '${e}' is not available, returning default instead`),Y)},90242:(e,t,n)=>{"use strict";n.d(t,{AF:()=>he,Ay:()=>be,D$:()=>He,DR:()=>Se,GZ:()=>Me,HP:()=>ve,Ik:()=>ke,J6:()=>Ue,Kn:()=>me,LQ:()=>de,Nm:()=>Le,O2:()=>Qe,Pz:()=>We,Q2:()=>we,QG:()=>Fe,UG:()=>Ne,Uj:()=>Ge,V9:()=>Je,Wl:()=>ge,XV:()=>Ve,Xb:()=>Ze,Zl:()=>Ae,_5:()=>Ee,be:()=>De,cz:()=>Ke,gp:()=>_e,hW:()=>Be,iQ:()=>xe,kJ:()=>ye,mz:()=>pe,nX:()=>qe,oG:()=>fe,oJ:()=>ze,po:()=>$e,r3:()=>Pe,wh:()=>Re,xi:()=>Ie});var r=n(58309),o=n.n(r),a=n(97606),i=n.n(a),s=n(74386),l=n.n(s),u=n(86),c=n.n(u),p=n(14418),f=n.n(p),h=n(28222),d=n.n(h),m=(n(11189),n(24282)),g=n.n(m),y=n(76986),v=n.n(y),b=n(2578),w=n.n(b),E=n(24278),x=n.n(E),_=(n(39022),n(92039)),S=n.n(_),A=(n(58118),n(35627)),C=n.n(A),k=n(11882),O=n.n(k),j=n(51679),T=n.n(j),I=n(27043),N=n.n(I),P=n(81607),R=n.n(P),M=n(43393),D=n.n(M),L=n(17967),B=n(68929),F=n.n(B),z=n(11700),U=n.n(z),q=n(88306),$=n.n(q),V=n(13311),W=n.n(V),H=n(59704),J=n.n(H),K=n(77813),G=n.n(K),Z=n(23560),Y=n.n(Z),Q=n(57050),X=n(27504),ee=n(8269),te=n.n(ee),ne=n(19069),re=n(92282),oe=n.n(re),ae=n(89072),ie=n.n(ae),se=n(1272),le=n(48764).Buffer;const ue="default",ce=e=>D().Iterable.isIterable(e);function pe(e){return me(e)?ce(e)?e.toJS():e:{}}function fe(e){var t,n;if(ce(e))return e;if(e instanceof X.Z.File)return e;if(!me(e))return e;if(o()(e))return i()(n=D().Seq(e)).call(n,fe).toList();if(Y()(l()(e))){var r;const t=function(e){if(!Y()(l()(e)))return e;const t={},n="_**[]",r={};for(let o of l()(e).call(e))if(t[o[0]]||r[o[0]]&&r[o[0]].containsMultiple){if(!r[o[0]]){r[o[0]]={containsMultiple:!0,length:1},t[`${o[0]}${n}${r[o[0]].length}`]=t[o[0]],delete t[o[0]]}r[o[0]].length+=1,t[`${o[0]}${n}${r[o[0]].length}`]=o[1]}else t[o[0]]=o[1];return t}(e);return i()(r=D().OrderedMap(t)).call(r,fe)}return i()(t=D().OrderedMap(e)).call(t,fe)}function he(e){return o()(e)?e:[e]}function de(e){return"function"==typeof e}function me(e){return!!e&&"object"==typeof e}function ge(e){return"function"==typeof e}function ye(e){return o()(e)}const ve=$();function be(e,t){var n;return g()(n=d()(e)).call(n,((n,r)=>(n[r]=t(e[r],r),n)),{})}function we(e,t){var n;return g()(n=d()(e)).call(n,((n,r)=>{let o=t(e[r],r);return o&&"object"==typeof o&&v()(n,o),n}),{})}function Ee(e){return t=>{let{dispatch:n,getState:r}=t;return t=>n=>"function"==typeof n?n(e()):t(n)}}function xe(e){var t;let n=e.keySeq();return n.contains(ue)?ue:w()(t=f()(n).call(n,(e=>"2"===(e+"")[0]))).call(t).first()}function _e(e,t){if(!D().Iterable.isIterable(e))return D().List();let n=e.getIn(o()(t)?t:[t]);return D().List.isList(n)?n:D().List()}function Se(e){let t,n=[/filename\*=[^']+'\w*'"([^"]+)";?/i,/filename\*=[^']+'\w*'([^;]+);?/i,/filename="([^;]*);?"/i,/filename=([^;]*);?/i];if(S()(n).call(n,(n=>(t=n.exec(e),null!==t))),null!==t&&t.length>1)try{return decodeURIComponent(t[1])}catch(e){console.error(e)}return null}function Ae(e){return t=e.replace(/\.[^./]*$/,""),U()(F()(t));var t}function Ce(e,t,n,r,a){if(!t)return[];let s=[],l=t.get("nullable"),u=t.get("required"),p=t.get("maximum"),h=t.get("minimum"),d=t.get("type"),m=t.get("format"),g=t.get("maxLength"),y=t.get("minLength"),v=t.get("uniqueItems"),b=t.get("maxItems"),w=t.get("minItems"),E=t.get("pattern");const x=n||!0===u,_=null!=e;if(l&&null===e||!d||!(x||_&&"array"===d||!(!x&&!_)))return[];let A="string"===d&&e,C="array"===d&&o()(e)&&e.length,k="array"===d&&D().List.isList(e)&&e.count();const O=[A,C,k,"array"===d&&"string"==typeof e&&e,"file"===d&&e instanceof X.Z.File,"boolean"===d&&(e||!1===e),"number"===d&&(e||0===e),"integer"===d&&(e||0===e),"object"===d&&"object"==typeof e&&null!==e,"object"===d&&"string"==typeof e&&e],j=S()(O).call(O,(e=>!!e));if(x&&!j&&!r)return s.push("Required field is not provided"),s;if("object"===d&&(null===a||"application/json"===a)){let n=e;if("string"==typeof e)try{n=JSON.parse(e)}catch(e){return s.push("Parameter string value must be valid JSON"),s}var T;if(t&&t.has("required")&&ge(u.isList)&&u.isList()&&c()(u).call(u,(e=>{void 0===n[e]&&s.push({propKey:e,error:"Required property not found"})})),t&&t.has("properties"))c()(T=t.get("properties")).call(T,((e,t)=>{const o=Ce(n[t],e,!1,r,a);s.push(...i()(o).call(o,(e=>({propKey:t,error:e}))))}))}if(E){let t=((e,t)=>{if(!new RegExp(t).test(e))return"Value must follow pattern "+t})(e,E);t&&s.push(t)}if(w&&"array"===d){let t=((e,t)=>{if(!e&&t>=1||e&&e.length{if(e&&e.length>t)return`Array must not contain more then ${t} item${1===t?"":"s"}`})(e,b);t&&s.push({needRemove:!0,error:t})}if(v&&"array"===d){let t=((e,t)=>{if(e&&("true"===t||!0===t)){const t=(0,M.fromJS)(e),n=t.toSet();if(e.length>n.size){let e=(0,M.Set)();if(c()(t).call(t,((n,r)=>{f()(t).call(t,(e=>ge(e.equals)?e.equals(n):e===n)).size>1&&(e=e.add(r))})),0!==e.size)return i()(e).call(e,(e=>({index:e,error:"No duplicates allowed."}))).toArray()}}})(e,v);t&&s.push(...t)}if(g||0===g){let t=((e,t)=>{if(e.length>t)return`Value must be no longer than ${t} character${1!==t?"s":""}`})(e,g);t&&s.push(t)}if(y){let t=((e,t)=>{if(e.length{if(e>t)return`Value must be less than ${t}`})(e,p);t&&s.push(t)}if(h||0===h){let t=((e,t)=>{if(e{if(isNaN(Date.parse(e)))return"Value must be a DateTime"})(e):"uuid"===m?(e=>{if(e=e.toString().toLowerCase(),!/^[{(]?[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}[)}]?$/.test(e))return"Value must be a Guid"})(e):(e=>{if(e&&"string"!=typeof e)return"Value must be a string"})(e),!t)return s;s.push(t)}else if("boolean"===d){let t=(e=>{if("true"!==e&&"false"!==e&&!0!==e&&!1!==e)return"Value must be a boolean"})(e);if(!t)return s;s.push(t)}else if("number"===d){let t=(e=>{if(!/^-?\d+(\.?\d+)?$/.test(e))return"Value must be a number"})(e);if(!t)return s;s.push(t)}else if("integer"===d){let t=(e=>{if(!/^-?\d+$/.test(e))return"Value must be an integer"})(e);if(!t)return s;s.push(t)}else if("array"===d){if(!C&&!k)return s;e&&c()(e).call(e,((e,n)=>{const o=Ce(e,t.get("items"),!1,r,a);s.push(...i()(o).call(o,(e=>({index:n,error:e}))))}))}else if("file"===d){let t=(e=>{if(e&&!(e instanceof X.Z.File))return"Value must be a file"})(e);if(!t)return s;s.push(t)}return s}const ke=function(e,t){let{isOAS3:n=!1,bypassRequiredCheck:r=!1}=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},o=e.get("required"),{schema:a,parameterContentMediaType:i}=(0,ne.Z)(e,{isOAS3:n});return Ce(t,a,o,r,i)},Oe=[{when:/json/,shouldStringifyTypes:["string"]}],je=["object"],Te=(e,t,n,r)=>{const o=(0,Q.memoizedSampleFromSchema)(e,t,r),a=typeof o,i=g()(Oe).call(Oe,((e,t)=>t.when.test(n)?[...e,...t.shouldStringifyTypes]:e),je);return J()(i,(e=>e===a))?C()(o,null,2):o},Ie=function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{},r=arguments.length>3&&void 0!==arguments[3]?arguments[3]:void 0;return e&&ge(e.toJS)&&(e=e.toJS()),r&&ge(r.toJS)&&(r=r.toJS()),/xml/.test(t)?((e,t,n)=>{if(e&&!e.xml&&(e.xml={}),e&&!e.xml.name){if(!e.$$ref&&(e.type||e.items||e.properties||e.additionalProperties))return'\n\x3c!-- XML example cannot be generated; root element name is undefined --\x3e';if(e.$$ref){let t=e.$$ref.match(/\S*\/(\S+)$/);e.xml.name=t[1]}}return(0,Q.memoizedCreateXMLExample)(e,t,n)})(e,n,r):/(yaml|yml)/.test(t)?((e,t,n,r)=>{const o=Te(e,t,n,r);let a;try{a=se.ZP.dump(se.ZP.load(o),{lineWidth:-1},{schema:se.A8}),"\n"===a[a.length-1]&&(a=x()(a).call(a,0,a.length-1))}catch(e){return console.error(e),"error: could not generate yaml example"}return a.replace(/\t/g," ")})(e,n,t,r):Te(e,n,t,r)},Ne=()=>{let e={},t=X.Z.location.search;if(!t)return{};if(""!=t){let n=t.substr(1).split("&");for(let t in n)Object.prototype.hasOwnProperty.call(n,t)&&(t=n[t].split("="),e[decodeURIComponent(t[0])]=t[1]&&decodeURIComponent(t[1])||"")}return e},Pe=e=>{let t;return t=e instanceof le?e:le.from(e.toString(),"utf-8"),t.toString("base64")},Re={operationsSorter:{alpha:(e,t)=>e.get("path").localeCompare(t.get("path")),method:(e,t)=>e.get("method").localeCompare(t.get("method"))},tagsSorter:{alpha:(e,t)=>e.localeCompare(t)}},Me=e=>{let t=[];for(let n in e){let r=e[n];void 0!==r&&""!==r&&t.push([n,"=",encodeURIComponent(r).replace(/%20/g,"+")].join(""))}return t.join("&")},De=(e,t,n)=>!!W()(n,(n=>G()(e[n],t[n])));function Le(e){return"string"!=typeof e||""===e?"":(0,L.N)(e)}function Be(e){return!(!e||O()(e).call(e,"localhost")>=0||O()(e).call(e,"127.0.0.1")>=0||"none"===e)}function Fe(e){if(!D().OrderedMap.isOrderedMap(e))return null;if(!e.size)return null;const t=T()(e).call(e,((e,t)=>N()(t).call(t,"2")&&d()(e.get("content")||{}).length>0)),n=e.get("default")||D().OrderedMap(),r=(n.get("content")||D().OrderedMap()).keySeq().toJS().length?n:null;return t||r}const ze=e=>"string"==typeof e||e instanceof String?R()(e).call(e).replace(/\s/g,"%20"):"",Ue=e=>te()(ze(e).replace(/%20/g,"_")),qe=e=>f()(e).call(e,((e,t)=>/^x-/.test(t))),$e=e=>f()(e).call(e,((e,t)=>/^pattern|maxLength|minLength|maximum|minimum/.test(t)));function Ve(e,t){var n;let r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:()=>!0;if("object"!=typeof e||o()(e)||null===e||!t)return e;const a=v()({},e);return c()(n=d()(a)).call(n,(e=>{e===t&&r(a[e],e)?delete a[e]:a[e]=Ve(a[e],t,r)})),a}function We(e){if("string"==typeof e)return e;if(e&&e.toJS&&(e=e.toJS()),"object"==typeof e&&null!==e)try{return C()(e,null,2)}catch(t){return String(e)}return null==e?"":e.toString()}function He(e){return"number"==typeof e?e.toString():e}function Je(e){let{returnAll:t=!1,allowHashes:n=!0}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!D().Map.isMap(e))throw new Error("paramToIdentifier: received a non-Im.Map parameter as input");const r=e.get("name"),o=e.get("in");let a=[];return e&&e.hashCode&&o&&r&&n&&a.push(`${o}.${r}.hash-${e.hashCode()}`),o&&r&&a.push(`${o}.${r}`),a.push(r),t?a:a[0]||""}function Ke(e,t){var n;const r=Je(e,{returnAll:!0});return f()(n=i()(r).call(r,(e=>t[e]))).call(n,(e=>void 0!==e))[0]}function Ge(){return Ye(oe()(32).toString("base64"))}function Ze(e){return Ye(ie()("sha256").update(e).digest("base64"))}function Ye(e){return e.replace(/\+/g,"-").replace(/\//g,"_").replace(/=/g,"")}const Qe=e=>!e||!(!ce(e)||!e.isEmpty())},2518:(e,t,n)=>{"use strict";function r(e){return function(e){try{return!!JSON.parse(e)}catch(e){return null}}(e)?"json":null}n.d(t,{O:()=>r})},27504:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=function(){var e={location:{},history:{},open:()=>{},close:()=>{},File:function(){}};if("undefined"==typeof window)return e;try{e=window;for(var t of["File","Blob","FormData"])t in window&&(e[t]=window[t])}catch(e){console.error(e)}return e}()},19069:(e,t,n)=>{"use strict";n.d(t,{Z:()=>c});var r=n(14418),o=n.n(r),a=n(58118),i=n.n(a),s=n(43393),l=n.n(s);const u=l().Set.of("type","format","items","default","maximum","exclusiveMaximum","minimum","exclusiveMinimum","maxLength","minLength","pattern","maxItems","minItems","uniqueItems","enum","multipleOf");function c(e){let{isOAS3:t}=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(!l().Map.isMap(e))return{schema:l().Map(),parameterContentMediaType:null};if(!t)return"body"===e.get("in")?{schema:e.get("schema",l().Map()),parameterContentMediaType:null}:{schema:o()(e).call(e,((e,t)=>i()(u).call(u,t))),parameterContentMediaType:null};if(e.get("content")){const t=e.get("content",l().Map({})).keySeq().first();return{schema:e.getIn(["content",t,"schema"],l().Map()),parameterContentMediaType:t}}return{schema:e.get("schema")?e.get("schema",l().Map()):l().Map(),parameterContentMediaType:null}}},60314:(e,t,n)=>{"use strict";n.d(t,{Z:()=>x});var r=n(58309),o=n.n(r),a=n(2250),i=n.n(a),s=n(25110),l=n.n(s),u=n(8712),c=n.n(u),p=n(51679),f=n.n(p),h=n(12373),d=n.n(h),m=n(18492),g=n.n(m),y=n(88306),v=n.n(y);const b=e=>t=>o()(e)&&o()(t)&&e.length===t.length&&i()(e).call(e,((e,n)=>e===t[n])),w=function(){for(var e=arguments.length,t=new Array(e),n=0;n1&&void 0!==arguments[1]?arguments[1]:w;const{Cache:n}=v();v().Cache=E;const r=v()(e,t);return v().Cache=n,r}},79742:(e,t)=>{"use strict";t.byteLength=function(e){var t=s(e),n=t[0],r=t[1];return 3*(n+r)/4-r},t.toByteArray=function(e){var t,n,a=s(e),i=a[0],l=a[1],u=new o(function(e,t,n){return 3*(t+n)/4-n}(0,i,l)),c=0,p=l>0?i-4:i;for(n=0;n>16&255,u[c++]=t>>8&255,u[c++]=255&t;2===l&&(t=r[e.charCodeAt(n)]<<2|r[e.charCodeAt(n+1)]>>4,u[c++]=255&t);1===l&&(t=r[e.charCodeAt(n)]<<10|r[e.charCodeAt(n+1)]<<4|r[e.charCodeAt(n+2)]>>2,u[c++]=t>>8&255,u[c++]=255&t);return u},t.fromByteArray=function(e){for(var t,r=e.length,o=r%3,a=[],i=16383,s=0,u=r-o;su?u:s+i));1===o?(t=e[r-1],a.push(n[t>>2]+n[t<<4&63]+"==")):2===o&&(t=(e[r-2]<<8)+e[r-1],a.push(n[t>>10]+n[t>>4&63]+n[t<<2&63]+"="));return a.join("")};for(var n=[],r=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0;i<64;++i)n[i]=a[i],r[a.charCodeAt(i)]=i;function s(e){var t=e.length;if(t%4>0)throw new Error("Invalid string. Length must be a multiple of 4");var n=e.indexOf("=");return-1===n&&(n=t),[n,n===t?0:4-n%4]}function l(e,t,r){for(var o,a,i=[],s=t;s>18&63]+n[a>>12&63]+n[a>>6&63]+n[63&a]);return i.join("")}r["-".charCodeAt(0)]=62,r["_".charCodeAt(0)]=63},48764:(e,t,n)=>{"use strict";const r=n(79742),o=n(80645),a="function"==typeof Symbol&&"function"==typeof Symbol.for?Symbol.for("nodejs.util.inspect.custom"):null;t.Buffer=l,t.SlowBuffer=function(e){+e!=e&&(e=0);return l.alloc(+e)},t.INSPECT_MAX_BYTES=50;const i=2147483647;function s(e){if(e>i)throw new RangeError('The value "'+e+'" is invalid for option "size"');const t=new Uint8Array(e);return Object.setPrototypeOf(t,l.prototype),t}function l(e,t,n){if("number"==typeof e){if("string"==typeof t)throw new TypeError('The "string" argument must be of type string. Received type number');return p(e)}return u(e,t,n)}function u(e,t,n){if("string"==typeof e)return function(e,t){"string"==typeof t&&""!==t||(t="utf8");if(!l.isEncoding(t))throw new TypeError("Unknown encoding: "+t);const n=0|m(e,t);let r=s(n);const o=r.write(e,t);o!==n&&(r=r.slice(0,o));return r}(e,t);if(ArrayBuffer.isView(e))return function(e){if(G(e,Uint8Array)){const t=new Uint8Array(e);return h(t.buffer,t.byteOffset,t.byteLength)}return f(e)}(e);if(null==e)throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e);if(G(e,ArrayBuffer)||e&&G(e.buffer,ArrayBuffer))return h(e,t,n);if("undefined"!=typeof SharedArrayBuffer&&(G(e,SharedArrayBuffer)||e&&G(e.buffer,SharedArrayBuffer)))return h(e,t,n);if("number"==typeof e)throw new TypeError('The "value" argument must not be of type number. Received type number');const r=e.valueOf&&e.valueOf();if(null!=r&&r!==e)return l.from(r,t,n);const o=function(e){if(l.isBuffer(e)){const t=0|d(e.length),n=s(t);return 0===n.length||e.copy(n,0,0,t),n}if(void 0!==e.length)return"number"!=typeof e.length||Z(e.length)?s(0):f(e);if("Buffer"===e.type&&Array.isArray(e.data))return f(e.data)}(e);if(o)return o;if("undefined"!=typeof Symbol&&null!=Symbol.toPrimitive&&"function"==typeof e[Symbol.toPrimitive])return l.from(e[Symbol.toPrimitive]("string"),t,n);throw new TypeError("The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type "+typeof e)}function c(e){if("number"!=typeof e)throw new TypeError('"size" argument must be of type number');if(e<0)throw new RangeError('The value "'+e+'" is invalid for option "size"')}function p(e){return c(e),s(e<0?0:0|d(e))}function f(e){const t=e.length<0?0:0|d(e.length),n=s(t);for(let r=0;r=i)throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+i.toString(16)+" bytes");return 0|e}function m(e,t){if(l.isBuffer(e))return e.length;if(ArrayBuffer.isView(e)||G(e,ArrayBuffer))return e.byteLength;if("string"!=typeof e)throw new TypeError('The "string" argument must be one of type string, Buffer, or ArrayBuffer. Received type '+typeof e);const n=e.length,r=arguments.length>2&&!0===arguments[2];if(!r&&0===n)return 0;let o=!1;for(;;)switch(t){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":return H(e).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return J(e).length;default:if(o)return r?-1:H(e).length;t=(""+t).toLowerCase(),o=!0}}function g(e,t,n){let r=!1;if((void 0===t||t<0)&&(t=0),t>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(t>>>=0))return"";for(e||(e="utf8");;)switch(e){case"hex":return T(this,t,n);case"utf8":case"utf-8":return C(this,t,n);case"ascii":return O(this,t,n);case"latin1":case"binary":return j(this,t,n);case"base64":return A(this,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return I(this,t,n);default:if(r)throw new TypeError("Unknown encoding: "+e);e=(e+"").toLowerCase(),r=!0}}function y(e,t,n){const r=e[t];e[t]=e[n],e[n]=r}function v(e,t,n,r,o){if(0===e.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),Z(n=+n)&&(n=o?0:e.length-1),n<0&&(n=e.length+n),n>=e.length){if(o)return-1;n=e.length-1}else if(n<0){if(!o)return-1;n=0}if("string"==typeof t&&(t=l.from(t,r)),l.isBuffer(t))return 0===t.length?-1:b(e,t,n,r,o);if("number"==typeof t)return t&=255,"function"==typeof Uint8Array.prototype.indexOf?o?Uint8Array.prototype.indexOf.call(e,t,n):Uint8Array.prototype.lastIndexOf.call(e,t,n):b(e,[t],n,r,o);throw new TypeError("val must be string, number or Buffer")}function b(e,t,n,r,o){let a,i=1,s=e.length,l=t.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(e.length<2||t.length<2)return-1;i=2,s/=2,l/=2,n/=2}function u(e,t){return 1===i?e[t]:e.readUInt16BE(t*i)}if(o){let r=-1;for(a=n;as&&(n=s-l),a=n;a>=0;a--){let n=!0;for(let r=0;ro&&(r=o):r=o;const a=t.length;let i;for(r>a/2&&(r=a/2),i=0;i>8,o=n%256,a.push(o),a.push(r);return a}(t,e.length-n),e,n,r)}function A(e,t,n){return 0===t&&n===e.length?r.fromByteArray(e):r.fromByteArray(e.slice(t,n))}function C(e,t,n){n=Math.min(e.length,n);const r=[];let o=t;for(;o239?4:t>223?3:t>191?2:1;if(o+i<=n){let n,r,s,l;switch(i){case 1:t<128&&(a=t);break;case 2:n=e[o+1],128==(192&n)&&(l=(31&t)<<6|63&n,l>127&&(a=l));break;case 3:n=e[o+1],r=e[o+2],128==(192&n)&&128==(192&r)&&(l=(15&t)<<12|(63&n)<<6|63&r,l>2047&&(l<55296||l>57343)&&(a=l));break;case 4:n=e[o+1],r=e[o+2],s=e[o+3],128==(192&n)&&128==(192&r)&&128==(192&s)&&(l=(15&t)<<18|(63&n)<<12|(63&r)<<6|63&s,l>65535&&l<1114112&&(a=l))}}null===a?(a=65533,i=1):a>65535&&(a-=65536,r.push(a>>>10&1023|55296),a=56320|1023&a),r.push(a),o+=i}return function(e){const t=e.length;if(t<=k)return String.fromCharCode.apply(String,e);let n="",r=0;for(;rr.length?(l.isBuffer(t)||(t=l.from(t)),t.copy(r,o)):Uint8Array.prototype.set.call(r,t,o);else{if(!l.isBuffer(t))throw new TypeError('"list" argument must be an Array of Buffers');t.copy(r,o)}o+=t.length}return r},l.byteLength=m,l.prototype._isBuffer=!0,l.prototype.swap16=function(){const e=this.length;if(e%2!=0)throw new RangeError("Buffer size must be a multiple of 16-bits");for(let t=0;tn&&(e+=" ... "),""},a&&(l.prototype[a]=l.prototype.inspect),l.prototype.compare=function(e,t,n,r,o){if(G(e,Uint8Array)&&(e=l.from(e,e.offset,e.byteLength)),!l.isBuffer(e))throw new TypeError('The "target" argument must be one of type Buffer or Uint8Array. Received type '+typeof e);if(void 0===t&&(t=0),void 0===n&&(n=e?e.length:0),void 0===r&&(r=0),void 0===o&&(o=this.length),t<0||n>e.length||r<0||o>this.length)throw new RangeError("out of range index");if(r>=o&&t>=n)return 0;if(r>=o)return-1;if(t>=n)return 1;if(this===e)return 0;let a=(o>>>=0)-(r>>>=0),i=(n>>>=0)-(t>>>=0);const s=Math.min(a,i),u=this.slice(r,o),c=e.slice(t,n);for(let e=0;e>>=0,isFinite(n)?(n>>>=0,void 0===r&&(r="utf8")):(r=n,n=void 0)}const o=this.length-t;if((void 0===n||n>o)&&(n=o),e.length>0&&(n<0||t<0)||t>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");let a=!1;for(;;)switch(r){case"hex":return w(this,e,t,n);case"utf8":case"utf-8":return E(this,e,t,n);case"ascii":case"latin1":case"binary":return x(this,e,t,n);case"base64":return _(this,e,t,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return S(this,e,t,n);default:if(a)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),a=!0}},l.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};const k=4096;function O(e,t,n){let r="";n=Math.min(e.length,n);for(let o=t;or)&&(n=r);let o="";for(let r=t;rn)throw new RangeError("Trying to access beyond buffer length")}function P(e,t,n,r,o,a){if(!l.isBuffer(e))throw new TypeError('"buffer" argument must be a Buffer instance');if(t>o||te.length)throw new RangeError("Index out of range")}function R(e,t,n,r,o){q(t,r,o,e,n,7);let a=Number(t&BigInt(4294967295));e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a,a>>=8,e[n++]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i,i>>=8,e[n++]=i,n}function M(e,t,n,r,o){q(t,r,o,e,n,7);let a=Number(t&BigInt(4294967295));e[n+7]=a,a>>=8,e[n+6]=a,a>>=8,e[n+5]=a,a>>=8,e[n+4]=a;let i=Number(t>>BigInt(32)&BigInt(4294967295));return e[n+3]=i,i>>=8,e[n+2]=i,i>>=8,e[n+1]=i,i>>=8,e[n]=i,n+8}function D(e,t,n,r,o,a){if(n+r>e.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function L(e,t,n,r,a){return t=+t,n>>>=0,a||D(e,0,n,4),o.write(e,t,n,r,23,4),n+4}function B(e,t,n,r,a){return t=+t,n>>>=0,a||D(e,0,n,8),o.write(e,t,n,r,52,8),n+8}l.prototype.slice=function(e,t){const n=this.length;(e=~~e)<0?(e+=n)<0&&(e=0):e>n&&(e=n),(t=void 0===t?n:~~t)<0?(t+=n)<0&&(t=0):t>n&&(t=n),t>>=0,t>>>=0,n||N(e,t,this.length);let r=this[e],o=1,a=0;for(;++a>>=0,t>>>=0,n||N(e,t,this.length);let r=this[e+--t],o=1;for(;t>0&&(o*=256);)r+=this[e+--t]*o;return r},l.prototype.readUint8=l.prototype.readUInt8=function(e,t){return e>>>=0,t||N(e,1,this.length),this[e]},l.prototype.readUint16LE=l.prototype.readUInt16LE=function(e,t){return e>>>=0,t||N(e,2,this.length),this[e]|this[e+1]<<8},l.prototype.readUint16BE=l.prototype.readUInt16BE=function(e,t){return e>>>=0,t||N(e,2,this.length),this[e]<<8|this[e+1]},l.prototype.readUint32LE=l.prototype.readUInt32LE=function(e,t){return e>>>=0,t||N(e,4,this.length),(this[e]|this[e+1]<<8|this[e+2]<<16)+16777216*this[e+3]},l.prototype.readUint32BE=l.prototype.readUInt32BE=function(e,t){return e>>>=0,t||N(e,4,this.length),16777216*this[e]+(this[e+1]<<16|this[e+2]<<8|this[e+3])},l.prototype.readBigUInt64LE=Q((function(e){$(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||V(e,this.length-8);const r=t+256*this[++e]+65536*this[++e]+this[++e]*2**24,o=this[++e]+256*this[++e]+65536*this[++e]+n*2**24;return BigInt(r)+(BigInt(o)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||V(e,this.length-8);const r=t*2**24+65536*this[++e]+256*this[++e]+this[++e],o=this[++e]*2**24+65536*this[++e]+256*this[++e]+n;return(BigInt(r)<>>=0,t>>>=0,n||N(e,t,this.length);let r=this[e],o=1,a=0;for(;++a=o&&(r-=Math.pow(2,8*t)),r},l.prototype.readIntBE=function(e,t,n){e>>>=0,t>>>=0,n||N(e,t,this.length);let r=t,o=1,a=this[e+--r];for(;r>0&&(o*=256);)a+=this[e+--r]*o;return o*=128,a>=o&&(a-=Math.pow(2,8*t)),a},l.prototype.readInt8=function(e,t){return e>>>=0,t||N(e,1,this.length),128&this[e]?-1*(255-this[e]+1):this[e]},l.prototype.readInt16LE=function(e,t){e>>>=0,t||N(e,2,this.length);const n=this[e]|this[e+1]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt16BE=function(e,t){e>>>=0,t||N(e,2,this.length);const n=this[e+1]|this[e]<<8;return 32768&n?4294901760|n:n},l.prototype.readInt32LE=function(e,t){return e>>>=0,t||N(e,4,this.length),this[e]|this[e+1]<<8|this[e+2]<<16|this[e+3]<<24},l.prototype.readInt32BE=function(e,t){return e>>>=0,t||N(e,4,this.length),this[e]<<24|this[e+1]<<16|this[e+2]<<8|this[e+3]},l.prototype.readBigInt64LE=Q((function(e){$(e>>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||V(e,this.length-8);const r=this[e+4]+256*this[e+5]+65536*this[e+6]+(n<<24);return(BigInt(r)<>>=0,"offset");const t=this[e],n=this[e+7];void 0!==t&&void 0!==n||V(e,this.length-8);const r=(t<<24)+65536*this[++e]+256*this[++e]+this[++e];return(BigInt(r)<>>=0,t||N(e,4,this.length),o.read(this,e,!0,23,4)},l.prototype.readFloatBE=function(e,t){return e>>>=0,t||N(e,4,this.length),o.read(this,e,!1,23,4)},l.prototype.readDoubleLE=function(e,t){return e>>>=0,t||N(e,8,this.length),o.read(this,e,!0,52,8)},l.prototype.readDoubleBE=function(e,t){return e>>>=0,t||N(e,8,this.length),o.read(this,e,!1,52,8)},l.prototype.writeUintLE=l.prototype.writeUIntLE=function(e,t,n,r){if(e=+e,t>>>=0,n>>>=0,!r){P(this,e,t,n,Math.pow(2,8*n)-1,0)}let o=1,a=0;for(this[t]=255&e;++a>>=0,n>>>=0,!r){P(this,e,t,n,Math.pow(2,8*n)-1,0)}let o=n-1,a=1;for(this[t+o]=255&e;--o>=0&&(a*=256);)this[t+o]=e/a&255;return t+n},l.prototype.writeUint8=l.prototype.writeUInt8=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,1,255,0),this[t]=255&e,t+1},l.prototype.writeUint16LE=l.prototype.writeUInt16LE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,2,65535,0),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeUint16BE=l.prototype.writeUInt16BE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,2,65535,0),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeUint32LE=l.prototype.writeUInt32LE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,4,4294967295,0),this[t+3]=e>>>24,this[t+2]=e>>>16,this[t+1]=e>>>8,this[t]=255&e,t+4},l.prototype.writeUint32BE=l.prototype.writeUInt32BE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,4,4294967295,0),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigUInt64LE=Q((function(e,t=0){return R(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeBigUInt64BE=Q((function(e,t=0){return M(this,e,t,BigInt(0),BigInt("0xffffffffffffffff"))})),l.prototype.writeIntLE=function(e,t,n,r){if(e=+e,t>>>=0,!r){const r=Math.pow(2,8*n-1);P(this,e,t,n,r-1,-r)}let o=0,a=1,i=0;for(this[t]=255&e;++o>0)-i&255;return t+n},l.prototype.writeIntBE=function(e,t,n,r){if(e=+e,t>>>=0,!r){const r=Math.pow(2,8*n-1);P(this,e,t,n,r-1,-r)}let o=n-1,a=1,i=0;for(this[t+o]=255&e;--o>=0&&(a*=256);)e<0&&0===i&&0!==this[t+o+1]&&(i=1),this[t+o]=(e/a>>0)-i&255;return t+n},l.prototype.writeInt8=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,1,127,-128),e<0&&(e=255+e+1),this[t]=255&e,t+1},l.prototype.writeInt16LE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,2,32767,-32768),this[t]=255&e,this[t+1]=e>>>8,t+2},l.prototype.writeInt16BE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,2,32767,-32768),this[t]=e>>>8,this[t+1]=255&e,t+2},l.prototype.writeInt32LE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,4,2147483647,-2147483648),this[t]=255&e,this[t+1]=e>>>8,this[t+2]=e>>>16,this[t+3]=e>>>24,t+4},l.prototype.writeInt32BE=function(e,t,n){return e=+e,t>>>=0,n||P(this,e,t,4,2147483647,-2147483648),e<0&&(e=4294967295+e+1),this[t]=e>>>24,this[t+1]=e>>>16,this[t+2]=e>>>8,this[t+3]=255&e,t+4},l.prototype.writeBigInt64LE=Q((function(e,t=0){return R(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeBigInt64BE=Q((function(e,t=0){return M(this,e,t,-BigInt("0x8000000000000000"),BigInt("0x7fffffffffffffff"))})),l.prototype.writeFloatLE=function(e,t,n){return L(this,e,t,!0,n)},l.prototype.writeFloatBE=function(e,t,n){return L(this,e,t,!1,n)},l.prototype.writeDoubleLE=function(e,t,n){return B(this,e,t,!0,n)},l.prototype.writeDoubleBE=function(e,t,n){return B(this,e,t,!1,n)},l.prototype.copy=function(e,t,n,r){if(!l.isBuffer(e))throw new TypeError("argument should be a Buffer");if(n||(n=0),r||0===r||(r=this.length),t>=e.length&&(t=e.length),t||(t=0),r>0&&r=this.length)throw new RangeError("Index out of range");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),e.length-t>>=0,n=void 0===n?this.length:n>>>0,e||(e=0),"number"==typeof e)for(o=t;o=r+4;n-=3)t=`_${e.slice(n-3,n)}${t}`;return`${e.slice(0,n)}${t}`}function q(e,t,n,r,o,a){if(e>n||e3?0===t||t===BigInt(0)?`>= 0${r} and < 2${r} ** ${8*(a+1)}${r}`:`>= -(2${r} ** ${8*(a+1)-1}${r}) and < 2 ** ${8*(a+1)-1}${r}`:`>= ${t}${r} and <= ${n}${r}`,new F.ERR_OUT_OF_RANGE("value",o,e)}!function(e,t,n){$(t,"offset"),void 0!==e[t]&&void 0!==e[t+n]||V(t,e.length-(n+1))}(r,o,a)}function $(e,t){if("number"!=typeof e)throw new F.ERR_INVALID_ARG_TYPE(t,"number",e)}function V(e,t,n){if(Math.floor(e)!==e)throw $(e,n),new F.ERR_OUT_OF_RANGE(n||"offset","an integer",e);if(t<0)throw new F.ERR_BUFFER_OUT_OF_BOUNDS;throw new F.ERR_OUT_OF_RANGE(n||"offset",`>= ${n?1:0} and <= ${t}`,e)}z("ERR_BUFFER_OUT_OF_BOUNDS",(function(e){return e?`${e} is outside of buffer bounds`:"Attempt to access memory outside buffer bounds"}),RangeError),z("ERR_INVALID_ARG_TYPE",(function(e,t){return`The "${e}" argument must be of type number. Received type ${typeof t}`}),TypeError),z("ERR_OUT_OF_RANGE",(function(e,t,n){let r=`The value of "${e}" is out of range.`,o=n;return Number.isInteger(n)&&Math.abs(n)>2**32?o=U(String(n)):"bigint"==typeof n&&(o=String(n),(n>BigInt(2)**BigInt(32)||n<-(BigInt(2)**BigInt(32)))&&(o=U(o)),o+="n"),r+=` It must be ${t}. Received ${o}`,r}),RangeError);const W=/[^+/0-9A-Za-z-_]/g;function H(e,t){let n;t=t||1/0;const r=e.length;let o=null;const a=[];for(let i=0;i55295&&n<57344){if(!o){if(n>56319){(t-=3)>-1&&a.push(239,191,189);continue}if(i+1===r){(t-=3)>-1&&a.push(239,191,189);continue}o=n;continue}if(n<56320){(t-=3)>-1&&a.push(239,191,189),o=n;continue}n=65536+(o-55296<<10|n-56320)}else o&&(t-=3)>-1&&a.push(239,191,189);if(o=null,n<128){if((t-=1)<0)break;a.push(n)}else if(n<2048){if((t-=2)<0)break;a.push(n>>6|192,63&n|128)}else if(n<65536){if((t-=3)<0)break;a.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((t-=4)<0)break;a.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return a}function J(e){return r.toByteArray(function(e){if((e=(e=e.split("=")[0]).trim().replace(W,"")).length<2)return"";for(;e.length%4!=0;)e+="=";return e}(e))}function K(e,t,n,r){let o;for(o=0;o=t.length||o>=e.length);++o)t[o+n]=e[o];return o}function G(e,t){return e instanceof t||null!=e&&null!=e.constructor&&null!=e.constructor.name&&e.constructor.name===t.name}function Z(e){return e!=e}const Y=function(){const e="0123456789abcdef",t=new Array(256);for(let n=0;n<16;++n){const r=16*n;for(let o=0;o<16;++o)t[r+o]=e[n]+e[o]}return t}();function Q(e){return"undefined"==typeof BigInt?X:e}function X(){throw new Error("BigInt not supported")}},21924:(e,t,n)=>{"use strict";var r=n(40210),o=n(55559),a=o(r("String.prototype.indexOf"));e.exports=function(e,t){var n=r(e,!!t);return"function"==typeof n&&a(e,".prototype.")>-1?o(n):n}},55559:(e,t,n)=>{"use strict";var r=n(58612),o=n(40210),a=o("%Function.prototype.apply%"),i=o("%Function.prototype.call%"),s=o("%Reflect.apply%",!0)||r.call(i,a),l=o("%Object.getOwnPropertyDescriptor%",!0),u=o("%Object.defineProperty%",!0),c=o("%Math.max%");if(u)try{u({},"a",{value:1})}catch(e){u=null}e.exports=function(e){var t=s(r,i,arguments);l&&u&&(l(t,"length").configurable&&u(t,"length",{value:1+c(0,e.length-(arguments.length-1))}));return t};var p=function(){return s(r,a,arguments)};u?u(e.exports,"apply",{value:p}):e.exports.apply=p},94184:(e,t)=>{var n;!function(){"use strict";var r={}.hasOwnProperty;function o(){for(var e=[],t=0;t{"use strict";t.parse=function(e,t){if("string"!=typeof e)throw new TypeError("argument str must be a string");var n={},r=(t||{}).decode||o,a=0;for(;a{"use strict";var r=n(11742),o={"text/plain":"Text","text/html":"Url",default:"Text"};e.exports=function(e,t){var n,a,i,s,l,u,c=!1;t||(t={}),n=t.debug||!1;try{if(i=r(),s=document.createRange(),l=document.getSelection(),(u=document.createElement("span")).textContent=e,u.ariaHidden="true",u.style.all="unset",u.style.position="fixed",u.style.top=0,u.style.clip="rect(0, 0, 0, 0)",u.style.whiteSpace="pre",u.style.webkitUserSelect="text",u.style.MozUserSelect="text",u.style.msUserSelect="text",u.style.userSelect="text",u.addEventListener("copy",(function(r){if(r.stopPropagation(),t.format)if(r.preventDefault(),void 0===r.clipboardData){n&&console.warn("unable to use e.clipboardData"),n&&console.warn("trying IE specific stuff"),window.clipboardData.clearData();var a=o[t.format]||o.default;window.clipboardData.setData(a,e)}else r.clipboardData.clearData(),r.clipboardData.setData(t.format,e);t.onCopy&&(r.preventDefault(),t.onCopy(r.clipboardData))})),document.body.appendChild(u),s.selectNodeContents(u),l.addRange(s),!document.execCommand("copy"))throw new Error("copy command was unsuccessful");c=!0}catch(r){n&&console.error("unable to copy using execCommand: ",r),n&&console.warn("trying IE specific stuff");try{window.clipboardData.setData(t.format||"text",e),t.onCopy&&t.onCopy(window.clipboardData),c=!0}catch(r){n&&console.error("unable to copy using clipboardData: ",r),n&&console.error("falling back to prompt"),a=function(e){var t=(/mac os x/i.test(navigator.userAgent)?"⌘":"Ctrl")+"+C";return e.replace(/#{\s*key\s*}/g,t)}("message"in t?t.message:"Copy to clipboard: #{key}, Enter"),window.prompt(a,e)}}finally{l&&("function"==typeof l.removeRange?l.removeRange(s):l.removeAllRanges()),u&&document.body.removeChild(u),i()}return c}},90093:(e,t,n)=>{var r=n(28196);e.exports=r},3688:(e,t,n)=>{var r=n(11955);e.exports=r},83838:(e,t,n)=>{var r=n(46279);e.exports=r},15684:(e,t,n)=>{var r=n(19373);e.exports=r},81331:(e,t,n)=>{var r=n(52759);e.exports=r},65362:(e,t,n)=>{var r=n(63383);e.exports=r},91254:(e,t,n)=>{var r=n(57396);e.exports=r},43536:(e,t,n)=>{var r=n(41910);e.exports=r},37331:(e,t,n)=>{var r=n(79427);e.exports=r},68522:(e,t,n)=>{var r=n(62857);e.exports=r},73151:(e,t,n)=>{var r=n(9534);e.exports=r},45012:(e,t,n)=>{var r=n(23059);e.exports=r},80281:(e,t,n)=>{var r=n(92547);n(97522),n(43975),n(45414),e.exports=r},40031:(e,t,n)=>{var r=n(46509);e.exports=r},17487:(e,t,n)=>{var r=n(35774);e.exports=r},54493:(e,t,n)=>{n(77971),n(53242);var r=n(54058);e.exports=r.Array.from},24034:(e,t,n)=>{n(92737);var r=n(54058);e.exports=r.Array.isArray},15367:(e,t,n)=>{n(85906);var r=n(35703);e.exports=r("Array").concat},12710:(e,t,n)=>{n(66274),n(55967);var r=n(35703);e.exports=r("Array").entries},51459:(e,t,n)=>{n(48851);var r=n(35703);e.exports=r("Array").every},6172:(e,t,n)=>{n(80290);var r=n(35703);e.exports=r("Array").fill},62383:(e,t,n)=>{n(21501);var r=n(35703);e.exports=r("Array").filter},60009:(e,t,n)=>{n(44929);var r=n(35703);e.exports=r("Array").findIndex},17671:(e,t,n)=>{n(80833);var r=n(35703);e.exports=r("Array").find},99324:(e,t,n)=>{n(2437);var r=n(35703);e.exports=r("Array").forEach},80991:(e,t,n)=>{n(97690);var r=n(35703);e.exports=r("Array").includes},8700:(e,t,n)=>{n(99076);var r=n(35703);e.exports=r("Array").indexOf},95909:(e,t,n)=>{n(66274),n(55967);var r=n(35703);e.exports=r("Array").keys},6442:(e,t,n)=>{n(75915);var r=n(35703);e.exports=r("Array").lastIndexOf},23866:(e,t,n)=>{n(68787);var r=n(35703);e.exports=r("Array").map},9896:(e,t,n)=>{n(48528);var r=n(35703);e.exports=r("Array").push},52999:(e,t,n)=>{n(81876);var r=n(35703);e.exports=r("Array").reduce},24900:(e,t,n)=>{n(60186);var r=n(35703);e.exports=r("Array").slice},3824:(e,t,n)=>{n(36026);var r=n(35703);e.exports=r("Array").some},2948:(e,t,n)=>{n(4115);var r=n(35703);e.exports=r("Array").sort},78209:(e,t,n)=>{n(98611);var r=n(35703);e.exports=r("Array").splice},14423:(e,t,n)=>{n(66274),n(55967);var r=n(35703);e.exports=r("Array").values},81103:(e,t,n)=>{n(95160);var r=n(54058);e.exports=r.Date.now},27700:(e,t,n)=>{n(73381);var r=n(35703);e.exports=r("Function").bind},16246:(e,t,n)=>{var r=n(7046),o=n(27700),a=Function.prototype;e.exports=function(e){var t=e.bind;return e===a||r(a,e)&&t===a.bind?o:t}},56043:(e,t,n)=>{var r=n(7046),o=n(15367),a=Array.prototype;e.exports=function(e){var t=e.concat;return e===a||r(a,e)&&t===a.concat?o:t}},13160:(e,t,n)=>{var r=n(7046),o=n(51459),a=Array.prototype;e.exports=function(e){var t=e.every;return e===a||r(a,e)&&t===a.every?o:t}},80446:(e,t,n)=>{var r=n(7046),o=n(6172),a=Array.prototype;e.exports=function(e){var t=e.fill;return e===a||r(a,e)&&t===a.fill?o:t}},2480:(e,t,n)=>{var r=n(7046),o=n(62383),a=Array.prototype;e.exports=function(e){var t=e.filter;return e===a||r(a,e)&&t===a.filter?o:t}},7147:(e,t,n)=>{var r=n(7046),o=n(60009),a=Array.prototype;e.exports=function(e){var t=e.findIndex;return e===a||r(a,e)&&t===a.findIndex?o:t}},32236:(e,t,n)=>{var r=n(7046),o=n(17671),a=Array.prototype;e.exports=function(e){var t=e.find;return e===a||r(a,e)&&t===a.find?o:t}},58557:(e,t,n)=>{var r=n(7046),o=n(80991),a=n(21631),i=Array.prototype,s=String.prototype;e.exports=function(e){var t=e.includes;return e===i||r(i,e)&&t===i.includes?o:"string"==typeof e||e===s||r(s,e)&&t===s.includes?a:t}},34570:(e,t,n)=>{var r=n(7046),o=n(8700),a=Array.prototype;e.exports=function(e){var t=e.indexOf;return e===a||r(a,e)&&t===a.indexOf?o:t}},57564:(e,t,n)=>{var r=n(7046),o=n(6442),a=Array.prototype;e.exports=function(e){var t=e.lastIndexOf;return e===a||r(a,e)&&t===a.lastIndexOf?o:t}},88287:(e,t,n)=>{var r=n(7046),o=n(23866),a=Array.prototype;e.exports=function(e){var t=e.map;return e===a||r(a,e)&&t===a.map?o:t}},93993:(e,t,n)=>{var r=n(7046),o=n(9896),a=Array.prototype;e.exports=function(e){var t=e.push;return e===a||r(a,e)&&t===a.push?o:t}},68025:(e,t,n)=>{var r=n(7046),o=n(52999),a=Array.prototype;e.exports=function(e){var t=e.reduce;return e===a||r(a,e)&&t===a.reduce?o:t}},59257:(e,t,n)=>{var r=n(7046),o=n(80454),a=String.prototype;e.exports=function(e){var t=e.repeat;return"string"==typeof e||e===a||r(a,e)&&t===a.repeat?o:t}},69601:(e,t,n)=>{var r=n(7046),o=n(24900),a=Array.prototype;e.exports=function(e){var t=e.slice;return e===a||r(a,e)&&t===a.slice?o:t}},28299:(e,t,n)=>{var r=n(7046),o=n(3824),a=Array.prototype;e.exports=function(e){var t=e.some;return e===a||r(a,e)&&t===a.some?o:t}},69355:(e,t,n)=>{var r=n(7046),o=n(2948),a=Array.prototype;e.exports=function(e){var t=e.sort;return e===a||r(a,e)&&t===a.sort?o:t}},18339:(e,t,n)=>{var r=n(7046),o=n(78209),a=Array.prototype;e.exports=function(e){var t=e.splice;return e===a||r(a,e)&&t===a.splice?o:t}},71611:(e,t,n)=>{var r=n(7046),o=n(3269),a=String.prototype;e.exports=function(e){var t=e.startsWith;return"string"==typeof e||e===a||r(a,e)&&t===a.startsWith?o:t}},62774:(e,t,n)=>{var r=n(7046),o=n(13348),a=String.prototype;e.exports=function(e){var t=e.trim;return"string"==typeof e||e===a||r(a,e)&&t===a.trim?o:t}},84426:(e,t,n)=>{n(32619);var r=n(54058),o=n(79730);r.JSON||(r.JSON={stringify:JSON.stringify}),e.exports=function(e,t,n){return o(r.JSON.stringify,null,arguments)}},91018:(e,t,n)=>{n(66274),n(37501),n(55967),n(77971);var r=n(54058);e.exports=r.Map},45999:(e,t,n)=>{n(49221);var r=n(54058);e.exports=r.Object.assign},7702:(e,t,n)=>{n(74979);var r=n(54058).Object,o=e.exports=function(e,t){return r.defineProperties(e,t)};r.defineProperties.sham&&(o.sham=!0)},48171:(e,t,n)=>{n(86450);var r=n(54058).Object,o=e.exports=function(e,t,n){return r.defineProperty(e,t,n)};r.defineProperty.sham&&(o.sham=!0)},286:(e,t,n)=>{n(46924);var r=n(54058).Object,o=e.exports=function(e,t){return r.getOwnPropertyDescriptor(e,t)};r.getOwnPropertyDescriptor.sham&&(o.sham=!0)},92766:(e,t,n)=>{n(88482);var r=n(54058);e.exports=r.Object.getOwnPropertyDescriptors},30498:(e,t,n)=>{n(35824);var r=n(54058);e.exports=r.Object.getOwnPropertySymbols},48494:(e,t,n)=>{n(21724);var r=n(54058);e.exports=r.Object.keys},98430:(e,t,n)=>{n(26614);var r=n(54058);e.exports=r.Object.values},52956:(e,t,n)=>{n(47627),n(66274),n(55967),n(98881),n(4560),n(91302),n(44349),n(77971);var r=n(54058);e.exports=r.Promise},21631:(e,t,n)=>{n(11035);var r=n(35703);e.exports=r("String").includes},80454:(e,t,n)=>{n(60986);var r=n(35703);e.exports=r("String").repeat},3269:(e,t,n)=>{n(94761);var r=n(35703);e.exports=r("String").startsWith},13348:(e,t,n)=>{n(57398);var r=n(35703);e.exports=r("String").trim},57473:(e,t,n)=>{n(85906),n(55967),n(35824),n(8555),n(52615),n(21732),n(35903),n(1825),n(28394),n(45915),n(61766),n(62737),n(89911),n(74315),n(63131),n(64714),n(70659),n(69120),n(79413),n(1502);var r=n(54058);e.exports=r.Symbol},24227:(e,t,n)=>{n(66274),n(55967),n(77971),n(1825);var r=n(11477);e.exports=r.f("iterator")},62978:(e,t,n)=>{n(18084),n(63131);var r=n(11477);e.exports=r.f("toPrimitive")},14122:(e,t,n)=>{e.exports=n(89097)},44442:(e,t,n)=>{e.exports=n(51675)},57152:(e,t,n)=>{e.exports=n(82507)},69447:(e,t,n)=>{e.exports=n(628)},1449:(e,t,n)=>{e.exports=n(34501)},60269:(e,t,n)=>{e.exports=n(76936)},70573:(e,t,n)=>{e.exports=n(18180)},73685:(e,t,n)=>{e.exports=n(80621)},27533:(e,t,n)=>{e.exports=n(22948)},39057:(e,t,n)=>{e.exports=n(82108)},84710:(e,t,n)=>{e.exports=n(14058)},93799:(e,t,n)=>{e.exports=n(92093)},86600:(e,t,n)=>{e.exports=n(52201)},9759:(e,t,n)=>{e.exports=n(27398)},71384:(e,t,n)=>{e.exports=n(26189)},89097:(e,t,n)=>{var r=n(90093);e.exports=r},51675:(e,t,n)=>{var r=n(3688);e.exports=r},82507:(e,t,n)=>{var r=n(83838);e.exports=r},628:(e,t,n)=>{var r=n(15684);e.exports=r},34501:(e,t,n)=>{var r=n(81331);e.exports=r},76936:(e,t,n)=>{var r=n(65362);e.exports=r},18180:(e,t,n)=>{var r=n(91254);e.exports=r},80621:(e,t,n)=>{var r=n(43536);e.exports=r},22948:(e,t,n)=>{var r=n(37331);e.exports=r},82108:(e,t,n)=>{var r=n(68522);e.exports=r},14058:(e,t,n)=>{var r=n(73151);e.exports=r},92093:(e,t,n)=>{var r=n(45012);e.exports=r},52201:(e,t,n)=>{var r=n(80281);n(28783),n(97618),n(6989),n(65799),n(46774),n(22731),n(85605),n(31943),n(80620),n(36172),e.exports=r},27398:(e,t,n)=>{var r=n(40031);e.exports=r},26189:(e,t,n)=>{var r=n(17487);e.exports=r},24883:(e,t,n)=>{var r=n(57475),o=n(69826),a=TypeError;e.exports=function(e){if(r(e))return e;throw a(o(e)+" is not a function")}},174:(e,t,n)=>{var r=n(24284),o=n(69826),a=TypeError;e.exports=function(e){if(r(e))return e;throw a(o(e)+" is not a constructor")}},11851:(e,t,n)=>{var r=n(57475),o=String,a=TypeError;e.exports=function(e){if("object"==typeof e||r(e))return e;throw a("Can't set "+o(e)+" as a prototype")}},18479:e=>{e.exports=function(){}},5743:(e,t,n)=>{var r=n(7046),o=TypeError;e.exports=function(e,t){if(r(t,e))return e;throw o("Incorrect invocation")}},96059:(e,t,n)=>{var r=n(10941),o=String,a=TypeError;e.exports=function(e){if(r(e))return e;throw a(o(e)+" is not an object")}},97135:(e,t,n)=>{var r=n(95981);e.exports=r((function(){if("function"==typeof ArrayBuffer){var e=new ArrayBuffer(8);Object.isExtensible(e)&&Object.defineProperty(e,"a",{value:8})}}))},91860:(e,t,n)=>{"use strict";var r=n(89678),o=n(59413),a=n(10623);e.exports=function(e){for(var t=r(this),n=a(t),i=arguments.length,s=o(i>1?arguments[1]:void 0,n),l=i>2?arguments[2]:void 0,u=void 0===l?n:o(l,n);u>s;)t[s++]=e;return t}},56837:(e,t,n)=>{"use strict";var r=n(3610).forEach,o=n(34194)("forEach");e.exports=o?[].forEach:function(e){return r(this,e,arguments.length>1?arguments[1]:void 0)}},11354:(e,t,n)=>{"use strict";var r=n(86843),o=n(78834),a=n(89678),i=n(75196),s=n(6782),l=n(24284),u=n(10623),c=n(55449),p=n(53476),f=n(22902),h=Array;e.exports=function(e){var t=a(e),n=l(this),d=arguments.length,m=d>1?arguments[1]:void 0,g=void 0!==m;g&&(m=r(m,d>2?arguments[2]:void 0));var y,v,b,w,E,x,_=f(t),S=0;if(!_||this===h&&s(_))for(y=u(t),v=n?new this(y):h(y);y>S;S++)x=g?m(t[S],S):t[S],c(v,S,x);else for(E=(w=p(t,_)).next,v=n?new this:[];!(b=o(E,w)).done;S++)x=g?i(w,m,[b.value,S],!0):b.value,c(v,S,x);return v.length=S,v}},31692:(e,t,n)=>{var r=n(74529),o=n(59413),a=n(10623),i=function(e){return function(t,n,i){var s,l=r(t),u=a(l),c=o(i,u);if(e&&n!=n){for(;u>c;)if((s=l[c++])!=s)return!0}else for(;u>c;c++)if((e||c in l)&&l[c]===n)return e||c||0;return!e&&-1}};e.exports={includes:i(!0),indexOf:i(!1)}},3610:(e,t,n)=>{var r=n(86843),o=n(95329),a=n(37026),i=n(89678),s=n(10623),l=n(64692),u=o([].push),c=function(e){var t=1==e,n=2==e,o=3==e,c=4==e,p=6==e,f=7==e,h=5==e||p;return function(d,m,g,y){for(var v,b,w=i(d),E=a(w),x=r(m,g),_=s(E),S=0,A=y||l,C=t?A(d,_):n||f?A(d,0):void 0;_>S;S++)if((h||S in E)&&(b=x(v=E[S],S,w),e))if(t)C[S]=b;else if(b)switch(e){case 3:return!0;case 5:return v;case 6:return S;case 2:u(C,v)}else switch(e){case 4:return!1;case 7:u(C,v)}return p?-1:o||c?c:C}};e.exports={forEach:c(0),map:c(1),filter:c(2),some:c(3),every:c(4),find:c(5),findIndex:c(6),filterReject:c(7)}},67145:(e,t,n)=>{"use strict";var r=n(79730),o=n(74529),a=n(62435),i=n(10623),s=n(34194),l=Math.min,u=[].lastIndexOf,c=!!u&&1/[1].lastIndexOf(1,-0)<0,p=s("lastIndexOf"),f=c||!p;e.exports=f?function(e){if(c)return r(u,this,arguments)||0;var t=o(this),n=i(t),s=n-1;for(arguments.length>1&&(s=l(s,a(arguments[1]))),s<0&&(s=n+s);s>=0;s--)if(s in t&&t[s]===e)return s||0;return-1}:u},50568:(e,t,n)=>{var r=n(95981),o=n(99813),a=n(53385),i=o("species");e.exports=function(e){return a>=51||!r((function(){var t=[];return(t.constructor={})[i]=function(){return{foo:1}},1!==t[e](Boolean).foo}))}},34194:(e,t,n)=>{"use strict";var r=n(95981);e.exports=function(e,t){var n=[][e];return!!n&&r((function(){n.call(null,t||function(){return 1},1)}))}},46499:(e,t,n)=>{var r=n(24883),o=n(89678),a=n(37026),i=n(10623),s=TypeError,l=function(e){return function(t,n,l,u){r(n);var c=o(t),p=a(c),f=i(c),h=e?f-1:0,d=e?-1:1;if(l<2)for(;;){if(h in p){u=p[h],h+=d;break}if(h+=d,e?h<0:f<=h)throw s("Reduce of empty array with no initial value")}for(;e?h>=0:f>h;h+=d)h in p&&(u=n(u,p[h],h,c));return u}};e.exports={left:l(!1),right:l(!0)}},89779:(e,t,n)=>{"use strict";var r=n(55746),o=n(1052),a=TypeError,i=Object.getOwnPropertyDescriptor,s=r&&!function(){if(void 0!==this)return!0;try{Object.defineProperty([],"length",{writable:!1}).length=1}catch(e){return e instanceof TypeError}}();e.exports=s?function(e,t){if(o(e)&&!i(e,"length").writable)throw a("Cannot set read only .length");return e.length=t}:function(e,t){return e.length=t}},15790:(e,t,n)=>{var r=n(59413),o=n(10623),a=n(55449),i=Array,s=Math.max;e.exports=function(e,t,n){for(var l=o(e),u=r(t,l),c=r(void 0===n?l:n,l),p=i(s(c-u,0)),f=0;u{var r=n(95329);e.exports=r([].slice)},61388:(e,t,n)=>{var r=n(15790),o=Math.floor,a=function(e,t){var n=e.length,l=o(n/2);return n<8?i(e,t):s(e,a(r(e,0,l),t),a(r(e,l),t),t)},i=function(e,t){for(var n,r,o=e.length,a=1;a0;)e[r]=e[--r];r!==a++&&(e[r]=n)}return e},s=function(e,t,n,r){for(var o=t.length,a=n.length,i=0,s=0;i{var r=n(1052),o=n(24284),a=n(10941),i=n(99813)("species"),s=Array;e.exports=function(e){var t;return r(e)&&(t=e.constructor,(o(t)&&(t===s||r(t.prototype))||a(t)&&null===(t=t[i]))&&(t=void 0)),void 0===t?s:t}},64692:(e,t,n)=>{var r=n(5693);e.exports=function(e,t){return new(r(e))(0===t?0:t)}},75196:(e,t,n)=>{var r=n(96059),o=n(7609);e.exports=function(e,t,n,a){try{return a?t(r(n)[0],n[1]):t(n)}catch(t){o(e,"throw",t)}}},21385:(e,t,n)=>{var r=n(99813)("iterator"),o=!1;try{var a=0,i={next:function(){return{done:!!a++}},return:function(){o=!0}};i[r]=function(){return this},Array.from(i,(function(){throw 2}))}catch(e){}e.exports=function(e,t){if(!t&&!o)return!1;var n=!1;try{var a={};a[r]=function(){return{next:function(){return{done:n=!0}}}},e(a)}catch(e){}return n}},82532:(e,t,n)=>{var r=n(95329),o=r({}.toString),a=r("".slice);e.exports=function(e){return a(o(e),8,-1)}},9697:(e,t,n)=>{var r=n(22885),o=n(57475),a=n(82532),i=n(99813)("toStringTag"),s=Object,l="Arguments"==a(function(){return arguments}());e.exports=r?a:function(e){var t,n,r;return void 0===e?"Undefined":null===e?"Null":"string"==typeof(n=function(e,t){try{return e[t]}catch(e){}}(t=s(e),i))?n:l?a(t):"Object"==(r=a(t))&&o(t.callee)?"Arguments":r}},85616:(e,t,n)=>{"use strict";var r=n(29290),o=n(29202),a=n(94380),i=n(86843),s=n(5743),l=n(82119),u=n(93091),c=n(75105),p=n(23538),f=n(94431),h=n(55746),d=n(21647).fastKey,m=n(45402),g=m.set,y=m.getterFor;e.exports={getConstructor:function(e,t,n,c){var p=e((function(e,o){s(e,f),g(e,{type:t,index:r(null),first:void 0,last:void 0,size:0}),h||(e.size=0),l(o)||u(o,e[c],{that:e,AS_ENTRIES:n})})),f=p.prototype,m=y(t),v=function(e,t,n){var r,o,a=m(e),i=b(e,t);return i?i.value=n:(a.last=i={index:o=d(t,!0),key:t,value:n,previous:r=a.last,next:void 0,removed:!1},a.first||(a.first=i),r&&(r.next=i),h?a.size++:e.size++,"F"!==o&&(a.index[o]=i)),e},b=function(e,t){var n,r=m(e),o=d(t);if("F"!==o)return r.index[o];for(n=r.first;n;n=n.next)if(n.key==t)return n};return a(f,{clear:function(){for(var e=m(this),t=e.index,n=e.first;n;)n.removed=!0,n.previous&&(n.previous=n.previous.next=void 0),delete t[n.index],n=n.next;e.first=e.last=void 0,h?e.size=0:this.size=0},delete:function(e){var t=this,n=m(t),r=b(t,e);if(r){var o=r.next,a=r.previous;delete n.index[r.index],r.removed=!0,a&&(a.next=o),o&&(o.previous=a),n.first==r&&(n.first=o),n.last==r&&(n.last=a),h?n.size--:t.size--}return!!r},forEach:function(e){for(var t,n=m(this),r=i(e,arguments.length>1?arguments[1]:void 0);t=t?t.next:n.first;)for(r(t.value,t.key,this);t&&t.removed;)t=t.previous},has:function(e){return!!b(this,e)}}),a(f,n?{get:function(e){var t=b(this,e);return t&&t.value},set:function(e,t){return v(this,0===e?0:e,t)}}:{add:function(e){return v(this,e=0===e?0:e,e)}}),h&&o(f,"size",{configurable:!0,get:function(){return m(this).size}}),p},setStrong:function(e,t,n){var r=t+" Iterator",o=y(t),a=y(r);c(e,t,(function(e,t){g(this,{type:r,target:e,state:o(e),kind:t,last:void 0})}),(function(){for(var e=a(this),t=e.kind,n=e.last;n&&n.removed;)n=n.previous;return e.target&&(e.last=n=n?n.next:e.state.first)?p("keys"==t?n.key:"values"==t?n.value:[n.key,n.value],!1):(e.target=void 0,p(void 0,!0))}),n?"entries":"values",!n,!0),f(t)}}},24683:(e,t,n)=>{"use strict";var r=n(76887),o=n(21899),a=n(21647),i=n(95981),s=n(32029),l=n(93091),u=n(5743),c=n(57475),p=n(10941),f=n(90904),h=n(65988).f,d=n(3610).forEach,m=n(55746),g=n(45402),y=g.set,v=g.getterFor;e.exports=function(e,t,n){var g,b=-1!==e.indexOf("Map"),w=-1!==e.indexOf("Weak"),E=b?"set":"add",x=o[e],_=x&&x.prototype,S={};if(m&&c(x)&&(w||_.forEach&&!i((function(){(new x).entries().next()})))){var A=(g=t((function(t,n){y(u(t,A),{type:e,collection:new x}),null!=n&&l(n,t[E],{that:t,AS_ENTRIES:b})}))).prototype,C=v(e);d(["add","clear","delete","forEach","get","has","set","keys","values","entries"],(function(e){var t="add"==e||"set"==e;!(e in _)||w&&"clear"==e||s(A,e,(function(n,r){var o=C(this).collection;if(!t&&w&&!p(n))return"get"==e&&void 0;var a=o[e](0===n?0:n,r);return t?this:a}))})),w||h(A,"size",{configurable:!0,get:function(){return C(this).collection.size}})}else g=n.getConstructor(t,e,b,E),a.enable();return f(g,e,!1,!0),S[e]=g,r({global:!0,forced:!0},S),w||n.setStrong(g,e,b),g}},23489:(e,t,n)=>{var r=n(90953),o=n(31136),a=n(49677),i=n(65988);e.exports=function(e,t,n){for(var s=o(t),l=i.f,u=a.f,c=0;c{var r=n(99813)("match");e.exports=function(e){var t=/./;try{"/./"[e](t)}catch(n){try{return t[r]=!1,"/./"[e](t)}catch(e){}}return!1}},64160:(e,t,n)=>{var r=n(95981);e.exports=!r((function(){function e(){}return e.prototype.constructor=null,Object.getPrototypeOf(new e)!==e.prototype}))},23538:e=>{e.exports=function(e,t){return{value:e,done:t}}},32029:(e,t,n)=>{var r=n(55746),o=n(65988),a=n(31887);e.exports=r?function(e,t,n){return o.f(e,t,a(1,n))}:function(e,t,n){return e[t]=n,e}},31887:e=>{e.exports=function(e,t){return{enumerable:!(1&e),configurable:!(2&e),writable:!(4&e),value:t}}},55449:(e,t,n)=>{"use strict";var r=n(83894),o=n(65988),a=n(31887);e.exports=function(e,t,n){var i=r(t);i in e?o.f(e,i,a(0,n)):e[i]=n}},29202:(e,t,n)=>{var r=n(65988);e.exports=function(e,t,n){return r.f(e,t,n)}},95929:(e,t,n)=>{var r=n(32029);e.exports=function(e,t,n,o){return o&&o.enumerable?e[t]=n:r(e,t,n),e}},94380:(e,t,n)=>{var r=n(95929);e.exports=function(e,t,n){for(var o in t)n&&n.unsafe&&e[o]?e[o]=t[o]:r(e,o,t[o],n);return e}},75609:(e,t,n)=>{var r=n(21899),o=Object.defineProperty;e.exports=function(e,t){try{o(r,e,{value:t,configurable:!0,writable:!0})}catch(n){r[e]=t}return t}},15863:(e,t,n)=>{"use strict";var r=n(69826),o=TypeError;e.exports=function(e,t){if(!delete e[t])throw o("Cannot delete property "+r(t)+" of "+r(e))}},55746:(e,t,n)=>{var r=n(95981);e.exports=!r((function(){return 7!=Object.defineProperty({},1,{get:function(){return 7}})[1]}))},76616:e=>{var t="object"==typeof document&&document.all,n=void 0===t&&void 0!==t;e.exports={all:t,IS_HTMLDDA:n}},61333:(e,t,n)=>{var r=n(21899),o=n(10941),a=r.document,i=o(a)&&o(a.createElement);e.exports=function(e){return i?a.createElement(e):{}}},66796:e=>{var t=TypeError;e.exports=function(e){if(e>9007199254740991)throw t("Maximum allowed index exceeded");return e}},63281:e=>{e.exports={CSSRuleList:0,CSSStyleDeclaration:0,CSSValueList:0,ClientRectList:0,DOMRectList:0,DOMStringList:0,DOMTokenList:1,DataTransferItemList:0,FileList:0,HTMLAllCollection:0,HTMLCollection:0,HTMLFormElement:0,HTMLSelectElement:0,MediaList:0,MimeTypeArray:0,NamedNodeMap:0,NodeList:1,PaintRequestList:0,Plugin:0,PluginArray:0,SVGLengthList:0,SVGNumberList:0,SVGPathSegList:0,SVGPointList:0,SVGStringList:0,SVGTransformList:0,SourceBufferList:0,StyleSheetList:0,TextTrackCueList:0,TextTrackList:0,TouchList:0}},34342:(e,t,n)=>{var r=n(2861).match(/firefox\/(\d+)/i);e.exports=!!r&&+r[1]},23321:(e,t,n)=>{var r=n(48501),o=n(6049);e.exports=!r&&!o&&"object"==typeof window&&"object"==typeof document},56491:e=>{e.exports="function"==typeof Bun&&Bun&&"string"==typeof Bun.version},48501:e=>{e.exports="object"==typeof Deno&&Deno&&"object"==typeof Deno.version},81046:(e,t,n)=>{var r=n(2861);e.exports=/MSIE|Trident/.test(r)},4470:(e,t,n)=>{var r=n(2861);e.exports=/ipad|iphone|ipod/i.test(r)&&"undefined"!=typeof Pebble},22749:(e,t,n)=>{var r=n(2861);e.exports=/(?:ipad|iphone|ipod).*applewebkit/i.test(r)},6049:(e,t,n)=>{var r=n(34155),o=n(82532);e.exports=void 0!==r&&"process"==o(r)},58045:(e,t,n)=>{var r=n(2861);e.exports=/web0s(?!.*chrome)/i.test(r)},2861:e=>{e.exports="undefined"!=typeof navigator&&String(navigator.userAgent)||""},53385:(e,t,n)=>{var r,o,a=n(21899),i=n(2861),s=a.process,l=a.Deno,u=s&&s.versions||l&&l.version,c=u&&u.v8;c&&(o=(r=c.split("."))[0]>0&&r[0]<4?1:+(r[0]+r[1])),!o&&i&&(!(r=i.match(/Edge\/(\d+)/))||r[1]>=74)&&(r=i.match(/Chrome\/(\d+)/))&&(o=+r[1]),e.exports=o},18938:(e,t,n)=>{var r=n(2861).match(/AppleWebKit\/(\d+)\./);e.exports=!!r&&+r[1]},35703:(e,t,n)=>{var r=n(54058);e.exports=function(e){return r[e+"Prototype"]}},56759:e=>{e.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},53995:(e,t,n)=>{var r=n(95329),o=Error,a=r("".replace),i=String(o("zxcasd").stack),s=/\n\s*at [^:]*:[^\n]*/,l=s.test(i);e.exports=function(e,t){if(l&&"string"==typeof e&&!o.prepareStackTrace)for(;t--;)e=a(e,s,"");return e}},79585:(e,t,n)=>{var r=n(32029),o=n(53995),a=n(18780),i=Error.captureStackTrace;e.exports=function(e,t,n,s){a&&(i?i(e,t):r(e,"stack",o(n,s)))}},18780:(e,t,n)=>{var r=n(95981),o=n(31887);e.exports=!r((function(){var e=Error("a");return!("stack"in e)||(Object.defineProperty(e,"stack",o(1,7)),7!==e.stack)}))},76887:(e,t,n)=>{"use strict";var r=n(21899),o=n(79730),a=n(97484),i=n(57475),s=n(49677).f,l=n(37252),u=n(54058),c=n(86843),p=n(32029),f=n(90953),h=function(e){var t=function(n,r,a){if(this instanceof t){switch(arguments.length){case 0:return new e;case 1:return new e(n);case 2:return new e(n,r)}return new e(n,r,a)}return o(e,this,arguments)};return t.prototype=e.prototype,t};e.exports=function(e,t){var n,o,d,m,g,y,v,b,w,E=e.target,x=e.global,_=e.stat,S=e.proto,A=x?r:_?r[E]:(r[E]||{}).prototype,C=x?u:u[E]||p(u,E,{})[E],k=C.prototype;for(m in t)o=!(n=l(x?m:E+(_?".":"#")+m,e.forced))&&A&&f(A,m),y=C[m],o&&(v=e.dontCallGetSet?(w=s(A,m))&&w.value:A[m]),g=o&&v?v:t[m],o&&typeof y==typeof g||(b=e.bind&&o?c(g,r):e.wrap&&o?h(g):S&&i(g)?a(g):g,(e.sham||g&&g.sham||y&&y.sham)&&p(b,"sham",!0),p(C,m,b),S&&(f(u,d=E+"Prototype")||p(u,d,{}),p(u[d],m,g),e.real&&k&&(n||!k[m])&&p(k,m,g)))}},95981:e=>{e.exports=function(e){try{return!!e()}catch(e){return!0}}},45602:(e,t,n)=>{var r=n(95981);e.exports=!r((function(){return Object.isExtensible(Object.preventExtensions({}))}))},79730:(e,t,n)=>{var r=n(18285),o=Function.prototype,a=o.apply,i=o.call;e.exports="object"==typeof Reflect&&Reflect.apply||(r?i.bind(a):function(){return i.apply(a,arguments)})},86843:(e,t,n)=>{var r=n(97484),o=n(24883),a=n(18285),i=r(r.bind);e.exports=function(e,t){return o(e),void 0===t?e:a?i(e,t):function(){return e.apply(t,arguments)}}},18285:(e,t,n)=>{var r=n(95981);e.exports=!r((function(){var e=function(){}.bind();return"function"!=typeof e||e.hasOwnProperty("prototype")}))},98308:(e,t,n)=>{"use strict";var r=n(95329),o=n(24883),a=n(10941),i=n(90953),s=n(93765),l=n(18285),u=Function,c=r([].concat),p=r([].join),f={};e.exports=l?u.bind:function(e){var t=o(this),n=t.prototype,r=s(arguments,1),l=function(){var n=c(r,s(arguments));return this instanceof l?function(e,t,n){if(!i(f,t)){for(var r=[],o=0;o{var r=n(18285),o=Function.prototype.call;e.exports=r?o.bind(o):function(){return o.apply(o,arguments)}},79417:(e,t,n)=>{var r=n(55746),o=n(90953),a=Function.prototype,i=r&&Object.getOwnPropertyDescriptor,s=o(a,"name"),l=s&&"something"===function(){}.name,u=s&&(!r||r&&i(a,"name").configurable);e.exports={EXISTS:s,PROPER:l,CONFIGURABLE:u}},45526:(e,t,n)=>{var r=n(95329),o=n(24883);e.exports=function(e,t,n){try{return r(o(Object.getOwnPropertyDescriptor(e,t)[n]))}catch(e){}}},97484:(e,t,n)=>{var r=n(82532),o=n(95329);e.exports=function(e){if("Function"===r(e))return o(e)}},95329:(e,t,n)=>{var r=n(18285),o=Function.prototype,a=o.call,i=r&&o.bind.bind(a,a);e.exports=r?i:function(e){return function(){return a.apply(e,arguments)}}},626:(e,t,n)=>{var r=n(54058),o=n(21899),a=n(57475),i=function(e){return a(e)?e:void 0};e.exports=function(e,t){return arguments.length<2?i(r[e])||i(o[e]):r[e]&&r[e][t]||o[e]&&o[e][t]}},22902:(e,t,n)=>{var r=n(9697),o=n(14229),a=n(82119),i=n(12077),s=n(99813)("iterator");e.exports=function(e){if(!a(e))return o(e,s)||o(e,"@@iterator")||i[r(e)]}},53476:(e,t,n)=>{var r=n(78834),o=n(24883),a=n(96059),i=n(69826),s=n(22902),l=TypeError;e.exports=function(e,t){var n=arguments.length<2?s(e):t;if(o(n))return a(r(n,e));throw l(i(e)+" is not iterable")}},33323:(e,t,n)=>{var r=n(95329),o=n(1052),a=n(57475),i=n(82532),s=n(85803),l=r([].push);e.exports=function(e){if(a(e))return e;if(o(e)){for(var t=e.length,n=[],r=0;r{var r=n(24883),o=n(82119);e.exports=function(e,t){var n=e[t];return o(n)?void 0:r(n)}},21899:function(e,t,n){var r=function(e){return e&&e.Math==Math&&e};e.exports=r("object"==typeof globalThis&&globalThis)||r("object"==typeof window&&window)||r("object"==typeof self&&self)||r("object"==typeof n.g&&n.g)||function(){return this}()||this||Function("return this")()},90953:(e,t,n)=>{var r=n(95329),o=n(89678),a=r({}.hasOwnProperty);e.exports=Object.hasOwn||function(e,t){return a(o(e),t)}},27748:e=>{e.exports={}},34845:e=>{e.exports=function(e,t){try{1==arguments.length?console.error(e):console.error(e,t)}catch(e){}}},15463:(e,t,n)=>{var r=n(626);e.exports=r("document","documentElement")},2840:(e,t,n)=>{var r=n(55746),o=n(95981),a=n(61333);e.exports=!r&&!o((function(){return 7!=Object.defineProperty(a("div"),"a",{get:function(){return 7}}).a}))},37026:(e,t,n)=>{var r=n(95329),o=n(95981),a=n(82532),i=Object,s=r("".split);e.exports=o((function(){return!i("z").propertyIsEnumerable(0)}))?function(e){return"String"==a(e)?s(e,""):i(e)}:i},81302:(e,t,n)=>{var r=n(95329),o=n(57475),a=n(63030),i=r(Function.toString);o(a.inspectSource)||(a.inspectSource=function(e){return i(e)}),e.exports=a.inspectSource},53794:(e,t,n)=>{var r=n(10941),o=n(32029);e.exports=function(e,t){r(t)&&"cause"in t&&o(e,"cause",t.cause)}},21647:(e,t,n)=>{var r=n(76887),o=n(95329),a=n(27748),i=n(10941),s=n(90953),l=n(65988).f,u=n(10946),c=n(684),p=n(91584),f=n(99418),h=n(45602),d=!1,m=f("meta"),g=0,y=function(e){l(e,m,{value:{objectID:"O"+g++,weakData:{}}})},v=e.exports={enable:function(){v.enable=function(){},d=!0;var e=u.f,t=o([].splice),n={};n[m]=1,e(n).length&&(u.f=function(n){for(var r=e(n),o=0,a=r.length;o{var r,o,a,i=n(47093),s=n(21899),l=n(10941),u=n(32029),c=n(90953),p=n(63030),f=n(44262),h=n(27748),d="Object already initialized",m=s.TypeError,g=s.WeakMap;if(i||p.state){var y=p.state||(p.state=new g);y.get=y.get,y.has=y.has,y.set=y.set,r=function(e,t){if(y.has(e))throw m(d);return t.facade=e,y.set(e,t),t},o=function(e){return y.get(e)||{}},a=function(e){return y.has(e)}}else{var v=f("state");h[v]=!0,r=function(e,t){if(c(e,v))throw m(d);return t.facade=e,u(e,v,t),t},o=function(e){return c(e,v)?e[v]:{}},a=function(e){return c(e,v)}}e.exports={set:r,get:o,has:a,enforce:function(e){return a(e)?o(e):r(e,{})},getterFor:function(e){return function(t){var n;if(!l(t)||(n=o(t)).type!==e)throw m("Incompatible receiver, "+e+" required");return n}}}},6782:(e,t,n)=>{var r=n(99813),o=n(12077),a=r("iterator"),i=Array.prototype;e.exports=function(e){return void 0!==e&&(o.Array===e||i[a]===e)}},1052:(e,t,n)=>{var r=n(82532);e.exports=Array.isArray||function(e){return"Array"==r(e)}},57475:(e,t,n)=>{var r=n(76616),o=r.all;e.exports=r.IS_HTMLDDA?function(e){return"function"==typeof e||e===o}:function(e){return"function"==typeof e}},24284:(e,t,n)=>{var r=n(95329),o=n(95981),a=n(57475),i=n(9697),s=n(626),l=n(81302),u=function(){},c=[],p=s("Reflect","construct"),f=/^\s*(?:class|function)\b/,h=r(f.exec),d=!f.exec(u),m=function(e){if(!a(e))return!1;try{return p(u,c,e),!0}catch(e){return!1}},g=function(e){if(!a(e))return!1;switch(i(e)){case"AsyncFunction":case"GeneratorFunction":case"AsyncGeneratorFunction":return!1}try{return d||!!h(f,l(e))}catch(e){return!0}};g.sham=!0,e.exports=!p||o((function(){var e;return m(m.call)||!m(Object)||!m((function(){e=!0}))||e}))?g:m},37252:(e,t,n)=>{var r=n(95981),o=n(57475),a=/#|\.prototype\./,i=function(e,t){var n=l[s(e)];return n==c||n!=u&&(o(t)?r(t):!!t)},s=i.normalize=function(e){return String(e).replace(a,".").toLowerCase()},l=i.data={},u=i.NATIVE="N",c=i.POLYFILL="P";e.exports=i},82119:e=>{e.exports=function(e){return null==e}},10941:(e,t,n)=>{var r=n(57475),o=n(76616),a=o.all;e.exports=o.IS_HTMLDDA?function(e){return"object"==typeof e?null!==e:r(e)||e===a}:function(e){return"object"==typeof e?null!==e:r(e)}},82529:e=>{e.exports=!0},60685:(e,t,n)=>{var r=n(10941),o=n(82532),a=n(99813)("match");e.exports=function(e){var t;return r(e)&&(void 0!==(t=e[a])?!!t:"RegExp"==o(e))}},56664:(e,t,n)=>{var r=n(626),o=n(57475),a=n(7046),i=n(32302),s=Object;e.exports=i?function(e){return"symbol"==typeof e}:function(e){var t=r("Symbol");return o(t)&&a(t.prototype,s(e))}},93091:(e,t,n)=>{var r=n(86843),o=n(78834),a=n(96059),i=n(69826),s=n(6782),l=n(10623),u=n(7046),c=n(53476),p=n(22902),f=n(7609),h=TypeError,d=function(e,t){this.stopped=e,this.result=t},m=d.prototype;e.exports=function(e,t,n){var g,y,v,b,w,E,x,_=n&&n.that,S=!(!n||!n.AS_ENTRIES),A=!(!n||!n.IS_RECORD),C=!(!n||!n.IS_ITERATOR),k=!(!n||!n.INTERRUPTED),O=r(t,_),j=function(e){return g&&f(g,"normal",e),new d(!0,e)},T=function(e){return S?(a(e),k?O(e[0],e[1],j):O(e[0],e[1])):k?O(e,j):O(e)};if(A)g=e.iterator;else if(C)g=e;else{if(!(y=p(e)))throw h(i(e)+" is not iterable");if(s(y)){for(v=0,b=l(e);b>v;v++)if((w=T(e[v]))&&u(m,w))return w;return new d(!1)}g=c(e,y)}for(E=A?e.next:g.next;!(x=o(E,g)).done;){try{w=T(x.value)}catch(e){f(g,"throw",e)}if("object"==typeof w&&w&&u(m,w))return w}return new d(!1)}},7609:(e,t,n)=>{var r=n(78834),o=n(96059),a=n(14229);e.exports=function(e,t,n){var i,s;o(e);try{if(!(i=a(e,"return"))){if("throw"===t)throw n;return n}i=r(i,e)}catch(e){s=!0,i=e}if("throw"===t)throw n;if(s)throw i;return o(i),n}},53847:(e,t,n)=>{"use strict";var r=n(35143).IteratorPrototype,o=n(29290),a=n(31887),i=n(90904),s=n(12077),l=function(){return this};e.exports=function(e,t,n,u){var c=t+" Iterator";return e.prototype=o(r,{next:a(+!u,n)}),i(e,c,!1,!0),s[c]=l,e}},75105:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(82529),i=n(79417),s=n(57475),l=n(53847),u=n(249),c=n(88929),p=n(90904),f=n(32029),h=n(95929),d=n(99813),m=n(12077),g=n(35143),y=i.PROPER,v=i.CONFIGURABLE,b=g.IteratorPrototype,w=g.BUGGY_SAFARI_ITERATORS,E=d("iterator"),x="keys",_="values",S="entries",A=function(){return this};e.exports=function(e,t,n,i,d,g,C){l(n,t,i);var k,O,j,T=function(e){if(e===d&&M)return M;if(!w&&e in P)return P[e];switch(e){case x:case _:case S:return function(){return new n(this,e)}}return function(){return new n(this)}},I=t+" Iterator",N=!1,P=e.prototype,R=P[E]||P["@@iterator"]||d&&P[d],M=!w&&R||T(d),D="Array"==t&&P.entries||R;if(D&&(k=u(D.call(new e)))!==Object.prototype&&k.next&&(a||u(k)===b||(c?c(k,b):s(k[E])||h(k,E,A)),p(k,I,!0,!0),a&&(m[I]=A)),y&&d==_&&R&&R.name!==_&&(!a&&v?f(P,"name",_):(N=!0,M=function(){return o(R,this)})),d)if(O={values:T(_),keys:g?M:T(x),entries:T(S)},C)for(j in O)(w||N||!(j in P))&&h(P,j,O[j]);else r({target:t,proto:!0,forced:w||N},O);return a&&!C||P[E]===M||h(P,E,M,{name:d}),m[t]=M,O}},35143:(e,t,n)=>{"use strict";var r,o,a,i=n(95981),s=n(57475),l=n(10941),u=n(29290),c=n(249),p=n(95929),f=n(99813),h=n(82529),d=f("iterator"),m=!1;[].keys&&("next"in(a=[].keys())?(o=c(c(a)))!==Object.prototype&&(r=o):m=!0),!l(r)||i((function(){var e={};return r[d].call(e)!==e}))?r={}:h&&(r=u(r)),s(r[d])||p(r,d,(function(){return this})),e.exports={IteratorPrototype:r,BUGGY_SAFARI_ITERATORS:m}},12077:e=>{e.exports={}},10623:(e,t,n)=>{var r=n(43057);e.exports=function(e){return r(e.length)}},35331:e=>{var t=Math.ceil,n=Math.floor;e.exports=Math.trunc||function(e){var r=+e;return(r>0?n:t)(r)}},66132:(e,t,n)=>{var r,o,a,i,s,l=n(21899),u=n(86843),c=n(49677).f,p=n(42941).set,f=n(18397),h=n(22749),d=n(4470),m=n(58045),g=n(6049),y=l.MutationObserver||l.WebKitMutationObserver,v=l.document,b=l.process,w=l.Promise,E=c(l,"queueMicrotask"),x=E&&E.value;if(!x){var _=new f,S=function(){var e,t;for(g&&(e=b.domain)&&e.exit();t=_.get();)try{t()}catch(e){throw _.head&&r(),e}e&&e.enter()};h||g||m||!y||!v?!d&&w&&w.resolve?((i=w.resolve(void 0)).constructor=w,s=u(i.then,i),r=function(){s(S)}):g?r=function(){b.nextTick(S)}:(p=u(p,l),r=function(){p(S)}):(o=!0,a=v.createTextNode(""),new y(S).observe(a,{characterData:!0}),r=function(){a.data=o=!o}),x=function(e){_.head||r(),_.add(e)}}e.exports=x},69520:(e,t,n)=>{"use strict";var r=n(24883),o=TypeError,a=function(e){var t,n;this.promise=new e((function(e,r){if(void 0!==t||void 0!==n)throw o("Bad Promise constructor");t=e,n=r})),this.resolve=r(t),this.reject=r(n)};e.exports.f=function(e){return new a(e)}},14649:(e,t,n)=>{var r=n(85803);e.exports=function(e,t){return void 0===e?arguments.length<2?"":t:r(e)}},70344:(e,t,n)=>{var r=n(60685),o=TypeError;e.exports=function(e){if(r(e))throw o("The method doesn't accept regular expressions");return e}},24420:(e,t,n)=>{"use strict";var r=n(55746),o=n(95329),a=n(78834),i=n(95981),s=n(14771),l=n(87857),u=n(36760),c=n(89678),p=n(37026),f=Object.assign,h=Object.defineProperty,d=o([].concat);e.exports=!f||i((function(){if(r&&1!==f({b:1},f(h({},"a",{enumerable:!0,get:function(){h(this,"b",{value:3,enumerable:!1})}}),{b:2})).b)return!0;var e={},t={},n=Symbol(),o="abcdefghijklmnopqrst";return e[n]=7,o.split("").forEach((function(e){t[e]=e})),7!=f({},e)[n]||s(f({},t)).join("")!=o}))?function(e,t){for(var n=c(e),o=arguments.length,i=1,f=l.f,h=u.f;o>i;)for(var m,g=p(arguments[i++]),y=f?d(s(g),f(g)):s(g),v=y.length,b=0;v>b;)m=y[b++],r&&!a(h,g,m)||(n[m]=g[m]);return n}:f},29290:(e,t,n)=>{var r,o=n(96059),a=n(59938),i=n(56759),s=n(27748),l=n(15463),u=n(61333),c=n(44262),p="prototype",f="script",h=c("IE_PROTO"),d=function(){},m=function(e){return"<"+f+">"+e+""},g=function(e){e.write(m("")),e.close();var t=e.parentWindow.Object;return e=null,t},y=function(){try{r=new ActiveXObject("htmlfile")}catch(e){}var e,t,n;y="undefined"!=typeof document?document.domain&&r?g(r):(t=u("iframe"),n="java"+f+":",t.style.display="none",l.appendChild(t),t.src=String(n),(e=t.contentWindow.document).open(),e.write(m("document.F=Object")),e.close(),e.F):g(r);for(var o=i.length;o--;)delete y[p][i[o]];return y()};s[h]=!0,e.exports=Object.create||function(e,t){var n;return null!==e?(d[p]=o(e),n=new d,d[p]=null,n[h]=e):n=y(),void 0===t?n:a.f(n,t)}},59938:(e,t,n)=>{var r=n(55746),o=n(83937),a=n(65988),i=n(96059),s=n(74529),l=n(14771);t.f=r&&!o?Object.defineProperties:function(e,t){i(e);for(var n,r=s(t),o=l(t),u=o.length,c=0;u>c;)a.f(e,n=o[c++],r[n]);return e}},65988:(e,t,n)=>{var r=n(55746),o=n(2840),a=n(83937),i=n(96059),s=n(83894),l=TypeError,u=Object.defineProperty,c=Object.getOwnPropertyDescriptor,p="enumerable",f="configurable",h="writable";t.f=r?a?function(e,t,n){if(i(e),t=s(t),i(n),"function"==typeof e&&"prototype"===t&&"value"in n&&h in n&&!n[h]){var r=c(e,t);r&&r[h]&&(e[t]=n.value,n={configurable:f in n?n[f]:r[f],enumerable:p in n?n[p]:r[p],writable:!1})}return u(e,t,n)}:u:function(e,t,n){if(i(e),t=s(t),i(n),o)try{return u(e,t,n)}catch(e){}if("get"in n||"set"in n)throw l("Accessors not supported");return"value"in n&&(e[t]=n.value),e}},49677:(e,t,n)=>{var r=n(55746),o=n(78834),a=n(36760),i=n(31887),s=n(74529),l=n(83894),u=n(90953),c=n(2840),p=Object.getOwnPropertyDescriptor;t.f=r?p:function(e,t){if(e=s(e),t=l(t),c)try{return p(e,t)}catch(e){}if(u(e,t))return i(!o(a.f,e,t),e[t])}},684:(e,t,n)=>{var r=n(82532),o=n(74529),a=n(10946).f,i=n(15790),s="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[];e.exports.f=function(e){return s&&"Window"==r(e)?function(e){try{return a(e)}catch(e){return i(s)}}(e):a(o(e))}},10946:(e,t,n)=>{var r=n(55629),o=n(56759).concat("length","prototype");t.f=Object.getOwnPropertyNames||function(e){return r(e,o)}},87857:(e,t)=>{t.f=Object.getOwnPropertySymbols},249:(e,t,n)=>{var r=n(90953),o=n(57475),a=n(89678),i=n(44262),s=n(64160),l=i("IE_PROTO"),u=Object,c=u.prototype;e.exports=s?u.getPrototypeOf:function(e){var t=a(e);if(r(t,l))return t[l];var n=t.constructor;return o(n)&&t instanceof n?n.prototype:t instanceof u?c:null}},91584:(e,t,n)=>{var r=n(95981),o=n(10941),a=n(82532),i=n(97135),s=Object.isExtensible,l=r((function(){s(1)}));e.exports=l||i?function(e){return!!o(e)&&((!i||"ArrayBuffer"!=a(e))&&(!s||s(e)))}:s},7046:(e,t,n)=>{var r=n(95329);e.exports=r({}.isPrototypeOf)},55629:(e,t,n)=>{var r=n(95329),o=n(90953),a=n(74529),i=n(31692).indexOf,s=n(27748),l=r([].push);e.exports=function(e,t){var n,r=a(e),u=0,c=[];for(n in r)!o(s,n)&&o(r,n)&&l(c,n);for(;t.length>u;)o(r,n=t[u++])&&(~i(c,n)||l(c,n));return c}},14771:(e,t,n)=>{var r=n(55629),o=n(56759);e.exports=Object.keys||function(e){return r(e,o)}},36760:(e,t)=>{"use strict";var n={}.propertyIsEnumerable,r=Object.getOwnPropertyDescriptor,o=r&&!n.call({1:2},1);t.f=o?function(e){var t=r(this,e);return!!t&&t.enumerable}:n},88929:(e,t,n)=>{var r=n(45526),o=n(96059),a=n(11851);e.exports=Object.setPrototypeOf||("__proto__"in{}?function(){var e,t=!1,n={};try{(e=r(Object.prototype,"__proto__","set"))(n,[]),t=n instanceof Array}catch(e){}return function(n,r){return o(n),a(r),t?e(n,r):n.__proto__=r,n}}():void 0)},88810:(e,t,n)=>{var r=n(55746),o=n(95981),a=n(95329),i=n(249),s=n(14771),l=n(74529),u=a(n(36760).f),c=a([].push),p=r&&o((function(){var e=Object.create(null);return e[2]=2,!u(e,2)})),f=function(e){return function(t){for(var n,o=l(t),a=s(o),f=p&&null===i(o),h=a.length,d=0,m=[];h>d;)n=a[d++],r&&!(f?n in o:u(o,n))||c(m,e?[n,o[n]]:o[n]);return m}};e.exports={entries:f(!0),values:f(!1)}},95623:(e,t,n)=>{"use strict";var r=n(22885),o=n(9697);e.exports=r?{}.toString:function(){return"[object "+o(this)+"]"}},39811:(e,t,n)=>{var r=n(78834),o=n(57475),a=n(10941),i=TypeError;e.exports=function(e,t){var n,s;if("string"===t&&o(n=e.toString)&&!a(s=r(n,e)))return s;if(o(n=e.valueOf)&&!a(s=r(n,e)))return s;if("string"!==t&&o(n=e.toString)&&!a(s=r(n,e)))return s;throw i("Can't convert object to primitive value")}},31136:(e,t,n)=>{var r=n(626),o=n(95329),a=n(10946),i=n(87857),s=n(96059),l=o([].concat);e.exports=r("Reflect","ownKeys")||function(e){var t=a.f(s(e)),n=i.f;return n?l(t,n(e)):t}},54058:e=>{e.exports={}},40002:e=>{e.exports=function(e){try{return{error:!1,value:e()}}catch(e){return{error:!0,value:e}}}},67742:(e,t,n)=>{var r=n(21899),o=n(6991),a=n(57475),i=n(37252),s=n(81302),l=n(99813),u=n(23321),c=n(48501),p=n(82529),f=n(53385),h=o&&o.prototype,d=l("species"),m=!1,g=a(r.PromiseRejectionEvent),y=i("Promise",(function(){var e=s(o),t=e!==String(o);if(!t&&66===f)return!0;if(p&&(!h.catch||!h.finally))return!0;if(!f||f<51||!/native code/.test(e)){var n=new o((function(e){e(1)})),r=function(e){e((function(){}),(function(){}))};if((n.constructor={})[d]=r,!(m=n.then((function(){}))instanceof r))return!0}return!t&&(u||c)&&!g}));e.exports={CONSTRUCTOR:y,REJECTION_EVENT:g,SUBCLASSING:m}},6991:(e,t,n)=>{var r=n(21899);e.exports=r.Promise},56584:(e,t,n)=>{var r=n(96059),o=n(10941),a=n(69520);e.exports=function(e,t){if(r(e),o(t)&&t.constructor===e)return t;var n=a.f(e);return(0,n.resolve)(t),n.promise}},31542:(e,t,n)=>{var r=n(6991),o=n(21385),a=n(67742).CONSTRUCTOR;e.exports=a||!o((function(e){r.all(e).then(void 0,(function(){}))}))},18397:e=>{var t=function(){this.head=null,this.tail=null};t.prototype={add:function(e){var t={item:e,next:null},n=this.tail;n?n.next=t:this.head=t,this.tail=t},get:function(){var e=this.head;if(e)return null===(this.head=e.next)&&(this.tail=null),e.item}},e.exports=t},48219:(e,t,n)=>{var r=n(82119),o=TypeError;e.exports=function(e){if(r(e))throw o("Can't call method on "+e);return e}},37620:(e,t,n)=>{"use strict";var r,o=n(21899),a=n(79730),i=n(57475),s=n(56491),l=n(2861),u=n(93765),c=n(18348),p=o.Function,f=/MSIE .\./.test(l)||s&&((r=o.Bun.version.split(".")).length<3||0==r[0]&&(r[1]<3||3==r[1]&&0==r[2]));e.exports=function(e,t){var n=t?2:1;return f?function(r,o){var s=c(arguments.length,1)>n,l=i(r)?r:p(r),f=s?u(arguments,n):[],h=s?function(){a(l,this,f)}:l;return t?e(h,o):e(h)}:e}},94431:(e,t,n)=>{"use strict";var r=n(626),o=n(29202),a=n(99813),i=n(55746),s=a("species");e.exports=function(e){var t=r(e);i&&t&&!t[s]&&o(t,s,{configurable:!0,get:function(){return this}})}},90904:(e,t,n)=>{var r=n(22885),o=n(65988).f,a=n(32029),i=n(90953),s=n(95623),l=n(99813)("toStringTag");e.exports=function(e,t,n,u){if(e){var c=n?e:e.prototype;i(c,l)||o(c,l,{configurable:!0,value:t}),u&&!r&&a(c,"toString",s)}}},44262:(e,t,n)=>{var r=n(68726),o=n(99418),a=r("keys");e.exports=function(e){return a[e]||(a[e]=o(e))}},63030:(e,t,n)=>{var r=n(21899),o=n(75609),a="__core-js_shared__",i=r[a]||o(a,{});e.exports=i},68726:(e,t,n)=>{var r=n(82529),o=n(63030);(e.exports=function(e,t){return o[e]||(o[e]=void 0!==t?t:{})})("versions",[]).push({version:"3.31.0",mode:r?"pure":"global",copyright:"© 2014-2023 Denis Pushkarev (zloirock.ru)",license:"https://github.com/zloirock/core-js/blob/v3.31.0/LICENSE",source:"https://github.com/zloirock/core-js"})},70487:(e,t,n)=>{var r=n(96059),o=n(174),a=n(82119),i=n(99813)("species");e.exports=function(e,t){var n,s=r(e).constructor;return void 0===s||a(n=r(s)[i])?t:o(n)}},64620:(e,t,n)=>{var r=n(95329),o=n(62435),a=n(85803),i=n(48219),s=r("".charAt),l=r("".charCodeAt),u=r("".slice),c=function(e){return function(t,n){var r,c,p=a(i(t)),f=o(n),h=p.length;return f<0||f>=h?e?"":void 0:(r=l(p,f))<55296||r>56319||f+1===h||(c=l(p,f+1))<56320||c>57343?e?s(p,f):r:e?u(p,f,f+2):c-56320+(r-55296<<10)+65536}};e.exports={codeAt:c(!1),charAt:c(!0)}},73291:(e,t,n)=>{var r=n(95329),o=2147483647,a=/[^\0-\u007E]/,i=/[.\u3002\uFF0E\uFF61]/g,s="Overflow: input needs wider integers to process",l=RangeError,u=r(i.exec),c=Math.floor,p=String.fromCharCode,f=r("".charCodeAt),h=r([].join),d=r([].push),m=r("".replace),g=r("".split),y=r("".toLowerCase),v=function(e){return e+22+75*(e<26)},b=function(e,t,n){var r=0;for(e=n?c(e/700):e>>1,e+=c(e/t);e>455;)e=c(e/35),r+=36;return c(r+36*e/(e+38))},w=function(e){var t=[];e=function(e){for(var t=[],n=0,r=e.length;n=55296&&o<=56319&&n=i&&rc((o-u)/E))throw l(s);for(u+=(w-i)*E,i=w,n=0;no)throw l(s);if(r==i){for(var x=u,_=36;;){var S=_<=m?1:_>=m+26?26:_-m;if(x{"use strict";var r=n(62435),o=n(85803),a=n(48219),i=RangeError;e.exports=function(e){var t=o(a(this)),n="",s=r(e);if(s<0||s==1/0)throw i("Wrong number of repetitions");for(;s>0;(s>>>=1)&&(t+=t))1&s&&(n+=t);return n}},93093:(e,t,n)=>{var r=n(79417).PROPER,o=n(95981),a=n(73483);e.exports=function(e){return o((function(){return!!a[e]()||"​…᠎"!=="​…᠎"[e]()||r&&a[e].name!==e}))}},74853:(e,t,n)=>{var r=n(95329),o=n(48219),a=n(85803),i=n(73483),s=r("".replace),l=RegExp("^["+i+"]+"),u=RegExp("(^|[^"+i+"])["+i+"]+$"),c=function(e){return function(t){var n=a(o(t));return 1&e&&(n=s(n,l,"")),2&e&&(n=s(n,u,"$1")),n}};e.exports={start:c(1),end:c(2),trim:c(3)}},63405:(e,t,n)=>{var r=n(53385),o=n(95981),a=n(21899).String;e.exports=!!Object.getOwnPropertySymbols&&!o((function(){var e=Symbol();return!a(e)||!(Object(e)instanceof Symbol)||!Symbol.sham&&r&&r<41}))},29630:(e,t,n)=>{var r=n(78834),o=n(626),a=n(99813),i=n(95929);e.exports=function(){var e=o("Symbol"),t=e&&e.prototype,n=t&&t.valueOf,s=a("toPrimitive");t&&!t[s]&&i(t,s,(function(e){return r(n,this)}),{arity:1})}},32087:(e,t,n)=>{var r=n(626),o=n(95329),a=r("Symbol"),i=a.keyFor,s=o(a.prototype.valueOf);e.exports=a.isRegisteredSymbol||function(e){try{return void 0!==i(s(e))}catch(e){return!1}}},96559:(e,t,n)=>{for(var r=n(68726),o=n(626),a=n(95329),i=n(56664),s=n(99813),l=o("Symbol"),u=l.isWellKnownSymbol,c=o("Object","getOwnPropertyNames"),p=a(l.prototype.valueOf),f=r("wks"),h=0,d=c(l),m=d.length;h{var r=n(63405);e.exports=r&&!!Symbol.for&&!!Symbol.keyFor},42941:(e,t,n)=>{var r,o,a,i,s=n(21899),l=n(79730),u=n(86843),c=n(57475),p=n(90953),f=n(95981),h=n(15463),d=n(93765),m=n(61333),g=n(18348),y=n(22749),v=n(6049),b=s.setImmediate,w=s.clearImmediate,E=s.process,x=s.Dispatch,_=s.Function,S=s.MessageChannel,A=s.String,C=0,k={},O="onreadystatechange";f((function(){r=s.location}));var j=function(e){if(p(k,e)){var t=k[e];delete k[e],t()}},T=function(e){return function(){j(e)}},I=function(e){j(e.data)},N=function(e){s.postMessage(A(e),r.protocol+"//"+r.host)};b&&w||(b=function(e){g(arguments.length,1);var t=c(e)?e:_(e),n=d(arguments,1);return k[++C]=function(){l(t,void 0,n)},o(C),C},w=function(e){delete k[e]},v?o=function(e){E.nextTick(T(e))}:x&&x.now?o=function(e){x.now(T(e))}:S&&!y?(i=(a=new S).port2,a.port1.onmessage=I,o=u(i.postMessage,i)):s.addEventListener&&c(s.postMessage)&&!s.importScripts&&r&&"file:"!==r.protocol&&!f(N)?(o=N,s.addEventListener("message",I,!1)):o=O in m("script")?function(e){h.appendChild(m("script"))[O]=function(){h.removeChild(this),j(e)}}:function(e){setTimeout(T(e),0)}),e.exports={set:b,clear:w}},59413:(e,t,n)=>{var r=n(62435),o=Math.max,a=Math.min;e.exports=function(e,t){var n=r(e);return n<0?o(n+t,0):a(n,t)}},74529:(e,t,n)=>{var r=n(37026),o=n(48219);e.exports=function(e){return r(o(e))}},62435:(e,t,n)=>{var r=n(35331);e.exports=function(e){var t=+e;return t!=t||0===t?0:r(t)}},43057:(e,t,n)=>{var r=n(62435),o=Math.min;e.exports=function(e){return e>0?o(r(e),9007199254740991):0}},89678:(e,t,n)=>{var r=n(48219),o=Object;e.exports=function(e){return o(r(e))}},46935:(e,t,n)=>{var r=n(78834),o=n(10941),a=n(56664),i=n(14229),s=n(39811),l=n(99813),u=TypeError,c=l("toPrimitive");e.exports=function(e,t){if(!o(e)||a(e))return e;var n,l=i(e,c);if(l){if(void 0===t&&(t="default"),n=r(l,e,t),!o(n)||a(n))return n;throw u("Can't convert object to primitive value")}return void 0===t&&(t="number"),s(e,t)}},83894:(e,t,n)=>{var r=n(46935),o=n(56664);e.exports=function(e){var t=r(e,"string");return o(t)?t:t+""}},22885:(e,t,n)=>{var r={};r[n(99813)("toStringTag")]="z",e.exports="[object z]"===String(r)},85803:(e,t,n)=>{var r=n(9697),o=String;e.exports=function(e){if("Symbol"===r(e))throw TypeError("Cannot convert a Symbol value to a string");return o(e)}},69826:e=>{var t=String;e.exports=function(e){try{return t(e)}catch(e){return"Object"}}},99418:(e,t,n)=>{var r=n(95329),o=0,a=Math.random(),i=r(1..toString);e.exports=function(e){return"Symbol("+(void 0===e?"":e)+")_"+i(++o+a,36)}},14766:(e,t,n)=>{var r=n(95981),o=n(99813),a=n(55746),i=n(82529),s=o("iterator");e.exports=!r((function(){var e=new URL("b?a=1&b=2&c=3","http://a"),t=e.searchParams,n=new URLSearchParams("a=1&a=2"),r="";return e.pathname="c%20d",t.forEach((function(e,n){t.delete("b"),r+=n+e})),n.delete("a",2),i&&(!e.toJSON||!n.has("a",1)||n.has("a",2))||!t.size&&(i||!a)||!t.sort||"http://a/c%20d?a=1&c=3"!==e.href||"3"!==t.get("c")||"a=1"!==String(new URLSearchParams("?a=1"))||!t[s]||"a"!==new URL("https://a@b").username||"b"!==new URLSearchParams(new URLSearchParams("a=b")).get("a")||"xn--e1aybc"!==new URL("http://тест").host||"#%D0%B1"!==new URL("http://a#б").hash||"a1c3"!==r||"x"!==new URL("http://x",void 0).host}))},32302:(e,t,n)=>{var r=n(63405);e.exports=r&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},83937:(e,t,n)=>{var r=n(55746),o=n(95981);e.exports=r&&o((function(){return 42!=Object.defineProperty((function(){}),"prototype",{value:42,writable:!1}).prototype}))},18348:e=>{var t=TypeError;e.exports=function(e,n){if(e{var r=n(21899),o=n(57475),a=r.WeakMap;e.exports=o(a)&&/native code/.test(String(a))},73464:(e,t,n)=>{var r=n(54058),o=n(90953),a=n(11477),i=n(65988).f;e.exports=function(e){var t=r.Symbol||(r.Symbol={});o(t,e)||i(t,e,{value:a.f(e)})}},11477:(e,t,n)=>{var r=n(99813);t.f=r},99813:(e,t,n)=>{var r=n(21899),o=n(68726),a=n(90953),i=n(99418),s=n(63405),l=n(32302),u=r.Symbol,c=o("wks"),p=l?u.for||u:u&&u.withoutSetter||i;e.exports=function(e){return a(c,e)||(c[e]=s&&a(u,e)?u[e]:p("Symbol."+e)),c[e]}},73483:e=>{e.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},49812:(e,t,n)=>{"use strict";var r=n(76887),o=n(7046),a=n(249),i=n(88929),s=n(23489),l=n(29290),u=n(32029),c=n(31887),p=n(53794),f=n(79585),h=n(93091),d=n(14649),m=n(99813)("toStringTag"),g=Error,y=[].push,v=function(e,t){var n,r=o(b,this);i?n=i(g(),r?a(this):b):(n=r?this:l(b),u(n,m,"Error")),void 0!==t&&u(n,"message",d(t)),f(n,v,n.stack,1),arguments.length>2&&p(n,arguments[2]);var s=[];return h(e,y,{that:s}),u(n,"errors",s),n};i?i(v,g):s(v,g,{name:!0});var b=v.prototype=l(g.prototype,{constructor:c(1,v),message:c(1,""),name:c(1,"AggregateError")});r({global:!0,constructor:!0,arity:2},{AggregateError:v})},47627:(e,t,n)=>{n(49812)},85906:(e,t,n)=>{"use strict";var r=n(76887),o=n(95981),a=n(1052),i=n(10941),s=n(89678),l=n(10623),u=n(66796),c=n(55449),p=n(64692),f=n(50568),h=n(99813),d=n(53385),m=h("isConcatSpreadable"),g=d>=51||!o((function(){var e=[];return e[m]=!1,e.concat()[0]!==e})),y=function(e){if(!i(e))return!1;var t=e[m];return void 0!==t?!!t:a(e)};r({target:"Array",proto:!0,arity:1,forced:!g||!f("concat")},{concat:function(e){var t,n,r,o,a,i=s(this),f=p(i,0),h=0;for(t=-1,r=arguments.length;t{"use strict";var r=n(76887),o=n(3610).every;r({target:"Array",proto:!0,forced:!n(34194)("every")},{every:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},80290:(e,t,n)=>{var r=n(76887),o=n(91860),a=n(18479);r({target:"Array",proto:!0},{fill:o}),a("fill")},21501:(e,t,n)=>{"use strict";var r=n(76887),o=n(3610).filter;r({target:"Array",proto:!0,forced:!n(50568)("filter")},{filter:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},44929:(e,t,n)=>{"use strict";var r=n(76887),o=n(3610).findIndex,a=n(18479),i="findIndex",s=!0;i in[]&&Array(1)[i]((function(){s=!1})),r({target:"Array",proto:!0,forced:s},{findIndex:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),a(i)},80833:(e,t,n)=>{"use strict";var r=n(76887),o=n(3610).find,a=n(18479),i="find",s=!0;i in[]&&Array(1)[i]((function(){s=!1})),r({target:"Array",proto:!0,forced:s},{find:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),a(i)},2437:(e,t,n)=>{"use strict";var r=n(76887),o=n(56837);r({target:"Array",proto:!0,forced:[].forEach!=o},{forEach:o})},53242:(e,t,n)=>{var r=n(76887),o=n(11354);r({target:"Array",stat:!0,forced:!n(21385)((function(e){Array.from(e)}))},{from:o})},97690:(e,t,n)=>{"use strict";var r=n(76887),o=n(31692).includes,a=n(95981),i=n(18479);r({target:"Array",proto:!0,forced:a((function(){return!Array(1).includes()}))},{includes:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}}),i("includes")},99076:(e,t,n)=>{"use strict";var r=n(76887),o=n(97484),a=n(31692).indexOf,i=n(34194),s=o([].indexOf),l=!!s&&1/s([1],1,-0)<0;r({target:"Array",proto:!0,forced:l||!i("indexOf")},{indexOf:function(e){var t=arguments.length>1?arguments[1]:void 0;return l?s(this,e,t)||0:a(this,e,t)}})},92737:(e,t,n)=>{n(76887)({target:"Array",stat:!0},{isArray:n(1052)})},66274:(e,t,n)=>{"use strict";var r=n(74529),o=n(18479),a=n(12077),i=n(45402),s=n(65988).f,l=n(75105),u=n(23538),c=n(82529),p=n(55746),f="Array Iterator",h=i.set,d=i.getterFor(f);e.exports=l(Array,"Array",(function(e,t){h(this,{type:f,target:r(e),index:0,kind:t})}),(function(){var e=d(this),t=e.target,n=e.kind,r=e.index++;return!t||r>=t.length?(e.target=void 0,u(void 0,!0)):u("keys"==n?r:"values"==n?t[r]:[r,t[r]],!1)}),"values");var m=a.Arguments=a.Array;if(o("keys"),o("values"),o("entries"),!c&&p&&"values"!==m.name)try{s(m,"name",{value:"values"})}catch(e){}},75915:(e,t,n)=>{var r=n(76887),o=n(67145);r({target:"Array",proto:!0,forced:o!==[].lastIndexOf},{lastIndexOf:o})},68787:(e,t,n)=>{"use strict";var r=n(76887),o=n(3610).map;r({target:"Array",proto:!0,forced:!n(50568)("map")},{map:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},48528:(e,t,n)=>{"use strict";var r=n(76887),o=n(89678),a=n(10623),i=n(89779),s=n(66796);r({target:"Array",proto:!0,arity:1,forced:n(95981)((function(){return 4294967297!==[].push.call({length:4294967296},1)}))||!function(){try{Object.defineProperty([],"length",{writable:!1}).push()}catch(e){return e instanceof TypeError}}()},{push:function(e){var t=o(this),n=a(t),r=arguments.length;s(n+r);for(var l=0;l{"use strict";var r=n(76887),o=n(46499).left,a=n(34194),i=n(53385);r({target:"Array",proto:!0,forced:!n(6049)&&i>79&&i<83||!a("reduce")},{reduce:function(e){var t=arguments.length;return o(this,e,t,t>1?arguments[1]:void 0)}})},60186:(e,t,n)=>{"use strict";var r=n(76887),o=n(1052),a=n(24284),i=n(10941),s=n(59413),l=n(10623),u=n(74529),c=n(55449),p=n(99813),f=n(50568),h=n(93765),d=f("slice"),m=p("species"),g=Array,y=Math.max;r({target:"Array",proto:!0,forced:!d},{slice:function(e,t){var n,r,p,f=u(this),d=l(f),v=s(e,d),b=s(void 0===t?d:t,d);if(o(f)&&(n=f.constructor,(a(n)&&(n===g||o(n.prototype))||i(n)&&null===(n=n[m]))&&(n=void 0),n===g||void 0===n))return h(f,v,b);for(r=new(void 0===n?g:n)(y(b-v,0)),p=0;v{"use strict";var r=n(76887),o=n(3610).some;r({target:"Array",proto:!0,forced:!n(34194)("some")},{some:function(e){return o(this,e,arguments.length>1?arguments[1]:void 0)}})},4115:(e,t,n)=>{"use strict";var r=n(76887),o=n(95329),a=n(24883),i=n(89678),s=n(10623),l=n(15863),u=n(85803),c=n(95981),p=n(61388),f=n(34194),h=n(34342),d=n(81046),m=n(53385),g=n(18938),y=[],v=o(y.sort),b=o(y.push),w=c((function(){y.sort(void 0)})),E=c((function(){y.sort(null)})),x=f("sort"),_=!c((function(){if(m)return m<70;if(!(h&&h>3)){if(d)return!0;if(g)return g<603;var e,t,n,r,o="";for(e=65;e<76;e++){switch(t=String.fromCharCode(e),e){case 66:case 69:case 70:case 72:n=3;break;case 68:case 71:n=4;break;default:n=2}for(r=0;r<47;r++)y.push({k:t+r,v:n})}for(y.sort((function(e,t){return t.v-e.v})),r=0;ru(n)?1:-1}}(e)),n=s(o),r=0;r{"use strict";var r=n(76887),o=n(89678),a=n(59413),i=n(62435),s=n(10623),l=n(89779),u=n(66796),c=n(64692),p=n(55449),f=n(15863),h=n(50568)("splice"),d=Math.max,m=Math.min;r({target:"Array",proto:!0,forced:!h},{splice:function(e,t){var n,r,h,g,y,v,b=o(this),w=s(b),E=a(e,w),x=arguments.length;for(0===x?n=r=0:1===x?(n=0,r=w-E):(n=x-2,r=m(d(i(t),0),w-E)),u(w+n-r),h=c(b,r),g=0;gw-r+n;g--)f(b,g-1)}else if(n>r)for(g=w-r;g>E;g--)v=g+n-1,(y=g+r-1)in b?b[v]=b[y]:f(b,v);for(g=0;g{var r=n(76887),o=n(95329),a=Date,i=o(a.prototype.getTime);r({target:"Date",stat:!0},{now:function(){return i(new a)}})},18084:()=>{},73381:(e,t,n)=>{var r=n(76887),o=n(98308);r({target:"Function",proto:!0,forced:Function.bind!==o},{bind:o})},32619:(e,t,n)=>{var r=n(76887),o=n(626),a=n(79730),i=n(78834),s=n(95329),l=n(95981),u=n(57475),c=n(56664),p=n(93765),f=n(33323),h=n(63405),d=String,m=o("JSON","stringify"),g=s(/./.exec),y=s("".charAt),v=s("".charCodeAt),b=s("".replace),w=s(1..toString),E=/[\uD800-\uDFFF]/g,x=/^[\uD800-\uDBFF]$/,_=/^[\uDC00-\uDFFF]$/,S=!h||l((function(){var e=o("Symbol")();return"[null]"!=m([e])||"{}"!=m({a:e})||"{}"!=m(Object(e))})),A=l((function(){return'"\\udf06\\ud834"'!==m("\udf06\ud834")||'"\\udead"'!==m("\udead")})),C=function(e,t){var n=p(arguments),r=f(t);if(u(r)||void 0!==e&&!c(e))return n[1]=function(e,t){if(u(r)&&(t=i(r,this,d(e),t)),!c(t))return t},a(m,null,n)},k=function(e,t,n){var r=y(n,t-1),o=y(n,t+1);return g(x,e)&&!g(_,o)||g(_,e)&&!g(x,r)?"\\u"+w(v(e,0),16):e};m&&r({target:"JSON",stat:!0,arity:3,forced:S||A},{stringify:function(e,t,n){var r=p(arguments),o=a(S?C:m,null,r);return A&&"string"==typeof o?b(o,E,k):o}})},69120:(e,t,n)=>{var r=n(21899);n(90904)(r.JSON,"JSON",!0)},23112:(e,t,n)=>{"use strict";n(24683)("Map",(function(e){return function(){return e(this,arguments.length?arguments[0]:void 0)}}),n(85616))},37501:(e,t,n)=>{n(23112)},79413:()=>{},49221:(e,t,n)=>{var r=n(76887),o=n(24420);r({target:"Object",stat:!0,arity:2,forced:Object.assign!==o},{assign:o})},74979:(e,t,n)=>{var r=n(76887),o=n(55746),a=n(59938).f;r({target:"Object",stat:!0,forced:Object.defineProperties!==a,sham:!o},{defineProperties:a})},86450:(e,t,n)=>{var r=n(76887),o=n(55746),a=n(65988).f;r({target:"Object",stat:!0,forced:Object.defineProperty!==a,sham:!o},{defineProperty:a})},46924:(e,t,n)=>{var r=n(76887),o=n(95981),a=n(74529),i=n(49677).f,s=n(55746);r({target:"Object",stat:!0,forced:!s||o((function(){i(1)})),sham:!s},{getOwnPropertyDescriptor:function(e,t){return i(a(e),t)}})},88482:(e,t,n)=>{var r=n(76887),o=n(55746),a=n(31136),i=n(74529),s=n(49677),l=n(55449);r({target:"Object",stat:!0,sham:!o},{getOwnPropertyDescriptors:function(e){for(var t,n,r=i(e),o=s.f,u=a(r),c={},p=0;u.length>p;)void 0!==(n=o(r,t=u[p++]))&&l(c,t,n);return c}})},37144:(e,t,n)=>{var r=n(76887),o=n(63405),a=n(95981),i=n(87857),s=n(89678);r({target:"Object",stat:!0,forced:!o||a((function(){i.f(1)}))},{getOwnPropertySymbols:function(e){var t=i.f;return t?t(s(e)):[]}})},21724:(e,t,n)=>{var r=n(76887),o=n(89678),a=n(14771);r({target:"Object",stat:!0,forced:n(95981)((function(){a(1)}))},{keys:function(e){return a(o(e))}})},55967:()=>{},26614:(e,t,n)=>{var r=n(76887),o=n(88810).values;r({target:"Object",stat:!0},{values:function(e){return o(e)}})},4560:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(24883),i=n(69520),s=n(40002),l=n(93091);r({target:"Promise",stat:!0,forced:n(31542)},{allSettled:function(e){var t=this,n=i.f(t),r=n.resolve,u=n.reject,c=s((function(){var n=a(t.resolve),i=[],s=0,u=1;l(e,(function(e){var a=s++,l=!1;u++,o(n,t,e).then((function(e){l||(l=!0,i[a]={status:"fulfilled",value:e},--u||r(i))}),(function(e){l||(l=!0,i[a]={status:"rejected",reason:e},--u||r(i))}))})),--u||r(i)}));return c.error&&u(c.value),n.promise}})},16890:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(24883),i=n(69520),s=n(40002),l=n(93091);r({target:"Promise",stat:!0,forced:n(31542)},{all:function(e){var t=this,n=i.f(t),r=n.resolve,u=n.reject,c=s((function(){var n=a(t.resolve),i=[],s=0,c=1;l(e,(function(e){var a=s++,l=!1;c++,o(n,t,e).then((function(e){l||(l=!0,i[a]=e,--c||r(i))}),u)})),--c||r(i)}));return c.error&&u(c.value),n.promise}})},91302:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(24883),i=n(626),s=n(69520),l=n(40002),u=n(93091),c=n(31542),p="No one promise resolved";r({target:"Promise",stat:!0,forced:c},{any:function(e){var t=this,n=i("AggregateError"),r=s.f(t),c=r.resolve,f=r.reject,h=l((function(){var r=a(t.resolve),i=[],s=0,l=1,h=!1;u(e,(function(e){var a=s++,u=!1;l++,o(r,t,e).then((function(e){u||h||(h=!0,c(e))}),(function(e){u||h||(u=!0,i[a]=e,--l||f(new n(i,p)))}))})),--l||f(new n(i,p))}));return h.error&&f(h.value),r.promise}})},83376:(e,t,n)=>{"use strict";var r=n(76887),o=n(82529),a=n(67742).CONSTRUCTOR,i=n(6991),s=n(626),l=n(57475),u=n(95929),c=i&&i.prototype;if(r({target:"Promise",proto:!0,forced:a,real:!0},{catch:function(e){return this.then(void 0,e)}}),!o&&l(i)){var p=s("Promise").prototype.catch;c.catch!==p&&u(c,"catch",p,{unsafe:!0})}},26934:(e,t,n)=>{"use strict";var r,o,a,i=n(76887),s=n(82529),l=n(6049),u=n(21899),c=n(78834),p=n(95929),f=n(88929),h=n(90904),d=n(94431),m=n(24883),g=n(57475),y=n(10941),v=n(5743),b=n(70487),w=n(42941).set,E=n(66132),x=n(34845),_=n(40002),S=n(18397),A=n(45402),C=n(6991),k=n(67742),O=n(69520),j="Promise",T=k.CONSTRUCTOR,I=k.REJECTION_EVENT,N=k.SUBCLASSING,P=A.getterFor(j),R=A.set,M=C&&C.prototype,D=C,L=M,B=u.TypeError,F=u.document,z=u.process,U=O.f,q=U,$=!!(F&&F.createEvent&&u.dispatchEvent),V="unhandledrejection",W=function(e){var t;return!(!y(e)||!g(t=e.then))&&t},H=function(e,t){var n,r,o,a=t.value,i=1==t.state,s=i?e.ok:e.fail,l=e.resolve,u=e.reject,p=e.domain;try{s?(i||(2===t.rejection&&Y(t),t.rejection=1),!0===s?n=a:(p&&p.enter(),n=s(a),p&&(p.exit(),o=!0)),n===e.promise?u(B("Promise-chain cycle")):(r=W(n))?c(r,n,l,u):l(n)):u(a)}catch(e){p&&!o&&p.exit(),u(e)}},J=function(e,t){e.notified||(e.notified=!0,E((function(){for(var n,r=e.reactions;n=r.get();)H(n,e);e.notified=!1,t&&!e.rejection&&G(e)})))},K=function(e,t,n){var r,o;$?((r=F.createEvent("Event")).promise=t,r.reason=n,r.initEvent(e,!1,!0),u.dispatchEvent(r)):r={promise:t,reason:n},!I&&(o=u["on"+e])?o(r):e===V&&x("Unhandled promise rejection",n)},G=function(e){c(w,u,(function(){var t,n=e.facade,r=e.value;if(Z(e)&&(t=_((function(){l?z.emit("unhandledRejection",r,n):K(V,n,r)})),e.rejection=l||Z(e)?2:1,t.error))throw t.value}))},Z=function(e){return 1!==e.rejection&&!e.parent},Y=function(e){c(w,u,(function(){var t=e.facade;l?z.emit("rejectionHandled",t):K("rejectionhandled",t,e.value)}))},Q=function(e,t,n){return function(r){e(t,r,n)}},X=function(e,t,n){e.done||(e.done=!0,n&&(e=n),e.value=t,e.state=2,J(e,!0))},ee=function(e,t,n){if(!e.done){e.done=!0,n&&(e=n);try{if(e.facade===t)throw B("Promise can't be resolved itself");var r=W(t);r?E((function(){var n={done:!1};try{c(r,t,Q(ee,n,e),Q(X,n,e))}catch(t){X(n,t,e)}})):(e.value=t,e.state=1,J(e,!1))}catch(t){X({done:!1},t,e)}}};if(T&&(L=(D=function(e){v(this,L),m(e),c(r,this);var t=P(this);try{e(Q(ee,t),Q(X,t))}catch(e){X(t,e)}}).prototype,(r=function(e){R(this,{type:j,done:!1,notified:!1,parent:!1,reactions:new S,rejection:!1,state:0,value:void 0})}).prototype=p(L,"then",(function(e,t){var n=P(this),r=U(b(this,D));return n.parent=!0,r.ok=!g(e)||e,r.fail=g(t)&&t,r.domain=l?z.domain:void 0,0==n.state?n.reactions.add(r):E((function(){H(r,n)})),r.promise})),o=function(){var e=new r,t=P(e);this.promise=e,this.resolve=Q(ee,t),this.reject=Q(X,t)},O.f=U=function(e){return e===D||undefined===e?new o(e):q(e)},!s&&g(C)&&M!==Object.prototype)){a=M.then,N||p(M,"then",(function(e,t){var n=this;return new D((function(e,t){c(a,n,e,t)})).then(e,t)}),{unsafe:!0});try{delete M.constructor}catch(e){}f&&f(M,L)}i({global:!0,constructor:!0,wrap:!0,forced:T},{Promise:D}),h(D,j,!1,!0),d(j)},44349:(e,t,n)=>{"use strict";var r=n(76887),o=n(82529),a=n(6991),i=n(95981),s=n(626),l=n(57475),u=n(70487),c=n(56584),p=n(95929),f=a&&a.prototype;if(r({target:"Promise",proto:!0,real:!0,forced:!!a&&i((function(){f.finally.call({then:function(){}},(function(){}))}))},{finally:function(e){var t=u(this,s("Promise")),n=l(e);return this.then(n?function(n){return c(t,e()).then((function(){return n}))}:e,n?function(n){return c(t,e()).then((function(){throw n}))}:e)}}),!o&&l(a)){var h=s("Promise").prototype.finally;f.finally!==h&&p(f,"finally",h,{unsafe:!0})}},98881:(e,t,n)=>{n(26934),n(16890),n(83376),n(55921),n(64069),n(14482)},55921:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(24883),i=n(69520),s=n(40002),l=n(93091);r({target:"Promise",stat:!0,forced:n(31542)},{race:function(e){var t=this,n=i.f(t),r=n.reject,u=s((function(){var i=a(t.resolve);l(e,(function(e){o(i,t,e).then(n.resolve,r)}))}));return u.error&&r(u.value),n.promise}})},64069:(e,t,n)=>{"use strict";var r=n(76887),o=n(78834),a=n(69520);r({target:"Promise",stat:!0,forced:n(67742).CONSTRUCTOR},{reject:function(e){var t=a.f(this);return o(t.reject,void 0,e),t.promise}})},14482:(e,t,n)=>{"use strict";var r=n(76887),o=n(626),a=n(82529),i=n(6991),s=n(67742).CONSTRUCTOR,l=n(56584),u=o("Promise"),c=a&&!s;r({target:"Promise",stat:!0,forced:a||s},{resolve:function(e){return l(c&&this===u?i:this,e)}})},1502:()=>{},11035:(e,t,n)=>{"use strict";var r=n(76887),o=n(95329),a=n(70344),i=n(48219),s=n(85803),l=n(67772),u=o("".indexOf);r({target:"String",proto:!0,forced:!l("includes")},{includes:function(e){return!!~u(s(i(this)),s(a(e)),arguments.length>1?arguments[1]:void 0)}})},77971:(e,t,n)=>{"use strict";var r=n(64620).charAt,o=n(85803),a=n(45402),i=n(75105),s=n(23538),l="String Iterator",u=a.set,c=a.getterFor(l);i(String,"String",(function(e){u(this,{type:l,string:o(e),index:0})}),(function(){var e,t=c(this),n=t.string,o=t.index;return o>=n.length?s(void 0,!0):(e=r(n,o),t.index+=e.length,s(e,!1))}))},60986:(e,t,n)=>{n(76887)({target:"String",proto:!0},{repeat:n(16178)})},94761:(e,t,n)=>{"use strict";var r,o=n(76887),a=n(97484),i=n(49677).f,s=n(43057),l=n(85803),u=n(70344),c=n(48219),p=n(67772),f=n(82529),h=a("".startsWith),d=a("".slice),m=Math.min,g=p("startsWith");o({target:"String",proto:!0,forced:!!(f||g||(r=i(String.prototype,"startsWith"),!r||r.writable))&&!g},{startsWith:function(e){var t=l(c(this));u(e);var n=s(m(arguments.length>1?arguments[1]:void 0,t.length)),r=l(e);return h?h(t,r,n):d(t,n,n+r.length)===r}})},57398:(e,t,n)=>{"use strict";var r=n(76887),o=n(74853).trim;r({target:"String",proto:!0,forced:n(93093)("trim")},{trim:function(){return o(this)}})},8555:(e,t,n)=>{n(73464)("asyncIterator")},48616:(e,t,n)=>{"use strict";var r=n(76887),o=n(21899),a=n(78834),i=n(95329),s=n(82529),l=n(55746),u=n(63405),c=n(95981),p=n(90953),f=n(7046),h=n(96059),d=n(74529),m=n(83894),g=n(85803),y=n(31887),v=n(29290),b=n(14771),w=n(10946),E=n(684),x=n(87857),_=n(49677),S=n(65988),A=n(59938),C=n(36760),k=n(95929),O=n(29202),j=n(68726),T=n(44262),I=n(27748),N=n(99418),P=n(99813),R=n(11477),M=n(73464),D=n(29630),L=n(90904),B=n(45402),F=n(3610).forEach,z=T("hidden"),U="Symbol",q="prototype",$=B.set,V=B.getterFor(U),W=Object[q],H=o.Symbol,J=H&&H[q],K=o.TypeError,G=o.QObject,Z=_.f,Y=S.f,Q=E.f,X=C.f,ee=i([].push),te=j("symbols"),ne=j("op-symbols"),re=j("wks"),oe=!G||!G[q]||!G[q].findChild,ae=l&&c((function(){return 7!=v(Y({},"a",{get:function(){return Y(this,"a",{value:7}).a}})).a}))?function(e,t,n){var r=Z(W,t);r&&delete W[t],Y(e,t,n),r&&e!==W&&Y(W,t,r)}:Y,ie=function(e,t){var n=te[e]=v(J);return $(n,{type:U,tag:e,description:t}),l||(n.description=t),n},se=function(e,t,n){e===W&&se(ne,t,n),h(e);var r=m(t);return h(n),p(te,r)?(n.enumerable?(p(e,z)&&e[z][r]&&(e[z][r]=!1),n=v(n,{enumerable:y(0,!1)})):(p(e,z)||Y(e,z,y(1,{})),e[z][r]=!0),ae(e,r,n)):Y(e,r,n)},le=function(e,t){h(e);var n=d(t),r=b(n).concat(fe(n));return F(r,(function(t){l&&!a(ue,n,t)||se(e,t,n[t])})),e},ue=function(e){var t=m(e),n=a(X,this,t);return!(this===W&&p(te,t)&&!p(ne,t))&&(!(n||!p(this,t)||!p(te,t)||p(this,z)&&this[z][t])||n)},ce=function(e,t){var n=d(e),r=m(t);if(n!==W||!p(te,r)||p(ne,r)){var o=Z(n,r);return!o||!p(te,r)||p(n,z)&&n[z][r]||(o.enumerable=!0),o}},pe=function(e){var t=Q(d(e)),n=[];return F(t,(function(e){p(te,e)||p(I,e)||ee(n,e)})),n},fe=function(e){var t=e===W,n=Q(t?ne:d(e)),r=[];return F(n,(function(e){!p(te,e)||t&&!p(W,e)||ee(r,te[e])})),r};u||(k(J=(H=function(){if(f(J,this))throw K("Symbol is not a constructor");var e=arguments.length&&void 0!==arguments[0]?g(arguments[0]):void 0,t=N(e),n=function(e){this===W&&a(n,ne,e),p(this,z)&&p(this[z],t)&&(this[z][t]=!1),ae(this,t,y(1,e))};return l&&oe&&ae(W,t,{configurable:!0,set:n}),ie(t,e)})[q],"toString",(function(){return V(this).tag})),k(H,"withoutSetter",(function(e){return ie(N(e),e)})),C.f=ue,S.f=se,A.f=le,_.f=ce,w.f=E.f=pe,x.f=fe,R.f=function(e){return ie(P(e),e)},l&&(O(J,"description",{configurable:!0,get:function(){return V(this).description}}),s||k(W,"propertyIsEnumerable",ue,{unsafe:!0}))),r({global:!0,constructor:!0,wrap:!0,forced:!u,sham:!u},{Symbol:H}),F(b(re),(function(e){M(e)})),r({target:U,stat:!0,forced:!u},{useSetter:function(){oe=!0},useSimple:function(){oe=!1}}),r({target:"Object",stat:!0,forced:!u,sham:!l},{create:function(e,t){return void 0===t?v(e):le(v(e),t)},defineProperty:se,defineProperties:le,getOwnPropertyDescriptor:ce}),r({target:"Object",stat:!0,forced:!u},{getOwnPropertyNames:pe}),D(),L(H,U),I[z]=!0},52615:()=>{},64523:(e,t,n)=>{var r=n(76887),o=n(626),a=n(90953),i=n(85803),s=n(68726),l=n(34680),u=s("string-to-symbol-registry"),c=s("symbol-to-string-registry");r({target:"Symbol",stat:!0,forced:!l},{for:function(e){var t=i(e);if(a(u,t))return u[t];var n=o("Symbol")(t);return u[t]=n,c[n]=t,n}})},21732:(e,t,n)=>{n(73464)("hasInstance")},35903:(e,t,n)=>{n(73464)("isConcatSpreadable")},1825:(e,t,n)=>{n(73464)("iterator")},35824:(e,t,n)=>{n(48616),n(64523),n(38608),n(32619),n(37144)},38608:(e,t,n)=>{var r=n(76887),o=n(90953),a=n(56664),i=n(69826),s=n(68726),l=n(34680),u=s("symbol-to-string-registry");r({target:"Symbol",stat:!0,forced:!l},{keyFor:function(e){if(!a(e))throw TypeError(i(e)+" is not a symbol");if(o(u,e))return u[e]}})},45915:(e,t,n)=>{n(73464)("matchAll")},28394:(e,t,n)=>{n(73464)("match")},61766:(e,t,n)=>{n(73464)("replace")},62737:(e,t,n)=>{n(73464)("search")},89911:(e,t,n)=>{n(73464)("species")},74315:(e,t,n)=>{n(73464)("split")},63131:(e,t,n)=>{var r=n(73464),o=n(29630);r("toPrimitive"),o()},64714:(e,t,n)=>{var r=n(626),o=n(73464),a=n(90904);o("toStringTag"),a(r("Symbol"),"Symbol")},70659:(e,t,n)=>{n(73464)("unscopables")},97522:(e,t,n)=>{var r=n(99813),o=n(65988).f,a=r("metadata"),i=Function.prototype;void 0===i[a]&&o(i,a,{value:null})},28783:(e,t,n)=>{n(73464)("asyncDispose")},43975:(e,t,n)=>{n(73464)("dispose")},97618:(e,t,n)=>{n(76887)({target:"Symbol",stat:!0},{isRegisteredSymbol:n(32087)})},22731:(e,t,n)=>{n(76887)({target:"Symbol",stat:!0,name:"isRegisteredSymbol"},{isRegistered:n(32087)})},6989:(e,t,n)=>{n(76887)({target:"Symbol",stat:!0,forced:!0},{isWellKnownSymbol:n(96559)})},85605:(e,t,n)=>{n(76887)({target:"Symbol",stat:!0,name:"isWellKnownSymbol",forced:!0},{isWellKnown:n(96559)})},65799:(e,t,n)=>{n(73464)("matcher")},31943:(e,t,n)=>{n(73464)("metadataKey")},45414:(e,t,n)=>{n(73464)("metadata")},46774:(e,t,n)=>{n(73464)("observable")},80620:(e,t,n)=>{n(73464)("patternMatch")},36172:(e,t,n)=>{n(73464)("replaceAll")},7634:(e,t,n)=>{n(66274);var r=n(63281),o=n(21899),a=n(9697),i=n(32029),s=n(12077),l=n(99813)("toStringTag");for(var u in r){var c=o[u],p=c&&c.prototype;p&&a(p)!==l&&i(p,l,u),s[u]=s.Array}},79229:(e,t,n)=>{var r=n(76887),o=n(21899),a=n(37620)(o.setInterval,!0);r({global:!0,bind:!0,forced:o.setInterval!==a},{setInterval:a})},17749:(e,t,n)=>{var r=n(76887),o=n(21899),a=n(37620)(o.setTimeout,!0);r({global:!0,bind:!0,forced:o.setTimeout!==a},{setTimeout:a})},71249:(e,t,n)=>{n(79229),n(17749)},62524:(e,t,n)=>{"use strict";n(66274);var r=n(76887),o=n(21899),a=n(78834),i=n(95329),s=n(55746),l=n(14766),u=n(95929),c=n(29202),p=n(94380),f=n(90904),h=n(53847),d=n(45402),m=n(5743),g=n(57475),y=n(90953),v=n(86843),b=n(9697),w=n(96059),E=n(10941),x=n(85803),_=n(29290),S=n(31887),A=n(53476),C=n(22902),k=n(18348),O=n(99813),j=n(61388),T=O("iterator"),I="URLSearchParams",N=I+"Iterator",P=d.set,R=d.getterFor(I),M=d.getterFor(N),D=Object.getOwnPropertyDescriptor,L=function(e){if(!s)return o[e];var t=D(o,e);return t&&t.value},B=L("fetch"),F=L("Request"),z=L("Headers"),U=F&&F.prototype,q=z&&z.prototype,$=o.RegExp,V=o.TypeError,W=o.decodeURIComponent,H=o.encodeURIComponent,J=i("".charAt),K=i([].join),G=i([].push),Z=i("".replace),Y=i([].shift),Q=i([].splice),X=i("".split),ee=i("".slice),te=/\+/g,ne=Array(4),re=function(e){return ne[e-1]||(ne[e-1]=$("((?:%[\\da-f]{2}){"+e+"})","gi"))},oe=function(e){try{return W(e)}catch(t){return e}},ae=function(e){var t=Z(e,te," "),n=4;try{return W(t)}catch(e){for(;n;)t=Z(t,re(n--),oe);return t}},ie=/[!'()~]|%20/g,se={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+"},le=function(e){return se[e]},ue=function(e){return Z(H(e),ie,le)},ce=h((function(e,t){P(this,{type:N,iterator:A(R(e).entries),kind:t})}),"Iterator",(function(){var e=M(this),t=e.kind,n=e.iterator.next(),r=n.value;return n.done||(n.value="keys"===t?r.key:"values"===t?r.value:[r.key,r.value]),n}),!0),pe=function(e){this.entries=[],this.url=null,void 0!==e&&(E(e)?this.parseObject(e):this.parseQuery("string"==typeof e?"?"===J(e,0)?ee(e,1):e:x(e)))};pe.prototype={type:I,bindURL:function(e){this.url=e,this.update()},parseObject:function(e){var t,n,r,o,i,s,l,u=C(e);if(u)for(n=(t=A(e,u)).next;!(r=a(n,t)).done;){if(i=(o=A(w(r.value))).next,(s=a(i,o)).done||(l=a(i,o)).done||!a(i,o).done)throw V("Expected sequence with length 2");G(this.entries,{key:x(s.value),value:x(l.value)})}else for(var c in e)y(e,c)&&G(this.entries,{key:c,value:x(e[c])})},parseQuery:function(e){if(e)for(var t,n,r=X(e,"&"),o=0;o0?arguments[0]:void 0));s||(this.size=e.entries.length)},he=fe.prototype;if(p(he,{append:function(e,t){var n=R(this);k(arguments.length,2),G(n.entries,{key:x(e),value:x(t)}),s||this.length++,n.updateURL()},delete:function(e){for(var t=R(this),n=k(arguments.length,1),r=t.entries,o=x(e),a=n<2?void 0:arguments[1],i=void 0===a?a:x(a),l=0;lt.key?1:-1})),e.updateURL()},forEach:function(e){for(var t,n=R(this).entries,r=v(e,arguments.length>1?arguments[1]:void 0),o=0;o1?ge(arguments[1]):{})}}),g(F)){var ye=function(e){return m(this,U),new F(e,arguments.length>1?ge(arguments[1]):{})};U.constructor=ye,ye.prototype=U,r({global:!0,constructor:!0,dontCallGetSet:!0,forced:!0},{Request:ye})}}e.exports={URLSearchParams:fe,getState:R}},16454:()=>{},73305:()=>{},95304:(e,t,n)=>{n(62524)},62337:()=>{},84630:(e,t,n)=>{var r=n(76887),o=n(626),a=n(95981),i=n(18348),s=n(85803),l=n(14766),u=o("URL");r({target:"URL",stat:!0,forced:!(l&&a((function(){u.canParse()})))},{canParse:function(e){var t=i(arguments.length,1),n=s(e),r=t<2||void 0===arguments[1]?void 0:s(arguments[1]);try{return!!new u(n,r)}catch(e){return!1}}})},47250:(e,t,n)=>{"use strict";n(77971);var r,o=n(76887),a=n(55746),i=n(14766),s=n(21899),l=n(86843),u=n(95329),c=n(95929),p=n(29202),f=n(5743),h=n(90953),d=n(24420),m=n(11354),g=n(15790),y=n(64620).codeAt,v=n(73291),b=n(85803),w=n(90904),E=n(18348),x=n(62524),_=n(45402),S=_.set,A=_.getterFor("URL"),C=x.URLSearchParams,k=x.getState,O=s.URL,j=s.TypeError,T=s.parseInt,I=Math.floor,N=Math.pow,P=u("".charAt),R=u(/./.exec),M=u([].join),D=u(1..toString),L=u([].pop),B=u([].push),F=u("".replace),z=u([].shift),U=u("".split),q=u("".slice),$=u("".toLowerCase),V=u([].unshift),W="Invalid scheme",H="Invalid host",J="Invalid port",K=/[a-z]/i,G=/[\d+-.a-z]/i,Z=/\d/,Y=/^0x/i,Q=/^[0-7]+$/,X=/^\d+$/,ee=/^[\da-f]+$/i,te=/[\0\t\n\r #%/:<>?@[\\\]^|]/,ne=/[\0\t\n\r #/:<>?@[\\\]^|]/,re=/^[\u0000-\u0020]+/,oe=/(^|[^\u0000-\u0020])[\u0000-\u0020]+$/,ae=/[\t\n\r]/g,ie=function(e){var t,n,r,o;if("number"==typeof e){for(t=[],n=0;n<4;n++)V(t,e%256),e=I(e/256);return M(t,".")}if("object"==typeof e){for(t="",r=function(e){for(var t=null,n=1,r=null,o=0,a=0;a<8;a++)0!==e[a]?(o>n&&(t=r,n=o),r=null,o=0):(null===r&&(r=a),++o);return o>n&&(t=r,n=o),t}(e),n=0;n<8;n++)o&&0===e[n]||(o&&(o=!1),r===n?(t+=n?":":"::",o=!0):(t+=D(e[n],16),n<7&&(t+=":")));return"["+t+"]"}return e},se={},le=d({},se,{" ":1,'"':1,"<":1,">":1,"`":1}),ue=d({},le,{"#":1,"?":1,"{":1,"}":1}),ce=d({},ue,{"/":1,":":1,";":1,"=":1,"@":1,"[":1,"\\":1,"]":1,"^":1,"|":1}),pe=function(e,t){var n=y(e,0);return n>32&&n<127&&!h(t,e)?e:encodeURIComponent(e)},fe={ftp:21,file:null,http:80,https:443,ws:80,wss:443},he=function(e,t){var n;return 2==e.length&&R(K,P(e,0))&&(":"==(n=P(e,1))||!t&&"|"==n)},de=function(e){var t;return e.length>1&&he(q(e,0,2))&&(2==e.length||"/"===(t=P(e,2))||"\\"===t||"?"===t||"#"===t)},me=function(e){return"."===e||"%2e"===$(e)},ge={},ye={},ve={},be={},we={},Ee={},xe={},_e={},Se={},Ae={},Ce={},ke={},Oe={},je={},Te={},Ie={},Ne={},Pe={},Re={},Me={},De={},Le=function(e,t,n){var r,o,a,i=b(e);if(t){if(o=this.parse(i))throw j(o);this.searchParams=null}else{if(void 0!==n&&(r=new Le(n,!0)),o=this.parse(i,null,r))throw j(o);(a=k(new C)).bindURL(this),this.searchParams=a}};Le.prototype={type:"URL",parse:function(e,t,n){var o,a,i,s,l,u=this,c=t||ge,p=0,f="",d=!1,y=!1,v=!1;for(e=b(e),t||(u.scheme="",u.username="",u.password="",u.host=null,u.port=null,u.path=[],u.query=null,u.fragment=null,u.cannotBeABaseURL=!1,e=F(e,re,""),e=F(e,oe,"$1")),e=F(e,ae,""),o=m(e);p<=o.length;){switch(a=o[p],c){case ge:if(!a||!R(K,a)){if(t)return W;c=ve;continue}f+=$(a),c=ye;break;case ye:if(a&&(R(G,a)||"+"==a||"-"==a||"."==a))f+=$(a);else{if(":"!=a){if(t)return W;f="",c=ve,p=0;continue}if(t&&(u.isSpecial()!=h(fe,f)||"file"==f&&(u.includesCredentials()||null!==u.port)||"file"==u.scheme&&!u.host))return;if(u.scheme=f,t)return void(u.isSpecial()&&fe[u.scheme]==u.port&&(u.port=null));f="","file"==u.scheme?c=je:u.isSpecial()&&n&&n.scheme==u.scheme?c=be:u.isSpecial()?c=_e:"/"==o[p+1]?(c=we,p++):(u.cannotBeABaseURL=!0,B(u.path,""),c=Re)}break;case ve:if(!n||n.cannotBeABaseURL&&"#"!=a)return W;if(n.cannotBeABaseURL&&"#"==a){u.scheme=n.scheme,u.path=g(n.path),u.query=n.query,u.fragment="",u.cannotBeABaseURL=!0,c=De;break}c="file"==n.scheme?je:Ee;continue;case be:if("/"!=a||"/"!=o[p+1]){c=Ee;continue}c=Se,p++;break;case we:if("/"==a){c=Ae;break}c=Pe;continue;case Ee:if(u.scheme=n.scheme,a==r)u.username=n.username,u.password=n.password,u.host=n.host,u.port=n.port,u.path=g(n.path),u.query=n.query;else if("/"==a||"\\"==a&&u.isSpecial())c=xe;else if("?"==a)u.username=n.username,u.password=n.password,u.host=n.host,u.port=n.port,u.path=g(n.path),u.query="",c=Me;else{if("#"!=a){u.username=n.username,u.password=n.password,u.host=n.host,u.port=n.port,u.path=g(n.path),u.path.length--,c=Pe;continue}u.username=n.username,u.password=n.password,u.host=n.host,u.port=n.port,u.path=g(n.path),u.query=n.query,u.fragment="",c=De}break;case xe:if(!u.isSpecial()||"/"!=a&&"\\"!=a){if("/"!=a){u.username=n.username,u.password=n.password,u.host=n.host,u.port=n.port,c=Pe;continue}c=Ae}else c=Se;break;case _e:if(c=Se,"/"!=a||"/"!=P(f,p+1))continue;p++;break;case Se:if("/"!=a&&"\\"!=a){c=Ae;continue}break;case Ae:if("@"==a){d&&(f="%40"+f),d=!0,i=m(f);for(var w=0;w65535)return J;u.port=u.isSpecial()&&_===fe[u.scheme]?null:_,f=""}if(t)return;c=Ne;continue}return J}f+=a;break;case je:if(u.scheme="file","/"==a||"\\"==a)c=Te;else{if(!n||"file"!=n.scheme){c=Pe;continue}if(a==r)u.host=n.host,u.path=g(n.path),u.query=n.query;else if("?"==a)u.host=n.host,u.path=g(n.path),u.query="",c=Me;else{if("#"!=a){de(M(g(o,p),""))||(u.host=n.host,u.path=g(n.path),u.shortenPath()),c=Pe;continue}u.host=n.host,u.path=g(n.path),u.query=n.query,u.fragment="",c=De}}break;case Te:if("/"==a||"\\"==a){c=Ie;break}n&&"file"==n.scheme&&!de(M(g(o,p),""))&&(he(n.path[0],!0)?B(u.path,n.path[0]):u.host=n.host),c=Pe;continue;case Ie:if(a==r||"/"==a||"\\"==a||"?"==a||"#"==a){if(!t&&he(f))c=Pe;else if(""==f){if(u.host="",t)return;c=Ne}else{if(s=u.parseHost(f))return s;if("localhost"==u.host&&(u.host=""),t)return;f="",c=Ne}continue}f+=a;break;case Ne:if(u.isSpecial()){if(c=Pe,"/"!=a&&"\\"!=a)continue}else if(t||"?"!=a)if(t||"#"!=a){if(a!=r&&(c=Pe,"/"!=a))continue}else u.fragment="",c=De;else u.query="",c=Me;break;case Pe:if(a==r||"/"==a||"\\"==a&&u.isSpecial()||!t&&("?"==a||"#"==a)){if(".."===(l=$(l=f))||"%2e."===l||".%2e"===l||"%2e%2e"===l?(u.shortenPath(),"/"==a||"\\"==a&&u.isSpecial()||B(u.path,"")):me(f)?"/"==a||"\\"==a&&u.isSpecial()||B(u.path,""):("file"==u.scheme&&!u.path.length&&he(f)&&(u.host&&(u.host=""),f=P(f,0)+":"),B(u.path,f)),f="","file"==u.scheme&&(a==r||"?"==a||"#"==a))for(;u.path.length>1&&""===u.path[0];)z(u.path);"?"==a?(u.query="",c=Me):"#"==a&&(u.fragment="",c=De)}else f+=pe(a,ue);break;case Re:"?"==a?(u.query="",c=Me):"#"==a?(u.fragment="",c=De):a!=r&&(u.path[0]+=pe(a,se));break;case Me:t||"#"!=a?a!=r&&("'"==a&&u.isSpecial()?u.query+="%27":u.query+="#"==a?"%23":pe(a,se)):(u.fragment="",c=De);break;case De:a!=r&&(u.fragment+=pe(a,le))}p++}},parseHost:function(e){var t,n,r;if("["==P(e,0)){if("]"!=P(e,e.length-1))return H;if(t=function(e){var t,n,r,o,a,i,s,l=[0,0,0,0,0,0,0,0],u=0,c=null,p=0,f=function(){return P(e,p)};if(":"==f()){if(":"!=P(e,1))return;p+=2,c=++u}for(;f();){if(8==u)return;if(":"!=f()){for(t=n=0;n<4&&R(ee,f());)t=16*t+T(f(),16),p++,n++;if("."==f()){if(0==n)return;if(p-=n,u>6)return;for(r=0;f();){if(o=null,r>0){if(!("."==f()&&r<4))return;p++}if(!R(Z,f()))return;for(;R(Z,f());){if(a=T(f(),10),null===o)o=a;else{if(0==o)return;o=10*o+a}if(o>255)return;p++}l[u]=256*l[u]+o,2!=++r&&4!=r||u++}if(4!=r)return;break}if(":"==f()){if(p++,!f())return}else if(f())return;l[u++]=t}else{if(null!==c)return;p++,c=++u}}if(null!==c)for(i=u-c,u=7;0!=u&&i>0;)s=l[u],l[u--]=l[c+i-1],l[c+--i]=s;else if(8!=u)return;return l}(q(e,1,-1)),!t)return H;this.host=t}else if(this.isSpecial()){if(e=v(e),R(te,e))return H;if(t=function(e){var t,n,r,o,a,i,s,l=U(e,".");if(l.length&&""==l[l.length-1]&&l.length--,(t=l.length)>4)return e;for(n=[],r=0;r1&&"0"==P(o,0)&&(a=R(Y,o)?16:8,o=q(o,8==a?1:2)),""===o)i=0;else{if(!R(10==a?X:8==a?Q:ee,o))return e;i=T(o,a)}B(n,i)}for(r=0;r=N(256,5-t))return null}else if(i>255)return null;for(s=L(n),r=0;r1?arguments[1]:void 0,r=S(t,new Le(e,!1,n));a||(t.href=r.serialize(),t.origin=r.getOrigin(),t.protocol=r.getProtocol(),t.username=r.getUsername(),t.password=r.getPassword(),t.host=r.getHost(),t.hostname=r.getHostname(),t.port=r.getPort(),t.pathname=r.getPathname(),t.search=r.getSearch(),t.searchParams=r.getSearchParams(),t.hash=r.getHash())},Fe=Be.prototype,ze=function(e,t){return{get:function(){return A(this)[e]()},set:t&&function(e){return A(this)[t](e)},configurable:!0,enumerable:!0}};if(a&&(p(Fe,"href",ze("serialize","setHref")),p(Fe,"origin",ze("getOrigin")),p(Fe,"protocol",ze("getProtocol","setProtocol")),p(Fe,"username",ze("getUsername","setUsername")),p(Fe,"password",ze("getPassword","setPassword")),p(Fe,"host",ze("getHost","setHost")),p(Fe,"hostname",ze("getHostname","setHostname")),p(Fe,"port",ze("getPort","setPort")),p(Fe,"pathname",ze("getPathname","setPathname")),p(Fe,"search",ze("getSearch","setSearch")),p(Fe,"searchParams",ze("getSearchParams")),p(Fe,"hash",ze("getHash","setHash"))),c(Fe,"toJSON",(function(){return A(this).serialize()}),{enumerable:!0}),c(Fe,"toString",(function(){return A(this).serialize()}),{enumerable:!0}),O){var Ue=O.createObjectURL,qe=O.revokeObjectURL;Ue&&c(Be,"createObjectURL",l(Ue,O)),qe&&c(Be,"revokeObjectURL",l(qe,O))}w(Be,"URL"),o({global:!0,constructor:!0,forced:!i,sham:!a},{URL:Be})},33601:(e,t,n)=>{n(47250)},98947:()=>{},24848:(e,t,n)=>{var r=n(54493);e.exports=r},83363:(e,t,n)=>{var r=n(24034);e.exports=r},62908:(e,t,n)=>{var r=n(12710);e.exports=r},49216:(e,t,n)=>{var r=n(99324);e.exports=r},56668:(e,t,n)=>{var r=n(95909);e.exports=r},74719:(e,t,n)=>{var r=n(14423);e.exports=r},57784:(e,t,n)=>{var r=n(81103);e.exports=r},28196:(e,t,n)=>{var r=n(16246);e.exports=r},8065:(e,t,n)=>{var r=n(56043);e.exports=r},57448:(e,t,n)=>{n(7634);var r=n(9697),o=n(90953),a=n(7046),i=n(62908),s=Array.prototype,l={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.entries;return e===s||a(s,e)&&t===s.entries||o(l,r(e))?i:t}},29455:(e,t,n)=>{var r=n(13160);e.exports=r},69743:(e,t,n)=>{var r=n(80446);e.exports=r},11955:(e,t,n)=>{var r=n(2480);e.exports=r},96064:(e,t,n)=>{var r=n(7147);e.exports=r},61577:(e,t,n)=>{var r=n(32236);e.exports=r},46279:(e,t,n)=>{n(7634);var r=n(9697),o=n(90953),a=n(7046),i=n(49216),s=Array.prototype,l={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.forEach;return e===s||a(s,e)&&t===s.forEach||o(l,r(e))?i:t}},33778:(e,t,n)=>{var r=n(58557);e.exports=r},19373:(e,t,n)=>{var r=n(34570);e.exports=r},73819:(e,t,n)=>{n(7634);var r=n(9697),o=n(90953),a=n(7046),i=n(56668),s=Array.prototype,l={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.keys;return e===s||a(s,e)&&t===s.keys||o(l,r(e))?i:t}},11022:(e,t,n)=>{var r=n(57564);e.exports=r},61798:(e,t,n)=>{var r=n(88287);e.exports=r},52759:(e,t,n)=>{var r=n(93993);e.exports=r},52527:(e,t,n)=>{var r=n(68025);e.exports=r},36857:(e,t,n)=>{var r=n(59257);e.exports=r},82073:(e,t,n)=>{var r=n(69601);e.exports=r},45286:(e,t,n)=>{var r=n(28299);e.exports=r},62856:(e,t,n)=>{var r=n(69355);e.exports=r},2348:(e,t,n)=>{var r=n(18339);e.exports=r},35178:(e,t,n)=>{var r=n(71611);e.exports=r},76361:(e,t,n)=>{var r=n(62774);e.exports=r},71815:(e,t,n)=>{n(7634);var r=n(9697),o=n(90953),a=n(7046),i=n(74719),s=Array.prototype,l={DOMTokenList:!0,NodeList:!0};e.exports=function(e){var t=e.values;return e===s||a(s,e)&&t===s.values||o(l,r(e))?i:t}},8933:(e,t,n)=>{var r=n(84426);e.exports=r},15868:(e,t,n)=>{var r=n(91018);n(7634),e.exports=r},63383:(e,t,n)=>{var r=n(45999);e.exports=r},57396:(e,t,n)=>{var r=n(7702);e.exports=r},41910:(e,t,n)=>{var r=n(48171);e.exports=r},79427:(e,t,n)=>{var r=n(286);e.exports=r},62857:(e,t,n)=>{var r=n(92766);e.exports=r},9534:(e,t,n)=>{var r=n(30498);e.exports=r},23059:(e,t,n)=>{var r=n(48494);e.exports=r},47795:(e,t,n)=>{var r=n(98430);e.exports=r},27460:(e,t,n)=>{var r=n(52956);n(7634),e.exports=r},27989:(e,t,n)=>{n(71249);var r=n(54058);e.exports=r.setTimeout},92547:(e,t,n)=>{var r=n(57473);n(7634),e.exports=r},46509:(e,t,n)=>{var r=n(24227);n(7634),e.exports=r},35774:(e,t,n)=>{var r=n(62978);e.exports=r},57641:(e,t,n)=>{var r=n(71459);e.exports=r},47610:(e,t,n)=>{n(95304),n(16454),n(73305),n(62337);var r=n(54058);e.exports=r.URLSearchParams},71459:(e,t,n)=>{n(47610),n(33601),n(84630),n(98947);var r=n(54058);e.exports=r.URL},31905:function(){!function(e){!function(t){var n="URLSearchParams"in e,r="Symbol"in e&&"iterator"in Symbol,o="FileReader"in e&&"Blob"in e&&function(){try{return new Blob,!0}catch(e){return!1}}(),a="FormData"in e,i="ArrayBuffer"in e;if(i)var s=["[object Int8Array]","[object Uint8Array]","[object Uint8ClampedArray]","[object Int16Array]","[object Uint16Array]","[object Int32Array]","[object Uint32Array]","[object Float32Array]","[object Float64Array]"],l=ArrayBuffer.isView||function(e){return e&&s.indexOf(Object.prototype.toString.call(e))>-1};function u(e){if("string"!=typeof e&&(e=String(e)),/[^a-z0-9\-#$%&'*+.^_`|~]/i.test(e))throw new TypeError("Invalid character in header field name");return e.toLowerCase()}function c(e){return"string"!=typeof e&&(e=String(e)),e}function p(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return r&&(t[Symbol.iterator]=function(){return t}),t}function f(e){this.map={},e instanceof f?e.forEach((function(e,t){this.append(t,e)}),this):Array.isArray(e)?e.forEach((function(e){this.append(e[0],e[1])}),this):e&&Object.getOwnPropertyNames(e).forEach((function(t){this.append(t,e[t])}),this)}function h(e){if(e.bodyUsed)return Promise.reject(new TypeError("Already read"));e.bodyUsed=!0}function d(e){return new Promise((function(t,n){e.onload=function(){t(e.result)},e.onerror=function(){n(e.error)}}))}function m(e){var t=new FileReader,n=d(t);return t.readAsArrayBuffer(e),n}function g(e){if(e.slice)return e.slice(0);var t=new Uint8Array(e.byteLength);return t.set(new Uint8Array(e)),t.buffer}function y(){return this.bodyUsed=!1,this._initBody=function(e){var t;this._bodyInit=e,e?"string"==typeof e?this._bodyText=e:o&&Blob.prototype.isPrototypeOf(e)?this._bodyBlob=e:a&&FormData.prototype.isPrototypeOf(e)?this._bodyFormData=e:n&&URLSearchParams.prototype.isPrototypeOf(e)?this._bodyText=e.toString():i&&o&&((t=e)&&DataView.prototype.isPrototypeOf(t))?(this._bodyArrayBuffer=g(e.buffer),this._bodyInit=new Blob([this._bodyArrayBuffer])):i&&(ArrayBuffer.prototype.isPrototypeOf(e)||l(e))?this._bodyArrayBuffer=g(e):this._bodyText=e=Object.prototype.toString.call(e):this._bodyText="",this.headers.get("content-type")||("string"==typeof e?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):n&&URLSearchParams.prototype.isPrototypeOf(e)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},o&&(this.blob=function(){var e=h(this);if(e)return e;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyArrayBuffer)return Promise.resolve(new Blob([this._bodyArrayBuffer]));if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this._bodyArrayBuffer?h(this)||Promise.resolve(this._bodyArrayBuffer):this.blob().then(m)}),this.text=function(){var e,t,n,r=h(this);if(r)return r;if(this._bodyBlob)return e=this._bodyBlob,t=new FileReader,n=d(t),t.readAsText(e),n;if(this._bodyArrayBuffer)return Promise.resolve(function(e){for(var t=new Uint8Array(e),n=new Array(t.length),r=0;r-1?r:n),this.mode=t.mode||this.mode||null,this.signal=t.signal||this.signal,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&o)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(o)}function w(e){var t=new FormData;return e.trim().split("&").forEach((function(e){if(e){var n=e.split("="),r=n.shift().replace(/\+/g," "),o=n.join("=").replace(/\+/g," ");t.append(decodeURIComponent(r),decodeURIComponent(o))}})),t}function E(e,t){t||(t={}),this.type="default",this.status=void 0===t.status?200:t.status,this.ok=this.status>=200&&this.status<300,this.statusText="statusText"in t?t.statusText:"OK",this.headers=new f(t.headers),this.url=t.url||"",this._initBody(e)}b.prototype.clone=function(){return new b(this,{body:this._bodyInit})},y.call(b.prototype),y.call(E.prototype),E.prototype.clone=function(){return new E(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new f(this.headers),url:this.url})},E.error=function(){var e=new E(null,{status:0,statusText:""});return e.type="error",e};var x=[301,302,303,307,308];E.redirect=function(e,t){if(-1===x.indexOf(t))throw new RangeError("Invalid status code");return new E(null,{status:t,headers:{location:e}})},t.DOMException=e.DOMException;try{new t.DOMException}catch(e){t.DOMException=function(e,t){this.message=e,this.name=t;var n=Error(e);this.stack=n.stack},t.DOMException.prototype=Object.create(Error.prototype),t.DOMException.prototype.constructor=t.DOMException}function _(e,n){return new Promise((function(r,a){var i=new b(e,n);if(i.signal&&i.signal.aborted)return a(new t.DOMException("Aborted","AbortError"));var s=new XMLHttpRequest;function l(){s.abort()}s.onload=function(){var e,t,n={status:s.status,statusText:s.statusText,headers:(e=s.getAllResponseHeaders()||"",t=new f,e.replace(/\r?\n[\t ]+/g," ").split(/\r?\n/).forEach((function(e){var n=e.split(":"),r=n.shift().trim();if(r){var o=n.join(":").trim();t.append(r,o)}})),t)};n.url="responseURL"in s?s.responseURL:n.headers.get("X-Request-URL");var o="response"in s?s.response:s.responseText;r(new E(o,n))},s.onerror=function(){a(new TypeError("Network request failed"))},s.ontimeout=function(){a(new TypeError("Network request failed"))},s.onabort=function(){a(new t.DOMException("Aborted","AbortError"))},s.open(i.method,i.url,!0),"include"===i.credentials?s.withCredentials=!0:"omit"===i.credentials&&(s.withCredentials=!1),"responseType"in s&&o&&(s.responseType="blob"),i.headers.forEach((function(e,t){s.setRequestHeader(t,e)})),i.signal&&(i.signal.addEventListener("abort",l),s.onreadystatechange=function(){4===s.readyState&&i.signal.removeEventListener("abort",l)}),s.send(void 0===i._bodyInit?null:i._bodyInit)}))}_.polyfill=!0,e.fetch||(e.fetch=_,e.Headers=f,e.Request=b,e.Response=E),t.Headers=f,t.Request=b,t.Response=E,t.fetch=_,Object.defineProperty(t,"__esModule",{value:!0})}({})}("undefined"!=typeof self?self:this)},8269:function(e,t,n){var r;r=void 0!==n.g?n.g:this,e.exports=function(e){if(e.CSS&&e.CSS.escape)return e.CSS.escape;var t=function(e){if(0==arguments.length)throw new TypeError("`CSS.escape` requires an argument.");for(var t,n=String(e),r=n.length,o=-1,a="",i=n.charCodeAt(0);++o=1&&t<=31||127==t||0==o&&t>=48&&t<=57||1==o&&t>=48&&t<=57&&45==i?"\\"+t.toString(16)+" ":0==o&&1==r&&45==t||!(t>=128||45==t||95==t||t>=48&&t<=57||t>=65&&t<=90||t>=97&&t<=122)?"\\"+n.charAt(o):n.charAt(o):a+="�";return a};return e.CSS||(e.CSS={}),e.CSS.escape=t,t}(r)},27698:(e,t,n)=>{"use strict";var r=n(48764).Buffer;function o(e){return e instanceof r||e instanceof Date||e instanceof RegExp}function a(e){if(e instanceof r){var t=r.alloc?r.alloc(e.length):new r(e.length);return e.copy(t),t}if(e instanceof Date)return new Date(e.getTime());if(e instanceof RegExp)return new RegExp(e);throw new Error("Unexpected situation")}function i(e){var t=[];return e.forEach((function(e,n){"object"==typeof e&&null!==e?Array.isArray(e)?t[n]=i(e):o(e)?t[n]=a(e):t[n]=l({},e):t[n]=e})),t}function s(e,t){return"__proto__"===t?void 0:e[t]}var l=e.exports=function(){if(arguments.length<1||"object"!=typeof arguments[0])return!1;if(arguments.length<2)return arguments[0];var e,t,n=arguments[0];return Array.prototype.slice.call(arguments,1).forEach((function(r){"object"!=typeof r||null===r||Array.isArray(r)||Object.keys(r).forEach((function(u){return t=s(n,u),(e=s(r,u))===n?void 0:"object"!=typeof e||null===e?void(n[u]=e):Array.isArray(e)?void(n[u]=i(e)):o(e)?void(n[u]=a(e)):"object"!=typeof t||null===t||Array.isArray(t)?void(n[u]=l({},e)):void(n[u]=l(t,e))}))})),n}},9996:e=>{"use strict";var t=function(e){return function(e){return!!e&&"object"==typeof e}(e)&&!function(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||function(e){return e.$$typeof===n}(e)}(e)};var n="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function r(e,t){return!1!==t.clone&&t.isMergeableObject(e)?l((n=e,Array.isArray(n)?[]:{}),e,t):e;var n}function o(e,t,n){return e.concat(t).map((function(e){return r(e,n)}))}function a(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter((function(t){return Object.propertyIsEnumerable.call(e,t)})):[]}(e))}function i(e,t){try{return t in e}catch(e){return!1}}function s(e,t,n){var o={};return n.isMergeableObject(e)&&a(e).forEach((function(t){o[t]=r(e[t],n)})),a(t).forEach((function(a){(function(e,t){return i(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))})(e,a)||(i(e,a)&&n.isMergeableObject(t[a])?o[a]=function(e,t){if(!t.customMerge)return l;var n=t.customMerge(e);return"function"==typeof n?n:l}(a,n)(e[a],t[a],n):o[a]=r(t[a],n))})),o}function l(e,n,a){(a=a||{}).arrayMerge=a.arrayMerge||o,a.isMergeableObject=a.isMergeableObject||t,a.cloneUnlessOtherwiseSpecified=r;var i=Array.isArray(n);return i===Array.isArray(e)?i?a.arrayMerge(e,n,a):s(e,n,a):r(n,a)}l.all=function(e,t){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce((function(e,n){return l(e,n,t)}),{})};var u=l;e.exports=u},27856:function(e){e.exports=function(){"use strict";const{entries:e,setPrototypeOf:t,isFrozen:n,getPrototypeOf:r,getOwnPropertyDescriptor:o}=Object;let{freeze:a,seal:i,create:s}=Object,{apply:l,construct:u}="undefined"!=typeof Reflect&&Reflect;l||(l=function(e,t,n){return e.apply(t,n)}),a||(a=function(e){return e}),i||(i=function(e){return e}),u||(u=function(e,t){return new e(...t)});const c=E(Array.prototype.forEach),p=E(Array.prototype.pop),f=E(Array.prototype.push),h=E(String.prototype.toLowerCase),d=E(String.prototype.toString),m=E(String.prototype.match),g=E(String.prototype.replace),y=E(String.prototype.indexOf),v=E(String.prototype.trim),b=E(RegExp.prototype.test),w=x(TypeError);function E(e){return function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o/gm),F=i(/\${[\w\W]*}/gm),z=i(/^data-[\-\w.\u00B7-\uFFFF]/),U=i(/^aria-[\-\w]+$/),q=i(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|sms|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),$=i(/^(?:\w+script|data):/i),V=i(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),W=i(/^html$/i);var H=Object.freeze({__proto__:null,MUSTACHE_EXPR:L,ERB_EXPR:B,TMPLIT_EXPR:F,DATA_ATTR:z,ARIA_ATTR:U,IS_ALLOWED_URI:q,IS_SCRIPT_OR_DATA:$,ATTR_WHITESPACE:V,DOCTYPE_NAME:W});const J=()=>"undefined"==typeof window?null:window,K=function(e,t){if("object"!=typeof e||"function"!=typeof e.createPolicy)return null;let n=null;const r="data-tt-policy-suffix";t.currentScript&&t.currentScript.hasAttribute(r)&&(n=t.currentScript.getAttribute(r));const o="dompurify"+(n?"#"+n:"");try{return e.createPolicy(o,{createHTML:e=>e,createScriptURL:e=>e})}catch(e){return console.warn("TrustedTypes policy "+o+" could not be created."),null}};function G(){let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:J();const n=e=>G(e);if(n.version="3.0.2",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;const r=t.document;let{document:o}=t;const{DocumentFragment:i,HTMLTemplateElement:s,Node:l,Element:u,NodeFilter:E,NamedNodeMap:x=t.NamedNodeMap||t.MozNamedAttrMap,HTMLFormElement:L,DOMParser:B,trustedTypes:F}=t,z=u.prototype,U=A(z,"cloneNode"),$=A(z,"nextSibling"),V=A(z,"childNodes"),Z=A(z,"parentNode");if("function"==typeof s){const e=o.createElement("template");e.content&&e.content.ownerDocument&&(o=e.content.ownerDocument)}const Y=K(F,r),Q=Y?Y.createHTML(""):"",{implementation:X,createNodeIterator:ee,createDocumentFragment:te,getElementsByTagName:ne}=o,{importNode:re}=r;let oe={};n.isSupported="function"==typeof e&&"function"==typeof Z&&X&&void 0!==X.createHTMLDocument;const{MUSTACHE_EXPR:ae,ERB_EXPR:ie,TMPLIT_EXPR:se,DATA_ATTR:le,ARIA_ATTR:ue,IS_SCRIPT_OR_DATA:ce,ATTR_WHITESPACE:pe}=H;let{IS_ALLOWED_URI:fe}=H,he=null;const de=_({},[...C,...k,...O,...T,...N]);let me=null;const ge=_({},[...P,...R,...M,...D]);let ye=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),ve=null,be=null,we=!0,Ee=!0,xe=!1,_e=!0,Se=!1,Ae=!1,Ce=!1,ke=!1,Oe=!1,je=!1,Te=!1,Ie=!0,Ne=!1;const Pe="user-content-";let Re=!0,Me=!1,De={},Le=null;const Be=_({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]);let Fe=null;const ze=_({},["audio","video","img","source","image","track"]);let Ue=null;const qe=_({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),$e="http://www.w3.org/1998/Math/MathML",Ve="http://www.w3.org/2000/svg",We="http://www.w3.org/1999/xhtml";let He=We,Je=!1,Ke=null;const Ge=_({},[$e,Ve,We],d);let Ze;const Ye=["application/xhtml+xml","text/html"],Qe="text/html";let Xe,et=null;const tt=o.createElement("form"),nt=function(e){return e instanceof RegExp||e instanceof Function},rt=function(e){et&&et===e||(e&&"object"==typeof e||(e={}),e=S(e),Ze=Ze=-1===Ye.indexOf(e.PARSER_MEDIA_TYPE)?Qe:e.PARSER_MEDIA_TYPE,Xe="application/xhtml+xml"===Ze?d:h,he="ALLOWED_TAGS"in e?_({},e.ALLOWED_TAGS,Xe):de,me="ALLOWED_ATTR"in e?_({},e.ALLOWED_ATTR,Xe):ge,Ke="ALLOWED_NAMESPACES"in e?_({},e.ALLOWED_NAMESPACES,d):Ge,Ue="ADD_URI_SAFE_ATTR"in e?_(S(qe),e.ADD_URI_SAFE_ATTR,Xe):qe,Fe="ADD_DATA_URI_TAGS"in e?_(S(ze),e.ADD_DATA_URI_TAGS,Xe):ze,Le="FORBID_CONTENTS"in e?_({},e.FORBID_CONTENTS,Xe):Be,ve="FORBID_TAGS"in e?_({},e.FORBID_TAGS,Xe):{},be="FORBID_ATTR"in e?_({},e.FORBID_ATTR,Xe):{},De="USE_PROFILES"in e&&e.USE_PROFILES,we=!1!==e.ALLOW_ARIA_ATTR,Ee=!1!==e.ALLOW_DATA_ATTR,xe=e.ALLOW_UNKNOWN_PROTOCOLS||!1,_e=!1!==e.ALLOW_SELF_CLOSE_IN_ATTR,Se=e.SAFE_FOR_TEMPLATES||!1,Ae=e.WHOLE_DOCUMENT||!1,Oe=e.RETURN_DOM||!1,je=e.RETURN_DOM_FRAGMENT||!1,Te=e.RETURN_TRUSTED_TYPE||!1,ke=e.FORCE_BODY||!1,Ie=!1!==e.SANITIZE_DOM,Ne=e.SANITIZE_NAMED_PROPS||!1,Re=!1!==e.KEEP_CONTENT,Me=e.IN_PLACE||!1,fe=e.ALLOWED_URI_REGEXP||q,He=e.NAMESPACE||We,ye=e.CUSTOM_ELEMENT_HANDLING||{},e.CUSTOM_ELEMENT_HANDLING&&nt(e.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(ye.tagNameCheck=e.CUSTOM_ELEMENT_HANDLING.tagNameCheck),e.CUSTOM_ELEMENT_HANDLING&&nt(e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(ye.attributeNameCheck=e.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),e.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(ye.allowCustomizedBuiltInElements=e.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Se&&(Ee=!1),je&&(Oe=!0),De&&(he=_({},[...N]),me=[],!0===De.html&&(_(he,C),_(me,P)),!0===De.svg&&(_(he,k),_(me,R),_(me,D)),!0===De.svgFilters&&(_(he,O),_(me,R),_(me,D)),!0===De.mathMl&&(_(he,T),_(me,M),_(me,D))),e.ADD_TAGS&&(he===de&&(he=S(he)),_(he,e.ADD_TAGS,Xe)),e.ADD_ATTR&&(me===ge&&(me=S(me)),_(me,e.ADD_ATTR,Xe)),e.ADD_URI_SAFE_ATTR&&_(Ue,e.ADD_URI_SAFE_ATTR,Xe),e.FORBID_CONTENTS&&(Le===Be&&(Le=S(Le)),_(Le,e.FORBID_CONTENTS,Xe)),Re&&(he["#text"]=!0),Ae&&_(he,["html","head","body"]),he.table&&(_(he,["tbody"]),delete ve.tbody),a&&a(e),et=e)},ot=_({},["mi","mo","mn","ms","mtext"]),at=_({},["foreignobject","desc","title","annotation-xml"]),it=_({},["title","style","font","a","script"]),st=_({},k);_(st,O),_(st,j);const lt=_({},T);_(lt,I);const ut=function(e){let t=Z(e);t&&t.tagName||(t={namespaceURI:He,tagName:"template"});const n=h(e.tagName),r=h(t.tagName);return!!Ke[e.namespaceURI]&&(e.namespaceURI===Ve?t.namespaceURI===We?"svg"===n:t.namespaceURI===$e?"svg"===n&&("annotation-xml"===r||ot[r]):Boolean(st[n]):e.namespaceURI===$e?t.namespaceURI===We?"math"===n:t.namespaceURI===Ve?"math"===n&&at[r]:Boolean(lt[n]):e.namespaceURI===We?!(t.namespaceURI===Ve&&!at[r])&&!(t.namespaceURI===$e&&!ot[r])&&!lt[n]&&(it[n]||!st[n]):!("application/xhtml+xml"!==Ze||!Ke[e.namespaceURI]))},ct=function(e){f(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){e.remove()}},pt=function(e,t){try{f(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){f(n.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!me[e])if(Oe||je)try{ct(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},ft=function(e){let t,n;if(ke)e=""+e;else{const t=m(e,/^[\r\n\t ]+/);n=t&&t[0]}"application/xhtml+xml"===Ze&&He===We&&(e=''+e+"");const r=Y?Y.createHTML(e):e;if(He===We)try{t=(new B).parseFromString(r,Ze)}catch(e){}if(!t||!t.documentElement){t=X.createDocument(He,"template",null);try{t.documentElement.innerHTML=Je?Q:r}catch(e){}}const a=t.body||t.documentElement;return e&&n&&a.insertBefore(o.createTextNode(n),a.childNodes[0]||null),He===We?ne.call(t,Ae?"html":"body")[0]:Ae?t.documentElement:a},ht=function(e){return ee.call(e.ownerDocument||e,e,E.SHOW_ELEMENT|E.SHOW_COMMENT|E.SHOW_TEXT,null,!1)},dt=function(e){return e instanceof L&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof x)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},mt=function(e){return"object"==typeof l?e instanceof l:e&&"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName},gt=function(e,t,r){oe[e]&&c(oe[e],(e=>{e.call(n,t,r,et)}))},yt=function(e){let t;if(gt("beforeSanitizeElements",e,null),dt(e))return ct(e),!0;const r=Xe(e.nodeName);if(gt("uponSanitizeElement",e,{tagName:r,allowedTags:he}),e.hasChildNodes()&&!mt(e.firstElementChild)&&(!mt(e.content)||!mt(e.content.firstElementChild))&&b(/<[/\w]/g,e.innerHTML)&&b(/<[/\w]/g,e.textContent))return ct(e),!0;if(!he[r]||ve[r]){if(!ve[r]&&bt(r)){if(ye.tagNameCheck instanceof RegExp&&b(ye.tagNameCheck,r))return!1;if(ye.tagNameCheck instanceof Function&&ye.tagNameCheck(r))return!1}if(Re&&!Le[r]){const t=Z(e)||e.parentNode,n=V(e)||e.childNodes;if(n&&t)for(let r=n.length-1;r>=0;--r)t.insertBefore(U(n[r],!0),$(e))}return ct(e),!0}return e instanceof u&&!ut(e)?(ct(e),!0):"noscript"!==r&&"noembed"!==r||!b(/<\/no(script|embed)/i,e.innerHTML)?(Se&&3===e.nodeType&&(t=e.textContent,t=g(t,ae," "),t=g(t,ie," "),t=g(t,se," "),e.textContent!==t&&(f(n.removed,{element:e.cloneNode()}),e.textContent=t)),gt("afterSanitizeElements",e,null),!1):(ct(e),!0)},vt=function(e,t,n){if(Ie&&("id"===t||"name"===t)&&(n in o||n in tt))return!1;if(Ee&&!be[t]&&b(le,t));else if(we&&b(ue,t));else if(!me[t]||be[t]){if(!(bt(e)&&(ye.tagNameCheck instanceof RegExp&&b(ye.tagNameCheck,e)||ye.tagNameCheck instanceof Function&&ye.tagNameCheck(e))&&(ye.attributeNameCheck instanceof RegExp&&b(ye.attributeNameCheck,t)||ye.attributeNameCheck instanceof Function&&ye.attributeNameCheck(t))||"is"===t&&ye.allowCustomizedBuiltInElements&&(ye.tagNameCheck instanceof RegExp&&b(ye.tagNameCheck,n)||ye.tagNameCheck instanceof Function&&ye.tagNameCheck(n))))return!1}else if(Ue[t]);else if(b(fe,g(n,pe,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==y(n,"data:")||!Fe[e])if(xe&&!b(ce,g(n,pe,"")));else if(n)return!1;return!0},bt=function(e){return e.indexOf("-")>0},wt=function(e){let t,r,o,a;gt("beforeSanitizeAttributes",e,null);const{attributes:i}=e;if(!i)return;const s={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:me};for(a=i.length;a--;){t=i[a];const{name:l,namespaceURI:u}=t;if(r="value"===l?t.value:v(t.value),o=Xe(l),s.attrName=o,s.attrValue=r,s.keepAttr=!0,s.forceKeepAttr=void 0,gt("uponSanitizeAttribute",e,s),r=s.attrValue,s.forceKeepAttr)continue;if(pt(l,e),!s.keepAttr)continue;if(!_e&&b(/\/>/i,r)){pt(l,e);continue}Se&&(r=g(r,ae," "),r=g(r,ie," "),r=g(r,se," "));const c=Xe(e.nodeName);if(vt(c,o,r)){if(!Ne||"id"!==o&&"name"!==o||(pt(l,e),r=Pe+r),Y&&"object"==typeof F&&"function"==typeof F.getAttributeType)if(u);else switch(F.getAttributeType(c,o)){case"TrustedHTML":r=Y.createHTML(r);break;case"TrustedScriptURL":r=Y.createScriptURL(r)}try{u?e.setAttributeNS(u,l,r):e.setAttribute(l,r),p(n.removed)}catch(e){}}}gt("afterSanitizeAttributes",e,null)},Et=function e(t){let n;const r=ht(t);for(gt("beforeSanitizeShadowDOM",t,null);n=r.nextNode();)gt("uponSanitizeShadowNode",n,null),yt(n)||(n.content instanceof i&&e(n.content),wt(n));gt("afterSanitizeShadowDOM",t,null)};return n.sanitize=function(e){let t,o,a,s,u=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if(Je=!e,Je&&(e="\x3c!--\x3e"),"string"!=typeof e&&!mt(e)){if("function"!=typeof e.toString)throw w("toString is not a function");if("string"!=typeof(e=e.toString()))throw w("dirty is not a string, aborting")}if(!n.isSupported)return e;if(Ce||rt(u),n.removed=[],"string"==typeof e&&(Me=!1),Me){if(e.nodeName){const t=Xe(e.nodeName);if(!he[t]||ve[t])throw w("root node is forbidden and cannot be sanitized in-place")}}else if(e instanceof l)t=ft("\x3c!----\x3e"),o=t.ownerDocument.importNode(e,!0),1===o.nodeType&&"BODY"===o.nodeName||"HTML"===o.nodeName?t=o:t.appendChild(o);else{if(!Oe&&!Se&&!Ae&&-1===e.indexOf("<"))return Y&&Te?Y.createHTML(e):e;if(t=ft(e),!t)return Oe?null:Te?Q:""}t&&ke&&ct(t.firstChild);const c=ht(Me?e:t);for(;a=c.nextNode();)yt(a)||(a.content instanceof i&&Et(a.content),wt(a));if(Me)return e;if(Oe){if(je)for(s=te.call(t.ownerDocument);t.firstChild;)s.appendChild(t.firstChild);else s=t;return(me.shadowroot||me.shadowrootmod)&&(s=re.call(r,s,!0)),s}let p=Ae?t.outerHTML:t.innerHTML;return Ae&&he["!doctype"]&&t.ownerDocument&&t.ownerDocument.doctype&&t.ownerDocument.doctype.name&&b(W,t.ownerDocument.doctype.name)&&(p="\n"+p),Se&&(p=g(p,ae," "),p=g(p,ie," "),p=g(p,se," ")),Y&&Te?Y.createHTML(p):p},n.setConfig=function(e){rt(e),Ce=!0},n.clearConfig=function(){et=null,Ce=!1},n.isValidAttribute=function(e,t,n){et||rt({});const r=Xe(e),o=Xe(t);return vt(r,o,n)},n.addHook=function(e,t){"function"==typeof t&&(oe[e]=oe[e]||[],f(oe[e],t))},n.removeHook=function(e){if(oe[e])return p(oe[e])},n.removeHooks=function(e){oe[e]&&(oe[e]=[])},n.removeAllHooks=function(){oe={}},n}return G()}()},69450:e=>{"use strict";class t{constructor(e,t){this.low=e,this.high=t,this.length=1+t-e}overlaps(e){return!(this.highe.high)}touches(e){return!(this.high+1e.high)}add(e){return new t(Math.min(this.low,e.low),Math.max(this.high,e.high))}subtract(e){return e.low<=this.low&&e.high>=this.high?[]:e.low>this.low&&e.highe+t.length),0)}add(e,r){var o=e=>{for(var t=0;t{for(var t=0;t{for(var n=0;n{for(var n=t.low;n<=t.high;)e.push(n),n++;return e}),[])}subranges(){return this.ranges.map((e=>({low:e.low,high:e.high,length:1+e.high-e.low})))}}e.exports=n},17187:e=>{"use strict";var t,n="object"==typeof Reflect?Reflect:null,r=n&&"function"==typeof n.apply?n.apply:function(e,t,n){return Function.prototype.apply.call(e,t,n)};t=n&&"function"==typeof n.ownKeys?n.ownKeys:Object.getOwnPropertySymbols?function(e){return Object.getOwnPropertyNames(e).concat(Object.getOwnPropertySymbols(e))}:function(e){return Object.getOwnPropertyNames(e)};var o=Number.isNaN||function(e){return e!=e};function a(){a.init.call(this)}e.exports=a,e.exports.once=function(e,t){return new Promise((function(n,r){function o(n){e.removeListener(t,a),r(n)}function a(){"function"==typeof e.removeListener&&e.removeListener("error",o),n([].slice.call(arguments))}m(e,t,a,{once:!0}),"error"!==t&&function(e,t,n){"function"==typeof e.on&&m(e,"error",t,n)}(e,o,{once:!0})}))},a.EventEmitter=a,a.prototype._events=void 0,a.prototype._eventsCount=0,a.prototype._maxListeners=void 0;var i=10;function s(e){if("function"!=typeof e)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof e)}function l(e){return void 0===e._maxListeners?a.defaultMaxListeners:e._maxListeners}function u(e,t,n,r){var o,a,i,u;if(s(n),void 0===(a=e._events)?(a=e._events=Object.create(null),e._eventsCount=0):(void 0!==a.newListener&&(e.emit("newListener",t,n.listener?n.listener:n),a=e._events),i=a[t]),void 0===i)i=a[t]=n,++e._eventsCount;else if("function"==typeof i?i=a[t]=r?[n,i]:[i,n]:r?i.unshift(n):i.push(n),(o=l(e))>0&&i.length>o&&!i.warned){i.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+i.length+" "+String(t)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=e,c.type=t,c.count=i.length,u=c,console&&console.warn&&console.warn(u)}return e}function c(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(e,t,n){var r={fired:!1,wrapFn:void 0,target:e,type:t,listener:n},o=c.bind(r);return o.listener=n,r.wrapFn=o,o}function f(e,t,n){var r=e._events;if(void 0===r)return[];var o=r[t];return void 0===o?[]:"function"==typeof o?n?[o.listener||o]:[o]:n?function(e){for(var t=new Array(e.length),n=0;n0&&(i=t[0]),i instanceof Error)throw i;var s=new Error("Unhandled error."+(i?" ("+i.message+")":""));throw s.context=i,s}var l=a[e];if(void 0===l)return!1;if("function"==typeof l)r(l,this,t);else{var u=l.length,c=d(l,u);for(n=0;n=0;a--)if(n[a]===t||n[a].listener===t){i=n[a].listener,o=a;break}if(o<0)return this;0===o?n.shift():function(e,t){for(;t+1=0;r--)this.removeListener(e,t[r]);return this},a.prototype.listeners=function(e){return f(this,e,!0)},a.prototype.rawListeners=function(e){return f(this,e,!1)},a.listenerCount=function(e,t){return"function"==typeof e.listenerCount?e.listenerCount(t):h.call(e,t)},a.prototype.listenerCount=h,a.prototype.eventNames=function(){return this._eventsCount>0?t(this._events):[]}},21102:(e,t,n)=>{"use strict";var r=n(46291),o=a(Error);function a(e){return t.displayName=e.displayName||e.name,t;function t(t){return t&&(t=r.apply(null,arguments)),new e(t)}}e.exports=o,o.eval=a(EvalError),o.range=a(RangeError),o.reference=a(ReferenceError),o.syntax=a(SyntaxError),o.type=a(TypeError),o.uri=a(URIError),o.create=a},46291:e=>{!function(){var t;function n(e){for(var t,n,r,o,a=1,i=[].slice.call(arguments),s=0,l=e.length,u="",c=!1,p=!1,f=function(){return i[a++]},h=function(){for(var n="";/\d/.test(e[s]);)n+=e[s++],t=e[s];return n.length>0?parseInt(n):null};s{"use strict";var t=Array.prototype.slice,n=Object.prototype.toString;e.exports=function(e){var r=this;if("function"!=typeof r||"[object Function]"!==n.call(r))throw new TypeError("Function.prototype.bind called on incompatible "+r);for(var o,a=t.call(arguments,1),i=Math.max(0,r.length-a.length),s=[],l=0;l{"use strict";var r=n(17648);e.exports=Function.prototype.bind||r},40210:(e,t,n)=>{"use strict";var r,o=SyntaxError,a=Function,i=TypeError,s=function(e){try{return a('"use strict"; return ('+e+").constructor;")()}catch(e){}},l=Object.getOwnPropertyDescriptor;if(l)try{l({},"")}catch(e){l=null}var u=function(){throw new i},c=l?function(){try{return u}catch(e){try{return l(arguments,"callee").get}catch(e){return u}}}():u,p=n(41405)(),f=Object.getPrototypeOf||function(e){return e.__proto__},h={},d="undefined"==typeof Uint8Array?r:f(Uint8Array),m={"%AggregateError%":"undefined"==typeof AggregateError?r:AggregateError,"%Array%":Array,"%ArrayBuffer%":"undefined"==typeof ArrayBuffer?r:ArrayBuffer,"%ArrayIteratorPrototype%":p?f([][Symbol.iterator]()):r,"%AsyncFromSyncIteratorPrototype%":r,"%AsyncFunction%":h,"%AsyncGenerator%":h,"%AsyncGeneratorFunction%":h,"%AsyncIteratorPrototype%":h,"%Atomics%":"undefined"==typeof Atomics?r:Atomics,"%BigInt%":"undefined"==typeof BigInt?r:BigInt,"%BigInt64Array%":"undefined"==typeof BigInt64Array?r:BigInt64Array,"%BigUint64Array%":"undefined"==typeof BigUint64Array?r:BigUint64Array,"%Boolean%":Boolean,"%DataView%":"undefined"==typeof DataView?r:DataView,"%Date%":Date,"%decodeURI%":decodeURI,"%decodeURIComponent%":decodeURIComponent,"%encodeURI%":encodeURI,"%encodeURIComponent%":encodeURIComponent,"%Error%":Error,"%eval%":eval,"%EvalError%":EvalError,"%Float32Array%":"undefined"==typeof Float32Array?r:Float32Array,"%Float64Array%":"undefined"==typeof Float64Array?r:Float64Array,"%FinalizationRegistry%":"undefined"==typeof FinalizationRegistry?r:FinalizationRegistry,"%Function%":a,"%GeneratorFunction%":h,"%Int8Array%":"undefined"==typeof Int8Array?r:Int8Array,"%Int16Array%":"undefined"==typeof Int16Array?r:Int16Array,"%Int32Array%":"undefined"==typeof Int32Array?r:Int32Array,"%isFinite%":isFinite,"%isNaN%":isNaN,"%IteratorPrototype%":p?f(f([][Symbol.iterator]())):r,"%JSON%":"object"==typeof JSON?JSON:r,"%Map%":"undefined"==typeof Map?r:Map,"%MapIteratorPrototype%":"undefined"!=typeof Map&&p?f((new Map)[Symbol.iterator]()):r,"%Math%":Math,"%Number%":Number,"%Object%":Object,"%parseFloat%":parseFloat,"%parseInt%":parseInt,"%Promise%":"undefined"==typeof Promise?r:Promise,"%Proxy%":"undefined"==typeof Proxy?r:Proxy,"%RangeError%":RangeError,"%ReferenceError%":ReferenceError,"%Reflect%":"undefined"==typeof Reflect?r:Reflect,"%RegExp%":RegExp,"%Set%":"undefined"==typeof Set?r:Set,"%SetIteratorPrototype%":"undefined"!=typeof Set&&p?f((new Set)[Symbol.iterator]()):r,"%SharedArrayBuffer%":"undefined"==typeof SharedArrayBuffer?r:SharedArrayBuffer,"%String%":String,"%StringIteratorPrototype%":p?f(""[Symbol.iterator]()):r,"%Symbol%":p?Symbol:r,"%SyntaxError%":o,"%ThrowTypeError%":c,"%TypedArray%":d,"%TypeError%":i,"%Uint8Array%":"undefined"==typeof Uint8Array?r:Uint8Array,"%Uint8ClampedArray%":"undefined"==typeof Uint8ClampedArray?r:Uint8ClampedArray,"%Uint16Array%":"undefined"==typeof Uint16Array?r:Uint16Array,"%Uint32Array%":"undefined"==typeof Uint32Array?r:Uint32Array,"%URIError%":URIError,"%WeakMap%":"undefined"==typeof WeakMap?r:WeakMap,"%WeakRef%":"undefined"==typeof WeakRef?r:WeakRef,"%WeakSet%":"undefined"==typeof WeakSet?r:WeakSet};try{null.error}catch(e){var g=f(f(e));m["%Error.prototype%"]=g}var y=function e(t){var n;if("%AsyncFunction%"===t)n=s("async function () {}");else if("%GeneratorFunction%"===t)n=s("function* () {}");else if("%AsyncGeneratorFunction%"===t)n=s("async function* () {}");else if("%AsyncGenerator%"===t){var r=e("%AsyncGeneratorFunction%");r&&(n=r.prototype)}else if("%AsyncIteratorPrototype%"===t){var o=e("%AsyncGenerator%");o&&(n=f(o.prototype))}return m[t]=n,n},v={"%ArrayBufferPrototype%":["ArrayBuffer","prototype"],"%ArrayPrototype%":["Array","prototype"],"%ArrayProto_entries%":["Array","prototype","entries"],"%ArrayProto_forEach%":["Array","prototype","forEach"],"%ArrayProto_keys%":["Array","prototype","keys"],"%ArrayProto_values%":["Array","prototype","values"],"%AsyncFunctionPrototype%":["AsyncFunction","prototype"],"%AsyncGenerator%":["AsyncGeneratorFunction","prototype"],"%AsyncGeneratorPrototype%":["AsyncGeneratorFunction","prototype","prototype"],"%BooleanPrototype%":["Boolean","prototype"],"%DataViewPrototype%":["DataView","prototype"],"%DatePrototype%":["Date","prototype"],"%ErrorPrototype%":["Error","prototype"],"%EvalErrorPrototype%":["EvalError","prototype"],"%Float32ArrayPrototype%":["Float32Array","prototype"],"%Float64ArrayPrototype%":["Float64Array","prototype"],"%FunctionPrototype%":["Function","prototype"],"%Generator%":["GeneratorFunction","prototype"],"%GeneratorPrototype%":["GeneratorFunction","prototype","prototype"],"%Int8ArrayPrototype%":["Int8Array","prototype"],"%Int16ArrayPrototype%":["Int16Array","prototype"],"%Int32ArrayPrototype%":["Int32Array","prototype"],"%JSONParse%":["JSON","parse"],"%JSONStringify%":["JSON","stringify"],"%MapPrototype%":["Map","prototype"],"%NumberPrototype%":["Number","prototype"],"%ObjectPrototype%":["Object","prototype"],"%ObjProto_toString%":["Object","prototype","toString"],"%ObjProto_valueOf%":["Object","prototype","valueOf"],"%PromisePrototype%":["Promise","prototype"],"%PromiseProto_then%":["Promise","prototype","then"],"%Promise_all%":["Promise","all"],"%Promise_reject%":["Promise","reject"],"%Promise_resolve%":["Promise","resolve"],"%RangeErrorPrototype%":["RangeError","prototype"],"%ReferenceErrorPrototype%":["ReferenceError","prototype"],"%RegExpPrototype%":["RegExp","prototype"],"%SetPrototype%":["Set","prototype"],"%SharedArrayBufferPrototype%":["SharedArrayBuffer","prototype"],"%StringPrototype%":["String","prototype"],"%SymbolPrototype%":["Symbol","prototype"],"%SyntaxErrorPrototype%":["SyntaxError","prototype"],"%TypedArrayPrototype%":["TypedArray","prototype"],"%TypeErrorPrototype%":["TypeError","prototype"],"%Uint8ArrayPrototype%":["Uint8Array","prototype"],"%Uint8ClampedArrayPrototype%":["Uint8ClampedArray","prototype"],"%Uint16ArrayPrototype%":["Uint16Array","prototype"],"%Uint32ArrayPrototype%":["Uint32Array","prototype"],"%URIErrorPrototype%":["URIError","prototype"],"%WeakMapPrototype%":["WeakMap","prototype"],"%WeakSetPrototype%":["WeakSet","prototype"]},b=n(58612),w=n(17642),E=b.call(Function.call,Array.prototype.concat),x=b.call(Function.apply,Array.prototype.splice),_=b.call(Function.call,String.prototype.replace),S=b.call(Function.call,String.prototype.slice),A=b.call(Function.call,RegExp.prototype.exec),C=/[^%.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|%$))/g,k=/\\(\\)?/g,O=function(e,t){var n,r=e;if(w(v,r)&&(r="%"+(n=v[r])[0]+"%"),w(m,r)){var a=m[r];if(a===h&&(a=y(r)),void 0===a&&!t)throw new i("intrinsic "+e+" exists, but is not available. Please file an issue!");return{alias:n,name:r,value:a}}throw new o("intrinsic "+e+" does not exist!")};e.exports=function(e,t){if("string"!=typeof e||0===e.length)throw new i("intrinsic name must be a non-empty string");if(arguments.length>1&&"boolean"!=typeof t)throw new i('"allowMissing" argument must be a boolean');if(null===A(/^%?[^%]*%?$/,e))throw new o("`%` may not be present anywhere but at the beginning and end of the intrinsic name");var n=function(e){var t=S(e,0,1),n=S(e,-1);if("%"===t&&"%"!==n)throw new o("invalid intrinsic syntax, expected closing `%`");if("%"===n&&"%"!==t)throw new o("invalid intrinsic syntax, expected opening `%`");var r=[];return _(e,C,(function(e,t,n,o){r[r.length]=n?_(o,k,"$1"):t||e})),r}(e),r=n.length>0?n[0]:"",a=O("%"+r+"%",t),s=a.name,u=a.value,c=!1,p=a.alias;p&&(r=p[0],x(n,E([0,1],p)));for(var f=1,h=!0;f=n.length){var v=l(u,d);u=(h=!!v)&&"get"in v&&!("originalValue"in v.get)?v.get:u[d]}else h=w(u,d),u=u[d];h&&!c&&(m[s]=u)}}return u}},41405:(e,t,n)=>{"use strict";var r="undefined"!=typeof Symbol&&Symbol,o=n(55419);e.exports=function(){return"function"==typeof r&&("function"==typeof Symbol&&("symbol"==typeof r("foo")&&("symbol"==typeof Symbol("bar")&&o())))}},55419:e=>{"use strict";e.exports=function(){if("function"!=typeof Symbol||"function"!=typeof Object.getOwnPropertySymbols)return!1;if("symbol"==typeof Symbol.iterator)return!0;var e={},t=Symbol("test"),n=Object(t);if("string"==typeof t)return!1;if("[object Symbol]"!==Object.prototype.toString.call(t))return!1;if("[object Symbol]"!==Object.prototype.toString.call(n))return!1;for(t in e[t]=42,e)return!1;if("function"==typeof Object.keys&&0!==Object.keys(e).length)return!1;if("function"==typeof Object.getOwnPropertyNames&&0!==Object.getOwnPropertyNames(e).length)return!1;var r=Object.getOwnPropertySymbols(e);if(1!==r.length||r[0]!==t)return!1;if(!Object.prototype.propertyIsEnumerable.call(e,t))return!1;if("function"==typeof Object.getOwnPropertyDescriptor){var o=Object.getOwnPropertyDescriptor(e,t);if(42!==o.value||!0!==o.enumerable)return!1}return!0}},17642:(e,t,n)=>{"use strict";var r=n(58612);e.exports=r.call(Function.call,Object.prototype.hasOwnProperty)},47802:e=>{function t(e){return e instanceof Map?e.clear=e.delete=e.set=function(){throw new Error("map is read-only")}:e instanceof Set&&(e.add=e.clear=e.delete=function(){throw new Error("set is read-only")}),Object.freeze(e),Object.getOwnPropertyNames(e).forEach((function(n){var r=e[n];"object"!=typeof r||Object.isFrozen(r)||t(r)})),e}var n=t,r=t;n.default=r;class o{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data,this.isMatchIgnored=!1}ignoreMatch(){this.isMatchIgnored=!0}}function a(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function i(e,...t){const n=Object.create(null);for(const t in e)n[t]=e[t];return t.forEach((function(e){for(const t in e)n[t]=e[t]})),n}const s=e=>!!e.kind;class l{constructor(e,t){this.buffer="",this.classPrefix=t.classPrefix,e.walk(this)}addText(e){this.buffer+=a(e)}openNode(e){if(!s(e))return;let t=e.kind;e.sublanguage||(t=`${this.classPrefix}${t}`),this.span(t)}closeNode(e){s(e)&&(this.buffer+="")}value(){return this.buffer}span(e){this.buffer+=``}}class u{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const t={kind:e,children:[]};this.add(t),this.stack.push(t)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,t){return"string"==typeof t?e.addText(t):t.children&&(e.openNode(t),t.children.forEach((t=>this._walk(e,t))),e.closeNode(t)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every((e=>"string"==typeof e))?e.children=[e.children.join("")]:e.children.forEach((e=>{u._collapse(e)})))}}class c extends u{constructor(e){super(),this.options=e}addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function p(e){return e?"string"==typeof e?e:e.source:null}const f=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./;const h="[a-zA-Z]\\w*",d="[a-zA-Z_]\\w*",m="\\b\\d+(\\.\\d+)?",g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",y="\\b(0b[01]+)",v={begin:"\\\\[\\s\\S]",relevance:0},b={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[v]},w={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[v]},E={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},x=function(e,t,n={}){const r=i({className:"comment",begin:e,end:t,contains:[]},n);return r.contains.push(E),r.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),r},_=x("//","$"),S=x("/\\*","\\*/"),A=x("#","$"),C={className:"number",begin:m,relevance:0},k={className:"number",begin:g,relevance:0},O={className:"number",begin:y,relevance:0},j={className:"number",begin:m+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},T={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[v,{begin:/\[/,end:/\]/,relevance:0,contains:[v]}]}]},I={className:"title",begin:h,relevance:0},N={className:"title",begin:d,relevance:0},P={begin:"\\.\\s*"+d,relevance:0};var R=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:h,UNDERSCORE_IDENT_RE:d,NUMBER_RE:m,C_NUMBER_RE:g,BINARY_NUMBER_RE:y,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const t=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map((e=>p(e))).join("")}(t,/.*\b/,e.binary,/\b.*/)),i({className:"meta",begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},BACKSLASH_ESCAPE:v,APOS_STRING_MODE:b,QUOTE_STRING_MODE:w,PHRASAL_WORDS_MODE:E,COMMENT:x,C_LINE_COMMENT_MODE:_,C_BLOCK_COMMENT_MODE:S,HASH_COMMENT_MODE:A,NUMBER_MODE:C,C_NUMBER_MODE:k,BINARY_NUMBER_MODE:O,CSS_NUMBER_MODE:j,REGEXP_MODE:T,TITLE_MODE:I,UNDERSCORE_TITLE_MODE:N,METHOD_GUARD:P,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})}});function M(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}function D(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=M,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))}function L(e,t){Array.isArray(e.illegal)&&(e.illegal=function(...e){return"("+e.map((e=>p(e))).join("|")+")"}(...e.illegal))}function B(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}function F(e,t){void 0===e.relevance&&(e.relevance=1)}const z=["of","and","for","in","not","or","if","then","parent","list","value"],U="keyword";function q(e,t,n=U){const r={};return"string"==typeof e?o(n,e.split(" ")):Array.isArray(e)?o(n,e):Object.keys(e).forEach((function(n){Object.assign(r,q(e[n],t,n))})),r;function o(e,n){t&&(n=n.map((e=>e.toLowerCase()))),n.forEach((function(t){const n=t.split("|");r[n[0]]=[e,$(n[0],n[1])]}))}}function $(e,t){return t?Number(t):function(e){return z.includes(e.toLowerCase())}(e)?0:1}function V(e,{plugins:t}){function n(t,n){return new RegExp(p(t),"m"+(e.case_insensitive?"i":"")+(n?"g":""))}class r{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,t){t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),this.matchAt+=function(e){return new RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map((e=>e[1]));this.matcherRe=n(function(e,t="|"){let n=0;return e.map((e=>{n+=1;const t=n;let r=p(e),o="";for(;r.length>0;){const e=f.exec(r);if(!e){o+=r;break}o+=r.substring(0,e.index),r=r.substring(e.index+e[0].length),"\\"===e[0][0]&&e[1]?o+="\\"+String(Number(e[1])+t):(o+=e[0],"("===e[0]&&n++)}return o})).map((e=>`(${e})`)).join(t)}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const t=this.matcherRe.exec(e);if(!t)return null;const n=t.findIndex(((e,t)=>t>0&&void 0!==e)),r=this.matchIndexes[n];return t.splice(0,n),Object.assign(t,r)}}class o{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const t=new r;return this.rules.slice(e).forEach((([e,n])=>t.addRule(e,n))),t.compile(),this.multiRegexes[e]=t,t}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex;let n=t.exec(e);if(this.resumingScanAtSamePosition())if(n&&n.index===this.lastIndex);else{const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}return n&&(this.regexIndex+=n.position+1,this.regexIndex===this.count&&this.considerAll()),n}}if(e.compilerExtensions||(e.compilerExtensions=[]),e.contains&&e.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return e.classNameAliases=i(e.classNameAliases||{}),function t(r,a){const s=r;if(r.isCompiled)return s;[B].forEach((e=>e(r,a))),e.compilerExtensions.forEach((e=>e(r,a))),r.__beforeBegin=null,[D,L,F].forEach((e=>e(r,a))),r.isCompiled=!0;let l=null;if("object"==typeof r.keywords&&(l=r.keywords.$pattern,delete r.keywords.$pattern),r.keywords&&(r.keywords=q(r.keywords,e.case_insensitive)),r.lexemes&&l)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l=l||r.lexemes||/\w+/,s.keywordPatternRe=n(l,!0),a&&(r.begin||(r.begin=/\B|\b/),s.beginRe=n(r.begin),r.endSameAsBegin&&(r.end=r.begin),r.end||r.endsWithParent||(r.end=/\B|\b/),r.end&&(s.endRe=n(r.end)),s.terminatorEnd=p(r.end)||"",r.endsWithParent&&a.terminatorEnd&&(s.terminatorEnd+=(r.end?"|":"")+a.terminatorEnd)),r.illegal&&(s.illegalRe=n(r.illegal)),r.contains||(r.contains=[]),r.contains=[].concat(...r.contains.map((function(e){return function(e){e.variants&&!e.cachedVariants&&(e.cachedVariants=e.variants.map((function(t){return i(e,{variants:null},t)})));if(e.cachedVariants)return e.cachedVariants;if(W(e))return i(e,{starts:e.starts?i(e.starts):null});if(Object.isFrozen(e))return i(e);return e}("self"===e?r:e)}))),r.contains.forEach((function(e){t(e,s)})),r.starts&&t(r.starts,a),s.matcher=function(e){const t=new o;return e.contains.forEach((e=>t.addRule(e.begin,{rule:e,type:"begin"}))),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t}(s),s}(e)}function W(e){return!!e&&(e.endsWithParent||W(e.starts))}function H(e){const t={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!e.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,a(this.code);let t={};return this.autoDetect?(t=e.highlightAuto(this.code),this.detectedLanguage=t.language):(t=e.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),t.value},autoDetect(){return!this.language||(e=this.autodetect,Boolean(e||""===e));var e},ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:t,VuePlugin:{install(e){e.component("highlightjs",t)}}}}const J={"after:highlightElement":({el:e,result:t,text:n})=>{const r=G(e);if(!r.length)return;const o=document.createElement("div");o.innerHTML=t.value,t.value=function(e,t,n){let r=0,o="";const i=[];function s(){return e.length&&t.length?e[0].offset!==t[0].offset?e[0].offset"}function u(e){o+=""}function c(e){("start"===e.event?l:u)(e.node)}for(;e.length||t.length;){let t=s();if(o+=a(n.substring(r,t[0].offset)),r=t[0].offset,t===e){i.reverse().forEach(u);do{c(t.splice(0,1)[0]),t=s()}while(t===e&&t.length&&t[0].offset===r);i.reverse().forEach(l)}else"start"===t[0].event?i.push(t[0].node):i.pop(),c(t.splice(0,1)[0])}return o+a(n.substr(r))}(r,G(o),n)}};function K(e){return e.nodeName.toLowerCase()}function G(e){const t=[];return function e(n,r){for(let o=n.firstChild;o;o=o.nextSibling)3===o.nodeType?r+=o.nodeValue.length:1===o.nodeType&&(t.push({event:"start",offset:r,node:o}),r=e(o,r),K(o).match(/br|hr|img|input/)||t.push({event:"stop",offset:r,node:o}));return r}(e,0),t}const Z={},Y=e=>{console.error(e)},Q=(e,...t)=>{console.log(`WARN: ${e}`,...t)},X=(e,t)=>{Z[`${e}/${t}`]||(console.log(`Deprecated as of ${e}. ${t}`),Z[`${e}/${t}`]=!0)},ee=a,te=i,ne=Symbol("nomatch");var re=function(e){const t=Object.create(null),r=Object.create(null),a=[];let i=!0;const s=/(^(<[^>]+>|\t|)+|\n)/gm,l="Could not find the language '{}', did you forget to load/include a language module?",u={disableAutodetect:!0,name:"Plain text",contains:[]};let p={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:c};function f(e){return p.noHighlightRe.test(e)}function h(e,t,n,r){let o="",a="";"object"==typeof t?(o=e,n=t.ignoreIllegals,a=t.language,r=void 0):(X("10.7.0","highlight(lang, code, ...args) has been deprecated."),X("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),a=e,o=t);const i={code:o,language:a};C("before:highlight",i);const s=i.result?i.result:d(i.language,i.code,n,r);return s.code=i.code,C("after:highlight",s),s}function d(e,n,r,s){function u(e,t){const n=E.case_insensitive?t[0].toLowerCase():t[0];return Object.prototype.hasOwnProperty.call(e.keywords,n)&&e.keywords[n]}function c(){null!=A.subLanguage?function(){if(""===O)return;let e=null;if("string"==typeof A.subLanguage){if(!t[A.subLanguage])return void k.addText(O);e=d(A.subLanguage,O,!0,C[A.subLanguage]),C[A.subLanguage]=e.top}else e=m(O,A.subLanguage.length?A.subLanguage:null);A.relevance>0&&(j+=e.relevance),k.addSublanguage(e.emitter,e.language)}():function(){if(!A.keywords)return void k.addText(O);let e=0;A.keywordPatternRe.lastIndex=0;let t=A.keywordPatternRe.exec(O),n="";for(;t;){n+=O.substring(e,t.index);const r=u(A,t);if(r){const[e,o]=r;if(k.addText(n),n="",j+=o,e.startsWith("_"))n+=t[0];else{const n=E.classNameAliases[e]||e;k.addKeyword(t[0],n)}}else n+=t[0];e=A.keywordPatternRe.lastIndex,t=A.keywordPatternRe.exec(O)}n+=O.substr(e),k.addText(n)}(),O=""}function f(e){return e.className&&k.openNode(E.classNameAliases[e.className]||e.className),A=Object.create(e,{parent:{value:A}}),A}function h(e,t,n){let r=function(e,t){const n=e&&e.exec(t);return n&&0===n.index}(e.endRe,n);if(r){if(e["on:end"]){const n=new o(e);e["on:end"](t,n),n.isMatchIgnored&&(r=!1)}if(r){for(;e.endsParent&&e.parent;)e=e.parent;return e}}if(e.endsWithParent)return h(e.parent,t,n)}function g(e){return 0===A.matcher.regexIndex?(O+=e[0],1):(N=!0,0)}function y(e){const t=e[0],n=e.rule,r=new o(n),a=[n.__beforeBegin,n["on:begin"]];for(const n of a)if(n&&(n(e,r),r.isMatchIgnored))return g(t);return n&&n.endSameAsBegin&&(n.endRe=new RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),n.skip?O+=t:(n.excludeBegin&&(O+=t),c(),n.returnBegin||n.excludeBegin||(O=t)),f(n),n.returnBegin?0:t.length}function v(e){const t=e[0],r=n.substr(e.index),o=h(A,e,r);if(!o)return ne;const a=A;a.skip?O+=t:(a.returnEnd||a.excludeEnd||(O+=t),c(),a.excludeEnd&&(O=t));do{A.className&&k.closeNode(),A.skip||A.subLanguage||(j+=A.relevance),A=A.parent}while(A!==o.parent);return o.starts&&(o.endSameAsBegin&&(o.starts.endRe=o.endRe),f(o.starts)),a.returnEnd?0:t.length}let b={};function w(t,o){const a=o&&o[0];if(O+=t,null==a)return c(),0;if("begin"===b.type&&"end"===o.type&&b.index===o.index&&""===a){if(O+=n.slice(o.index,o.index+1),!i){const t=new Error("0 width match regex");throw t.languageName=e,t.badRule=b.rule,t}return 1}if(b=o,"begin"===o.type)return y(o);if("illegal"===o.type&&!r){const e=new Error('Illegal lexeme "'+a+'" for mode "'+(A.className||"")+'"');throw e.mode=A,e}if("end"===o.type){const e=v(o);if(e!==ne)return e}if("illegal"===o.type&&""===a)return 1;if(I>1e5&&I>3*o.index){throw new Error("potential infinite loop, way more iterations than matches")}return O+=a,a.length}const E=_(e);if(!E)throw Y(l.replace("{}",e)),new Error('Unknown language: "'+e+'"');const x=V(E,{plugins:a});let S="",A=s||x;const C={},k=new p.__emitter(p);!function(){const e=[];for(let t=A;t!==E;t=t.parent)t.className&&e.unshift(t.className);e.forEach((e=>k.openNode(e)))}();let O="",j=0,T=0,I=0,N=!1;try{for(A.matcher.considerAll();;){I++,N?N=!1:A.matcher.considerAll(),A.matcher.lastIndex=T;const e=A.matcher.exec(n);if(!e)break;const t=w(n.substring(T,e.index),e);T=e.index+t}return w(n.substr(T)),k.closeAllNodes(),k.finalize(),S=k.toHTML(),{relevance:Math.floor(j),value:S,language:e,illegal:!1,emitter:k,top:A}}catch(t){if(t.message&&t.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:t.message,context:n.slice(T-100,T+100),mode:t.mode},sofar:S,relevance:0,value:ee(n),emitter:k};if(i)return{illegal:!1,relevance:0,value:ee(n),emitter:k,language:e,top:A,errorRaised:t};throw t}}function m(e,n){n=n||p.languages||Object.keys(t);const r=function(e){const t={relevance:0,emitter:new p.__emitter(p),value:ee(e),illegal:!1,top:u};return t.emitter.addText(e),t}(e),o=n.filter(_).filter(A).map((t=>d(t,e,!1)));o.unshift(r);const a=o.sort(((e,t)=>{if(e.relevance!==t.relevance)return t.relevance-e.relevance;if(e.language&&t.language){if(_(e.language).supersetOf===t.language)return 1;if(_(t.language).supersetOf===e.language)return-1}return 0})),[i,s]=a,l=i;return l.second_best=s,l}const g={"before:highlightElement":({el:e})=>{p.useBR&&(e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"))},"after:highlightElement":({result:e})=>{p.useBR&&(e.value=e.value.replace(/\n/g,"
"))}},y=/^(<[^>]+>|\t)+/gm,v={"after:highlightElement":({result:e})=>{p.tabReplace&&(e.value=e.value.replace(y,(e=>e.replace(/\t/g,p.tabReplace))))}};function b(e){let t=null;const n=function(e){let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"";const n=p.languageDetectRe.exec(t);if(n){const t=_(n[1]);return t||(Q(l.replace("{}",n[1])),Q("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}return t.split(/\s+/).find((e=>f(e)||_(e)))}(e);if(f(n))return;C("before:highlightElement",{el:e,language:n}),t=e;const o=t.textContent,a=n?h(o,{language:n,ignoreIllegals:!0}):m(o);C("after:highlightElement",{el:e,result:a,text:o}),e.innerHTML=a.value,function(e,t,n){const o=t?r[t]:n;e.classList.add("hljs"),o&&e.classList.add(o)}(e,n,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const w=()=>{if(w.called)return;w.called=!0,X("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead.");document.querySelectorAll("pre code").forEach(b)};let E=!1;function x(){if("loading"===document.readyState)return void(E=!0);document.querySelectorAll("pre code").forEach(b)}function _(e){return e=(e||"").toLowerCase(),t[e]||t[r[e]]}function S(e,{languageName:t}){"string"==typeof e&&(e=[e]),e.forEach((e=>{r[e.toLowerCase()]=t}))}function A(e){const t=_(e);return t&&!t.disableAutodetect}function C(e,t){const n=e;a.forEach((function(e){e[n]&&e[n](t)}))}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",(function(){E&&x()}),!1),Object.assign(e,{highlight:h,highlightAuto:m,highlightAll:x,fixMarkup:function(e){return X("10.2.0","fixMarkup will be removed entirely in v11.0"),X("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),t=e,p.tabReplace||p.useBR?t.replace(s,(e=>"\n"===e?p.useBR?"
":e:p.tabReplace?e.replace(/\t/g,p.tabReplace):e)):t;var t},highlightElement:b,highlightBlock:function(e){return X("10.7.0","highlightBlock will be removed entirely in v12.0"),X("10.7.0","Please use highlightElement now."),b(e)},configure:function(e){e.useBR&&(X("10.3.0","'useBR' will be removed entirely in v11.0"),X("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),p=te(p,e)},initHighlighting:w,initHighlightingOnLoad:function(){X("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),E=!0},registerLanguage:function(n,r){let o=null;try{o=r(e)}catch(e){if(Y("Language definition for '{}' could not be registered.".replace("{}",n)),!i)throw e;Y(e),o=u}o.name||(o.name=n),t[n]=o,o.rawDefinition=r.bind(null,e),o.aliases&&S(o.aliases,{languageName:n})},unregisterLanguage:function(e){delete t[e];for(const t of Object.keys(r))r[t]===e&&delete r[t]},listLanguages:function(){return Object.keys(t)},getLanguage:_,registerAliases:S,requireLanguage:function(e){X("10.4.0","requireLanguage will be removed entirely in v11."),X("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844");const t=_(e);if(t)return t;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:A,inherit:te,addPlugin:function(e){!function(e){e["before:highlightBlock"]&&!e["before:highlightElement"]&&(e["before:highlightElement"]=t=>{e["before:highlightBlock"](Object.assign({block:t.el},t))}),e["after:highlightBlock"]&&!e["after:highlightElement"]&&(e["after:highlightElement"]=t=>{e["after:highlightBlock"](Object.assign({block:t.el},t))})}(e),a.push(e)},vuePlugin:H(e).VuePlugin}),e.debugMode=function(){i=!1},e.safeMode=function(){i=!0},e.versionString="10.7.3";for(const e in R)"object"==typeof R[e]&&n(R[e]);return Object.assign(e,R),e.addPlugin(g),e.addPlugin(J),e.addPlugin(v),e}({});e.exports=re},61519:e=>{function t(...e){return e.map((e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t})).join("")}e.exports=function(e){const n={},r={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[n]}]};Object.assign(n,{className:"variable",variants:[{begin:t(/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])")},r]});const o={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},a={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},i={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,n,o]};o.contains.push(i);const s={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,n]},l=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),u={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[l,e.SHEBANG(),u,s,e.HASH_COMMENT_MODE,a,i,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},n]}}},30786:e=>{function t(...e){return e.map((e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t})).join("")}e.exports=function(e){const n="HTTP/(2|1\\.[01])",r={className:"attribute",begin:t("^",/[A-Za-z][A-Za-z0-9-]*/,"(?=\\:\\s)"),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},o=[r,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+n+" \\d{3})",end:/$/,contains:[{className:"meta",begin:n},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:o}},{begin:"(?=^[A-Z]+ (.*?) "+n+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:n},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:o}},e.inherit(r,{relevance:0})]}}},96344:e=>{const t="[A-Za-z$_][0-9A-Za-z$_]*",n=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],r=["true","false","null","undefined","NaN","Infinity"],o=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function a(e){return i("(?=",e,")")}function i(...e){return e.map((e=>{return(t=e)?"string"==typeof t?t:t.source:null;var t})).join("")}e.exports=function(e){const s=t,l="<>",u="",c={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/,isTrulyOpeningTag:(e,t)=>{const n=e[0].length+e.index,r=e.input[n];"<"!==r?">"===r&&(((e,{after:t})=>{const n="",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:p,contains:_}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:l,end:u},{begin:c.begin,"on:begin":c.isTrulyOpeningTag,end:c.end}],subLanguage:"xml",contains:[{begin:c.begin,end:c.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[{;]/,excludeEnd:!0,keywords:p,contains:["self",e.inherit(e.TITLE_MODE,{begin:s}),S],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[S,e.inherit(e.TITLE_MODE,{begin:s})]},{variants:[{begin:"\\."+s},{begin:"\\$"+s}],relevance:0},{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:s}),"self",S]},{begin:"(get|set)\\s+(?="+s+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:s}),{begin:/\(\)/},S]},{begin:/\$[(.]/}]}}},82026:e=>{e.exports=function(e){const t={literal:"true false null"},n=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],r=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],o={end:",",endsWithParent:!0,excludeEnd:!0,contains:r,keywords:t},a={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(o,{begin:/:/})].concat(n),illegal:"\\S"},i={begin:"\\[",end:"\\]",contains:[e.inherit(o)],illegal:"\\S"};return r.push(a,i),n.forEach((function(e){r.push(e)})),{name:"JSON",contains:r,keywords:t,illegal:"\\S"}}},66336:e=>{e.exports=function(e){const t={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},n={begin:"`[\\s\\S]",relevance:0},r={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},o={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[n,r,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},a={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},i=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),s={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},l={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[e.TITLE_MODE]},u={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[r]}]},c={begin:/using\s/,end:/$/,returnBegin:!0,contains:[o,a,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},p={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},f={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(t.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},e.inherit(e.TITLE_MODE,{endsParent:!0})]},h=[f,i,n,e.NUMBER_MODE,o,a,s,r,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],d={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",h,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return f.contains.unshift(d),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:t,contains:h.concat(l,u,c,p,d)}}},42157:e=>{function t(e){return e?"string"==typeof e?e:e.source:null}function n(e){return r("(?=",e,")")}function r(...e){return e.map((e=>t(e))).join("")}function o(...e){return"("+e.map((e=>t(e))).join("|")+")"}e.exports=function(e){const t=r(/[A-Z_]/,r("(",/[A-Z0-9_.-]*:/,")?"),/[A-Z0-9_.-]*/),a={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},i={begin:/\s/,contains:[{className:"meta-keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},s=e.inherit(i,{begin:/\(/,end:/\)/}),l=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),u=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),c={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[i,u,l,s,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[i,s,u,l]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},a,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[c],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[c],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:r(//,/>/,/\s/)))),end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:c}]},{className:"tag",begin:r(/<\//,n(r(t,/>/))),contains:[{className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}},54587:e=>{e.exports=function(e){var t="true false yes no null",n="[\\w#;/?:@&=+$,.~*'()[\\]]+",r={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},o=e.inherit(r,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),a={className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},i={end:",",endsWithParent:!0,excludeEnd:!0,keywords:t,relevance:0},s={begin:/\{/,end:/\}/,contains:[i],illegal:"\\n",relevance:0},l={begin:"\\[",end:"\\]",contains:[i],illegal:"\\n",relevance:0},u=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+n},{className:"type",begin:"!<"+n+">"},{className:"type",begin:"!"+n},{className:"type",begin:"!!"+n},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:t,keywords:{literal:t}},a,{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},s,l,r],c=[...u];return c.pop(),c.push(o),i.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:u}}},8679:(e,t,n)=>{"use strict";var r=n(59864),o={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},a={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},s={};function l(e){return r.isMemo(e)?i:s[e.$$typeof]||o}s[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},s[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,p=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,h=Object.getPrototypeOf,d=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(d){var o=h(n);o&&o!==d&&e(t,o,r)}var i=c(n);p&&(i=i.concat(p(n)));for(var s=l(t),m=l(n),g=0;g{t.read=function(e,t,n,r,o){var a,i,s=8*o-r-1,l=(1<>1,c=-7,p=n?o-1:0,f=n?-1:1,h=e[t+p];for(p+=f,a=h&(1<<-c)-1,h>>=-c,c+=s;c>0;a=256*a+e[t+p],p+=f,c-=8);for(i=a&(1<<-c)-1,a>>=-c,c+=r;c>0;i=256*i+e[t+p],p+=f,c-=8);if(0===a)a=1-u;else{if(a===l)return i?NaN:1/0*(h?-1:1);i+=Math.pow(2,r),a-=u}return(h?-1:1)*i*Math.pow(2,a-r)},t.write=function(e,t,n,r,o,a){var i,s,l,u=8*a-o-1,c=(1<>1,f=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:a-1,d=r?1:-1,m=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(s=isNaN(t)?1:0,i=c):(i=Math.floor(Math.log(t)/Math.LN2),t*(l=Math.pow(2,-i))<1&&(i--,l*=2),(t+=i+p>=1?f/l:f*Math.pow(2,1-p))*l>=2&&(i++,l/=2),i+p>=c?(s=0,i=c):i+p>=1?(s=(t*l-1)*Math.pow(2,o),i+=p):(s=t*Math.pow(2,p-1)*Math.pow(2,o),i=0));o>=8;e[n+h]=255&s,h+=d,s/=256,o-=8);for(i=i<0;e[n+h]=255&i,h+=d,i/=256,u-=8);e[n+h-d]|=128*m}},43393:function(e){e.exports=function(){"use strict";var e=Array.prototype.slice;function t(e,t){t&&(e.prototype=Object.create(t.prototype)),e.prototype.constructor=e}function n(e){return i(e)?e:J(e)}function r(e){return s(e)?e:K(e)}function o(e){return l(e)?e:G(e)}function a(e){return i(e)&&!u(e)?e:Z(e)}function i(e){return!(!e||!e[p])}function s(e){return!(!e||!e[f])}function l(e){return!(!e||!e[h])}function u(e){return s(e)||l(e)}function c(e){return!(!e||!e[d])}t(r,n),t(o,n),t(a,n),n.isIterable=i,n.isKeyed=s,n.isIndexed=l,n.isAssociative=u,n.isOrdered=c,n.Keyed=r,n.Indexed=o,n.Set=a;var p="@@__IMMUTABLE_ITERABLE__@@",f="@@__IMMUTABLE_KEYED__@@",h="@@__IMMUTABLE_INDEXED__@@",d="@@__IMMUTABLE_ORDERED__@@",m="delete",g=5,y=1<>>0;if(""+n!==t||4294967295===n)return NaN;t=n}return t<0?C(e)+t:t}function O(){return!0}function j(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&t>=n)}function T(e,t){return N(e,t,0)}function I(e,t){return N(e,t,t)}function N(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var P=0,R=1,M=2,D="function"==typeof Symbol&&Symbol.iterator,L="@@iterator",B=D||L;function F(e){this.next=e}function z(e,t,n,r){var o=0===e?t:1===e?n:[t,n];return r?r.value=o:r={value:o,done:!1},r}function U(){return{value:void 0,done:!0}}function q(e){return!!W(e)}function $(e){return e&&"function"==typeof e.next}function V(e){var t=W(e);return t&&t.call(e)}function W(e){var t=e&&(D&&e[D]||e[L]);if("function"==typeof t)return t}function H(e){return e&&"number"==typeof e.length}function J(e){return null==e?ie():i(e)?e.toSeq():ue(e)}function K(e){return null==e?ie().toKeyedSeq():i(e)?s(e)?e.toSeq():e.fromEntrySeq():se(e)}function G(e){return null==e?ie():i(e)?s(e)?e.entrySeq():e.toIndexedSeq():le(e)}function Z(e){return(null==e?ie():i(e)?s(e)?e.entrySeq():e:le(e)).toSetSeq()}F.prototype.toString=function(){return"[Iterator]"},F.KEYS=P,F.VALUES=R,F.ENTRIES=M,F.prototype.inspect=F.prototype.toSource=function(){return this.toString()},F.prototype[B]=function(){return this},t(J,n),J.of=function(){return J(arguments)},J.prototype.toSeq=function(){return this},J.prototype.toString=function(){return this.__toString("Seq {","}")},J.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},J.prototype.__iterate=function(e,t){return pe(this,e,t,!0)},J.prototype.__iterator=function(e,t){return fe(this,e,t,!0)},t(K,J),K.prototype.toKeyedSeq=function(){return this},t(G,J),G.of=function(){return G(arguments)},G.prototype.toIndexedSeq=function(){return this},G.prototype.toString=function(){return this.__toString("Seq [","]")},G.prototype.__iterate=function(e,t){return pe(this,e,t,!1)},G.prototype.__iterator=function(e,t){return fe(this,e,t,!1)},t(Z,J),Z.of=function(){return Z(arguments)},Z.prototype.toSetSeq=function(){return this},J.isSeq=ae,J.Keyed=K,J.Set=Z,J.Indexed=G;var Y,Q,X,ee="@@__IMMUTABLE_SEQ__@@";function te(e){this._array=e,this.size=e.length}function ne(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function re(e){this._iterable=e,this.size=e.length||e.size}function oe(e){this._iterator=e,this._iteratorCache=[]}function ae(e){return!(!e||!e[ee])}function ie(){return Y||(Y=new te([]))}function se(e){var t=Array.isArray(e)?new te(e).fromEntrySeq():$(e)?new oe(e).fromEntrySeq():q(e)?new re(e).fromEntrySeq():"object"==typeof e?new ne(e):void 0;if(!t)throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e);return t}function le(e){var t=ce(e);if(!t)throw new TypeError("Expected Array or iterable object of values: "+e);return t}function ue(e){var t=ce(e)||"object"==typeof e&&new ne(e);if(!t)throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e);return t}function ce(e){return H(e)?new te(e):$(e)?new oe(e):q(e)?new re(e):void 0}function pe(e,t,n,r){var o=e._cache;if(o){for(var a=o.length-1,i=0;i<=a;i++){var s=o[n?a-i:i];if(!1===t(s[1],r?s[0]:i,e))return i+1}return i}return e.__iterateUncached(t,n)}function fe(e,t,n,r){var o=e._cache;if(o){var a=o.length-1,i=0;return new F((function(){var e=o[n?a-i:i];return i++>a?U():z(t,r?e[0]:i-1,e[1])}))}return e.__iteratorUncached(t,n)}function he(e,t){return t?de(t,e,"",{"":e}):me(e)}function de(e,t,n,r){return Array.isArray(t)?e.call(r,n,G(t).map((function(n,r){return de(e,n,r,t)}))):ge(t)?e.call(r,n,K(t).map((function(n,r){return de(e,n,r,t)}))):t}function me(e){return Array.isArray(e)?G(e).map(me).toList():ge(e)?K(e).map(me).toMap():e}function ge(e){return e&&(e.constructor===Object||void 0===e.constructor)}function ye(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if((e=e.valueOf())===(t=t.valueOf())||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function ve(e,t){if(e===t)return!0;if(!i(t)||void 0!==e.size&&void 0!==t.size&&e.size!==t.size||void 0!==e.__hash&&void 0!==t.__hash&&e.__hash!==t.__hash||s(e)!==s(t)||l(e)!==l(t)||c(e)!==c(t))return!1;if(0===e.size&&0===t.size)return!0;var n=!u(e);if(c(e)){var r=e.entries();return t.every((function(e,t){var o=r.next().value;return o&&ye(o[1],e)&&(n||ye(o[0],t))}))&&r.next().done}var o=!1;if(void 0===e.size)if(void 0===t.size)"function"==typeof e.cacheResult&&e.cacheResult();else{o=!0;var a=e;e=t,t=a}var p=!0,f=t.__iterate((function(t,r){if(n?!e.has(t):o?!ye(t,e.get(r,b)):!ye(e.get(r,b),t))return p=!1,!1}));return p&&e.size===f}function be(e,t){if(!(this instanceof be))return new be(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(Q)return Q;Q=this}}function we(e,t){if(!e)throw new Error(t)}function Ee(e,t,n){if(!(this instanceof Ee))return new Ee(e,t,n);if(we(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),tr?U():z(e,o,n[t?r-o++:o++])}))},t(ne,K),ne.prototype.get=function(e,t){return void 0===t||this.has(e)?this._object[e]:t},ne.prototype.has=function(e){return this._object.hasOwnProperty(e)},ne.prototype.__iterate=function(e,t){for(var n=this._object,r=this._keys,o=r.length-1,a=0;a<=o;a++){var i=r[t?o-a:a];if(!1===e(n[i],i,this))return a+1}return a},ne.prototype.__iterator=function(e,t){var n=this._object,r=this._keys,o=r.length-1,a=0;return new F((function(){var i=r[t?o-a:a];return a++>o?U():z(e,i,n[i])}))},ne.prototype[d]=!0,t(re,G),re.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n=V(this._iterable),r=0;if($(n))for(var o;!(o=n.next()).done&&!1!==e(o.value,r++,this););return r},re.prototype.__iteratorUncached=function(e,t){if(t)return this.cacheResult().__iterator(e,t);var n=V(this._iterable);if(!$(n))return new F(U);var r=0;return new F((function(){var t=n.next();return t.done?t:z(e,r++,t.value)}))},t(oe,G),oe.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n,r=this._iterator,o=this._iteratorCache,a=0;a=r.length){var t=n.next();if(t.done)return t;r[o]=t.value}return z(e,o,r[o++])}))},t(be,G),be.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},be.prototype.get=function(e,t){return this.has(e)?this._value:t},be.prototype.includes=function(e){return ye(this._value,e)},be.prototype.slice=function(e,t){var n=this.size;return j(e,t,n)?this:new be(this._value,I(t,n)-T(e,n))},be.prototype.reverse=function(){return this},be.prototype.indexOf=function(e){return ye(this._value,e)?0:-1},be.prototype.lastIndexOf=function(e){return ye(this._value,e)?this.size:-1},be.prototype.__iterate=function(e,t){for(var n=0;n=0&&t=0&&nn?U():z(e,a++,i)}))},Ee.prototype.equals=function(e){return e instanceof Ee?this._start===e._start&&this._end===e._end&&this._step===e._step:ve(this,e)},t(xe,n),t(_e,xe),t(Se,xe),t(Ae,xe),xe.Keyed=_e,xe.Indexed=Se,xe.Set=Ae;var Ce="function"==typeof Math.imul&&-2===Math.imul(4294967295,2)?Math.imul:function(e,t){var n=65535&(e|=0),r=65535&(t|=0);return n*r+((e>>>16)*r+n*(t>>>16)<<16>>>0)|0};function ke(e){return e>>>1&1073741824|3221225471&e}function Oe(e){if(!1===e||null==e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t=typeof e;if("number"===t){if(e!=e||e===1/0)return 0;var n=0|e;for(n!==e&&(n^=4294967295*e);e>4294967295;)n^=e/=4294967295;return ke(n)}if("string"===t)return e.length>Fe?je(e):Te(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"===t)return Ie(e);if("function"==typeof e.toString)return Te(e.toString());throw new Error("Value type "+t+" cannot be hashed.")}function je(e){var t=qe[e];return void 0===t&&(t=Te(e),Ue===ze&&(Ue=0,qe={}),Ue++,qe[e]=t),t}function Te(e){for(var t=0,n=0;n0)switch(e.nodeType){case 1:return e.uniqueID;case 9:return e.documentElement&&e.documentElement.uniqueID}}var Me,De="function"==typeof WeakMap;De&&(Me=new WeakMap);var Le=0,Be="__immutablehash__";"function"==typeof Symbol&&(Be=Symbol(Be));var Fe=16,ze=255,Ue=0,qe={};function $e(e){we(e!==1/0,"Cannot perform this action with an infinite size.")}function Ve(e){return null==e?ot():We(e)&&!c(e)?e:ot().withMutations((function(t){var n=r(e);$e(n.size),n.forEach((function(e,n){return t.set(n,e)}))}))}function We(e){return!(!e||!e[Je])}t(Ve,_e),Ve.of=function(){var t=e.call(arguments,0);return ot().withMutations((function(e){for(var n=0;n=t.length)throw new Error("Missing value for key: "+t[n]);e.set(t[n],t[n+1])}}))},Ve.prototype.toString=function(){return this.__toString("Map {","}")},Ve.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},Ve.prototype.set=function(e,t){return at(this,e,t)},Ve.prototype.setIn=function(e,t){return this.updateIn(e,b,(function(){return t}))},Ve.prototype.remove=function(e){return at(this,e,b)},Ve.prototype.deleteIn=function(e){return this.updateIn(e,(function(){return b}))},Ve.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},Ve.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);var r=gt(this,xn(e),t,n);return r===b?void 0:r},Ve.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):ot()},Ve.prototype.merge=function(){return ft(this,void 0,arguments)},Ve.prototype.mergeWith=function(t){return ft(this,t,e.call(arguments,1))},Ve.prototype.mergeIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,ot(),(function(e){return"function"==typeof e.merge?e.merge.apply(e,n):n[n.length-1]}))},Ve.prototype.mergeDeep=function(){return ft(this,ht,arguments)},Ve.prototype.mergeDeepWith=function(t){var n=e.call(arguments,1);return ft(this,dt(t),n)},Ve.prototype.mergeDeepIn=function(t){var n=e.call(arguments,1);return this.updateIn(t,ot(),(function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,n):n[n.length-1]}))},Ve.prototype.sort=function(e){return qt(pn(this,e))},Ve.prototype.sortBy=function(e,t){return qt(pn(this,t,e))},Ve.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},Ve.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new S)},Ve.prototype.asImmutable=function(){return this.__ensureOwner()},Ve.prototype.wasAltered=function(){return this.__altered},Ve.prototype.__iterator=function(e,t){return new et(this,e,t)},Ve.prototype.__iterate=function(e,t){var n=this,r=0;return this._root&&this._root.iterate((function(t){return r++,e(t[1],t[0],n)}),t),r},Ve.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?rt(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},Ve.isMap=We;var He,Je="@@__IMMUTABLE_MAP__@@",Ke=Ve.prototype;function Ge(e,t){this.ownerID=e,this.entries=t}function Ze(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function Ye(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function Qe(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function Xe(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function et(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&nt(e._root)}function tt(e,t){return z(e,t[0],t[1])}function nt(e,t){return{node:e,index:0,__prev:t}}function rt(e,t,n,r){var o=Object.create(Ke);return o.size=e,o._root=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function ot(){return He||(He=rt(0))}function at(e,t,n){var r,o;if(e._root){var a=x(w),i=x(E);if(r=it(e._root,e.__ownerID,0,void 0,t,n,a,i),!i.value)return e;o=e.size+(a.value?n===b?-1:1:0)}else{if(n===b)return e;o=1,r=new Ge(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=o,e._root=r,e.__hash=void 0,e.__altered=!0,e):r?rt(o,r):ot()}function it(e,t,n,r,o,a,i,s){return e?e.update(t,n,r,o,a,i,s):a===b?e:(_(s),_(i),new Xe(t,r,[o,a]))}function st(e){return e.constructor===Xe||e.constructor===Qe}function lt(e,t,n,r,o){if(e.keyHash===r)return new Qe(t,r,[e.entry,o]);var a,i=(0===n?e.keyHash:e.keyHash>>>n)&v,s=(0===n?r:r>>>n)&v;return new Ze(t,1<>>=1)i[s]=1&n?t[a++]:void 0;return i[r]=o,new Ye(e,a+1,i)}function ft(e,t,n){for(var o=[],a=0;a>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,e+=e>>8,127&(e+=e>>16)}function vt(e,t,n,r){var o=r?e:A(e);return o[t]=n,o}function bt(e,t,n,r){var o=e.length+1;if(r&&t+1===o)return e[t]=n,e;for(var a=new Array(o),i=0,s=0;s=Et)return ut(e,l,r,o);var f=e&&e===this.ownerID,h=f?l:A(l);return p?s?u===c-1?h.pop():h[u]=h.pop():h[u]=[r,o]:h.push([r,o]),f?(this.entries=h,this):new Ge(e,h)}},Ze.prototype.get=function(e,t,n,r){void 0===t&&(t=Oe(n));var o=1<<((0===e?t:t>>>e)&v),a=this.bitmap;return 0==(a&o)?r:this.nodes[yt(a&o-1)].get(e+g,t,n,r)},Ze.prototype.update=function(e,t,n,r,o,a,i){void 0===n&&(n=Oe(r));var s=(0===t?n:n>>>t)&v,l=1<=xt)return pt(e,f,u,s,d);if(c&&!d&&2===f.length&&st(f[1^p]))return f[1^p];if(c&&d&&1===f.length&&st(d))return d;var m=e&&e===this.ownerID,y=c?d?u:u^l:u|l,w=c?d?vt(f,p,d,m):wt(f,p,m):bt(f,p,d,m);return m?(this.bitmap=y,this.nodes=w,this):new Ze(e,y,w)},Ye.prototype.get=function(e,t,n,r){void 0===t&&(t=Oe(n));var o=(0===e?t:t>>>e)&v,a=this.nodes[o];return a?a.get(e+g,t,n,r):r},Ye.prototype.update=function(e,t,n,r,o,a,i){void 0===n&&(n=Oe(r));var s=(0===t?n:n>>>t)&v,l=o===b,u=this.nodes,c=u[s];if(l&&!c)return this;var p=it(c,e,t+g,n,r,o,a,i);if(p===c)return this;var f=this.count;if(c){if(!p&&--f<_t)return ct(e,u,f,s)}else f++;var h=e&&e===this.ownerID,d=vt(u,s,p,h);return h?(this.count=f,this.nodes=d,this):new Ye(e,f,d)},Qe.prototype.get=function(e,t,n,r){for(var o=this.entries,a=0,i=o.length;a0&&r=0&&e>>t&v;if(r>=this.array.length)return new Ot([],e);var o,a=0===r;if(t>0){var i=this.array[r];if((o=i&&i.removeBefore(e,t-g,n))===i&&a)return this}if(a&&!o)return this;var s=Lt(this,e);if(!a)for(var l=0;l>>t&v;if(o>=this.array.length)return this;if(t>0){var a=this.array[o];if((r=a&&a.removeAfter(e,t-g,n))===a&&o===this.array.length-1)return this}var i=Lt(this,e);return i.array.splice(o+1),r&&(i.array[o]=r),i};var jt,Tt,It={};function Nt(e,t){var n=e._origin,r=e._capacity,o=Ut(r),a=e._tail;return i(e._root,e._level,0);function i(e,t,n){return 0===t?s(e,n):l(e,t,n)}function s(e,i){var s=i===o?a&&a.array:e&&e.array,l=i>n?0:n-i,u=r-i;return u>y&&(u=y),function(){if(l===u)return It;var e=t?--u:l++;return s&&s[e]}}function l(e,o,a){var s,l=e&&e.array,u=a>n?0:n-a>>o,c=1+(r-a>>o);return c>y&&(c=y),function(){for(;;){if(s){var e=s();if(e!==It)return e;s=null}if(u===c)return It;var n=t?--c:u++;s=i(l&&l[n],o-g,a+(n<=e.size||t<0)return e.withMutations((function(e){t<0?Ft(e,t).set(0,n):Ft(e,0,t+1).set(t,n)}));t+=e._origin;var r=e._tail,o=e._root,a=x(E);return t>=Ut(e._capacity)?r=Dt(r,e.__ownerID,0,t,n,a):o=Dt(o,e.__ownerID,e._level,t,n,a),a.value?e.__ownerID?(e._root=o,e._tail=r,e.__hash=void 0,e.__altered=!0,e):Pt(e._origin,e._capacity,e._level,o,r):e}function Dt(e,t,n,r,o,a){var i,s=r>>>n&v,l=e&&s0){var u=e&&e.array[s],c=Dt(u,t,n-g,r,o,a);return c===u?e:((i=Lt(e,t)).array[s]=c,i)}return l&&e.array[s]===o?e:(_(a),i=Lt(e,t),void 0===o&&s===i.array.length-1?i.array.pop():i.array[s]=o,i)}function Lt(e,t){return t&&e&&t===e.ownerID?e:new Ot(e?e.array.slice():[],t)}function Bt(e,t){if(t>=Ut(e._capacity))return e._tail;if(t<1<0;)n=n.array[t>>>r&v],r-=g;return n}}function Ft(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new S,o=e._origin,a=e._capacity,i=o+t,s=void 0===n?a:n<0?a+n:o+n;if(i===o&&s===a)return e;if(i>=s)return e.clear();for(var l=e._level,u=e._root,c=0;i+c<0;)u=new Ot(u&&u.array.length?[void 0,u]:[],r),c+=1<<(l+=g);c&&(i+=c,o+=c,s+=c,a+=c);for(var p=Ut(a),f=Ut(s);f>=1<p?new Ot([],r):h;if(h&&f>p&&ig;y-=g){var b=p>>>y&v;m=m.array[b]=Lt(m.array[b],r)}m.array[p>>>g&v]=h}if(s=f)i-=f,s-=f,l=g,u=null,d=d&&d.removeBefore(r,0,i);else if(i>o||f>>l&v;if(w!==f>>>l&v)break;w&&(c+=(1<o&&(u=u.removeBefore(r,l,i-c)),u&&fa&&(a=u.size),i(l)||(u=u.map((function(e){return he(e)}))),r.push(u)}return a>e.size&&(e=e.setSize(a)),mt(e,t,r)}function Ut(e){return e>>g<=y&&i.size>=2*a.size?(r=(o=i.filter((function(e,t){return void 0!==e&&s!==t}))).toKeyedSeq().map((function(e){return e[0]})).flip().toMap(),e.__ownerID&&(r.__ownerID=o.__ownerID=e.__ownerID)):(r=a.remove(t),o=s===i.size-1?i.pop():i.set(s,void 0))}else if(l){if(n===i.get(s)[1])return e;r=a,o=i.set(s,[t,n])}else r=a.set(t,i.size),o=i.set(i.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=o,e.__hash=void 0,e):Vt(r,o)}function Jt(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function Kt(e){this._iter=e,this.size=e.size}function Gt(e){this._iter=e,this.size=e.size}function Zt(e){this._iter=e,this.size=e.size}function Yt(e){var t=bn(e);return t._iter=e,t.size=e.size,t.flip=function(){return e},t.reverse=function(){var t=e.reverse.apply(this);return t.flip=function(){return e.reverse()},t},t.has=function(t){return e.includes(t)},t.includes=function(t){return e.has(t)},t.cacheResult=wn,t.__iterateUncached=function(t,n){var r=this;return e.__iterate((function(e,n){return!1!==t(n,e,r)}),n)},t.__iteratorUncached=function(t,n){if(t===M){var r=e.__iterator(t,n);return new F((function(){var e=r.next();if(!e.done){var t=e.value[0];e.value[0]=e.value[1],e.value[1]=t}return e}))}return e.__iterator(t===R?P:R,n)},t}function Qt(e,t,n){var r=bn(e);return r.size=e.size,r.has=function(t){return e.has(t)},r.get=function(r,o){var a=e.get(r,b);return a===b?o:t.call(n,a,r,e)},r.__iterateUncached=function(r,o){var a=this;return e.__iterate((function(e,o,i){return!1!==r(t.call(n,e,o,i),o,a)}),o)},r.__iteratorUncached=function(r,o){var a=e.__iterator(M,o);return new F((function(){var o=a.next();if(o.done)return o;var i=o.value,s=i[0];return z(r,s,t.call(n,i[1],s,e),o)}))},r}function Xt(e,t){var n=bn(e);return n._iter=e,n.size=e.size,n.reverse=function(){return e},e.flip&&(n.flip=function(){var t=Yt(e);return t.reverse=function(){return e.flip()},t}),n.get=function(n,r){return e.get(t?n:-1-n,r)},n.has=function(n){return e.has(t?n:-1-n)},n.includes=function(t){return e.includes(t)},n.cacheResult=wn,n.__iterate=function(t,n){var r=this;return e.__iterate((function(e,n){return t(e,n,r)}),!n)},n.__iterator=function(t,n){return e.__iterator(t,!n)},n}function en(e,t,n,r){var o=bn(e);return r&&(o.has=function(r){var o=e.get(r,b);return o!==b&&!!t.call(n,o,r,e)},o.get=function(r,o){var a=e.get(r,b);return a!==b&&t.call(n,a,r,e)?a:o}),o.__iterateUncached=function(o,a){var i=this,s=0;return e.__iterate((function(e,a,l){if(t.call(n,e,a,l))return s++,o(e,r?a:s-1,i)}),a),s},o.__iteratorUncached=function(o,a){var i=e.__iterator(M,a),s=0;return new F((function(){for(;;){var a=i.next();if(a.done)return a;var l=a.value,u=l[0],c=l[1];if(t.call(n,c,u,e))return z(o,r?u:s++,c,a)}}))},o}function tn(e,t,n){var r=Ve().asMutable();return e.__iterate((function(o,a){r.update(t.call(n,o,a,e),0,(function(e){return e+1}))})),r.asImmutable()}function nn(e,t,n){var r=s(e),o=(c(e)?qt():Ve()).asMutable();e.__iterate((function(a,i){o.update(t.call(n,a,i,e),(function(e){return(e=e||[]).push(r?[i,a]:a),e}))}));var a=vn(e);return o.map((function(t){return mn(e,a(t))}))}function rn(e,t,n,r){var o=e.size;if(void 0!==t&&(t|=0),void 0!==n&&(n===1/0?n=o:n|=0),j(t,n,o))return e;var a=T(t,o),i=I(n,o);if(a!=a||i!=i)return rn(e.toSeq().cacheResult(),t,n,r);var s,l=i-a;l==l&&(s=l<0?0:l);var u=bn(e);return u.size=0===s?s:e.size&&s||void 0,!r&&ae(e)&&s>=0&&(u.get=function(t,n){return(t=k(this,t))>=0&&ts)return U();var e=o.next();return r||t===R?e:z(t,l-1,t===P?void 0:e.value[1],e)}))},u}function on(e,t,n){var r=bn(e);return r.__iterateUncached=function(r,o){var a=this;if(o)return this.cacheResult().__iterate(r,o);var i=0;return e.__iterate((function(e,o,s){return t.call(n,e,o,s)&&++i&&r(e,o,a)})),i},r.__iteratorUncached=function(r,o){var a=this;if(o)return this.cacheResult().__iterator(r,o);var i=e.__iterator(M,o),s=!0;return new F((function(){if(!s)return U();var e=i.next();if(e.done)return e;var o=e.value,l=o[0],u=o[1];return t.call(n,u,l,a)?r===M?e:z(r,l,u,e):(s=!1,U())}))},r}function an(e,t,n,r){var o=bn(e);return o.__iterateUncached=function(o,a){var i=this;if(a)return this.cacheResult().__iterate(o,a);var s=!0,l=0;return e.__iterate((function(e,a,u){if(!s||!(s=t.call(n,e,a,u)))return l++,o(e,r?a:l-1,i)})),l},o.__iteratorUncached=function(o,a){var i=this;if(a)return this.cacheResult().__iterator(o,a);var s=e.__iterator(M,a),l=!0,u=0;return new F((function(){var e,a,c;do{if((e=s.next()).done)return r||o===R?e:z(o,u++,o===P?void 0:e.value[1],e);var p=e.value;a=p[0],c=p[1],l&&(l=t.call(n,c,a,i))}while(l);return o===M?e:z(o,a,c,e)}))},o}function sn(e,t){var n=s(e),o=[e].concat(t).map((function(e){return i(e)?n&&(e=r(e)):e=n?se(e):le(Array.isArray(e)?e:[e]),e})).filter((function(e){return 0!==e.size}));if(0===o.length)return e;if(1===o.length){var a=o[0];if(a===e||n&&s(a)||l(e)&&l(a))return a}var u=new te(o);return n?u=u.toKeyedSeq():l(e)||(u=u.toSetSeq()),(u=u.flatten(!0)).size=o.reduce((function(e,t){if(void 0!==e){var n=t.size;if(void 0!==n)return e+n}}),0),u}function ln(e,t,n){var r=bn(e);return r.__iterateUncached=function(r,o){var a=0,s=!1;function l(e,u){var c=this;e.__iterate((function(e,o){return(!t||u0}function dn(e,t,r){var o=bn(e);return o.size=new te(r).map((function(e){return e.size})).min(),o.__iterate=function(e,t){for(var n,r=this.__iterator(R,t),o=0;!(n=r.next()).done&&!1!==e(n.value,o++,this););return o},o.__iteratorUncached=function(e,o){var a=r.map((function(e){return e=n(e),V(o?e.reverse():e)})),i=0,s=!1;return new F((function(){var n;return s||(n=a.map((function(e){return e.next()})),s=n.some((function(e){return e.done}))),s?U():z(e,i++,t.apply(null,n.map((function(e){return e.value}))))}))},o}function mn(e,t){return ae(e)?t:e.constructor(t)}function gn(e){if(e!==Object(e))throw new TypeError("Expected [K, V] tuple: "+e)}function yn(e){return $e(e.size),C(e)}function vn(e){return s(e)?r:l(e)?o:a}function bn(e){return Object.create((s(e)?K:l(e)?G:Z).prototype)}function wn(){return this._iter.cacheResult?(this._iter.cacheResult(),this.size=this._iter.size,this):J.prototype.cacheResult.call(this)}function En(e,t){return e>t?1:e=0;n--)t={value:arguments[n],next:t};return this.__ownerID?(this.size=e,this._head=t,this.__hash=void 0,this.__altered=!0,this):Kn(e,t)},$n.prototype.pushAll=function(e){if(0===(e=o(e)).size)return this;$e(e.size);var t=this.size,n=this._head;return e.reverse().forEach((function(e){t++,n={value:e,next:n}})),this.__ownerID?(this.size=t,this._head=n,this.__hash=void 0,this.__altered=!0,this):Kn(t,n)},$n.prototype.pop=function(){return this.slice(1)},$n.prototype.unshift=function(){return this.push.apply(this,arguments)},$n.prototype.unshiftAll=function(e){return this.pushAll(e)},$n.prototype.shift=function(){return this.pop.apply(this,arguments)},$n.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._head=void 0,this.__hash=void 0,this.__altered=!0,this):Gn()},$n.prototype.slice=function(e,t){if(j(e,t,this.size))return this;var n=T(e,this.size);if(I(t,this.size)!==this.size)return Se.prototype.slice.call(this,e,t);for(var r=this.size-n,o=this._head;n--;)o=o.next;return this.__ownerID?(this.size=r,this._head=o,this.__hash=void 0,this.__altered=!0,this):Kn(r,o)},$n.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?Kn(this.size,this._head,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},$n.prototype.__iterate=function(e,t){if(t)return this.reverse().__iterate(e);for(var n=0,r=this._head;r&&!1!==e(r.value,n++,this);)r=r.next;return n},$n.prototype.__iterator=function(e,t){if(t)return this.reverse().__iterator(e);var n=0,r=this._head;return new F((function(){if(r){var t=r.value;return r=r.next,z(e,n++,t)}return U()}))},$n.isStack=Vn;var Wn,Hn="@@__IMMUTABLE_STACK__@@",Jn=$n.prototype;function Kn(e,t,n,r){var o=Object.create(Jn);return o.size=e,o._head=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function Gn(){return Wn||(Wn=Kn(0))}function Zn(e,t){var n=function(n){e.prototype[n]=t[n]};return Object.keys(t).forEach(n),Object.getOwnPropertySymbols&&Object.getOwnPropertySymbols(t).forEach(n),e}Jn[Hn]=!0,Jn.withMutations=Ke.withMutations,Jn.asMutable=Ke.asMutable,Jn.asImmutable=Ke.asImmutable,Jn.wasAltered=Ke.wasAltered,n.Iterator=F,Zn(n,{toArray:function(){$e(this.size);var e=new Array(this.size||0);return this.valueSeq().__iterate((function(t,n){e[n]=t})),e},toIndexedSeq:function(){return new Kt(this)},toJS:function(){return this.toSeq().map((function(e){return e&&"function"==typeof e.toJS?e.toJS():e})).__toJS()},toJSON:function(){return this.toSeq().map((function(e){return e&&"function"==typeof e.toJSON?e.toJSON():e})).__toJS()},toKeyedSeq:function(){return new Jt(this,!0)},toMap:function(){return Ve(this.toKeyedSeq())},toObject:function(){$e(this.size);var e={};return this.__iterate((function(t,n){e[n]=t})),e},toOrderedMap:function(){return qt(this.toKeyedSeq())},toOrderedSet:function(){return Ln(s(this)?this.valueSeq():this)},toSet:function(){return jn(s(this)?this.valueSeq():this)},toSetSeq:function(){return new Gt(this)},toSeq:function(){return l(this)?this.toIndexedSeq():s(this)?this.toKeyedSeq():this.toSetSeq()},toStack:function(){return $n(s(this)?this.valueSeq():this)},toList:function(){return St(s(this)?this.valueSeq():this)},toString:function(){return"[Iterable]"},__toString:function(e,t){return 0===this.size?e+t:e+" "+this.toSeq().map(this.__toStringMapper).join(", ")+" "+t},concat:function(){return mn(this,sn(this,e.call(arguments,0)))},includes:function(e){return this.some((function(t){return ye(t,e)}))},entries:function(){return this.__iterator(M)},every:function(e,t){$e(this.size);var n=!0;return this.__iterate((function(r,o,a){if(!e.call(t,r,o,a))return n=!1,!1})),n},filter:function(e,t){return mn(this,en(this,e,t,!0))},find:function(e,t,n){var r=this.findEntry(e,t);return r?r[1]:n},forEach:function(e,t){return $e(this.size),this.__iterate(t?e.bind(t):e)},join:function(e){$e(this.size),e=void 0!==e?""+e:",";var t="",n=!0;return this.__iterate((function(r){n?n=!1:t+=e,t+=null!=r?r.toString():""})),t},keys:function(){return this.__iterator(P)},map:function(e,t){return mn(this,Qt(this,e,t))},reduce:function(e,t,n){var r,o;return $e(this.size),arguments.length<2?o=!0:r=t,this.__iterate((function(t,a,i){o?(o=!1,r=t):r=e.call(n,r,t,a,i)})),r},reduceRight:function(e,t,n){var r=this.toKeyedSeq().reverse();return r.reduce.apply(r,arguments)},reverse:function(){return mn(this,Xt(this,!0))},slice:function(e,t){return mn(this,rn(this,e,t,!0))},some:function(e,t){return!this.every(tr(e),t)},sort:function(e){return mn(this,pn(this,e))},values:function(){return this.__iterator(R)},butLast:function(){return this.slice(0,-1)},isEmpty:function(){return void 0!==this.size?0===this.size:!this.some((function(){return!0}))},count:function(e,t){return C(e?this.toSeq().filter(e,t):this)},countBy:function(e,t){return tn(this,e,t)},equals:function(e){return ve(this,e)},entrySeq:function(){var e=this;if(e._cache)return new te(e._cache);var t=e.toSeq().map(er).toIndexedSeq();return t.fromEntrySeq=function(){return e.toSeq()},t},filterNot:function(e,t){return this.filter(tr(e),t)},findEntry:function(e,t,n){var r=n;return this.__iterate((function(n,o,a){if(e.call(t,n,o,a))return r=[o,n],!1})),r},findKey:function(e,t){var n=this.findEntry(e,t);return n&&n[0]},findLast:function(e,t,n){return this.toKeyedSeq().reverse().find(e,t,n)},findLastEntry:function(e,t,n){return this.toKeyedSeq().reverse().findEntry(e,t,n)},findLastKey:function(e,t){return this.toKeyedSeq().reverse().findKey(e,t)},first:function(){return this.find(O)},flatMap:function(e,t){return mn(this,un(this,e,t))},flatten:function(e){return mn(this,ln(this,e,!0))},fromEntrySeq:function(){return new Zt(this)},get:function(e,t){return this.find((function(t,n){return ye(n,e)}),void 0,t)},getIn:function(e,t){for(var n,r=this,o=xn(e);!(n=o.next()).done;){var a=n.value;if((r=r&&r.get?r.get(a,b):b)===b)return t}return r},groupBy:function(e,t){return nn(this,e,t)},has:function(e){return this.get(e,b)!==b},hasIn:function(e){return this.getIn(e,b)!==b},isSubset:function(e){return e="function"==typeof e.includes?e:n(e),this.every((function(t){return e.includes(t)}))},isSuperset:function(e){return(e="function"==typeof e.isSubset?e:n(e)).isSubset(this)},keyOf:function(e){return this.findKey((function(t){return ye(t,e)}))},keySeq:function(){return this.toSeq().map(Xn).toIndexedSeq()},last:function(){return this.toSeq().reverse().first()},lastKeyOf:function(e){return this.toKeyedSeq().reverse().keyOf(e)},max:function(e){return fn(this,e)},maxBy:function(e,t){return fn(this,t,e)},min:function(e){return fn(this,e?nr(e):ar)},minBy:function(e,t){return fn(this,t?nr(t):ar,e)},rest:function(){return this.slice(1)},skip:function(e){return this.slice(Math.max(0,e))},skipLast:function(e){return mn(this,this.toSeq().reverse().skip(e).reverse())},skipWhile:function(e,t){return mn(this,an(this,e,t,!0))},skipUntil:function(e,t){return this.skipWhile(tr(e),t)},sortBy:function(e,t){return mn(this,pn(this,t,e))},take:function(e){return this.slice(0,Math.max(0,e))},takeLast:function(e){return mn(this,this.toSeq().reverse().take(e).reverse())},takeWhile:function(e,t){return mn(this,on(this,e,t))},takeUntil:function(e,t){return this.takeWhile(tr(e),t)},valueSeq:function(){return this.toIndexedSeq()},hashCode:function(){return this.__hash||(this.__hash=ir(this))}});var Yn=n.prototype;Yn[p]=!0,Yn[B]=Yn.values,Yn.__toJS=Yn.toArray,Yn.__toStringMapper=rr,Yn.inspect=Yn.toSource=function(){return this.toString()},Yn.chain=Yn.flatMap,Yn.contains=Yn.includes,Zn(r,{flip:function(){return mn(this,Yt(this))},mapEntries:function(e,t){var n=this,r=0;return mn(this,this.toSeq().map((function(o,a){return e.call(t,[a,o],r++,n)})).fromEntrySeq())},mapKeys:function(e,t){var n=this;return mn(this,this.toSeq().flip().map((function(r,o){return e.call(t,r,o,n)})).flip())}});var Qn=r.prototype;function Xn(e,t){return t}function er(e,t){return[t,e]}function tr(e){return function(){return!e.apply(this,arguments)}}function nr(e){return function(){return-e.apply(this,arguments)}}function rr(e){return"string"==typeof e?JSON.stringify(e):String(e)}function or(){return A(arguments)}function ar(e,t){return et?-1:0}function ir(e){if(e.size===1/0)return 0;var t=c(e),n=s(e),r=t?1:0;return sr(e.__iterate(n?t?function(e,t){r=31*r+lr(Oe(e),Oe(t))|0}:function(e,t){r=r+lr(Oe(e),Oe(t))|0}:t?function(e){r=31*r+Oe(e)|0}:function(e){r=r+Oe(e)|0}),r)}function sr(e,t){return t=Ce(t,3432918353),t=Ce(t<<15|t>>>-15,461845907),t=Ce(t<<13|t>>>-13,5),t=Ce((t=(t+3864292196|0)^e)^t>>>16,2246822507),t=ke((t=Ce(t^t>>>13,3266489909))^t>>>16)}function lr(e,t){return e^t+2654435769+(e<<6)+(e>>2)|0}return Qn[f]=!0,Qn[B]=Yn.entries,Qn.__toJS=Yn.toObject,Qn.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+rr(e)},Zn(o,{toKeyedSeq:function(){return new Jt(this,!1)},filter:function(e,t){return mn(this,en(this,e,t,!1))},findIndex:function(e,t){var n=this.findEntry(e,t);return n?n[0]:-1},indexOf:function(e){var t=this.keyOf(e);return void 0===t?-1:t},lastIndexOf:function(e){var t=this.lastKeyOf(e);return void 0===t?-1:t},reverse:function(){return mn(this,Xt(this,!1))},slice:function(e,t){return mn(this,rn(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=T(e,e<0?this.count():this.size);var r=this.slice(0,e);return mn(this,1===n?r:r.concat(A(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){var n=this.findLastEntry(e,t);return n?n[0]:-1},first:function(){return this.get(0)},flatten:function(e){return mn(this,ln(this,e,!1))},get:function(e,t){return(e=k(this,e))<0||this.size===1/0||void 0!==this.size&&e>this.size?t:this.find((function(t,n){return n===e}),void 0,t)},has:function(e){return(e=k(this,e))>=0&&(void 0!==this.size?this.size===1/0||e{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){if(t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}}},35823:e=>{e.exports=function(e,t,n,r){var o=new Blob(void 0!==r?[r,e]:[e],{type:n||"application/octet-stream"});if(void 0!==window.navigator.msSaveBlob)window.navigator.msSaveBlob(o,t);else{var a=window.URL&&window.URL.createObjectURL?window.URL.createObjectURL(o):window.webkitURL.createObjectURL(o),i=document.createElement("a");i.style.display="none",i.href=a,i.setAttribute("download",t),void 0===i.download&&i.setAttribute("target","_blank"),document.body.appendChild(i),i.click(),setTimeout((function(){document.body.removeChild(i),window.URL.revokeObjectURL(a)}),200)}}},91296:(e,t,n)=>{var r=NaN,o="[object Symbol]",a=/^\s+|\s+$/g,i=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,l=/^0o[0-7]+$/i,u=parseInt,c="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,p="object"==typeof self&&self&&self.Object===Object&&self,f=c||p||Function("return this")(),h=Object.prototype.toString,d=Math.max,m=Math.min,g=function(){return f.Date.now()};function y(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function v(e){if("number"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&h.call(e)==o}(e))return r;if(y(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=y(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(a,"");var n=s.test(e);return n||l.test(e)?u(e.slice(2),n?2:8):i.test(e)?r:+e}e.exports=function(e,t,n){var r,o,a,i,s,l,u=0,c=!1,p=!1,f=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function h(t){var n=r,a=o;return r=o=void 0,u=t,i=e.apply(a,n)}function b(e){var n=e-l;return void 0===l||n>=t||n<0||p&&e-u>=a}function w(){var e=g();if(b(e))return E(e);s=setTimeout(w,function(e){var n=t-(e-l);return p?m(n,a-(e-u)):n}(e))}function E(e){return s=void 0,f&&r?h(e):(r=o=void 0,i)}function x(){var e=g(),n=b(e);if(r=arguments,o=this,l=e,n){if(void 0===s)return function(e){return u=e,s=setTimeout(w,t),c?h(e):i}(l);if(p)return s=setTimeout(w,t),h(l)}return void 0===s&&(s=setTimeout(w,t)),i}return t=v(t)||0,y(n)&&(c=!!n.leading,a=(p="maxWait"in n)?d(v(n.maxWait)||0,t):a,f="trailing"in n?!!n.trailing:f),x.cancel=function(){void 0!==s&&clearTimeout(s),u=0,r=l=o=s=void 0},x.flush=function(){return void 0===s?i:E(g())},x}},18552:(e,t,n)=>{var r=n(10852)(n(55639),"DataView");e.exports=r},1989:(e,t,n)=>{var r=n(51789),o=n(80401),a=n(57667),i=n(21327),s=n(81866);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{var r=n(27040),o=n(14125),a=n(82117),i=n(67518),s=n(54705);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{var r=n(10852)(n(55639),"Map");e.exports=r},83369:(e,t,n)=>{var r=n(24785),o=n(11285),a=n(96e3),i=n(49916),s=n(95265);function l(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{var r=n(10852)(n(55639),"Promise");e.exports=r},58525:(e,t,n)=>{var r=n(10852)(n(55639),"Set");e.exports=r},88668:(e,t,n)=>{var r=n(83369),o=n(90619),a=n(72385);function i(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new r;++t{var r=n(38407),o=n(37465),a=n(63779),i=n(67599),s=n(44758),l=n(34309);function u(e){var t=this.__data__=new r(e);this.size=t.size}u.prototype.clear=o,u.prototype.delete=a,u.prototype.get=i,u.prototype.has=s,u.prototype.set=l,e.exports=u},62705:(e,t,n)=>{var r=n(55639).Symbol;e.exports=r},11149:(e,t,n)=>{var r=n(55639).Uint8Array;e.exports=r},70577:(e,t,n)=>{var r=n(10852)(n(55639),"WeakMap");e.exports=r},96874:e=>{e.exports=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}},77412:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,a=[];++n{var r=n(22545),o=n(35694),a=n(1469),i=n(44144),s=n(65776),l=n(36719),u=Object.prototype.hasOwnProperty;e.exports=function(e,t){var n=a(e),c=!n&&o(e),p=!n&&!c&&i(e),f=!n&&!c&&!p&&l(e),h=n||c||p||f,d=h?r(e.length,String):[],m=d.length;for(var g in e)!t&&!u.call(e,g)||h&&("length"==g||p&&("offset"==g||"parent"==g)||f&&("buffer"==g||"byteLength"==g||"byteOffset"==g)||s(g,m))||d.push(g);return d}},29932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n{e.exports=function(e,t){for(var n=-1,r=t.length,o=e.length;++n{e.exports=function(e,t,n,r){var o=-1,a=null==e?0:e.length;for(r&&a&&(n=e[++o]);++o{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n{e.exports=function(e){return e.split("")}},49029:e=>{var t=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;e.exports=function(e){return e.match(t)||[]}},86556:(e,t,n)=>{var r=n(89465),o=n(77813);e.exports=function(e,t,n){(void 0!==n&&!o(e[t],n)||void 0===n&&!(t in e))&&r(e,t,n)}},34865:(e,t,n)=>{var r=n(89465),o=n(77813),a=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var i=e[t];a.call(e,t)&&o(i,n)&&(void 0!==n||t in e)||r(e,t,n)}},18470:(e,t,n)=>{var r=n(77813);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},44037:(e,t,n)=>{var r=n(98363),o=n(3674);e.exports=function(e,t){return e&&r(t,o(t),e)}},63886:(e,t,n)=>{var r=n(98363),o=n(81704);e.exports=function(e,t){return e&&r(t,o(t),e)}},89465:(e,t,n)=>{var r=n(38777);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},85990:(e,t,n)=>{var r=n(46384),o=n(77412),a=n(34865),i=n(44037),s=n(63886),l=n(64626),u=n(278),c=n(18805),p=n(1911),f=n(58234),h=n(46904),d=n(98882),m=n(43824),g=n(29148),y=n(38517),v=n(1469),b=n(44144),w=n(56688),E=n(13218),x=n(72928),_=n(3674),S=n(81704),A="[object Arguments]",C="[object Function]",k="[object Object]",O={};O[A]=O["[object Array]"]=O["[object ArrayBuffer]"]=O["[object DataView]"]=O["[object Boolean]"]=O["[object Date]"]=O["[object Float32Array]"]=O["[object Float64Array]"]=O["[object Int8Array]"]=O["[object Int16Array]"]=O["[object Int32Array]"]=O["[object Map]"]=O["[object Number]"]=O[k]=O["[object RegExp]"]=O["[object Set]"]=O["[object String]"]=O["[object Symbol]"]=O["[object Uint8Array]"]=O["[object Uint8ClampedArray]"]=O["[object Uint16Array]"]=O["[object Uint32Array]"]=!0,O["[object Error]"]=O[C]=O["[object WeakMap]"]=!1,e.exports=function e(t,n,j,T,I,N){var P,R=1&n,M=2&n,D=4&n;if(j&&(P=I?j(t,T,I,N):j(t)),void 0!==P)return P;if(!E(t))return t;var L=v(t);if(L){if(P=m(t),!R)return u(t,P)}else{var B=d(t),F=B==C||"[object GeneratorFunction]"==B;if(b(t))return l(t,R);if(B==k||B==A||F&&!I){if(P=M||F?{}:y(t),!R)return M?p(t,s(P,t)):c(t,i(P,t))}else{if(!O[B])return I?t:{};P=g(t,B,R)}}N||(N=new r);var z=N.get(t);if(z)return z;N.set(t,P),x(t)?t.forEach((function(r){P.add(e(r,n,j,r,t,N))})):w(t)&&t.forEach((function(r,o){P.set(o,e(r,n,j,o,t,N))}));var U=L?void 0:(D?M?h:f:M?S:_)(t);return o(U||t,(function(r,o){U&&(r=t[o=r]),a(P,o,e(r,n,j,o,t,N))})),P}},3118:(e,t,n)=>{var r=n(13218),o=Object.create,a=function(){function e(){}return function(t){if(!r(t))return{};if(o)return o(t);e.prototype=t;var n=new e;return e.prototype=void 0,n}}();e.exports=a},89881:(e,t,n)=>{var r=n(47816),o=n(99291)(r);e.exports=o},41848:e=>{e.exports=function(e,t,n,r){for(var o=e.length,a=n+(r?1:-1);r?a--:++a{var r=n(62488),o=n(37285);e.exports=function e(t,n,a,i,s){var l=-1,u=t.length;for(a||(a=o),s||(s=[]);++l0&&a(c)?n>1?e(c,n-1,a,i,s):r(s,c):i||(s[s.length]=c)}return s}},28483:(e,t,n)=>{var r=n(25063)();e.exports=r},47816:(e,t,n)=>{var r=n(28483),o=n(3674);e.exports=function(e,t){return e&&r(e,t,o)}},97786:(e,t,n)=>{var r=n(71811),o=n(40327);e.exports=function(e,t){for(var n=0,a=(t=r(t,e)).length;null!=e&&n{var r=n(62488),o=n(1469);e.exports=function(e,t,n){var a=t(e);return o(e)?a:r(a,n(e))}},44239:(e,t,n)=>{var r=n(62705),o=n(89607),a=n(2333),i=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":i&&i in Object(e)?o(e):a(e)}},13:e=>{e.exports=function(e,t){return null!=e&&t in Object(e)}},9454:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return o(e)&&"[object Arguments]"==r(e)}},90939:(e,t,n)=>{var r=n(2492),o=n(37005);e.exports=function e(t,n,a,i,s){return t===n||(null==t||null==n||!o(t)&&!o(n)?t!=t&&n!=n:r(t,n,a,i,e,s))}},2492:(e,t,n)=>{var r=n(46384),o=n(67114),a=n(18351),i=n(16096),s=n(98882),l=n(1469),u=n(44144),c=n(36719),p="[object Arguments]",f="[object Array]",h="[object Object]",d=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,m,g,y){var v=l(e),b=l(t),w=v?f:s(e),E=b?f:s(t),x=(w=w==p?h:w)==h,_=(E=E==p?h:E)==h,S=w==E;if(S&&u(e)){if(!u(t))return!1;v=!0,x=!1}if(S&&!x)return y||(y=new r),v||c(e)?o(e,t,n,m,g,y):a(e,t,w,n,m,g,y);if(!(1&n)){var A=x&&d.call(e,"__wrapped__"),C=_&&d.call(t,"__wrapped__");if(A||C){var k=A?e.value():e,O=C?t.value():t;return y||(y=new r),g(k,O,n,m,y)}}return!!S&&(y||(y=new r),i(e,t,n,m,g,y))}},25588:(e,t,n)=>{var r=n(98882),o=n(37005);e.exports=function(e){return o(e)&&"[object Map]"==r(e)}},2958:(e,t,n)=>{var r=n(46384),o=n(90939);e.exports=function(e,t,n,a){var i=n.length,s=i,l=!a;if(null==e)return!s;for(e=Object(e);i--;){var u=n[i];if(l&&u[2]?u[1]!==e[u[0]]:!(u[0]in e))return!1}for(;++i{var r=n(23560),o=n(15346),a=n(13218),i=n(80346),s=/^\[object .+?Constructor\]$/,l=Function.prototype,u=Object.prototype,c=l.toString,p=u.hasOwnProperty,f=RegExp("^"+c.call(p).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!a(e)||o(e))&&(r(e)?f:s).test(i(e))}},29221:(e,t,n)=>{var r=n(98882),o=n(37005);e.exports=function(e){return o(e)&&"[object Set]"==r(e)}},38749:(e,t,n)=>{var r=n(44239),o=n(41780),a=n(37005),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return a(e)&&o(e.length)&&!!i[r(e)]}},67206:(e,t,n)=>{var r=n(91573),o=n(16432),a=n(6557),i=n(1469),s=n(39601);e.exports=function(e){return"function"==typeof e?e:null==e?a:"object"==typeof e?i(e)?o(e[0],e[1]):r(e):s(e)}},280:(e,t,n)=>{var r=n(25726),o=n(86916),a=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return o(e);var t=[];for(var n in Object(e))a.call(e,n)&&"constructor"!=n&&t.push(n);return t}},10313:(e,t,n)=>{var r=n(13218),o=n(25726),a=n(33498),i=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return a(e);var t=o(e),n=[];for(var s in e)("constructor"!=s||!t&&i.call(e,s))&&n.push(s);return n}},91573:(e,t,n)=>{var r=n(2958),o=n(1499),a=n(42634);e.exports=function(e){var t=o(e);return 1==t.length&&t[0][2]?a(t[0][0],t[0][1]):function(n){return n===e||r(n,e,t)}}},16432:(e,t,n)=>{var r=n(90939),o=n(27361),a=n(79095),i=n(15403),s=n(89162),l=n(42634),u=n(40327);e.exports=function(e,t){return i(e)&&s(t)?l(u(e),t):function(n){var i=o(n,e);return void 0===i&&i===t?a(n,e):r(t,i,3)}}},42980:(e,t,n)=>{var r=n(46384),o=n(86556),a=n(28483),i=n(59783),s=n(13218),l=n(81704),u=n(36390);e.exports=function e(t,n,c,p,f){t!==n&&a(n,(function(a,l){if(f||(f=new r),s(a))i(t,n,l,c,e,p,f);else{var h=p?p(u(t,l),a,l+"",t,n,f):void 0;void 0===h&&(h=a),o(t,l,h)}}),l)}},59783:(e,t,n)=>{var r=n(86556),o=n(64626),a=n(77133),i=n(278),s=n(38517),l=n(35694),u=n(1469),c=n(29246),p=n(44144),f=n(23560),h=n(13218),d=n(68630),m=n(36719),g=n(36390),y=n(59881);e.exports=function(e,t,n,v,b,w,E){var x=g(e,n),_=g(t,n),S=E.get(_);if(S)r(e,n,S);else{var A=w?w(x,_,n+"",e,t,E):void 0,C=void 0===A;if(C){var k=u(_),O=!k&&p(_),j=!k&&!O&&m(_);A=_,k||O||j?u(x)?A=x:c(x)?A=i(x):O?(C=!1,A=o(_,!0)):j?(C=!1,A=a(_,!0)):A=[]:d(_)||l(_)?(A=x,l(x)?A=y(x):h(x)&&!f(x)||(A=s(_))):C=!1}C&&(E.set(_,A),b(A,_,v,w,E),E.delete(_)),r(e,n,A)}}},40371:e=>{e.exports=function(e){return function(t){return null==t?void 0:t[e]}}},79152:(e,t,n)=>{var r=n(97786);e.exports=function(e){return function(t){return r(t,e)}}},18674:e=>{e.exports=function(e){return function(t){return null==e?void 0:e[t]}}},10107:e=>{e.exports=function(e,t,n,r,o){return o(e,(function(e,o,a){n=r?(r=!1,e):t(n,e,o,a)})),n}},5976:(e,t,n)=>{var r=n(6557),o=n(45357),a=n(30061);e.exports=function(e,t){return a(o(e,t,r),e+"")}},10611:(e,t,n)=>{var r=n(34865),o=n(71811),a=n(65776),i=n(13218),s=n(40327);e.exports=function(e,t,n,l){if(!i(e))return e;for(var u=-1,c=(t=o(t,e)).length,p=c-1,f=e;null!=f&&++u{var r=n(75703),o=n(38777),a=n(6557),i=o?function(e,t){return o(e,"toString",{configurable:!0,enumerable:!1,value:r(t),writable:!0})}:a;e.exports=i},14259:e=>{e.exports=function(e,t,n){var r=-1,o=e.length;t<0&&(t=-t>o?0:o+t),(n=n>o?o:n)<0&&(n+=o),o=t>n?0:n-t>>>0,t>>>=0;for(var a=Array(o);++r{var r=n(89881);e.exports=function(e,t){var n;return r(e,(function(e,r,o){return!(n=t(e,r,o))})),!!n}},22545:e=>{e.exports=function(e,t){for(var n=-1,r=Array(e);++n{var r=n(62705),o=n(29932),a=n(1469),i=n(33448),s=r?r.prototype:void 0,l=s?s.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(a(t))return o(t,e)+"";if(i(t))return l?l.call(t):"";var n=t+"";return"0"==n&&1/t==-Infinity?"-0":n}},27561:(e,t,n)=>{var r=n(67990),o=/^\s+/;e.exports=function(e){return e?e.slice(0,r(e)+1).replace(o,""):e}},7518:e=>{e.exports=function(e){return function(t){return e(t)}}},57406:(e,t,n)=>{var r=n(71811),o=n(10928),a=n(40292),i=n(40327);e.exports=function(e,t){return t=r(t,e),null==(e=a(e,t))||delete e[i(o(t))]}},1757:e=>{e.exports=function(e,t,n){for(var r=-1,o=e.length,a=t.length,i={};++r{e.exports=function(e,t){return e.has(t)}},71811:(e,t,n)=>{var r=n(1469),o=n(15403),a=n(55514),i=n(79833);e.exports=function(e,t){return r(e)?e:o(e,t)?[e]:a(i(e))}},40180:(e,t,n)=>{var r=n(14259);e.exports=function(e,t,n){var o=e.length;return n=void 0===n?o:n,!t&&n>=o?e:r(e,t,n)}},74318:(e,t,n)=>{var r=n(11149);e.exports=function(e){var t=new e.constructor(e.byteLength);return new r(t).set(new r(e)),t}},64626:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o?r.Buffer:void 0,s=i?i.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();var n=e.length,r=s?s(n):new e.constructor(n);return e.copy(r),r}},57157:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.byteLength)}},93147:e=>{var t=/\w*$/;e.exports=function(e){var n=new e.constructor(e.source,t.exec(e));return n.lastIndex=e.lastIndex,n}},40419:(e,t,n)=>{var r=n(62705),o=r?r.prototype:void 0,a=o?o.valueOf:void 0;e.exports=function(e){return a?Object(a.call(e)):{}}},77133:(e,t,n)=>{var r=n(74318);e.exports=function(e,t){var n=t?r(e.buffer):e.buffer;return new e.constructor(n,e.byteOffset,e.length)}},278:e=>{e.exports=function(e,t){var n=-1,r=e.length;for(t||(t=Array(r));++n{var r=n(34865),o=n(89465);e.exports=function(e,t,n,a){var i=!n;n||(n={});for(var s=-1,l=t.length;++s{var r=n(98363),o=n(99551);e.exports=function(e,t){return r(e,o(e),t)}},1911:(e,t,n)=>{var r=n(98363),o=n(51442);e.exports=function(e,t){return r(e,o(e),t)}},14429:(e,t,n)=>{var r=n(55639)["__core-js_shared__"];e.exports=r},21463:(e,t,n)=>{var r=n(5976),o=n(16612);e.exports=function(e){return r((function(t,n){var r=-1,a=n.length,i=a>1?n[a-1]:void 0,s=a>2?n[2]:void 0;for(i=e.length>3&&"function"==typeof i?(a--,i):void 0,s&&o(n[0],n[1],s)&&(i=a<3?void 0:i,a=1),t=Object(t);++r{var r=n(98612);e.exports=function(e,t){return function(n,o){if(null==n)return n;if(!r(n))return e(n,o);for(var a=n.length,i=t?a:-1,s=Object(n);(t?i--:++i{e.exports=function(e){return function(t,n,r){for(var o=-1,a=Object(t),i=r(t),s=i.length;s--;){var l=i[e?s:++o];if(!1===n(a[l],l,a))break}return t}}},98805:(e,t,n)=>{var r=n(40180),o=n(62689),a=n(83140),i=n(79833);e.exports=function(e){return function(t){t=i(t);var n=o(t)?a(t):void 0,s=n?n[0]:t.charAt(0),l=n?r(n,1).join(""):t.slice(1);return s[e]()+l}}},35393:(e,t,n)=>{var r=n(62663),o=n(53816),a=n(58748),i=RegExp("['’]","g");e.exports=function(e){return function(t){return r(a(o(t).replace(i,"")),e,"")}}},67740:(e,t,n)=>{var r=n(67206),o=n(98612),a=n(3674);e.exports=function(e){return function(t,n,i){var s=Object(t);if(!o(t)){var l=r(n,3);t=a(t),n=function(e){return l(s[e],e,s)}}var u=e(t,n,i);return u>-1?s[l?t[u]:u]:void 0}}},60696:(e,t,n)=>{var r=n(68630);e.exports=function(e){return r(e)?void 0:e}},69389:(e,t,n)=>{var r=n(18674)({À:"A",Á:"A",Â:"A",Ã:"A",Ä:"A",Å:"A",à:"a",á:"a",â:"a",ã:"a",ä:"a",å:"a",Ç:"C",ç:"c",Ð:"D",ð:"d",È:"E",É:"E",Ê:"E",Ë:"E",è:"e",é:"e",ê:"e",ë:"e",Ì:"I",Í:"I",Î:"I",Ï:"I",ì:"i",í:"i",î:"i",ï:"i",Ñ:"N",ñ:"n",Ò:"O",Ó:"O",Ô:"O",Õ:"O",Ö:"O",Ø:"O",ò:"o",ó:"o",ô:"o",õ:"o",ö:"o",ø:"o",Ù:"U",Ú:"U",Û:"U",Ü:"U",ù:"u",ú:"u",û:"u",ü:"u",Ý:"Y",ý:"y",ÿ:"y",Æ:"Ae",æ:"ae",Þ:"Th",þ:"th",ß:"ss",Ā:"A",Ă:"A",Ą:"A",ā:"a",ă:"a",ą:"a",Ć:"C",Ĉ:"C",Ċ:"C",Č:"C",ć:"c",ĉ:"c",ċ:"c",č:"c",Ď:"D",Đ:"D",ď:"d",đ:"d",Ē:"E",Ĕ:"E",Ė:"E",Ę:"E",Ě:"E",ē:"e",ĕ:"e",ė:"e",ę:"e",ě:"e",Ĝ:"G",Ğ:"G",Ġ:"G",Ģ:"G",ĝ:"g",ğ:"g",ġ:"g",ģ:"g",Ĥ:"H",Ħ:"H",ĥ:"h",ħ:"h",Ĩ:"I",Ī:"I",Ĭ:"I",Į:"I",İ:"I",ĩ:"i",ī:"i",ĭ:"i",į:"i",ı:"i",Ĵ:"J",ĵ:"j",Ķ:"K",ķ:"k",ĸ:"k",Ĺ:"L",Ļ:"L",Ľ:"L",Ŀ:"L",Ł:"L",ĺ:"l",ļ:"l",ľ:"l",ŀ:"l",ł:"l",Ń:"N",Ņ:"N",Ň:"N",Ŋ:"N",ń:"n",ņ:"n",ň:"n",ŋ:"n",Ō:"O",Ŏ:"O",Ő:"O",ō:"o",ŏ:"o",ő:"o",Ŕ:"R",Ŗ:"R",Ř:"R",ŕ:"r",ŗ:"r",ř:"r",Ś:"S",Ŝ:"S",Ş:"S",Š:"S",ś:"s",ŝ:"s",ş:"s",š:"s",Ţ:"T",Ť:"T",Ŧ:"T",ţ:"t",ť:"t",ŧ:"t",Ũ:"U",Ū:"U",Ŭ:"U",Ů:"U",Ű:"U",Ų:"U",ũ:"u",ū:"u",ŭ:"u",ů:"u",ű:"u",ų:"u",Ŵ:"W",ŵ:"w",Ŷ:"Y",ŷ:"y",Ÿ:"Y",Ź:"Z",Ż:"Z",Ž:"Z",ź:"z",ż:"z",ž:"z",IJ:"IJ",ij:"ij",Œ:"Oe",œ:"oe",ʼn:"'n",ſ:"s"});e.exports=r},38777:(e,t,n)=>{var r=n(10852),o=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(e){}}();e.exports=o},67114:(e,t,n)=>{var r=n(88668),o=n(82908),a=n(74757);e.exports=function(e,t,n,i,s,l){var u=1&n,c=e.length,p=t.length;if(c!=p&&!(u&&p>c))return!1;var f=l.get(e),h=l.get(t);if(f&&h)return f==t&&h==e;var d=-1,m=!0,g=2&n?new r:void 0;for(l.set(e,t),l.set(t,e);++d{var r=n(62705),o=n(11149),a=n(77813),i=n(67114),s=n(68776),l=n(21814),u=r?r.prototype:void 0,c=u?u.valueOf:void 0;e.exports=function(e,t,n,r,u,p,f){switch(n){case"[object DataView]":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case"[object ArrayBuffer]":return!(e.byteLength!=t.byteLength||!p(new o(e),new o(t)));case"[object Boolean]":case"[object Date]":case"[object Number]":return a(+e,+t);case"[object Error]":return e.name==t.name&&e.message==t.message;case"[object RegExp]":case"[object String]":return e==t+"";case"[object Map]":var h=s;case"[object Set]":var d=1&r;if(h||(h=l),e.size!=t.size&&!d)return!1;var m=f.get(e);if(m)return m==t;r|=2,f.set(e,t);var g=i(h(e),h(t),r,u,p,f);return f.delete(e),g;case"[object Symbol]":if(c)return c.call(e)==c.call(t)}return!1}},16096:(e,t,n)=>{var r=n(58234),o=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,a,i,s){var l=1&n,u=r(e),c=u.length;if(c!=r(t).length&&!l)return!1;for(var p=c;p--;){var f=u[p];if(!(l?f in t:o.call(t,f)))return!1}var h=s.get(e),d=s.get(t);if(h&&d)return h==t&&d==e;var m=!0;s.set(e,t),s.set(t,e);for(var g=l;++p{var r=n(85564),o=n(45357),a=n(30061);e.exports=function(e){return a(o(e,void 0,r),e+"")}},31957:(e,t,n)=>{var r="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=r},58234:(e,t,n)=>{var r=n(68866),o=n(99551),a=n(3674);e.exports=function(e){return r(e,a,o)}},46904:(e,t,n)=>{var r=n(68866),o=n(51442),a=n(81704);e.exports=function(e){return r(e,a,o)}},45050:(e,t,n)=>{var r=n(37019);e.exports=function(e,t){var n=e.__data__;return r(t)?n["string"==typeof t?"string":"hash"]:n.map}},1499:(e,t,n)=>{var r=n(89162),o=n(3674);e.exports=function(e){for(var t=o(e),n=t.length;n--;){var a=t[n],i=e[a];t[n]=[a,i,r(i)]}return t}},10852:(e,t,n)=>{var r=n(28458),o=n(47801);e.exports=function(e,t){var n=o(e,t);return r(n)?n:void 0}},85924:(e,t,n)=>{var r=n(5569)(Object.getPrototypeOf,Object);e.exports=r},89607:(e,t,n)=>{var r=n(62705),o=Object.prototype,a=o.hasOwnProperty,i=o.toString,s=r?r.toStringTag:void 0;e.exports=function(e){var t=a.call(e,s),n=e[s];try{e[s]=void 0;var r=!0}catch(e){}var o=i.call(e);return r&&(t?e[s]=n:delete e[s]),o}},99551:(e,t,n)=>{var r=n(34963),o=n(70479),a=Object.prototype.propertyIsEnumerable,i=Object.getOwnPropertySymbols,s=i?function(e){return null==e?[]:(e=Object(e),r(i(e),(function(t){return a.call(e,t)})))}:o;e.exports=s},51442:(e,t,n)=>{var r=n(62488),o=n(85924),a=n(99551),i=n(70479),s=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)r(t,a(e)),e=o(e);return t}:i;e.exports=s},98882:(e,t,n)=>{var r=n(18552),o=n(57071),a=n(53818),i=n(58525),s=n(70577),l=n(44239),u=n(80346),c="[object Map]",p="[object Promise]",f="[object Set]",h="[object WeakMap]",d="[object DataView]",m=u(r),g=u(o),y=u(a),v=u(i),b=u(s),w=l;(r&&w(new r(new ArrayBuffer(1)))!=d||o&&w(new o)!=c||a&&w(a.resolve())!=p||i&&w(new i)!=f||s&&w(new s)!=h)&&(w=function(e){var t=l(e),n="[object Object]"==t?e.constructor:void 0,r=n?u(n):"";if(r)switch(r){case m:return d;case g:return c;case y:return p;case v:return f;case b:return h}return t}),e.exports=w},47801:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},222:(e,t,n)=>{var r=n(71811),o=n(35694),a=n(1469),i=n(65776),s=n(41780),l=n(40327);e.exports=function(e,t,n){for(var u=-1,c=(t=r(t,e)).length,p=!1;++u{var t=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");e.exports=function(e){return t.test(e)}},93157:e=>{var t=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;e.exports=function(e){return t.test(e)}},51789:(e,t,n)=>{var r=n(94536);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},80401:e=>{e.exports=function(e){var t=this.has(e)&&delete this.__data__[e];return this.size-=t?1:0,t}},57667:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;if(r){var n=t[e];return"__lodash_hash_undefined__"===n?void 0:n}return o.call(t,e)?t[e]:void 0}},21327:(e,t,n)=>{var r=n(94536),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:o.call(t,e)}},81866:(e,t,n)=>{var r=n(94536);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},43824:e=>{var t=Object.prototype.hasOwnProperty;e.exports=function(e){var n=e.length,r=new e.constructor(n);return n&&"string"==typeof e[0]&&t.call(e,"index")&&(r.index=e.index,r.input=e.input),r}},29148:(e,t,n)=>{var r=n(74318),o=n(57157),a=n(93147),i=n(40419),s=n(77133);e.exports=function(e,t,n){var l=e.constructor;switch(t){case"[object ArrayBuffer]":return r(e);case"[object Boolean]":case"[object Date]":return new l(+e);case"[object DataView]":return o(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return s(e,n);case"[object Map]":case"[object Set]":return new l;case"[object Number]":case"[object String]":return new l(e);case"[object RegExp]":return a(e);case"[object Symbol]":return i(e)}}},38517:(e,t,n)=>{var r=n(3118),o=n(85924),a=n(25726);e.exports=function(e){return"function"!=typeof e.constructor||a(e)?{}:r(o(e))}},37285:(e,t,n)=>{var r=n(62705),o=n(35694),a=n(1469),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return a(e)||o(e)||!!(i&&e&&e[i])}},65776:e=>{var t=/^(?:0|[1-9]\d*)$/;e.exports=function(e,n){var r=typeof e;return!!(n=null==n?9007199254740991:n)&&("number"==r||"symbol"!=r&&t.test(e))&&e>-1&&e%1==0&&e{var r=n(77813),o=n(98612),a=n(65776),i=n(13218);e.exports=function(e,t,n){if(!i(n))return!1;var s=typeof t;return!!("number"==s?o(n)&&a(t,n.length):"string"==s&&t in n)&&r(n[t],e)}},15403:(e,t,n)=>{var r=n(1469),o=n(33448),a=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!o(e))||(i.test(e)||!a.test(e)||null!=t&&e in Object(t))}},37019:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},15346:(e,t,n)=>{var r,o=n(14429),a=(r=/[^.]+$/.exec(o&&o.keys&&o.keys.IE_PROTO||""))?"Symbol(src)_1."+r:"";e.exports=function(e){return!!a&&a in e}},25726:e=>{var t=Object.prototype;e.exports=function(e){var n=e&&e.constructor;return e===("function"==typeof n&&n.prototype||t)}},89162:(e,t,n)=>{var r=n(13218);e.exports=function(e){return e==e&&!r(e)}},27040:e=>{e.exports=function(){this.__data__=[],this.size=0}},14125:(e,t,n)=>{var r=n(18470),o=Array.prototype.splice;e.exports=function(e){var t=this.__data__,n=r(t,e);return!(n<0)&&(n==t.length-1?t.pop():o.call(t,n,1),--this.size,!0)}},82117:(e,t,n)=>{var r=n(18470);e.exports=function(e){var t=this.__data__,n=r(t,e);return n<0?void 0:t[n][1]}},67518:(e,t,n)=>{var r=n(18470);e.exports=function(e){return r(this.__data__,e)>-1}},54705:(e,t,n)=>{var r=n(18470);e.exports=function(e,t){var n=this.__data__,o=r(n,e);return o<0?(++this.size,n.push([e,t])):n[o][1]=t,this}},24785:(e,t,n)=>{var r=n(1989),o=n(38407),a=n(57071);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(a||o),string:new r}}},11285:(e,t,n)=>{var r=n(45050);e.exports=function(e){var t=r(this,e).delete(e);return this.size-=t?1:0,t}},96e3:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).get(e)}},49916:(e,t,n)=>{var r=n(45050);e.exports=function(e){return r(this,e).has(e)}},95265:(e,t,n)=>{var r=n(45050);e.exports=function(e,t){var n=r(this,e),o=n.size;return n.set(e,t),this.size+=n.size==o?0:1,this}},68776:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e,r){n[++t]=[r,e]})),n}},42634:e=>{e.exports=function(e,t){return function(n){return null!=n&&(n[e]===t&&(void 0!==t||e in Object(n)))}}},24523:(e,t,n)=>{var r=n(88306);e.exports=function(e){var t=r(e,(function(e){return 500===n.size&&n.clear(),e})),n=t.cache;return t}},94536:(e,t,n)=>{var r=n(10852)(Object,"create");e.exports=r},86916:(e,t,n)=>{var r=n(5569)(Object.keys,Object);e.exports=r},33498:e=>{e.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},31167:(e,t,n)=>{e=n.nmd(e);var r=n(31957),o=t&&!t.nodeType&&t,a=o&&e&&!e.nodeType&&e,i=a&&a.exports===o&&r.process,s=function(){try{var e=a&&a.require&&a.require("util").types;return e||i&&i.binding&&i.binding("util")}catch(e){}}();e.exports=s},2333:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},5569:e=>{e.exports=function(e,t){return function(n){return e(t(n))}}},45357:(e,t,n)=>{var r=n(96874),o=Math.max;e.exports=function(e,t,n){return t=o(void 0===t?e.length-1:t,0),function(){for(var a=arguments,i=-1,s=o(a.length-t,0),l=Array(s);++i{var r=n(97786),o=n(14259);e.exports=function(e,t){return t.length<2?e:r(e,o(t,0,-1))}},55639:(e,t,n)=>{var r=n(31957),o="object"==typeof self&&self&&self.Object===Object&&self,a=r||o||Function("return this")();e.exports=a},36390:e=>{e.exports=function(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}},90619:e=>{e.exports=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this}},72385:e=>{e.exports=function(e){return this.__data__.has(e)}},21814:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach((function(e){n[++t]=e})),n}},30061:(e,t,n)=>{var r=n(56560),o=n(21275)(r);e.exports=o},21275:e=>{var t=Date.now;e.exports=function(e){var n=0,r=0;return function(){var o=t(),a=16-(o-r);if(r=o,a>0){if(++n>=800)return arguments[0]}else n=0;return e.apply(void 0,arguments)}}},37465:(e,t,n)=>{var r=n(38407);e.exports=function(){this.__data__=new r,this.size=0}},63779:e=>{e.exports=function(e){var t=this.__data__,n=t.delete(e);return this.size=t.size,n}},67599:e=>{e.exports=function(e){return this.__data__.get(e)}},44758:e=>{e.exports=function(e){return this.__data__.has(e)}},34309:(e,t,n)=>{var r=n(38407),o=n(57071),a=n(83369);e.exports=function(e,t){var n=this.__data__;if(n instanceof r){var i=n.__data__;if(!o||i.length<199)return i.push([e,t]),this.size=++n.size,this;n=this.__data__=new a(i)}return n.set(e,t),this.size=n.size,this}},83140:(e,t,n)=>{var r=n(44286),o=n(62689),a=n(676);e.exports=function(e){return o(e)?a(e):r(e)}},55514:(e,t,n)=>{var r=n(24523),o=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,a=/\\(\\)?/g,i=r((function(e){var t=[];return 46===e.charCodeAt(0)&&t.push(""),e.replace(o,(function(e,n,r,o){t.push(r?o.replace(a,"$1"):n||e)})),t}));e.exports=i},40327:(e,t,n)=>{var r=n(33448);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-Infinity?"-0":t}},80346:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},67990:e=>{var t=/\s/;e.exports=function(e){for(var n=e.length;n--&&t.test(e.charAt(n)););return n}},676:e=>{var t="\\ud800-\\udfff",n="["+t+"]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",o="\\ud83c[\\udffb-\\udfff]",a="[^"+t+"]",i="(?:\\ud83c[\\udde6-\\uddff]){2}",s="[\\ud800-\\udbff][\\udc00-\\udfff]",l="(?:"+r+"|"+o+")"+"?",u="[\\ufe0e\\ufe0f]?",c=u+l+("(?:\\u200d(?:"+[a,i,s].join("|")+")"+u+l+")*"),p="(?:"+[a+r+"?",r,i,s,n].join("|")+")",f=RegExp(o+"(?="+o+")|"+p+c,"g");e.exports=function(e){return e.match(f)||[]}},2757:e=>{var t="\\ud800-\\udfff",n="\\u2700-\\u27bf",r="a-z\\xdf-\\xf6\\xf8-\\xff",o="A-Z\\xc0-\\xd6\\xd8-\\xde",a="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",i="["+a+"]",s="\\d+",l="["+n+"]",u="["+r+"]",c="[^"+t+a+s+n+r+o+"]",p="(?:\\ud83c[\\udde6-\\uddff]){2}",f="[\\ud800-\\udbff][\\udc00-\\udfff]",h="["+o+"]",d="(?:"+u+"|"+c+")",m="(?:"+h+"|"+c+")",g="(?:['’](?:d|ll|m|re|s|t|ve))?",y="(?:['’](?:D|LL|M|RE|S|T|VE))?",v="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",b="[\\ufe0e\\ufe0f]?",w=b+v+("(?:\\u200d(?:"+["[^"+t+"]",p,f].join("|")+")"+b+v+")*"),E="(?:"+[l,p,f].join("|")+")"+w,x=RegExp([h+"?"+u+"+"+g+"(?="+[i,h,"$"].join("|")+")",m+"+"+y+"(?="+[i,h+d,"$"].join("|")+")",h+"?"+d+"+"+g,h+"+"+y,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])",s,E].join("|"),"g");e.exports=function(e){return e.match(x)||[]}},68929:(e,t,n)=>{var r=n(48403),o=n(35393)((function(e,t,n){return t=t.toLowerCase(),e+(n?r(t):t)}));e.exports=o},48403:(e,t,n)=>{var r=n(79833),o=n(11700);e.exports=function(e){return o(r(e).toLowerCase())}},75703:e=>{e.exports=function(e){return function(){return e}}},23279:(e,t,n)=>{var r=n(13218),o=n(7771),a=n(14841),i=Math.max,s=Math.min;e.exports=function(e,t,n){var l,u,c,p,f,h,d=0,m=!1,g=!1,y=!0;if("function"!=typeof e)throw new TypeError("Expected a function");function v(t){var n=l,r=u;return l=u=void 0,d=t,p=e.apply(r,n)}function b(e){var n=e-h;return void 0===h||n>=t||n<0||g&&e-d>=c}function w(){var e=o();if(b(e))return E(e);f=setTimeout(w,function(e){var n=t-(e-h);return g?s(n,c-(e-d)):n}(e))}function E(e){return f=void 0,y&&l?v(e):(l=u=void 0,p)}function x(){var e=o(),n=b(e);if(l=arguments,u=this,h=e,n){if(void 0===f)return function(e){return d=e,f=setTimeout(w,t),m?v(e):p}(h);if(g)return clearTimeout(f),f=setTimeout(w,t),v(h)}return void 0===f&&(f=setTimeout(w,t)),p}return t=a(t)||0,r(n)&&(m=!!n.leading,c=(g="maxWait"in n)?i(a(n.maxWait)||0,t):c,y="trailing"in n?!!n.trailing:y),x.cancel=function(){void 0!==f&&clearTimeout(f),d=0,l=h=u=f=void 0},x.flush=function(){return void 0===f?p:E(o())},x}},53816:(e,t,n)=>{var r=n(69389),o=n(79833),a=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,i=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");e.exports=function(e){return(e=o(e))&&e.replace(a,r).replace(i,"")}},77813:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},13311:(e,t,n)=>{var r=n(67740)(n(30998));e.exports=r},30998:(e,t,n)=>{var r=n(41848),o=n(67206),a=n(40554),i=Math.max;e.exports=function(e,t,n){var s=null==e?0:e.length;if(!s)return-1;var l=null==n?0:a(n);return l<0&&(l=i(s+l,0)),r(e,o(t,3),l)}},85564:(e,t,n)=>{var r=n(21078);e.exports=function(e){return(null==e?0:e.length)?r(e,1):[]}},27361:(e,t,n)=>{var r=n(97786);e.exports=function(e,t,n){var o=null==e?void 0:r(e,t);return void 0===o?n:o}},79095:(e,t,n)=>{var r=n(13),o=n(222);e.exports=function(e,t){return null!=e&&o(e,t,r)}},6557:e=>{e.exports=function(e){return e}},35694:(e,t,n)=>{var r=n(9454),o=n(37005),a=Object.prototype,i=a.hasOwnProperty,s=a.propertyIsEnumerable,l=r(function(){return arguments}())?r:function(e){return o(e)&&i.call(e,"callee")&&!s.call(e,"callee")};e.exports=l},1469:e=>{var t=Array.isArray;e.exports=t},98612:(e,t,n)=>{var r=n(23560),o=n(41780);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},29246:(e,t,n)=>{var r=n(98612),o=n(37005);e.exports=function(e){return o(e)&&r(e)}},44144:(e,t,n)=>{e=n.nmd(e);var r=n(55639),o=n(95062),a=t&&!t.nodeType&&t,i=a&&e&&!e.nodeType&&e,s=i&&i.exports===a?r.Buffer:void 0,l=(s?s.isBuffer:void 0)||o;e.exports=l},41609:(e,t,n)=>{var r=n(280),o=n(98882),a=n(35694),i=n(1469),s=n(98612),l=n(44144),u=n(25726),c=n(36719),p=Object.prototype.hasOwnProperty;e.exports=function(e){if(null==e)return!0;if(s(e)&&(i(e)||"string"==typeof e||"function"==typeof e.splice||l(e)||c(e)||a(e)))return!e.length;var t=o(e);if("[object Map]"==t||"[object Set]"==t)return!e.size;if(u(e))return!r(e).length;for(var n in e)if(p.call(e,n))return!1;return!0}},23560:(e,t,n)=>{var r=n(44239),o=n(13218);e.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Function]"==t||"[object GeneratorFunction]"==t||"[object AsyncFunction]"==t||"[object Proxy]"==t}},41780:e=>{e.exports=function(e){return"number"==typeof e&&e>-1&&e%1==0&&e<=9007199254740991}},56688:(e,t,n)=>{var r=n(25588),o=n(7518),a=n(31167),i=a&&a.isMap,s=i?o(i):r;e.exports=s},13218:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},37005:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},68630:(e,t,n)=>{var r=n(44239),o=n(85924),a=n(37005),i=Function.prototype,s=Object.prototype,l=i.toString,u=s.hasOwnProperty,c=l.call(Object);e.exports=function(e){if(!a(e)||"[object Object]"!=r(e))return!1;var t=o(e);if(null===t)return!0;var n=u.call(t,"constructor")&&t.constructor;return"function"==typeof n&&n instanceof n&&l.call(n)==c}},72928:(e,t,n)=>{var r=n(29221),o=n(7518),a=n(31167),i=a&&a.isSet,s=i?o(i):r;e.exports=s},47037:(e,t,n)=>{var r=n(44239),o=n(1469),a=n(37005);e.exports=function(e){return"string"==typeof e||!o(e)&&a(e)&&"[object String]"==r(e)}},33448:(e,t,n)=>{var r=n(44239),o=n(37005);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},36719:(e,t,n)=>{var r=n(38749),o=n(7518),a=n(31167),i=a&&a.isTypedArray,s=i?o(i):r;e.exports=s},3674:(e,t,n)=>{var r=n(14636),o=n(280),a=n(98612);e.exports=function(e){return a(e)?r(e):o(e)}},81704:(e,t,n)=>{var r=n(14636),o=n(10313),a=n(98612);e.exports=function(e){return a(e)?r(e,!0):o(e)}},10928:e=>{e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},88306:(e,t,n)=>{var r=n(83369);function o(e,t){if("function"!=typeof e||null!=t&&"function"!=typeof t)throw new TypeError("Expected a function");var n=function(){var r=arguments,o=t?t.apply(this,r):r[0],a=n.cache;if(a.has(o))return a.get(o);var i=e.apply(this,r);return n.cache=a.set(o,i)||a,i};return n.cache=new(o.Cache||r),n}o.Cache=r,e.exports=o},82492:(e,t,n)=>{var r=n(42980),o=n(21463)((function(e,t,n){r(e,t,n)}));e.exports=o},7771:(e,t,n)=>{var r=n(55639);e.exports=function(){return r.Date.now()}},57557:(e,t,n)=>{var r=n(29932),o=n(85990),a=n(57406),i=n(71811),s=n(98363),l=n(60696),u=n(99021),c=n(46904),p=u((function(e,t){var n={};if(null==e)return n;var u=!1;t=r(t,(function(t){return t=i(t,e),u||(u=t.length>1),t})),s(e,c(e),n),u&&(n=o(n,7,l));for(var p=t.length;p--;)a(n,t[p]);return n}));e.exports=p},39601:(e,t,n)=>{var r=n(40371),o=n(79152),a=n(15403),i=n(40327);e.exports=function(e){return a(e)?r(i(e)):o(e)}},54061:(e,t,n)=>{var r=n(62663),o=n(89881),a=n(67206),i=n(10107),s=n(1469);e.exports=function(e,t,n){var l=s(e)?r:i,u=arguments.length<3;return l(e,a(t,4),n,u,o)}},36968:(e,t,n)=>{var r=n(10611);e.exports=function(e,t,n){return null==e?e:r(e,t,n)}},59704:(e,t,n)=>{var r=n(82908),o=n(67206),a=n(5076),i=n(1469),s=n(16612);e.exports=function(e,t,n){var l=i(e)?r:a;return n&&s(e,t,n)&&(t=void 0),l(e,o(t,3))}},70479:e=>{e.exports=function(){return[]}},95062:e=>{e.exports=function(){return!1}},18601:(e,t,n)=>{var r=n(14841),o=1/0;e.exports=function(e){return e?(e=r(e))===o||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},40554:(e,t,n)=>{var r=n(18601);e.exports=function(e){var t=r(e),n=t%1;return t==t?n?t-n:t:0}},7334:(e,t,n)=>{var r=n(79833);e.exports=function(e){return r(e).toLowerCase()}},14841:(e,t,n)=>{var r=n(27561),o=n(13218),a=n(33448),i=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,l=/^0o[0-7]+$/i,u=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(a(e))return NaN;if(o(e)){var t="function"==typeof e.valueOf?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=r(e);var n=s.test(e);return n||l.test(e)?u(e.slice(2),n?2:8):i.test(e)?NaN:+e}},59881:(e,t,n)=>{var r=n(98363),o=n(81704);e.exports=function(e){return r(e,o(e))}},79833:(e,t,n)=>{var r=n(80531);e.exports=function(e){return null==e?"":r(e)}},11700:(e,t,n)=>{var r=n(98805)("toUpperCase");e.exports=r},58748:(e,t,n)=>{var r=n(49029),o=n(93157),a=n(79833),i=n(2757);e.exports=function(e,t,n){return e=a(e),void 0===(t=n?void 0:t)?o(e)?i(e):r(e):e.match(t)||[]}},7287:(e,t,n)=>{var r=n(34865),o=n(1757);e.exports=function(e,t){return o(e||[],t||[],r)}},96470:(e,t,n)=>{"use strict";var r=n(47802),o=n(21102);t.highlight=i,t.highlightAuto=function(e,t){var n,s,l,u,c=t||{},p=c.subset||r.listLanguages(),f=c.prefix,h=p.length,d=-1;null==f&&(f=a);if("string"!=typeof e)throw o("Expected `string` for value, got `%s`",e);s={relevance:0,language:null,value:[]},n={relevance:0,language:null,value:[]};for(;++ds.relevance&&(s=l),l.relevance>n.relevance&&(s=n,n=l));s.language&&(n.secondBest=s);return n},t.registerLanguage=function(e,t){r.registerLanguage(e,t)},t.listLanguages=function(){return r.listLanguages()},t.registerAlias=function(e,t){var n,o=e;t&&((o={})[e]=t);for(n in o)r.registerAliases(o[n],{languageName:n})},s.prototype.addText=function(e){var t,n,r=this.stack;if(""===e)return;t=r[r.length-1],(n=t.children[t.children.length-1])&&"text"===n.type?n.value+=e:t.children.push({type:"text",value:e})},s.prototype.addKeyword=function(e,t){this.openNode(t),this.addText(e),this.closeNode()},s.prototype.addSublanguage=function(e,t){var n=this.stack,r=n[n.length-1],o=e.rootNode.children,a=t?{type:"element",tagName:"span",properties:{className:[t]},children:o}:o;r.children=r.children.concat(a)},s.prototype.openNode=function(e){var t=this.stack,n=this.options.classPrefix+e,r=t[t.length-1],o={type:"element",tagName:"span",properties:{className:[n]},children:[]};r.children.push(o),t.push(o)},s.prototype.closeNode=function(){this.stack.pop()},s.prototype.closeAllNodes=l,s.prototype.finalize=l,s.prototype.toHTML=function(){return""};var a="hljs-";function i(e,t,n){var i,l=r.configure({}),u=(n||{}).prefix;if("string"!=typeof e)throw o("Expected `string` for name, got `%s`",e);if(!r.getLanguage(e))throw o("Unknown language: `%s` is not registered",e);if("string"!=typeof t)throw o("Expected `string` for value, got `%s`",t);if(null==u&&(u=a),r.configure({__emitter:s,classPrefix:u}),i=r.highlight(t,{language:e,ignoreIllegals:!0}),r.configure(l||{}),i.errorRaised)throw i.errorRaised;return{relevance:i.relevance,language:i.language,value:i.emitter.rootNode.children}}function s(e){this.options=e,this.rootNode={children:[]},this.stack=[this.rootNode]}function l(){}},27418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(e){return!1}}()?Object.assign:function(e,o){for(var a,i,s=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),l=1;l{var r="function"==typeof Map&&Map.prototype,o=Object.getOwnPropertyDescriptor&&r?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,a=r&&o&&"function"==typeof o.get?o.get:null,i=r&&Map.prototype.forEach,s="function"==typeof Set&&Set.prototype,l=Object.getOwnPropertyDescriptor&&s?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,u=s&&l&&"function"==typeof l.get?l.get:null,c=s&&Set.prototype.forEach,p="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,f="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,h="function"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,d=Boolean.prototype.valueOf,m=Object.prototype.toString,g=Function.prototype.toString,y=String.prototype.match,v=String.prototype.slice,b=String.prototype.replace,w=String.prototype.toUpperCase,E=String.prototype.toLowerCase,x=RegExp.prototype.test,_=Array.prototype.concat,S=Array.prototype.join,A=Array.prototype.slice,C=Math.floor,k="function"==typeof BigInt?BigInt.prototype.valueOf:null,O=Object.getOwnPropertySymbols,j="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol.prototype.toString:null,T="function"==typeof Symbol&&"object"==typeof Symbol.iterator,I="function"==typeof Symbol&&Symbol.toStringTag&&(typeof Symbol.toStringTag===T||"symbol")?Symbol.toStringTag:null,N=Object.prototype.propertyIsEnumerable,P=("function"==typeof Reflect?Reflect.getPrototypeOf:Object.getPrototypeOf)||([].__proto__===Array.prototype?function(e){return e.__proto__}:null);function R(e,t){if(e===1/0||e===-1/0||e!=e||e&&e>-1e3&&e<1e3||x.call(/e/,t))return t;var n=/[0-9](?=(?:[0-9]{3})+(?![0-9]))/g;if("number"==typeof e){var r=e<0?-C(-e):C(e);if(r!==e){var o=String(r),a=v.call(t,o.length+1);return b.call(o,n,"$&_")+"."+b.call(b.call(a,/([0-9]{3})/g,"$&_"),/_$/,"")}}return b.call(t,n,"$&_")}var M=n(24654),D=M.custom,L=q(D)?D:null;function B(e,t,n){var r="double"===(n.quoteStyle||t)?'"':"'";return r+e+r}function F(e){return b.call(String(e),/"/g,""")}function z(e){return!("[object Array]"!==W(e)||I&&"object"==typeof e&&I in e)}function U(e){return!("[object RegExp]"!==W(e)||I&&"object"==typeof e&&I in e)}function q(e){if(T)return e&&"object"==typeof e&&e instanceof Symbol;if("symbol"==typeof e)return!0;if(!e||"object"!=typeof e||!j)return!1;try{return j.call(e),!0}catch(e){}return!1}e.exports=function e(t,n,r,o){var s=n||{};if(V(s,"quoteStyle")&&"single"!==s.quoteStyle&&"double"!==s.quoteStyle)throw new TypeError('option "quoteStyle" must be "single" or "double"');if(V(s,"maxStringLength")&&("number"==typeof s.maxStringLength?s.maxStringLength<0&&s.maxStringLength!==1/0:null!==s.maxStringLength))throw new TypeError('option "maxStringLength", if provided, must be a positive integer, Infinity, or `null`');var l=!V(s,"customInspect")||s.customInspect;if("boolean"!=typeof l&&"symbol"!==l)throw new TypeError("option \"customInspect\", if provided, must be `true`, `false`, or `'symbol'`");if(V(s,"indent")&&null!==s.indent&&"\t"!==s.indent&&!(parseInt(s.indent,10)===s.indent&&s.indent>0))throw new TypeError('option "indent" must be "\\t", an integer > 0, or `null`');if(V(s,"numericSeparator")&&"boolean"!=typeof s.numericSeparator)throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');var m=s.numericSeparator;if(void 0===t)return"undefined";if(null===t)return"null";if("boolean"==typeof t)return t?"true":"false";if("string"==typeof t)return J(t,s);if("number"==typeof t){if(0===t)return 1/0/t>0?"0":"-0";var w=String(t);return m?R(t,w):w}if("bigint"==typeof t){var x=String(t)+"n";return m?R(t,x):x}var C=void 0===s.depth?5:s.depth;if(void 0===r&&(r=0),r>=C&&C>0&&"object"==typeof t)return z(t)?"[Array]":"[Object]";var O=function(e,t){var n;if("\t"===e.indent)n="\t";else{if(!("number"==typeof e.indent&&e.indent>0))return null;n=S.call(Array(e.indent+1)," ")}return{base:n,prev:S.call(Array(t+1),n)}}(s,r);if(void 0===o)o=[];else if(H(o,t)>=0)return"[Circular]";function D(t,n,a){if(n&&(o=A.call(o)).push(n),a){var i={depth:s.depth};return V(s,"quoteStyle")&&(i.quoteStyle=s.quoteStyle),e(t,i,r+1,o)}return e(t,s,r+1,o)}if("function"==typeof t&&!U(t)){var $=function(e){if(e.name)return e.name;var t=y.call(g.call(e),/^function\s*([\w$]+)/);if(t)return t[1];return null}(t),K=X(t,D);return"[Function"+($?": "+$:" (anonymous)")+"]"+(K.length>0?" { "+S.call(K,", ")+" }":"")}if(q(t)){var ee=T?b.call(String(t),/^(Symbol\(.*\))_[^)]*$/,"$1"):j.call(t);return"object"!=typeof t||T?ee:G(ee)}if(function(e){if(!e||"object"!=typeof e)return!1;if("undefined"!=typeof HTMLElement&&e instanceof HTMLElement)return!0;return"string"==typeof e.nodeName&&"function"==typeof e.getAttribute}(t)){for(var te="<"+E.call(String(t.nodeName)),ne=t.attributes||[],re=0;re"}if(z(t)){if(0===t.length)return"[]";var oe=X(t,D);return O&&!function(e){for(var t=0;t=0)return!1;return!0}(oe)?"["+Q(oe,O)+"]":"[ "+S.call(oe,", ")+" ]"}if(function(e){return!("[object Error]"!==W(e)||I&&"object"==typeof e&&I in e)}(t)){var ae=X(t,D);return"cause"in Error.prototype||!("cause"in t)||N.call(t,"cause")?0===ae.length?"["+String(t)+"]":"{ ["+String(t)+"] "+S.call(ae,", ")+" }":"{ ["+String(t)+"] "+S.call(_.call("[cause]: "+D(t.cause),ae),", ")+" }"}if("object"==typeof t&&l){if(L&&"function"==typeof t[L]&&M)return M(t,{depth:C-r});if("symbol"!==l&&"function"==typeof t.inspect)return t.inspect()}if(function(e){if(!a||!e||"object"!=typeof e)return!1;try{a.call(e);try{u.call(e)}catch(e){return!0}return e instanceof Map}catch(e){}return!1}(t)){var ie=[];return i&&i.call(t,(function(e,n){ie.push(D(n,t,!0)+" => "+D(e,t))})),Y("Map",a.call(t),ie,O)}if(function(e){if(!u||!e||"object"!=typeof e)return!1;try{u.call(e);try{a.call(e)}catch(e){return!0}return e instanceof Set}catch(e){}return!1}(t)){var se=[];return c&&c.call(t,(function(e){se.push(D(e,t))})),Y("Set",u.call(t),se,O)}if(function(e){if(!p||!e||"object"!=typeof e)return!1;try{p.call(e,p);try{f.call(e,f)}catch(e){return!0}return e instanceof WeakMap}catch(e){}return!1}(t))return Z("WeakMap");if(function(e){if(!f||!e||"object"!=typeof e)return!1;try{f.call(e,f);try{p.call(e,p)}catch(e){return!0}return e instanceof WeakSet}catch(e){}return!1}(t))return Z("WeakSet");if(function(e){if(!h||!e||"object"!=typeof e)return!1;try{return h.call(e),!0}catch(e){}return!1}(t))return Z("WeakRef");if(function(e){return!("[object Number]"!==W(e)||I&&"object"==typeof e&&I in e)}(t))return G(D(Number(t)));if(function(e){if(!e||"object"!=typeof e||!k)return!1;try{return k.call(e),!0}catch(e){}return!1}(t))return G(D(k.call(t)));if(function(e){return!("[object Boolean]"!==W(e)||I&&"object"==typeof e&&I in e)}(t))return G(d.call(t));if(function(e){return!("[object String]"!==W(e)||I&&"object"==typeof e&&I in e)}(t))return G(D(String(t)));if(!function(e){return!("[object Date]"!==W(e)||I&&"object"==typeof e&&I in e)}(t)&&!U(t)){var le=X(t,D),ue=P?P(t)===Object.prototype:t instanceof Object||t.constructor===Object,ce=t instanceof Object?"":"null prototype",pe=!ue&&I&&Object(t)===t&&I in t?v.call(W(t),8,-1):ce?"Object":"",fe=(ue||"function"!=typeof t.constructor?"":t.constructor.name?t.constructor.name+" ":"")+(pe||ce?"["+S.call(_.call([],pe||[],ce||[]),": ")+"] ":"");return 0===le.length?fe+"{}":O?fe+"{"+Q(le,O)+"}":fe+"{ "+S.call(le,", ")+" }"}return String(t)};var $=Object.prototype.hasOwnProperty||function(e){return e in this};function V(e,t){return $.call(e,t)}function W(e){return m.call(e)}function H(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;nt.maxStringLength){var n=e.length-t.maxStringLength,r="... "+n+" more character"+(n>1?"s":"");return J(v.call(e,0,t.maxStringLength),t)+r}return B(b.call(b.call(e,/(['\\])/g,"\\$1"),/[\x00-\x1f]/g,K),"single",t)}function K(e){var t=e.charCodeAt(0),n={8:"b",9:"t",10:"n",12:"f",13:"r"}[t];return n?"\\"+n:"\\x"+(t<16?"0":"")+w.call(t.toString(16))}function G(e){return"Object("+e+")"}function Z(e){return e+" { ? }"}function Y(e,t,n,r){return e+" ("+t+") {"+(r?Q(n,r):S.call(n,", "))+"}"}function Q(e,t){if(0===e.length)return"";var n="\n"+t.prev+t.base;return n+S.call(e,","+n)+"\n"+t.prev}function X(e,t){var n=z(e),r=[];if(n){r.length=e.length;for(var o=0;o{var t,n,r=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function a(){throw new Error("clearTimeout has not been defined")}function i(e){if(t===setTimeout)return setTimeout(e,0);if((t===o||!t)&&setTimeout)return t=setTimeout,setTimeout(e,0);try{return t(e,0)}catch(n){try{return t.call(null,e,0)}catch(n){return t.call(this,e,0)}}}!function(){try{t="function"==typeof setTimeout?setTimeout:o}catch(e){t=o}try{n="function"==typeof clearTimeout?clearTimeout:a}catch(e){n=a}}();var s,l=[],u=!1,c=-1;function p(){u&&s&&(u=!1,s.length?l=s.concat(l):c=-1,l.length&&f())}function f(){if(!u){var e=i(p);u=!0;for(var t=l.length;t;){for(s=l,l=[];++c1)for(var n=1;n{"use strict";var r=n(50414);function o(){}function a(){}a.resetWarningCache=o,e.exports=function(){function e(e,t,n,o,a,i){if(i!==r){var s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw s.name="Invariant Violation",s}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:a,resetWarningCache:o};return n.PropTypes=n,n}},45697:(e,t,n)=>{e.exports=n(92703)()},50414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},55798:e=>{"use strict";var t=String.prototype.replace,n=/%20/g,r="RFC1738",o="RFC3986";e.exports={default:o,formatters:{RFC1738:function(e){return t.call(e,n,"+")},RFC3986:function(e){return String(e)}},RFC1738:r,RFC3986:o}},80129:(e,t,n)=>{"use strict";var r=n(58261),o=n(55235),a=n(55798);e.exports={formats:a,parse:o,stringify:r}},55235:(e,t,n)=>{"use strict";var r=n(12769),o=Object.prototype.hasOwnProperty,a=Array.isArray,i={allowDots:!1,allowPrototypes:!1,allowSparse:!1,arrayLimit:20,charset:"utf-8",charsetSentinel:!1,comma:!1,decoder:r.decode,delimiter:"&",depth:5,ignoreQueryPrefix:!1,interpretNumericEntities:!1,parameterLimit:1e3,parseArrays:!0,plainObjects:!1,strictNullHandling:!1},s=function(e){return e.replace(/&#(\d+);/g,(function(e,t){return String.fromCharCode(parseInt(t,10))}))},l=function(e,t){return e&&"string"==typeof e&&t.comma&&e.indexOf(",")>-1?e.split(","):e},u=function(e,t,n,r){if(e){var a=n.allowDots?e.replace(/\.([^.[]+)/g,"[$1]"):e,i=/(\[[^[\]]*])/g,s=n.depth>0&&/(\[[^[\]]*])/.exec(a),u=s?a.slice(0,s.index):a,c=[];if(u){if(!n.plainObjects&&o.call(Object.prototype,u)&&!n.allowPrototypes)return;c.push(u)}for(var p=0;n.depth>0&&null!==(s=i.exec(a))&&p=0;--a){var i,s=e[a];if("[]"===s&&n.parseArrays)i=[].concat(o);else{i=n.plainObjects?Object.create(null):{};var u="["===s.charAt(0)&&"]"===s.charAt(s.length-1)?s.slice(1,-1):s,c=parseInt(u,10);n.parseArrays||""!==u?!isNaN(c)&&s!==u&&String(c)===u&&c>=0&&n.parseArrays&&c<=n.arrayLimit?(i=[])[c]=o:"__proto__"!==u&&(i[u]=o):i={0:o}}o=i}return o}(c,t,n,r)}};e.exports=function(e,t){var n=function(e){if(!e)return i;if(null!==e.decoder&&void 0!==e.decoder&&"function"!=typeof e.decoder)throw new TypeError("Decoder has to be a function.");if(void 0!==e.charset&&"utf-8"!==e.charset&&"iso-8859-1"!==e.charset)throw new TypeError("The charset option must be either utf-8, iso-8859-1, or undefined");var t=void 0===e.charset?i.charset:e.charset;return{allowDots:void 0===e.allowDots?i.allowDots:!!e.allowDots,allowPrototypes:"boolean"==typeof e.allowPrototypes?e.allowPrototypes:i.allowPrototypes,allowSparse:"boolean"==typeof e.allowSparse?e.allowSparse:i.allowSparse,arrayLimit:"number"==typeof e.arrayLimit?e.arrayLimit:i.arrayLimit,charset:t,charsetSentinel:"boolean"==typeof e.charsetSentinel?e.charsetSentinel:i.charsetSentinel,comma:"boolean"==typeof e.comma?e.comma:i.comma,decoder:"function"==typeof e.decoder?e.decoder:i.decoder,delimiter:"string"==typeof e.delimiter||r.isRegExp(e.delimiter)?e.delimiter:i.delimiter,depth:"number"==typeof e.depth||!1===e.depth?+e.depth:i.depth,ignoreQueryPrefix:!0===e.ignoreQueryPrefix,interpretNumericEntities:"boolean"==typeof e.interpretNumericEntities?e.interpretNumericEntities:i.interpretNumericEntities,parameterLimit:"number"==typeof e.parameterLimit?e.parameterLimit:i.parameterLimit,parseArrays:!1!==e.parseArrays,plainObjects:"boolean"==typeof e.plainObjects?e.plainObjects:i.plainObjects,strictNullHandling:"boolean"==typeof e.strictNullHandling?e.strictNullHandling:i.strictNullHandling}}(t);if(""===e||null==e)return n.plainObjects?Object.create(null):{};for(var c="string"==typeof e?function(e,t){var n,u={},c=t.ignoreQueryPrefix?e.replace(/^\?/,""):e,p=t.parameterLimit===1/0?void 0:t.parameterLimit,f=c.split(t.delimiter,p),h=-1,d=t.charset;if(t.charsetSentinel)for(n=0;n-1&&(g=a(g)?[g]:g),o.call(u,m)?u[m]=r.combine(u[m],g):u[m]=g}return u}(e,n):e,p=n.plainObjects?Object.create(null):{},f=Object.keys(c),h=0;h{"use strict";var r=n(37478),o=n(12769),a=n(55798),i=Object.prototype.hasOwnProperty,s={brackets:function(e){return e+"[]"},comma:"comma",indices:function(e,t){return e+"["+t+"]"},repeat:function(e){return e}},l=Array.isArray,u=String.prototype.split,c=Array.prototype.push,p=function(e,t){c.apply(e,l(t)?t:[t])},f=Date.prototype.toISOString,h=a.default,d={addQueryPrefix:!1,allowDots:!1,charset:"utf-8",charsetSentinel:!1,delimiter:"&",encode:!0,encoder:o.encode,encodeValuesOnly:!1,format:h,formatter:a.formatters[h],indices:!1,serializeDate:function(e){return f.call(e)},skipNulls:!1,strictNullHandling:!1},m={},g=function e(t,n,a,i,s,c,f,h,g,y,v,b,w,E,x,_){for(var S,A=t,C=_,k=0,O=!1;void 0!==(C=C.get(m))&&!O;){var j=C.get(t);if(k+=1,void 0!==j){if(j===k)throw new RangeError("Cyclic object value");O=!0}void 0===C.get(m)&&(k=0)}if("function"==typeof h?A=h(n,A):A instanceof Date?A=v(A):"comma"===a&&l(A)&&(A=o.maybeMap(A,(function(e){return e instanceof Date?v(e):e}))),null===A){if(s)return f&&!E?f(n,d.encoder,x,"key",b):n;A=""}if("string"==typeof(S=A)||"number"==typeof S||"boolean"==typeof S||"symbol"==typeof S||"bigint"==typeof S||o.isBuffer(A)){if(f){var T=E?n:f(n,d.encoder,x,"key",b);if("comma"===a&&E){for(var I=u.call(String(A),","),N="",P=0;P0?A.join(",")||null:void 0}];else if(l(h))R=h;else{var D=Object.keys(A);R=g?D.sort(g):D}for(var L=i&&l(A)&&1===A.length?n+"[]":n,B=0;B0?E+w:""}},12769:(e,t,n)=>{"use strict";var r=n(55798),o=Object.prototype.hasOwnProperty,a=Array.isArray,i=function(){for(var e=[],t=0;t<256;++t)e.push("%"+((t<16?"0":"")+t.toString(16)).toUpperCase());return e}(),s=function(e,t){for(var n=t&&t.plainObjects?Object.create(null):{},r=0;r1;){var t=e.pop(),n=t.obj[t.prop];if(a(n)){for(var r=[],o=0;o=48&&c<=57||c>=65&&c<=90||c>=97&&c<=122||a===r.RFC1738&&(40===c||41===c)?l+=s.charAt(u):c<128?l+=i[c]:c<2048?l+=i[192|c>>6]+i[128|63&c]:c<55296||c>=57344?l+=i[224|c>>12]+i[128|c>>6&63]+i[128|63&c]:(u+=1,c=65536+((1023&c)<<10|1023&s.charCodeAt(u)),l+=i[240|c>>18]+i[128|c>>12&63]+i[128|c>>6&63]+i[128|63&c])}return l},isBuffer:function(e){return!(!e||"object"!=typeof e)&&!!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(a(e)){for(var n=[],r=0;r{"use strict";function t(e,t){return Object.prototype.hasOwnProperty.call(e,t)}e.exports=function(e,n,r,o){n=n||"&",r=r||"=";var a={};if("string"!=typeof e||0===e.length)return a;var i=/\+/g;e=e.split(n);var s=1e3;o&&"number"==typeof o.maxKeys&&(s=o.maxKeys);var l=e.length;s>0&&l>s&&(l=s);for(var u=0;u=0?(c=d.substr(0,m),p=d.substr(m+1)):(c=d,p=""),f=decodeURIComponent(c),h=decodeURIComponent(p),t(a,f)?Array.isArray(a[f])?a[f].push(h):a[f]=[a[f],h]:a[f]=h}return a}},12361:e=>{"use strict";var t=function(e){switch(typeof e){case"string":return e;case"boolean":return e?"true":"false";case"number":return isFinite(e)?e:"";default:return""}};e.exports=function(e,n,r,o){return n=n||"&",r=r||"=",null===e&&(e=void 0),"object"==typeof e?Object.keys(e).map((function(o){var a=encodeURIComponent(t(o))+r;return Array.isArray(e[o])?e[o].map((function(e){return a+encodeURIComponent(t(e))})).join(n):a+encodeURIComponent(t(e[o]))})).join(n):o?encodeURIComponent(t(o))+r+encodeURIComponent(t(e)):""}},17673:(e,t,n)=>{"use strict";t.decode=t.parse=n(62587),t.encode=t.stringify=n(12361)},57129:(e,t)=>{"use strict";var n=Object.prototype.hasOwnProperty;function r(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function o(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){t=t||"";var r,a,i=[];for(a in"string"!=typeof t&&(t="?"),e)if(n.call(e,a)){if((r=e[a])||null!=r&&!isNaN(r)||(r=""),a=o(a),r=o(r),null===a||null===r)continue;i.push(a+"="+r)}return i.length?t+i.join("&"):""},t.parse=function(e){for(var t,n=/([^=?#&]+)=?([^&]*)/g,o={};t=n.exec(e);){var a=r(t[1]),i=r(t[2]);null===a||null===i||a in o||(o[a]=i)}return o}},14419:(e,t,n)=>{const r=n(60697),o=n(69450),a=r.types;e.exports=class e{constructor(e,t){if(this._setDefaults(e),e instanceof RegExp)this.ignoreCase=e.ignoreCase,this.multiline=e.multiline,e=e.source;else{if("string"!=typeof e)throw new Error("Expected a regexp or string");this.ignoreCase=t&&-1!==t.indexOf("i"),this.multiline=t&&-1!==t.indexOf("m")}this.tokens=r(e)}_setDefaults(t){this.max=null!=t.max?t.max:null!=e.prototype.max?e.prototype.max:100,this.defaultRange=t.defaultRange?t.defaultRange:this.defaultRange.clone(),t.randInt&&(this.randInt=t.randInt)}gen(){return this._gen(this.tokens,[])}_gen(e,t){var n,r,o,i,s;switch(e.type){case a.ROOT:case a.GROUP:if(e.followedBy||e.notFollowedBy)return"";for(e.remember&&void 0===e.groupNumber&&(e.groupNumber=t.push(null)-1),r="",i=0,s=(n=e.options?this._randSelect(e.options):e.stack).length;i{"use strict";var r=n(34155),o=65536,a=4294967295;var i=n(89509).Buffer,s=n.g.crypto||n.g.msCrypto;s&&s.getRandomValues?e.exports=function(e,t){if(e>a)throw new RangeError("requested too many random bytes");var n=i.allocUnsafe(e);if(e>0)if(e>o)for(var l=0;l{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.CopyToClipboard=void 0;var o=s(n(67294)),a=s(n(20640)),i=["text","onCopy","options","children"];function s(e){return e&&e.__esModule?e:{default:e}}function l(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function u(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function p(e,t){for(var n=0;n{"use strict";var r=n(74300).CopyToClipboard;r.CopyToClipboard=r,e.exports=r},53441:(e,t,n)=>{"use strict";function r(e){return r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},r(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.DebounceInput=void 0;var o=s(n(67294)),a=s(n(91296)),i=["element","onChange","value","minLength","debounceTimeout","forceNotifyByEnter","forceNotifyOnBlur","onKeyDown","onBlur","inputRef"];function s(e){return e&&e.__esModule?e:{default:e}}function l(e,t){if(null==e)return{};var n,r,o=function(e,t){if(null==e)return{};var n,r,o={},a=Object.keys(e);for(r=0;r=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}function u(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function c(e){for(var t=1;t=r?t.notify(e):n.length>o.length&&t.notify(c(c({},e),{},{target:c(c({},e.target),{},{value:""})}))}))})),g(d(t),"onKeyDown",(function(e){"Enter"===e.key&&t.forceNotify(e);var n=t.props.onKeyDown;n&&(e.persist(),n(e))})),g(d(t),"onBlur",(function(e){t.forceNotify(e);var n=t.props.onBlur;n&&(e.persist(),n(e))})),g(d(t),"createNotifier",(function(e){if(e<0)t.notify=function(){return null};else if(0===e)t.notify=t.doNotify;else{var n=(0,a.default)((function(e){t.isDebouncing=!1,t.doNotify(e)}),e);t.notify=function(e){t.isDebouncing=!0,n(e)},t.flush=function(){return n.flush()},t.cancel=function(){t.isDebouncing=!1,n.cancel()}}})),g(d(t),"doNotify",(function(){t.props.onChange.apply(void 0,arguments)})),g(d(t),"forceNotify",(function(e){var n=t.props.debounceTimeout;if(t.isDebouncing||!(n>0)){t.cancel&&t.cancel();var r=t.state.value,o=t.props.minLength;r.length>=o?t.doNotify(e):t.doNotify(c(c({},e),{},{target:c(c({},e.target),{},{value:r})}))}})),t.isDebouncing=!1,t.state={value:void 0===e.value||null===e.value?"":e.value};var n=t.props.debounceTimeout;return t.createNotifier(n),t}return t=u,(n=[{key:"componentDidUpdate",value:function(e){if(!this.isDebouncing){var t=this.props,n=t.value,r=t.debounceTimeout,o=e.debounceTimeout,a=e.value,i=this.state.value;void 0!==n&&a!==n&&i!==n&&this.setState({value:n}),r!==o&&this.createNotifier(r)}}},{key:"componentWillUnmount",value:function(){this.flush&&this.flush()}},{key:"render",value:function(){var e,t,n=this.props,r=n.element,a=(n.onChange,n.value,n.minLength,n.debounceTimeout,n.forceNotifyByEnter),s=n.forceNotifyOnBlur,u=n.onKeyDown,p=n.onBlur,f=n.inputRef,h=l(n,i),d=this.state.value;e=a?{onKeyDown:this.onKeyDown}:u?{onKeyDown:u}:{},t=s?{onBlur:this.onBlur}:p?{onBlur:p}:{};var m=f?{ref:f}:{};return o.default.createElement(r,c(c(c(c({},h),{},{onChange:this.onChange,value:d},e),t),m))}}])&&p(t.prototype,n),r&&p(t,r),Object.defineProperty(t,"prototype",{writable:!1}),u}(o.default.PureComponent);t.DebounceInput=y,g(y,"defaultProps",{element:"input",type:"text",onKeyDown:void 0,onBlur:void 0,value:void 0,minLength:0,debounceTimeout:100,forceNotifyByEnter:!0,forceNotifyOnBlur:!0,inputRef:void 0})},775:(e,t,n)=>{"use strict";var r=n(53441).DebounceInput;r.DebounceInput=r,e.exports=r},64448:(e,t,n)=>{"use strict";var r=n(67294),o=n(27418),a=n(63840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n
")}value(){return this.buffer}span(e){this.buffer+=``}}class o{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){e={kind:e,children:[]};this.add(e),this.stack.push(e)}closeNode(){if(1this._walk(t,e)),t.closeNode(e)),t}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{o._collapse(e)}))}}class y extends o{constructor(e){super(),this.options=e}addKeyword(e,t){""!==e&&(this.openNode(t),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,t){const n=e.root;n.kind=t,n.sublanguage=!0,this.add(n)}toHTML(){return new t(this,this.options).value()}finalize(){return!0}}function c(e){return e?"string"==typeof e?e:e.source:null}function s(e,t,n={}){const r=l({className:"comment",begin:e,end:t,contains:[]},n);return r.contains.push(w),r.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),r}const p=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,i="[a-zA-Z]\\w*",a="[a-zA-Z_]\\w*",h="\\b\\d+(\\.\\d+)?",d="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",f="\\b(0b[01]+)",m={begin:"\\\\[\\s\\S]",relevance:0},v={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[m]},b={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[m]},w={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},E=s("//","$"),S=s("/\\*","\\*/"),x=s("#","$"),C={className:"number",begin:h,relevance:0},j={className:"number",begin:d,relevance:0},B={className:"number",begin:f,relevance:0},L={className:"number",begin:h+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},q={begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[m,{begin:/\[/,end:/\]/,relevance:0,contains:[m]}]}]},$={className:"title",begin:i,relevance:0},z={className:"title",begin:a,relevance:0},U={begin:"\\.\\s*"+a,relevance:0};var N=Object.freeze({__proto__:null,MATCH_NOTHING_RE:/\b\B/,IDENT_RE:i,UNDERSCORE_IDENT_RE:a,NUMBER_RE:h,C_NUMBER_RE:d,BINARY_NUMBER_RE:f,RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{var t=/^#![ ]*\//;return e.binary&&(e.begin=[t,/.*\b/,e.binary,/\b.*/].map(e=>c(e)).join("")),l({className:"meta",begin:t,end:/$/,relevance:0,"on:begin":(e,t)=>{0!==e.index&&t.ignoreMatch()}},e)},BACKSLASH_ESCAPE:m,APOS_STRING_MODE:v,QUOTE_STRING_MODE:b,PHRASAL_WORDS_MODE:w,COMMENT:s,C_LINE_COMMENT_MODE:E,C_BLOCK_COMMENT_MODE:S,HASH_COMMENT_MODE:x,NUMBER_MODE:C,C_NUMBER_MODE:j,BINARY_NUMBER_MODE:B,CSS_NUMBER_MODE:L,REGEXP_MODE:q,TITLE_MODE:$,UNDERSCORE_TITLE_MODE:z,METHOD_GUARD:U,END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,t)=>{t.data._beginMatch=e[1]},"on:end":(e,t)=>{t.data._beginMatch!==e[1]&&t.ignoreMatch()}})}});function V(e,t){"."===e.input[e.index-1]&&t.ignoreMatch()}const K=["of","and","for","in","not","or","if","then","parent","list","value"],W="keyword";function _(t,r,e=W){const o={};return"string"==typeof t?n(e,t.split(" ")):Array.isArray(t)?n(e,t):Object.keys(t).forEach(function(e){Object.assign(o,_(t[e],r,e))}),o;function n(n,e){(e=r?e.map(e=>e.toLowerCase()):e).forEach(function(e){var t,e=e.split("|");o[e[0]]=[n,(t=e[0],(e=e[1])?Number(e):function(e){return K.includes(e.toLowerCase())}(t)?0:1)]})}}function J(s,{}){function i(e,t){return new RegExp(c(e),"m"+(s.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,t){t.position=this.position++,this.matchIndexes[this.matchAt]=t,this.regexes.push([t,e]),this.matchAt+=new RegExp(e.toString()+"|").exec("").length-1+1}compile(){0===this.regexes.length&&(this.exec=()=>null);var e=this.regexes.map(e=>e[1]);this.matcherRe=i(function(e,t="|"){let o=0;return e.map(e=>{var t=o+=1;let n=c(e),r="";for(;0`(${e})`).join(t)}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const t=this.matcherRe.exec(e);if(!t)return null;var e=t.findIndex((e,t)=>0n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n}resumingScanAtSamePosition(){return 0!==this.regexIndex}considerAll(){this.regexIndex=0}addRule(e,t){this.rules.push([e,t]),"begin"===t.type&&this.count++}exec(e){const t=this.getMatcher(this.regexIndex);t.lastIndex=this.lastIndex;let n=t.exec(e);if(this.resumingScanAtSamePosition()&&(!n||n.index!==this.lastIndex)){const t=this.getMatcher(0);t.lastIndex=this.lastIndex+1,n=t.exec(e)}return n&&(this.regexIndex+=n.position+1,this.regexIndex===this.count&&this.considerAll()),n}}if(s.compilerExtensions||(s.compilerExtensions=[]),s.contains&&s.contains.includes("self"))throw new Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return s.classNameAliases=l(s.classNameAliases||{}),function t(n,r){const o=n;if(n.isCompiled)return o;[function(e,t){if(e.match){if(e.begin||e.end)throw new Error("begin & end are not supported with match");e.begin=e.match,delete e.match}}].forEach(e=>e(n,r)),s.compilerExtensions.forEach(e=>e(n,r)),n.__beforeBegin=null,[function(e,t){t&&e.beginKeywords&&(e.begin="\\b("+e.beginKeywords.split(" ").join("|")+")(?!\\.)(?=\\b|\\s)",e.__beforeBegin=V,e.keywords=e.keywords||e.beginKeywords,delete e.beginKeywords,void 0===e.relevance&&(e.relevance=0))},function(e,t){Array.isArray(e.illegal)&&(e.illegal=([...e]=[...e.illegal],"("+e.map(e=>c(e)).join("|")+")"))},function(e,t){void 0===e.relevance&&(e.relevance=1)}].forEach(e=>e(n,r)),n.isCompiled=!0;let e=null;if("object"==typeof n.keywords&&(e=n.keywords.$pattern,delete n.keywords.$pattern),n.keywords&&(n.keywords=_(n.keywords,s.case_insensitive)),n.lexemes&&e)throw new Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return e=e||n.lexemes||/\w+/,o.keywordPatternRe=i(e,!0),r&&(n.begin||(n.begin=/\B|\b/),o.beginRe=i(n.begin),n.endSameAsBegin&&(n.end=n.begin),n.end||n.endsWithParent||(n.end=/\B|\b/),n.end&&(o.endRe=i(n.end)),o.terminatorEnd=c(n.end)||"",n.endsWithParent&&r.terminatorEnd&&(o.terminatorEnd+=(n.end?"|":"")+r.terminatorEnd)),n.illegal&&(o.illegalRe=i(n.illegal)),n.contains||(n.contains=[]),n.contains=[].concat(...n.contains.map(function(e){return(t="self"===e?n:e).variants&&!t.cachedVariants&&(t.cachedVariants=t.variants.map(function(e){return l(t,{variants:null},e)})),t.cachedVariants||(function e(t){return!!t&&(t.endsWithParent||e(t.starts))}(t)?l(t,{starts:t.starts?l(t.starts):null}):Object.isFrozen(t)?l(t):t);var t})),n.contains.forEach(function(e){t(e,o)}),n.starts&&t(n.starts,r),o.matcher=function(e){const t=new a;return e.contains.forEach(e=>t.addRule(e.begin,{rule:e,type:"begin"})),e.terminatorEnd&&t.addRule(e.terminatorEnd,{type:"end"}),e.illegal&&t.addRule(e.illegal,{type:"illegal"}),t}(o),o}(s)}function H(t){const n={props:["language","code","autodetect"],data:function(){return{detectedLanguage:"",unknownLanguage:!1}},computed:{className(){return this.unknownLanguage?"":"hljs "+this.detectedLanguage},highlighted(){if(!this.autoDetect&&!t.getLanguage(this.language))return console.warn(`The language "${this.language}" you specified could not be found.`),this.unknownLanguage=!0,u(this.code);let e={};return this.autoDetect?(e=t.highlightAuto(this.code),this.detectedLanguage=e.language):(e=t.highlight(this.language,this.code,this.ignoreIllegals),this.detectedLanguage=this.language),e.value},autoDetect(){return!this.language||(e=this.autodetect,Boolean(e||""===e));var e},ignoreIllegals:()=>!0},render(e){return e("pre",{},[e("code",{class:this.className,domProps:{innerHTML:this.highlighted}})])}};return{Component:n,VuePlugin:{install(e){e.component("highlightjs",n)}}}}const G={"after:highlightElement":({el:e,result:t,text:n})=>{e=A(e);if(e.length){const r=document.createElement("div");r.innerHTML=t.value,t.value=function(t,e,n){let r=0,o="";const s=[];function i(){return t.length&&e.length?t[0].offset!==e[0].offset?t[0].offset"}function l(e){o+=""}function c(e){("start"===e.event?a:l)(e.node)}for(;t.length||e.length;){let e=i();if(o+=u(n.substring(r,e[0].offset)),r=e[0].offset,e===t){for(s.reverse().forEach(l);c(e.splice(0,1)[0]),(e=i())===t&&e.length&&e[0].offset===r;);s.reverse().forEach(a)}else"start"===e[0].event?s.push(e[0].node):s.pop(),c(e.splice(0,1)[0])}return o+u(n.substr(r))}(e,A(r),n)}}};function k(e){return e.nodeName.toLowerCase()}function A(e){const o=[];return function t(n,r){for(let e=n.firstChild;e;e=e.nextSibling)3===e.nodeType?r+=e.nodeValue.length:1===e.nodeType&&(o.push({event:"start",offset:r,node:e}),r=t(e,r),k(e).match(/br|hr|img|input/)||o.push({event:"stop",offset:r,node:e}));return r}(e,0),o}const O={},I=e=>{console.error(e)},T=(e,...t)=>{console.log("WARN: "+e,...t)},R=(e,t)=>{O[e+"/"+t]||(console.log(`Deprecated as of ${e}. `+t),O[e+"/"+t]=!0)},M=u,D=l,F=Symbol("nomatch");var Y=function(r){const S=Object.create(null),s=Object.create(null),x=[];let _=!0;const t=/(^(<[^>]+>|\t|)+|\n)/gm,k="Could not find the language '{}', did you forget to load/include a language module?",l={disableAutodetect:!0,name:"Plain text",contains:[]};let A={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:y};function i(e){return A.noHighlightRe.test(e)}function a(e,t,n,r){let o="",s="";"object"==typeof t?(o=e,n=t.ignoreIllegals,s=t.language,r=void 0):(R("10.7.0","highlight(lang, code, ...args) has been deprecated."),R("10.7.0","Please use highlight(code, options) instead.\nhttps://github.com/highlightjs/highlight.js/issues/2277"),s=e,o=t);e={code:o,language:s};m("before:highlight",e);const i=e.result||O(e.language,e.code,n,r);return i.code=e.code,m("after:highlight",i),i}function O(r,o,s,e){function i(){(null!=d.subLanguage?function(){if(""!==g){let e=null;if("string"==typeof d.subLanguage){if(!S[d.subLanguage])return m.addText(g);e=O(d.subLanguage,g,!0,f[d.subLanguage]),f[d.subLanguage]=e.top}else e=C(g,d.subLanguage.length?d.subLanguage:null);0")+'"');throw r.mode=d,r}if("end"===t.type){const r=c(t);if(r!==F)return r}if("illegal"===t.type&&""===n)return 1;if(1e53*t.index)throw new Error("potential infinite loop, way more iterations than matches");return g+=n,n.length}const p=j(r);if(!p)throw I(k.replace("{}",r)),new Error('Unknown language: "'+r+'"');var n=J(p,{plugins:x});let h="",d=e||n;const f={},m=new A.__emitter(A);{const E=[];for(let e=d;e!==p;e=e.parent)e.className&&E.unshift(e.className);E.forEach(e=>m.openNode(e))}let g="",y=0,v=0,b=0,w=!1;try{for(d.matcher.considerAll();;){b++,w?w=!1:d.matcher.considerAll(),d.matcher.lastIndex=v;const r=d.matcher.exec(o);if(!r)break;const S=t(o.substring(v,r.index),r);v=r.index+S}return t(o.substr(v)),m.closeAllNodes(),m.finalize(),h=m.toHTML(),{relevance:Math.floor(y),value:h,language:r,illegal:!1,emitter:m,top:d}}catch(e){if(e.message&&e.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:e.message,context:o.slice(v-100,v+100),mode:e.mode},sofar:h,relevance:0,value:M(o),emitter:m};if(_)return{illegal:!1,relevance:0,value:M(o),emitter:m,language:r,top:d,errorRaised:e};throw e}}function C(t,e){e=e||A.languages||Object.keys(S);const n=function(e){const t={relevance:0,emitter:new A.__emitter(A),value:M(e),illegal:!1,top:l};return t.emitter.addText(e),t}(t),r=e.filter(j).filter(f).map(e=>O(e,t,!1)),o=(r.unshift(n),r.sort((e,t)=>{if(e.relevance!==t.relevance)return t.relevance-e.relevance;if(e.language&&t.language){if(j(e.language).supersetOf===t.language)return 1;if(j(t.language).supersetOf===e.language)return-1}return 0})),[s,i]=o,a=s;return a.second_best=i,a}const e={"before:highlightElement":({el:e})=>{A.useBR&&(e.innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"))},"after:highlightElement":({result:e})=>{A.useBR&&(e.value=e.value.replace(/\n/g,"
"))}},n=/^(<[^>]+>|\t)+/gm,o={"after:highlightElement":({result:e})=>{A.tabReplace&&(e.value=e.value.replace(n,e=>e.replace(/\t/g,A.tabReplace)))}};function c(e){var t,n,r,o=function(e){let t=e.className+" ";t+=e.parentNode?e.parentNode.className:"";var n=A.languageDetectRe.exec(t);if(n){const t=j(n[1]);return t||(T(k.replace("{}",n[1])),T("Falling back to no-highlight mode for this block.",e)),t?n[1]:"no-highlight"}return t.split(/\s+/).find(e=>i(e)||j(e))}(e);i(o)||(m("before:highlightElement",{el:e,language:o}),n=e.textContent,m("after:highlightElement",{el:e,result:t=o?a(n,{language:o,ignoreIllegals:!0}):C(n),text:n}),e.innerHTML=t.value,n=e,o=o,r=t.language,o=o?s[o]:r,n.classList.add("hljs"),o&&n.classList.add(o),e.result={language:t.language,re:t.relevance,relavance:t.relevance},t.second_best&&(e.second_best={language:t.second_best.language,re:t.second_best.relevance,relavance:t.second_best.relevance}))}const u=()=>{u.called||(u.called=!0,R("10.6.0","initHighlighting() is deprecated. Use highlightAll() instead."),document.querySelectorAll("pre code").forEach(c))};let p=!1;function h(){"loading"===document.readyState?p=!0:document.querySelectorAll("pre code").forEach(c)}function j(e){return e=(e||"").toLowerCase(),S[e]||S[s[e]]}function d(e,{languageName:t}){(e="string"==typeof e?[e]:e).forEach(e=>{s[e.toLowerCase()]=t})}function f(e){e=j(e);return e&&!e.disableAutodetect}function m(e,t){const n=e;x.forEach(function(e){e[n]&&e[n](t)})}"undefined"!=typeof window&&window.addEventListener&&window.addEventListener("DOMContentLoaded",function(){p&&h()},!1),Object.assign(r,{highlight:a,highlightAuto:C,highlightAll:h,fixMarkup:function(e){return R("10.2.0","fixMarkup will be removed entirely in v11.0"),R("10.2.0","Please see https://github.com/highlightjs/highlight.js/issues/2534"),e=e,A.tabReplace||A.useBR?e.replace(t,e=>"\n"===e?A.useBR?"
":e:A.tabReplace?e.replace(/\t/g,A.tabReplace):e):e},highlightElement:c,highlightBlock:function(e){return R("10.7.0","highlightBlock will be removed entirely in v12.0"),R("10.7.0","Please use highlightElement now."),c(e)},configure:function(e){e.useBR&&(R("10.3.0","'useBR' will be removed entirely in v11.0"),R("10.3.0","Please see https://github.com/highlightjs/highlight.js/issues/2559")),A=D(A,e)},initHighlighting:u,initHighlightingOnLoad:function(){R("10.6.0","initHighlightingOnLoad() is deprecated. Use highlightAll() instead."),p=!0},registerLanguage:function(t,e){let n=null;try{n=e(r)}catch(e){if(I("Language definition for '{}' could not be registered.".replace("{}",t)),!_)throw e;I(e),n=l}n.name||(n.name=t),(S[t]=n).rawDefinition=e.bind(null,r),n.aliases&&d(n.aliases,{languageName:t})},unregisterLanguage:function(e){delete S[e];for(const t of Object.keys(s))s[t]===e&&delete s[t]},listLanguages:function(){return Object.keys(S)},getLanguage:j,registerAliases:d,requireLanguage:function(e){R("10.4.0","requireLanguage will be removed entirely in v11."),R("10.4.0","Please see https://github.com/highlightjs/highlight.js/pull/2844");var t=j(e);if(t)return t;throw new Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:f,inherit:D,addPlugin:function(e){var t;(t=e)["before:highlightBlock"]&&!t["before:highlightElement"]&&(t["before:highlightElement"]=e=>{t["before:highlightBlock"](Object.assign({block:e.el},e))}),t["after:highlightBlock"]&&!t["after:highlightElement"]&&(t["after:highlightElement"]=e=>{t["after:highlightBlock"](Object.assign({block:e.el},e))}),x.push(e)},vuePlugin:H(r).VuePlugin}),r.debugMode=function(){_=!1},r.safeMode=function(){_=!0},r.versionString="10.7.3";for(const r in N)"object"==typeof N[r]&&g(N[r]);return Object.assign(r,N),r.addPlugin(e),r.addPlugin(G),r.addPlugin(o),r}({});e.exports=Y},35344:e=>{e.exports=function(e){var t={},n={begin:/\$\{/,end:/\}/,contains:["self",{begin:/:-/,contains:[t]}]};Object.assign(t,{className:"variable",variants:[{begin:[/\$[\w\d#@][\w\d_]*/,"(?![\\w\\d])(?![$])"].map(e=>{return e?"string"==typeof e?e:e.source:null}).join("")},n]});const r={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},o={begin:/<<-?\s*(?=\w+)/,starts:{contains:[e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,className:"string"})]}},s={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,t,r]};r.contains.push(s);var n={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,t]},i=e.SHEBANG({binary:`(${["fish","bash","zsh","sh","csh","ksh","tcsh","dash","scsh"].join("|")})`,relevance:10}),a={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b[a-z._-]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp"},contains:[i,e.SHEBANG(),a,n,e.HASH_COMMENT_MODE,o,s,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},t]}}},73402:e=>{e.exports=function(e){var t="HTTP/(2|1\\.[01])",n={className:"attribute",begin:["^",/[A-Za-z][A-Za-z0-9-]*/,"(?=\\:\\s)"].map(e=>{return e?"string"==typeof e?e:e.source:null}).join(""),starts:{contains:[{className:"punctuation",begin:/: /,relevance:0,starts:{end:"$",relevance:0}}]}},r=[n,{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}];return{name:"HTTP",aliases:["https"],illegal:/\S/,contains:[{begin:"^(?="+t+" \\d{3})",end:/$/,contains:[{className:"meta",begin:t},{className:"number",begin:"\\b\\d{3}\\b"}],starts:{end:/\b\B/,illegal:/\S/,contains:r}},{begin:"(?=^[A-Z]+ (.*?) "+t+"$)",end:/$/,contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{className:"meta",begin:t},{className:"keyword",begin:"[A-Z]+"}],starts:{end:/\b\B/,illegal:/\S/,contains:r}},e.inherit(n,{relevance:0})]}}},95089:e=>{const b="[A-Za-z$_][0-9A-Za-z$_]*",w=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],E=["true","false","null","undefined","NaN","Infinity"],S=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer","BigInt64Array","BigUint64Array","BigInt"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function x(e){return _("(?=",e,")")}function _(...e){return e.map(e=>{return e?"string"==typeof e?e:e.source:null}).join("")}e.exports=function(e){const t=b,n=/<[A-Za-z0-9\\._:-]+/,r=/\/[A-Za-z0-9\\._:-]+>|\/>/,o=(e,t)=>{var n=e[0].length+e.index,r=e.input[n];"<"!==r?">"===r&&([r,e]=[e,{after:n}["after"]],n="",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:e.UNDERSCORE_IDENT_RE,relevance:0},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:s,contains:y}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:""},{begin:n,"on:begin":o,end:r}],subLanguage:"xml",contains:[{begin:n,end:r,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[{;]/,excludeEnd:!0,keywords:s,contains:["self",e.inherit(e.TITLE_MODE,{begin:t}),v],illegal:/%/},{beginKeywords:"while if switch catch for"},{className:"function",begin:e.UNDERSCORE_IDENT_RE+"\\([^()]*(\\([^()]*(\\([^()]*\\)[^()]*)*\\)[^()]*)*\\)\\s*\\{",returnBegin:!0,contains:[v,e.inherit(e.TITLE_MODE,{begin:t})]},{variants:[{begin:"\\."+t},{begin:"\\$"+t}],relevance:0},{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"[\]]/,contains:[{beginKeywords:"extends"},e.UNDERSCORE_TITLE_MODE]},{begin:/\b(?=constructor)/,end:/[{;]/,excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:t}),"self",v]},{begin:"(get|set)\\s+(?="+t+"\\()",end:/\{/,keywords:"get set",contains:[e.inherit(e.TITLE_MODE,{begin:t}),{begin:/\(\)/},v]},{begin:/\$[(.]/}]}}},65772:e=>{e.exports=function(e){const t={literal:"true false null"},n=[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE],r=[e.QUOTE_STRING_MODE,e.C_NUMBER_MODE],o={end:",",endsWithParent:!0,excludeEnd:!0,contains:r,keywords:t},s={begin:/\{/,end:/\}/,contains:[{className:"attr",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE],illegal:"\\n"},e.inherit(o,{begin:/:/})].concat(n),illegal:"\\S"},i={begin:"\\[",end:"\\]",contains:[e.inherit(o)],illegal:"\\S"};return r.push(s,i),n.forEach(function(e){r.push(e)}),{name:"JSON",contains:r,keywords:t,illegal:"\\S"}}},26571:e=>{e.exports=function(e){const t={$pattern:/-?[A-z\.\-]+\b/,keyword:"if else foreach return do while until elseif begin for trap data dynamicparam end break throw param continue finally in switch exit filter try process catch hidden static parameter",built_in:"ac asnp cat cd CFS chdir clc clear clhy cli clp cls clv cnsn compare copy cp cpi cpp curl cvpa dbp del diff dir dnsn ebp echo|0 epal epcsv epsn erase etsn exsn fc fhx fl ft fw gal gbp gc gcb gci gcm gcs gdr gerr ghy gi gin gjb gl gm gmo gp gps gpv group gsn gsnp gsv gtz gu gv gwmi h history icm iex ihy ii ipal ipcsv ipmo ipsn irm ise iwmi iwr kill lp ls man md measure mi mount move mp mv nal ndr ni nmo npssc nsn nv ogv oh popd ps pushd pwd r rbp rcjb rcsn rd rdr ren ri rjb rm rmdir rmo rni rnp rp rsn rsnp rujb rv rvpa rwmi sajb sal saps sasv sbp sc scb select set shcm si sl sleep sls sort sp spjb spps spsv start stz sujb sv swmi tee trcm type wget where wjb write"},n={begin:"`[\\s\\S]",relevance:0},r={className:"variable",variants:[{begin:/\$\B/},{className:"keyword",begin:/\$this/},{begin:/\$[\w\d][\w\d_:]*/}]},o={className:"string",variants:[{begin:/"/,end:/"/},{begin:/@"/,end:/^"@/}],contains:[n,r,{className:"variable",begin:/\$[A-z]/,end:/[^A-z]/}]},s={className:"string",variants:[{begin:/'/,end:/'/},{begin:/@'/,end:/^'@/}]},i=e.inherit(e.COMMENT(null,null),{variants:[{begin:/#/,end:/$/},{begin:/<#/,end:/#>/}],contains:[{className:"doctag",variants:[{begin:/\.(synopsis|description|example|inputs|outputs|notes|link|component|role|functionality)/},{begin:/\.(parameter|forwardhelptargetname|forwardhelpcategory|remotehelprunspace|externalhelp)\s+\S+/}]}]}),a={className:"built_in",variants:[{begin:"(".concat("Add|Clear|Close|Copy|Enter|Exit|Find|Format|Get|Hide|Join|Lock|Move|New|Open|Optimize|Pop|Push|Redo|Remove|Rename|Reset|Resize|Search|Select|Set|Show|Skip|Split|Step|Switch|Undo|Unlock|Watch|Backup|Checkpoint|Compare|Compress|Convert|ConvertFrom|ConvertTo|Dismount|Edit|Expand|Export|Group|Import|Initialize|Limit|Merge|Mount|Out|Publish|Restore|Save|Sync|Unpublish|Update|Approve|Assert|Build|Complete|Confirm|Deny|Deploy|Disable|Enable|Install|Invoke|Register|Request|Restart|Resume|Start|Stop|Submit|Suspend|Uninstall|Unregister|Wait|Debug|Measure|Ping|Repair|Resolve|Test|Trace|Connect|Disconnect|Read|Receive|Send|Write|Block|Grant|Protect|Revoke|Unblock|Unprotect|Use|ForEach|Sort|Tee|Where",")+(-)[\\w\\d]+")}]},l={className:"class",beginKeywords:"class enum",end:/\s*[{]/,excludeEnd:!0,relevance:0,contains:[e.TITLE_MODE]},c={className:"function",begin:/function\s+/,end:/\s*\{|$/,excludeEnd:!0,returnBegin:!0,relevance:0,contains:[{begin:"function",relevance:0,className:"keyword"},{className:"title",begin:/\w[\w\d]*((-)[\w\d]+)*/,relevance:0},{begin:/\(/,end:/\)/,className:"params",relevance:0,contains:[r]}]},u={begin:/using\s/,end:/$/,returnBegin:!0,contains:[o,s,{className:"keyword",begin:/(using|assembly|command|module|namespace|type)/}]},p={variants:[{className:"operator",begin:"(".concat("-and|-as|-band|-bnot|-bor|-bxor|-casesensitive|-ccontains|-ceq|-cge|-cgt|-cle|-clike|-clt|-cmatch|-cne|-cnotcontains|-cnotlike|-cnotmatch|-contains|-creplace|-csplit|-eq|-exact|-f|-file|-ge|-gt|-icontains|-ieq|-ige|-igt|-ile|-ilike|-ilt|-imatch|-in|-ine|-inotcontains|-inotlike|-inotmatch|-ireplace|-is|-isnot|-isplit|-join|-le|-like|-lt|-match|-ne|-not|-notcontains|-notin|-notlike|-notmatch|-or|-regex|-replace|-shl|-shr|-split|-wildcard|-xor",")\\b")},{className:"literal",begin:/(-)[\w\d]+/,relevance:0}]},h={className:"function",begin:/\[.*\]\s*[\w]+[ ]??\(/,end:/$/,returnBegin:!0,relevance:0,contains:[{className:"keyword",begin:"(".concat(t.keyword.toString().replace(/\s/g,"|"),")\\b"),endsParent:!0,relevance:0},e.inherit(e.TITLE_MODE,{endsParent:!0})]},d=[h,i,n,e.NUMBER_MODE,o,s,a,r,{className:"literal",begin:/\$(null|true|false)\b/},{className:"selector-tag",begin:/@\B/,relevance:0}],f={begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[].concat("self",d,{begin:"("+["string","char","byte","int","long","bool","decimal","single","double","DateTime","xml","array","hashtable","void"].join("|")+")",className:"built_in",relevance:0},{className:"type",begin:/[\.\w\d]+/,relevance:0})};return h.contains.unshift(f),{name:"PowerShell",aliases:["ps","ps1"],case_insensitive:!0,keywords:t,contains:d.concat(l,c,u,p,f)}}},17285:e=>{function l(e){return e?"string"==typeof e?e:e.source:null}function c(e){return u("(?=",e,")")}function u(...e){return e.map(e=>l(e)).join("")}e.exports=function(e){var t=u(/[A-Z_]/,u("(",/[A-Z0-9_.-]*:/,")?"),/[A-Z0-9_.-]*/),n={className:"symbol",begin:/&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;/},r={begin:/\s/,contains:[{className:"meta-keyword",begin:/#?[a-z_][a-z1-9_-]+/,illegal:/\n/}]},o=e.inherit(r,{begin:/\(/,end:/\)/}),s=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),i=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),a={endsWithParent:!0,illegal:/`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin://,relevance:10,contains:[r,i,s,o,{begin:/\[/,end:/\]/,contains:[{className:"meta",begin://,contains:[r,o,i,s]}]}]},e.COMMENT(//,{relevance:10}),{begin://,relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:/)/,end:/>/,keywords:{name:"style"},contains:[a],starts:{end:/<\/style>/,returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:/)/,end:/>/,keywords:{name:"script"},contains:[a],starts:{end:/<\/script>/,returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:/<>|<\/>/},{className:"tag",begin:u(//,/>/,/\s/].map(e=>l(e)).join("|")+")"))),end:/\/?>/,contains:[{className:"name",begin:t,relevance:0,starts:a}]},{className:"tag",begin:u(/<\//,c(u(t,/>/))),contains:[{className:"name",begin:t,relevance:0},{begin:/>/,relevance:0,endsParent:!0}]}]}}},17533:e=>{e.exports=function(e){var t="true false yes no null",n="[\\w#;/?:@&=+$,.~*'()[\\]]+",r={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:/\{\{/,end:/\}\}/},{begin:/%\{/,end:/\}/}]}]},o=e.inherit(r,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),s={end:",",endsWithParent:!0,excludeEnd:!0,keywords:t,relevance:0},n=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---\\s*$",relevance:10},{className:"string",begin:"[\\|>]([1-9]?[+-])?[ ]*\\n( +)[^ ][^\\n]*\\n(\\2[^\\n]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+n},{className:"type",begin:"!<"+n+">"},{className:"type",begin:"!"+n},{className:"type",begin:"!!"+n},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:t,keywords:{literal:t}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b",relevance:0},{begin:/\{/,end:/\}/,contains:[s],illegal:"\\n",relevance:0},{begin:"\\[",end:"\\]",contains:[s],illegal:"\\n",relevance:0},r],t=[...n];return t.pop(),t.push(o),s.contains=t,{name:"YAML",case_insensitive:!0,aliases:["yml"],contains:n}}},251:(e,t)=>{t.read=function(e,t,n,r,o){var s,i,a=8*o-r-1,l=(1<>1,u=-7,p=n?o-1:0,h=n?-1:1,o=e[t+p];for(p+=h,s=o&(1<<-u)-1,o>>=-u,u+=a;0>=-u,u+=r;0>1,p=23===o?Math.pow(2,-24)-Math.pow(2,-77):0,h=r?0:s-1,d=r?1:-1,s=t<0||0===t&&1/t<0?1:0;for(t=Math.abs(t),isNaN(t)||t===1/0?(a=isNaN(t)?1:0,i=c):(i=Math.floor(Math.log(t)/Math.LN2),t*(r=Math.pow(2,-i))<1&&(i--,r*=2),2<=(t+=1<=i+u?p/r:p*Math.pow(2,1-u))*r&&(i++,r/=2),c<=i+u?(a=0,i=c):1<=i+u?(a=(t*r-1)*Math.pow(2,o),i+=u):(a=t*Math.pow(2,u-1)*Math.pow(2,o),i=0));8<=o;e[n+h]=255&a,h+=d,a/=256,o-=8);for(i=i<>>0;if(""+n!==t||4294967295==n)return NaN;t=n}return t<0?H(e)+t:t}function Y(){return!0}function X(e,t,n){return(0===e||void 0!==n&&e<=-n)&&(void 0===t||void 0!==n&&n<=t)}function Q(e,t){return ee(e,t,0)}function Z(e,t){return ee(e,t,t)}function ee(e,t,n){return void 0===e?n:e<0?Math.max(0,t+e):void 0===t?e:Math.min(t,e)}var te=0,h=1,ne=2,re="function"==typeof Symbol&&Symbol.iterator,oe="@@iterator",se=re||oe;function d(e){this.next=e}function f(e,t,n,r){e=0===e?t:1===e?n:[t,n];return r?r.value=e:r={value:e,done:!1},r}function m(){return{value:void 0,done:!0}}function ie(e){return ce(e)}function ae(e){return e&&"function"==typeof e.next}function le(e){var t=ce(e);return t&&t.call(e)}function ce(e){e=e&&(re&&e[re]||e[oe]);if("function"==typeof e)return e}function ue(e){return e&&"number"==typeof e.length}function n(e){{if(null==e)return Se();if(u(e))return e.toSeq();var t=ke(e)||"object"==typeof e&&new ve(e);if(t)return t;throw new TypeError("Expected Array or iterable object of values, or keyed object: "+e)}}function pe(e){return null==e?Se().toKeyedSeq():u(e)?c(e)?e.toSeq():e.fromEntrySeq():xe(e)}function g(e){return null==e?Se():u(e)?c(e)?e.entrySeq():e.toIndexedSeq():_e(e)}function he(e){return(null==e?Se():u(e)?c(e)?e.entrySeq():e:_e(e)).toSetSeq()}d.prototype.toString=function(){return"[Iterator]"},d.KEYS=te,d.VALUES=h,d.ENTRIES=ne,d.prototype.inspect=d.prototype.toSource=function(){return this.toString()},d.prototype[se]=function(){return this},e(n,l),n.of=function(){return n(arguments)},n.prototype.toSeq=function(){return this},n.prototype.toString=function(){return this.__toString("Seq {","}")},n.prototype.cacheResult=function(){return!this._cache&&this.__iterateUncached&&(this._cache=this.entrySeq().toArray(),this.size=this._cache.length),this},n.prototype.__iterate=function(e,t){return Ae(this,e,t,!0)},n.prototype.__iterator=function(e,t){return Oe(this,e,t,!0)},e(pe,n),pe.prototype.toKeyedSeq=function(){return this},e(g,n),g.of=function(){return g(arguments)},g.prototype.toIndexedSeq=function(){return this},g.prototype.toString=function(){return this.__toString("Seq [","]")},g.prototype.__iterate=function(e,t){return Ae(this,e,t,!1)},g.prototype.__iterator=function(e,t){return Oe(this,e,t,!1)},e(he,n),he.of=function(){return he(arguments)},he.prototype.toSetSeq=function(){return this},n.isSeq=Ee,n.Keyed=pe,n.Set=he,n.Indexed=g;var de,fe,me,ge="@@__IMMUTABLE_SEQ__@@";function ye(e){this._array=e,this.size=e.length}function ve(e){var t=Object.keys(e);this._object=e,this._keys=t,this.size=t.length}function be(e){this._iterable=e,this.size=e.length||e.size}function we(e){this._iterator=e,this._iteratorCache=[]}function Ee(e){return!(!e||!e[ge])}function Se(){return de=de||new ye([])}function xe(e){var t=Array.isArray(e)?new ye(e).fromEntrySeq():ae(e)?new we(e).fromEntrySeq():ie(e)?new be(e).fromEntrySeq():"object"==typeof e?new ve(e):void 0;if(t)return t;throw new TypeError("Expected Array or iterable object of [k, v] entries, or keyed object: "+e)}function _e(e){var t=ke(e);if(t)return t;throw new TypeError("Expected Array or iterable object of values: "+e)}function ke(e){return ue(e)?new ye(e):ae(e)?new we(e):ie(e)?new be(e):void 0}function Ae(e,t,n,r){var o=e._cache;if(o){for(var s=o.length-1,i=0;i<=s;i++){var a=o[n?s-i:i];if(!1===t(a[1],r?a[0]:i,e))return i+1}return i}return e.__iterateUncached(t,n)}function Oe(e,t,n,r){var o,s,i=e._cache;return i?(o=i.length-1,s=0,new d(function(){var e=i[n?o-s:s];return s++>o?m():f(t,r?e[0]:s-1,e[1])})):e.__iteratorUncached(t,n)}function Ce(e,t){return t?function n(r,o,e,t){return Array.isArray(o)?r.call(t,e,g(o).map(function(e,t){return n(r,e,t,o)})):Pe(o)?r.call(t,e,pe(o).map(function(e,t){return n(r,e,t,o)})):o}(t,e,"",{"":e}):je(e)}function je(e){return Array.isArray(e)?g(e).map(je).toList():Pe(e)?pe(e).map(je).toMap():e}function Pe(e){return e&&(e.constructor===Object||void 0===e.constructor)}function v(e,t){if(e===t||e!=e&&t!=t)return!0;if(!e||!t)return!1;if("function"==typeof e.valueOf&&"function"==typeof t.valueOf){if((e=e.valueOf())===(t=t.valueOf())||e!=e&&t!=t)return!0;if(!e||!t)return!1}return!("function"!=typeof e.equals||"function"!=typeof t.equals||!e.equals(t))}function Ne(n,e){if(n===e)return!0;if(!u(e)||void 0!==n.size&&void 0!==e.size&&n.size!==e.size||void 0!==n.__hash&&void 0!==e.__hash&&n.__hash!==e.__hash||c(n)!==c(e)||p(n)!==p(e)||B(n)!==B(e))return!1;if(0===n.size&&0===e.size)return!0;var r,o=!F(n);if(B(n))return r=n.entries(),e.every(function(e,t){var n=r.next().value;return n&&v(n[1],e)&&(o||v(n[0],t))})&&r.next().done;var s=!1,i=(void 0===n.size&&(void 0===e.size?"function"==typeof n.cacheResult&&n.cacheResult():(s=!0,t=n,n=e,e=t)),!0),t=e.__iterate(function(e,t){if(o?!n.has(e):s?!v(e,n.get(t,x)):!v(n.get(t,x),e))return i=!1});return i&&n.size===t}function s(e,t){if(!(this instanceof s))return new s(e,t);if(this._value=e,this.size=void 0===t?1/0:Math.max(0,t),0===this.size){if(fe)return fe;fe=this}}function Ie(e,t){if(!e)throw new Error(t)}function i(e,t,n){if(!(this instanceof i))return new i(e,t,n);if(Ie(0!==n,"Cannot step a Range by 0"),e=e||0,void 0===t&&(t=1/0),n=void 0===n?1:Math.abs(n),ts?m():f(t,e,r[e])})},ve.prototype[z]=!0,e(be,g),be.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);var n,r=le(this._iterable),o=0;if(ae(r))for(;!(n=r.next()).done&&!1!==e(n.value,o++,this););return o},be.prototype.__iteratorUncached=function(t,e){if(e)return this.cacheResult().__iterator(t,e);var n=le(this._iterable);if(!ae(n))return new d(m);var r=0;return new d(function(){var e=n.next();return e.done?e:f(t,r++,e.value)})},e(we,g),we.prototype.__iterateUncached=function(e,t){if(t)return this.cacheResult().__iterate(e,t);for(var n=this._iterator,r=this._iteratorCache,o=0;o=r.length){var e=n.next();if(e.done)return e;r[o]=e.value}return f(t,o,r[o++])})},e(s,g),s.prototype.toString=function(){return 0===this.size?"Repeat []":"Repeat [ "+this._value+" "+this.size+" times ]"},s.prototype.get=function(e,t){return this.has(e)?this._value:t},s.prototype.includes=function(e){return v(this._value,e)},s.prototype.slice=function(e,t){var n=this.size;return X(e,t,n)?this:new s(this._value,Z(t,n)-Q(e,n))},s.prototype.reverse=function(){return this},s.prototype.indexOf=function(e){return v(this._value,e)?0:-1},s.prototype.lastIndexOf=function(e){return v(this._value,e)?this.size:-1},s.prototype.__iterate=function(e,t){for(var n=0;n>>16)*r+n*(t>>>16)<<16>>>0)|0};function Be(e){return e>>>1&1073741824|3221225471&e}function _(e){if(!1===e||null==e)return 0;if("function"==typeof e.valueOf&&(!1===(e=e.valueOf())||null==e))return 0;if(!0===e)return 1;var t,n,r=typeof e;if("number"==r){if(e!=e||e===1/0)return 0;var o=0|e;for(o!==e&&(o^=4294967295*e);4294967295We?(void 0===(t=Ge[s=e])&&(t=Le(s),He===Je&&(He=0,Ge={}),He++,Ge[s]=t),t):Le(e);if("function"==typeof e.hashCode)return e.hashCode();if("object"==r){var s=e;if(Ue&&void 0!==(n=ze.get(s)))return n;if(void 0!==(n=s[Ke]))return n;if(!$e){if(void 0!==(n=s.propertyIsEnumerable&&s.propertyIsEnumerable[Ke]))return n;if(void 0!==(n=function(e){if(e&&0=n.length)throw new Error("Missing value for key: "+n[t]);e.set(n[t],n[t+1])}})},k.prototype.toString=function(){return this.__toString("Map {","}")},k.prototype.get=function(e,t){return this._root?this._root.get(0,void 0,e,t):t},k.prototype.set=function(e,t){return ct(this,e,t)},k.prototype.setIn=function(e,t){return this.updateIn(e,x,function(){return t})},k.prototype.remove=function(e){return ct(this,e,x)},k.prototype.deleteIn=function(e){return this.updateIn(e,function(){return x})},k.prototype.update=function(e,t,n){return 1===arguments.length?e(this):this.updateIn([e],t,n)},k.prototype.updateIn=function(e,t,n){n||(n=t,t=void 0);e=function e(t,n,r,o){var s=t===x,i=n.next();if(i.done)return(l=o(a=s?r:t))===a?t:l;Ie(s||t&&t.set,"invalid keyPath");var a=i.value,l=s?x:t.get(a,x),i=e(l,n,r,o);return i===l?t:i===x?t.remove(a):(s?lt():t).set(a,i)}(this,cn(e),t,n);return e===x?void 0:e},k.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=0,this._root=null,this.__hash=void 0,this.__altered=!0,this):lt()},k.prototype.merge=function(){return dt(this,void 0,arguments)},k.prototype.mergeWith=function(e){return dt(this,e,r.call(arguments,1))},k.prototype.mergeIn=function(e){var t=r.call(arguments,1);return this.updateIn(e,lt(),function(e){return"function"==typeof e.merge?e.merge.apply(e,t):t[t.length-1]})},k.prototype.mergeDeep=function(){return dt(this,ft,arguments)},k.prototype.mergeDeepWith=function(e){return dt(this,mt(e),r.call(arguments,1))},k.prototype.mergeDeepIn=function(e){var t=r.call(arguments,1);return this.updateIn(e,lt(),function(e){return"function"==typeof e.mergeDeep?e.mergeDeep.apply(e,t):t[t.length-1]})},k.prototype.sort=function(e){return j(Qt(this,e))},k.prototype.sortBy=function(e,t){return j(Qt(this,t,e))},k.prototype.withMutations=function(e){var t=this.asMutable();return e(t),t.wasAltered()?t.__ensureOwner(this.__ownerID):this},k.prototype.asMutable=function(){return this.__ownerID?this:this.__ensureOwner(new W)},k.prototype.asImmutable=function(){return this.__ensureOwner()},k.prototype.wasAltered=function(){return this.__altered},k.prototype.__iterator=function(e,t){return new ot(this,e,t)},k.prototype.__iterate=function(t,e){var n=this,r=0;return this._root&&this._root.iterate(function(e){return r++,t(e[1],e[0],n)},e),r},k.prototype.__ensureOwner=function(e){return e===this.__ownerID?this:e?at(this.size,this._root,e,this.__hash):(this.__ownerID=e,this.__altered=!1,this)},k.isMap=Ye;var Xe,Qe="@@__IMMUTABLE_MAP__@@",A=k.prototype;function Ze(e,t){this.ownerID=e,this.entries=t}function et(e,t,n){this.ownerID=e,this.bitmap=t,this.nodes=n}function tt(e,t,n){this.ownerID=e,this.count=t,this.nodes=n}function nt(e,t,n){this.ownerID=e,this.keyHash=t,this.entries=n}function rt(e,t,n){this.ownerID=e,this.keyHash=t,this.entry=n}function ot(e,t,n){this._type=t,this._reverse=n,this._stack=e._root&&it(e._root)}function st(e,t){return f(e,t[0],t[1])}function it(e,t){return{node:e,index:0,__prev:t}}function at(e,t,n,r){var o=Object.create(A);return o.size=e,o._root=t,o.__ownerID=n,o.__hash=r,o.__altered=!1,o}function lt(){return Xe=Xe||at(0)}function ct(e,t,n){if(e._root){var r=K(U),o=K(V),s=ut(e._root,e.__ownerID,0,void 0,t,n,r,o);if(!o.value)return e;o=e.size+(r.value?n===x?-1:1:0)}else{if(n===x)return e;o=1,s=new Ze(e.__ownerID,[[t,n]])}return e.__ownerID?(e.size=o,e._root=s,e.__hash=void 0,e.__altered=!0,e):s?at(o,s):lt()}function ut(e,t,n,r,o,s,i,a){return e?e.update(t,n,r,o,s,i,a):s===x?e:(y(a),y(i),new rt(t,r,[o,s]))}function pt(e){return e.constructor===rt||e.constructor===nt}function ht(e,t,n,r,o){if(e.keyHash===r)return new nt(t,r,[e.entry,o]);var s=(0===n?e.keyHash:e.keyHash>>>n)&S,i=(0===n?r:r>>>n)&S;return new et(t,1<>1&1431655765))+(e>>2&858993459))+(e>>4)&252645135,127&(e+=e>>8)+(e>>16)}function vt(e,t,n,r){r=r?e:J(e);return r[t]=n,r}A[Qe]=!0,A[t]=A.remove,A.removeIn=A.deleteIn,Ze.prototype.get=function(e,t,n,r){for(var o=this.entries,s=0,i=o.length;s=bt){for(var h=e,d=l,i=r,s=o,f=new rt(h=h||new W,_(i),[i,s]),m=0;m>>e)&S),s=this.bitmap;return 0==(s&o)?r:this.nodes[yt(s&o-1)].get(e+w,t,n,r)},et.prototype.update=function(e,t,n,r,o,s,i){void 0===n&&(n=_(r));var a=(0===t?n:n>>>t)&S,l=1<=wt){for(var n=e,f=h,m=c,r=a,o=t,g=0,y=new Array(E),v=0;0!==m;v++,m>>>=1)y[v]=1&m?f[g++]:void 0;return y[r]=o,new tt(n,g+1,y)}if(u&&!t&&2===h.length&&pt(h[1^p]))return h[1^p];if(u&&t&&1===h.length&&pt(t))return t;s=e&&e===this.ownerID,i=u?t?c:c^l:c|l,d=u?t?vt(h,p,t,s):function(e,t,n){var r=e.length-1;if(n&&t===r)return e.pop(),e;for(var o=new Array(r),s=0,i=0;i>>e)&S];return o?o.get(e+w,t,n,r):r},tt.prototype.update=function(e,t,n,r,o,s,i){void 0===n&&(n=_(r));var a=(0===t?n:n>>>t)&S,l=o===x,c=this.nodes,u=c[a];if(l&&!u)return this;l=ut(u,e,t+w,n,r,o,s,i);if(l===u)return this;t=this.count;if(u){if(!l&&--t=n.size||r<0)return n.withMutations(function(e){r<0?Rt(e,r).set(0,o):Rt(e,0,r+1).set(r,o)});r+=n._origin;var e=n._tail,t=n._root,s=K(V);return r>=Dt(n._capacity)?e=Nt(e,n.__ownerID,0,r,o,s):t=Nt(t,n.__ownerID,n._level,r,o,s),s.value?n.__ownerID?(n._root=t,n._tail=e,n.__hash=void 0,n.__altered=!0,n):jt(n._origin,n._capacity,n._level,t,e):n},O.prototype.remove=function(e){return this.has(e)?0===e?this.shift():e===this.size-1?this.pop():this.splice(e,1):this},O.prototype.insert=function(e,t){return this.splice(e,0,t)},O.prototype.clear=function(){return 0===this.size?this:this.__ownerID?(this.size=this._origin=this._capacity=0,this._level=w,this._root=this._tail=null,this.__hash=void 0,this.__altered=!0,this):Pt()},O.prototype.push=function(){var n=arguments,r=this.size;return this.withMutations(function(e){Rt(e,0,r+n.length);for(var t=0;t>>t&S;if(r>=this.array.length)return new _t([],e);var o,s=0==r;if(0>>t&S;if(o>=this.array.length)return this;if(0>r,E<(l=1+(g-o>>r))&&(l=E),function(){for(;;){if(s){var e=s();if(e!==Ot)return e;s=null}if(a===l)return Ot;e=f?--l:a++;s=b(i&&i[e],r-w,o+(e<>>n&S,c=e&&l=Dt(e._capacity))return e._tail;if(t<1<>>r&S],r-=w;return n}}function Rt(e,t,n){void 0!==t&&(t|=0),void 0!==n&&(n|=0);var r=e.__ownerID||new W,o=e._origin,s=e._capacity,i=o+t,t=void 0===n?s:n<0?s+n:o+n;if(i===o&&t===s)return e;if(t<=i)return e.clear();for(var a=e._level,l=e._root,c=0;i+c<0;)l=new _t(l&&l.array.length?[void 0,l]:[],r),c+=1<<(a+=w);c&&(i+=c,o+=c,t+=c,s+=c);for(var u=Dt(s),p=Dt(t);1<>>f&S,d=d.array[m]=It(d.array[m],r);d.array[u>>>w&S]=n}if(t>>a&S;if(g!=p>>>a&S)break;g&&(c+=(1<o&&(o=a.size),u(i)||(a=a.map(function(e){return Ce(e)})),r.push(a)}return gt(e=o>e.size?e.setSize(o):e,t,r)}function Dt(e){return e>>w<=E&&i.size>=2*s.size?(r=(o=i.filter(function(e,t){return void 0!==e&&a!==t})).toKeyedSeq().map(function(e){return e[0]}).flip().toMap(),e.__ownerID&&(r.__ownerID=o.__ownerID=e.__ownerID)):(r=s.remove(t),o=a===i.size-1?i.pop():i.set(a,void 0))}else if(l){if(n===i.get(a)[1])return e;r=s,o=i.set(a,[t,n])}else r=s.set(t,i.size),o=i.set(i.size,[t,n]);return e.__ownerID?(e.size=r.size,e._map=r,e._list=o,e.__hash=void 0,e):Bt(r,o)}function $t(e,t){this._iter=e,this._useKeys=t,this.size=e.size}function zt(e){this._iter=e,this.size=e.size}function Ut(e){this._iter=e,this.size=e.size}function Vt(e){this._iter=e,this.size=e.size}function Kt(o){var e=sn(o);return e._iter=o,e.size=o.size,e.flip=function(){return o},e.reverse=function(){var e=o.reverse.apply(this);return e.flip=function(){return o.reverse()},e},e.has=function(e){return o.includes(e)},e.includes=function(e){return o.has(e)},e.cacheResult=an,e.__iterateUncached=function(n,e){var r=this;return o.__iterate(function(e,t){return!1!==n(t,e,r)},e)},e.__iteratorUncached=function(e,t){var n;return e===ne?(n=o.__iterator(e,t),new d(function(){var e,t=n.next();return t.done||(e=t.value[0],t.value[0]=t.value[1],t.value[1]=e),t})):o.__iterator(e===h?te:h,t)},e}function Wt(s,i,a){var e=sn(s);return e.size=s.size,e.has=function(e){return s.has(e)},e.get=function(e,t){var n=s.get(e,x);return n===x?t:i.call(a,n,e,s)},e.__iterateUncached=function(r,e){var o=this;return s.__iterate(function(e,t,n){return!1!==r(i.call(a,e,t,n),t,o)},e)},e.__iteratorUncached=function(r,e){var o=s.__iterator(ne,e);return new d(function(){var e=o.next();if(e.done)return e;var t=e.value,n=t[0];return f(r,n,i.call(a,t[1],n,s),e)})},e}function Jt(o,n){var e=sn(o);return e._iter=o,e.size=o.size,e.reverse=function(){return o},o.flip&&(e.flip=function(){var e=Kt(o);return e.reverse=function(){return o.flip()},e}),e.get=function(e,t){return o.get(n?e:-1-e,t)},e.has=function(e){return o.has(n?e:-1-e)},e.includes=function(e){return o.includes(e)},e.cacheResult=an,e.__iterate=function(n,e){var r=this;return o.__iterate(function(e,t){return n(e,t,r)},!e)},e.__iterator=function(e,t){return o.__iterator(e,!t)},e}function Ht(i,a,l,c){var e=sn(i);return c&&(e.has=function(e){var t=i.get(e,x);return t!==x&&!!a.call(l,t,e,i)},e.get=function(e,t){var n=i.get(e,x);return n!==x&&a.call(l,n,e,i)?n:t}),e.__iterateUncached=function(r,e){var o=this,s=0;return i.__iterate(function(e,t,n){if(a.call(l,e,t,n))return s++,r(e,c?t:s-1,o)},e),s},e.__iteratorUncached=function(r,e){var o=i.__iterator(ne,e),s=0;return new d(function(){for(;;){var e=o.next();if(e.done)return e;var t=e.value,n=t[0],t=t[1];if(a.call(l,t,n,i))return f(r,c?n:s++,t,e)}})},e}function Gt(a,e,t,l){var n=a.size;if(void 0!==e&&(e|=0),void 0!==t&&(t===1/0?t=n:t|=0),X(e,t,n))return a;var c=Q(e,n),n=Z(t,n);if(c!=c||n!=n)return Gt(a.toSeq().cacheResult(),e,t,l);var u,e=n-c,t=(e==e&&(u=e<0?0:e),sn(a));return t.size=0===u?u:a.size&&u||void 0,!l&&Ee(a)&&0<=u&&(t.get=function(e,t){return 0<=(e=G(this,e))&&eu)return m();var e=n.next();return l||t===h?e:f(t,o-1,t===te?void 0:e.value[1],e)})},t}function Yt(t,c,u,p){var e=sn(t);return e.__iterateUncached=function(r,e){var o=this;if(e)return this.cacheResult().__iterate(r,e);var s=!0,i=0;return t.__iterate(function(e,t,n){if(!s||!(s=c.call(u,e,t,n)))return i++,r(e,p?t:i-1,o)}),i},e.__iteratorUncached=function(o,e){var s=this;if(e)return this.cacheResult().__iterator(o,e);var i=t.__iterator(ne,e),a=!0,l=0;return new d(function(){var e;do{if((e=i.next()).done)return p||o===h?e:f(o,l++,o===te?void 0:e.value[1],e);var t=e.value,n=t[0],r=t[1]}while(a=a&&c.call(u,r,n,s));return o===ne?e:f(o,n,r,e)})},e}function Xt(e,l,c){var t=sn(e);return t.__iterateUncached=function(s,t){var i=0,a=!1;return function n(e,r){var o=this;e.__iterate(function(e,t){return(!l||r>>-15,461845907),t=Fe(t<<13|t>>>-13,5),t=Fe((t=(t+3864292196|0)^e)^t>>>16,2246822507),t=Be((t=Fe(t^t>>>13,3266489909))^t>>>16)}(e.__iterate(n?t?function(e,t){r=31*r+Ln(_(e),_(t))|0}:function(e,t){r=r+Ln(_(e),_(t))|0}:t?function(e){r=31*r+_(e)|0}:function(e){r=r+_(e)|0}),r)}(this))}});var t=l.prototype,Nn=(t[L]=!0,t[se]=t.values,t.__toJS=t.toArray,t.__toStringMapper=Dn,t.inspect=t.toSource=function(){return this.toString()},t.chain=t.flatMap,t.contains=t.includes,Pn(a,{flip:function(){return P(this,Kt(this))},mapEntries:function(n,r){var o=this,s=0;return P(this,this.toSeq().map(function(e,t){return n.call(r,[t,e],s++,o)}).fromEntrySeq())},mapKeys:function(n,r){var o=this;return P(this,this.toSeq().flip().map(function(e,t){return n.call(r,e,t,o)}).flip())}}),a.prototype);function In(e,t){return t}function Tn(e,t){return[t,e]}function Rn(e){return function(){return!e.apply(this,arguments)}}function Mn(e){return function(){return-e.apply(this,arguments)}}function Dn(e){return"string"==typeof e?JSON.stringify(e):String(e)}function Fn(){return J(arguments)}function Bn(e,t){return e>2)|0}return Nn[q]=!0,Nn[se]=t.entries,Nn.__toJS=t.toObject,Nn.__toStringMapper=function(e,t){return JSON.stringify(t)+": "+Dn(e)},Pn(D,{toKeyedSeq:function(){return new $t(this,!1)},filter:function(e,t){return P(this,Ht(this,e,t,!1))},findIndex:function(e,t){e=this.findEntry(e,t);return e?e[0]:-1},indexOf:function(e){e=this.keyOf(e);return void 0===e?-1:e},lastIndexOf:function(e){e=this.lastKeyOf(e);return void 0===e?-1:e},reverse:function(){return P(this,Jt(this,!1))},slice:function(e,t){return P(this,Gt(this,e,t,!1))},splice:function(e,t){var n=arguments.length;if(t=Math.max(0|t,0),0===n||2===n&&!t)return this;e=Q(e,e<0?this.count():this.size);var r=this.slice(0,e);return P(this,1===n?r:r.concat(J(arguments,2),this.slice(e+t)))},findLastIndex:function(e,t){e=this.findLastEntry(e,t);return e?e[0]:-1},first:function(){return this.get(0)},flatten:function(e){return P(this,Xt(this,e,!1))},get:function(n,e){return(n=G(this,n))<0||this.size===1/0||void 0!==this.size&&n>this.size?e:this.find(function(e,t){return t===n},void 0,e)},has:function(e){return 0<=(e=G(this,e))&&(void 0!==this.size?this.size===1/0||e{"function"==typeof Object.create?e.exports=function(e,t){t&&(e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}))}:e.exports=function(e,t){var n;t&&(e.super_=t,(n=function(){}).prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e)}},5419:e=>{e.exports=function(e,t,n,r){var o,s,r=new Blob(void 0!==r?[r,e]:[e],{type:n||"application/octet-stream"});void 0!==window.navigator.msSaveBlob?window.navigator.msSaveBlob(r,t):(o=(window.URL&&window.URL.createObjectURL?window.URL:window.webkitURL).createObjectURL(r),(s=document.createElement("a")).style.display="none",s.href=o,s.setAttribute("download",t),void 0===s.download&&s.setAttribute("target","_blank"),document.body.appendChild(s),s.click(),setTimeout(function(){document.body.removeChild(s),window.URL.revokeObjectURL(o)},200))}},20181:(e,t,n)=>{function v(){return c.Date.now()}var r=/^\s+|\s+$/g,o=/^[-+]0x[0-9a-f]+$/i,s=/^0b[01]+$/i,i=/^0o[0-7]+$/i,a=parseInt,n="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g,l="object"==typeof self&&self&&self.Object===Object&&self,c=n||l||Function("return this")(),u=Object.prototype.toString,b=Math.max,w=Math.min;function E(e){var t=typeof e;return e&&("object"==t||"function"==t)}function S(e){if("number"==typeof e)return e;if("symbol"==typeof(n=e)||(t=n)&&"object"==typeof t&&"[object Symbol]"==u.call(n))return NaN;var t;if("string"!=typeof(e=E(e)?E(t="function"==typeof e.valueOf?e.valueOf():e)?t+"":t:e))return 0===e?e:+e;e=e.replace(r,"");var n=s.test(e);return n||i.test(e)?a(e.slice(2),n?2:8):o.test(e)?NaN:+e}e.exports=function(r,n,e){var o,s,i,a,l,c,u=0,p=!1,h=!1,t=!0;if("function"!=typeof r)throw new TypeError("Expected a function");function d(e){var t=o,n=s;return o=s=void 0,u=e,a=r.apply(n,t)}function f(e){var t=e-c;return void 0===c||n<=t||t<0||h&&i<=e-u}function m(){var e,t=v();if(f(t))return g(t);l=setTimeout(m,(e=n-((t=t)-c),h?w(e,i-(t-u)):e))}function g(e){return l=void 0,t&&o?d(e):(o=s=void 0,a)}function y(){var e=v(),t=f(e);if(o=arguments,s=this,c=e,t){if(void 0===l)return u=e=c,l=setTimeout(m,n),p?d(e):a;if(h)return l=setTimeout(m,n),d(c)}return void 0===l&&(l=setTimeout(m,n)),a}return n=S(n)||0,E(e)&&(p=!!e.leading,i=(h="maxWait"in e)?b(S(e.maxWait)||0,n):i,t="trailing"in e?!!e.trailing:t),y.cancel=function(){void 0!==l&&clearTimeout(l),o=c=s=l=void(u=0)},y.flush=function(){return void 0===l?a:g(v())},y}},55580:(e,t,n)=>{n=n(56110)(n(9325),"DataView");e.exports=n},21549:(e,t,n)=>{var r=n(22032),o=n(63862),s=n(66721),i=n(12749),n=n(35749);function a(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{var r=n(39344),n=n(94033);function o(e){this.__wrapped__=e,this.__actions__=[],this.__dir__=1,this.__filtered__=!1,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}o.prototype=r(n.prototype),e.exports=o.prototype.constructor=o},80079:(e,t,n)=>{var r=n(63702),o=n(70080),s=n(24739),i=n(48655),n=n(31175);function a(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{var r=n(39344),n=n(94033);function o(e,t){this.__wrapped__=e,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=void 0}o.prototype=r(n.prototype),e.exports=o.prototype.constructor=o},68223:(e,t,n)=>{n=n(56110)(n(9325),"Map");e.exports=n},53661:(e,t,n)=>{var r=n(63040),o=n(17670),s=n(90289),i=n(4509),n=n(72949);function a(e){var t=-1,n=null==e?0:e.length;for(this.clear();++t{n=n(56110)(n(9325),"Promise");e.exports=n},76545:(e,t,n)=>{n=n(56110)(n(9325),"Set");e.exports=n},38859:(e,t,n)=>{var r=n(53661),o=n(31380),n=n(51459);function s(e){var t=-1,n=null==e?0:e.length;for(this.__data__=new r;++t{var r=n(80079),o=n(51420),s=n(90938),i=n(63605),a=n(29817),n=n(80945);function l(e){e=this.__data__=new r(e);this.size=e.size}l.prototype.clear=o,l.prototype.delete=s,l.prototype.get=i,l.prototype.has=a,l.prototype.set=n,e.exports=l},51873:(e,t,n)=>{n=n(9325).Symbol;e.exports=n},37828:(e,t,n)=>{n=n(9325).Uint8Array;e.exports=n},28303:(e,t,n)=>{n=n(56110)(n(9325),"WeakMap");e.exports=n},91033:e=>{e.exports=function(e,t,n){switch(n.length){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}},83729:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=0,s=[];++n{var r=n(96131);e.exports=function(e,t){return!(null==e||!e.length)&&-1{var u=n(78096),p=n(72428),h=n(56449),d=n(3656),f=n(30361),m=n(37167),g=Object.prototype.hasOwnProperty;e.exports=function(e,t){var n,r=h(e),o=!r&&p(e),s=!r&&!o&&d(e),i=!r&&!o&&!s&&m(e),a=r||o||s||i,l=a?u(e.length,String):[],c=l.length;for(n in e)!t&&!g.call(e,n)||a&&("length"==n||s&&("offset"==n||"parent"==n)||i&&("buffer"==n||"byteLength"==n||"byteOffset"==n)||f(n,c))||l.push(n);return l}},34932:e=>{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length,o=Array(r);++n{e.exports=function(e,t){for(var n=-1,r=t.length,o=e.length;++n{e.exports=function(e,t,n,r){var o=-1,s=null==e?0:e.length;for(r&&s&&(n=e[++o]);++o{e.exports=function(e,t){for(var n=-1,r=null==e?0:e.length;++n{e.exports=function(e){return e.split("")}},1733:e=>{var t=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g;e.exports=function(e){return e.match(t)||[]}},87805:(e,t,n)=>{var r=n(43360),o=n(75288);e.exports=function(e,t,n){(void 0===n||o(e[t],n))&&(void 0!==n||t in e)||r(e,t,n)}},16547:(e,t,n)=>{var o=n(43360),s=n(75288),i=Object.prototype.hasOwnProperty;e.exports=function(e,t,n){var r=e[t];i.call(e,t)&&s(r,n)&&(void 0!==n||t in e)||o(e,t,n)}},26025:(e,t,n)=>{var r=n(75288);e.exports=function(e,t){for(var n=e.length;n--;)if(r(e[n][0],t))return n;return-1}},74733:(e,t,n)=>{var r=n(21791),o=n(95950);e.exports=function(e,t){return e&&r(t,o(t),e)}},43838:(e,t,n)=>{var r=n(21791),o=n(37241);e.exports=function(e,t){return e&&r(t,o(t),e)}},43360:(e,t,n)=>{var r=n(93243);e.exports=function(e,t,n){"__proto__"==t&&r?r(e,t,{configurable:!0,enumerable:!0,value:n,writable:!0}):e[t]=n}},9999:(e,t,n)=>{var f=n(37217),m=n(83729),g=n(16547),y=n(74733),v=n(43838),b=n(93290),w=n(23007),E=n(92271),S=n(48948),x=n(50002),_=n(83349),k=n(5861),A=n(76189),O=n(77199),C=n(35529),j=n(56449),P=n(3656),N=n(87730),I=n(23805),T=n(38440),R=n(95950),M=n(37241),D="[object Arguments]",F="[object Function]",B="[object Object]",L={};L[D]=L["[object Array]"]=L["[object ArrayBuffer]"]=L["[object DataView]"]=L["[object Boolean]"]=L["[object Date]"]=L["[object Float32Array]"]=L["[object Float64Array]"]=L["[object Int8Array]"]=L["[object Int16Array]"]=L["[object Int32Array]"]=L["[object Map]"]=L["[object Number]"]=L[B]=L["[object RegExp]"]=L["[object Set]"]=L["[object String]"]=L["[object Symbol]"]=L["[object Uint8Array]"]=L["[object Uint8ClampedArray]"]=L["[object Uint16Array]"]=L["[object Uint32Array]"]=!0,L["[object Error]"]=L[F]=L["[object WeakMap]"]=!1,e.exports=function n(r,o,s,e,t,i){var a,l=1&o,c=2&o,u=4&o;if(void 0!==(a=s?t?s(r,e,t,i):s(r):a))return a;if(!I(r))return r;e=j(r);if(e){if(a=A(r),!l)return w(r,a)}else{var p=k(r),h=p==F||"[object GeneratorFunction]"==p;if(P(r))return b(r,l);if(p==B||p==D||h&&!t){if(a=c||h?{}:C(r),!l)return c?S(r,v(a,r)):E(r,y(a,r))}else{if(!L[p])return t?r:{};a=O(r,p,l)}}h=(i=i||new f).get(r);if(h)return h;i.set(r,a),T(r)?r.forEach(function(e){a.add(n(e,o,s,e,r,i))}):N(r)&&r.forEach(function(e,t){a.set(t,n(e,o,s,t,r,i))});var d=e?void 0:(u?c?_:x:c?M:R)(r);return m(d||r,function(e,t){d&&(e=r[t=e]),g(a,t,n(e,o,s,t,r,i))}),a}},39344:(e,t,n)=>{var r=n(23805),o=Object.create;function s(){}e.exports=function(e){if(!r(e))return{};if(o)return o(e);s.prototype=e;e=new s;return s.prototype=void 0,e}},80909:(e,t,n)=>{var r=n(30641),n=n(38329)(r);e.exports=n},2523:e=>{e.exports=function(e,t,n,r){for(var o=e.length,s=n+(r?1:-1);r?s--:++s{var c=n(14528),u=n(45891);e.exports=function e(t,n,r,o,s){var i=-1,a=t.length;for(r=r||u,s=s||[];++i{n=n(83221)();e.exports=n},30641:(e,t,n)=>{var r=n(86649),o=n(95950);e.exports=function(e,t){return e&&r(e,t,o)}},47422:(e,t,n)=>{var o=n(31769),s=n(77797);e.exports=function(e,t){for(var n=0,r=(t=o(t,e)).length;null!=e&&n{var r=n(14528),o=n(56449);e.exports=function(e,t,n){t=t(e);return o(e)?t:r(t,n(e))}},72552:(e,t,n)=>{var r=n(51873),o=n(659),s=n(59350),i=r?r.toStringTag:void 0;e.exports=function(e){return null==e?void 0===e?"[object Undefined]":"[object Null]":(i&&i in Object(e)?o:s)(e)}},28077:e=>{e.exports=function(e,t){return null!=e&&t in Object(e)}},96131:(e,t,n)=>{var r=n(2523),o=n(85463),s=n(76959);e.exports=function(e,t,n){return t==t?s(e,t,n):r(e,o,n)}},27534:(e,t,n)=>{var r=n(72552),o=n(40346);e.exports=function(e){return o(e)&&"[object Arguments]"==r(e)}},60270:(e,t,n)=>{var i=n(87068),a=n(40346);e.exports=function e(t,n,r,o,s){return t===n||(null==t||null==n||!a(t)&&!a(n)?t!=t&&n!=n:i(t,n,r,o,e,s))}},87068:(e,t,n)=>{var p=n(37217),h=n(25911),d=n(21986),f=n(50689),m=n(5861),g=n(56449),y=n(3656),v=n(37167),b="[object Arguments]",w="[object Array]",E="[object Object]",S=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,r,o,s){var i=g(e),a=g(t),l=i?w:m(e),a=a?w:m(t),c=(l=l==b?E:l)==E,u=(a=a==b?E:a)==E,a=l==a;if(a&&y(e)){if(!y(t))return!1;c=!(i=!0)}if(a&&!c)return s=s||new p,i||v(e)?h(e,t,n,r,o,s):d(e,t,l,n,r,o,s);if(!(1&n)){i=c&&S.call(e,"__wrapped__"),l=u&&S.call(t,"__wrapped__");if(i||l)return o(i?e.value():e,l?t.value():t,n,r,s=s||new p)}return!!a&&(s=s||new p,f(e,t,n,r,o,s))}},29172:(e,t,n)=>{var r=n(5861),o=n(40346);e.exports=function(e){return o(e)&&"[object Map]"==r(e)}},41799:(e,t,n)=>{var d=n(37217),f=n(60270);e.exports=function(e,t,n,r){var o=n.length,s=o,i=!r;if(null==e)return!s;for(e=Object(e);o--;){var a=n[o];if(i&&a[2]?a[1]!==e[a[0]]:!(a[0]in e))return!1}for(;++o{e.exports=function(e){return e!=e}},45083:(e,t,n)=>{var r=n(1882),o=n(87296),s=n(23805),i=n(47473),a=/^\[object .+?Constructor\]$/,n=Function.prototype,l=Object.prototype,n=n.toString,l=l.hasOwnProperty,c=RegExp("^"+n.call(l).replace(/[\\^$.*+?()[\]{}|]/g,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$");e.exports=function(e){return!(!s(e)||o(e))&&(r(e)?c:a).test(i(e))}},16038:(e,t,n)=>{var r=n(5861),o=n(40346);e.exports=function(e){return o(e)&&"[object Set]"==r(e)}},4901:(e,t,n)=>{var r=n(72552),o=n(30294),s=n(40346),i={};i["[object Float32Array]"]=i["[object Float64Array]"]=i["[object Int8Array]"]=i["[object Int16Array]"]=i["[object Int32Array]"]=i["[object Uint8Array]"]=i["[object Uint8ClampedArray]"]=i["[object Uint16Array]"]=i["[object Uint32Array]"]=!0,i["[object Arguments]"]=i["[object Array]"]=i["[object ArrayBuffer]"]=i["[object Boolean]"]=i["[object DataView]"]=i["[object Date]"]=i["[object Error]"]=i["[object Function]"]=i["[object Map]"]=i["[object Number]"]=i["[object Object]"]=i["[object RegExp]"]=i["[object Set]"]=i["[object String]"]=i["[object WeakMap]"]=!1,e.exports=function(e){return s(e)&&o(e.length)&&!!i[r(e)]}},15389:(e,t,n)=>{var r=n(93663),o=n(87978),s=n(83488),i=n(56449),a=n(50583);e.exports=function(e){return"function"==typeof e?e:null==e?s:"object"==typeof e?i(e)?o(e[0],e[1]):r(e):a(e)}},88984:(e,t,n)=>{var r=n(55527),o=n(3650),s=Object.prototype.hasOwnProperty;e.exports=function(e){if(!r(e))return o(e);var t,n=[];for(t in Object(e))s.call(e,t)&&"constructor"!=t&&n.push(t);return n}},72903:(e,t,n)=>{var o=n(23805),s=n(55527),i=n(90181),a=Object.prototype.hasOwnProperty;e.exports=function(e){if(!o(e))return i(e);var t,n=s(e),r=[];for(t in e)("constructor"!=t||!n&&a.call(e,t))&&r.push(t);return r}},94033:e=>{e.exports=function(){}},93663:(e,t,n)=>{var r=n(41799),o=n(10776),s=n(67197);e.exports=function(t){var n=o(t);return 1==n.length&&n[0][2]?s(n[0][0],n[0][1]):function(e){return e===t||r(e,t,n)}}},87978:(e,t,n)=>{var o=n(60270),s=n(58156),i=n(80631),a=n(28586),l=n(30756),c=n(67197),u=n(77797);e.exports=function(n,r){return a(n)&&l(r)?c(u(n),r):function(e){var t=s(e,n);return void 0===t&&t===r?i(e,n):o(r,t,3)}}},85250:(e,t,n)=>{var c=n(37217),u=n(87805),p=n(86649),h=n(42824),d=n(23805),f=n(37241),m=n(14974);e.exports=function r(o,s,i,a,l){o!==s&&p(s,function(e,t){var n;l=l||new c,d(e)?h(o,s,t,i,r,a,l):(n=a?a(m(o,t),e,t+"",o,s,l):void 0,u(o,t,n=void 0===n?e:n))},f)}},42824:(e,t,n)=>{var d=n(87805),f=n(93290),m=n(71961),g=n(23007),y=n(35529),v=n(72428),b=n(56449),w=n(83693),E=n(3656),S=n(1882),x=n(23805),_=n(11331),k=n(37167),A=n(14974),O=n(69884);e.exports=function(e,t,n,r,o,s,i){var a,l,c,u=A(e,n),p=A(t,n),h=i.get(p);h?d(e,n,h):((t=void 0===(h=s?s(u,p,n+"",e,t,i):void 0))&&(l=!(a=b(p))&&E(p),c=!a&&!l&&k(p),h=p,a||l||c?h=b(u)?u:w(u)?g(u):l?f(p,!(t=!1)):c?m(p,!(t=!1)):[]:_(p)||v(p)?v(h=u)?h=O(u):x(u)&&!S(u)||(h=y(p)):t=!1),t&&(i.set(p,h),o(h,p,r,s,i),i.delete(p)),d(e,n,h))}},47237:e=>{e.exports=function(t){return function(e){return null==e?void 0:e[t]}}},17255:(e,t,n)=>{var r=n(47422);e.exports=function(t){return function(e){return r(e,t)}}},54552:e=>{e.exports=function(t){return function(e){return null==t?void 0:t[e]}}},85558:e=>{e.exports=function(e,r,o,s,t){return t(e,function(e,t,n){o=s?(s=!1,e):r(o,e,t,n)}),o}},69302:(e,t,n)=>{var r=n(83488),o=n(56757),s=n(32865);e.exports=function(e,t){return s(o(e,t,r),e+"")}},73170:(e,t,n)=>{var p=n(16547),h=n(31769),d=n(30361),f=n(23805),m=n(77797);e.exports=function(e,t,n,r){if(!f(e))return e;for(var o=-1,s=(t=h(t,e)).length,i=s-1,a=e;null!=a&&++o{var r=n(83488),o=n(48152);e.exports=o?function(e,t){return o.set(e,t),e}:r},19570:(e,t,n)=>{var r=n(37334),o=n(93243),n=n(83488);e.exports=o?function(e,t){return o(e,"toString",{configurable:!0,enumerable:!1,value:r(t),writable:!0})}:n},25160:e=>{e.exports=function(e,t,n){var r=-1,o=e.length;(n=o>>0,t>>>=0;for(var s=Array(o);++r{var s=n(80909);e.exports=function(e,r){var o;return s(e,function(e,t,n){return!(o=r(e,t,n))}),!!o}},78096:e=>{e.exports=function(e,t){for(var n=-1,r=Array(e);++n{var r=n(51873),o=n(34932),s=n(56449),i=n(44394),n=r?r.prototype:void 0,a=n?n.toString:void 0;e.exports=function e(t){if("string"==typeof t)return t;if(s(t))return o(t,e)+"";if(i(t))return a?a.call(t):"";var n=t+"";return"0"==n&&1/t==-1/0?"-0":n}},54128:(e,t,n)=>{var r=n(31800),o=/^\s+/;e.exports=function(e){return e&&e.slice(0,r(e)+1).replace(o,"")}},27301:e=>{e.exports=function(t){return function(e){return t(e)}}},19931:(e,t,n)=>{var r=n(31769),o=n(68090),s=n(68969),i=n(77797);e.exports=function(e,t){return t=r(t,e),null==(e=s(e,t))||delete e[i(o(t))]}},51234:e=>{e.exports=function(e,t,n){for(var r=-1,o=e.length,s=t.length,i={};++r{e.exports=function(e,t){return e.has(t)}},31769:(e,t,n)=>{var r=n(56449),o=n(28586),s=n(61802),i=n(13222);e.exports=function(e,t){return r(e)?e:o(e,t)?[e]:s(i(e))}},28754:(e,t,n)=>{var o=n(25160);e.exports=function(e,t,n){var r=e.length;return n=void 0===n?r:n,!t&&r<=n?e:o(e,t,n)}},49653:(e,t,n)=>{var r=n(37828);e.exports=function(e){var t=new e.constructor(e.byteLength);return new r(t).set(new r(e)),t}},93290:(e,t,n)=>{e=n.nmd(e);var n=n(9325),t=t&&!t.nodeType&&t,r=t&&e&&!e.nodeType&&e,r=r&&r.exports===t?n.Buffer:void 0,o=r?r.allocUnsafe:void 0;e.exports=function(e,t){if(t)return e.slice();t=e.length,t=o?o(t):new e.constructor(t);return e.copy(t),t}},76169:(e,t,n)=>{var r=n(49653);e.exports=function(e,t){t=t?r(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.byteLength)}},73201:e=>{var n=/\w*$/;e.exports=function(e){var t=new e.constructor(e.source,n.exec(e));return t.lastIndex=e.lastIndex,t}},93736:(e,t,n)=>{var n=n(51873),n=n?n.prototype:void 0,r=n?n.valueOf:void 0;e.exports=function(e){return r?Object(r.call(e)):{}}},71961:(e,t,n)=>{var r=n(49653);e.exports=function(e,t){t=t?r(e.buffer):e.buffer;return new e.constructor(t,e.byteOffset,e.length)}},91596:e=>{var h=Math.max;e.exports=function(e,t,n,r){for(var o=-1,s=e.length,i=n.length,a=-1,l=t.length,c=h(s-i,0),u=Array(l+c),p=!r;++a{var f=Math.max;e.exports=function(e,t,n,r){for(var o=-1,s=e.length,i=-1,a=n.length,l=-1,c=t.length,u=f(s-a,0),p=Array(u+c),h=!r;++o{e.exports=function(e,t){var n=-1,r=e.length;for(t=t||Array(r);++n{var c=n(16547),u=n(43360);e.exports=function(e,t,n,r){var o=!n;n=n||{};for(var s=-1,i=t.length;++s{var r=n(21791),o=n(4664);e.exports=function(e,t){return r(e,o(e),t)}},48948:(e,t,n)=>{var r=n(21791),o=n(86375);e.exports=function(e,t){return r(e,o(e),t)}},55481:(e,t,n)=>{n=n(9325)["__core-js_shared__"];e.exports=n},58523:e=>{e.exports=function(e,t){for(var n=e.length,r=0;n--;)e[n]===t&&++r;return r}},20999:(e,t,n)=>{var r=n(69302),l=n(36800);e.exports=function(a){return r(function(e,t){var n=-1,r=t.length,o=1{var a=n(64894);e.exports=function(s,i){return function(e,t){if(null==e)return e;if(!a(e))return s(e,t);for(var n=e.length,r=i?n:-1,o=Object(e);(i?r--:++r{e.exports=function(l){return function(e,t,n){for(var r=-1,o=Object(e),s=n(e),i=s.length;i--;){var a=s[l?i:++r];if(!1===t(o[a],a,o))break}return e}}},11842:(e,t,n)=>{var s=n(82819),i=n(9325);e.exports=function(t,e,n){var r=1&e,o=s(t);return function e(){return(this&&this!==i&&this instanceof e?o:t).apply(r?n:this,arguments)}}},12507:(e,t,n)=>{var o=n(28754),s=n(49698),i=n(63912),a=n(13222);e.exports=function(r){return function(e){e=a(e);var t=s(e)?i(e):void 0,n=t?t[0]:e.charAt(0),t=t?o(t,1).join(""):e.slice(1);return n[r]()+t}}},45539:(e,t,n)=>{var r=n(40882),o=n(50828),s=n(66645),i=RegExp("['’]","g");e.exports=function(t){return function(e){return r(s(o(e).replace(i,"")),t,"")}}},82819:(e,t,n)=>{var o=n(39344),s=n(23805);e.exports=function(r){return function(){var e=arguments;switch(e.length){case 0:return new r;case 1:return new r(e[0]);case 2:return new r(e[0],e[1]);case 3:return new r(e[0],e[1],e[2]);case 4:return new r(e[0],e[1],e[2],e[3]);case 5:return new r(e[0],e[1],e[2],e[3],e[4]);case 6:return new r(e[0],e[1],e[2],e[3],e[4],e[5]);case 7:return new r(e[0],e[1],e[2],e[3],e[4],e[5],e[6])}var t=o(r.prototype),n=r.apply(t,e);return s(n)?n:t}}},77078:(e,t,n)=>{var c=n(91033),r=n(82819),u=n(37471),p=n(18073),h=n(11287),d=n(36306),f=n(9325);e.exports=function(s,i,a){var l=r(s);return function e(){for(var t=arguments.length,n=Array(t),r=t,o=h(e);r--;)n[r]=arguments[r];o=t<3&&n[0]!==o&&n[t-1]!==o?[]:d(n,o);return(t-=o.length){var i=n(15389),a=n(64894),l=n(95950);e.exports=function(s){return function(e,t,n){var r,o=Object(e),t=(a(e)||(r=i(t,3),e=l(e),t=function(e){return r(o[e],e,o)}),s(e,t,n));return-1{var x=n(91596),_=n(53320),k=n(58523),A=n(82819),O=n(18073),C=n(11287),j=n(68294),P=n(36306),N=n(9325);e.exports=function i(a,l,c,u,p,h,d,f,m,g){var y=128&l,v=1&l,b=2&l,w=24&l,E=512&l,S=b?void 0:A(a);return function e(){for(var t=arguments.length,n=Array(t),r=t;r--;)n[r]=arguments[r];if(w&&(o=C(e),s=k(n,o)),u&&(n=x(n,u,p,w)),h&&(n=_(n,h,d,w)),t-=s,w&&t{var h=n(91033),r=n(82819),d=n(9325);e.exports=function(a,e,l,c){var u=1&e,p=r(a);return function e(){for(var t=-1,n=arguments.length,r=-1,o=c.length,s=Array(o+n),i=this&&this!==d&&this instanceof e?p:a;++r{var p=n(85087),h=n(54641),d=n(70981);e.exports=function(e,t,n,r,o,s,i,a,l,c){var u=8&t,o=(4&(t=(t|(u?32:64))&~(u?64:32))||(t&=-4),[e,t,o,u?s:void 0,u?i:void 0,u?void 0:s,u?void 0:i,a,l,c]),s=n.apply(void 0,o);return p(e)&&h(s,o),s.placeholder=r,d(s,e,t)}},66977:(e,t,n)=>{var d=n(68882),f=n(11842),m=n(77078),g=n(37471),y=n(24168),v=n(37381),b=n(3209),w=n(54641),E=n(70981),S=n(61489),x=Math.max;e.exports=function(e,t,n,r,o,s,i,a){var l=2&t;if(!l&&"function"!=typeof e)throw new TypeError("Expected a function");var c,u=r?r.length:0,p=(u||(t&=-97,r=o=void 0),i=void 0===i?i:x(S(i),0),a=void 0===a?a:S(a),u-=o?o.length:0,64&t&&(h=r,c=o,r=o=void 0),l?void 0:v(e)),h=[e,t,n,r,o,h,c,s,i,a];return p&&b(h,p),e=h[0],t=h[1],n=h[2],r=h[3],o=h[4],!(a=h[9]=void 0===h[9]?l?0:e.length:x(h[9]-u,0))&&24&t&&(t&=-25),c=t&&1!=t?8==t||16==t?m(e,t,a):32!=t&&33!=t||o.length?g.apply(void 0,h):y(e,t,n,r):f(e,t,n),E((p?d:w)(c,h),e,t)}},53138:(e,t,n)=>{var r=n(11331);e.exports=function(e){return r(e)?void 0:e}},24647:(e,t,n)=>{n=n(54552)({"À":"A","Á":"A","Â":"A","Ã":"A","Ä":"A","Å":"A","à":"a","á":"a","â":"a","ã":"a","ä":"a","å":"a","Ç":"C","ç":"c","Ð":"D","ð":"d","È":"E","É":"E","Ê":"E","Ë":"E","è":"e","é":"e","ê":"e","ë":"e","Ì":"I","Í":"I","Î":"I","Ï":"I","ì":"i","í":"i","î":"i","ï":"i","Ñ":"N","ñ":"n","Ò":"O","Ó":"O","Ô":"O","Õ":"O","Ö":"O","Ø":"O","ò":"o","ó":"o","ô":"o","õ":"o","ö":"o","ø":"o","Ù":"U","Ú":"U","Û":"U","Ü":"U","ù":"u","ú":"u","û":"u","ü":"u","Ý":"Y","ý":"y","ÿ":"y","Æ":"Ae","æ":"ae","Þ":"Th","þ":"th","ß":"ss","Ā":"A","Ă":"A","Ą":"A","ā":"a","ă":"a","ą":"a","Ć":"C","Ĉ":"C","Ċ":"C","Č":"C","ć":"c","ĉ":"c","ċ":"c","č":"c","Ď":"D","Đ":"D","ď":"d","đ":"d","Ē":"E","Ĕ":"E","Ė":"E","Ę":"E","Ě":"E","ē":"e","ĕ":"e","ė":"e","ę":"e","ě":"e","Ĝ":"G","Ğ":"G","Ġ":"G","Ģ":"G","ĝ":"g","ğ":"g","ġ":"g","ģ":"g","Ĥ":"H","Ħ":"H","ĥ":"h","ħ":"h","Ĩ":"I","Ī":"I","Ĭ":"I","Į":"I","İ":"I","ĩ":"i","ī":"i","ĭ":"i","į":"i","ı":"i","Ĵ":"J","ĵ":"j","Ķ":"K","ķ":"k","ĸ":"k","Ĺ":"L","Ļ":"L","Ľ":"L","Ŀ":"L","Ł":"L","ĺ":"l","ļ":"l","ľ":"l","ŀ":"l","ł":"l","Ń":"N","Ņ":"N","Ň":"N","Ŋ":"N","ń":"n","ņ":"n","ň":"n","ŋ":"n","Ō":"O","Ŏ":"O","Ő":"O","ō":"o","ŏ":"o","ő":"o","Ŕ":"R","Ŗ":"R","Ř":"R","ŕ":"r","ŗ":"r","ř":"r","Ś":"S","Ŝ":"S","Ş":"S","Š":"S","ś":"s","ŝ":"s","ş":"s","š":"s","Ţ":"T","Ť":"T","Ŧ":"T","ţ":"t","ť":"t","ŧ":"t","Ũ":"U","Ū":"U","Ŭ":"U","Ů":"U","Ű":"U","Ų":"U","ũ":"u","ū":"u","ŭ":"u","ů":"u","ű":"u","ų":"u","Ŵ":"W","ŵ":"w","Ŷ":"Y","ŷ":"y","Ÿ":"Y","Ź":"Z","Ż":"Z","Ž":"Z","ź":"z","ż":"z","ž":"z","IJ":"IJ","ij":"ij","Œ":"Oe","œ":"oe","ʼn":"'n","ſ":"s"});e.exports=n},93243:(e,t,n)=>{var r=n(56110),n=function(){try{var e=r(Object,"defineProperty");return e({},"",{}),e}catch(e){}}();e.exports=n},25911:(e,t,n)=>{var g=n(38859),y=n(14248),v=n(19219);e.exports=function(e,t,n,r,o,s){var i=1&n,a=e.length,l=t.length;if(a!=l&&!(i&&a{var r=n(51873),c=n(37828),u=n(75288),p=n(25911),h=n(20317),d=n(84247),n=r?r.prototype:void 0,f=n?n.valueOf:void 0;e.exports=function(e,t,n,r,o,s,i){switch(n){case"[object DataView]":if(e.byteLength!=t.byteLength||e.byteOffset!=t.byteOffset)return!1;e=e.buffer,t=t.buffer;case"[object ArrayBuffer]":return!(e.byteLength!=t.byteLength||!s(new c(e),new c(t)));case"[object Boolean]":case"[object Date]":case"[object Number]":return u(+e,+t);case"[object Error]":return e.name==t.name&&e.message==t.message;case"[object RegExp]":case"[object String]":return e==t+"";case"[object Map]":var a=h;case"[object Set]":a=a||d;if(e.size!=t.size&&!(1&r))return!1;var l=i.get(e);if(l)return l==t;r|=2,i.set(e,t);l=p(a(e),a(t),r,o,s,i);return i.delete(e),l;case"[object Symbol]":if(f)return f.call(e)==f.call(t)}return!1}},50689:(e,t,n)=>{var v=n(50002),b=Object.prototype.hasOwnProperty;e.exports=function(e,t,n,r,o,s){var i=1&n,a=v(e),l=a.length;if(l!=v(t).length&&!i)return!1;for(var c=l;c--;){var u=a[c];if(!(i?u in t:b.call(t,u)))return!1}var p=s.get(e),h=s.get(t);if(p&&h)return p==t&&h==e;var d=!0;s.set(e,t),s.set(t,e);for(var f=i;++c{var r=n(35970),o=n(56757),s=n(32865);e.exports=function(e){return s(o(e,void 0,r),e+"")}},34840:(e,t,n)=>{n="object"==typeof n.g&&n.g&&n.g.Object===Object&&n.g;e.exports=n},50002:(e,t,n)=>{var r=n(82199),o=n(4664),s=n(95950);e.exports=function(e){return r(e,s,o)}},83349:(e,t,n)=>{var r=n(82199),o=n(86375),s=n(37241);e.exports=function(e){return r(e,s,o)}},37381:(e,t,n)=>{var r=n(48152),n=n(63950);e.exports=r?function(e){return r.get(e)}:n},62284:(e,t,n)=>{var i=n(84629),a=Object.prototype.hasOwnProperty;e.exports=function(e){for(var t=e.name+"",n=i[t],r=a.call(i,t)?n.length:0;r--;){var o=n[r],s=o.func;if(null==s||s==e)return o.name}return t}},11287:e=>{e.exports=function(e){return e.placeholder}},12651:(e,t,n)=>{var r=n(74218);e.exports=function(e,t){e=e.__data__;return r(t)?e["string"==typeof t?"string":"hash"]:e.map}},10776:(e,t,n)=>{var s=n(30756),i=n(95950);e.exports=function(e){for(var t=i(e),n=t.length;n--;){var r=t[n],o=e[r];t[n]=[r,o,s(o)]}return t}},56110:(e,t,n)=>{var r=n(45083),o=n(10392);e.exports=function(e,t){e=o(e,t);return r(e)?e:void 0}},28879:(e,t,n)=>{n=n(74335)(Object.getPrototypeOf,Object);e.exports=n},659:(e,t,n)=>{var n=n(51873),r=Object.prototype,s=r.hasOwnProperty,i=r.toString,a=n?n.toStringTag:void 0;e.exports=function(e){var t=s.call(e,a),n=e[a];try{var r=!(e[a]=void 0)}catch(e){}var o=i.call(e);return r&&(t?e[a]=n:delete e[a]),o}},4664:(e,t,n)=>{var r=n(79770),n=n(63345),o=Object.prototype.propertyIsEnumerable,s=Object.getOwnPropertySymbols;e.exports=s?function(t){return null==t?[]:(t=Object(t),r(s(t),function(e){return o.call(t,e)}))}:n},86375:(e,t,n)=>{var r=n(14528),o=n(28879),s=n(4664),n=n(63345),n=Object.getOwnPropertySymbols?function(e){for(var t=[];e;)r(t,s(e)),e=o(e);return t}:n;e.exports=n},5861:(e,t,n)=>{var r=n(55580),o=n(68223),s=n(32804),i=n(76545),a=n(28303),l=n(72552),c=n(47473),u="[object Map]",p="[object Promise]",h="[object Set]",d="[object WeakMap]",f="[object DataView]",m=c(r),g=c(o),y=c(s),v=c(i),b=c(a),n=l;(r&&n(new r(new ArrayBuffer(1)))!=f||o&&n(new o)!=u||s&&n(s.resolve())!=p||i&&n(new i)!=h||a&&n(new a)!=d)&&(n=function(e){var t=l(e),e="[object Object]"==t?e.constructor:void 0,e=e?c(e):"";if(e)switch(e){case m:return f;case g:return u;case y:return p;case v:return h;case b:return d}return t}),e.exports=n},10392:e=>{e.exports=function(e,t){return null==e?void 0:e[t]}},75251:e=>{var t=/\{\n\/\* \[wrapped with (.+)\] \*/,n=/,? & /;e.exports=function(e){e=e.match(t);return e?e[1].split(n):[]}},49326:(e,t,n)=>{var a=n(31769),l=n(72428),c=n(56449),u=n(30361),p=n(30294),h=n(77797);e.exports=function(e,t,n){for(var r=-1,o=(t=a(t,e)).length,s=!1;++r{var t=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]");e.exports=function(e){return t.test(e)}},45434:e=>{var t=/[a-z][A-Z]|[A-Z]{2}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;e.exports=function(e){return t.test(e)}},22032:(e,t,n)=>{var r=n(81042);e.exports=function(){this.__data__=r?r(null):{},this.size=0}},63862:e=>{e.exports=function(e){e=this.has(e)&&delete this.__data__[e];return this.size-=e?1:0,e}},66721:(e,t,n)=>{var r=n(81042),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t,n=this.__data__;return r?"__lodash_hash_undefined__"===(t=n[e])?void 0:t:o.call(n,e)?n[e]:void 0}},12749:(e,t,n)=>{var r=n(81042),o=Object.prototype.hasOwnProperty;e.exports=function(e){var t=this.__data__;return r?void 0!==t[e]:o.call(t,e)}},35749:(e,t,n)=>{var r=n(81042);e.exports=function(e,t){var n=this.__data__;return this.size+=this.has(e)?0:1,n[e]=r&&void 0===t?"__lodash_hash_undefined__":t,this}},76189:e=>{var r=Object.prototype.hasOwnProperty;e.exports=function(e){var t=e.length,n=new e.constructor(t);return t&&"string"==typeof e[0]&&r.call(e,"index")&&(n.index=e.index,n.input=e.input),n}},77199:(e,t,n)=>{var o=n(49653),s=n(76169),i=n(73201),a=n(93736),l=n(71961);e.exports=function(e,t,n){var r=e.constructor;switch(t){case"[object ArrayBuffer]":return o(e);case"[object Boolean]":case"[object Date]":return new r(+e);case"[object DataView]":return s(e,n);case"[object Float32Array]":case"[object Float64Array]":case"[object Int8Array]":case"[object Int16Array]":case"[object Int32Array]":case"[object Uint8Array]":case"[object Uint8ClampedArray]":case"[object Uint16Array]":case"[object Uint32Array]":return l(e,n);case"[object Map]":case"[object Set]":return new r;case"[object Number]":case"[object String]":return new r(e);case"[object RegExp]":return i(e);case"[object Symbol]":return a(e)}}},35529:(e,t,n)=>{var r=n(39344),o=n(28879),s=n(55527);e.exports=function(e){return"function"!=typeof e.constructor||s(e)?{}:r(o(e))}},62060:e=>{var o=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/;e.exports=function(e,t){var n=t.length;if(!n)return e;var r=n-1;return t[r]=(1{var r=n(51873),o=n(72428),s=n(56449),i=r?r.isConcatSpreadable:void 0;e.exports=function(e){return s(e)||o(e)||!!(i&&e&&e[i])}},30361:e=>{var r=/^(?:0|[1-9]\d*)$/;e.exports=function(e,t){var n=typeof e;return!!(t=null==t?9007199254740991:t)&&("number"==n||"symbol"!=n&&r.test(e))&&-1{var o=n(75288),s=n(64894),i=n(30361),a=n(23805);e.exports=function(e,t,n){if(!a(n))return!1;var r=typeof t;return!!("number"==r?s(n)&&i(t,n.length):"string"==r&&t in n)&&o(n[t],e)}},28586:(e,t,n)=>{var r=n(56449),o=n(44394),s=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,i=/^\w*$/;e.exports=function(e,t){if(r(e))return!1;var n=typeof e;return!("number"!=n&&"symbol"!=n&&"boolean"!=n&&null!=e&&!o(e))||i.test(e)||!s.test(e)||null!=t&&e in Object(t)}},74218:e=>{e.exports=function(e){var t=typeof e;return"string"==t||"number"==t||"symbol"==t||"boolean"==t?"__proto__"!==e:null===e}},85087:(e,t,n)=>{var r=n(30980),o=n(37381),s=n(62284),i=n(53758);e.exports=function(e){var t=s(e),n=i[t];if("function"!=typeof n||!(t in r.prototype))return!1;if(e===n)return!0;t=o(n);return!!t&&e===t[0]}},87296:(e,t,n)=>{var n=n(55481),r=(n=/[^.]+$/.exec(n&&n.keys&&n.keys.IE_PROTO||""))?"Symbol(src)_1."+n:"";e.exports=function(e){return!!r&&r in e}},55527:e=>{var n=Object.prototype;e.exports=function(e){var t=e&&e.constructor;return e===("function"==typeof t&&t.prototype||n)}},30756:(e,t,n)=>{var r=n(23805);e.exports=function(e){return e==e&&!r(e)}},63702:e=>{e.exports=function(){this.__data__=[],this.size=0}},70080:(e,t,n)=>{var r=n(26025),o=Array.prototype.splice;e.exports=function(e){var t=this.__data__,e=r(t,e);return!(e<0||(e==t.length-1?t.pop():o.call(t,e,1),--this.size,0))}},24739:(e,t,n)=>{var r=n(26025);e.exports=function(e){var t=this.__data__,e=r(t,e);return e<0?void 0:t[e][1]}},48655:(e,t,n)=>{var r=n(26025);e.exports=function(e){return-1{var o=n(26025);e.exports=function(e,t){var n=this.__data__,r=o(n,e);return r<0?(++this.size,n.push([e,t])):n[r][1]=t,this}},63040:(e,t,n)=>{var r=n(21549),o=n(80079),s=n(68223);e.exports=function(){this.size=0,this.__data__={hash:new r,map:new(s||o),string:new r}}},17670:(e,t,n)=>{var r=n(12651);e.exports=function(e){e=r(this,e).delete(e);return this.size-=e?1:0,e}},90289:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).get(e)}},4509:(e,t,n)=>{var r=n(12651);e.exports=function(e){return r(this,e).has(e)}},72949:(e,t,n)=>{var o=n(12651);e.exports=function(e,t){var n=o(this,e),r=n.size;return n.set(e,t),this.size+=n.size==r?0:1,this}},20317:e=>{e.exports=function(e){var n=-1,r=Array(e.size);return e.forEach(function(e,t){r[++n]=[t,e]}),r}},67197:e=>{e.exports=function(t,n){return function(e){return null!=e&&e[t]===n&&(void 0!==n||t in Object(e))}}},62224:(e,t,n)=>{var r=n(50104);e.exports=function(e){var e=r(e,function(e){return 500===t.size&&t.clear(),e}),t=e.cache;return e}},3209:(e,t,n)=>{var a=n(91596),l=n(53320),c=n(36306),u="__lodash_placeholder__",p=Math.min;e.exports=function(e,t){var n=e[1],r=t[1],o=n|r,s=128==r&&8==n||128==r&&256==n&&e[7].length<=t[8]||384==r&&t[7].length<=t[8]&&8==n;if(!(o<131)&&!s)return e;1&r&&(e[2]=t[2],o|=1&n?0:4);var i,s=t[3];return s&&(i=e[3],e[3]=i?a(i,s,t[4]):s,e[4]=i?c(e[3],u):t[4]),(s=t[5])&&(i=e[5],e[5]=i?l(i,s,t[6]):s,e[6]=i?c(e[5],u):t[6]),(s=t[7])&&(e[7]=s),128&r&&(e[8]=null==e[8]?t[8]:p(e[8],t[8])),null==e[9]&&(e[9]=t[9]),e[0]=t[0],e[1]=o,e}},48152:(e,t,n)=>{n=n(28303),n=n&&new n;e.exports=n},81042:(e,t,n)=>{n=n(56110)(Object,"create");e.exports=n},3650:(e,t,n)=>{n=n(74335)(Object.keys,Object);e.exports=n},90181:e=>{e.exports=function(e){var t=[];if(null!=e)for(var n in Object(e))t.push(n);return t}},86009:(e,t,n)=>{e=n.nmd(e);var n=n(34840),t=t&&!t.nodeType&&t,r=t&&e&&!e.nodeType&&e,o=r&&r.exports===t&&n.process,t=function(){try{return r&&r.require&&r.require("util").types||o&&o.binding&&o.binding("util")}catch(e){}}();e.exports=t},59350:e=>{var t=Object.prototype.toString;e.exports=function(e){return t.call(e)}},74335:e=>{e.exports=function(t,n){return function(e){return t(n(e))}}},56757:(e,t,n)=>{var l=n(91033),c=Math.max;e.exports=function(s,i,a){return i=c(void 0===i?s.length-1:i,0),function(){for(var e=arguments,t=-1,n=c(e.length-i,0),r=Array(n);++t{var r=n(47422),o=n(25160);e.exports=function(e,t){return t.length<2?e:r(e,o(t,0,-1))}},84629:e=>{e.exports={}},68294:(e,t,n)=>{var i=n(23007),a=n(30361),l=Math.min;e.exports=function(e,t){for(var n=e.length,r=l(t.length,n),o=i(e);r--;){var s=t[r];e[r]=a(s,n)?o[s]:void 0}return e}},36306:e=>{var a="__lodash_placeholder__";e.exports=function(e,t){for(var n=-1,r=e.length,o=0,s=[];++n{var n=n(34840),r="object"==typeof self&&self&&self.Object===Object&&self,n=n||r||Function("return this")();e.exports=n},14974:e=>{e.exports=function(e,t){if(("constructor"!==t||"function"!=typeof e[t])&&"__proto__"!=t)return e[t]}},31380:e=>{e.exports=function(e){return this.__data__.set(e,"__lodash_hash_undefined__"),this}},51459:e=>{e.exports=function(e){return this.__data__.has(e)}},54641:(e,t,n)=>{var r=n(68882),n=n(51811)(r);e.exports=n},84247:e=>{e.exports=function(e){var t=-1,n=Array(e.size);return e.forEach(function(e){n[++t]=e}),n}},32865:(e,t,n)=>{var r=n(19570),n=n(51811)(r);e.exports=n},70981:(e,t,n)=>{var r=n(75251),o=n(62060),s=n(32865),i=n(75948);e.exports=function(e,t,n){t+="";return s(e,o(t,i(r(t),n)))}},51811:e=>{var s=Date.now;e.exports=function(n){var r=0,o=0;return function(){var e=s(),t=16-(e-o);if(o=e,0{var r=n(80079);e.exports=function(){this.__data__=new r,this.size=0}},90938:e=>{e.exports=function(e){var t=this.__data__,e=t.delete(e);return this.size=t.size,e}},63605:e=>{e.exports=function(e){return this.__data__.get(e)}},29817:e=>{e.exports=function(e){return this.__data__.has(e)}},80945:(e,t,n)=>{var o=n(80079),s=n(68223),i=n(53661);e.exports=function(e,t){var n=this.__data__;if(n instanceof o){var r=n.__data__;if(!s||r.length<199)return r.push([e,t]),this.size=++n.size,this;n=this.__data__=new i(r)}return n.set(e,t),this.size=n.size,this}},76959:e=>{e.exports=function(e,t,n){for(var r=n-1,o=e.length;++r{var r=n(61074),o=n(49698),s=n(42054);e.exports=function(e){return(o(e)?s:r)(e)}},61802:(e,t,n)=>{var n=n(62224),r=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,s=/\\(\\)?/g,n=n(function(e){var o=[];return 46===e.charCodeAt(0)&&o.push(""),e.replace(r,function(e,t,n,r){o.push(n?r.replace(s,"$1"):t||e)}),o});e.exports=n},77797:(e,t,n)=>{var r=n(44394);e.exports=function(e){if("string"==typeof e||r(e))return e;var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}},47473:e=>{var t=Function.prototype.toString;e.exports=function(e){if(null!=e){try{return t.call(e)}catch(e){}try{return e+""}catch(e){}}return""}},31800:e=>{var n=/\s/;e.exports=function(e){for(var t=e.length;t--&&n.test(e.charAt(t)););return t}},42054:e=>{var t="\\ud800-\\udfff",n="["+t+"]",r="[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]",o="\\ud83c[\\udffb-\\udfff]",t="[^"+t+"]",s="(?:\\ud83c[\\udde6-\\uddff]){2}",i="[\\ud800-\\udbff][\\udc00-\\udfff]",a="(?:"+r+"|"+o+")?",l="[\\ufe0e\\ufe0f]?",l=l+a+"(?:\\u200d(?:"+[t,s,i].join("|")+")"+l+a+")*",a="(?:"+[t+r+"?",r,s,i,n].join("|")+")",c=RegExp(o+"(?="+o+")|"+a+l,"g");e.exports=function(e){return e.match(c)||[]}},22225:e=>{var t="\\ud800-\\udfff",n="\\u2700-\\u27bf",r="a-z\\xdf-\\xf6\\xf8-\\xff",o="A-Z\\xc0-\\xd6\\xd8-\\xde",s="\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000",i="["+s+"]",a="["+n+"]",l="["+r+"]",s="[^"+t+s+"\\d+"+n+r+o+"]",n="(?:\\ud83c[\\udde6-\\uddff]){2}",r="[\\ud800-\\udbff][\\udc00-\\udfff]",o="["+o+"]",c="(?:"+l+"|"+s+")",s="(?:"+o+"|"+s+")",u="(?:['’](?:d|ll|m|re|s|t|ve))?",p="(?:['’](?:D|LL|M|RE|S|T|VE))?",h="(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?",d="[\\ufe0e\\ufe0f]?",t=d+h+"(?:\\u200d(?:"+["[^"+t+"]",n,r].join("|")+")"+d+h+")*",d="(?:"+[a,n,r].join("|")+")"+t,f=RegExp([o+"?"+l+"+"+u+"(?="+[i,o,"$"].join("|")+")",s+"+"+p+"(?="+[i,o+c,"$"].join("|")+")",o+"?"+c+"+"+u,o+"+"+p,"\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])","\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])","\\d+",d].join("|"),"g");e.exports=function(e){return e.match(f)||[]}},75948:(e,t,n)=>{var o=n(83729),s=n(15325),i=[["ary",128],["bind",1],["bindKey",2],["curry",8],["curryRight",16],["flip",512],["partial",32],["partialRight",64],["rearg",256]];e.exports=function(n,r){return o(i,function(e){var t="_."+e[0];r&e[1]&&!s(n,t)&&n.push(t)}),n.sort()}},80257:(e,t,n)=>{var r=n(30980),o=n(56017),s=n(23007);e.exports=function(e){if(e instanceof r)return e.clone();var t=new o(e.__wrapped__,e.__chain__);return t.__actions__=s(e.__actions__),t.__index__=e.__index__,t.__values__=e.__values__,t}},64626:(e,t,n)=>{var r=n(66977);e.exports=function(e,t,n){return t=n?void 0:t,t=e&&null==t?e.length:t,r(e,128,void 0,void 0,void 0,void 0,t)}},84058:(e,t,n)=>{var r=n(14792),n=n(45539)(function(e,t,n){return t=t.toLowerCase(),e+(n?r(t):t)});e.exports=n},14792:(e,t,n)=>{var r=n(13222),o=n(55808);e.exports=function(e){return o(r(e).toLowerCase())}},32629:(e,t,n)=>{var r=n(9999);e.exports=function(e){return r(e,4)}},37334:e=>{e.exports=function(e){return function(){return e}}},49747:(e,t,n)=>{var r=n(66977);function o(e,t,n){e=r(e,8,void 0,void 0,void 0,void 0,void 0,t=n?void 0:t);return e.placeholder=o.placeholder,e}o.placeholder={},e.exports=o},38221:(e,t,n)=>{var v=n(23805),b=n(10124),w=n(99374),E=Math.max,S=Math.min;e.exports=function(r,n,e){var o,s,i,a,l,c,u=0,p=!1,h=!1,t=!0;if("function"!=typeof r)throw new TypeError("Expected a function");function d(e){var t=o,n=s;return o=s=void 0,u=e,a=r.apply(n,t)}function f(e){var t=e-c;return void 0===c||n<=t||t<0||h&&i<=e-u}function m(){var e,t=b();if(f(t))return g(t);l=setTimeout(m,(e=n-((t=t)-c),h?S(e,i-(t-u)):e))}function g(e){return l=void 0,t&&o?d(e):(o=s=void 0,a)}function y(){var e=b(),t=f(e);if(o=arguments,s=this,c=e,t){if(void 0===l)return u=e=c,l=setTimeout(m,n),p?d(e):a;if(h)return clearTimeout(l),l=setTimeout(m,n),d(c)}return void 0===l&&(l=setTimeout(m,n)),a}return n=w(n)||0,v(e)&&(p=!!e.leading,i=(h="maxWait"in e)?E(w(e.maxWait)||0,n):i,t="trailing"in e?!!e.trailing:t),y.cancel=function(){void 0!==l&&clearTimeout(l),o=c=s=l=void(u=0)},y.flush=function(){return void 0===l?a:g(b())},y}},50828:(e,t,n)=>{var r=n(24647),o=n(13222),s=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,i=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g");e.exports=function(e){return(e=o(e))&&e.replace(s,r).replace(i,"")}},75288:e=>{e.exports=function(e,t){return e===t||e!=e&&t!=t}},7309:(e,t,n)=>{n=n(62006)(n(24713));e.exports=n},24713:(e,t,n)=>{var o=n(2523),s=n(15389),i=n(61489),a=Math.max;e.exports=function(e,t,n){var r=null==e?0:e.length;if(!r)return-1;n=null==n?0:i(n);return n<0&&(n=a(r+n,0)),o(e,s(t,3),n)}},35970:(e,t,n)=>{var r=n(83120);e.exports=function(e){return null!=e&&e.length?r(e,1):[]}},73424:(e,t,n)=>{var B=n(16962),L=n(2874),q=Array.prototype.push;function $(n,e){return 2==e?function(e,t){return n(e,t)}:function(e){return n(e)}}function z(e){for(var t=e?e.length:0,n=Array(t);t--;)n[t]=e[t];return n}function U(r,o){return function(){var e=arguments.length;if(e){for(var t=Array(e);e--;)t[e]=arguments[e];var n=t[0]=o.apply(void 0,t);return r.apply(void 0,t),n}}}e.exports=function a(n,e,t,l){var c="function"==typeof e,r=e===Object(e);if(r&&(l=t,t=e,e=void 0),null==t)throw new TypeError;var u={cap:!("cap"in(l=l||{}))||l.cap,curry:!("curry"in l)||l.curry,fixed:!("fixed"in l)||l.fixed,immutable:!("immutable"in l)||l.immutable,rearg:!("rearg"in l)||l.rearg},o=c?t:L,p="curry"in l&&l.curry,h="fixed"in l&&l.fixed,s="rearg"in l&&l.rearg,d=c?t.runInContext():void 0,f=c?t:{ary:n.ary,assign:n.assign,clone:n.clone,curry:n.curry,forEach:n.forEach,isArray:n.isArray,isError:n.isError,isFunction:n.isFunction,isWeakMap:n.isWeakMap,iteratee:n.iteratee,keys:n.keys,rearg:n.rearg,toInteger:n.toInteger,toPath:n.toPath},m=f.ary,g=f.assign,y=f.clone,v=f.curry,b=f.forEach,i=f.isArray,w=f.isError,E=f.isFunction,S=f.isWeakMap,x=f.keys,_=f.rearg,k=f.toInteger,A=f.toPath,O=x(B.aryMethod),C={castArray:function(t){return function(){var e=arguments[0];return i(e)?t(z(e)):t.apply(void 0,arguments)}},iteratee:function(r){return function(){var e=arguments[1],t=r(arguments[0],e),n=t.length;return u.cap&&"number"==typeof e?(e=2{s.aliasToReal={each:"forEach",eachRight:"forEachRight",entries:"toPairs",entriesIn:"toPairsIn",extend:"assignIn",extendAll:"assignInAll",extendAllWith:"assignInAllWith",extendWith:"assignInWith",first:"head",conforms:"conformsTo",matches:"isMatch",property:"get",__:"placeholder",F:"stubFalse",T:"stubTrue",all:"every",allPass:"overEvery",always:"constant",any:"some",anyPass:"overSome",apply:"spread",assoc:"set",assocPath:"set",complement:"negate",compose:"flowRight",contains:"includes",dissoc:"unset",dissocPath:"unset",dropLast:"dropRight",dropLastWhile:"dropRightWhile",equals:"isEqual",identical:"eq",indexBy:"keyBy",init:"initial",invertObj:"invert",juxt:"over",omitAll:"omit",nAry:"ary",path:"get",pathEq:"matchesProperty",pathOr:"getOr",paths:"at",pickAll:"pick",pipe:"flow",pluck:"map",prop:"get",propEq:"matchesProperty",propOr:"getOr",props:"at",symmetricDifference:"xor",symmetricDifferenceBy:"xorBy",symmetricDifferenceWith:"xorWith",takeLast:"takeRight",takeLastWhile:"takeRightWhile",unapply:"rest",unnest:"flatten",useWith:"overArgs",where:"conformsTo",whereEq:"isMatch",zipObj:"zipObject"},s.aryMethod={1:["assignAll","assignInAll","attempt","castArray","ceil","create","curry","curryRight","defaultsAll","defaultsDeepAll","floor","flow","flowRight","fromPairs","invert","iteratee","memoize","method","mergeAll","methodOf","mixin","nthArg","over","overEvery","overSome","rest","reverse","round","runInContext","spread","template","trim","trimEnd","trimStart","uniqueId","words","zipAll"],2:["add","after","ary","assign","assignAllWith","assignIn","assignInAllWith","at","before","bind","bindAll","bindKey","chunk","cloneDeepWith","cloneWith","concat","conformsTo","countBy","curryN","curryRightN","debounce","defaults","defaultsDeep","defaultTo","delay","difference","divide","drop","dropRight","dropRightWhile","dropWhile","endsWith","eq","every","filter","find","findIndex","findKey","findLast","findLastIndex","findLastKey","flatMap","flatMapDeep","flattenDepth","forEach","forEachRight","forIn","forInRight","forOwn","forOwnRight","get","groupBy","gt","gte","has","hasIn","includes","indexOf","intersection","invertBy","invoke","invokeMap","isEqual","isMatch","join","keyBy","lastIndexOf","lt","lte","map","mapKeys","mapValues","matchesProperty","maxBy","meanBy","merge","mergeAllWith","minBy","multiply","nth","omit","omitBy","overArgs","pad","padEnd","padStart","parseInt","partial","partialRight","partition","pick","pickBy","propertyOf","pull","pullAll","pullAt","random","range","rangeRight","rearg","reject","remove","repeat","restFrom","result","sampleSize","some","sortBy","sortedIndex","sortedIndexOf","sortedLastIndex","sortedLastIndexOf","sortedUniqBy","split","spreadFrom","startsWith","subtract","sumBy","take","takeRight","takeRightWhile","takeWhile","tap","throttle","thru","times","trimChars","trimCharsEnd","trimCharsStart","truncate","union","uniqBy","uniqWith","unset","unzipWith","without","wrap","xor","zip","zipObject","zipObjectDeep"],3:["assignInWith","assignWith","clamp","differenceBy","differenceWith","findFrom","findIndexFrom","findLastFrom","findLastIndexFrom","getOr","includesFrom","indexOfFrom","inRange","intersectionBy","intersectionWith","invokeArgs","invokeArgsMap","isEqualWith","isMatchWith","flatMapDepth","lastIndexOfFrom","mergeWith","orderBy","padChars","padCharsEnd","padCharsStart","pullAllBy","pullAllWith","rangeStep","rangeStepRight","reduce","reduceRight","replace","set","slice","sortedIndexBy","sortedLastIndexBy","transform","unionBy","unionWith","update","xorBy","xorWith","zipWith"],4:["fill","setWith","updateWith"]},s.aryRearg={2:[1,0],3:[2,0,1],4:[3,2,0,1]},s.iterateeAry={dropRightWhile:1,dropWhile:1,every:1,filter:1,find:1,findFrom:1,findIndex:1,findIndexFrom:1,findKey:1,findLast:1,findLastFrom:1,findLastIndex:1,findLastIndexFrom:1,findLastKey:1,flatMap:1,flatMapDeep:1,flatMapDepth:1,forEach:1,forEachRight:1,forIn:1,forInRight:1,forOwn:1,forOwnRight:1,map:1,mapKeys:1,mapValues:1,partition:1,reduce:2,reduceRight:2,reject:1,remove:1,some:1,takeRightWhile:1,takeWhile:1,times:1,transform:2},s.iterateeRearg={mapKeys:[1],reduceRight:[1,0]},s.methodRearg={assignInAllWith:[1,0],assignInWith:[1,2,0],assignAllWith:[1,0],assignWith:[1,2,0],differenceBy:[1,2,0],differenceWith:[1,2,0],getOr:[2,1,0],intersectionBy:[1,2,0],intersectionWith:[1,2,0],isEqualWith:[1,2,0],isMatchWith:[2,1,0],mergeAllWith:[1,0],mergeWith:[1,2,0],padChars:[2,1,0],padCharsEnd:[2,1,0],padCharsStart:[2,1,0],pullAllBy:[2,1,0],pullAllWith:[2,1,0],rangeStep:[1,2,0],rangeStepRight:[1,2,0],setWith:[3,1,2,0],sortedIndexBy:[2,1,0],sortedLastIndexBy:[2,1,0],unionBy:[1,2,0],unionWith:[1,2,0],updateWith:[3,1,2,0],xorBy:[1,2,0],xorWith:[1,2,0],zipWith:[1,2,0]},s.methodSpread={assignAll:{start:0},assignAllWith:{start:0},assignInAll:{start:0},assignInAllWith:{start:0},defaultsAll:{start:0},defaultsDeepAll:{start:0},invokeArgs:{start:2},invokeArgsMap:{start:2},mergeAll:{start:0},mergeAllWith:{start:0},partial:{start:1},partialRight:{start:1},without:{start:1},zipAll:{start:0}},s.mutate={array:{fill:!0,pull:!0,pullAll:!0,pullAllBy:!0,pullAllWith:!0,pullAt:!0,remove:!0,reverse:!0},object:{assign:!0,assignAll:!0,assignAllWith:!0,assignIn:!0,assignInAll:!0,assignInAllWith:!0,assignInWith:!0,assignWith:!0,defaults:!0,defaultsAll:!0,defaultsDeep:!0,defaultsDeepAll:!0,merge:!0,mergeAll:!0,mergeAllWith:!0,mergeWith:!0},set:{set:!0,setWith:!0,unset:!0,update:!0,updateWith:!0}},s.realToAlias=function(){var e,t=Object.prototype.hasOwnProperty,n=s.aliasToReal,r={};for(e in n){var o=n[e];t.call(r,o)?r[o].push(e):r[o]=[e]}return r}(),s.remap={assignAll:"assign",assignAllWith:"assignWith",assignInAll:"assignIn",assignInAllWith:"assignInWith",curryN:"curry",curryRightN:"curryRight",defaultsAll:"defaults",defaultsDeepAll:"defaultsDeep",findFrom:"find",findIndexFrom:"findIndex",findLastFrom:"findLast",findLastIndexFrom:"findLastIndex",getOr:"get",includesFrom:"includes",indexOfFrom:"indexOf",invokeArgs:"invoke",invokeArgsMap:"invokeMap",lastIndexOfFrom:"lastIndexOf",mergeAll:"merge",mergeAllWith:"mergeWith",padChars:"pad",padCharsEnd:"padEnd",padCharsStart:"padStart",propertyOf:"get",rangeStep:"range",rangeStepRight:"rangeRight",restFrom:"rest",spreadFrom:"spread",trimChars:"trim",trimCharsEnd:"trimEnd",trimCharsStart:"trimStart",zipAll:"zip"},s.skipFixed={castArray:!0,flow:!0,flowRight:!0,iteratee:!0,mixin:!0,rearg:!0,runInContext:!0},s.skipRearg={add:!0,assign:!0,assignIn:!0,bind:!0,bindKey:!0,concat:!0,difference:!0,divide:!0,eq:!0,gt:!0,gte:!0,isEqual:!0,lt:!0,lte:!0,matchesProperty:!0,merge:!0,multiply:!0,overArgs:!0,partial:!0,partialRight:!0,propertyOf:!0,random:!0,range:!0,rangeRight:!0,subtract:!0,zip:!0,zipObject:!0,zipObjectDeep:!0}},47934:(e,t,n)=>{e.exports={ary:n(64626),assign:n(74733),clone:n(32629),curry:n(49747),forEach:n(83729),isArray:n(56449),isError:n(23546),isFunction:n(1882),isWeakMap:n(47886),iteratee:n(33855),keys:n(88984),rearg:n(84195),toInteger:n(61489),toPath:n(42072)}},56367:(e,t,n)=>{e.exports=n(77731)},79920:(e,t,n)=>{var r=n(73424),o=n(47934);e.exports=function(e,t,n){return r(o,e,t,n)}},2874:e=>{e.exports={}},77731:(e,t,n)=>{var r=n(79920)("set",n(63560));r.placeholder=n(2874),e.exports=r},58156:(e,t,n)=>{var r=n(47422);e.exports=function(e,t,n){e=null==e?void 0:r(e,t);return void 0===e?n:e}},80631:(e,t,n)=>{var r=n(28077),o=n(49326);e.exports=function(e,t){return null!=e&&o(e,t,r)}},83488:e=>{e.exports=function(e){return e}},72428:(e,t,n)=>{var r=n(27534),o=n(40346),n=Object.prototype,s=n.hasOwnProperty,i=n.propertyIsEnumerable,n=r(function(){return arguments}())?r:function(e){return o(e)&&s.call(e,"callee")&&!i.call(e,"callee")};e.exports=n},56449:e=>{var t=Array.isArray;e.exports=t},64894:(e,t,n)=>{var r=n(1882),o=n(30294);e.exports=function(e){return null!=e&&o(e.length)&&!r(e)}},83693:(e,t,n)=>{var r=n(64894),o=n(40346);e.exports=function(e){return o(e)&&r(e)}},53812:(e,t,n)=>{var r=n(72552),o=n(40346);e.exports=function(e){return!0===e||!1===e||o(e)&&"[object Boolean]"==r(e)}},3656:(e,t,n)=>{e=n.nmd(e);var r=n(9325),n=n(89935),t=t&&!t.nodeType&&t,o=t&&e&&!e.nodeType&&e,o=o&&o.exports===t?r.Buffer:void 0,t=(o?o.isBuffer:void 0)||n;e.exports=t},62193:(e,t,n)=>{var r=n(88984),o=n(5861),s=n(72428),i=n(56449),a=n(64894),l=n(3656),c=n(55527),u=n(37167),p=Object.prototype.hasOwnProperty;e.exports=function(e){if(null==e)return!0;if(a(e)&&(i(e)||"string"==typeof e||"function"==typeof e.splice||l(e)||u(e)||s(e)))return!e.length;var t,n=o(e);if("[object Map]"==n||"[object Set]"==n)return!e.size;if(c(e))return!r(e).length;for(t in e)if(p.call(e,t))return!1;return!0}},2404:(e,t,n)=>{var r=n(60270);e.exports=function(e,t){return r(e,t)}},23546:(e,t,n)=>{var r=n(72552),o=n(40346),s=n(11331);e.exports=function(e){if(!o(e))return!1;var t=r(e);return"[object Error]"==t||"[object DOMException]"==t||"string"==typeof e.message&&"string"==typeof e.name&&!s(e)}},1882:(e,t,n)=>{var r=n(72552),o=n(23805);e.exports=function(e){if(!o(e))return!1;e=r(e);return"[object Function]"==e||"[object GeneratorFunction]"==e||"[object AsyncFunction]"==e||"[object Proxy]"==e}},30294:e=>{e.exports=function(e){return"number"==typeof e&&-1{var r=n(29172),o=n(27301),n=n(86009),n=n&&n.isMap,o=n?o(n):r;e.exports=o},5187:e=>{e.exports=function(e){return null===e}},98023:(e,t,n)=>{var r=n(72552),o=n(40346);e.exports=function(e){return"number"==typeof e||o(e)&&"[object Number]"==r(e)}},23805:e=>{e.exports=function(e){var t=typeof e;return null!=e&&("object"==t||"function"==t)}},40346:e=>{e.exports=function(e){return null!=e&&"object"==typeof e}},11331:(e,t,n)=>{var r=n(72552),o=n(28879),s=n(40346),n=Function.prototype,i=Object.prototype,a=n.toString,l=i.hasOwnProperty,c=a.call(Object);e.exports=function(e){if(!s(e)||"[object Object]"!=r(e))return!1;e=o(e);if(null===e)return!0;e=l.call(e,"constructor")&&e.constructor;return"function"==typeof e&&e instanceof e&&a.call(e)==c}},38440:(e,t,n)=>{var r=n(16038),o=n(27301),n=n(86009),n=n&&n.isSet,o=n?o(n):r;e.exports=o},85015:(e,t,n)=>{var r=n(72552),o=n(56449),s=n(40346);e.exports=function(e){return"string"==typeof e||!o(e)&&s(e)&&"[object String]"==r(e)}},44394:(e,t,n)=>{var r=n(72552),o=n(40346);e.exports=function(e){return"symbol"==typeof e||o(e)&&"[object Symbol]"==r(e)}},37167:(e,t,n)=>{var r=n(4901),o=n(27301),n=n(86009),n=n&&n.isTypedArray,o=n?o(n):r;e.exports=o},47886:(e,t,n)=>{var r=n(5861),o=n(40346);e.exports=function(e){return o(e)&&"[object WeakMap]"==r(e)}},33855:(e,t,n)=>{var r=n(9999),o=n(15389);e.exports=function(e){return o("function"==typeof e?e:r(e,1))}},95950:(e,t,n)=>{var r=n(70695),o=n(88984),s=n(64894);e.exports=function(e){return(s(e)?r:o)(e)}},37241:(e,t,n)=>{var r=n(70695),o=n(72903),s=n(64894);e.exports=function(e){return s(e)?r(e,!0):o(e)}},68090:e=>{e.exports=function(e){var t=null==e?0:e.length;return t?e[t-1]:void 0}},50104:(e,t,n)=>{var i=n(53661);function a(r,o){if("function"!=typeof r||null!=o&&"function"!=typeof o)throw new TypeError("Expected a function");function s(){var e=arguments,t=o?o.apply(this,e):e[0],n=s.cache;return n.has(t)?n.get(t):(e=r.apply(this,e),s.cache=n.set(t,e)||n,e)}return s.cache=new(a.Cache||i),s}a.Cache=i,e.exports=a},55364:(e,t,n)=>{var r=n(85250),n=n(20999)(function(e,t,n){r(e,t,n)});e.exports=n},6048:e=>{e.exports=function(t){if("function"!=typeof t)throw new TypeError("Expected a function");return function(){var e=arguments;switch(e.length){case 0:return!t.call(this);case 1:return!t.call(this,e[0]);case 2:return!t.call(this,e[0],e[1]);case 3:return!t.call(this,e[0],e[1],e[2])}return!t.apply(this,e)}}},63950:e=>{e.exports=function(){}},10124:(e,t,n)=>{var r=n(9325);e.exports=function(){return r.Date.now()}},90179:(e,t,n)=>{var s=n(34932),i=n(9999),a=n(19931),l=n(31769),c=n(21791),u=n(53138),r=n(38816),p=n(83349),n=r(function(t,e){var n={};if(null==t)return n;var r=!1;e=s(e,function(e){return e=l(e,t),r=r||1{var r=n(47237),o=n(17255),s=n(28586),i=n(77797);e.exports=function(e){return s(e)?r(i(e)):o(e)}},84195:(e,t,n)=>{var r=n(66977),n=n(38816)(function(e,t){return r(e,256,void 0,void 0,void 0,t)});e.exports=n},40860:(e,t,n)=>{var s=n(40882),i=n(80909),a=n(15389),l=n(85558),c=n(56449);e.exports=function(e,t,n){var r=c(e)?s:l,o=arguments.length<3;return r(e,a(t,4),n,o,i)}},63560:(e,t,n)=>{var r=n(73170);e.exports=function(e,t,n){return null==e?e:r(e,t,n)}},42426:(e,t,n)=>{var o=n(14248),s=n(15389),i=n(90916),a=n(56449),l=n(36800);e.exports=function(e,t,n){var r=a(e)?o:i;return n&&l(e,t,n)&&(t=void 0),r(e,s(t,3))}},63345:e=>{e.exports=function(){return[]}},89935:e=>{e.exports=function(){return!1}},17400:(e,t,n)=>{var r=n(99374);e.exports=function(e){return e?(e=r(e))===1/0||e===-1/0?17976931348623157e292*(e<0?-1:1):e==e?e:0:0===e?e:0}},61489:(e,t,n)=>{var r=n(17400);e.exports=function(e){var e=r(e),t=e%1;return e==e?t?e-t:e:0}},80218:(e,t,n)=>{var r=n(13222);e.exports=function(e){return r(e).toLowerCase()}},99374:(e,t,n)=>{var r=n(54128),o=n(23805),s=n(44394),i=/^[-+]0x[0-9a-f]+$/i,a=/^0b[01]+$/i,l=/^0o[0-7]+$/i,c=parseInt;e.exports=function(e){if("number"==typeof e)return e;if(s(e))return NaN;if(o(e)&&(t="function"==typeof e.valueOf?e.valueOf():e,e=o(t)?t+"":t),"string"!=typeof e)return 0===e?e:+e;e=r(e);var t=a.test(e);return t||l.test(e)?c(e.slice(2),t?2:8):i.test(e)?NaN:+e}},42072:(e,t,n)=>{var r=n(34932),o=n(23007),s=n(56449),i=n(44394),a=n(61802),l=n(77797),c=n(13222);e.exports=function(e){return s(e)?r(e,l):i(e)?[e]:o(a(c(e)))}},69884:(e,t,n)=>{var r=n(21791),o=n(37241);e.exports=function(e){return r(e,o(e))}},13222:(e,t,n)=>{var r=n(77556);e.exports=function(e){return null==e?"":r(e)}},55808:(e,t,n)=>{n=n(12507)("toUpperCase");e.exports=n},66645:(e,t,n)=>{var r=n(1733),o=n(45434),s=n(13222),i=n(22225);e.exports=function(e,t,n){return e=s(e),void 0===(t=n?void 0:t)?(o(e)?i:r)(e):e.match(t)||[]}},53758:(e,t,n)=>{var r=n(30980),o=n(56017),s=n(94033),i=n(56449),a=n(40346),l=n(80257),c=Object.prototype.hasOwnProperty;function u(e){if(a(e)&&!i(e)&&!(e instanceof r)){if(e instanceof o)return e;if(c.call(e,"__wrapped__"))return l(e)}return new o(e)}u.prototype=s.prototype,e.exports=u.prototype.constructor=u},47248:(e,t,n)=>{var r=n(16547),o=n(51234);e.exports=function(e,t){return o(e||[],t||[],r)}},43768:(e,t,n)=>{"use strict";var u=n(45981),p=n(85587),o=(t.highlight=h,t.highlightAuto=function(e,t){var n,r,o,s,i=t||{},a=i.subset||u.listLanguages(),i=i.prefix,l=a.length,c=-1;if(null==i&&0,"string"!=typeof e)throw p("Expected `string` for value, got `%s`",e);for(r={relevance:0,language:null,value:[]},n={relevance:0,language:null,value:[]};++cr.relevance&&(r=o),o.relevance>n.relevance&&(r=n,n=o));return r.language&&(n.secondBest=r),n},t.registerLanguage=function(e,t){u.registerLanguage(e,t)},t.listLanguages=function(){return u.listLanguages()},t.registerAlias=function(e,t){var n,r=e;for(n in t&&((r={})[e]=t),r)u.registerAliases(r[n],{languageName:n})},s.prototype.addText=function(e){var t,n=this.stack;""!==e&&((t=(n=n[n.length-1]).children[n.children.length-1])&&"text"===t.type?t.value+=e:n.children.push({type:"text",value:e}))},s.prototype.addKeyword=function(e,t){this.openNode(t),this.addText(e),this.closeNode()},s.prototype.addSublanguage=function(e,t){var n=this.stack,n=n[n.length-1],e=e.rootNode.children;n.children=n.children.concat(t?{type:"element",tagName:"span",properties:{className:[t]},children:e}:e)},s.prototype.openNode=function(e){var t=this.stack,e={type:"element",tagName:"span",properties:{className:[this.options.classPrefix+e]},children:[]};t[t.length-1].children.push(e),t.push(e)},s.prototype.closeNode=function(){this.stack.pop()},s.prototype.closeAllNodes=r,s.prototype.finalize=r,s.prototype.toHTML=function(){return""},"hljs-");function h(e,t,n){var r=u.configure({}),n=(n||{}).prefix;if("string"!=typeof e)throw p("Expected `string` for name, got `%s`",e);if(!u.getLanguage(e))throw p("Unknown language: `%s` is not registered",e);if("string"!=typeof t)throw p("Expected `string` for value, got `%s`",t);if(u.configure({__emitter:s,classPrefix:n=null==n?o:n}),n=u.highlight(t,{language:e,ignoreIllegals:!0}),u.configure(r||{}),n.errorRaised)throw n.errorRaised;return{relevance:n.relevance,language:n.language,value:n.emitter.rootNode.children}}function s(e){this.options=e,this.rootNode={children:[]},this.stack=[this.rootNode]}function r(){}},92340:(e,t,n)=>{const r=n(6048);function o(t){return"string"==typeof t?e=>e.element===t:t.constructor&&t.extend?e=>e instanceof t:t}class s{constructor(e){this.elements=e||[]}toValue(){return this.elements.map(e=>e.toValue())}map(e,t){return this.elements.map(e,t)}flatMap(e,t){return this.map(e,t).reduce((e,t)=>e.concat(t),[])}compactMap(t,n){const r=[];return this.forEach(e=>{e=t.bind(n)(e);e&&r.push(e)}),r}filter(e,t){return e=o(e),new s(this.elements.filter(e,t))}reject(e,t){return e=o(e),new s(this.elements.filter(r(e),t))}find(e,t){return e=o(e),this.elements.find(e,t)}forEach(e,t){this.elements.forEach(e,t)}reduce(e,t){return this.elements.reduce(e,t)}includes(t){return this.elements.some(e=>e.equals(t))}shift(){return this.elements.shift()}unshift(e){this.elements.unshift(this.refract(e))}push(e){return this.elements.push(this.refract(e)),this}add(e){this.push(e)}get(e){return this.elements[e]}getValue(e){const t=this.elements[e];if(t)return t.toValue()}get length(){return this.elements.length}get isEmpty(){return 0===this.elements.length}get first(){return this.elements[0]}}"undefined"!=typeof Symbol&&(s.prototype[Symbol.iterator]=function(){return this.elements[Symbol.iterator]()}),e.exports=s},55973:e=>{e.exports=class t{constructor(e,t){this.key=e,this.value=t}clone(){const e=new t;return this.key&&(e.key=this.key.clone()),this.value&&(e.value=this.value.clone()),e}}},3110:(e,t,n)=>{const r=n(5187),o=n(85015),s=n(98023),i=n(53812),a=n(23805),l=n(85105),c=n(86804);class u{constructor(e){this.elementMap={},this.elementDetection=[],this.Element=c.Element,this.KeyValuePair=c.KeyValuePair,e&&e.noDefault||this.useDefault(),this._attributeElementKeys=[],this._attributeElementArrayKeys=[]}use(e){return e.namespace&&e.namespace({base:this}),e.load&&e.load({base:this}),this}useDefault(){return this.register("null",c.NullElement).register("string",c.StringElement).register("number",c.NumberElement).register("boolean",c.BooleanElement).register("array",c.ArrayElement).register("object",c.ObjectElement).register("member",c.MemberElement).register("ref",c.RefElement).register("link",c.LinkElement),this.detect(r,c.NullElement,!1).detect(o,c.StringElement,!1).detect(s,c.NumberElement,!1).detect(i,c.BooleanElement,!1).detect(Array.isArray,c.ArrayElement,!1).detect(a,c.ObjectElement,!1),this}register(e,t){return this._elements=void 0,this.elementMap[e]=t,this}unregister(e){return this._elements=void 0,delete this.elementMap[e],this}detect(e,t,n){return void 0===n||n?this.elementDetection.unshift([e,t]):this.elementDetection.push([e,t]),this}toElement(t){if(t instanceof this.Element)return t;let n;for(let e=0;e{var t=e[0].toUpperCase()+e.substr(1);this._elements[t]=this.elementMap[e]})),this._elements}get serialiser(){return new l(this)}}l.prototype.Namespace=u,e.exports=u},10866:(e,t,n)=>{const r=n(6048),o=n(92340);class s extends o{map(t,n){return this.elements.map(e=>t.bind(n)(e.value,e.key,e))}filter(t,n){return new s(this.elements.filter(e=>t.bind(n)(e.value,e.key,e)))}reject(e,t){return this.filter(r(e.bind(t)))}forEach(n,r){return this.elements.forEach((e,t)=>{n.bind(r)(e.value,e.key,e,t)})}keys(){return this.map((e,t)=>t.toValue())}values(){return this.map(e=>e.toValue())}}e.exports=s},86804:(e,t,n)=>{const r=n(10316),o=n(41067),s=n(71167),i=n(40239),a=n(12242),l=n(6233),c=n(87726),u=n(61045),p=n(86303),h=n(14540),d=n(92340),f=n(10866),m=n(55973);function g(e){return e instanceof r?e:"string"==typeof e?new s(e):"number"==typeof e?new i(e):"boolean"==typeof e?new a(e):null===e?new o:Array.isArray(e)?new l(e.map(g)):"object"==typeof e?new u(e):e}r.prototype.ObjectElement=u,r.prototype.RefElement=h,r.prototype.MemberElement=c,r.prototype.refract=g,d.prototype.refract=g,e.exports={Element:r,NullElement:o,StringElement:s,NumberElement:i,BooleanElement:a,ArrayElement:l,MemberElement:c,ObjectElement:u,LinkElement:p,RefElement:h,refract:g,ArraySlice:d,ObjectSlice:f,KeyValuePair:m}},86303:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e||[],t,n),this.element="link"}get relation(){return this.attributes.get("relation")}set relation(e){this.attributes.set("relation",e)}get href(){return this.attributes.get("href")}set href(e){this.attributes.set("href",e)}}},14540:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e||[],t,n),this.element="ref",this.path||(this.path="element")}get path(){return this.attributes.get("path")}set path(e){this.attributes.set("path",e)}}},34035:(e,t,n)=>{var r=n(3110),o=n(86804);t.g$=r,t.KeyValuePair=n(55973),t.G6=o.ArraySlice,t.ot=o.ObjectSlice,t.Hg=o.Element,t.Om=o.StringElement,t.kT=o.NumberElement,t.bd=o.BooleanElement,t.Os=o.NullElement,t.wE=o.ArrayElement,t.Sh=o.ObjectElement,t.Pr=o.MemberElement,t.sI=o.RefElement,t.Ft=o.LinkElement,t.e=o.refract,n(85105),n(75147)},6233:(e,t,n)=>{const r=n(6048),o=n(10316),s=n(92340);class i extends o{constructor(e,t,n){super(e||[],t,n),this.element="array"}primitive(){return"array"}get(e){return this.content[e]}getValue(e){const t=this.get(e);if(t)return t.toValue()}getIndex(e){return this.content[e]}set(e,t){return this.content[e]=this.refract(t),this}remove(e){e=this.content.splice(e,1);return e.length?e[0]:null}map(e,t){return this.content.map(e,t)}flatMap(e,t){return this.map(e,t).reduce((e,t)=>e.concat(t),[])}compactMap(t,n){const r=[];return this.forEach(e=>{e=t.bind(n)(e);e&&r.push(e)}),r}filter(e,t){return new s(this.content.filter(e,t))}reject(e,t){return this.filter(r(e),t)}reduce(t,e){let n,r;r=void 0!==e?(n=0,this.refract(e)):(n=1,"object"===this.primitive()?this.first.value:this.first);for(let e=n;e{n.bind(r)(e,this.refract(t))})}shift(){return this.content.shift()}unshift(e){this.content.unshift(this.refract(e))}push(e){return this.content.push(this.refract(e)),this}add(e){this.push(e)}findElements(r,e){const t=e||{},o=!!t.recursive,s=void 0===t.results?[]:t.results;return this.forEach((e,t,n)=>{o&&void 0!==e.findElements&&e.findElements(r,{results:s,recursive:o}),r(e,t,n)&&s.push(e)}),s}find(e){return new s(this.findElements(e,{recursive:!0}))}findByElement(t){return this.find(e=>e.element===t)}findByClass(t){return this.find(e=>e.classes.includes(t))}getById(t){return this.find(e=>e.id.toValue()===t).first}includes(t){return this.content.some(e=>e.equals(t))}contains(e){return this.includes(e)}empty(){return new this.constructor([])}"fantasy-land/empty"(){return this.empty()}concat(e){return new this.constructor(this.content.concat(e.content))}"fantasy-land/concat"(e){return this.concat(e)}"fantasy-land/map"(e){return new this.constructor(this.map(e))}"fantasy-land/chain"(t){return this.map(e=>t(e),this).reduce((e,t)=>e.concat(t),this.empty())}"fantasy-land/filter"(e){return new this.constructor(this.content.filter(e))}"fantasy-land/reduce"(e,t){return this.content.reduce(e,t)}get length(){return this.content.length}get isEmpty(){return 0===this.content.length}get first(){return this.getIndex(0)}get second(){return this.getIndex(1)}get last(){return this.getIndex(this.length-1)}}i["fantasy-land/empty"]=i.empty=function(){return new this},"undefined"!=typeof Symbol&&(i.prototype[Symbol.iterator]=function(){return this.content[Symbol.iterator]()}),e.exports=i},12242:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e,t,n),this.element="boolean"}primitive(){return"boolean"}}},10316:(e,t,n)=>{const r=n(2404),a=n(55973),l=n(92340);e.exports=class o{constructor(e,t,n){t&&(this.meta=t),n&&(this.attributes=n),this.content=e}freeze(){Object.isFrozen(this)||(this._meta&&(this.meta.parent=this).meta.freeze(),this._attributes&&(this.attributes.parent=this).attributes.freeze(),this.children.forEach(e=>{e.parent=this,e.freeze()},this),this.content&&Array.isArray(this.content)&&Object.freeze(this.content),Object.freeze(this))}primitive(){}clone(){const e=new this.constructor;return e.element=this.element,this.meta.length&&(e._meta=this.meta.clone()),this.attributes.length&&(e._attributes=this.attributes.clone()),this.content?this.content.clone?e.content=this.content.clone():Array.isArray(this.content)?e.content=this.content.map(e=>e.clone()):e.content=this.content:e.content=this.content,e}toValue(){return this.content instanceof o?this.content.toValue():this.content instanceof a?{key:this.content.key.toValue(),value:this.content.value?this.content.value.toValue():void 0}:this.content&&this.content.map?this.content.map(e=>e.toValue(),this):this.content}toRef(e){if(""===this.id.toValue())throw Error("Cannot create reference to an element that does not contain an ID");const t=new this.RefElement(this.id.toValue());return e&&(t.path=e),t}findRecursive(...r){if(1(e.push(t),e),i=(e,t)=>{t.element===o&&e.push(t);const n=t.findRecursive(o);return n&&n.reduce(s,e),t.content instanceof a&&(t.content.key&&i(e,t.content.key),t.content.value&&i(e,t.content.value)),e};return this.content&&(this.content.element&&i(e,this.content),Array.isArray(this.content)&&this.content.reduce(i,e)),e=r.isEmpty?e:e.filter(e=>{let t=e.parents.map(e=>e.element);for(const e in r){var n=r[e];if(-1===(n=t.indexOf(n)))return!1;t=t.splice(0,n)}return!0})}set(e){return this.content=e,this}equals(e){return r(this.toValue(),e)}getMetaProperty(e,t){if(!this.meta.hasKey(e)){if(this.isFrozen){const e=this.refract(t);return e.freeze(),e}this.meta.set(e,t)}return this.meta.get(e)}setMetaProperty(e,t){this.meta.set(e,t)}get element(){return this._storedElement||"element"}set element(e){this._storedElement=e}get content(){return this._content}set content(t){if(t instanceof o)this._content=t;else if(t instanceof l)this.content=t.elements;else if("string"==typeof t||"number"==typeof t||"boolean"==typeof t||"null"===t||null==t)this._content=t;else if(t instanceof a)this._content=t;else if(Array.isArray(t))this._content=t.map(this.refract);else{if("object"!=typeof t)throw new Error("Cannot set content to given value");this._content=Object.keys(t).map(e=>new this.MemberElement(e,t[e]))}}get meta(){if(!this._meta){if(this.isFrozen){const e=new this.ObjectElement;return e.freeze(),e}this._meta=new this.ObjectElement}return this._meta}set meta(e){e instanceof this.ObjectElement?this._meta=e:this.meta.set(e||{})}get attributes(){if(!this._attributes){if(this.isFrozen){const e=new this.ObjectElement;return e.freeze(),e}this._attributes=new this.ObjectElement}return this._attributes}set attributes(e){e instanceof this.ObjectElement?this._attributes=e:this.attributes.set(e||{})}get id(){return this.getMetaProperty("id","")}set id(e){this.setMetaProperty("id",e)}get classes(){return this.getMetaProperty("classes",[])}set classes(e){this.setMetaProperty("classes",e)}get title(){return this.getMetaProperty("title","")}set title(e){this.setMetaProperty("title",e)}get description(){return this.getMetaProperty("description","")}set description(e){this.setMetaProperty("description",e)}get links(){return this.getMetaProperty("links",[])}set links(e){this.setMetaProperty("links",e)}get isFrozen(){return Object.isFrozen(this)}get parents(){let e=this.parent;const t=new l;for(;e;)t.push(e),e=e.parent;return t}get children(){if(Array.isArray(this.content))return new l(this.content);if(this.content instanceof a){const e=new l([this.content.key]);return this.content.value&&e.push(this.content.value),e}return this.content instanceof o?new l([this.content]):new l}get recursiveChildren(){const t=new l;return this.children.forEach(e=>{t.push(e),e.recursiveChildren.forEach(e=>{t.push(e)})}),t}}},87726:(e,t,n)=>{const o=n(55973),r=n(10316);e.exports=class extends r{constructor(e,t,n,r){super(new o,n,r),this.element="member",this.key=e,this.value=t}get key(){return this.content.key}set key(e){this.content.key=this.refract(e)}get value(){return this.content.value}set value(e){this.content.value=this.refract(e)}}},41067:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e||null,t,n),this.element="null"}primitive(){return"null"}set(){return new Error("Cannot set the value of null")}}},40239:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e,t,n),this.element="number"}primitive(){return"number"}}},61045:(e,t,n)=>{const r=n(6048),o=n(23805),s=n(6233),i=n(87726),a=n(10866);e.exports=class extends s{constructor(e,t,n){super(e||[],t,n),this.element="object"}primitive(){return"object"}toValue(){return this.content.reduce((e,t)=>(e[t.key.toValue()]=t.value?t.value.toValue():void 0,e),{})}get(e){e=this.getMember(e);if(e)return e.value}getMember(t){if(void 0!==t)return this.content.find(e=>e.key.toValue()===t)}remove(t){let n=null;return this.content=this.content.filter(e=>e.key.toValue()!==t||(n=e,!1)),n}getKey(e){e=this.getMember(e);if(e)return e.key}set(t,e){if(o(t))return Object.keys(t).forEach(e=>{this.set(e,t[e])}),this;const n=t,r=this.getMember(n);return r?r.value=e:this.content.push(new i(n,e)),this}keys(){return this.content.map(e=>e.key.toValue())}values(){return this.content.map(e=>e.value.toValue())}hasKey(t){return this.content.some(e=>e.key.equals(t))}items(){return this.content.map(e=>[e.key.toValue(),e.value.toValue()])}map(t,n){return this.content.map(e=>t.bind(n)(e.value,e.key,e))}compactMap(r,o){const s=[];return this.forEach((e,t,n)=>{e=r.bind(o)(e,t,n);e&&s.push(e)}),s}filter(e,t){return new a(this.content).filter(e,t)}reject(e,t){return this.filter(r(e),t)}forEach(t,n){return this.content.forEach(e=>t.bind(n)(e.value,e.key,e))}}},71167:(e,t,n)=>{n=n(10316);e.exports=class extends n{constructor(e,t,n){super(e,t,n),this.element="string"}primitive(){return"string"}get length(){return this.content.length}}},75147:(e,t,n)=>{n=n(85105);e.exports=class extends n{serialise(t){if(!(t instanceof this.namespace.elements.Element))throw new TypeError(`Given element \`${t}\` is not an Element instance`);let n;t._attributes&&t.attributes.get("variable")&&(n=t.attributes.get("variable"));const r={element:t.element};t._meta&&0{e.content&&e.content.element&&e.content.attributes.remove("typeAttributes")}),e.content&&0!==n.length&&o.unshift(e.content),(o=o.map(e=>e instanceof this.namespace.elements.Array?[e]:new this.namespace.elements.Array([e.content]))).length&&t.set("samples",o),0{const t=e.clone();return t.attributes.remove("typeAttributes"),this.serialise(t)})}if(e.content){const n=e.content.clone();return n.attributes.remove("typeAttributes"),[this.serialise(n)]}return[]}deserialise(t){if("string"==typeof t)return new this.namespace.elements.String(t);if("number"==typeof t)return new this.namespace.elements.Number(t);if("boolean"==typeof t)return new this.namespace.elements.Boolean(t);if(null===t)return new this.namespace.elements.Null;if(Array.isArray(t))return new this.namespace.elements.Array(t.map(this.deserialise,this));const r=this.namespace.getElementClass(t.element),o=new r,s=(o.element!==t.element&&(o.element=t.element),t.meta&&this.deserialiseObject(t.meta,o.meta),t.attributes&&this.deserialiseObject(t.attributes,o.attributes),this.deserialiseContent(t.content));if(void 0===s&&null!==o.content||(o.content=s),"enum"===o.element){o.content&&o.attributes.set("enumerations",o.content);let n=o.attributes.get("samples");if(o.attributes.remove("samples"),n){const s=n;n=new this.namespace.elements.Array,s.forEach(e=>{e.forEach(e=>{const t=new r(e);t.element=o.element,n.push(t)})});t=n.shift();o.content=t?t.content:void 0,o.attributes.set("samples",n)}else o.content=void 0;let e=o.attributes.get("default");if(e&&0this.shouldRefract(e)||"default"===t?this.serialise(e):"array"===e.element||"object"===e.element||"enum"===e.element?e.children.map(e=>this.serialise(e)):e.toValue()):"object"===e.element?(e.content||[]).map(this.serialise,this):e.toValue()}serialiseEnum(e){return e.children.map(e=>this.serialise(e))}serialiseObject(e){const n={};return e.forEach((e,t)=>{e&&(t=t.toValue(),n[t]=this.convertKeyToRefract(t,e))}),n}deserialiseObject(t,n){Object.keys(t).forEach(e=>{n.set(e,this.deserialise(t[e]))})}}},85105:e=>{e.exports=class{constructor(e){this.namespace=e||new this.Namespace}serialise(e){if(!(e instanceof this.namespace.elements.Element))throw new TypeError(`Given element \`${e}\` is not an Element instance`);const t={element:e.element};e._meta&&0{e&&(n[t.toValue()]=this.serialise(e))}),0!==Object.keys(n).length)return n}deserialiseObject(t,n){Object.keys(t).forEach(e=>{n.set(e,this.deserialise(t[e]))})}}},58859:(n,r,w)=>{var e="function"==typeof Map&&Map.prototype,t=Object.getOwnPropertyDescriptor&&e?Object.getOwnPropertyDescriptor(Map.prototype,"size"):null,E=e&&t&&"function"==typeof t.get?t.get:null,S=e&&Map.prototype.forEach,t="function"==typeof Set&&Set.prototype,e=Object.getOwnPropertyDescriptor&&t?Object.getOwnPropertyDescriptor(Set.prototype,"size"):null,x=t&&e&&"function"==typeof e.get?e.get:null,_=t&&Set.prototype.forEach,k="function"==typeof WeakMap&&WeakMap.prototype?WeakMap.prototype.has:null,A="function"==typeof WeakSet&&WeakSet.prototype?WeakSet.prototype.has:null,O="function"==typeof WeakRef&&WeakRef.prototype?WeakRef.prototype.deref:null,X=Boolean.prototype.valueOf,s=Object.prototype.toString,Q=Function.prototype.toString,Z=String.prototype.match,C=String.prototype.slice,j=String.prototype.replace,i=String.prototype.toUpperCase,P=String.prototype.toLowerCase,u=RegExp.prototype.test,N=Array.prototype.concat,I=Array.prototype.join,ee=Array.prototype.slice,o=Math.floor,T="function"==typeof BigInt?BigInt.prototype.valueOf:null,p=Object.getOwnPropertySymbols,R="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?Symbol.prototype.toString:null,M="function"==typeof Symbol&&"object"==typeof Symbol.iterator,D="function"==typeof Symbol&&Symbol.toStringTag&&(Symbol.toStringTag,1)?Symbol.toStringTag:null,F=Object.prototype.propertyIsEnumerable,B=("function"==typeof Reflect?Reflect:Object).getPrototypeOf||([].__proto__===Array.prototype?function(e){return e.__proto__}:null);function L(e,t){if(e===1/0||e===-1/0||e!=e||e&&-1e3 0, or `null`');if(K(i,"numericSeparator")&&"boolean"!=typeof i.numericSeparator)throw new TypeError('option "numericSeparator", if provided, must be `true` or `false`');var t=i.numericSeparator;if(void 0===n)return"undefined";if(null===n)return"null";if("boolean"==typeof n)return n?"true":"false";if("string"==typeof n)return function e(t,n){{var r;if(t.length>n.maxStringLength)return r=t.length-n.maxStringLength,r="... "+r+" more character"+(1"}if(U(n)){if(0===n.length)return"[]";var b=Y(n,m);return a&&!function(e){for(var t=0;t "+m(e,n))}),oe("Map",E.call(n),u,a)):function(e){if(x&&e&&"object"==typeof e)try{x.call(e);try{E.call(e)}catch(e){return 1}return e instanceof Set}catch(e){}}(n)?(p=[],_&&_.call(n,function(e){p.push(m(e,n))}),oe("Set",x.call(n),p,a)):function(e){if(k&&e&&"object"==typeof e)try{k.call(e,k);try{A.call(e,A)}catch(e){return 1}return e instanceof WeakMap}catch(e){}}(n)?H("WeakMap"):function(e){if(A&&e&&"object"==typeof e)try{A.call(e,A);try{k.call(e,k)}catch(e){return 1}return e instanceof WeakSet}catch(e){}}(n)?H("WeakSet"):function(e){if(O&&e&&"object"==typeof e)try{return O.call(e),1}catch(e){}}(n)?H("WeakRef"):"[object Number]"!==W(h=n)||D&&"object"==typeof h&&D in h?function(e){if(e&&"object"==typeof e&&T)try{return T.call(e),1}catch(e){}}(n)?J(m(T.call(n))):"[object Boolean]"!==W(t=n)||D&&"object"==typeof t&&D in t?"[object String]"!==W(e=n)||D&&"object"==typeof e&&D in e?"undefined"!=typeof window&&n===window?"{ [object Window] }":n===w.g?"{ [object globalThis] }":("[object Date]"!==W(t=n)||D&&"object"==typeof t&&D in t)&&!V(n)?(e=Y(n,m),t=B?B(n)===Object.prototype:n instanceof Object||n.constructor===Object,d=n instanceof Object?"":"null prototype",f=!t&&D&&Object(n)===n&&D in n?C.call(W(n),8,-1):d?"Object":"",t=(!t&&"function"==typeof n.constructor&&n.constructor.name?n.constructor.name+" ":"")+(f||d?"["+I.call(N.call([],f||[],d||[]),": ")+"] ":""),0===e.length?t+"{}":a?t+"{"+G(e,a)+"}":t+"{ "+I.call(e,", ")+" }"):String(n):J(m(String(n))):J(X.call(n)):J(m(Number(n)))};var a=Object.prototype.hasOwnProperty||function(e){return e in this};function K(e,t){return a.call(e,t)}function W(e){return s.call(e)}function ne(e,t){if(e.indexOf)return e.indexOf(t);for(var n=0,r=e.length;n{var n,r,e=e.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function i(t){if(n===setTimeout)return setTimeout(t,0);if((n===o||!n)&&setTimeout)return(n=setTimeout)(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}try{n="function"==typeof setTimeout?setTimeout:o}catch(e){n=o}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(e){r=s}var a,l=[],c=!1,u=-1;function p(){c&&a&&(c=!1,a.length?l=a.concat(l):u=-1,l.length&&h())}function h(){if(!c){var e=i(p);c=!0;for(var t=l.length;t;){for(a=l,l=[];++u{"use strict";var i=n(6925);function r(){}function o(){}o.resetWarningCache=r,e.exports=function(){function e(e,t,n,r,o,s){if(s!==i)throw(s=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")).name="Invariant Violation",s}function t(){return e}var n={array:e.isRequired=e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:r};return n.PropTypes=n}},5556:(e,t,n)=>{e.exports=n(2694)()},6925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},74765:e=>{"use strict";var t=String.prototype.replace,n=/%20/g;e.exports={default:"RFC3986",formatters:{RFC1738:function(e){return t.call(e,n,"+")},RFC3986:function(e){return String(e)}},RFC1738:"RFC1738",RFC3986:"RFC3986"}},55373:(e,t,n)=>{"use strict";var r=n(98636),o=n(62642),n=n(74765);e.exports={formats:n,parse:o,stringify:r}},62642:(e,t,n)=>{"use strict";function y(e,t){return e&&"string"==typeof e&&t.comma&&-1{"use strict";function I(e,t){r.apply(e,D(t)?t:[t])}function T(e,t,n,r,o,s,i,a,l,c,u,p,h,d,f,m){for(var g=e,y=m,v=0,b=!1;void 0!==(y=y.get(L))&&!b;){var w=y.get(e);if(v+=1,void 0!==w){if(w===v)throw new RangeError("Cyclic object value");b=!0}void 0===y.get(L)&&(v=0)}if("function"==typeof a?g=a(t,g):g instanceof Date?g=u(g):"comma"===n&&D(g)&&(g=M.maybeMap(g,function(e){return e instanceof Date?u(e):e})),null===g){if(o)return i&&!d?i(t,B.encoder,f,"key",p):t;g=""}if("string"==typeof(E=g)||"number"==typeof E||"boolean"==typeof E||"symbol"==typeof E||"bigint"==typeof E||M.isBuffer(g)){if(i){var E=d?t:i(t,B.encoder,f,"key",p);if("comma"===n&&d){for(var S=F.call(String(g),","),x="",_=0;_{"use strict";function a(e,t){for(var n=t&&t.plainObjects?Object.create(null):{},r=0;r>6]+u[128|63&l]:l<55296||57344<=l?i+=u[224|l>>12]+u[128|l>>6&63]+u[128|63&l]:(a+=1,l=65536+((1023&l)<<10|1023&s.charCodeAt(a)),i+=u[240|l>>18]+u[128|l>>12&63]+u[128|l>>6&63]+u[128|63&l])}return i},isBuffer:function(e){return!(!e||"object"!=typeof e||!(e.constructor&&e.constructor.isBuffer&&e.constructor.isBuffer(e)))},isRegExp:function(e){return"[object RegExp]"===Object.prototype.toString.call(e)},maybeMap:function(e,t){if(m(e)){for(var n=[],r=0;r{"use strict";var s=Object.prototype.hasOwnProperty;function i(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function a(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){var n,r,o=[];for(r in"string"!=typeof(t=t||"")&&(t="?"),e)if(s.call(e,r)){if((n=e[r])||null!=n&&!isNaN(n)||(n=""),r=a(r),n=a(n),null===r||null===n)continue;o.push(r+"="+n)}return o.length?t+o.join("&"):""},t.parse=function(e){for(var t=/([^=?#&]+)=?([^&]*)/g,n={};o=t.exec(e);){var r=i(o[1]),o=i(o[2]);null===r||null===o||r in n||(n[r]=o)}return n}},41859:(e,t,n)=>{const i=n(27096),a=n(78004),l=i.types;e.exports=class r{constructor(e,t){if(this._setDefaults(e),e instanceof RegExp)this.ignoreCase=e.ignoreCase,this.multiline=e.multiline,e=e.source;else{if("string"!=typeof e)throw new Error("Expected a regexp or string");this.ignoreCase=t&&-1!==t.indexOf("i"),this.multiline=t&&-1!==t.indexOf("m")}this.tokens=i(e)}_setDefaults(e){this.max=null!=e.max?e.max:null!=r.prototype.max?r.prototype.max:100,this.defaultRange=e.defaultRange||this.defaultRange.clone(),e.randInt&&(this.randInt=e.randInt)}gen(){return this._gen(this.tokens,[])}_gen(e,t){var n,r,o,s,i;switch(e.type){case l.ROOT:case l.GROUP:if(e.followedBy||e.notFollowedBy)return"";for(e.remember&&void 0===e.groupNumber&&(e.groupNumber=t.push(null)-1),r="",s=0,i=(n=e.options?this._randSelect(e.options):e.stack).length;s{"use strict";var o=n(65606),s=n(92861).Buffer,i=n.g.crypto||n.g.msCrypto;i&&i.getRandomValues?e.exports=function(e,t){if(4294967295{"use strict";function s(e){return(s="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.CopyToClipboard=void 0;var l=r(n(96540)),c=r(n(17965)),u=["text","onCopy","options","children"];function r(e){return e&&e.__esModule?e:{default:e}}function o(t,e){var n,r=Object.keys(t);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(t),e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)),r}function p(t){for(var e=1;e{"use strict";n=n(25264).CopyToClipboard;n.CopyToClipboard=n,e.exports=n},81214:(e,t,n)=>{"use strict";function a(e){return(a="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.DebounceInput=void 0;var l=r(n(96540)),c=r(n(20181)),u=["element","onChange","value","minLength","debounceTimeout","forceNotifyByEnter","forceNotifyOnBlur","onKeyDown","onBlur","inputRef"];function r(e){return e&&e.__esModule?e:{default:e}}function o(t,e){var n,r=Object.keys(t);return Object.getOwnPropertySymbols&&(n=Object.getOwnPropertySymbols(t),e&&(n=n.filter(function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable})),r.push.apply(r,n)),r}function p(t){for(var e=1;e=r?o.notify(t):n.length>e.length&&o.notify(p(p({},t),{},{target:p(p({},t.target),{},{value:""})}))})}),g(f(o),"onKeyDown",function(e){"Enter"===e.key&&o.forceNotify(e);var t=o.props.onKeyDown;t&&(e.persist(),t(e))}),g(f(o),"onBlur",function(e){o.forceNotify(e);var t=o.props.onBlur;t&&(e.persist(),t(e))}),g(f(o),"createNotifier",function(e){var t;e<0?o.notify=function(){return null}:0===e?o.notify=o.doNotify:(t=(0,c.default)(function(e){o.isDebouncing=!1,o.doNotify(e)},e),o.notify=function(e){o.isDebouncing=!0,t(e)},o.flush=function(){return t.flush()},o.cancel=function(){o.isDebouncing=!1,t.cancel()})}),g(f(o),"doNotify",function(){o.props.onChange.apply(void 0,arguments)}),g(f(o),"forceNotify",function(e){var t,n=o.props.debounceTimeout;!o.isDebouncing&&0=t?o.doNotify(e):o.doNotify(p(p({},e),{},{target:p(p({},e.target),{},{value:n})})))}),o.isDebouncing=!1,o.state={value:void 0===e.value||null===e.value?"":e.value};e=o.props.debounceTimeout;return o.createNotifier(e),o}return t=i,(e=[{key:"componentDidUpdate",value:function(e){var t,n,r,o;this.isDebouncing||(t=(n=this.props).value,n=n.debounceTimeout,r=e.debounceTimeout,e=e.value,o=this.state.value,void 0!==t&&e!==t&&o!==t&&this.setState({value:t}),n!==r&&this.createNotifier(n))}},{key:"componentWillUnmount",value:function(){this.flush&&this.flush()}},{key:"render",value:function(){var e=this.props,t=e.element,n=(e.onChange,e.value,e.minLength,e.debounceTimeout,e.forceNotifyByEnter),r=e.forceNotifyOnBlur,o=e.onKeyDown,s=e.onBlur,i=e.inputRef,e=function(e,t){if(null==e)return{};var n,r=function(e,t){if(null==e)return{};for(var n,r={},o=Object.keys(e),s=0;s{"use strict";n=n(81214).DebounceInput;n.DebounceInput=n,e.exports=n},22551:(l,f,e)=>{"use strict";var O=e(96540),n=e(69982);function q(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n