localstack-core 4.6.1.dev60__py3-none-any.whl → 4.10.1.dev12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (672) hide show
  1. localstack/aws/api/apigateway/__init__.py +87 -110
  2. localstack/aws/api/cloudformation/__init__.py +18 -4
  3. localstack/aws/api/cloudwatch/__init__.py +41 -1
  4. localstack/aws/api/config/__init__.py +4 -0
  5. localstack/aws/api/core.py +8 -5
  6. localstack/aws/api/dynamodb/__init__.py +30 -0
  7. localstack/aws/api/ec2/__init__.py +1545 -66
  8. localstack/aws/api/events/__init__.py +12 -16
  9. localstack/aws/api/iam/__init__.py +7 -0
  10. localstack/aws/api/kinesis/__init__.py +19 -0
  11. localstack/aws/api/kms/__init__.py +6 -0
  12. localstack/aws/api/lambda_/__init__.py +36 -23
  13. localstack/aws/api/logs/__init__.py +20 -8
  14. localstack/aws/api/opensearch/__init__.py +16 -0
  15. localstack/aws/api/pipes/__init__.py +24 -32
  16. localstack/aws/api/redshift/__init__.py +9 -3
  17. localstack/aws/api/route53/__init__.py +5 -0
  18. localstack/aws/api/s3/__init__.py +12 -0
  19. localstack/aws/api/s3control/__init__.py +56 -0
  20. localstack/aws/api/scheduler/__init__.py +14 -16
  21. localstack/aws/api/ssm/__init__.py +2 -0
  22. localstack/aws/api/stepfunctions/__init__.py +88 -114
  23. localstack/aws/api/support/__init__.py +8 -9
  24. localstack/aws/api/transcribe/__init__.py +17 -0
  25. localstack/aws/chain.py +2 -2
  26. localstack/aws/client.py +14 -11
  27. localstack/aws/connect.py +42 -41
  28. localstack/aws/forwarder.py +57 -9
  29. localstack/aws/gateway.py +1 -3
  30. localstack/aws/handlers/analytics.py +2 -3
  31. localstack/aws/handlers/cors.py +4 -5
  32. localstack/aws/handlers/internal_requests.py +6 -1
  33. localstack/aws/handlers/logging.py +13 -4
  34. localstack/aws/handlers/metric_handler.py +44 -5
  35. localstack/aws/handlers/service.py +48 -28
  36. localstack/aws/mocking.py +18 -27
  37. localstack/aws/patches.py +2 -2
  38. localstack/aws/protocol/op_router.py +11 -10
  39. localstack/aws/protocol/parser.py +475 -49
  40. localstack/aws/protocol/serializer.py +723 -106
  41. localstack/aws/protocol/service_router.py +133 -33
  42. localstack/aws/protocol/validate.py +6 -6
  43. localstack/aws/scaffold.py +9 -10
  44. localstack/aws/serving/edge.py +5 -6
  45. localstack/aws/serving/hypercorn.py +2 -2
  46. localstack/aws/serving/twisted.py +1 -2
  47. localstack/aws/serving/werkzeug.py +2 -2
  48. localstack/aws/skeleton.py +12 -11
  49. localstack/aws/spec-patches.json +58 -0
  50. localstack/aws/spec.py +66 -46
  51. localstack/cli/exceptions.py +1 -1
  52. localstack/cli/localstack.py +11 -11
  53. localstack/cli/lpm.py +4 -5
  54. localstack/cli/plugins.py +1 -1
  55. localstack/cli/profiles.py +1 -2
  56. localstack/config.py +44 -30
  57. localstack/constants.py +4 -29
  58. localstack/deprecations.py +5 -5
  59. localstack/dev/kubernetes/__main__.py +130 -7
  60. localstack/dev/run/__main__.py +5 -5
  61. localstack/dev/run/configurators.py +1 -4
  62. localstack/dev/run/paths.py +6 -6
  63. localstack/dns/models.py +2 -1
  64. localstack/dns/plugins.py +5 -1
  65. localstack/dns/server.py +16 -6
  66. localstack/http/dispatcher.py +1 -2
  67. localstack/http/response.py +2 -2
  68. localstack/http/router.py +1 -1
  69. localstack/http/trace.py +2 -1
  70. localstack/logging/format.py +6 -6
  71. localstack/packages/api.py +13 -12
  72. localstack/packages/core.py +4 -4
  73. localstack/packages/debugpy.py +1 -3
  74. localstack/packages/ffmpeg.py +1 -2
  75. localstack/packages/java.py +38 -12
  76. localstack/packages/plugins.py +0 -8
  77. localstack/runtime/analytics.py +3 -0
  78. localstack/runtime/hooks.py +1 -1
  79. localstack/runtime/init.py +8 -9
  80. localstack/runtime/main.py +5 -5
  81. localstack/runtime/patches.py +2 -2
  82. localstack/runtime/shutdown.py +2 -1
  83. localstack/services/apigateway/exporter.py +1 -2
  84. localstack/services/apigateway/helpers.py +7 -10
  85. localstack/services/apigateway/legacy/context.py +21 -21
  86. localstack/services/apigateway/legacy/helpers.py +27 -28
  87. localstack/services/apigateway/legacy/integration.py +11 -10
  88. localstack/services/apigateway/legacy/invocations.py +6 -5
  89. localstack/services/apigateway/legacy/provider.py +148 -68
  90. localstack/services/apigateway/legacy/router_asf.py +2 -2
  91. localstack/services/apigateway/legacy/templates.py +6 -6
  92. localstack/services/apigateway/models.py +16 -16
  93. localstack/services/apigateway/next_gen/execute_api/api.py +2 -2
  94. localstack/services/apigateway/next_gen/execute_api/context.py +25 -25
  95. localstack/services/apigateway/next_gen/execute_api/handlers/api_key_validation.py +2 -5
  96. localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
  97. localstack/services/apigateway/next_gen/execute_api/handlers/parse.py +1 -2
  98. localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +2 -3
  99. localstack/services/apigateway/next_gen/execute_api/header_utils.py +1 -1
  100. localstack/services/apigateway/next_gen/execute_api/helpers.py +2 -2
  101. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +9 -6
  102. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +12 -12
  103. localstack/services/apigateway/next_gen/execute_api/router.py +31 -0
  104. localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
  105. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
  106. localstack/services/apigateway/next_gen/execute_api/variables.py +63 -63
  107. localstack/services/apigateway/next_gen/provider.py +5 -0
  108. localstack/services/apigateway/resource_providers/aws_apigateway_account.py +3 -3
  109. localstack/services/apigateway/resource_providers/aws_apigateway_account_plugin.py +1 -3
  110. localstack/services/apigateway/resource_providers/aws_apigateway_apikey.py +14 -14
  111. localstack/services/apigateway/resource_providers/aws_apigateway_apikey_plugin.py +1 -3
  112. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping.py +5 -5
  113. localstack/services/apigateway/resource_providers/aws_apigateway_basepathmapping_plugin.py +1 -3
  114. localstack/services/apigateway/resource_providers/aws_apigateway_deployment.py +46 -46
  115. localstack/services/apigateway/resource_providers/aws_apigateway_deployment_plugin.py +1 -3
  116. localstack/services/apigateway/resource_providers/aws_apigateway_domainname.py +18 -18
  117. localstack/services/apigateway/resource_providers/aws_apigateway_domainname_plugin.py +1 -3
  118. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse.py +7 -7
  119. localstack/services/apigateway/resource_providers/aws_apigateway_gatewayresponse_plugin.py +1 -3
  120. localstack/services/apigateway/resource_providers/aws_apigateway_method.py +36 -36
  121. localstack/services/apigateway/resource_providers/aws_apigateway_method_plugin.py +1 -3
  122. localstack/services/apigateway/resource_providers/aws_apigateway_model.py +6 -6
  123. localstack/services/apigateway/resource_providers/aws_apigateway_model_plugin.py +1 -3
  124. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator.py +6 -6
  125. localstack/services/apigateway/resource_providers/aws_apigateway_requestvalidator_plugin.py +1 -3
  126. localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +6 -6
  127. localstack/services/apigateway/resource_providers/aws_apigateway_resource_plugin.py +1 -3
  128. localstack/services/apigateway/resource_providers/aws_apigateway_restapi.py +26 -26
  129. localstack/services/apigateway/resource_providers/aws_apigateway_restapi_plugin.py +1 -3
  130. localstack/services/apigateway/resource_providers/aws_apigateway_stage.py +33 -33
  131. localstack/services/apigateway/resource_providers/aws_apigateway_stage_plugin.py +1 -3
  132. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan.py +18 -18
  133. localstack/services/apigateway/resource_providers/aws_apigateway_usageplan_plugin.py +1 -3
  134. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey.py +5 -5
  135. localstack/services/apigateway/resource_providers/aws_apigateway_usageplankey_plugin.py +1 -3
  136. localstack/services/cdk/resource_providers/cdk_metadata.py +4 -3
  137. localstack/services/cdk/resource_providers/cdk_metadata_plugin.py +1 -3
  138. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate.py +14 -14
  139. localstack/services/certificatemanager/resource_providers/aws_certificatemanager_certificate_plugin.py +1 -3
  140. localstack/services/cloudformation/api_utils.py +4 -8
  141. localstack/services/cloudformation/cfn_utils.py +2 -2
  142. localstack/services/cloudformation/deployment_utils.py +14 -12
  143. localstack/services/cloudformation/engine/changes.py +3 -3
  144. localstack/services/cloudformation/engine/entities.py +27 -17
  145. localstack/services/cloudformation/engine/parameters.py +4 -4
  146. localstack/services/cloudformation/engine/template_deployer.py +15 -14
  147. localstack/services/cloudformation/engine/template_utils.py +34 -12
  148. localstack/services/cloudformation/engine/transformers.py +11 -8
  149. localstack/services/cloudformation/engine/types.py +5 -4
  150. localstack/services/cloudformation/engine/v2/change_set_model.py +336 -39
  151. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +96 -17
  152. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +289 -136
  153. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +315 -146
  154. localstack/services/cloudformation/engine/v2/change_set_model_transform.py +380 -105
  155. localstack/services/cloudformation/engine/v2/change_set_model_validator.py +183 -0
  156. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +6 -0
  157. localstack/services/cloudformation/engine/v2/resolving.py +102 -0
  158. localstack/services/cloudformation/engine/yaml_parser.py +9 -2
  159. localstack/services/cloudformation/provider.py +11 -6
  160. localstack/services/cloudformation/provider_utils.py +34 -4
  161. localstack/services/cloudformation/resource_provider.py +31 -21
  162. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro.py +7 -7
  163. localstack/services/cloudformation/resource_providers/aws_cloudformation_macro_plugin.py +1 -3
  164. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack.py +9 -9
  165. localstack/services/cloudformation/resource_providers/aws_cloudformation_stack_plugin.py +1 -3
  166. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition.py +6 -6
  167. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitcondition_plugin.py +1 -3
  168. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle.py +2 -2
  169. localstack/services/cloudformation/resource_providers/aws_cloudformation_waitconditionhandle_plugin.py +1 -3
  170. localstack/services/cloudformation/resources.py +24149 -0
  171. localstack/services/cloudformation/scaffolding/__main__.py +13 -12
  172. localstack/services/cloudformation/scaffolding/propgen.py +2 -2
  173. localstack/services/cloudformation/service_models.py +2 -2
  174. localstack/services/cloudformation/stores.py +33 -22
  175. localstack/services/cloudformation/v2/entities.py +103 -88
  176. localstack/services/cloudformation/v2/provider.py +872 -131
  177. localstack/services/cloudformation/v2/types.py +38 -0
  178. localstack/services/cloudformation/v2/utils.py +4 -1
  179. localstack/services/cloudwatch/alarm_scheduler.py +11 -8
  180. localstack/services/cloudwatch/cloudwatch_database_helper.py +4 -5
  181. localstack/services/cloudwatch/models.py +5 -7
  182. localstack/services/cloudwatch/provider.py +30 -25
  183. localstack/services/cloudwatch/provider_v2.py +27 -32
  184. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py +40 -40
  185. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm_plugin.py +1 -3
  186. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm.py +12 -12
  187. localstack/services/cloudwatch/resource_providers/aws_cloudwatch_compositealarm_plugin.py +1 -3
  188. localstack/services/dynamodb/packages.py +3 -3
  189. localstack/services/dynamodb/provider.py +159 -18
  190. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable.py +63 -63
  191. localstack/services/dynamodb/resource_providers/aws_dynamodb_globaltable_plugin.py +1 -3
  192. localstack/services/dynamodb/resource_providers/aws_dynamodb_table.py +57 -57
  193. localstack/services/dynamodb/resource_providers/aws_dynamodb_table_plugin.py +1 -3
  194. localstack/services/dynamodb/server.py +2 -2
  195. localstack/services/dynamodb/utils.py +13 -14
  196. localstack/services/dynamodb/v2/provider.py +157 -18
  197. localstack/services/dynamodbstreams/dynamodbstreams_api.py +2 -2
  198. localstack/services/dynamodbstreams/models.py +1 -3
  199. localstack/services/ec2/patches.py +26 -5
  200. localstack/services/ec2/provider.py +3 -3
  201. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions.py +10 -10
  202. localstack/services/ec2/resource_providers/aws_ec2_dhcpoptions_plugin.py +1 -3
  203. localstack/services/ec2/resource_providers/aws_ec2_instance.py +96 -96
  204. localstack/services/ec2/resource_providers/aws_ec2_instance_plugin.py +1 -3
  205. localstack/services/ec2/resource_providers/aws_ec2_internetgateway.py +5 -5
  206. localstack/services/ec2/resource_providers/aws_ec2_internetgateway_plugin.py +1 -3
  207. localstack/services/ec2/resource_providers/aws_ec2_keypair.py +10 -10
  208. localstack/services/ec2/resource_providers/aws_ec2_keypair_plugin.py +1 -3
  209. localstack/services/ec2/resource_providers/aws_ec2_natgateway.py +13 -13
  210. localstack/services/ec2/resource_providers/aws_ec2_natgateway_plugin.py +1 -3
  211. localstack/services/ec2/resource_providers/aws_ec2_networkacl.py +6 -6
  212. localstack/services/ec2/resource_providers/aws_ec2_networkacl_plugin.py +1 -3
  213. localstack/services/ec2/resource_providers/aws_ec2_prefixlist.py +14 -14
  214. localstack/services/ec2/resource_providers/aws_ec2_prefixlist_plugin.py +1 -3
  215. localstack/services/ec2/resource_providers/aws_ec2_route.py +15 -15
  216. localstack/services/ec2/resource_providers/aws_ec2_route_plugin.py +1 -3
  217. localstack/services/ec2/resource_providers/aws_ec2_routetable.py +6 -6
  218. localstack/services/ec2/resource_providers/aws_ec2_routetable_plugin.py +1 -3
  219. localstack/services/ec2/resource_providers/aws_ec2_securitygroup.py +29 -29
  220. localstack/services/ec2/resource_providers/aws_ec2_securitygroup_plugin.py +1 -3
  221. localstack/services/ec2/resource_providers/aws_ec2_subnet.py +19 -19
  222. localstack/services/ec2/resource_providers/aws_ec2_subnet_plugin.py +1 -3
  223. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation.py +4 -4
  224. localstack/services/ec2/resource_providers/aws_ec2_subnetroutetableassociation_plugin.py +1 -3
  225. localstack/services/ec2/resource_providers/aws_ec2_transitgateway.py +16 -16
  226. localstack/services/ec2/resource_providers/aws_ec2_transitgateway_plugin.py +1 -3
  227. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment.py +9 -9
  228. localstack/services/ec2/resource_providers/aws_ec2_transitgatewayattachment_plugin.py +1 -3
  229. localstack/services/ec2/resource_providers/aws_ec2_vpc.py +15 -15
  230. localstack/services/ec2/resource_providers/aws_ec2_vpc_plugin.py +1 -3
  231. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint.py +29 -22
  232. localstack/services/ec2/resource_providers/aws_ec2_vpcendpoint_plugin.py +1 -3
  233. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment.py +5 -5
  234. localstack/services/ec2/resource_providers/aws_ec2_vpcgatewayattachment_plugin.py +1 -3
  235. localstack/services/ecr/resource_providers/aws_ecr_repository.py +22 -19
  236. localstack/services/ecr/resource_providers/aws_ecr_repository_plugin.py +1 -3
  237. localstack/services/edge.py +6 -6
  238. localstack/services/es/provider.py +21 -21
  239. localstack/services/events/archive.py +2 -2
  240. localstack/services/events/connection.py +5 -5
  241. localstack/services/events/event_bus.py +9 -9
  242. localstack/services/events/event_rule_engine.py +31 -13
  243. localstack/services/events/models.py +29 -30
  244. localstack/services/events/provider.py +29 -26
  245. localstack/services/events/replay.py +3 -3
  246. localstack/services/events/resource_providers/aws_events_apidestination.py +8 -8
  247. localstack/services/events/resource_providers/aws_events_apidestination_plugin.py +1 -3
  248. localstack/services/events/resource_providers/aws_events_connection.py +27 -27
  249. localstack/services/events/resource_providers/aws_events_connection_plugin.py +1 -3
  250. localstack/services/events/resource_providers/aws_events_eventbus.py +9 -9
  251. localstack/services/events/resource_providers/aws_events_eventbus_plugin.py +1 -3
  252. localstack/services/events/resource_providers/aws_events_eventbuspolicy.py +11 -11
  253. localstack/services/events/resource_providers/aws_events_eventbuspolicy_plugin.py +1 -3
  254. localstack/services/events/resource_providers/aws_events_rule.py +82 -82
  255. localstack/services/events/resource_providers/aws_events_rule_plugin.py +1 -3
  256. localstack/services/events/rule.py +15 -15
  257. localstack/services/events/target.py +21 -13
  258. localstack/services/events/utils.py +7 -7
  259. localstack/services/events/v1/models.py +1 -3
  260. localstack/services/events/v1/provider.py +15 -15
  261. localstack/services/firehose/models.py +1 -3
  262. localstack/services/firehose/provider.py +25 -16
  263. localstack/services/iam/iam_patches.py +5 -6
  264. localstack/services/iam/provider.py +14 -119
  265. localstack/services/iam/resource_providers/aws_iam_accesskey.py +6 -6
  266. localstack/services/iam/resource_providers/aws_iam_accesskey_plugin.py +1 -3
  267. localstack/services/iam/resource_providers/aws_iam_group.py +9 -9
  268. localstack/services/iam/resource_providers/aws_iam_group_plugin.py +1 -3
  269. localstack/services/iam/resource_providers/aws_iam_instanceprofile.py +5 -5
  270. localstack/services/iam/resource_providers/aws_iam_instanceprofile_plugin.py +1 -3
  271. localstack/services/iam/resource_providers/aws_iam_managedpolicy.py +9 -9
  272. localstack/services/iam/resource_providers/aws_iam_managedpolicy_plugin.py +1 -3
  273. localstack/services/iam/resource_providers/aws_iam_policy.py +7 -7
  274. localstack/services/iam/resource_providers/aws_iam_policy_plugin.py +1 -3
  275. localstack/services/iam/resource_providers/aws_iam_role.py +16 -16
  276. localstack/services/iam/resource_providers/aws_iam_role_plugin.py +1 -3
  277. localstack/services/iam/resource_providers/aws_iam_servercertificate.py +10 -10
  278. localstack/services/iam/resource_providers/aws_iam_servercertificate_plugin.py +1 -3
  279. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole.py +5 -5
  280. localstack/services/iam/resource_providers/aws_iam_servicelinkedrole_plugin.py +1 -3
  281. localstack/services/iam/resource_providers/aws_iam_user.py +17 -17
  282. localstack/services/iam/resource_providers/aws_iam_user_plugin.py +1 -3
  283. localstack/services/iam/resources/policy_simulator.py +133 -0
  284. localstack/services/kinesis/kinesis_mock_server.py +7 -8
  285. localstack/services/kinesis/models.py +17 -5
  286. localstack/services/kinesis/packages.py +3 -3
  287. localstack/services/kinesis/provider.py +86 -3
  288. localstack/services/kinesis/resource_providers/aws_kinesis_stream.py +13 -13
  289. localstack/services/kinesis/resource_providers/aws_kinesis_stream_plugin.py +1 -3
  290. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer.py +7 -7
  291. localstack/services/kinesis/resource_providers/aws_kinesis_streamconsumer_plugin.py +1 -3
  292. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream.py +191 -191
  293. localstack/services/kinesisfirehose/resource_providers/aws_kinesisfirehose_deliverystream_plugin.py +1 -3
  294. localstack/services/kms/models.py +21 -18
  295. localstack/services/kms/provider.py +62 -26
  296. localstack/services/kms/resource_providers/aws_kms_alias.py +3 -3
  297. localstack/services/kms/resource_providers/aws_kms_alias_plugin.py +1 -3
  298. localstack/services/kms/resource_providers/aws_kms_key.py +14 -14
  299. localstack/services/kms/resource_providers/aws_kms_key_plugin.py +1 -3
  300. localstack/services/kms/utils.py +4 -3
  301. localstack/services/lambda_/api_utils.py +19 -16
  302. localstack/services/lambda_/custom_endpoints.py +2 -2
  303. localstack/services/lambda_/event_source_mapping/esm_worker_factory.py +4 -7
  304. localstack/services/lambda_/event_source_mapping/pipe_utils.py +2 -2
  305. localstack/services/lambda_/event_source_mapping/pollers/stream_poller.py +1 -1
  306. localstack/services/lambda_/event_source_mapping/senders/sender_utils.py +2 -1
  307. localstack/services/lambda_/hooks.py +6 -1
  308. localstack/services/lambda_/invocation/assignment.py +1 -2
  309. localstack/services/lambda_/invocation/docker_runtime_executor.py +7 -11
  310. localstack/services/lambda_/invocation/event_manager.py +1 -1
  311. localstack/services/lambda_/invocation/execution_environment.py +4 -4
  312. localstack/services/lambda_/invocation/executor_endpoint.py +8 -11
  313. localstack/services/lambda_/invocation/internal_sqs_queue.py +6 -10
  314. localstack/services/lambda_/invocation/lambda_models.py +33 -30
  315. localstack/services/lambda_/invocation/lambda_service.py +12 -5
  316. localstack/services/lambda_/invocation/logs.py +2 -3
  317. localstack/services/lambda_/invocation/runtime_executor.py +3 -3
  318. localstack/services/lambda_/invocation/version_manager.py +31 -8
  319. localstack/services/lambda_/ldm.py +14 -0
  320. localstack/services/lambda_/packages.py +3 -4
  321. localstack/services/lambda_/provider.py +9 -26
  322. localstack/services/lambda_/provider_utils.py +1 -1
  323. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig.py +8 -8
  324. localstack/services/lambda_/resource_providers/aws_lambda_codesigningconfig_plugin.py +1 -3
  325. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig.py +11 -11
  326. localstack/services/lambda_/resource_providers/aws_lambda_eventinvokeconfig_plugin.py +1 -3
  327. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping.py +39 -39
  328. localstack/services/lambda_/resource_providers/aws_lambda_eventsourcemapping_plugin.py +1 -3
  329. localstack/services/lambda_/resource_providers/aws_lambda_function.py +54 -54
  330. localstack/services/lambda_/resource_providers/aws_lambda_function_plugin.py +1 -3
  331. localstack/services/lambda_/resource_providers/aws_lambda_layerversion.py +11 -11
  332. localstack/services/lambda_/resource_providers/aws_lambda_layerversion_plugin.py +1 -3
  333. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission.py +6 -6
  334. localstack/services/lambda_/resource_providers/aws_lambda_layerversionpermission_plugin.py +1 -3
  335. localstack/services/lambda_/resource_providers/aws_lambda_permission.py +10 -10
  336. localstack/services/lambda_/resource_providers/aws_lambda_permission_plugin.py +1 -3
  337. localstack/services/lambda_/resource_providers/aws_lambda_url.py +15 -15
  338. localstack/services/lambda_/resource_providers/aws_lambda_url_plugin.py +1 -3
  339. localstack/services/lambda_/resource_providers/aws_lambda_version.py +8 -8
  340. localstack/services/lambda_/resource_providers/aws_lambda_version_plugin.py +1 -3
  341. localstack/services/lambda_/resource_providers/lambda_alias.py +12 -12
  342. localstack/services/lambda_/resource_providers/lambda_alias_plugin.py +1 -3
  343. localstack/services/lambda_/runtimes.py +1 -3
  344. localstack/services/lambda_/urlrouter.py +14 -1
  345. localstack/services/logs/models.py +1 -3
  346. localstack/services/logs/provider.py +39 -22
  347. localstack/services/logs/resource_providers/aws_logs_loggroup.py +9 -9
  348. localstack/services/logs/resource_providers/aws_logs_loggroup_plugin.py +1 -3
  349. localstack/services/logs/resource_providers/aws_logs_logstream.py +4 -4
  350. localstack/services/logs/resource_providers/aws_logs_logstream_plugin.py +1 -3
  351. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter.py +7 -7
  352. localstack/services/logs/resource_providers/aws_logs_subscriptionfilter_plugin.py +1 -3
  353. localstack/services/moto.py +5 -4
  354. localstack/services/opensearch/cluster.py +28 -20
  355. localstack/services/opensearch/cluster_manager.py +13 -14
  356. localstack/services/opensearch/models.py +1 -3
  357. localstack/services/opensearch/packages.py +27 -9
  358. localstack/services/opensearch/provider.py +15 -10
  359. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain.py +61 -61
  360. localstack/services/opensearch/resource_providers/aws_elasticsearch_domain_plugin.py +1 -3
  361. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain.py +89 -89
  362. localstack/services/opensearch/resource_providers/aws_opensearchservice_domain_plugin.py +1 -3
  363. localstack/services/opensearch/versions.py +57 -10
  364. localstack/services/plugins.py +37 -32
  365. localstack/services/providers.py +10 -2
  366. localstack/services/redshift/provider.py +0 -21
  367. localstack/services/redshift/resource_providers/aws_redshift_cluster.py +57 -57
  368. localstack/services/redshift/resource_providers/aws_redshift_cluster_plugin.py +1 -3
  369. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group.py +21 -21
  370. localstack/services/resource_groups/resource_providers/aws_resourcegroups_group_plugin.py +1 -3
  371. localstack/services/route53/models.py +1 -3
  372. localstack/services/route53/provider.py +1 -2
  373. localstack/services/route53/resource_providers/aws_route53_healthcheck.py +6 -6
  374. localstack/services/route53/resource_providers/aws_route53_healthcheck_plugin.py +1 -3
  375. localstack/services/route53/resource_providers/aws_route53_recordset.py +27 -27
  376. localstack/services/route53/resource_providers/aws_route53_recordset_plugin.py +1 -3
  377. localstack/services/route53resolver/models.py +8 -10
  378. localstack/services/route53resolver/provider.py +12 -12
  379. localstack/services/s3/codec.py +2 -2
  380. localstack/services/s3/constants.py +5 -2
  381. localstack/services/s3/cors.py +8 -8
  382. localstack/services/s3/models.py +73 -73
  383. localstack/services/s3/notifications.py +74 -58
  384. localstack/services/s3/presigned_url.py +41 -59
  385. localstack/services/s3/provider.py +86 -29
  386. localstack/services/s3/resource_providers/aws_s3_bucket.py +180 -180
  387. localstack/services/s3/resource_providers/aws_s3_bucket_plugin.py +1 -3
  388. localstack/services/s3/resource_providers/aws_s3_bucketpolicy.py +4 -4
  389. localstack/services/s3/resource_providers/aws_s3_bucketpolicy_plugin.py +1 -3
  390. localstack/services/s3/storage/core.py +4 -3
  391. localstack/services/s3/storage/ephemeral.py +7 -6
  392. localstack/services/s3/utils.py +51 -31
  393. localstack/services/s3/validation.py +47 -33
  394. localstack/services/s3/website_hosting.py +9 -7
  395. localstack/services/scheduler/resource_providers/aws_scheduler_schedule.py +60 -60
  396. localstack/services/scheduler/resource_providers/aws_scheduler_schedule_plugin.py +1 -3
  397. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup.py +9 -9
  398. localstack/services/scheduler/resource_providers/aws_scheduler_schedulegroup_plugin.py +1 -3
  399. localstack/services/secretsmanager/provider.py +10 -12
  400. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy.py +5 -5
  401. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_resourcepolicy_plugin.py +1 -3
  402. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule.py +21 -21
  403. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_rotationschedule_plugin.py +1 -3
  404. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret.py +23 -23
  405. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secret_plugin.py +1 -3
  406. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment.py +5 -5
  407. localstack/services/secretsmanager/resource_providers/aws_secretsmanager_secrettargetattachment_plugin.py +1 -3
  408. localstack/services/ses/models.py +8 -1
  409. localstack/services/ses/provider.py +128 -55
  410. localstack/services/ses/resource_providers/aws_ses_emailidentity.py +21 -21
  411. localstack/services/ses/resource_providers/aws_ses_emailidentity_plugin.py +1 -3
  412. localstack/services/sns/constants.py +7 -1
  413. localstack/services/sns/executor.py +9 -2
  414. localstack/services/sns/models.py +25 -25
  415. localstack/services/sns/provider.py +9 -7
  416. localstack/services/sns/publisher.py +37 -23
  417. localstack/services/sns/resource_providers/aws_sns_subscription.py +13 -13
  418. localstack/services/sns/resource_providers/aws_sns_subscription_plugin.py +1 -3
  419. localstack/services/sns/resource_providers/aws_sns_topic.py +16 -16
  420. localstack/services/sns/resource_providers/aws_sns_topic_plugin.py +1 -3
  421. localstack/services/sns/resource_providers/aws_sns_topicpolicy.py +4 -4
  422. localstack/services/sns/resource_providers/aws_sns_topicpolicy_plugin.py +1 -3
  423. localstack/services/sns/v2/models.py +167 -0
  424. localstack/services/sns/v2/provider.py +867 -0
  425. localstack/services/sns/v2/utils.py +130 -0
  426. localstack/services/sqs/constants.py +2 -2
  427. localstack/services/sqs/developer_api.py +205 -0
  428. localstack/services/sqs/models.py +71 -36
  429. localstack/services/sqs/provider.py +56 -332
  430. localstack/services/sqs/query_api.py +8 -5
  431. localstack/services/sqs/resource_providers/aws_sqs_queue.py +21 -21
  432. localstack/services/sqs/resource_providers/aws_sqs_queue_plugin.py +1 -3
  433. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy.py +7 -5
  434. localstack/services/sqs/resource_providers/aws_sqs_queuepolicy_plugin.py +1 -3
  435. localstack/services/sqs/utils.py +123 -4
  436. localstack/services/ssm/provider.py +3 -4
  437. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow.py +15 -15
  438. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindow_plugin.py +1 -3
  439. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget.py +10 -10
  440. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtarget_plugin.py +1 -3
  441. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask.py +48 -48
  442. localstack/services/ssm/resource_providers/aws_ssm_maintenancewindowtask_plugin.py +1 -3
  443. localstack/services/ssm/resource_providers/aws_ssm_parameter.py +10 -10
  444. localstack/services/ssm/resource_providers/aws_ssm_parameter_plugin.py +1 -3
  445. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline.py +29 -29
  446. localstack/services/ssm/resource_providers/aws_ssm_patchbaseline_plugin.py +1 -3
  447. localstack/services/stepfunctions/asl/antlt4utils/antlr4utils.py +3 -4
  448. localstack/services/stepfunctions/asl/component/common/assign/assign_decl.py +1 -1
  449. localstack/services/stepfunctions/asl/component/common/assign/assign_decl_binding.py +1 -1
  450. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_array.py +1 -1
  451. localstack/services/stepfunctions/asl/component/common/assign/assign_template_value_object.py +1 -1
  452. localstack/services/stepfunctions/asl/component/common/catch/catcher_decl.py +9 -9
  453. localstack/services/stepfunctions/asl/component/common/error_name/custom_error_name.py +2 -2
  454. localstack/services/stepfunctions/asl/component/common/error_name/error_name.py +4 -4
  455. localstack/services/stepfunctions/asl/component/common/error_name/failure_event.py +8 -8
  456. localstack/services/stepfunctions/asl/component/common/error_name/states_error_name_type.py +1 -1
  457. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_binding.py +2 -2
  458. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_array.py +1 -1
  459. localstack/services/stepfunctions/asl/component/common/jsonata/jsonata_template_value_object.py +1 -1
  460. localstack/services/stepfunctions/asl/component/common/path/input_path.py +4 -4
  461. localstack/services/stepfunctions/asl/component/common/path/output_path.py +4 -4
  462. localstack/services/stepfunctions/asl/component/common/path/result_path.py +3 -3
  463. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadarr/payload_arr.py +1 -1
  464. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding.py +3 -3
  465. localstack/services/stepfunctions/asl/component/common/payload/payloadvalue/payloadtmpl/payload_tmpl.py +1 -1
  466. localstack/services/stepfunctions/asl/component/common/retry/retrier_decl.py +8 -8
  467. localstack/services/stepfunctions/asl/component/common/string/string_expression.py +3 -3
  468. localstack/services/stepfunctions/asl/component/common/timeouts/timeout.py +3 -3
  469. localstack/services/stepfunctions/asl/component/eval_component.py +2 -3
  470. localstack/services/stepfunctions/asl/component/intrinsic/argument/argument.py +4 -4
  471. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/array/array_partition.py +1 -1
  472. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/generic/string_format.py +1 -1
  473. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_array.py +1 -1
  474. localstack/services/stepfunctions/asl/component/intrinsic/function/statesfunction/states_function_format.py +1 -1
  475. localstack/services/stepfunctions/asl/component/intrinsic/jsonata.py +3 -3
  476. localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
  477. localstack/services/stepfunctions/asl/component/program/program.py +9 -9
  478. localstack/services/stepfunctions/asl/component/program/states.py +1 -1
  479. localstack/services/stepfunctions/asl/component/state/state.py +10 -11
  480. localstack/services/stepfunctions/asl/component/state/state_choice/choice_rule.py +11 -11
  481. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
  482. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/operator/implementations/is_operator.py +2 -2
  483. localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +3 -5
  484. localstack/services/stepfunctions/asl/component/state/state_execution/execute_state.py +9 -9
  485. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/item_reader_decl.py +7 -7
  486. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/reader_config/reader_config_decl.py +5 -5
  487. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_eval_s3.py +2 -1
  488. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/item_reader/resource_eval/resource_output_transformer/resource_output_transformer_csv.py +2 -2
  489. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/distributed_iteration_component.py +8 -8
  490. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/inline_iteration_component.py +7 -7
  491. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +4 -4
  492. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/inline_item_processor_worker.py +5 -5
  493. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/itemprocessor/map_run_record.py +10 -10
  494. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_component.py +3 -3
  495. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_declaration.py +3 -3
  496. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iteration_worker.py +2 -2
  497. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/distributed_iterator_worker.py +3 -5
  498. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator.py +1 -2
  499. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/iterator/inline_iterator_worker.py +5 -5
  500. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/iteration/job.py +9 -9
  501. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/result_writer/resource_eval/resource_eval_s3.py +2 -1
  502. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +12 -13
  503. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branch_worker.py +3 -3
  504. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/branches_decl.py +7 -7
  505. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +2 -3
  506. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/lambda_eval_utils.py +7 -7
  507. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/resource.py +3 -3
  508. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service.py +10 -10
  509. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_api_gateway.py +18 -18
  510. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_aws_sdk.py +1 -1
  511. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_batch.py +8 -7
  512. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_callback.py +18 -17
  513. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_dynamodb.py +2 -2
  514. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_ecs.py +5 -4
  515. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_events.py +4 -4
  516. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_glue.py +7 -6
  517. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_lambda.py +4 -4
  518. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sfn.py +9 -8
  519. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sns.py +2 -2
  520. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/service/state_task_service_sqs.py +4 -4
  521. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +5 -5
  522. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task_lambda.py +2 -2
  523. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +3 -5
  524. localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +5 -7
  525. localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
  526. localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
  527. localstack/services/stepfunctions/asl/component/state/state_wait/wait_function/timestamp.py +2 -2
  528. localstack/services/stepfunctions/asl/eval/callback/callback.py +18 -18
  529. localstack/services/stepfunctions/asl/eval/environment.py +22 -24
  530. localstack/services/stepfunctions/asl/eval/evaluation_details.py +3 -5
  531. localstack/services/stepfunctions/asl/eval/event/event_manager.py +10 -10
  532. localstack/services/stepfunctions/asl/eval/event/logging.py +3 -3
  533. localstack/services/stepfunctions/asl/eval/program_state.py +8 -8
  534. localstack/services/stepfunctions/asl/eval/states.py +12 -12
  535. localstack/services/stepfunctions/asl/eval/test_state/environment.py +3 -5
  536. localstack/services/stepfunctions/asl/eval/variable_store.py +6 -6
  537. localstack/services/stepfunctions/asl/jsonata/jsonata.py +7 -6
  538. localstack/services/stepfunctions/asl/parse/asl_parser.py +1 -1
  539. localstack/services/stepfunctions/asl/parse/intrinsic/preprocessor.py +2 -3
  540. localstack/services/stepfunctions/asl/parse/preprocessor.py +44 -44
  541. localstack/services/stepfunctions/asl/parse/typed_props.py +2 -2
  542. localstack/services/stepfunctions/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py +1 -1
  543. localstack/services/stepfunctions/asl/static_analyser/variable_references_static_analyser.py +2 -2
  544. localstack/services/stepfunctions/asl/utils/encoding.py +2 -2
  545. localstack/services/stepfunctions/asl/utils/json_path.py +2 -2
  546. localstack/services/stepfunctions/backend/activity.py +4 -4
  547. localstack/services/stepfunctions/backend/alias.py +8 -8
  548. localstack/services/stepfunctions/backend/execution.py +29 -30
  549. localstack/services/stepfunctions/backend/execution_worker.py +7 -7
  550. localstack/services/stepfunctions/backend/state_machine.py +28 -28
  551. localstack/services/stepfunctions/backend/test_state/execution.py +3 -4
  552. localstack/services/stepfunctions/backend/test_state/execution_worker.py +1 -3
  553. localstack/services/stepfunctions/mocking/mock_config.py +9 -9
  554. localstack/services/stepfunctions/mocking/mock_config_file.py +10 -10
  555. localstack/services/stepfunctions/packages.py +14 -5
  556. localstack/services/stepfunctions/provider.py +34 -44
  557. localstack/services/stepfunctions/quotas.py +2 -3
  558. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity.py +6 -6
  559. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_activity_plugin.py +1 -3
  560. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine.py +25 -25
  561. localstack/services/stepfunctions/resource_providers/aws_stepfunctions_statemachine_plugin.py +1 -3
  562. localstack/services/stepfunctions/stepfunctions_utils.py +1 -2
  563. localstack/services/stores.py +8 -8
  564. localstack/services/transcribe/packages.py +1 -3
  565. localstack/services/transcribe/provider.py +8 -3
  566. localstack/state/codecs.py +61 -0
  567. localstack/state/core.py +11 -5
  568. localstack/state/inspect.py +4 -4
  569. localstack/state/pickle.py +36 -23
  570. localstack/testing/aws/asf_utils.py +3 -2
  571. localstack/testing/aws/cloudformation_utils.py +1 -1
  572. localstack/testing/aws/lambda_utils.py +15 -14
  573. localstack/testing/aws/util.py +3 -2
  574. localstack/testing/pytest/cloudformation/fixtures.py +68 -18
  575. localstack/testing/pytest/container.py +5 -5
  576. localstack/testing/pytest/filters.py +1 -3
  577. localstack/testing/pytest/fixtures.py +188 -49
  578. localstack/testing/pytest/in_memory_localstack.py +1 -3
  579. localstack/testing/pytest/marking.py +42 -15
  580. localstack/testing/pytest/path_filter.py +1 -1
  581. localstack/testing/pytest/stepfunctions/fixtures.py +4 -4
  582. localstack/testing/pytest/stepfunctions/utils.py +11 -10
  583. localstack/testing/pytest/util.py +1 -1
  584. localstack/testing/pytest/validation_tracking.py +3 -4
  585. localstack/testing/scenario/provisioning.py +11 -10
  586. localstack/testing/snapshots/transformer_utility.py +8 -3
  587. localstack/testing/testselection/matching.py +2 -2
  588. localstack/testing/testselection/opt_out.py +1 -1
  589. localstack/testing/testselection/scripts/filter_by_test_selection.py +1 -1
  590. localstack/testing/testselection/scripts/generate_test_selection.py +1 -1
  591. localstack/testing/testselection/testselection.py +2 -2
  592. localstack/utils/analytics/cli.py +2 -3
  593. localstack/utils/analytics/client.py +5 -5
  594. localstack/utils/analytics/events.py +2 -2
  595. localstack/utils/analytics/metadata.py +6 -4
  596. localstack/utils/analytics/metrics/counter.py +11 -18
  597. localstack/utils/analytics/metrics/registry.py +2 -2
  598. localstack/utils/analytics/publisher.py +4 -5
  599. localstack/utils/analytics/service_providers.py +19 -0
  600. localstack/utils/analytics/service_request_aggregator.py +4 -4
  601. localstack/utils/archives.py +12 -12
  602. localstack/utils/asyncio.py +2 -2
  603. localstack/utils/aws/arns.py +26 -31
  604. localstack/utils/aws/aws_responses.py +21 -28
  605. localstack/utils/aws/aws_stack.py +7 -12
  606. localstack/utils/aws/dead_letter_queue.py +4 -9
  607. localstack/utils/aws/message_forwarding.py +8 -11
  608. localstack/utils/aws/request_context.py +5 -6
  609. localstack/utils/aws/resources.py +1 -1
  610. localstack/utils/aws/templating.py +4 -4
  611. localstack/utils/batch_policy.py +4 -4
  612. localstack/utils/bootstrap.py +37 -30
  613. localstack/utils/catalog/catalog.py +139 -0
  614. localstack/utils/catalog/catalog_loader.py +119 -0
  615. localstack/utils/catalog/common.py +58 -0
  616. localstack/utils/catalog/plugins.py +28 -0
  617. localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
  618. localstack/utils/collections.py +33 -27
  619. localstack/utils/config_listener.py +2 -2
  620. localstack/utils/container_networking.py +5 -6
  621. localstack/utils/container_utils/container_client.py +156 -160
  622. localstack/utils/container_utils/docker_cmd_client.py +97 -81
  623. localstack/utils/container_utils/docker_sdk_client.py +75 -72
  624. localstack/utils/crypto.py +12 -13
  625. localstack/utils/diagnose.py +11 -12
  626. localstack/utils/docker_utils.py +11 -7
  627. localstack/utils/files.py +34 -15
  628. localstack/utils/functions.py +5 -4
  629. localstack/utils/http.py +14 -14
  630. localstack/utils/iputils.py +2 -1
  631. localstack/utils/json.py +21 -7
  632. localstack/utils/kinesis/kinesis_connector.py +2 -1
  633. localstack/utils/net.py +25 -17
  634. localstack/utils/no_exit_argument_parser.py +2 -2
  635. localstack/utils/numbers.py +9 -2
  636. localstack/utils/objects.py +15 -14
  637. localstack/utils/patch.py +14 -7
  638. localstack/utils/platform.py +2 -2
  639. localstack/utils/run.py +15 -14
  640. localstack/utils/scheduler.py +13 -12
  641. localstack/utils/server/tcp_proxy.py +2 -2
  642. localstack/utils/serving.py +3 -4
  643. localstack/utils/strings.py +15 -16
  644. localstack/utils/sync.py +126 -1
  645. localstack/utils/tagging.py +10 -8
  646. localstack/utils/testutil.py +17 -17
  647. localstack/utils/threads.py +3 -3
  648. localstack/utils/time.py +12 -4
  649. localstack/utils/urls.py +1 -3
  650. localstack/utils/xml.py +1 -1
  651. localstack/utils/xray/traceid.py +1 -1
  652. localstack/version.py +16 -3
  653. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -13
  654. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +663 -655
  655. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
  656. localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
  657. localstack/packages/terraform.py +0 -47
  658. localstack/services/cloudformation/deploy.html +0 -144
  659. localstack/services/cloudformation/deploy_ui.py +0 -47
  660. localstack/services/cloudformation/plugins.py +0 -12
  661. localstack/services/lambda_/lambda_debug_mode/ldm.py +0 -375
  662. localstack/services/lambda_/lambda_debug_mode/ldm_config_file.py +0 -178
  663. localstack/services/lambda_/lambda_debug_mode/ldm_types.py +0 -11
  664. localstack/services/lambda_/lambda_debug_mode/ldm_utils.py +0 -43
  665. localstack_core-4.6.1.dev60.dist-info/plux.json +0 -1
  666. /localstack/{services/lambda_/lambda_debug_mode/__init__.py → testing/pytest/cloudformation/transformers.py} +0 -0
  667. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
  668. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
  669. {localstack_core-4.6.1.dev60.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
  670. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
  671. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
  672. {localstack_core-4.6.1.dev60.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  import logging
2
2
  import re
3
- from typing import Optional, Protocol, Tuple
3
+ from typing import Protocol
4
4
 
5
5
  from werkzeug.datastructures import Headers
6
6
 
@@ -21,13 +21,13 @@ from localstack.aws.protocol.op_router import RestServiceOperationRouter
21
21
  from localstack.aws.spec import get_service_catalog
22
22
  from localstack.config import S3_VIRTUAL_HOSTNAME
23
23
  from localstack.http import Request, Response
24
+ from localstack.services.s3.constants import S3_HOST_ID
24
25
  from localstack.services.s3.utils import S3_VIRTUAL_HOSTNAME_REGEX
25
26
 
26
27
  # TODO: add more logging statements
27
28
  LOG = logging.getLogger(__name__)
28
29
 
29
30
  _s3_virtual_host_regex = re.compile(S3_VIRTUAL_HOSTNAME_REGEX)
30
- FAKE_HOST_ID = "9Gjjt1m+cjU4OPvX9O9/8RuvnG41MRb/18Oux2o5H5MY7ISNTlXN+Dz9IG62/ILVxhAGI0qyPfg="
31
31
 
32
32
  # TODO: refactor those to expose the needed methods maybe in another way that both can import
33
33
  add_default_headers = CorsResponseEnricher.add_cors_headers
@@ -58,7 +58,7 @@ class S3CorsHandler(Handler):
58
58
  def __call__(self, chain: HandlerChain, context: RequestContext, response: Response):
59
59
  self.handle_cors(chain, context, response)
60
60
 
61
- def pre_parse_s3_request(self, request: Request) -> Tuple[bool, Optional[str]]:
61
+ def pre_parse_s3_request(self, request: Request) -> tuple[bool, str | None]:
62
62
  """
63
63
  Parse the request to try to determine if it's directed towards S3. It tries to match on host, then check
64
64
  if the targeted bucket exists. If we could not determine it was a s3 request from the host, but the first
@@ -135,7 +135,7 @@ class S3CorsHandler(Handler):
135
135
  if is_options_request:
136
136
  context.operation = self._get_op_from_request(request)
137
137
  raise BadRequest(
138
- "Insufficient information. Origin request header needed.", HostId=FAKE_HOST_ID
138
+ "Insufficient information. Origin request header needed.", HostId=S3_HOST_ID
139
139
  )
140
140
  else:
141
141
  # If the header is missing, Amazon S3 doesn't treat the request as a cross-origin request,
@@ -167,7 +167,7 @@ class S3CorsHandler(Handler):
167
167
  context.operation = self._get_op_from_request(request)
168
168
  raise AccessForbidden(
169
169
  message,
170
- HostId=FAKE_HOST_ID,
170
+ HostId=S3_HOST_ID,
171
171
  Method=request.headers.get("Access-Control-Request-Method", "OPTIONS"),
172
172
  ResourceType="BUCKET",
173
173
  )
@@ -182,7 +182,7 @@ class S3CorsHandler(Handler):
182
182
  context.operation = self._get_op_from_request(request)
183
183
  raise AccessForbidden(
184
184
  "CORSResponse: This CORS request is not allowed. This is usually because the evalution of Origin, request method / Access-Control-Request-Method or Access-Control-Request-Headers are not whitelisted by the resource's CORS spec.",
185
- HostId=FAKE_HOST_ID,
185
+ HostId=S3_HOST_ID,
186
186
  Method=request.headers.get("Access-Control-Request-Method"),
187
187
  ResourceType="OBJECT",
188
188
  )
@@ -224,7 +224,7 @@ class S3CorsHandler(Handler):
224
224
  def invalidate_cache(self):
225
225
  self.bucket_cors_index.invalidate()
226
226
 
227
- def match_rules(self, request: Request, rules: CORSRules) -> Optional[CORSRule]:
227
+ def match_rules(self, request: Request, rules: CORSRules) -> CORSRule | None:
228
228
  """
229
229
  Try to match the request to the bucket rules. How to match rules:
230
230
  - The request's Origin header must match AllowedOrigin elements.
@@ -243,7 +243,7 @@ class S3CorsHandler(Handler):
243
243
  return matched_rule
244
244
 
245
245
  @staticmethod
246
- def _match_rule(rule: CORSRule, method: str, headers: Headers) -> Optional[CORSRule]:
246
+ def _match_rule(rule: CORSRule, method: str, headers: Headers) -> CORSRule | None:
247
247
  """
248
248
  Check if the request method and headers matches the given CORS rule.
249
249
  :param rule: CORSRule: a CORS Rule from the bucket
@@ -4,7 +4,7 @@ import logging
4
4
  from collections import defaultdict
5
5
  from datetime import datetime
6
6
  from secrets import token_urlsafe
7
- from typing import Literal, NamedTuple, Optional, Union
7
+ from typing import Literal, NamedTuple, Union
8
8
  from zoneinfo import ZoneInfo
9
9
 
10
10
  from localstack.aws.api import CommonServiceException
@@ -105,25 +105,25 @@ class S3Bucket:
105
105
  multiparts: dict[MultipartUploadId, "S3Multipart"]
106
106
  objects: Union["KeyStore", "VersionedKeyStore"]
107
107
  versioning_status: BucketVersioningStatus | None
108
- lifecycle_rules: Optional[LifecycleRules]
109
- transition_default_minimum_object_size: Optional[TransitionDefaultMinimumObjectSize]
110
- policy: Optional[Policy]
111
- website_configuration: Optional[WebsiteConfiguration]
108
+ lifecycle_rules: LifecycleRules | None
109
+ transition_default_minimum_object_size: TransitionDefaultMinimumObjectSize | None
110
+ policy: Policy | None
111
+ website_configuration: WebsiteConfiguration | None
112
112
  acl: AccessControlPolicy
113
- cors_rules: Optional[CORSConfiguration]
113
+ cors_rules: CORSConfiguration | None
114
114
  logging: LoggingEnabled
115
115
  notification_configuration: NotificationConfiguration
116
116
  payer: Payer
117
- encryption_rule: Optional[ServerSideEncryptionRule]
118
- public_access_block: Optional[PublicAccessBlockConfiguration]
119
- accelerate_status: Optional[BucketAccelerateStatus]
117
+ encryption_rule: ServerSideEncryptionRule | None
118
+ public_access_block: PublicAccessBlockConfiguration | None
119
+ accelerate_status: BucketAccelerateStatus | None
120
120
  object_lock_enabled: bool
121
121
  object_ownership: ObjectOwnership
122
122
  intelligent_tiering_configurations: dict[IntelligentTieringId, IntelligentTieringConfiguration]
123
123
  analytics_configurations: dict[AnalyticsId, AnalyticsConfiguration]
124
124
  inventory_configurations: dict[InventoryId, InventoryConfiguration]
125
125
  metric_configurations: dict[MetricsId, MetricsConfiguration]
126
- object_lock_default_retention: Optional[DefaultRetention]
126
+ object_lock_default_retention: DefaultRetention | None
127
127
  replication: ReplicationConfiguration
128
128
  owner: Owner
129
129
 
@@ -256,58 +256,58 @@ class S3Bucket:
256
256
 
257
257
  class S3Object:
258
258
  key: ObjectKey
259
- version_id: Optional[ObjectVersionId]
259
+ version_id: ObjectVersionId | None
260
260
  bucket: BucketName
261
- owner: Optional[Owner]
262
- size: Optional[Size]
263
- etag: Optional[ETag]
261
+ owner: Owner | None
262
+ size: Size | None
263
+ etag: ETag | None
264
264
  user_metadata: Metadata
265
265
  system_metadata: Metadata
266
266
  last_modified: datetime
267
- expires: Optional[datetime]
268
- expiration: Optional[Expiration] # right now, this is stored in the provider cache
267
+ expires: datetime | None
268
+ expiration: Expiration | None # right now, this is stored in the provider cache
269
269
  storage_class: StorageClass | ObjectStorageClass
270
- encryption: Optional[ServerSideEncryption] # inherit bucket
271
- kms_key_id: Optional[SSEKMSKeyId] # inherit bucket
272
- bucket_key_enabled: Optional[bool] # inherit bucket
273
- sse_key_hash: Optional[SSECustomerKeyMD5]
270
+ encryption: ServerSideEncryption | None # inherit bucket
271
+ kms_key_id: SSEKMSKeyId | None # inherit bucket
272
+ bucket_key_enabled: bool | None # inherit bucket
273
+ sse_key_hash: SSECustomerKeyMD5 | None
274
274
  checksum_algorithm: ChecksumAlgorithm
275
275
  checksum_value: str
276
276
  checksum_type: ChecksumType
277
- lock_mode: Optional[ObjectLockMode | ObjectLockRetentionMode]
278
- lock_legal_status: Optional[ObjectLockLegalHoldStatus]
279
- lock_until: Optional[datetime]
280
- website_redirect_location: Optional[WebsiteRedirectLocation]
281
- acl: Optional[AccessControlPolicy]
277
+ lock_mode: ObjectLockMode | ObjectLockRetentionMode | None
278
+ lock_legal_status: ObjectLockLegalHoldStatus | None
279
+ lock_until: datetime | None
280
+ website_redirect_location: WebsiteRedirectLocation | None
281
+ acl: AccessControlPolicy | None
282
282
  is_current: bool
283
- parts: Optional[dict[int, InternalObjectPart]]
284
- restore: Optional[Restore]
283
+ parts: dict[int, InternalObjectPart] | None
284
+ restore: Restore | None
285
285
  internal_last_modified: int
286
286
 
287
287
  def __init__(
288
288
  self,
289
289
  key: ObjectKey,
290
- etag: Optional[ETag] = None,
291
- size: Optional[int] = None,
292
- version_id: Optional[ObjectVersionId] = None,
293
- user_metadata: Optional[Metadata] = None,
294
- system_metadata: Optional[Metadata] = None,
290
+ etag: ETag | None = None,
291
+ size: int | None = None,
292
+ version_id: ObjectVersionId | None = None,
293
+ user_metadata: Metadata | None = None,
294
+ system_metadata: Metadata | None = None,
295
295
  storage_class: StorageClass = StorageClass.STANDARD,
296
- expires: Optional[datetime] = None,
297
- expiration: Optional[Expiration] = None,
298
- checksum_algorithm: Optional[ChecksumAlgorithm] = None,
299
- checksum_value: Optional[str] = None,
300
- checksum_type: Optional[ChecksumType] = ChecksumType.FULL_OBJECT,
301
- encryption: Optional[ServerSideEncryption] = None,
302
- kms_key_id: Optional[SSEKMSKeyId] = None,
303
- sse_key_hash: Optional[SSECustomerKeyMD5] = None,
296
+ expires: datetime | None = None,
297
+ expiration: Expiration | None = None,
298
+ checksum_algorithm: ChecksumAlgorithm | None = None,
299
+ checksum_value: str | None = None,
300
+ checksum_type: ChecksumType | None = ChecksumType.FULL_OBJECT,
301
+ encryption: ServerSideEncryption | None = None,
302
+ kms_key_id: SSEKMSKeyId | None = None,
303
+ sse_key_hash: SSECustomerKeyMD5 | None = None,
304
304
  bucket_key_enabled: bool = False,
305
- lock_mode: Optional[ObjectLockMode | ObjectLockRetentionMode] = None,
306
- lock_legal_status: Optional[ObjectLockLegalHoldStatus] = None,
307
- lock_until: Optional[datetime] = None,
308
- website_redirect_location: Optional[WebsiteRedirectLocation] = None,
309
- acl: Optional[AccessControlPolicy] = None, # TODO
310
- owner: Optional[Owner] = None,
305
+ lock_mode: ObjectLockMode | ObjectLockRetentionMode | None = None,
306
+ lock_legal_status: ObjectLockLegalHoldStatus | None = None,
307
+ lock_until: datetime | None = None,
308
+ website_redirect_location: WebsiteRedirectLocation | None = None,
309
+ acl: AccessControlPolicy | None = None, # TODO
310
+ owner: Owner | None = None,
311
311
  ):
312
312
  self.key = key
313
313
  self.user_metadata = (
@@ -406,19 +406,19 @@ class S3DeleteMarker:
406
406
  # TODO: could use dataclass, validate after models are set
407
407
  class S3Part:
408
408
  part_number: PartNumber
409
- etag: Optional[ETag]
409
+ etag: ETag | None
410
410
  last_modified: datetime
411
- size: Optional[int]
412
- checksum_algorithm: Optional[ChecksumAlgorithm]
413
- checksum_value: Optional[str]
411
+ size: int | None
412
+ checksum_algorithm: ChecksumAlgorithm | None
413
+ checksum_value: str | None
414
414
 
415
415
  def __init__(
416
416
  self,
417
417
  part_number: PartNumber,
418
418
  size: int = None,
419
419
  etag: ETag = None,
420
- checksum_algorithm: Optional[ChecksumAlgorithm] = None,
421
- checksum_value: Optional[str] = None,
420
+ checksum_algorithm: ChecksumAlgorithm | None = None,
421
+ checksum_value: str | None = None,
422
422
  ):
423
423
  self.last_modified = datetime.now(tz=_gmt_zone_info)
424
424
  self.part_number = part_number
@@ -436,8 +436,8 @@ class S3Multipart:
436
436
  parts: dict[PartNumber, S3Part]
437
437
  object: S3Object
438
438
  upload_id: MultipartUploadId
439
- checksum_value: Optional[str]
440
- checksum_type: Optional[ChecksumType]
439
+ checksum_value: str | None
440
+ checksum_type: ChecksumType | None
441
441
  checksum_algorithm: ChecksumAlgorithm
442
442
  initiated: datetime
443
443
  precondition: bool
@@ -446,25 +446,25 @@ class S3Multipart:
446
446
  self,
447
447
  key: ObjectKey,
448
448
  storage_class: StorageClass | ObjectStorageClass = StorageClass.STANDARD,
449
- expires: Optional[datetime] = None,
450
- expiration: Optional[datetime] = None, # come from lifecycle
451
- checksum_algorithm: Optional[ChecksumAlgorithm] = None,
452
- checksum_type: Optional[ChecksumType] = None,
453
- encryption: Optional[ServerSideEncryption] = None, # inherit bucket
454
- kms_key_id: Optional[SSEKMSKeyId] = None, # inherit bucket
449
+ expires: datetime | None = None,
450
+ expiration: datetime | None = None, # come from lifecycle
451
+ checksum_algorithm: ChecksumAlgorithm | None = None,
452
+ checksum_type: ChecksumType | None = None,
453
+ encryption: ServerSideEncryption | None = None, # inherit bucket
454
+ kms_key_id: SSEKMSKeyId | None = None, # inherit bucket
455
455
  bucket_key_enabled: bool = False, # inherit bucket
456
- sse_key_hash: Optional[SSECustomerKeyMD5] = None,
457
- lock_mode: Optional[ObjectLockMode] = None,
458
- lock_legal_status: Optional[ObjectLockLegalHoldStatus] = None,
459
- lock_until: Optional[datetime] = None,
460
- website_redirect_location: Optional[WebsiteRedirectLocation] = None,
461
- acl: Optional[AccessControlPolicy] = None, # TODO
462
- user_metadata: Optional[Metadata] = None,
463
- system_metadata: Optional[Metadata] = None,
464
- initiator: Optional[Owner] = None,
465
- tagging: Optional[dict[str, str]] = None,
466
- owner: Optional[Owner] = None,
467
- precondition: Optional[bool] = None,
456
+ sse_key_hash: SSECustomerKeyMD5 | None = None,
457
+ lock_mode: ObjectLockMode | None = None,
458
+ lock_legal_status: ObjectLockLegalHoldStatus | None = None,
459
+ lock_until: datetime | None = None,
460
+ website_redirect_location: WebsiteRedirectLocation | None = None,
461
+ acl: AccessControlPolicy | None = None, # TODO
462
+ user_metadata: Metadata | None = None,
463
+ system_metadata: Metadata | None = None,
464
+ initiator: Owner | None = None,
465
+ tagging: dict[str, str] | None = None,
466
+ owner: Owner | None = None,
467
+ precondition: bool | None = None,
468
468
  ):
469
469
  self.id = token_urlsafe(96) # MultipartUploadId is 128 characters long
470
470
  self.initiated = datetime.now(tz=_gmt_zone_info)
@@ -638,7 +638,7 @@ class KeyStore:
638
638
 
639
639
  def values(self, *_, **__) -> list[S3Object | S3DeleteMarker]:
640
640
  # we create a shallow copy with dict to avoid size changed during iteration
641
- return [value for value in dict(self._store).values()]
641
+ return list(dict(self._store).values())
642
642
 
643
643
  def is_empty(self) -> bool:
644
644
  return not self._store
@@ -6,7 +6,7 @@ import logging
6
6
  import re
7
7
  from concurrent.futures import ThreadPoolExecutor
8
8
  from dataclasses import dataclass
9
- from typing import Dict, List, Optional, Tuple, TypedDict, Union
9
+ from typing import TypedDict
10
10
  from urllib.parse import quote
11
11
 
12
12
  from botocore.exceptions import ClientError
@@ -21,6 +21,7 @@ from localstack.aws.api.s3 import (
21
21
  Event,
22
22
  EventBridgeConfiguration,
23
23
  EventList,
24
+ InvalidArgument,
24
25
  LambdaFunctionArn,
25
26
  LambdaFunctionConfiguration,
26
27
  NotificationConfiguration,
@@ -34,8 +35,8 @@ from localstack.aws.api.s3 import (
34
35
  TopicConfiguration,
35
36
  )
36
37
  from localstack.aws.connect import connect_to
38
+ from localstack.services.s3.exceptions import MalformedXML
37
39
  from localstack.services.s3.models import S3Bucket, S3DeleteMarker, S3Object
38
- from localstack.services.s3.utils import _create_invalid_argument_exc
39
40
  from localstack.utils.aws import arns
40
41
  from localstack.utils.aws.arns import ARN_PARTITION_REGEX, get_partition, parse_arn, s3_bucket_arn
41
42
  from localstack.utils.aws.client_types import ServicePrincipal
@@ -64,8 +65,8 @@ HEADER_AMZN_XRAY = "X-Amzn-Trace-Id"
64
65
  class S3NotificationContent(TypedDict):
65
66
  s3SchemaVersion: str
66
67
  configurationId: NotificationId
67
- bucket: Dict[str, str] # todo
68
- object: Dict[str, Union[str, int]] # todo
68
+ bucket: dict[str, str] # todo
69
+ object: dict[str, str | int] # todo
69
70
 
70
71
 
71
72
  class EventRecord(TypedDict):
@@ -74,14 +75,14 @@ class EventRecord(TypedDict):
74
75
  awsRegion: str
75
76
  eventTime: str
76
77
  eventName: str
77
- userIdentity: Dict[str, str]
78
- requestParameters: Dict[str, str]
79
- responseElements: Dict[str, str]
78
+ userIdentity: dict[str, str]
79
+ requestParameters: dict[str, str]
80
+ responseElements: dict[str, str]
80
81
  s3: S3NotificationContent
81
82
 
82
83
 
83
84
  class Notification(TypedDict):
84
- Records: List[EventRecord]
85
+ Records: list[EventRecord]
85
86
 
86
87
 
87
88
  @dataclass
@@ -101,15 +102,15 @@ class S3EventNotificationContext:
101
102
  key_etag: str
102
103
  key_version_id: str
103
104
  key_expiry: datetime.datetime
104
- key_storage_class: Optional[StorageClass]
105
+ key_storage_class: StorageClass | None
105
106
 
106
107
  @classmethod
107
- def from_request_context_native(
108
+ def from_request_context(
108
109
  cls,
109
110
  request_context: RequestContext,
110
111
  s3_bucket: S3Bucket,
111
112
  s3_object: S3Object | S3DeleteMarker,
112
- ) -> "S3EventNotificationContext":
113
+ ) -> S3EventNotificationContext:
113
114
  """
114
115
  Create an S3EventNotificationContext from a RequestContext.
115
116
  The key is not always present in the request context depending on the event type. In that case, we can use
@@ -165,7 +166,7 @@ class BucketVerificationContext:
165
166
  request_id: str
166
167
  bucket_name: str
167
168
  region: str
168
- configuration: Dict
169
+ configuration: dict
169
170
  skip_destination_validation: bool
170
171
 
171
172
 
@@ -185,7 +186,7 @@ def _matching_event(events: EventList, event_name: str) -> bool:
185
186
 
186
187
 
187
188
  def _matching_filter(
188
- notification_filter: Optional[NotificationConfigurationFilter], key_name: str
189
+ notification_filter: NotificationConfigurationFilter | None, key_name: str
189
190
  ) -> bool:
190
191
  """
191
192
  See: https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-filtering.html
@@ -213,11 +214,11 @@ def _matching_filter(
213
214
  class BaseNotifier:
214
215
  service_name: str
215
216
 
216
- def notify(self, ctx: S3EventNotificationContext, config: Dict):
217
+ def notify(self, ctx: S3EventNotificationContext, config: dict):
217
218
  raise NotImplementedError
218
219
 
219
220
  @staticmethod
220
- def should_notify(ctx: S3EventNotificationContext, config: Dict) -> bool:
221
+ def should_notify(ctx: S3EventNotificationContext, config: dict) -> bool:
221
222
  """
222
223
  Helper method checking if the event should be notified to the configured notifiers from the configuration
223
224
  :param ctx: S3EventNotificationContext
@@ -229,12 +230,12 @@ class BaseNotifier:
229
230
  )
230
231
 
231
232
  @staticmethod
232
- def _get_arn_value_and_name(notifier_configuration: Dict) -> Tuple[str, str]:
233
+ def _get_arn_value_and_name(notifier_configuration: dict) -> tuple[str, str]:
233
234
  raise NotImplementedError
234
235
 
235
236
  def validate_configuration_for_notifier(
236
237
  self,
237
- configurations: List[Dict],
238
+ configurations: list[dict],
238
239
  skip_destination_validation: bool,
239
240
  context: RequestContext,
240
241
  bucket_name: str,
@@ -272,26 +273,29 @@ class BaseNotifier:
272
273
  arn, argument_name = self._get_arn_value_and_name(configuration)
273
274
 
274
275
  if not re.match(f"{ARN_PARTITION_REGEX}:{self.service_name}:", arn):
275
- raise _create_invalid_argument_exc(
276
- "The ARN could not be parsed", name=argument_name, value=arn
276
+ raise InvalidArgument(
277
+ "The ARN could not be parsed",
278
+ ArgumentName=argument_name,
279
+ ArgumentValue=arn,
277
280
  )
281
+
278
282
  if not verification_ctx.skip_destination_validation:
279
283
  self._verify_target(arn, verification_ctx)
280
284
 
281
285
  if filter_rules := configuration.get("Filter", {}).get("Key", {}).get("FilterRules"):
282
286
  for rule in filter_rules:
283
- rule["Name"] = rule["Name"].capitalize()
284
- if rule["Name"] not in ["Suffix", "Prefix"]:
285
- raise _create_invalid_argument_exc(
287
+ if "Name" not in rule or "Value" not in rule:
288
+ raise MalformedXML()
289
+
290
+ if rule["Name"].lower() not in ["suffix", "prefix"]:
291
+ raise InvalidArgument(
286
292
  "filter rule name must be either prefix or suffix",
287
- rule["Name"],
288
- rule["Value"],
289
- )
290
- if not rule["Value"]:
291
- raise _create_invalid_argument_exc(
292
- "filter value cannot be empty", rule["Name"], rule["Value"]
293
+ ArgumentName="FilterRule.Name",
294
+ ArgumentValue=rule["Name"],
293
295
  )
294
296
 
297
+ rule["Name"] = rule["Name"].capitalize()
298
+
295
299
  @staticmethod
296
300
  def _get_test_payload(verification_ctx: BucketVerificationContext):
297
301
  return {
@@ -381,8 +385,8 @@ class SqsNotifier(BaseNotifier):
381
385
  service_name = "sqs"
382
386
 
383
387
  @staticmethod
384
- def _get_arn_value_and_name(queue_configuration: QueueConfiguration) -> Tuple[QueueArn, str]:
385
- return queue_configuration.get("QueueArn", ""), "QueueArn"
388
+ def _get_arn_value_and_name(queue_configuration: QueueConfiguration) -> tuple[QueueArn, str]:
389
+ return queue_configuration.get("QueueArn", ""), "Queue"
386
390
 
387
391
  def _verify_target(self, target_arn: str, verification_ctx: BucketVerificationContext) -> None:
388
392
  if not is_api_enabled("sqs"):
@@ -402,13 +406,20 @@ class SqsNotifier(BaseNotifier):
402
406
  queue_url = sqs_client.get_queue_url(
403
407
  QueueName=arn_data["resource"], QueueOwnerAWSAccountId=arn_data["account"]
404
408
  )["QueueUrl"]
405
- except ClientError:
406
- LOG.exception("Could not validate the notification destination %s", target_arn)
407
- raise _create_invalid_argument_exc(
409
+ except ClientError as e:
410
+ code = e.response["Error"]["Code"]
411
+ LOG.error(
412
+ "Could not validate the notification destination %s: %s",
413
+ target_arn,
414
+ code,
415
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
416
+ )
417
+ raise InvalidArgument(
408
418
  "Unable to validate the following destination configurations",
409
- name=target_arn,
410
- value="The destination queue does not exist",
419
+ ArgumentName=target_arn,
420
+ ArgumentValue="The destination queue does not exist",
411
421
  )
422
+
412
423
  # send test event with the request metadata for permissions
413
424
  # https://docs.aws.amazon.com/AmazonS3/latest/userguide/notification-how-to-event-types-and-destinations.html#supported-notification-event-types
414
425
  sqs_client = connect_to(region_name=arn_data["region"]).sqs.request_metadata(
@@ -424,10 +435,10 @@ class SqsNotifier(BaseNotifier):
424
435
  verification_ctx.bucket_name,
425
436
  target_arn,
426
437
  )
427
- raise _create_invalid_argument_exc(
438
+ raise InvalidArgument(
428
439
  "Unable to validate the following destination configurations",
429
- name=target_arn,
430
- value="Permissions on the destination queue do not allow S3 to publish notifications from this bucket",
440
+ ArgumentName=target_arn,
441
+ ArgumentValue="Permissions on the destination queue do not allow S3 to publish notifications from this bucket",
431
442
  ) from e
432
443
 
433
444
  def notify(self, ctx: S3EventNotificationContext, config: QueueConfiguration):
@@ -454,10 +465,11 @@ class SqsNotifier(BaseNotifier):
454
465
  MessageSystemAttributes=system_attributes,
455
466
  )
456
467
  except Exception:
457
- LOG.exception(
468
+ LOG.error(
458
469
  'Unable to send notification for S3 bucket "%s" to SQS queue "%s"',
459
470
  ctx.bucket_name,
460
471
  parsed_arn["resource"],
472
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
461
473
  )
462
474
 
463
475
 
@@ -483,10 +495,10 @@ class SnsNotifier(BaseNotifier):
483
495
  try:
484
496
  sns_client.get_topic_attributes(TopicArn=target_arn)
485
497
  except ClientError:
486
- raise _create_invalid_argument_exc(
498
+ raise InvalidArgument(
487
499
  "Unable to validate the following destination configurations",
488
- name=target_arn,
489
- value="The destination topic does not exist",
500
+ ArgumentName=target_arn,
501
+ ArgumentValue="The destination topic does not exist",
490
502
  )
491
503
 
492
504
  sns_client = connect_to(region_name=arn_data["region"]).sns.request_metadata(
@@ -506,10 +518,10 @@ class SnsNotifier(BaseNotifier):
506
518
  verification_ctx.bucket_name,
507
519
  target_arn,
508
520
  )
509
- raise _create_invalid_argument_exc(
521
+ raise InvalidArgument(
510
522
  "Unable to validate the following destination configurations",
511
- name=target_arn,
512
- value="Permissions on the destination topic do not allow S3 to publish notifications from this bucket",
523
+ ArgumentName=target_arn,
524
+ ArgumentValue="Permissions on the destination topic do not allow S3 to publish notifications from this bucket",
513
525
  ) from e
514
526
 
515
527
  def notify(self, ctx: S3EventNotificationContext, config: TopicConfiguration):
@@ -536,10 +548,11 @@ class SnsNotifier(BaseNotifier):
536
548
  Subject="Amazon S3 Notification",
537
549
  )
538
550
  except Exception:
539
- LOG.exception(
551
+ LOG.error(
540
552
  'Unable to send notification for S3 bucket "%s" to SNS topic "%s"',
541
553
  ctx.bucket_name,
542
554
  topic_arn,
555
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
543
556
  )
544
557
 
545
558
 
@@ -549,7 +562,7 @@ class LambdaNotifier(BaseNotifier):
549
562
  @staticmethod
550
563
  def _get_arn_value_and_name(
551
564
  lambda_configuration: LambdaFunctionConfiguration,
552
- ) -> Tuple[LambdaFunctionArn, str]:
565
+ ) -> tuple[LambdaFunctionArn, str]:
553
566
  return lambda_configuration.get("LambdaFunctionArn", ""), "LambdaFunctionArn"
554
567
 
555
568
  def _verify_target(self, target_arn: str, verification_ctx: BucketVerificationContext) -> None:
@@ -567,10 +580,10 @@ class LambdaNotifier(BaseNotifier):
567
580
  try:
568
581
  lambda_client.get_function(FunctionName=target_arn)
569
582
  except ClientError:
570
- raise _create_invalid_argument_exc(
583
+ raise InvalidArgument(
571
584
  "Unable to validate the following destination configurations",
572
- name=target_arn,
573
- value="The destination Lambda does not exist",
585
+ ArgumentName=target_arn,
586
+ ArgumentValue="The destination Lambda does not exist",
574
587
  )
575
588
  lambda_client = connect_to(region_name=arn_data["region"]).lambda_.request_metadata(
576
589
  source_arn=s3_bucket_arn(verification_ctx.bucket_name, region=verification_ctx.region),
@@ -579,10 +592,10 @@ class LambdaNotifier(BaseNotifier):
579
592
  try:
580
593
  lambda_client.invoke(FunctionName=target_arn, InvocationType=InvocationType.DryRun)
581
594
  except ClientError as e:
582
- raise _create_invalid_argument_exc(
595
+ raise InvalidArgument(
583
596
  "Unable to validate the following destination configurations",
584
- name=f"{target_arn}, null",
585
- value=f"Not authorized to invoke function [{target_arn}]",
597
+ ArgumentName=f"{target_arn}, null",
598
+ ArgumentValue=f"Not authorized to invoke function [{target_arn}]",
586
599
  ) from e
587
600
 
588
601
  def notify(self, ctx: S3EventNotificationContext, config: LambdaFunctionConfiguration):
@@ -604,10 +617,11 @@ class LambdaNotifier(BaseNotifier):
604
617
  Payload=payload,
605
618
  )
606
619
  except Exception:
607
- LOG.exception(
620
+ LOG.error(
608
621
  'Unable to send notification for S3 bucket "%s" to Lambda function "%s".',
609
622
  ctx.bucket_name,
610
623
  lambda_arn,
624
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
611
625
  )
612
626
 
613
627
 
@@ -698,14 +712,14 @@ class EventBridgeNotifier(BaseNotifier):
698
712
  return entry
699
713
 
700
714
  @staticmethod
701
- def should_notify(ctx: S3EventNotificationContext, config: Dict) -> bool:
715
+ def should_notify(ctx: S3EventNotificationContext, config: dict) -> bool:
702
716
  # Events are always passed to EventBridge, you can route the event in EventBridge
703
717
  # See https://docs.aws.amazon.com/AmazonS3/latest/userguide/EventBridge.html
704
718
  return True
705
719
 
706
720
  def validate_configuration_for_notifier(
707
721
  self,
708
- configurations: List[Dict],
722
+ configurations: list[dict],
709
723
  skip_destination_validation: bool,
710
724
  context: RequestContext,
711
725
  bucket_name: str,
@@ -729,8 +743,10 @@ class EventBridgeNotifier(BaseNotifier):
729
743
  try:
730
744
  events_client.put_events(Entries=[entry])
731
745
  except Exception:
732
- LOG.exception(
733
- 'Unable to send notification for S3 bucket "%s" to EventBridge', ctx.bucket_name
746
+ LOG.error(
747
+ 'Unable to send notification for S3 bucket "%s" to EventBridge',
748
+ ctx.bucket_name,
749
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
734
750
  )
735
751
 
736
752