From f711736de694115d471f44b057e45fa9be947844 Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Thu, 15 Aug 2024 08:26:06 -0500 Subject: [PATCH 1/4] refactor(parser): add from __future__ import annotations and update code according to ruff rules TCH, UP006, UP007, UP037 and FA100. --- .../utilities/parser/functions.py | 6 +- .../utilities/parser/models/alb.py | 8 +- .../utilities/parser/models/apigw.py | 84 +++++++++---------- .../utilities/parser/models/apigwv2.py | 50 +++++------ .../utilities/parser/models/bedrock_agent.py | 14 ++-- .../models/cloudformation_custom_resource.py | 10 +-- .../utilities/parser/models/cloudwatch.py | 13 +-- .../utilities/parser/models/dynamodb.py | 19 +++-- .../utilities/parser/models/event_bridge.py | 11 +-- .../utilities/parser/models/kafka.py | 15 ++-- .../utilities/parser/models/kinesis.py | 13 +-- .../parser/models/kinesis_firehose.py | 10 +-- .../parser/models/kinesis_firehose_sqs.py | 14 ++-- .../utilities/parser/models/s3.py | 38 ++++----- .../parser/models/s3_batch_operation.py | 18 ++-- .../parser/models/s3_event_notification.py | 8 +- .../parser/models/s3_object_event.py | 12 +-- .../utilities/parser/models/ses.py | 30 +++---- .../utilities/parser/models/sns.py | 25 +++--- .../utilities/parser/models/sqs.py | 32 +++---- .../utilities/parser/models/vpc_lattice.py | 8 +- .../utilities/parser/models/vpc_latticev2.py | 33 ++++---- .../utilities/parser/parser.py | 28 ++++--- .../utilities/parser/types.py | 8 +- 24 files changed, 260 insertions(+), 247 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/functions.py b/aws_lambda_powertools/utilities/parser/functions.py index 696437a6550..4cf3f131395 100644 --- a/aws_lambda_powertools/utilities/parser/functions.py +++ b/aws_lambda_powertools/utilities/parser/functions.py @@ -1,9 +1,13 @@ from __future__ import annotations +from typing import TYPE_CHECKING + from pydantic import TypeAdapter from aws_lambda_powertools.shared.cache_dict import LRUDict -from aws_lambda_powertools.utilities.parser.types import T + +if TYPE_CHECKING: + from aws_lambda_powertools.utilities.parser.types import T CACHE_TYPE_ADAPTER = LRUDict(max_items=1024) diff --git a/aws_lambda_powertools/utilities/parser/models/alb.py b/aws_lambda_powertools/utilities/parser/models/alb.py index d903e9f0fd8..1261b26c19e 100644 --- a/aws_lambda_powertools/utilities/parser/models/alb.py +++ b/aws_lambda_powertools/utilities/parser/models/alb.py @@ -1,4 +1,4 @@ -from typing import Dict, Type, Union +from __future__ import annotations from pydantic import BaseModel @@ -14,8 +14,8 @@ class AlbRequestContext(BaseModel): class AlbModel(BaseModel): httpMethod: str path: str - body: Union[str, Type[BaseModel]] + body: str | type[BaseModel] isBase64Encoded: bool - headers: Dict[str, str] - queryStringParameters: Dict[str, str] + headers: dict[str, str] + queryStringParameters: dict[str, str] requestContext: AlbRequestContext diff --git a/aws_lambda_powertools/utilities/parser/models/apigw.py b/aws_lambda_powertools/utilities/parser/models/apigw.py index 301360b556d..9d8caa43a6a 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigw.py +++ b/aws_lambda_powertools/utilities/parser/models/apigw.py @@ -1,10 +1,10 @@ -from datetime import datetime -from typing import Any, Dict, List, Optional, Type, Union +from __future__ import annotations -from pydantic import BaseModel, model_validator -from pydantic.networks import IPvAnyNetwork +from datetime import datetime # noqa: TCH003 +from typing import Any, Literal -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel, model_validator +from pydantic.networks import IPvAnyNetwork # noqa: TCH002 class ApiGatewayUserCertValidity(BaseModel): @@ -21,54 +21,54 @@ class ApiGatewayUserCert(BaseModel): class APIGatewayEventIdentity(BaseModel): - accessKey: Optional[str] = None - accountId: Optional[str] = None - apiKey: Optional[str] = None - apiKeyId: Optional[str] = None - caller: Optional[str] = None - cognitoAuthenticationProvider: Optional[str] = None - cognitoAuthenticationType: Optional[str] = None - cognitoIdentityId: Optional[str] = None - cognitoIdentityPoolId: Optional[str] = None - principalOrgId: Optional[str] = None + accessKey: str | None = None + accountId: str | None = None + apiKey: str | None = None + apiKeyId: str | None = None + caller: str | None = None + cognitoAuthenticationProvider: str | None = None + cognitoAuthenticationType: str | None = None + cognitoIdentityId: str | None = None + cognitoIdentityPoolId: str | None = None + principalOrgId: str | None = None # see #1562, temp workaround until API Gateway fixes it the Test button payload # removing it will not be considered a regression in the future - sourceIp: Union[IPvAnyNetwork, Literal["test-invoke-source-ip"]] - user: Optional[str] = None - userAgent: Optional[str] = None - userArn: Optional[str] = None - clientCert: Optional[ApiGatewayUserCert] = None + sourceIp: IPvAnyNetwork | Literal["test-invoke-source-ip"] + user: str | None = None + userAgent: str | None = None + userArn: str | None = None + clientCert: ApiGatewayUserCert | None = None class APIGatewayEventAuthorizer(BaseModel): - claims: Optional[Dict[str, Any]] = None - scopes: Optional[List[str]] = None + claims: dict[str, Any] | None = None + scopes: list[str] | None = None class APIGatewayEventRequestContext(BaseModel): accountId: str apiId: str - authorizer: Optional[APIGatewayEventAuthorizer] = None + authorizer: APIGatewayEventAuthorizer | None = None stage: str protocol: str identity: APIGatewayEventIdentity requestId: str requestTime: str requestTimeEpoch: datetime - resourceId: Optional[str] = None + resourceId: str | None = None resourcePath: str - domainName: Optional[str] = None - domainPrefix: Optional[str] = None - extendedRequestId: Optional[str] = None + domainName: str | None = None + domainPrefix: str | None = None + extendedRequestId: str | None = None httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] path: str - connectedAt: Optional[datetime] = None - connectionId: Optional[str] = None - eventType: Optional[Literal["CONNECT", "MESSAGE", "DISCONNECT"]] = None - messageDirection: Optional[str] = None - messageId: Optional[str] = None - routeKey: Optional[str] = None - operationName: Optional[str] = None + connectedAt: datetime | None = None + connectionId: str | None = None + eventType: Literal["CONNECT", "MESSAGE", "DISCONNECT"] | None = None + messageDirection: str | None = None + messageId: str | None = None + routeKey: str | None = None + operationName: str | None = None @model_validator(mode="before") def check_message_id(cls, values): @@ -79,16 +79,16 @@ def check_message_id(cls, values): class APIGatewayProxyEventModel(BaseModel): - version: Optional[str] = None + version: str | None = None resource: str path: str httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] - headers: Dict[str, str] - multiValueHeaders: Dict[str, List[str]] - queryStringParameters: Optional[Dict[str, str]] = None - multiValueQueryStringParameters: Optional[Dict[str, List[str]]] = None + headers: dict[str, str] + multiValueHeaders: dict[str, list[str]] + queryStringParameters: dict[str, str] | None = None + multiValueQueryStringParameters: dict[str, list[str]] | None = None requestContext: APIGatewayEventRequestContext - pathParameters: Optional[Dict[str, str]] = None - stageVariables: Optional[Dict[str, str]] = None + pathParameters: dict[str, str] | None = None + stageVariables: dict[str, str] | None = None isBase64Encoded: bool - body: Optional[Union[str, Type[BaseModel]]] = None + body: str | type[BaseModel] | None = None diff --git a/aws_lambda_powertools/utilities/parser/models/apigwv2.py b/aws_lambda_powertools/utilities/parser/models/apigwv2.py index 8f0f8dbf50c..829f0ff2f1b 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigwv2.py +++ b/aws_lambda_powertools/utilities/parser/models/apigwv2.py @@ -1,37 +1,37 @@ -from datetime import datetime -from typing import Any, Dict, List, Optional, Type, Union +from __future__ import annotations -from pydantic import BaseModel, Field -from pydantic.networks import IPvAnyNetwork +from datetime import datetime # noqa: TCH003 +from typing import Any, Literal -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel, Field +from pydantic.networks import IPvAnyNetwork # noqa: TCH002 class RequestContextV2AuthorizerIamCognito(BaseModel): - amr: List[str] + amr: list[str] identityId: str identityPoolId: str class RequestContextV2AuthorizerIam(BaseModel): - accessKey: Optional[str] = None - accountId: Optional[str] = None - callerId: Optional[str] = None - principalOrgId: Optional[str] = None - userArn: Optional[str] = None - userId: Optional[str] = None - cognitoIdentity: Optional[RequestContextV2AuthorizerIamCognito] = None + accessKey: str | None = None + accountId: str | None = None + callerId: str | None = None + principalOrgId: str | None = None + userArn: str | None = None + userId: str | None = None + cognitoIdentity: RequestContextV2AuthorizerIamCognito | None = None class RequestContextV2AuthorizerJwt(BaseModel): - claims: Dict[str, Any] - scopes: Optional[List[str]] = None + claims: dict[str, Any] + scopes: list[str] | None = None class RequestContextV2Authorizer(BaseModel): - jwt: Optional[RequestContextV2AuthorizerJwt] = None - iam: Optional[RequestContextV2AuthorizerIam] = None - lambda_value: Optional[Dict[str, Any]] = Field(None, alias="lambda") + jwt: RequestContextV2AuthorizerJwt | None = None + iam: RequestContextV2AuthorizerIam | None = None + lambda_value: dict[str, Any] | None = Field(None, alias="lambda") class RequestContextV2Http(BaseModel): @@ -45,7 +45,7 @@ class RequestContextV2Http(BaseModel): class RequestContextV2(BaseModel): accountId: str apiId: str - authorizer: Optional[RequestContextV2Authorizer] = None + authorizer: RequestContextV2Authorizer | None = None domainName: str domainPrefix: str requestId: str @@ -61,11 +61,11 @@ class APIGatewayProxyEventV2Model(BaseModel): routeKey: str rawPath: str rawQueryString: str - cookies: Optional[List[str]] = None - headers: Dict[str, str] - queryStringParameters: Optional[Dict[str, str]] = None - pathParameters: Optional[Dict[str, str]] = None - stageVariables: Optional[Dict[str, str]] = None + cookies: list[str] | None = None + headers: dict[str, str] + queryStringParameters: dict[str, str] | None = None + pathParameters: dict[str, str] | None = None + stageVariables: dict[str, str] | None = None requestContext: RequestContextV2 - body: Optional[Union[str, Type[BaseModel]]] = None + body: str | type[BaseModel] | None = None isBase64Encoded: bool diff --git a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py index 62465162167..800f8158aaa 100644 --- a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +++ b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py @@ -1,4 +1,4 @@ -from typing import Dict, List, Optional +from __future__ import annotations from pydantic import BaseModel, Field @@ -17,11 +17,11 @@ class BedrockAgentPropertyModel(BaseModel): class BedrockAgentRequestMediaModel(BaseModel): - properties: List[BedrockAgentPropertyModel] + properties: list[BedrockAgentPropertyModel] class BedrockAgentRequestBodyModel(BaseModel): - content: Dict[str, BedrockAgentRequestMediaModel] + content: dict[str, BedrockAgentRequestMediaModel] class BedrockAgentEventModel(BaseModel): @@ -31,8 +31,8 @@ class BedrockAgentEventModel(BaseModel): action_group: str = Field(..., alias="actionGroup") api_path: str = Field(..., alias="apiPath") http_method: str = Field(..., alias="httpMethod") - session_attributes: Dict[str, str] = Field({}, alias="sessionAttributes") - prompt_session_attributes: Dict[str, str] = Field({}, alias="promptSessionAttributes") + session_attributes: dict[str, str] = Field({}, alias="sessionAttributes") + prompt_session_attributes: dict[str, str] = Field({}, alias="promptSessionAttributes") agent: BedrockAgentModel - parameters: Optional[List[BedrockAgentPropertyModel]] = None - request_body: Optional[BedrockAgentRequestBodyModel] = Field(None, alias="requestBody") + parameters: list[BedrockAgentPropertyModel] | None = None + request_body: BedrockAgentRequestBodyModel | None = Field(None, alias="requestBody") diff --git a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py index 27e9ba996aa..4b8912519ae 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py @@ -1,8 +1,8 @@ -from typing import Any, Dict, Union +from __future__ import annotations -from pydantic import BaseModel, Field, HttpUrl +from typing import Any, Literal -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel, Field, HttpUrl class CloudFormationCustomResourceBaseModel(BaseModel): @@ -13,7 +13,7 @@ class CloudFormationCustomResourceBaseModel(BaseModel): request_id: str = Field(..., alias="RequestId") logical_resource_id: str = Field(..., alias="LogicalResourceId") resource_type: str = Field(..., alias="ResourceType") - resource_properties: Union[Dict[str, Any], BaseModel, None] = Field(None, alias="ResourceProperties") + resource_properties: dict[str, Any] | BaseModel | None = Field(None, alias="ResourceProperties") class CloudFormationCustomResourceCreateModel(CloudFormationCustomResourceBaseModel): @@ -28,4 +28,4 @@ class CloudFormationCustomResourceDeleteModel(CloudFormationCustomResourceBaseMo class CloudFormationCustomResourceUpdateModel(CloudFormationCustomResourceBaseModel): request_type: Literal["Update"] = Field(..., alias="RequestType") physical_resource_id: str = Field(..., alias="PhysicalResourceId") - old_resource_properties: Union[Dict[str, Any], BaseModel, None] = Field(None, alias="OldResourceProperties") + old_resource_properties: dict[str, Any] | BaseModel | None = Field(None, alias="OldResourceProperties") diff --git a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py index df464edd65e..0d590a93dd9 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py @@ -1,9 +1,10 @@ +from __future__ import annotations + import base64 import json import logging import zlib -from datetime import datetime -from typing import List, Optional, Type, Union +from datetime import datetime # noqa: TCH003 from pydantic import BaseModel, Field, field_validator @@ -13,7 +14,7 @@ class CloudWatchLogsLogEvent(BaseModel): id: str # noqa AA03 VNE003 timestamp: datetime - message: Union[str, Type[BaseModel]] + message: str | type[BaseModel] class CloudWatchLogsDecode(BaseModel): @@ -21,9 +22,9 @@ class CloudWatchLogsDecode(BaseModel): owner: str logGroup: str logStream: str - subscriptionFilters: List[str] - logEvents: List[CloudWatchLogsLogEvent] - policyLevel: Optional[str] = None + subscriptionFilters: list[str] + logEvents: list[CloudWatchLogsLogEvent] + policyLevel: str | None = None class CloudWatchLogsData(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/dynamodb.py b/aws_lambda_powertools/utilities/parser/models/dynamodb.py index 7a3581ab13f..0df0490d675 100644 --- a/aws_lambda_powertools/utilities/parser/models/dynamodb.py +++ b/aws_lambda_powertools/utilities/parser/models/dynamodb.py @@ -1,19 +1,20 @@ -from datetime import datetime -from typing import Any, Dict, List, Optional, Type, Union +from __future__ import annotations + +from datetime import datetime # noqa: TCH003 +from typing import Any, Literal from pydantic import BaseModel, field_validator from aws_lambda_powertools.shared.dynamodb_deserializer import TypeDeserializer -from aws_lambda_powertools.utilities.parser.types import Literal _DESERIALIZER = TypeDeserializer() class DynamoDBStreamChangedRecordModel(BaseModel): - ApproximateCreationDateTime: Optional[datetime] = None - Keys: Dict[str, Any] - NewImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = None - OldImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = None + ApproximateCreationDateTime: datetime | None = None + Keys: dict[str, Any] + NewImage: dict[str, Any] | type[BaseModel] | BaseModel | None = None + OldImage: dict[str, Any] | type[BaseModel] | BaseModel | None = None SequenceNumber: str SizeBytes: int StreamViewType: Literal["NEW_AND_OLD_IMAGES", "KEYS_ONLY", "NEW_IMAGE", "OLD_IMAGE"] @@ -47,8 +48,8 @@ class DynamoDBStreamRecordModel(BaseModel): awsRegion: str eventSourceARN: str dynamodb: DynamoDBStreamChangedRecordModel - userIdentity: Optional[UserIdentity] = None + userIdentity: UserIdentity | None = None class DynamoDBStreamModel(BaseModel): - Records: List[DynamoDBStreamRecordModel] + Records: list[DynamoDBStreamRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/event_bridge.py b/aws_lambda_powertools/utilities/parser/models/event_bridge.py index eab6c54d12d..2c49c7f6977 100644 --- a/aws_lambda_powertools/utilities/parser/models/event_bridge.py +++ b/aws_lambda_powertools/utilities/parser/models/event_bridge.py @@ -1,9 +1,10 @@ -from datetime import datetime -from typing import List, Optional +from __future__ import annotations + +from datetime import datetime # noqa: TCH003 from pydantic import BaseModel, Field -from aws_lambda_powertools.utilities.parser.types import RawDictOrModel +from aws_lambda_powertools.utilities.parser.types import RawDictOrModel # noqa: TCH001 class EventBridgeModel(BaseModel): @@ -13,7 +14,7 @@ class EventBridgeModel(BaseModel): account: str time: datetime region: str - resources: List[str] + resources: list[str] detail_type: str = Field(None, alias="detail-type") detail: RawDictOrModel - replay_name: Optional[str] = Field(None, alias="replay-name") + replay_name: str | None = Field(None, alias="replay-name") diff --git a/aws_lambda_powertools/utilities/parser/models/kafka.py b/aws_lambda_powertools/utilities/parser/models/kafka.py index ea81408d301..d085ba2535d 100644 --- a/aws_lambda_powertools/utilities/parser/models/kafka.py +++ b/aws_lambda_powertools/utilities/parser/models/kafka.py @@ -1,10 +1,11 @@ -from datetime import datetime -from typing import Dict, List, Type, Union +from __future__ import annotations + +from datetime import datetime # noqa: TCH003 +from typing import Literal from pydantic import BaseModel, field_validator from aws_lambda_powertools.shared.functions import base64_decode, bytes_to_string -from aws_lambda_powertools.utilities.parser.types import Literal SERVERS_DELIMITER = "," @@ -16,8 +17,8 @@ class KafkaRecordModel(BaseModel): timestamp: datetime timestampType: str key: bytes - value: Union[str, Type[BaseModel]] - headers: List[Dict[str, bytes]] + value: str | type[BaseModel] + headers: list[dict[str, bytes]] # Added type ignore to keep compatibility between Pydantic v1 and v2 _decode_key = field_validator("key")(base64_decode) # type: ignore[type-var, unused-ignore] @@ -36,8 +37,8 @@ def decode_headers_list(cls, value): class KafkaBaseEventModel(BaseModel): - bootstrapServers: List[str] - records: Dict[str, List[KafkaRecordModel]] + bootstrapServers: list[str] + records: dict[str, list[KafkaRecordModel]] @field_validator("bootstrapServers", mode="before") def split_servers(cls, value): diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis.py b/aws_lambda_powertools/utilities/parser/models/kinesis.py index be81eb5fa92..68633a3b117 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis.py @@ -1,6 +1,8 @@ +from __future__ import annotations + import json import zlib -from typing import Dict, List, Type, Union +from typing import Literal from pydantic import BaseModel, field_validator @@ -8,14 +10,13 @@ from aws_lambda_powertools.utilities.parser.models.cloudwatch import ( CloudWatchLogsDecode, ) -from aws_lambda_powertools.utilities.parser.types import Literal class KinesisDataStreamRecordPayload(BaseModel): kinesisSchemaVersion: str partitionKey: str sequenceNumber: str - data: Union[bytes, Type[BaseModel], BaseModel] # base64 encoded str is parsed into bytes + data: bytes | type[BaseModel] | BaseModel # base64 encoded str is parsed into bytes approximateArrivalTimestamp: float @field_validator("data", mode="before") @@ -33,7 +34,7 @@ class KinesisDataStreamRecord(BaseModel): eventSourceARN: str kinesis: KinesisDataStreamRecordPayload - def decompress_zlib_record_data_as_json(self) -> Dict: + def decompress_zlib_record_data_as_json(self) -> dict: """Decompress Kinesis Record bytes data zlib compressed to JSON""" if not isinstance(self.kinesis.data, bytes): raise ValueError("We can only decompress bytes data, not custom models.") @@ -42,10 +43,10 @@ def decompress_zlib_record_data_as_json(self) -> Dict: class KinesisDataStreamModel(BaseModel): - Records: List[KinesisDataStreamRecord] + Records: list[KinesisDataStreamRecord] -def extract_cloudwatch_logs_from_event(event: KinesisDataStreamModel) -> List[CloudWatchLogsDecode]: +def extract_cloudwatch_logs_from_event(event: KinesisDataStreamModel) -> list[CloudWatchLogsDecode]: return [CloudWatchLogsDecode(**record.decompress_zlib_record_data_as_json()) for record in event.Records] diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py index 6c50b93b9a7..9a37286b81d 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Type, Union +from __future__ import annotations from pydantic import BaseModel, PositiveInt, field_validator @@ -14,10 +14,10 @@ class KinesisFirehoseRecordMetadata(BaseModel): class KinesisFirehoseRecord(BaseModel): - data: Union[bytes, Type[BaseModel]] # base64 encoded str is parsed into bytes + data: bytes | type[BaseModel] # base64 encoded str is parsed into bytes recordId: str approximateArrivalTimestamp: PositiveInt - kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = None + kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = None @field_validator("data", mode="before") def data_base64_decode(cls, value): @@ -28,5 +28,5 @@ class KinesisFirehoseModel(BaseModel): invocationId: str deliveryStreamArn: str region: str - sourceKinesisStreamArn: Optional[str] = None - records: List[KinesisFirehoseRecord] + sourceKinesisStreamArn: str | None = None + records: list[KinesisFirehoseRecord] diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py index 7117fc4a011..42e84b7a421 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py @@ -1,19 +1,19 @@ +from __future__ import annotations + import json -from typing import List, Optional from pydantic import BaseModel, PositiveInt, field_validator from aws_lambda_powertools.shared.functions import base64_decode -from aws_lambda_powertools.utilities.parser.models import KinesisFirehoseRecordMetadata - -from .sqs import SqsRecordModel +from aws_lambda_powertools.utilities.parser.models import KinesisFirehoseRecordMetadata # noqa: TCH001 +from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel # noqa: TCH001 class KinesisFirehoseSqsRecord(BaseModel): data: SqsRecordModel recordId: str approximateArrivalTimestamp: PositiveInt - kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = None + kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = None @field_validator("data", mode="before") def data_base64_decode(cls, value): @@ -25,5 +25,5 @@ class KinesisFirehoseSqsModel(BaseModel): invocationId: str deliveryStreamArn: str region: str - sourceKinesisStreamArn: Optional[str] = None - records: List[KinesisFirehoseSqsRecord] + sourceKinesisStreamArn: str | None = None + records: list[KinesisFirehoseSqsRecord] diff --git a/aws_lambda_powertools/utilities/parser/models/s3.py b/aws_lambda_powertools/utilities/parser/models/s3.py index cfba76fb078..732a6290b92 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3.py +++ b/aws_lambda_powertools/utilities/parser/models/s3.py @@ -1,12 +1,12 @@ -from datetime import datetime -from typing import List, Optional +from __future__ import annotations + +from datetime import datetime # noqa: TCH003 +from typing import Literal from pydantic import BaseModel, model_validator from pydantic.fields import Field -from pydantic.networks import IPvAnyNetwork -from pydantic.types import NonNegativeFloat - -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic.networks import IPvAnyNetwork # noqa: TCH002 +from pydantic.types import NonNegativeFloat # noqa: TCH002 from .event_bridge import EventBridgeModel @@ -45,10 +45,10 @@ class S3Bucket(BaseModel): class S3Object(BaseModel): key: str - size: Optional[NonNegativeFloat] = None - eTag: Optional[str] = None + size: NonNegativeFloat | None = None + eTag: str | None = None sequencer: str - versionId: Optional[str] = None + versionId: str | None = None class S3Message(BaseModel): @@ -60,10 +60,10 @@ class S3Message(BaseModel): class S3EventNotificationObjectModel(BaseModel): key: str - size: Optional[NonNegativeFloat] = None + size: NonNegativeFloat | None = None etag: str = Field(default="") version_id: str = Field(None, alias="version-id") - sequencer: Optional[str] = None + sequencer: str | None = None class S3EventNotificationEventBridgeBucketModel(BaseModel): @@ -77,12 +77,12 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): request_id: str = Field(None, alias="request-id") requester: str source_ip_address: str = Field(None, alias="source-ip-address") - reason: Optional[str] = None - deletion_type: Optional[str] = Field(None, alias="deletion-type") - restore_expiry_time: Optional[str] = Field(None, alias="restore-expiry-time") - source_storage_class: Optional[str] = Field(None, alias="source-storage-class") - destination_storage_class: Optional[str] = Field(None, alias="destination-storage-class") - destination_access_tier: Optional[str] = Field(None, alias="destination-access-tier") + reason: str | None = None + deletion_type: str | None = Field(None, alias="deletion-type") + restore_expiry_time: str | None = Field(None, alias="restore-expiry-time") + source_storage_class: str | None = Field(None, alias="source-storage-class") + destination_storage_class: str | None = Field(None, alias="destination-storage-class") + destination_access_tier: str | None = Field(None, alias="destination-access-tier") class S3EventNotificationEventBridgeModel(EventBridgeModel): @@ -99,7 +99,7 @@ class S3RecordModel(BaseModel): requestParameters: S3RequestParameters responseElements: S3ResponseElements s3: S3Message - glacierEventData: Optional[S3EventRecordGlacierEventData] = None + glacierEventData: S3EventRecordGlacierEventData | None = None @model_validator(mode="before") def validate_s3_object(cls, values): @@ -111,4 +111,4 @@ def validate_s3_object(cls, values): class S3Model(BaseModel): - Records: List[S3RecordModel] + Records: list[S3RecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py index affff0921fb..97cf570822e 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py @@ -1,19 +1,19 @@ -from typing import Any, Dict, List, Optional +from __future__ import annotations -from pydantic import BaseModel, model_validator +from typing import Any, Literal -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel, model_validator class S3BatchOperationTaskModel(BaseModel): taskId: str s3Key: str - s3VersionId: Optional[str] = None - s3BucketArn: Optional[str] = None - s3Bucket: Optional[str] = None + s3VersionId: str | None = None + s3BucketArn: str | None = None + s3Bucket: str | None = None @model_validator(mode="before") - def validate_s3bucket(cls, values: Dict[str, Any]) -> Dict[str, Any]: + def validate_s3bucket(cls, values: dict[str, Any]) -> dict[str, Any]: if values.get("s3BucketArn") and not values.get("s3Bucket"): values["s3Bucket"] = values["s3BucketArn"].split(":::")[-1] @@ -22,11 +22,11 @@ def validate_s3bucket(cls, values: Dict[str, Any]) -> Dict[str, Any]: class S3BatchOperationJobModel(BaseModel): id: str - userArguments: Optional[Dict[str, Any]] = None + userArguments: dict[str, Any] | None = None class S3BatchOperationModel(BaseModel): invocationId: str invocationSchemaVersion: Literal["1.0", "2.0"] job: S3BatchOperationJobModel - tasks: List[S3BatchOperationTaskModel] + tasks: list[S3BatchOperationTaskModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index 1bcbc83ac18..b4687c0dd37 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -1,8 +1,8 @@ -from typing import List +from __future__ import annotations -from pydantic import Json +from pydantic import Json # noqa: TCH002 -from aws_lambda_powertools.utilities.parser.models.s3 import S3Model +from aws_lambda_powertools.utilities.parser.models.s3 import S3Model # noqa: TCH001 from aws_lambda_powertools.utilities.parser.models.sqs import SqsModel, SqsRecordModel @@ -11,4 +11,4 @@ class S3SqsEventNotificationRecordModel(SqsRecordModel): class S3SqsEventNotificationModel(SqsModel): - Records: List[S3SqsEventNotificationRecordModel] + Records: list[S3SqsEventNotificationRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py index 867cd996fa0..0a4c0d9ff6e 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py @@ -1,4 +1,4 @@ -from typing import Dict, Optional, Type, Union +from __future__ import annotations from pydantic import BaseModel, HttpUrl @@ -12,17 +12,17 @@ class S3ObjectContext(BaseModel): class S3ObjectConfiguration(BaseModel): accessPointArn: str supportingAccessPointArn: str - payload: Union[str, Type[BaseModel]] + payload: str | type[BaseModel] class S3ObjectUserRequest(BaseModel): url: str - headers: Dict[str, str] + headers: dict[str, str] class S3ObjectSessionIssuer(BaseModel): type: str # noqa: A003, VNE003 - userName: Optional[str] = None + userName: str | None = None principalId: str arn: str accountId: str @@ -42,10 +42,10 @@ class S3ObjectUserIdentity(BaseModel): type: str # noqa: A003 accountId: str accessKeyId: str - userName: Optional[str] = None + userName: str | None = None principalId: str arn: str - sessionContext: Optional[S3ObjectSessionContext] = None + sessionContext: S3ObjectSessionContext | None = None class S3ObjectLambdaEvent(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/ses.py b/aws_lambda_powertools/utilities/parser/models/ses.py index 2e9e93f368e..c96c7b8602f 100644 --- a/aws_lambda_powertools/utilities/parser/models/ses.py +++ b/aws_lambda_powertools/utilities/parser/models/ses.py @@ -1,10 +1,10 @@ -from datetime import datetime -from typing import List, Optional +from __future__ import annotations -from pydantic import BaseModel, Field -from pydantic.types import PositiveInt +from datetime import datetime # noqa: TCH003 +from typing import Literal -from ..types import Literal +from pydantic import BaseModel, Field +from pydantic.types import PositiveInt # noqa: TCH002 class SesReceiptVerdict(BaseModel): @@ -20,7 +20,7 @@ class SesReceiptAction(BaseModel): class SesReceipt(BaseModel): timestamp: datetime processingTimeMillis: PositiveInt - recipients: List[str] + recipients: list[str] spamVerdict: SesReceiptVerdict virusVerdict: SesReceiptVerdict spfVerdict: SesReceiptVerdict @@ -34,12 +34,12 @@ class SesMailHeaders(BaseModel): class SesMailCommonHeaders(BaseModel): - header_from: List[str] = Field(None, alias="from") - to: List[str] - cc: Optional[List[str]] = None - bcc: Optional[List[str]] = None - sender: Optional[List[str]] = None - reply_to: Optional[List[str]] = Field(None, alias="reply-to") + header_from: list[str] = Field(None, alias="from") + to: list[str] + cc: list[str] | None = None + bcc: list[str] | None = None + sender: list[str] | None = None + reply_to: list[str] | None = Field(None, alias="reply-to") returnPath: str messageId: str date: str @@ -50,9 +50,9 @@ class SesMail(BaseModel): timestamp: datetime source: str messageId: str - destination: List[str] + destination: list[str] headersTruncated: bool - headers: List[SesMailHeaders] + headers: list[SesMailHeaders] commonHeaders: SesMailCommonHeaders @@ -68,4 +68,4 @@ class SesRecordModel(BaseModel): class SesModel(BaseModel): - Records: List[SesRecordModel] + Records: list[SesRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/sns.py b/aws_lambda_powertools/utilities/parser/models/sns.py index 6dccf956f8a..b94c7a4d952 100644 --- a/aws_lambda_powertools/utilities/parser/models/sns.py +++ b/aws_lambda_powertools/utilities/parser/models/sns.py @@ -1,11 +1,10 @@ -from datetime import datetime -from typing import Dict, List, Optional, Union -from typing import Type as TypingType +from __future__ import annotations -from pydantic import BaseModel, model_validator -from pydantic.networks import HttpUrl +from datetime import datetime # noqa: TCH003 +from typing import Literal -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel, model_validator +from pydantic.networks import HttpUrl # noqa: TCH002 class SnsMsgAttributeModel(BaseModel): @@ -14,17 +13,17 @@ class SnsMsgAttributeModel(BaseModel): class SnsNotificationModel(BaseModel): - Subject: Optional[str] = None + Subject: str | None = None TopicArn: str UnsubscribeUrl: HttpUrl Type: Literal["Notification"] - MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = None - Message: Union[str, TypingType[BaseModel]] + MessageAttributes: dict[str, SnsMsgAttributeModel] | None = None + Message: str | type[BaseModel] MessageId: str - SigningCertUrl: Optional[HttpUrl] = None # NOTE: FIFO opt-in removes attribute - Signature: Optional[str] = None # NOTE: FIFO opt-in removes attribute + SigningCertUrl: HttpUrl | None = None # NOTE: FIFO opt-in removes attribute + Signature: str | None = None # NOTE: FIFO opt-in removes attribute Timestamp: datetime - SignatureVersion: Optional[str] = None # NOTE: FIFO opt-in removes attribute + SignatureVersion: str | None = None # NOTE: FIFO opt-in removes attribute @model_validator(mode="before") def check_sqs_protocol(cls, values): @@ -46,4 +45,4 @@ class SnsRecordModel(BaseModel): class SnsModel(BaseModel): - Records: List[SnsRecordModel] + Records: list[SnsRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/sqs.py b/aws_lambda_powertools/utilities/parser/models/sqs.py index 317b76c3227..4e80320e46d 100644 --- a/aws_lambda_powertools/utilities/parser/models/sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/sqs.py @@ -1,28 +1,28 @@ -from datetime import datetime -from typing import Dict, List, Optional, Sequence, Type, Union +from __future__ import annotations -from pydantic import BaseModel +from datetime import datetime # noqa: TCH003 +from typing import Literal, Sequence -from aws_lambda_powertools.utilities.parser.types import Literal +from pydantic import BaseModel class SqsAttributesModel(BaseModel): ApproximateReceiveCount: str ApproximateFirstReceiveTimestamp: datetime - MessageDeduplicationId: Optional[str] = None - MessageGroupId: Optional[str] = None + MessageDeduplicationId: str | None = None + MessageGroupId: str | None = None SenderId: str SentTimestamp: datetime - SequenceNumber: Optional[str] = None - AWSTraceHeader: Optional[str] = None - DeadLetterQueueSourceArn: Optional[str] = None + SequenceNumber: str | None = None + AWSTraceHeader: str | None = None + DeadLetterQueueSourceArn: str | None = None class SqsMsgAttributeModel(BaseModel): - stringValue: Optional[str] = None - binaryValue: Optional[str] = None - stringListValues: List[str] = [] - binaryListValues: List[str] = [] + stringValue: str | None = None + binaryValue: str | None = None + stringListValues: list[str] = [] + binaryListValues: list[str] = [] dataType: str # context on why it's commented: https://github.com/aws-powertools/powertools-lambda-python/pull/118 @@ -53,11 +53,11 @@ class SqsMsgAttributeModel(BaseModel): class SqsRecordModel(BaseModel): messageId: str receiptHandle: str - body: Union[str, Type[BaseModel], BaseModel] + body: str | type[BaseModel] | BaseModel attributes: SqsAttributesModel - messageAttributes: Dict[str, SqsMsgAttributeModel] + messageAttributes: dict[str, SqsMsgAttributeModel] md5OfBody: str - md5OfMessageAttributes: Optional[str] = None + md5OfMessageAttributes: str | None = None eventSource: Literal["aws:sqs"] eventSourceARN: str awsRegion: str diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py index 8442fc92781..b25f9d2018d 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py @@ -1,4 +1,4 @@ -from typing import Dict, Type, Union +from __future__ import annotations from pydantic import BaseModel @@ -6,7 +6,7 @@ class VpcLatticeModel(BaseModel): method: str raw_path: str - body: Union[str, Type[BaseModel]] + body: str | type[BaseModel] is_base64_encoded: bool - headers: Dict[str, str] - query_string_parameters: Dict[str, str] + headers: dict[str, str] + query_string_parameters: dict[str, str] diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py index 3d4b616d135..8ee7129c93f 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py @@ -1,20 +1,21 @@ -from datetime import datetime -from typing import Dict, Optional, Type, Union +from __future__ import annotations + +from datetime import datetime # noqa: TCH003 from pydantic import BaseModel, Field, field_validator class VpcLatticeV2RequestContextIdentity(BaseModel): - source_vpc_arn: Optional[str] = Field(None, alias="sourceVpcArn") - get_type: Optional[str] = Field(None, alias="type") - principal: Optional[str] = Field(None, alias="principal") - principal_org_id: Optional[str] = Field(None, alias="principalOrgID") - session_name: Optional[str] = Field(None, alias="sessionName") - x509_subject_cn: Optional[str] = Field(None, alias="X509SubjectCn") - x509_issuer_ou: Optional[str] = Field(None, alias="X509IssuerOu") - x509_san_dns: Optional[str] = Field(None, alias="x509SanDns") - x509_san_uri: Optional[str] = Field(None, alias="X509SanUri") - x509_san_name_cn: Optional[str] = Field(None, alias="X509SanNameCn") + source_vpc_arn: str | None = Field(None, alias="sourceVpcArn") + get_type: str | None = Field(None, alias="type") + principal: str | None = Field(None, alias="principal") + principal_org_id: str | None = Field(None, alias="principalOrgID") + session_name: str | None = Field(None, alias="sessionName") + x509_subject_cn: str | None = Field(None, alias="X509SubjectCn") + x509_issuer_ou: str | None = Field(None, alias="X509IssuerOu") + x509_san_dns: str | None = Field(None, alias="x509SanDns") + x509_san_uri: str | None = Field(None, alias="X509SanUri") + x509_san_name_cn: str | None = Field(None, alias="X509SanNameCn") class VpcLatticeV2RequestContext(BaseModel): @@ -35,8 +36,8 @@ class VpcLatticeV2Model(BaseModel): version: str path: str method: str - headers: Dict[str, str] - query_string_parameters: Optional[Dict[str, str]] = Field(None, alias="queryStringParameters") - body: Optional[Union[str, Type[BaseModel]]] = None - is_base64_encoded: Optional[bool] = Field(None, alias="isBase64Encoded") + headers: dict[str, str] + query_string_parameters: dict[str, str] | None = Field(None, alias="queryStringParameters") + body: str | type[BaseModel] | None = None + is_base64_encoded: bool | None = Field(None, alias="isBase64Encoded") request_context: VpcLatticeV2RequestContext = Field(None, alias="requestContext") diff --git a/aws_lambda_powertools/utilities/parser/parser.py b/aws_lambda_powertools/utilities/parser/parser.py index 26a6c439704..3d2f236c75e 100644 --- a/aws_lambda_powertools/utilities/parser/parser.py +++ b/aws_lambda_powertools/utilities/parser/parser.py @@ -2,16 +2,18 @@ import logging import typing -from typing import Any, Callable, Dict, Optional, Type, overload +from typing import TYPE_CHECKING, Any, Callable, overload from pydantic import PydanticSchemaGenerationError, ValidationError from aws_lambda_powertools.middleware_factory import lambda_handler_decorator -from aws_lambda_powertools.utilities.parser.envelopes.base import Envelope from aws_lambda_powertools.utilities.parser.exceptions import InvalidEnvelopeError, InvalidModelTypeError from aws_lambda_powertools.utilities.parser.functions import _retrieve_or_set_model_from_cache -from aws_lambda_powertools.utilities.parser.types import EventParserReturnType, T -from aws_lambda_powertools.utilities.typing import LambdaContext + +if TYPE_CHECKING: + from aws_lambda_powertools.utilities.parser.envelopes.base import Envelope + from aws_lambda_powertools.utilities.parser.types import EventParserReturnType, T + from aws_lambda_powertools.utilities.typing import LambdaContext logger = logging.getLogger(__name__) @@ -19,10 +21,10 @@ @lambda_handler_decorator def event_parser( handler: Callable[..., EventParserReturnType], - event: Dict[str, Any], + event: dict[str, Any], context: LambdaContext, - model: Optional[type[T]] = None, - envelope: Optional[Type[Envelope]] = None, + model: type[T] | None = None, + envelope: type[Envelope] | None = None, **kwargs: Any, ) -> EventParserReturnType: """Lambda handler decorator to parse & validate events using Pydantic models @@ -67,11 +69,11 @@ def handler(event: Order, context: LambdaContext): ---------- handler: Callable Method to annotate on - event: Dict + event: dict Lambda event to be parsed & validated context: LambdaContext Lambda context object - model: Optional[type[T]] + model: type[T] | None Your data model that will replace the event. envelope: Envelope Optional envelope to extract the model from @@ -111,14 +113,14 @@ def handler(event: Order, context: LambdaContext): @overload -def parse(event: Dict[str, Any], model: type[T]) -> T: ... # pragma: no cover +def parse(event: dict[str, Any], model: type[T]) -> T: ... # pragma: no cover @overload -def parse(event: Dict[str, Any], model: type[T], envelope: Type[Envelope]) -> T: ... # pragma: no cover +def parse(event: dict[str, Any], model: type[T], envelope: type[Envelope]) -> T: ... # pragma: no cover -def parse(event: Dict[str, Any], model: type[T], envelope: Optional[Type[Envelope]] = None): +def parse(event: dict[str, Any], model: type[T], envelope: type[Envelope] | None = None): """Standalone function to parse & validate events using Pydantic models Typically used when you need fine-grained control over error handling compared to event_parser decorator. @@ -156,7 +158,7 @@ def handler(event: Order, context: LambdaContext): Parameters ---------- - event: Dict + event: dict Lambda event to be parsed & validated model: Model Your data model that will replace the event diff --git a/aws_lambda_powertools/utilities/parser/types.py b/aws_lambda_powertools/utilities/parser/types.py index 91bf9a9119e..31242c1c121 100644 --- a/aws_lambda_powertools/utilities/parser/types.py +++ b/aws_lambda_powertools/utilities/parser/types.py @@ -1,14 +1,16 @@ """Generics and other shared types used across parser""" -from typing import Any, Dict, Literal, Type, TypeVar, Union +from __future__ import annotations + +from typing import Any, Literal, TypeVar from pydantic import BaseModel, Json Model = TypeVar("Model", bound=BaseModel) EnvelopeModel = TypeVar("EnvelopeModel") EventParserReturnType = TypeVar("EventParserReturnType") -AnyInheritedModel = Union[Type[BaseModel], BaseModel] -RawDictOrModel = Union[Dict[str, Any], AnyInheritedModel] +AnyInheritedModel = type[BaseModel] | BaseModel +RawDictOrModel = dict[str, Any] | AnyInheritedModel T = TypeVar("T") __all__ = ["Json", "Literal"] From 6406f59ef4a2ec8492dd2f14b93b56e5431cd19c Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Thu, 15 Aug 2024 13:28:47 -0500 Subject: [PATCH 2/4] Fix type alias with Python 3.8 See https://bugs.python.org/issue45117 --- aws_lambda_powertools/utilities/parser/types.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/types.py b/aws_lambda_powertools/utilities/parser/types.py index 31242c1c121..cd967b90287 100644 --- a/aws_lambda_powertools/utilities/parser/types.py +++ b/aws_lambda_powertools/utilities/parser/types.py @@ -2,15 +2,15 @@ from __future__ import annotations -from typing import Any, Literal, TypeVar +from typing import Any, Dict, Literal, TypeVar, Union from pydantic import BaseModel, Json Model = TypeVar("Model", bound=BaseModel) EnvelopeModel = TypeVar("EnvelopeModel") EventParserReturnType = TypeVar("EventParserReturnType") -AnyInheritedModel = type[BaseModel] | BaseModel -RawDictOrModel = dict[str, Any] | AnyInheritedModel +AnyInheritedModel = Union[type[BaseModel], BaseModel] +RawDictOrModel = Union[Dict[str, Any], AnyInheritedModel] T = TypeVar("T") __all__ = ["Json", "Literal"] From a1baf632d6d149b7e96d7e4c4bcff918fc0b50e0 Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Thu, 15 Aug 2024 17:56:44 -0500 Subject: [PATCH 3/4] Fix pydantic not working with Python 3.8 TypeError: You have a type annotation 'str | None' which makes use of newer typing features than are supported in your version of Python. To handle this error, you should either remove the use of new syntax or install the `eval_type_backport` package. --- .../utilities/parser/models/alb.py | 9 +- .../utilities/parser/models/apigw.py | 83 +++++++++---------- .../utilities/parser/models/apigwv2.py | 49 ++++++----- .../utilities/parser/models/bedrock_agent.py | 15 ++-- .../models/cloudformation_custom_resource.py | 9 +- .../utilities/parser/models/cloudwatch.py | 14 ++-- .../utilities/parser/models/dynamodb.py | 19 ++--- .../utilities/parser/models/event_bridge.py | 12 +-- .../utilities/parser/models/kafka.py | 15 ++-- .../utilities/parser/models/kinesis.py | 13 ++- .../parser/models/kinesis_firehose.py | 11 +-- .../parser/models/kinesis_firehose_sqs.py | 15 ++-- .../utilities/parser/models/s3.py | 37 ++++----- .../parser/models/s3_batch_operation.py | 17 ++-- .../parser/models/s3_event_notification.py | 9 +- .../parser/models/s3_object_event.py | 13 +-- .../utilities/parser/models/ses.py | 29 ++++--- .../utilities/parser/models/sns.py | 24 +++--- .../utilities/parser/models/sqs.py | 31 ++++--- .../utilities/parser/models/vpc_lattice.py | 9 +- .../utilities/parser/models/vpc_latticev2.py | 34 ++++---- .../utilities/parser/types.py | 6 +- 22 files changed, 234 insertions(+), 239 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/models/alb.py b/aws_lambda_powertools/utilities/parser/models/alb.py index 1261b26c19e..7b2abf4c32a 100644 --- a/aws_lambda_powertools/utilities/parser/models/alb.py +++ b/aws_lambda_powertools/utilities/parser/models/alb.py @@ -1,4 +1,5 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import Dict, Type, Union from pydantic import BaseModel @@ -14,8 +15,8 @@ class AlbRequestContext(BaseModel): class AlbModel(BaseModel): httpMethod: str path: str - body: str | type[BaseModel] + body: Union[str, Type[BaseModel]] isBase64Encoded: bool - headers: dict[str, str] - queryStringParameters: dict[str, str] + headers: Dict[str, str] + queryStringParameters: Dict[str, str] requestContext: AlbRequestContext diff --git a/aws_lambda_powertools/utilities/parser/models/apigw.py b/aws_lambda_powertools/utilities/parser/models/apigw.py index 9d8caa43a6a..bd239e00e61 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigw.py +++ b/aws_lambda_powertools/utilities/parser/models/apigw.py @@ -1,10 +1,9 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Any, Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import Any, Dict, List, Literal, Optional, Type, Union from pydantic import BaseModel, model_validator -from pydantic.networks import IPvAnyNetwork # noqa: TCH002 +from pydantic.networks import IPvAnyNetwork class ApiGatewayUserCertValidity(BaseModel): @@ -21,54 +20,54 @@ class ApiGatewayUserCert(BaseModel): class APIGatewayEventIdentity(BaseModel): - accessKey: str | None = None - accountId: str | None = None - apiKey: str | None = None - apiKeyId: str | None = None - caller: str | None = None - cognitoAuthenticationProvider: str | None = None - cognitoAuthenticationType: str | None = None - cognitoIdentityId: str | None = None - cognitoIdentityPoolId: str | None = None - principalOrgId: str | None = None + accessKey: Optional[str] = None + accountId: Optional[str] = None + apiKey: Optional[str] = None + apiKeyId: Optional[str] = None + caller: Optional[str] = None + cognitoAuthenticationProvider: Optional[str] = None + cognitoAuthenticationType: Optional[str] = None + cognitoIdentityId: Optional[str] = None + cognitoIdentityPoolId: Optional[str] = None + principalOrgId: Optional[str] = None # see #1562, temp workaround until API Gateway fixes it the Test button payload # removing it will not be considered a regression in the future - sourceIp: IPvAnyNetwork | Literal["test-invoke-source-ip"] - user: str | None = None - userAgent: str | None = None - userArn: str | None = None - clientCert: ApiGatewayUserCert | None = None + sourceIp: Union[IPvAnyNetwork, Literal["test-invoke-source-ip"]] + user: Optional[str] = None + userAgent: Optional[str] = None + userArn: Optional[str] = None + clientCert: Optional[ApiGatewayUserCert] = None class APIGatewayEventAuthorizer(BaseModel): - claims: dict[str, Any] | None = None - scopes: list[str] | None = None + claims: Optional[Dict[str, Any]] = None + scopes: Optional[List[str]] = None class APIGatewayEventRequestContext(BaseModel): accountId: str apiId: str - authorizer: APIGatewayEventAuthorizer | None = None + authorizer: Optional[APIGatewayEventAuthorizer] = None stage: str protocol: str identity: APIGatewayEventIdentity requestId: str requestTime: str requestTimeEpoch: datetime - resourceId: str | None = None + resourceId: Optional[str] = None resourcePath: str - domainName: str | None = None - domainPrefix: str | None = None - extendedRequestId: str | None = None + domainName: Optional[str] = None + domainPrefix: Optional[str] = None + extendedRequestId: Optional[str] = None httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] path: str - connectedAt: datetime | None = None - connectionId: str | None = None - eventType: Literal["CONNECT", "MESSAGE", "DISCONNECT"] | None = None - messageDirection: str | None = None - messageId: str | None = None - routeKey: str | None = None - operationName: str | None = None + connectedAt: Optional[datetime] = None + connectionId: Optional[str] = None + eventType: Optional[Literal["CONNECT", "MESSAGE", "DISCONNECT"]] = None + messageDirection: Optional[str] = None + messageId: Optional[str] = None + routeKey: Optional[str] = None + operationName: Optional[str] = None @model_validator(mode="before") def check_message_id(cls, values): @@ -79,16 +78,16 @@ def check_message_id(cls, values): class APIGatewayProxyEventModel(BaseModel): - version: str | None = None + version: Optional[str] = None resource: str path: str httpMethod: Literal["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"] - headers: dict[str, str] - multiValueHeaders: dict[str, list[str]] - queryStringParameters: dict[str, str] | None = None - multiValueQueryStringParameters: dict[str, list[str]] | None = None + headers: Dict[str, str] + multiValueHeaders: Dict[str, List[str]] + queryStringParameters: Optional[Dict[str, str]] = None + multiValueQueryStringParameters: Optional[Dict[str, List[str]]] = None requestContext: APIGatewayEventRequestContext - pathParameters: dict[str, str] | None = None - stageVariables: dict[str, str] | None = None + pathParameters: Optional[Dict[str, str]] = None + stageVariables: Optional[Dict[str, str]] = None isBase64Encoded: bool - body: str | type[BaseModel] | None = None + body: Optional[Union[str, Type[BaseModel]]] = None diff --git a/aws_lambda_powertools/utilities/parser/models/apigwv2.py b/aws_lambda_powertools/utilities/parser/models/apigwv2.py index 829f0ff2f1b..7598797da83 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigwv2.py +++ b/aws_lambda_powertools/utilities/parser/models/apigwv2.py @@ -1,37 +1,36 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Any, Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import Any, Dict, List, Literal, Optional, Type, Union from pydantic import BaseModel, Field -from pydantic.networks import IPvAnyNetwork # noqa: TCH002 +from pydantic.networks import IPvAnyNetwork class RequestContextV2AuthorizerIamCognito(BaseModel): - amr: list[str] + amr: List[str] identityId: str identityPoolId: str class RequestContextV2AuthorizerIam(BaseModel): - accessKey: str | None = None - accountId: str | None = None - callerId: str | None = None - principalOrgId: str | None = None - userArn: str | None = None - userId: str | None = None - cognitoIdentity: RequestContextV2AuthorizerIamCognito | None = None + accessKey: Optional[str] = None + accountId: Optional[str] = None + callerId: Optional[str] = None + principalOrgId: Optional[str] = None + userArn: Optional[str] = None + userId: Optional[str] = None + cognitoIdentity: Optional[RequestContextV2AuthorizerIamCognito] = None class RequestContextV2AuthorizerJwt(BaseModel): - claims: dict[str, Any] - scopes: list[str] | None = None + claims: Dict[str, Any] + scopes: Optional[List[str]] = None class RequestContextV2Authorizer(BaseModel): - jwt: RequestContextV2AuthorizerJwt | None = None - iam: RequestContextV2AuthorizerIam | None = None - lambda_value: dict[str, Any] | None = Field(None, alias="lambda") + jwt: Optional[RequestContextV2AuthorizerJwt] = None + iam: Optional[RequestContextV2AuthorizerIam] = None + lambda_value: Optional[Dict[str, Any]] = Field(None, alias="lambda") class RequestContextV2Http(BaseModel): @@ -45,7 +44,7 @@ class RequestContextV2Http(BaseModel): class RequestContextV2(BaseModel): accountId: str apiId: str - authorizer: RequestContextV2Authorizer | None = None + authorizer: Optional[RequestContextV2Authorizer] = None domainName: str domainPrefix: str requestId: str @@ -61,11 +60,11 @@ class APIGatewayProxyEventV2Model(BaseModel): routeKey: str rawPath: str rawQueryString: str - cookies: list[str] | None = None - headers: dict[str, str] - queryStringParameters: dict[str, str] | None = None - pathParameters: dict[str, str] | None = None - stageVariables: dict[str, str] | None = None + cookies: Optional[List[str]] = None + headers: Dict[str, str] + queryStringParameters: Optional[Dict[str, str]] = None + pathParameters: Optional[Dict[str, str]] = None + stageVariables: Optional[Dict[str, str]] = None requestContext: RequestContextV2 - body: str | type[BaseModel] | None = None + body: Optional[Union[str, Type[BaseModel]]] = None isBase64Encoded: bool diff --git a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py index 800f8158aaa..cc61307b459 100644 --- a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +++ b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py @@ -1,4 +1,5 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import Dict, List, Optional from pydantic import BaseModel, Field @@ -17,11 +18,11 @@ class BedrockAgentPropertyModel(BaseModel): class BedrockAgentRequestMediaModel(BaseModel): - properties: list[BedrockAgentPropertyModel] + properties: List[BedrockAgentPropertyModel] class BedrockAgentRequestBodyModel(BaseModel): - content: dict[str, BedrockAgentRequestMediaModel] + content: Dict[str, BedrockAgentRequestMediaModel] class BedrockAgentEventModel(BaseModel): @@ -31,8 +32,8 @@ class BedrockAgentEventModel(BaseModel): action_group: str = Field(..., alias="actionGroup") api_path: str = Field(..., alias="apiPath") http_method: str = Field(..., alias="httpMethod") - session_attributes: dict[str, str] = Field({}, alias="sessionAttributes") - prompt_session_attributes: dict[str, str] = Field({}, alias="promptSessionAttributes") + session_attributes: Dict[str, str] = Field({}, alias="sessionAttributes") + prompt_session_attributes: Dict[str, str] = Field({}, alias="promptSessionAttributes") agent: BedrockAgentModel - parameters: list[BedrockAgentPropertyModel] | None = None - request_body: BedrockAgentRequestBodyModel | None = Field(None, alias="requestBody") + parameters: Optional[List[BedrockAgentPropertyModel]] = None + request_body: Optional[BedrockAgentRequestBodyModel] = Field(None, alias="requestBody") diff --git a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py index 4b8912519ae..b2e9f29cfed 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py @@ -1,6 +1,5 @@ -from __future__ import annotations - -from typing import Any, Literal +# ruff: noqa: FA100 +from typing import Any, Dict, Literal, Union from pydantic import BaseModel, Field, HttpUrl @@ -13,7 +12,7 @@ class CloudFormationCustomResourceBaseModel(BaseModel): request_id: str = Field(..., alias="RequestId") logical_resource_id: str = Field(..., alias="LogicalResourceId") resource_type: str = Field(..., alias="ResourceType") - resource_properties: dict[str, Any] | BaseModel | None = Field(None, alias="ResourceProperties") + resource_properties: Union[Dict[str, Any], BaseModel, None] = Field(None, alias="ResourceProperties") class CloudFormationCustomResourceCreateModel(CloudFormationCustomResourceBaseModel): @@ -28,4 +27,4 @@ class CloudFormationCustomResourceDeleteModel(CloudFormationCustomResourceBaseMo class CloudFormationCustomResourceUpdateModel(CloudFormationCustomResourceBaseModel): request_type: Literal["Update"] = Field(..., alias="RequestType") physical_resource_id: str = Field(..., alias="PhysicalResourceId") - old_resource_properties: dict[str, Any] | BaseModel | None = Field(None, alias="OldResourceProperties") + old_resource_properties: Union[Dict[str, Any], BaseModel, None] = Field(None, alias="OldResourceProperties") diff --git a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py index 0d590a93dd9..2efdb32ea93 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py @@ -1,10 +1,10 @@ -from __future__ import annotations - +# ruff: noqa: FA100 import base64 import json import logging import zlib -from datetime import datetime # noqa: TCH003 +from datetime import datetime +from typing import List, Optional, Type, Union from pydantic import BaseModel, Field, field_validator @@ -14,7 +14,7 @@ class CloudWatchLogsLogEvent(BaseModel): id: str # noqa AA03 VNE003 timestamp: datetime - message: str | type[BaseModel] + message: Union[str, Type[BaseModel]] class CloudWatchLogsDecode(BaseModel): @@ -22,9 +22,9 @@ class CloudWatchLogsDecode(BaseModel): owner: str logGroup: str logStream: str - subscriptionFilters: list[str] - logEvents: list[CloudWatchLogsLogEvent] - policyLevel: str | None = None + subscriptionFilters: List[str] + logEvents: List[CloudWatchLogsLogEvent] + policyLevel: Optional[str] = None class CloudWatchLogsData(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/dynamodb.py b/aws_lambda_powertools/utilities/parser/models/dynamodb.py index 0df0490d675..99d82c7853d 100644 --- a/aws_lambda_powertools/utilities/parser/models/dynamodb.py +++ b/aws_lambda_powertools/utilities/parser/models/dynamodb.py @@ -1,7 +1,6 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Any, Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import Any, Dict, List, Literal, Optional, Type, Union from pydantic import BaseModel, field_validator @@ -11,10 +10,10 @@ class DynamoDBStreamChangedRecordModel(BaseModel): - ApproximateCreationDateTime: datetime | None = None - Keys: dict[str, Any] - NewImage: dict[str, Any] | type[BaseModel] | BaseModel | None = None - OldImage: dict[str, Any] | type[BaseModel] | BaseModel | None = None + ApproximateCreationDateTime: Optional[datetime] = None + Keys: Dict[str, Any] + NewImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = None + OldImage: Optional[Union[Dict[str, Any], Type[BaseModel], BaseModel]] = None SequenceNumber: str SizeBytes: int StreamViewType: Literal["NEW_AND_OLD_IMAGES", "KEYS_ONLY", "NEW_IMAGE", "OLD_IMAGE"] @@ -48,8 +47,8 @@ class DynamoDBStreamRecordModel(BaseModel): awsRegion: str eventSourceARN: str dynamodb: DynamoDBStreamChangedRecordModel - userIdentity: UserIdentity | None = None + userIdentity: Optional[UserIdentity] = None class DynamoDBStreamModel(BaseModel): - Records: list[DynamoDBStreamRecordModel] + Records: List[DynamoDBStreamRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/event_bridge.py b/aws_lambda_powertools/utilities/parser/models/event_bridge.py index 2c49c7f6977..019ad556604 100644 --- a/aws_lambda_powertools/utilities/parser/models/event_bridge.py +++ b/aws_lambda_powertools/utilities/parser/models/event_bridge.py @@ -1,10 +1,10 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 +# ruff: noqa: FA100 +from datetime import datetime +from typing import List, Optional from pydantic import BaseModel, Field -from aws_lambda_powertools.utilities.parser.types import RawDictOrModel # noqa: TCH001 +from aws_lambda_powertools.utilities.parser.types import RawDictOrModel class EventBridgeModel(BaseModel): @@ -14,7 +14,7 @@ class EventBridgeModel(BaseModel): account: str time: datetime region: str - resources: list[str] + resources: List[str] detail_type: str = Field(None, alias="detail-type") detail: RawDictOrModel - replay_name: str | None = Field(None, alias="replay-name") + replay_name: Optional[str] = Field(None, alias="replay-name") diff --git a/aws_lambda_powertools/utilities/parser/models/kafka.py b/aws_lambda_powertools/utilities/parser/models/kafka.py index d085ba2535d..5da4b4c1976 100644 --- a/aws_lambda_powertools/utilities/parser/models/kafka.py +++ b/aws_lambda_powertools/utilities/parser/models/kafka.py @@ -1,7 +1,6 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import Dict, List, Literal, Type, Union from pydantic import BaseModel, field_validator @@ -17,8 +16,8 @@ class KafkaRecordModel(BaseModel): timestamp: datetime timestampType: str key: bytes - value: str | type[BaseModel] - headers: list[dict[str, bytes]] + value: Union[str, Type[BaseModel]] + headers: List[Dict[str, bytes]] # Added type ignore to keep compatibility between Pydantic v1 and v2 _decode_key = field_validator("key")(base64_decode) # type: ignore[type-var, unused-ignore] @@ -37,8 +36,8 @@ def decode_headers_list(cls, value): class KafkaBaseEventModel(BaseModel): - bootstrapServers: list[str] - records: dict[str, list[KafkaRecordModel]] + bootstrapServers: List[str] + records: Dict[str, List[KafkaRecordModel]] @field_validator("bootstrapServers", mode="before") def split_servers(cls, value): diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis.py b/aws_lambda_powertools/utilities/parser/models/kinesis.py index 68633a3b117..b1c9211a880 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis.py @@ -1,8 +1,7 @@ -from __future__ import annotations - +# ruff: noqa: FA100 import json import zlib -from typing import Literal +from typing import Dict, List, Literal, Type, Union from pydantic import BaseModel, field_validator @@ -16,7 +15,7 @@ class KinesisDataStreamRecordPayload(BaseModel): kinesisSchemaVersion: str partitionKey: str sequenceNumber: str - data: bytes | type[BaseModel] | BaseModel # base64 encoded str is parsed into bytes + data: Union[bytes, Type[BaseModel], BaseModel] # base64 encoded str is parsed into bytes approximateArrivalTimestamp: float @field_validator("data", mode="before") @@ -34,7 +33,7 @@ class KinesisDataStreamRecord(BaseModel): eventSourceARN: str kinesis: KinesisDataStreamRecordPayload - def decompress_zlib_record_data_as_json(self) -> dict: + def decompress_zlib_record_data_as_json(self) -> Dict: """Decompress Kinesis Record bytes data zlib compressed to JSON""" if not isinstance(self.kinesis.data, bytes): raise ValueError("We can only decompress bytes data, not custom models.") @@ -43,10 +42,10 @@ def decompress_zlib_record_data_as_json(self) -> dict: class KinesisDataStreamModel(BaseModel): - Records: list[KinesisDataStreamRecord] + Records: List[KinesisDataStreamRecord] -def extract_cloudwatch_logs_from_event(event: KinesisDataStreamModel) -> list[CloudWatchLogsDecode]: +def extract_cloudwatch_logs_from_event(event: KinesisDataStreamModel) -> List[CloudWatchLogsDecode]: return [CloudWatchLogsDecode(**record.decompress_zlib_record_data_as_json()) for record in event.Records] diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py index 9a37286b81d..e54131dc5ae 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py @@ -1,4 +1,5 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import List, Optional, Type, Union from pydantic import BaseModel, PositiveInt, field_validator @@ -14,10 +15,10 @@ class KinesisFirehoseRecordMetadata(BaseModel): class KinesisFirehoseRecord(BaseModel): - data: bytes | type[BaseModel] # base64 encoded str is parsed into bytes + data: Union[bytes, Type[BaseModel]] # base64 encoded str is parsed into bytes recordId: str approximateArrivalTimestamp: PositiveInt - kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = None + kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = None @field_validator("data", mode="before") def data_base64_decode(cls, value): @@ -28,5 +29,5 @@ class KinesisFirehoseModel(BaseModel): invocationId: str deliveryStreamArn: str region: str - sourceKinesisStreamArn: str | None = None - records: list[KinesisFirehoseRecord] + sourceKinesisStreamArn: Optional[str] = None + records: List[KinesisFirehoseRecord] diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py index 42e84b7a421..6d39d65c52e 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py @@ -1,19 +1,20 @@ -from __future__ import annotations - +# ruff: noqa: FA100 import json +from typing import List, Optional from pydantic import BaseModel, PositiveInt, field_validator from aws_lambda_powertools.shared.functions import base64_decode -from aws_lambda_powertools.utilities.parser.models import KinesisFirehoseRecordMetadata # noqa: TCH001 -from aws_lambda_powertools.utilities.parser.models.sqs import SqsRecordModel # noqa: TCH001 +from aws_lambda_powertools.utilities.parser.models import KinesisFirehoseRecordMetadata + +from .sqs import SqsRecordModel class KinesisFirehoseSqsRecord(BaseModel): data: SqsRecordModel recordId: str approximateArrivalTimestamp: PositiveInt - kinesisRecordMetadata: KinesisFirehoseRecordMetadata | None = None + kinesisRecordMetadata: Optional[KinesisFirehoseRecordMetadata] = None @field_validator("data", mode="before") def data_base64_decode(cls, value): @@ -25,5 +26,5 @@ class KinesisFirehoseSqsModel(BaseModel): invocationId: str deliveryStreamArn: str region: str - sourceKinesisStreamArn: str | None = None - records: list[KinesisFirehoseSqsRecord] + sourceKinesisStreamArn: Optional[str] = None + records: List[KinesisFirehoseSqsRecord] diff --git a/aws_lambda_powertools/utilities/parser/models/s3.py b/aws_lambda_powertools/utilities/parser/models/s3.py index 732a6290b92..1118cd1d1fd 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3.py +++ b/aws_lambda_powertools/utilities/parser/models/s3.py @@ -1,12 +1,11 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import List, Literal, Optional from pydantic import BaseModel, model_validator from pydantic.fields import Field -from pydantic.networks import IPvAnyNetwork # noqa: TCH002 -from pydantic.types import NonNegativeFloat # noqa: TCH002 +from pydantic.networks import IPvAnyNetwork +from pydantic.types import NonNegativeFloat from .event_bridge import EventBridgeModel @@ -45,10 +44,10 @@ class S3Bucket(BaseModel): class S3Object(BaseModel): key: str - size: NonNegativeFloat | None = None - eTag: str | None = None + size: Optional[NonNegativeFloat] = None + eTag: Optional[str] = None sequencer: str - versionId: str | None = None + versionId: Optional[str] = None class S3Message(BaseModel): @@ -60,10 +59,10 @@ class S3Message(BaseModel): class S3EventNotificationObjectModel(BaseModel): key: str - size: NonNegativeFloat | None = None + size: Optional[NonNegativeFloat] = None etag: str = Field(default="") version_id: str = Field(None, alias="version-id") - sequencer: str | None = None + sequencer: Optional[str] = None class S3EventNotificationEventBridgeBucketModel(BaseModel): @@ -77,12 +76,12 @@ class S3EventNotificationEventBridgeDetailModel(BaseModel): request_id: str = Field(None, alias="request-id") requester: str source_ip_address: str = Field(None, alias="source-ip-address") - reason: str | None = None - deletion_type: str | None = Field(None, alias="deletion-type") - restore_expiry_time: str | None = Field(None, alias="restore-expiry-time") - source_storage_class: str | None = Field(None, alias="source-storage-class") - destination_storage_class: str | None = Field(None, alias="destination-storage-class") - destination_access_tier: str | None = Field(None, alias="destination-access-tier") + reason: Optional[str] = None + deletion_type: Optional[str] = Field(None, alias="deletion-type") + restore_expiry_time: Optional[str] = Field(None, alias="restore-expiry-time") + source_storage_class: Optional[str] = Field(None, alias="source-storage-class") + destination_storage_class: Optional[str] = Field(None, alias="destination-storage-class") + destination_access_tier: Optional[str] = Field(None, alias="destination-access-tier") class S3EventNotificationEventBridgeModel(EventBridgeModel): @@ -99,7 +98,7 @@ class S3RecordModel(BaseModel): requestParameters: S3RequestParameters responseElements: S3ResponseElements s3: S3Message - glacierEventData: S3EventRecordGlacierEventData | None = None + glacierEventData: Optional[S3EventRecordGlacierEventData] = None @model_validator(mode="before") def validate_s3_object(cls, values): @@ -111,4 +110,4 @@ def validate_s3_object(cls, values): class S3Model(BaseModel): - Records: list[S3RecordModel] + Records: List[S3RecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py index 97cf570822e..6dcdf621d1e 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py @@ -1,6 +1,5 @@ -from __future__ import annotations - -from typing import Any, Literal +# ruff: noqa: FA100 +from typing import Any, Dict, List, Literal, Optional from pydantic import BaseModel, model_validator @@ -8,12 +7,12 @@ class S3BatchOperationTaskModel(BaseModel): taskId: str s3Key: str - s3VersionId: str | None = None - s3BucketArn: str | None = None - s3Bucket: str | None = None + s3VersionId: Optional[str] = None + s3BucketArn: Optional[str] = None + s3Bucket: Optional[str] = None @model_validator(mode="before") - def validate_s3bucket(cls, values: dict[str, Any]) -> dict[str, Any]: + def validate_s3bucket(cls, values: Dict[str, Any]) -> Dict[str, Any]: if values.get("s3BucketArn") and not values.get("s3Bucket"): values["s3Bucket"] = values["s3BucketArn"].split(":::")[-1] @@ -22,11 +21,11 @@ def validate_s3bucket(cls, values: dict[str, Any]) -> dict[str, Any]: class S3BatchOperationJobModel(BaseModel): id: str - userArguments: dict[str, Any] | None = None + userArguments: Optional[Dict[str, Any]] = None class S3BatchOperationModel(BaseModel): invocationId: str invocationSchemaVersion: Literal["1.0", "2.0"] job: S3BatchOperationJobModel - tasks: list[S3BatchOperationTaskModel] + tasks: List[S3BatchOperationTaskModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index b4687c0dd37..af08d929465 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -1,8 +1,9 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import List -from pydantic import Json # noqa: TCH002 +from pydantic import Json -from aws_lambda_powertools.utilities.parser.models.s3 import S3Model # noqa: TCH001 +from aws_lambda_powertools.utilities.parser.models.s3 import S3Model from aws_lambda_powertools.utilities.parser.models.sqs import SqsModel, SqsRecordModel @@ -11,4 +12,4 @@ class S3SqsEventNotificationRecordModel(SqsRecordModel): class S3SqsEventNotificationModel(SqsModel): - Records: list[S3SqsEventNotificationRecordModel] + Records: List[S3SqsEventNotificationRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py index 0a4c0d9ff6e..b940f41ad00 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py @@ -1,4 +1,5 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import Dict, Optional, Type, Union from pydantic import BaseModel, HttpUrl @@ -12,17 +13,17 @@ class S3ObjectContext(BaseModel): class S3ObjectConfiguration(BaseModel): accessPointArn: str supportingAccessPointArn: str - payload: str | type[BaseModel] + payload: Union[str, Type[BaseModel]] class S3ObjectUserRequest(BaseModel): url: str - headers: dict[str, str] + headers: Dict[str, str] class S3ObjectSessionIssuer(BaseModel): type: str # noqa: A003, VNE003 - userName: str | None = None + userName: Optional[str] = None principalId: str arn: str accountId: str @@ -42,10 +43,10 @@ class S3ObjectUserIdentity(BaseModel): type: str # noqa: A003 accountId: str accessKeyId: str - userName: str | None = None + userName: Optional[str] = None principalId: str arn: str - sessionContext: S3ObjectSessionContext | None = None + sessionContext: Optional[S3ObjectSessionContext] = None class S3ObjectLambdaEvent(BaseModel): diff --git a/aws_lambda_powertools/utilities/parser/models/ses.py b/aws_lambda_powertools/utilities/parser/models/ses.py index c96c7b8602f..485cd4db25b 100644 --- a/aws_lambda_powertools/utilities/parser/models/ses.py +++ b/aws_lambda_powertools/utilities/parser/models/ses.py @@ -1,10 +1,9 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import List, Literal, Optional from pydantic import BaseModel, Field -from pydantic.types import PositiveInt # noqa: TCH002 +from pydantic.types import PositiveInt class SesReceiptVerdict(BaseModel): @@ -20,7 +19,7 @@ class SesReceiptAction(BaseModel): class SesReceipt(BaseModel): timestamp: datetime processingTimeMillis: PositiveInt - recipients: list[str] + recipients: List[str] spamVerdict: SesReceiptVerdict virusVerdict: SesReceiptVerdict spfVerdict: SesReceiptVerdict @@ -34,12 +33,12 @@ class SesMailHeaders(BaseModel): class SesMailCommonHeaders(BaseModel): - header_from: list[str] = Field(None, alias="from") - to: list[str] - cc: list[str] | None = None - bcc: list[str] | None = None - sender: list[str] | None = None - reply_to: list[str] | None = Field(None, alias="reply-to") + header_from: List[str] = Field(None, alias="from") + to: List[str] + cc: Optional[List[str]] = None + bcc: Optional[List[str]] = None + sender: Optional[List[str]] = None + reply_to: Optional[List[str]] = Field(None, alias="reply-to") returnPath: str messageId: str date: str @@ -50,9 +49,9 @@ class SesMail(BaseModel): timestamp: datetime source: str messageId: str - destination: list[str] + destination: List[str] headersTruncated: bool - headers: list[SesMailHeaders] + headers: List[SesMailHeaders] commonHeaders: SesMailCommonHeaders @@ -68,4 +67,4 @@ class SesRecordModel(BaseModel): class SesModel(BaseModel): - Records: list[SesRecordModel] + Records: List[SesRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/sns.py b/aws_lambda_powertools/utilities/parser/models/sns.py index b94c7a4d952..329c0f45490 100644 --- a/aws_lambda_powertools/utilities/parser/models/sns.py +++ b/aws_lambda_powertools/utilities/parser/models/sns.py @@ -1,10 +1,10 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Literal +# ruff: noqa: FA100 +from datetime import datetime +from typing import Dict, List, Literal, Optional, Union +from typing import Type as TypingType from pydantic import BaseModel, model_validator -from pydantic.networks import HttpUrl # noqa: TCH002 +from pydantic.networks import HttpUrl class SnsMsgAttributeModel(BaseModel): @@ -13,17 +13,17 @@ class SnsMsgAttributeModel(BaseModel): class SnsNotificationModel(BaseModel): - Subject: str | None = None + Subject: Optional[str] = None TopicArn: str UnsubscribeUrl: HttpUrl Type: Literal["Notification"] - MessageAttributes: dict[str, SnsMsgAttributeModel] | None = None - Message: str | type[BaseModel] + MessageAttributes: Optional[Dict[str, SnsMsgAttributeModel]] = None + Message: Union[str, TypingType[BaseModel]] MessageId: str - SigningCertUrl: HttpUrl | None = None # NOTE: FIFO opt-in removes attribute - Signature: str | None = None # NOTE: FIFO opt-in removes attribute + SigningCertUrl: Optional[HttpUrl] = None # NOTE: FIFO opt-in removes attribute + Signature: Optional[str] = None # NOTE: FIFO opt-in removes attribute Timestamp: datetime - SignatureVersion: str | None = None # NOTE: FIFO opt-in removes attribute + SignatureVersion: Optional[str] = None # NOTE: FIFO opt-in removes attribute @model_validator(mode="before") def check_sqs_protocol(cls, values): @@ -45,4 +45,4 @@ class SnsRecordModel(BaseModel): class SnsModel(BaseModel): - Records: list[SnsRecordModel] + Records: List[SnsRecordModel] diff --git a/aws_lambda_powertools/utilities/parser/models/sqs.py b/aws_lambda_powertools/utilities/parser/models/sqs.py index 4e80320e46d..be23251c6da 100644 --- a/aws_lambda_powertools/utilities/parser/models/sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/sqs.py @@ -1,7 +1,6 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 -from typing import Literal, Sequence +# ruff: noqa: FA100 +from datetime import datetime +from typing import Dict, List, Literal, Optional, Sequence, Type, Union from pydantic import BaseModel @@ -9,20 +8,20 @@ class SqsAttributesModel(BaseModel): ApproximateReceiveCount: str ApproximateFirstReceiveTimestamp: datetime - MessageDeduplicationId: str | None = None - MessageGroupId: str | None = None + MessageDeduplicationId: Optional[str] = None + MessageGroupId: Optional[str] = None SenderId: str SentTimestamp: datetime - SequenceNumber: str | None = None - AWSTraceHeader: str | None = None - DeadLetterQueueSourceArn: str | None = None + SequenceNumber: Optional[str] = None + AWSTraceHeader: Optional[str] = None + DeadLetterQueueSourceArn: Optional[str] = None class SqsMsgAttributeModel(BaseModel): - stringValue: str | None = None - binaryValue: str | None = None - stringListValues: list[str] = [] - binaryListValues: list[str] = [] + stringValue: Optional[str] = None + binaryValue: Optional[str] = None + stringListValues: List[str] = [] + binaryListValues: List[str] = [] dataType: str # context on why it's commented: https://github.com/aws-powertools/powertools-lambda-python/pull/118 @@ -53,11 +52,11 @@ class SqsMsgAttributeModel(BaseModel): class SqsRecordModel(BaseModel): messageId: str receiptHandle: str - body: str | type[BaseModel] | BaseModel + body: Union[str, Type[BaseModel], BaseModel] attributes: SqsAttributesModel - messageAttributes: dict[str, SqsMsgAttributeModel] + messageAttributes: Dict[str, SqsMsgAttributeModel] md5OfBody: str - md5OfMessageAttributes: str | None = None + md5OfMessageAttributes: Optional[str] = None eventSource: Literal["aws:sqs"] eventSourceARN: str awsRegion: str diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py index b25f9d2018d..39d2853990c 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py @@ -1,4 +1,5 @@ -from __future__ import annotations +# ruff: noqa: FA100 +from typing import Dict, Type, Union from pydantic import BaseModel @@ -6,7 +7,7 @@ class VpcLatticeModel(BaseModel): method: str raw_path: str - body: str | type[BaseModel] + body: Union[str, Type[BaseModel]] is_base64_encoded: bool - headers: dict[str, str] - query_string_parameters: dict[str, str] + headers: Dict[str, str] + query_string_parameters: Dict[str, str] diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py index 8ee7129c93f..4fa55ee0939 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py @@ -1,21 +1,21 @@ -from __future__ import annotations - -from datetime import datetime # noqa: TCH003 +# ruff: noqa: FA100 +from datetime import datetime +from typing import Dict, Optional, Type, Union from pydantic import BaseModel, Field, field_validator class VpcLatticeV2RequestContextIdentity(BaseModel): - source_vpc_arn: str | None = Field(None, alias="sourceVpcArn") - get_type: str | None = Field(None, alias="type") - principal: str | None = Field(None, alias="principal") - principal_org_id: str | None = Field(None, alias="principalOrgID") - session_name: str | None = Field(None, alias="sessionName") - x509_subject_cn: str | None = Field(None, alias="X509SubjectCn") - x509_issuer_ou: str | None = Field(None, alias="X509IssuerOu") - x509_san_dns: str | None = Field(None, alias="x509SanDns") - x509_san_uri: str | None = Field(None, alias="X509SanUri") - x509_san_name_cn: str | None = Field(None, alias="X509SanNameCn") + source_vpc_arn: Optional[str] = Field(None, alias="sourceVpcArn") + get_type: Optional[str] = Field(None, alias="type") + principal: Optional[str] = Field(None, alias="principal") + principal_org_id: Optional[str] = Field(None, alias="principalOrgID") + session_name: Optional[str] = Field(None, alias="sessionName") + x509_subject_cn: Optional[str] = Field(None, alias="X509SubjectCn") + x509_issuer_ou: Optional[str] = Field(None, alias="X509IssuerOu") + x509_san_dns: Optional[str] = Field(None, alias="x509SanDns") + x509_san_uri: Optional[str] = Field(None, alias="X509SanUri") + x509_san_name_cn: Optional[str] = Field(None, alias="X509SanNameCn") class VpcLatticeV2RequestContext(BaseModel): @@ -36,8 +36,8 @@ class VpcLatticeV2Model(BaseModel): version: str path: str method: str - headers: dict[str, str] - query_string_parameters: dict[str, str] | None = Field(None, alias="queryStringParameters") - body: str | type[BaseModel] | None = None - is_base64_encoded: bool | None = Field(None, alias="isBase64Encoded") + headers: Dict[str, str] + query_string_parameters: Optional[Dict[str, str]] = Field(None, alias="queryStringParameters") + body: Optional[Union[str, Type[BaseModel]]] = None + is_base64_encoded: Optional[bool] = Field(None, alias="isBase64Encoded") request_context: VpcLatticeV2RequestContext = Field(None, alias="requestContext") diff --git a/aws_lambda_powertools/utilities/parser/types.py b/aws_lambda_powertools/utilities/parser/types.py index cd967b90287..91bf9a9119e 100644 --- a/aws_lambda_powertools/utilities/parser/types.py +++ b/aws_lambda_powertools/utilities/parser/types.py @@ -1,15 +1,13 @@ """Generics and other shared types used across parser""" -from __future__ import annotations - -from typing import Any, Dict, Literal, TypeVar, Union +from typing import Any, Dict, Literal, Type, TypeVar, Union from pydantic import BaseModel, Json Model = TypeVar("Model", bound=BaseModel) EnvelopeModel = TypeVar("EnvelopeModel") EventParserReturnType = TypeVar("EventParserReturnType") -AnyInheritedModel = Union[type[BaseModel], BaseModel] +AnyInheritedModel = Union[Type[BaseModel], BaseModel] RawDictOrModel = Union[Dict[str, Any], AnyInheritedModel] T = TypeVar("T") From 78ff665ced3f8da5e50f4dadc97b771668ec48b8 Mon Sep 17 00:00:00 2001 From: Eric Nielsen <4120606+ericbn@users.noreply.github.com> Date: Sat, 17 Aug 2024 08:18:52 -0500 Subject: [PATCH 4/4] Update ruff.toml Configure lint.per-file-ignores in ruff.toml instead of adding a # ruff: noqa: FA100 line to each file. --- aws_lambda_powertools/utilities/parser/models/alb.py | 1 - aws_lambda_powertools/utilities/parser/models/apigw.py | 1 - aws_lambda_powertools/utilities/parser/models/apigwv2.py | 1 - aws_lambda_powertools/utilities/parser/models/bedrock_agent.py | 1 - .../utilities/parser/models/cloudformation_custom_resource.py | 1 - aws_lambda_powertools/utilities/parser/models/cloudwatch.py | 1 - aws_lambda_powertools/utilities/parser/models/event_bridge.py | 1 - aws_lambda_powertools/utilities/parser/models/kafka.py | 1 - aws_lambda_powertools/utilities/parser/models/kinesis.py | 1 - .../utilities/parser/models/kinesis_firehose.py | 1 - .../utilities/parser/models/kinesis_firehose_sqs.py | 1 - aws_lambda_powertools/utilities/parser/models/s3.py | 1 - .../utilities/parser/models/s3_batch_operation.py | 1 - .../utilities/parser/models/s3_event_notification.py | 1 - .../utilities/parser/models/s3_object_event.py | 1 - aws_lambda_powertools/utilities/parser/models/ses.py | 1 - aws_lambda_powertools/utilities/parser/models/sns.py | 1 - aws_lambda_powertools/utilities/parser/models/sqs.py | 1 - aws_lambda_powertools/utilities/parser/models/vpc_lattice.py | 1 - aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py | 1 - ruff.toml | 3 +++ 21 files changed, 3 insertions(+), 20 deletions(-) diff --git a/aws_lambda_powertools/utilities/parser/models/alb.py b/aws_lambda_powertools/utilities/parser/models/alb.py index 7b2abf4c32a..d903e9f0fd8 100644 --- a/aws_lambda_powertools/utilities/parser/models/alb.py +++ b/aws_lambda_powertools/utilities/parser/models/alb.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Dict, Type, Union from pydantic import BaseModel diff --git a/aws_lambda_powertools/utilities/parser/models/apigw.py b/aws_lambda_powertools/utilities/parser/models/apigw.py index bd239e00e61..f19530a3e25 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigw.py +++ b/aws_lambda_powertools/utilities/parser/models/apigw.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Any, Dict, List, Literal, Optional, Type, Union diff --git a/aws_lambda_powertools/utilities/parser/models/apigwv2.py b/aws_lambda_powertools/utilities/parser/models/apigwv2.py index 7598797da83..9c6638993a9 100644 --- a/aws_lambda_powertools/utilities/parser/models/apigwv2.py +++ b/aws_lambda_powertools/utilities/parser/models/apigwv2.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Any, Dict, List, Literal, Optional, Type, Union diff --git a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py index cc61307b459..62465162167 100644 --- a/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py +++ b/aws_lambda_powertools/utilities/parser/models/bedrock_agent.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Dict, List, Optional from pydantic import BaseModel, Field diff --git a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py index b2e9f29cfed..fcdb749afde 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudformation_custom_resource.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Any, Dict, Literal, Union from pydantic import BaseModel, Field, HttpUrl diff --git a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py index 2efdb32ea93..df464edd65e 100644 --- a/aws_lambda_powertools/utilities/parser/models/cloudwatch.py +++ b/aws_lambda_powertools/utilities/parser/models/cloudwatch.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 import base64 import json import logging diff --git a/aws_lambda_powertools/utilities/parser/models/event_bridge.py b/aws_lambda_powertools/utilities/parser/models/event_bridge.py index 019ad556604..eab6c54d12d 100644 --- a/aws_lambda_powertools/utilities/parser/models/event_bridge.py +++ b/aws_lambda_powertools/utilities/parser/models/event_bridge.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import List, Optional diff --git a/aws_lambda_powertools/utilities/parser/models/kafka.py b/aws_lambda_powertools/utilities/parser/models/kafka.py index 5da4b4c1976..4969f7f427b 100644 --- a/aws_lambda_powertools/utilities/parser/models/kafka.py +++ b/aws_lambda_powertools/utilities/parser/models/kafka.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Dict, List, Literal, Type, Union diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis.py b/aws_lambda_powertools/utilities/parser/models/kinesis.py index b1c9211a880..4b1a93fd226 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 import json import zlib from typing import Dict, List, Literal, Type, Union diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py index e54131dc5ae..6c50b93b9a7 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import List, Optional, Type, Union from pydantic import BaseModel, PositiveInt, field_validator diff --git a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py index 6d39d65c52e..7117fc4a011 100644 --- a/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/kinesis_firehose_sqs.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 import json from typing import List, Optional diff --git a/aws_lambda_powertools/utilities/parser/models/s3.py b/aws_lambda_powertools/utilities/parser/models/s3.py index 1118cd1d1fd..4de89d42c78 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3.py +++ b/aws_lambda_powertools/utilities/parser/models/s3.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import List, Literal, Optional diff --git a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py index 6dcdf621d1e..934ace9ac07 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_batch_operation.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Any, Dict, List, Literal, Optional from pydantic import BaseModel, model_validator diff --git a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py index af08d929465..1bcbc83ac18 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_event_notification.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import List from pydantic import Json diff --git a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py index b940f41ad00..867cd996fa0 100644 --- a/aws_lambda_powertools/utilities/parser/models/s3_object_event.py +++ b/aws_lambda_powertools/utilities/parser/models/s3_object_event.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Dict, Optional, Type, Union from pydantic import BaseModel, HttpUrl diff --git a/aws_lambda_powertools/utilities/parser/models/ses.py b/aws_lambda_powertools/utilities/parser/models/ses.py index 485cd4db25b..59a5226292f 100644 --- a/aws_lambda_powertools/utilities/parser/models/ses.py +++ b/aws_lambda_powertools/utilities/parser/models/ses.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import List, Literal, Optional diff --git a/aws_lambda_powertools/utilities/parser/models/sns.py b/aws_lambda_powertools/utilities/parser/models/sns.py index 329c0f45490..585489e9323 100644 --- a/aws_lambda_powertools/utilities/parser/models/sns.py +++ b/aws_lambda_powertools/utilities/parser/models/sns.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Dict, List, Literal, Optional, Union from typing import Type as TypingType diff --git a/aws_lambda_powertools/utilities/parser/models/sqs.py b/aws_lambda_powertools/utilities/parser/models/sqs.py index be23251c6da..efa5130bf06 100644 --- a/aws_lambda_powertools/utilities/parser/models/sqs.py +++ b/aws_lambda_powertools/utilities/parser/models/sqs.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Dict, List, Literal, Optional, Sequence, Type, Union diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py index 39d2853990c..8442fc92781 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_lattice.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from typing import Dict, Type, Union from pydantic import BaseModel diff --git a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py index 4fa55ee0939..3d4b616d135 100644 --- a/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py +++ b/aws_lambda_powertools/utilities/parser/models/vpc_latticev2.py @@ -1,4 +1,3 @@ -# ruff: noqa: FA100 from datetime import datetime from typing import Dict, Optional, Type, Union diff --git a/ruff.toml b/ruff.toml index 374a183541b..264870c35df 100644 --- a/ruff.toml +++ b/ruff.toml @@ -90,3 +90,6 @@ split-on-trailing-comma = true "aws_lambda_powertools/event_handler/openapi/compat.py" = ["F401"] # Maintenance: we're keeping EphemeralMetrics code in case of Hyrum's law so we can quickly revert it "aws_lambda_powertools/metrics/metrics.py" = ["ERA001"] +"examples/*" = ["FA100"] +"tests/*" = ["FA100"] +"aws_lambda_powertools/utilities/parser/models/*" = ["FA100"] \ No newline at end of file