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
@@ -323,8 +323,18 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
323
323
  tags: MapOfStringToString = None,
324
324
  **kwargs,
325
325
  ) -> ApiKey:
326
+ if name and len(name) > 1024:
327
+ raise BadRequestException("Invalid API Key name, can be at most 1024 characters.")
328
+ if value:
329
+ if len(value) > 128:
330
+ raise BadRequestException("API Key value exceeds maximum size of 128 characters")
331
+ elif len(value) < 20:
332
+ raise BadRequestException("API Key value should be at least 20 characters")
333
+ if description and len(description) > 125000:
334
+ raise BadRequestException("Invalid API Key description specified.")
326
335
  api_key = call_moto(context)
327
-
336
+ if name == "":
337
+ api_key.pop("name", None)
328
338
  # transform array of stage keys [{'restApiId': '0iscapk09u', 'stageName': 'dev'}] into
329
339
  # array of strings ['0iscapk09u/dev']
330
340
  stage_keys = api_key.get("stageKeys", [])
@@ -665,66 +675,6 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
665
675
  parent_id = moto_resource.parent_id
666
676
  api_resources[parent_id].remove(resource_id)
667
677
 
668
- def update_integration_response(
669
- self,
670
- context: RequestContext,
671
- rest_api_id: String,
672
- resource_id: String,
673
- http_method: String,
674
- status_code: StatusCode,
675
- patch_operations: ListOfPatchOperation = None,
676
- **kwargs,
677
- ) -> IntegrationResponse:
678
- # XXX: THIS IS NOT A COMPLETE IMPLEMENTATION, just the minimum required to get tests going
679
- # TODO: validate patch operations
680
-
681
- moto_rest_api = get_moto_rest_api(context, rest_api_id)
682
- moto_resource = moto_rest_api.resources.get(resource_id)
683
- if not moto_resource:
684
- raise NotFoundException("Invalid Resource identifier specified")
685
-
686
- moto_method = moto_resource.resource_methods.get(http_method)
687
- if not moto_method:
688
- raise NotFoundException("Invalid Method identifier specified")
689
-
690
- integration_response = moto_method.method_integration.integration_responses.get(status_code)
691
- if not integration_response:
692
- raise NotFoundException("Invalid Integration Response identifier specified")
693
-
694
- for patch_operation in patch_operations:
695
- op = patch_operation.get("op")
696
- path = patch_operation.get("path")
697
-
698
- # for path "/responseTemplates/application~1json"
699
- if "/responseTemplates" in path:
700
- integration_response.response_templates = (
701
- integration_response.response_templates or {}
702
- )
703
- value = patch_operation.get("value")
704
- if not isinstance(value, str):
705
- raise BadRequestException(
706
- f"Invalid patch value '{value}' specified for op '{op}'. Must be a string"
707
- )
708
- param = path.removeprefix("/responseTemplates/")
709
- param = param.replace("~1", "/")
710
- if op == "remove":
711
- integration_response.response_templates.pop(param)
712
- elif op in ("add", "replace"):
713
- integration_response.response_templates[param] = value
714
-
715
- elif "/contentHandling" in path and op == "replace":
716
- integration_response.content_handling = patch_operation.get("value")
717
-
718
- elif "/selectionPattern" in path and op == "replace":
719
- integration_response.selection_pattern = patch_operation.get("value")
720
-
721
- response: IntegrationResponse = integration_response.to_json()
722
- # in case it's empty, we still want to pass it on as ""
723
- # TODO: add a test case for this
724
- response["selectionPattern"] = integration_response.selection_pattern
725
-
726
- return response
727
-
728
678
  def update_resource(
729
679
  self,
730
680
  context: RequestContext,
@@ -757,6 +707,9 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
757
707
  f"Invalid patch path '{path}' specified for op '{op}'. Please choose supported operations"
758
708
  )
759
709
 
710
+ if moto_resource.parent_id is None:
711
+ raise BadRequestException(f"Root resource cannot update its {path.strip('/')}.")
712
+
760
713
  if path == "/parentId":
761
714
  value = patch_operation.get("value")
