localstack-core 4.13.2.dev69__py3-none-any.whl → 4.13.2.dev71__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.
@@ -1138,11 +1138,14 @@ class TlsConfig(TypedDict, total=False):
1138
1138
  insecureSkipVerification: Boolean | None
1139
1139
 
1140
1140
 
1141
+ MapOfStringToNullableString = dict[String, String | None]
1142
+
1143
+
1141
1144
  class IntegrationResponse(TypedDict, total=False):
1142
1145
  statusCode: StatusCode | None
1143
1146
  selectionPattern: String | None
1144
1147
  responseParameters: MapOfStringToString | None
1145
- responseTemplates: MapOfStringToString | None
1148
+ responseTemplates: MapOfStringToNullableString | None
1146
1149
  contentHandling: ContentHandlingStrategy | None
1147
1150
 
1148
1151
 
@@ -1533,6 +1533,17 @@ class RestJSONResponseSerializer(BaseRestResponseSerializer, JSONResponseSeriali
1533
1533
  if has_body and not has_content_type:
1534
1534
  serialized.headers["Content-Type"] = mime_type
1535
1535
 
1536
+ def _serialize_type_map(
1537
+ self, body: dict, value: dict, shape: MapShape, key: str, mime_type: str
1538
+ ):
1539
+ # REST JSON is different from regular JSON, it returns None values in Map
1540
+ if value is None:
1541
+ return
1542
+ map_obj = {}
1543
+ body[key] = map_obj
1544
+ for sub_key, sub_value in value.items():
1545
+ self._serialize(map_obj, sub_value, shape.value, sub_key, mime_type)
1546
+
1536
1547
 
1537
1548
  class BaseCBORResponseSerializer(ResponseSerializer):
1538
1549
  """
@@ -64,6 +64,14 @@ def html_to_rst(html: str):
64
64
  return rst
65
65
 
66
66
 
67
+ def is_sparse_shape(shape: ListShape | MapShape):
68
+ # see https://smithy.io/2.0/spec/type-refinement-traits.html#sparse-trait
69
+ # this is needed for generating Map that can have nullable values
70
+ # We need to access `_shape_model` directly, because `sparse` is not used by Botocore, so it is not picked in
71
+ # `metadata`: see ``botocore.model.Shape.METADATA_ATTRS`` and ``botocore.model.Shape.metadata``
72
+ return getattr(shape, "_shape_model", {}).get("sparse")
73
+
74
+
67
75
  class ShapeNode:
68
76
  service: ServiceModel
69
77
  shape: Shape
@@ -258,8 +266,12 @@ class ShapeNode:
258
266
  f"{to_valid_python_name(shape.name)} = list[{q}{to_valid_python_name(shape.member.name)}{q}]"
259
267
  )
260
268
  elif isinstance(shape, MapShape):
269
+ if is_sparse_shape(shape):
270
+ value_key = f"{q}{to_valid_python_name(shape.value.name)} | None{q}"
271
+ else:
272
+ value_key = f"{q}{to_valid_python_name(shape.value.name)}{q}"
261
273
  output.write(
262
- f"{to_valid_python_name(shape.name)} = dict[{q}{to_valid_python_name(shape.key.name)}{q}, {q}{to_valid_python_name(shape.value.name)}{q}]"
274
+ f"{to_valid_python_name(shape.name)} = dict[{q}{to_valid_python_name(shape.key.name)}{q}, {value_key}]"
263
275
  )
264
276
  elif isinstance(shape, StringShape):
265
277
  if shape.enum:
@@ -1372,5 +1372,22 @@
1372
1372
  "path": "/operations/CreateApiMapping/http/responseCode",
1373
1373
  "value": 200
1374
1374
  }
1375
+ ],
1376
+ "apigateway/2015-07-09/service-2": [
1377
+ {
1378
+ "op": "add",
1379
+ "path": "/shapes/MapOfStringToNullableString",
1380
+ "value": {
1381
+ "type":"map",
1382
+ "key":{"shape":"String"},
1383
+ "value":{"shape":"String"},
1384
+ "sparse": true
1385
+ }
1386
+ },
1387
+ {
1388
+ "op": "replace",
1389
+ "path": "/shapes/IntegrationResponse/members/responseTemplates/shape",
1390
+ "value": "MapOfStringToNullableString"
1391
+ }
1375
1392
  ]
1376
1393
  }
@@ -2821,3 +2821,40 @@ def aws_catalog_mock(monkeypatch):
2821
2821
  return catalog
2822
2822
 
2823
2823
  return _mock_catalog
2824
+
2825
+
2826
+ @pytest.fixture
2827
+ def logs_log_group(aws_client):
2828
+ """Create a log group for testing and clean up afterwards."""
2829
+
2830
+ log_group_names = []
2831
+
2832
+ def _create_log_group():
2833
+ log_group_name = f"test-log-group-{short_uid()}"
2834
+ aws_client.logs.create_log_group(logGroupName=log_group_name)
2835
+ log_group_names.append(log_group_name)
2836
+ return log_group_name
2837
+
2838
+ yield _create_log_group()
2839
+
2840
+ for group_name in log_group_names:
2841
+ aws_client.logs.delete_log_group(logGroupName=group_name)
2842
+
2843
+
2844
+ @pytest.fixture
2845
+ def logs_log_stream(logs_log_group, aws_client):
2846
+ """Create a log stream for testing and clean up afterwards."""
2847
+ log_stream_names = []
2848
+
2849
+ def _create_log_stream():
2850
+ log_stream_name = f"test-log-stream-{short_uid()}"
2851
+ aws_client.logs.create_log_stream(
2852
+ logGroupName=logs_log_group, logStreamName=log_stream_name
2853
+ )
2854
+ log_stream_names.append(log_stream_name)
2855
+ return log_stream_name
2856
+
2857
+ yield _create_log_stream()
2858
+
2859
+ for stream_name in log_stream_names:
2860
+ aws_client.logs.delete_log_stream(logStreamName=stream_name, logGroupName=logs_log_group)
localstack/version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '4.13.2.dev69'
32
- __version_tuple__ = version_tuple = (4, 13, 2, 'dev69')
31
+ __version__ = version = '4.13.2.dev71'
32
+ __version_tuple__ = version_tuple = (4, 13, 2, 'dev71')
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: localstack-core
3
- Version: 4.13.2.dev69
3
+ Version: 4.13.2.dev71
4
4
  Summary: The core library and runtime of LocalStack
5
5
  Author-email: LocalStack Contributors <info@localstack.cloud>
6
6
  License-Expression: Apache-2.0
@@ -4,7 +4,7 @@ localstack/deprecations.py,sha256=-3IYgCd6LEC3PjO7hbr3Dg-p0PIS6phjmv1qZnj1uo0,15
4
4
  localstack/openapi.yaml,sha256=jFUzv-NKkJttxb8HRrmKiNYOmJD-zVfPxG3DDMrRwfg,30865
5
5
  localstack/plugins.py,sha256=BIJC9dlo0WbP7lLKkCiGtd_2q5oeqiHZohvoRTcejXM,2457
6
6
  localstack/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
- localstack/version.py,sha256=EkURekcDSUdm0MV3wrHgwGzpocKIvsPMvPJMl_fzyuE,721
7
+ localstack/version.py,sha256=aGAfA7KWqsAuyy2y7e5Z1YRtCIbWNKY6nYfUxHNJLjg,721
8
8
  localstack/aws/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
9
  localstack/aws/accounts.py,sha256=102zpGowOxo0S6UGMpfjw14QW7WCLVAGsnFK5xFMLoo,3043
10
10
  localstack/aws/app.py,sha256=n9bJCfJRuMz_gLGAH430c3bIQXgUXeWO5NPfcdL2MV8,5145
@@ -17,14 +17,14 @@ localstack/aws/forwarder.py,sha256=GGo3l0GCsaASLOC7THKoUsVaH678WVH-PJoMzEotk0Y,1
17
17
  localstack/aws/gateway.py,sha256=d_Tm0N2-mAnuvE4puXfRjgzMHwR3EuuOQH5IIWX-vAQ,903
18
18
  localstack/aws/mocking.py,sha256=JZZ7ZyAmlCGzywTF8jH4IelPGIiLqyz_ltDtO046a3E,13683
19
19
  localstack/aws/patches.py,sha256=r5EDhDE_OL25fQzT6oEhV7LvpBzTisOqxdn-JD_ZfrI,1883
20
- localstack/aws/scaffold.py,sha256=GxUHvnmc5zidpj1d6IIHqF7q9w1UCrAh1SNco7rlpS4,19943
20
+ localstack/aws/scaffold.py,sha256=bHxaAyWF2-E5Fh6gRte0_1oX8jnCepChKUicfkb7lQg,20602
21
21
  localstack/aws/skeleton.py,sha256=7R0M8X5hnoPxdZ1sy0oaBOu_gWAFS4ZrIYUx5617VZs,8832
22
- localstack/aws/spec-patches.json,sha256=TsGJ6uLE5L0WylJ0i4URhvNauGHkgB45jJ3-MVWeN90,43032
22
+ localstack/aws/spec-patches.json,sha256=w13utQLNiMtkpu1fKRASguVKsrRXK2AW0rkguw7lgqE,43458
23
23
  localstack/aws/spec.py,sha256=WT_sqIIKjWjrD-lBfJFgbvmrfhAbcqak5cfOQdnBJZo,14976
24
24
  localstack/aws/api/__init__.py,sha256=JspwCauxfTTdLNVAr7AkQaPu1lELdBQ1miB9B9sndOo,297
25
25
  localstack/aws/api/core.py,sha256=7qi_hFySJTnOSh1Kv-FCAp2JNpK5jP8sucoG-VTyH4k,6913
26
26
  localstack/aws/api/acm/__init__.py,sha256=g0f7UL6AIRsb64cUOxm_n0UR2VMZRaknJvVWPUNbq18,18773
27
- localstack/aws/api/apigateway/__init__.py,sha256=NWFc6T3nHO8LGI06PC47sNMuOXxsg5huAT7E8IryzbY,80078
27
+ localstack/aws/api/apigateway/__init__.py,sha256=GhWxpSBRGKlfT0Wsw4sC5AwM0zmwPcEKWF7uumCpYcg,80146
28
28
  localstack/aws/api/cloudcontrol/__init__.py,sha256=qFIcOWAtk4Xe4REXn8JSqpV1zIXzaTcTXQwlJGmghyA,11424
29
29
  localstack/aws/api/cloudformation/__init__.py,sha256=Tbi6JoTo_pA03rVuR2R_DvdWFD7fS-qgt-eW007uRsM,121616
30
30
  localstack/aws/api/cloudwatch/__init__.py,sha256=MWUSm7rqKf3p_MMVmXcZFaqRgmNAFTIGhqP-WNZjWbE,46267
@@ -87,7 +87,7 @@ localstack/aws/protocol/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG
87
87
  localstack/aws/protocol/op_router.py,sha256=2nSpL6H9seK1h_AuIZlBG1yYa_ykARIgJJrKm4Hkc0s,12039
88
88
  localstack/aws/protocol/parser.py,sha256=69633HWAlRH01orBZxsbaOKAmd94A64UbkL5udGlD2o,71608
89
89
  localstack/aws/protocol/routing.py,sha256=bi02VUUEQaneVribxAvSkQ4VJloSFWxmSBlwTbHH3j8,3188
90
- localstack/aws/protocol/serializer.py,sha256=sOW5TEeAWD82yy5tjd9pSdbx1qW92-o1Yd9sVqq-ivk,108086
90
+ localstack/aws/protocol/serializer.py,sha256=aJKsjr-kXdmhkiLTBh0tEhULXW4VOpPx_etX803vtGo,108510
91
91
  localstack/aws/protocol/service_router.py,sha256=M5iQ8XKUaPV65DyKewlVYHYNmu4k17Zn_p6_Jdj2Bw8,20705
92
92
  localstack/aws/protocol/validate.py,sha256=j3HJAQEKS6V_arrmvlPmP2jbge3LutxwEXDNabDlDdY,5285
93
93
  localstack/aws/serving/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -1194,7 +1194,7 @@ localstack/testing/pytest/detect_thread_leakage.py,sha256=iV2qFm4sQ7AkoqRfSZgoAU
1194
1194
  localstack/testing/pytest/filters.py,sha256=4PUUj6B-L8leWE00qzS0LP76LHZ3eiycM9jTozMIrkk,1149
1195
1195
  localstack/testing/pytest/find_orphaned_snapshots.py,sha256=-abDUtXa2-9PkZBDjU9XxQkT7i0dATXnFR2GzsX0TFc,1336
1196
1196
  localstack/testing/pytest/fixture_conflicts.py,sha256=cCWOEwO5clVRFseFS0_9wH5v47n_x4OQeIfVXHJvSOU,1497
1197
- localstack/testing/pytest/fixtures.py,sha256=BZ4z-Jy6T5tpIn2YDCa0GVESu5DdyumaAuvFyCw-5O0,96639
1197
+ localstack/testing/pytest/fixtures.py,sha256=A-XCiw1JQ_E3Yla01-Zqsg0mHJRP0HsJAwRQNpkO62o,97778
1198
1198
  localstack/testing/pytest/in_memory_localstack.py,sha256=8dnsVzKu-ARz9CnL4Q7d0bTxAFXfXHFrSihWOvXSd_U,3242
1199
1199
  localstack/testing/pytest/marker_report.py,sha256=_GOdUQQ5e-FUdw-26rHJ3B13qHrM9m4qGuzKvW2CdsE,5549
1200
1200
  localstack/testing/pytest/marking.py,sha256=bPtqIDuNcfXUuc9U66G4CEJykGdGbTb1BVBEZBc49XI,9007
@@ -1311,10 +1311,10 @@ localstack/utils/server/tcp_proxy.py,sha256=y2NJAmvftTiAYsLU_8qe4W5LGqwUw21i90Pu
1311
1311
  localstack/utils/xray/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
1312
1312
  localstack/utils/xray/trace_header.py,sha256=ahXk9eonq7LpeENwlqUEPj3jDOCiVRixhntQuxNor-Q,6209
1313
1313
  localstack/utils/xray/traceid.py,sha256=GKO-R2sMMjlrH2UaLPXlQlZ6flbE7ZKb6IZMtMu_M5U,1110
1314
- localstack_core-4.13.2.dev69.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1315
- localstack_core-4.13.2.dev69.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1316
- localstack_core-4.13.2.dev69.dist-info/METADATA,sha256=E4FANnz9E_Qmzh7GRzalH8bwupg-GNDbtBvjCdDsqiY,5867
1317
- localstack_core-4.13.2.dev69.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
1318
- localstack_core-4.13.2.dev69.dist-info/entry_points.txt,sha256=59aAnn8KVHWAHkMg2dOgmgYtRZ-xTX9T4UiIchWgK6k,20975
1319
- localstack_core-4.13.2.dev69.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1320
- localstack_core-4.13.2.dev69.dist-info/RECORD,,
1314
+ localstack_core-4.13.2.dev71.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1315
+ localstack_core-4.13.2.dev71.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1316
+ localstack_core-4.13.2.dev71.dist-info/METADATA,sha256=rhMFBe7t9jXKXZAqVWszr9NLZFBgZmubPTCkE3KPXis,5867
1317
+ localstack_core-4.13.2.dev71.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
1318
+ localstack_core-4.13.2.dev71.dist-info/entry_points.txt,sha256=59aAnn8KVHWAHkMg2dOgmgYtRZ-xTX9T4UiIchWgK6k,20975
1319
+ localstack_core-4.13.2.dev71.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1320
+ localstack_core-4.13.2.dev71.dist-info/RECORD,,