762
715
  future_parent_resource = moto_rest_api.resources.get(value)
@@ -793,7 +746,7 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
793
746
  api_resources.pop(current_parent_id)
794
747
 
795
748
  # add it to the new parent children
796
- future_sibling_resources = api_resources[moto_resource.parent_id]
749
+ future_sibling_resources = api_resources.setdefault(moto_resource.parent_id, [])
797
750
  future_sibling_resources.append(resource_id)
798
751
 
799
752
  response = moto_resource.to_dict()
@@ -2111,6 +2064,20 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2111
2064
  for integration_response in integration_responses.values():
2112
2065
  remove_empty_attributes_from_integration_response(integration_response)
2113
2066
 
2067
+ if response.get("connectionType") == "VPC_LINK":
2068
+ # FIXME: this is hacky to workaround moto not saving the VPC Link `connectionId`
2069
+ # only do this internal check of Moto if the integration is of VPC_LINK type
2070
+ moto_rest_api = get_moto_rest_api(context=context, rest_api_id=rest_api_id)
2071
+ try:
2072
+ method = moto_rest_api.resources[resource_id].resource_methods[http_method]
2073
+ integration = method.method_integration
2074
+ if connection_id := getattr(integration, "connection_id", None):
2075
+ response["connectionId"] = connection_id
2076
+
2077
+ except (AttributeError, KeyError):
2078
+ # this error should have been caught by `call_moto`
2079
+ pass
2080
+
2114
2081
  return response
2115
2082
 
2116
2083
  def put_integration(
@@ -2165,6 +2132,7 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2165
2132
  moto_request.setdefault("timeoutInMillis", 29000)
2166
2133
  if integration_type in (IntegrationType.HTTP, IntegrationType.HTTP_PROXY):
2167
2134
  moto_request.setdefault("connectionType", ConnectionType.INTERNET)
2135
+
2168
2136
  response = call_moto_with_request(context, moto_request)
2169
2137
  remove_empty_attributes_from_integration(integration=response)
2170
2138
 
@@ -2172,6 +2140,13 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2172
2140
  if integration_type == "MOCK":
2173
2141
  response.pop("uri", None)
2174
2142
 
2143
+ # TODO: moto does not save the connection_id
2144
+ elif moto_request.get("connectionType") == "VPC_LINK":
2145
+ connection_id = moto_request.get("connectionId", "")
2146
+ # attach the connection id to the moto object
2147
+ method.method_integration.connection_id = connection_id
2148
+ response["connectionId"] = connection_id
2149
+
2175
2150
  return response
2176
2151
 
2177
2152
  def update_integration(
@@ -2193,6 +2168,7 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2193
2168
  raise NotFoundException("Invalid Integration identifier specified")
2194
2169
 
2195
2170
  integration = method.method_integration
2171
+ # TODO: validate the patch operations
2196
2172
  patch_api_gateway_entity(integration, patch_operations)
2197
2173
 
2198
2174
  # fix data types
@@ -2201,8 +2177,12 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2201
2177
  if skip_verification := (integration.tls_config or {}).get("insecureSkipVerification"):
2202
2178
  integration.tls_config["insecureSkipVerification"] = str_to_bool(skip_verification)
2203
2179
 
2204
- integration_dict: Integration = integration.to_json()
2205
- return integration_dict
2180
+ response: Integration = integration.to_json()
2181
+
2182
+ if connection_id := getattr(integration, "connection_id", None):
2183
+ response["connectionId"] = connection_id
2184
+
2185
+ return response
2206
2186
 
2207
2187
  def delete_integration(
2208
2188
  self,
@@ -2307,6 +2287,93 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2307
2287
 
2308
2288
  return response
2309
2289
 
2290
+ def update_integration_response(
2291
+ self,
2292
+ context: RequestContext,
2293
+ rest_api_id: String,
2294
+ resource_id: String,
2295
+ http_method: String,
2296
+ status_code: StatusCode,
2297
+ patch_operations: ListOfPatchOperation = None,
2298
+ **kwargs,
2299
+ ) -> IntegrationResponse:
2300
+ # XXX: THIS IS NOT A COMPLETE IMPLEMENTATION, just the minimum required to get tests going
2301
+ # TODO: validate patch operations
2302
+
2303
+ moto_rest_api = get_moto_rest_api(context, rest_api_id)
2304
+ moto_resource = moto_rest_api.resources.get(resource_id)
2305
+ if not moto_resource:
2306
+ raise NotFoundException("Invalid Resource identifier specified")
2307
+
2308
+ moto_method = moto_resource.resource_methods.get(http_method)
2309
+ if not moto_method:
2310
+ raise NotFoundException("Invalid Method identifier specified")
2311
+
2312
+ integration_response = moto_method.method_integration.integration_responses.get(status_code)
2313
+ if not integration_response:
2314
+ raise NotFoundException("Invalid Integration Response identifier specified")
2315
+
2316
+ for patch_operation in patch_operations:
2317
+ op = patch_operation.get("op")
2318
+ path = patch_operation.get("path")
2319
+
2320
+ # for path "/responseTemplates/application~1json"
2321
+ if "/responseTemplates" in path:
2322
+ integration_response.response_templates = (
2323
+ integration_response.response_templates or {}
2324
+ )
2325
+ value = patch_operation.get("value")
2326
+ if not isinstance(value, str):
2327
+ raise BadRequestException(
2328
+ f"Invalid patch value '{value}' specified for op '{op}'. Must be a string"
2329
+ )
2330
+ param = path.removeprefix("/responseTemplates/")
2331
+ param = param.replace("~1", "/")
2332
+ if op == "remove":
2333
+ integration_response.response_templates.pop(param)
2334
+ elif op in ("add", "replace"):
2335
+ integration_response.response_templates[param] = value
2336
+
2337
+ elif "/contentHandling" in path and op == "replace":
2338
+ integration_response.content_handling = patch_operation.get("value")
2339
+
2340
+ elif "/selectionPattern" in path and op == "replace":
2341
+ integration_response.selection_pattern = patch_operation.get("value")
2342
+
2343
+ response: IntegrationResponse = integration_response.to_json()
2344
+ # in case it's empty, we still want to pass it on as ""
2345
+ # TODO: add a test case for this
2346
+ response["selectionPattern"] = integration_response.selection_pattern
2347
+
2348
+ return response
2349
+
2350
+ def delete_integration_response(
2351
+ self,
2352
+ context: RequestContext,
2353
+ rest_api_id: String,
2354
+ resource_id: String,
2355
+ http_method: String,
2356
+ status_code: StatusCode,
2357
+ **kwargs,
2358
+ ) -> None:
2359
+ moto_backend = apigw_models.apigateway_backends[context.account_id][context.region]
2360
+ moto_rest_api = moto_backend.apis.get(rest_api_id)
2361
+ if not moto_rest_api:
2362
+ raise NotFoundException("Invalid Resource identifier specified")
2363
+
2364
+ if not (moto_resource := moto_rest_api.resources.get(resource_id)):
2365
+ raise NotFoundException("Invalid Resource identifier specified")
2366
+
2367
+ if not (moto_method := moto_resource.resource_methods.get(http_method)):
2368
+ raise NotFoundException("Invalid Integration identifier specified")
2369
+
2370
+ if not moto_method.method_integration:
2371
+ raise NotFoundException("Invalid Integration identifier specified")
2372
+ if not (
2373
+ integration_responses := moto_method.method_integration.integration_responses
2374
+ ) or not integration_responses.pop(status_code, None):
2375
+ raise NotFoundException("Invalid Response status code specified")
2376
+
2310
2377
  def get_export(
2311
2378
  self,
2312
2379
  context: RequestContext,
@@ -2363,6 +2430,10 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2363
2430
  for api_key in api_keys:
2364
2431
  api_key.pop("value")
2365
2432
 
2433
+ if limit is not None:
2434
+ if limit < 1 or limit > 500:
2435
+ limit = None
2436
+
2366
2437
  item_list = PaginatedList(api_keys)
2367
2438
 
2368
2439
  def token_generator(item):
@@ -2387,6 +2458,14 @@ class ApigatewayProvider(ApigatewayApi, ServiceLifecycleHook):
2387
2458
  patch_operations: ListOfPatchOperation = None,
2388
2459
  **kwargs,
2389
2460
  ) -> ApiKey:
2461
+ for patch_op in patch_operations:
2462
+ if patch_op["path"] not in ("/description", "/enabled", "/name", "/customerId"):
2463
+ raise BadRequestException(
2464
+ f"Invalid patch path '{patch_op['path']}' specified for op '{patch_op['op']}'. Must be one of: [/description, /enabled, /name, /customerId]"
2465
+ )
2466
+
2467
+ if patch_op["path"] == "/description" and len(patch_op["value"]) > 125000:
2468
+ raise BadRequestException("Invalid API Key description specified.")
2390
2469
  response: ApiKey = call_moto(context)
2391
2470
  if "value" in response:
2392
2471
  response.pop("value", None)
@@ -2947,6 +3026,7 @@ def create_custom_context(
2947
3026
  ctx = create_aws_request_context(
2948
3027
  service_name=context.service.service_name,
2949
3028
  action=action,
3029
+ protocol=context.service.protocol,
2950
3030
  parameters=parameters,
2951
3031
  region=context.region,
2952
3032
  )
@@ -2998,7 +3078,7 @@ def to_documentation_part_response_json(api_id, data):
2998
3078
 
2999
3079
 
3000
3080
  def to_base_mapping_response_json(domain_name, base_path, data):
3001
- self_link = "/domainnames/%s/basepathmappings/%s" % (domain_name, base_path)
3081
+ self_link = f"/domainnames/{domain_name}/basepathmappings/{base_path}"
3002
3082
  result = to_response_json("basepathmapping", data, self_link=self_link)
3003
3083
  result = select_from_typed_dict(BasePathMapping, result)
3004
3084
  return result
@@ -3034,9 +3114,9 @@ def to_response_json(model_type, data, api_id=None, self_link=None, id_attr=None
3034
3114
  id_attr = id_attr or "id"
3035
3115
  result = deepcopy(data)
3036
3116
  if not self_link:
3037
- self_link = "/%ss/%s" % (model_type, data[id_attr])
3117
+ self_link = f"/{model_type}s/{data[id_attr]}"
3038
3118
  if api_id:
3039
- self_link = "/restapis/%s/%s" % (api_id, self_link)
3119
+ self_link = f"/restapis/{api_id}/{self_link}"
3040
3120
  # TODO: check if this is still required - "_links" are listed in the sample responses in the docs, but
3041
3121
  # recent parity tests indicate that this field is not returned by real AWS...
3042
3122
  # https://docs.aws.amazon.com/apigateway/latest/api/API_GetAuthorizers.html#API_GetAuthorizers_Example_1_Response
@@ -3048,7 +3128,7 @@ def to_response_json(model_type, data, api_id=None, self_link=None, id_attr=None
3048
3128
  "name": model_type,
3049
3129
  "templated": True,
3050
3130
  }
3051
- result["_links"]["%s:delete" % model_type] = {"href": self_link}
3131
+ result["_links"][f"{model_type}:delete"] = {"href": self_link}
3052
3132
  return result
3053
3133
 
3054
3134
 
@@ -1,5 +1,5 @@
1
1
  import logging
2
- from typing import Any, Dict
2
+ from typing import Any
3
3
 
4
4
  from requests.models import Response as RequestsResponse
5
5
  from werkzeug.datastructures import Headers
@@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
22
22
  # invocation context property decorators and use the url_params directly,
23
23
  # something asked for a long time.
24
24
  def to_invocation_context(
25
- request: Request, url_params: Dict[str, Any] = None
25
+ request: Request, url_params: dict[str, Any] = None
26
26
  ) -> ApiInvocationContext:
27
27
  """
28
28
  Converts an HTTP Request object into an ApiInvocationContext.
@@ -3,7 +3,7 @@ import copy
3
3
  import json
4
4
  import logging
5
5
  from enum import Enum
6
- from typing import Any, Dict, Union
6
+ from typing import Any
7
7
  from urllib.parse import quote_plus, unquote_plus
8
8
 
9
9
  import xmltodict
@@ -68,7 +68,7 @@ class AttributeDict(dict):
68
68
  """
69
69
 
70
70
  def __init__(self, *args, **kwargs):
71
- super(AttributeDict, self).__init__(*args, **kwargs)
71
+ super().__init__(*args, **kwargs)
72
72
  for key, value in self.items():
73
73
  if isinstance(value, dict):
74
74
  self[key] = AttributeDict(value)
@@ -184,7 +184,7 @@ class VelocityInput:
184
184
  class ApiGatewayVtlTemplate(VtlTemplate):
185
185
  """Util class for rendering VTL templates with API Gateway specific extensions"""
186
186
 
187
- def prepare_namespace(self, variables, source: str = APIGW_SOURCE) -> Dict[str, Any]:
187
+ def prepare_namespace(self, variables, source: str = APIGW_SOURCE) -> dict[str, Any]:
188
188
  namespace = super().prepare_namespace(variables, source)
189
189
  if stage_var := variables.get("stage_variables") or {}:
190
190
  namespace["stageVariables"] = stage_var
@@ -203,7 +203,7 @@ class Templates:
203
203
  def __init__(self):
204
204
  self.vtl = ApiGatewayVtlTemplate()
205
205
 
206
- def render(self, api_context: ApiInvocationContext) -> Union[bytes, str]:
206
+ def render(self, api_context: ApiInvocationContext) -> bytes | str:
207
207
  pass
208
208
 
209
209
  def render_vtl(self, template, variables):
@@ -250,7 +250,7 @@ class RequestTemplates(Templates):
250
250
 
251
251
  def render(
252
252
  self, api_context: ApiInvocationContext, template_key: str = APPLICATION_JSON
253
- ) -> Union[bytes, str]:
253
+ ) -> bytes | str:
254
254
  LOG.debug(
255
255
  "Method request body before transformations: %s", to_str(api_context.data_as_string())
256
256
  )
@@ -278,7 +278,7 @@ class ResponseTemplates(Templates):
278
278
  template is used.
279
279
  """
280
280
 
281
- def render(self, api_context: ApiInvocationContext, **kwargs) -> Union[bytes, str]:
281
+ def render(self, api_context: ApiInvocationContext, **kwargs) -> bytes | str:
282
282
  # XXX: keep backwards compatibility until we migrate all integrations to this new classes
283
283
  # api_context contains a response object that we want slowly remove from it
284
284
  data = kwargs.get("response", "")
@@ -1,4 +1,4 @@
1
- from typing import Any, Dict, List
1
+ from typing import Any
2
2
 
3
3
  from requests.structures import CaseInsensitiveDict
4
4
 
@@ -28,21 +28,21 @@ class RestApiContainer:
28
28
  # contains the RestApi dictionary. We're not making use of it yet, still using moto data.
29
29
  rest_api: RestApi
30
30
  # maps AuthorizerId -> Authorizer
31
- authorizers: Dict[str, Authorizer]
31
+ authorizers: dict[str, Authorizer]
32
32
  # maps RequestValidatorId -> RequestValidator
33
- validators: Dict[str, RequestValidator]
33
+ validators: dict[str, RequestValidator]
34
34
  # map DocumentationPartId -> DocumentationPart
35
- documentation_parts: Dict[str, DocumentationPart]
35
+ documentation_parts: dict[str, DocumentationPart]
36
36
  # map doc version name -> DocumentationVersion
37
- documentation_versions: Dict[str, DocumentationVersion]
37
+ documentation_versions: dict[str, DocumentationVersion]
38
38
  # not used yet, still in moto
39
- gateway_responses: Dict[GatewayResponseType, GatewayResponse]
39
+ gateway_responses: dict[GatewayResponseType, GatewayResponse]
40
40
  # maps Model name -> Model
41
- models: Dict[str, Model]
41
+ models: dict[str, Model]
42
42
  # maps Model name -> resolved dict Model, so we don't need to load the JSON everytime
43
- resolved_models: Dict[str, dict]
43
+ resolved_models: dict[str, dict]
44
44
  # maps ResourceId of a Resource to its children ResourceIds
45
- resource_children: Dict[str, List[str]]
45
+ resource_children: dict[str, list[str]]
46
46
 
47
47
  def __init__(self, rest_api: RestApi):
48
48
  self.rest_api = rest_api
@@ -102,25 +102,25 @@ class RestApiDeployment:
102
102
  class ApiGatewayStore(BaseStore):
103
103
  # maps (API id) -> RestApiContainer
104
104
  # TODO: remove CaseInsensitiveDict, and lower the value of the ID when getting it from the tags
105
- rest_apis: Dict[str, RestApiContainer] = LocalAttribute(default=CaseInsensitiveDict)
105
+ rest_apis: dict[str, RestApiContainer] = LocalAttribute(default=CaseInsensitiveDict)
106
106
 
107
107
  # account details
108
- _account: Dict[str, Any] = LocalAttribute(default=dict)
108
+ _account: dict[str, Any] = LocalAttribute(default=dict)
109
109
 
110
110
  # maps (domain_name) -> [path_mappings]
111
- base_path_mappings: Dict[str, List[Dict]] = LocalAttribute(default=dict)
111
+ base_path_mappings: dict[str, list[dict]] = LocalAttribute(default=dict)
112
112
 
113
113
  # maps ID to VPC link details
114
- vpc_links: Dict[str, Dict] = LocalAttribute(default=dict)
114
+ vpc_links: dict[str, dict] = LocalAttribute(default=dict)
115
115
 
116
116
  # maps cert ID to client certificate details
117
- client_certificates: Dict[str, Dict] = LocalAttribute(default=dict)
117
+ client_certificates: dict[str, dict] = LocalAttribute(default=dict)
118
118
 
119
119
  # maps domain name to domain name model
120
- domain_names: Dict[str, DomainName] = LocalAttribute(default=dict)
120
+ domain_names: dict[str, DomainName] = LocalAttribute(default=dict)
121
121
 
122
122
  # maps resource ARN to tags
123
- TAGS: Dict[str, Dict[str, str]] = CrossRegionAttribute(default=dict)
123
+ TAGS: dict[str, dict[str, str]] = CrossRegionAttribute(default=dict)
124
124
 
125
125
  # internal deployments, represents a frozen REST API for a deployment, used in our router
126
126
  # TODO: make sure API ID are unique across all accounts
@@ -1,4 +1,4 @@
1
- from typing import Callable, Type
1
+ from collections.abc import Callable
2
2
 
3
3
  from rolo import Response
4
4
  from rolo.gateway.chain import HandlerChain as RoloHandlerChain
@@ -14,4 +14,4 @@ RestApiGatewayExceptionHandler = Callable[
14
14
  None,
15
15
  ]
16
16
 
17
- RestApiGatewayHandlerChain: Type[RoloHandlerChain[RestApiInvocationContext]] = RoloHandlerChain
17
+ RestApiGatewayHandlerChain: type[RoloHandlerChain[RestApiInvocationContext]] = RoloHandlerChain
@@ -1,5 +1,5 @@
1
1
  from http import HTTPMethod
2
- from typing import Optional, TypedDict
2
+ from typing import TypedDict
3
3
 
4
4
  from rolo import Request
5
5
  from rolo.gateway import RequestContext
@@ -14,12 +14,12 @@ from .variables import ContextVariableOverrides, ContextVariables, LoggingContex
14
14
  class InvocationRequest(TypedDict, total=False):
15
15
  http_method: HTTPMethod
16
16
  """HTTP Method of the incoming request"""
17
- raw_path: Optional[str]
17
+ raw_path: str | None
18
18
  # TODO: verify if raw_path is needed
19
19
  """Raw path of the incoming request with no modification, needed to keep double forward slashes"""
20
- path: Optional[str]
20
+ path: str | None
21
21
  """Path of the request with no URL decoding"""
22
- path_parameters: Optional[dict[str, str]]
22
+ path_parameters: dict[str, str] | None
23
23
  """Path parameters of the request"""
24
24
  query_string_parameters: dict[str, str]
25
25
  """Query string parameters of the request"""
@@ -72,48 +72,48 @@ class RestApiInvocationContext(RequestContext):
72
72
  This context is going to be used to pass relevant information across an API Gateway invocation.
73
73
  """
74
74
 
75
- deployment: Optional[RestApiDeployment]
75
+ deployment: RestApiDeployment | None
76
76
  """Contains the invoked REST API Resources"""
77
- integration: Optional[Integration]
77
+ integration: Integration | None
78
78
  """The Method Integration for the invoked request"""
79
- api_id: Optional[str]
79
+ api_id: str | None
80
80
  """The REST API identifier of the invoked API"""
81
- stage: Optional[str]
81
+ stage: str | None
82
82
  """The REST API stage name linked to this invocation"""
83
- base_path: Optional[str]
83
+ base_path: str | None
84
84
  """The REST API base path mapped to the stage of this invocation"""
85
- deployment_id: Optional[str]
85
+ deployment_id: str | None
86
86
  """The REST API deployment linked to this invocation"""
87
- region: Optional[str]
87
+ region: str | None
88
88
  """The region the REST API is living in."""
89
- account_id: Optional[str]
89
+ account_id: str | None
90
90
  """The account the REST API is living in."""
91
- trace_id: Optional[str]
91
+ trace_id: str | None
92
92
  """The X-Ray trace ID for the request."""
93
- resource: Optional[Resource]
93
+ resource: Resource | None
94
94
  """The resource the invocation matched"""
95
- resource_method: Optional[Method]
95
+ resource_method: Method | None
96
96
  """The method of the resource the invocation matched"""
97
- stage_variables: Optional[dict[str, str]]
97
+ stage_variables: dict[str, str] | None
98
98
  """The Stage variables, also used in parameters mapping and mapping templates"""
99
- stage_configuration: Optional[Stage]
99
+ stage_configuration: Stage | None
100
100
  """The Stage configuration, containing canary deployment settings"""
101
- is_canary: Optional[bool]
101
+ is_canary: bool | None
102
102
  """If the current call was directed to a canary deployment"""
103
- context_variables: Optional[ContextVariables]
103
+ context_variables: ContextVariables | None
104
104
  """The $context used in data models, authorizers, mapping templates, and CloudWatch access logging"""
105
- context_variable_overrides: Optional[ContextVariableOverrides]
105
+ context_variable_overrides: ContextVariableOverrides | None
106
106
  """requestOverrides and responseOverrides are passed from request templates to response templates but are
107
107
  not in the integration context"""
108
- logging_context_variables: Optional[LoggingContextVariables]
108
+ logging_context_variables: LoggingContextVariables | None
109
109
  """Additional $context variables available only for access logging, not yet implemented"""
110
- invocation_request: Optional[InvocationRequest]
110
+ invocation_request: InvocationRequest | None
111
111
  """Contains the data relative to the invocation request"""
112
- integration_request: Optional[IntegrationRequest]
112
+ integration_request: IntegrationRequest | None
113
113
  """Contains the data needed to construct an HTTP request to an Integration"""
114
- endpoint_response: Optional[EndpointResponse]
114
+ endpoint_response: EndpointResponse | None
115
115
  """Contains the data returned by an Integration"""
116
- invocation_response: Optional[InvocationResponse]
116
+ invocation_response: InvocationResponse | None
117
117
  """Contains the data serialized and to be returned by an invocation"""
118
118
 
119
119
  def __init__(self, request: Request):
@@ -1,5 +1,4 @@
1
1
  import logging
2
- from typing import Optional
3
2
 
4
3
  from localstack.aws.api.apigateway import ApiKey, ApiKeySourceType, RestApi
5
4
  from localstack.http import Response
@@ -56,9 +55,7 @@ class ApiKeyValidationHandler(RestApiGatewayHandler):
56
55
  LOG.debug("Updating $context.identity.apiKeyId='%s'", validated_key["id"])
57
56
  identity["apiKeyId"] = validated_key["id"]
58
57
 
59
- def validate_api_key(
60
- self, api_key_value, context: RestApiInvocationContext
61
- ) -> Optional[ApiKey]:
58
+ def validate_api_key(self, api_key_value, context: RestApiInvocationContext) -> ApiKey | None:
62
59
  api_id = context.api_id
63
60
  stage = context.stage
64
61
  account_id = context.account_id
@@ -95,7 +92,7 @@ class ApiKeyValidationHandler(RestApiGatewayHandler):
95
92
 
96
93
  def get_request_api_key(
97
94
  self, rest_api: RestApi, request: InvocationRequest, identity: ContextVarsIdentity
98
- ) -> Optional[str]:
95
+ ) -> str | None:
99
96
  """https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-api-key-source.html
100
97
  The source of the API key for metering requests according to a usage plan.
101
98
  Valid values are:
@@ -50,7 +50,11 @@ class MethodRequestHandler(RestApiGatewayHandler):
50
50
  # check if there is a validator for this request
51
51
  if not (validator := rest_api.validators.get(request_validator_id)):
52
52
  # TODO Should we raise an exception instead?
53
- LOG.exception("No validator were found with matching id: '%s'", request_validator_id)
53
+ LOG.error(
54
+ "No validator were found with matching id: '%s'",
55
+ request_validator_id,
56
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
57
+ )
54
58
  return
55
59
 
56
60
  if self.should_validate_request(validator) and (
@@ -87,9 +91,10 @@ class MethodRequestHandler(RestApiGatewayHandler):
87
91
  # try to get the resolved model first
88
92
  resolved_schema = model_resolver.get_resolved_model()
89
93
  if not resolved_schema:
90
- LOG.exception(
94
+ LOG.error(
91
95
  "An exception occurred while trying to validate the request: could not resolve the model '%s'",
92
96
  model_name,
97
+ exc_info=LOG.isEnabledFor(logging.DEBUG),
93
98
  )
94
99
  return False
95
100
 
@@ -2,7 +2,6 @@ import datetime
2
2
  import logging
3
3
  import re
4
4
  from collections import defaultdict
5
- from typing import Optional
6
5
  from urllib.parse import urlparse
7
6
 
8
7
  from rolo.request import restore_payload
@@ -178,7 +177,7 @@ class InvocationRequestParser(RestApiGatewayHandler):
178
177
  return context_variables
179
178
 
180
179
  @staticmethod
181
- def get_stage_variables(context: RestApiInvocationContext) -> Optional[dict[str, str]]:
180
+ def get_stage_variables(context: RestApiInvocationContext) -> dict[str, str] | None:
182
181
  stage_variables = context.stage_configuration.get("variables")
183
182
  if context.is_canary:
184
183
  overrides = (
@@ -1,7 +1,7 @@
1
1
  import logging
2
+ from collections.abc import Iterable
2
3
  from functools import cache
3
4
  from http import HTTPMethod
4
- from typing import Iterable
5
5
 
6
6
  from werkzeug.exceptions import MethodNotAllowed, NotFound
7
7
  from werkzeug.routing import Map, MapAdapter, Rule
@@ -85,12 +85,11 @@ class RestAPIResourceRouter:
85
85
  rule, args = matcher.match(path, method=request.method, return_rule=True)
86
86
  except (MethodNotAllowed, NotFound) as e:
87
87
  # MethodNotAllowed (405) exception is raised if a path is matching, but the method does not.
88
- # Our router might handle this as a 404, validate with AWS.
88
+ # AWS handles this and the regular 404 as a '403 MissingAuthTokenError'
89
89
  LOG.warning(
90
90
  "API Gateway: No resource or method was found for: %s %s",
91
91
  request.method,
92
92
  path,
93
- exc_info=LOG.isEnabledFor(logging.DEBUG),
94
93
  )
95
94
  raise MissingAuthTokenError("Missing Authentication Token") from e
96
95