localstack-core 4.13.2.dev104__py3-none-any.whl → 4.13.2.dev106__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.
@@ -7,6 +7,7 @@ from typing import TYPE_CHECKING
7
7
 
8
8
  from localstack.aws.api.cloudwatch import MetricAlarm, MetricDataQuery, MetricStat, StateValue
9
9
  from localstack.aws.connect import connect_to
10
+ from localstack.runtime.shutdown import SHUTDOWN_HANDLERS
10
11
  from localstack.utils.aws import arns, aws_stack
11
12
  from localstack.utils.scheduler import Scheduler
12
13
 
@@ -38,16 +39,26 @@ class AlarmScheduler:
38
39
  """
39
40
  super().__init__()
40
41
  self.scheduler = Scheduler()
41
- self.thread = threading.Thread(target=self.scheduler.run, name="cloudwatch-scheduler")
42
- self.thread.start()
43
42
  self.scheduled_alarms = {}
43
+ self.thread: threading.Thread | None = None
44
44
 
45
- def shutdown_scheduler(self) -> None:
45
+ def start(self) -> None:
46
+ if not (self.thread and self.thread.is_alive()):
47
+ LOG.debug("Starting CloudWatch scheduler")
48
+ self.thread = threading.Thread(target=self.scheduler.run, name="cloudwatch-scheduler")
49
+ self.thread.start()
50
+ SHUTDOWN_HANDLERS.register(self.shutdown)
51
+
52
+ def shutdown(self) -> None:
46
53
  """
47
- Shutsdown the scheduler, must be called before application stops
54
+ Shutdown the scheduler, must be called before application stops
48
55
  """
56
+ LOG.debug("Stopping CloudWatch scheduler")
49
57
  self.scheduler.close()
50
- self.thread.join(10)
58
+ self.scheduled_alarms.clear()
59
+ SHUTDOWN_HANDLERS.unregister(self.shutdown)
60
+ if self.thread:
61
+ self.thread.join(10)
51
62
 
52
63
  def schedule_metric_alarm(self, alarm_arn: str) -> None:
53
64
  """(Re-)schedules the alarm, if the alarm is re-scheduled, the running alarm scheduler will be cancelled before
@@ -305,7 +305,7 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
305
305
 
306
306
  def __init__(self):
307
307
  self.tags = TaggingService()
308
- self.alarm_scheduler = None
308
+ self.alarm_scheduler = AlarmScheduler()
309
309
 
310
310
  def accept_state_visitor(self, visitor: StateVisitor):
311
311
  visitor.visit(cloudwatch_backends)
@@ -314,19 +314,19 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
314
314
  ROUTER.add(PATH_GET_RAW_METRICS, self.get_raw_metrics)
315
315
 
316
316
  def on_before_start(self):
317
- self.start_alarm_scheduler()
317
+ self.alarm_scheduler.start()
318
318
 
319
319
  def on_before_state_reset(self):
320
- self.shutdown_alarm_scheduler()
320
+ self.alarm_scheduler.shutdown()
321
321
 
322
322
  def on_after_state_reset(self):
323
- self.start_alarm_scheduler()
323
+ self.alarm_scheduler.start()
324
324
 
325
325
  def on_before_state_load(self):
326
- self.shutdown_alarm_scheduler()
326
+ self.alarm_scheduler.shutdown()
327
327
 
328
328
  def on_after_state_load(self):
329
- self.start_alarm_scheduler()
329
+ self.alarm_scheduler.start()
330
330
 
331
331
  def restart_alarms(*args):
332
332
  poll_condition(lambda: SERVICE_PLUGINS.is_running("cloudwatch"))
@@ -335,18 +335,7 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
335
335
  start_worker_thread(restart_alarms)
336
336
 
337
337
  def on_before_stop(self):
338
- self.shutdown_alarm_scheduler()
339
-
340
- def start_alarm_scheduler(self):
341
- if not self.alarm_scheduler:
342
- LOG.debug("starting cloudwatch scheduler")
343
- self.alarm_scheduler = AlarmScheduler()
344
-
345
- def shutdown_alarm_scheduler(self):
346
- if self.alarm_scheduler:
347
- LOG.debug("stopping cloudwatch scheduler")
348
- self.alarm_scheduler.shutdown_scheduler()
349
- self.alarm_scheduler = None
338
+ self.alarm_scheduler.shutdown()
350
339
 
351
340
  def delete_alarms(self, context: RequestContext, alarm_names: AlarmNames, **kwargs) -> None:
352
341
  moto.call_moto(context)
@@ -148,9 +148,9 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
148
148
  """
149
149
 
150
150
  def __init__(self):
151
- self.alarm_scheduler: AlarmScheduler = None
152
151
  self.store = None
153
152
  self.cloudwatch_database = CloudwatchDatabase()
153
+ self.alarm_scheduler = AlarmScheduler()
154
154
 
155
155
  @staticmethod
156
156
  def get_store(account_id: str, region: str) -> CloudWatchStore:
@@ -164,21 +164,21 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
164
164
  ROUTER.add(PATH_GET_RAW_METRICS, self.get_raw_metrics)
165
165
 
166
166
  def on_before_start(self):
167
- self.start_alarm_scheduler()
167
+ self.alarm_scheduler.start()
168
168
 
169
169
  def on_before_state_reset(self):
170
- self.shutdown_alarm_scheduler()
170
+ self.alarm_scheduler.shutdown()
171
171
  self.cloudwatch_database.clear_tables()
172
172
 
173
173
  def on_after_state_reset(self):
174
174
  self.cloudwatch_database = CloudwatchDatabase()
175
- self.start_alarm_scheduler()
175
+ self.alarm_scheduler.start()
176
176
 
177
177
  def on_before_state_load(self):
178
- self.shutdown_alarm_scheduler()
178
+ self.alarm_scheduler.shutdown()
179
179
 
180
180
  def on_after_state_load(self):
181
- self.start_alarm_scheduler()
181
+ self.alarm_scheduler.start()
182
182
 
183
183
  def restart_alarms(*args):
184
184
  poll_condition(lambda: SERVICE_PLUGINS.is_running("cloudwatch"))
@@ -187,18 +187,7 @@ class CloudwatchProvider(CloudwatchApi, ServiceLifecycleHook):
187
187
  start_worker_thread(restart_alarms)
188
188
 
189
189
  def on_before_stop(self):
190
- self.shutdown_alarm_scheduler()
191
-
192
- def start_alarm_scheduler(self):
193
- if not self.alarm_scheduler:
194
- LOG.debug("starting cloudwatch scheduler")
195
- self.alarm_scheduler = AlarmScheduler()
196
-
197
- def shutdown_alarm_scheduler(self):
198
- if self.alarm_scheduler:
199
- LOG.debug("stopping cloudwatch scheduler")
200
- self.alarm_scheduler.shutdown_scheduler()
201
- self.alarm_scheduler = None
190
+ self.alarm_scheduler.shutdown()
202
191
 
203
192
  def delete_alarms(self, context: RequestContext, alarm_names: AlarmNames, **kwargs) -> None:
204
193
  """
@@ -213,7 +213,6 @@ from localstack.aws.api.s3 import (
213
213
  StorageClass,
214
214
  Tag,
215
215
  Tagging,
216
- TagSet,
217
216
  Token,
218
217
  TransitionDefaultMinimumObjectSize,
219
218
  UploadIdMarker,
@@ -463,44 +462,20 @@ class S3Provider(S3Api, ServiceLifecycleHook):
463
462
  f"The value of the expected bucket owner parameter must be an AWS Account ID... [{expected_bucket_owner}]",
464
463
  )
465
464
 
466
- store = self.get_store(context.account_id, context.region)
467
- if not (s3_bucket := store.buckets.get(bucket_name)):
468
- if not (account_id := store.global_bucket_map.get(bucket_name)):
465
+ request_store = self.get_store(context.account_id, context.region)
466
+ if not (s3_bucket := request_store.buckets.get(bucket_name)):
467
+ if not (bucket_account_id := request_store.global_bucket_map.get(bucket_name)):
469
468
  raise NoSuchBucket("The specified bucket does not exist", BucketName=bucket_name)
470
469
 
471
- store = self.get_store(account_id, context.region)
472
- if not (s3_bucket := store.buckets.get(bucket_name)):
470
+ bucket_account_store = self.get_store(bucket_account_id, context.region)
471
+ if not (s3_bucket := bucket_account_store.buckets.get(bucket_name)):
473
472
  raise NoSuchBucket("The specified bucket does not exist", BucketName=bucket_name)
474
473
 
475
474
  if expected_bucket_owner and s3_bucket.bucket_account_id != expected_bucket_owner:
476
475
  raise AccessDenied("Access Denied")
477
476
 
478
- return store, s3_bucket
479
-
480
- def _create_bucket_tags(self, bucket: S3Bucket, tags: TagSet):
481
- store = self.get_store(bucket.bucket_account_id, bucket.bucket_region)
482
- store.tags.update_tags(bucket.bucket_arn, {tag["Key"]: tag["Value"] for tag in tags})
483
-
484
- def _remove_all_bucket_tags(self, bucket: S3Bucket):
485
- store = self.get_store(bucket.bucket_account_id, bucket.bucket_region)
486
- store.tags.delete_all_tags(bucket.bucket_arn)
487
-
488
- def _list_bucket_tags(self, bucket: S3Bucket) -> TagSet:
489
- store = self.get_store(bucket.bucket_account_id, bucket.bucket_region)
490
- tags = store.tags.get_tags(bucket.bucket_arn)
491
- return [{"Key": key, "Value": value} for key, value in tags.items()]
492
-
493
- @staticmethod
494
- def _create_object_tags(store: S3Store, key_id: str, tags: dict[str, str]):
495
- store.tags.update_tags(key_id, tags)
496
-
497
- @staticmethod
498
- def _remove_all_object_tags(store: S3Store, key_id: str):
499
- store.tags.delete_all_tags(key_id)
500
-
501
- @staticmethod
502
- def _list_object_tags(store: S3Store, key_id: str) -> dict[str, str]:
503
- return store.tags.get_tags(key_id)
477
+ regional_bucket_store = self.get_store(s3_bucket.bucket_account_id, s3_bucket.bucket_region)
478
+ return regional_bucket_store, s3_bucket
504
479
 
505
480
  @staticmethod
506
481
  def get_store(account_id: str, region_name: str) -> S3Store:
@@ -590,7 +565,9 @@ class S3Provider(S3Api, ServiceLifecycleHook):
590
565
  store.buckets[bucket_name] = s3_bucket
591
566
  store.global_bucket_map[bucket_name] = s3_bucket.bucket_account_id
592
567
  if bucket_tags:
593
- self._create_bucket_tags(s3_bucket, bucket_tags)
568
+ store.tags.update_tags(
569
+ s3_bucket.bucket_arn, {tag["Key"]: tag["Value"] for tag in bucket_tags}
570
+ )
594
571
  self._cors_handler.invalidate_cache()
595
572
  self._storage_backend.create_bucket(bucket_name)
596
573
 
@@ -629,7 +606,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
629
606
  self._preconditions_locks.pop(bucket, None)
630
607
  # clean up the storage backend
631
608
  self._storage_backend.delete_bucket(bucket)
632
- self._remove_all_bucket_tags(s3_bucket)
609
+ store.tags.delete_all_tags(s3_bucket.bucket_arn)
633
610
 
634
611
  def list_buckets(
635
612
  self,
@@ -931,7 +908,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
931
908
  key_id = get_unique_key_id(bucket_name, key, version_id)
932
909
  store.tags.delete_all_tags(key_id)
933
910
  if tagging:
934
- self._create_object_tags(store, key_id, tagging)
911
+ store.tags.update_tags(key_id, tagging)
935
912
 
936
913
  # RequestCharged: Optional[RequestCharged] # TODO
937
914
  response = PutObjectOutput(
@@ -949,7 +926,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
949
926
  s3_bucket.lifecycle_rules,
950
927
  bucket_name,
951
928
  s3_object,
952
- self._list_object_tags(store, key_id),
929
+ store.tags.get_tags(key_id),
953
930
  ):
954
931
  # TODO: we either apply the lifecycle to existing objects when we set the new rules, or we need to
955
932
  # apply them everytime we get/head an object
@@ -1094,9 +1071,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1094
1071
 
1095
1072
  add_encryption_to_response(response, s3_object=s3_object)
1096
1073
 
1097
- object_tags = self._list_object_tags(
1098
- store, get_unique_key_id(bucket_name, object_key, version_id)
1099
- )
1074
+ object_tags = store.tags.get_tags(get_unique_key_id(bucket_name, object_key, version_id))
1100
1075
 
1101
1076
  if tag_count := len(object_tags):
1102
1077
  response["TagCount"] = tag_count
@@ -1237,8 +1212,8 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1237
1212
  response["ChecksumType"] = checksum_type
1238
1213
 
1239
1214
  add_encryption_to_response(response, s3_object=s3_object)
1240
- object_tags = self._list_object_tags(
1241
- store, get_unique_key_id(bucket_name, object_key, s3_object.version_id)
1215
+ object_tags = store.tags.get_tags(
1216
+ get_unique_key_id(bucket_name, object_key, s3_object.version_id)
1242
1217
  )
1243
1218
  if tag_count := len(object_tags):
1244
1219
  response["TagCount"] = tag_count
@@ -1327,7 +1302,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1327
1302
  if found_object:
1328
1303
  self._storage_backend.remove(bucket, found_object)
1329
1304
  self._notify(context, s3_bucket=s3_bucket, s3_object=found_object)
1330
- self._remove_all_object_tags(store, get_unique_key_id(bucket, key, version_id))
1305
+ store.tags.delete_all_tags(get_unique_key_id(bucket, key, version_id))
1331
1306
 
1332
1307
  return DeleteObjectOutput()
1333
1308
 
@@ -1365,7 +1340,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1365
1340
  response["DeleteMarker"] = True
1366
1341
  else:
1367
1342
  self._storage_backend.remove(bucket, s3_object)
1368
- self._remove_all_object_tags(store, get_unique_key_id(bucket, key, version_id))
1343
+ store.tags.delete_all_tags(get_unique_key_id(bucket, key, version_id))
1369
1344
  self._notify(context, s3_bucket=s3_bucket, s3_object=s3_object)
1370
1345
 
1371
1346
  if key not in s3_bucket.objects:
@@ -1425,9 +1400,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1425
1400
  if found_object:
1426
1401
  to_remove.append(found_object)
1427
1402
  self._notify(context, s3_bucket=s3_bucket, s3_object=found_object)
1428
- self._remove_all_object_tags(
1429
- store, get_unique_key_id(bucket, object_key, version_id)
1430
- )
1403
+ store.tags.delete_all_tags(get_unique_key_id(bucket, object_key, version_id))
1431
1404
  # small hack to not create a fake object for nothing
1432
1405
  elif s3_bucket.notification_configuration:
1433
1406
  # DeleteObjects is a bit weird, even if the object didn't exist, S3 will trigger a notification
@@ -1505,7 +1478,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1505
1478
  to_remove.append(found_object)
1506
1479
 
1507
1480
  self._notify(context, s3_bucket=s3_bucket, s3_object=found_object)
1508
- self._remove_all_object_tags(store, get_unique_key_id(bucket, object_key, version_id))
1481
+ store.tags.delete_all_tags(get_unique_key_id(bucket, object_key, version_id))
1509
1482
 
1510
1483
  for versioned_key in versioned_keys:
1511
1484
  # we clean up keys that do not have any object versions in them anymore
@@ -1725,13 +1698,13 @@ class S3Provider(S3Api, ServiceLifecycleHook):
1725
1698
  dest_key_id = get_unique_key_id(dest_bucket, dest_key, dest_version_id)
1726
1699
 
1727
1700
  if (request.get("TaggingDirective")) == "REPLACE":
1728
- self._remove_all_object_tags(store, dest_key_id)
1729
- self._create_object_tags(store, dest_key_id, tagging or {})
1701
+ store.tags.delete_all_tags(dest_key_id)
1702
+ store.tags.update_tags(dest_key_id, tagging or {})
1730
1703
  else:
1731
1704
  src_key_id = get_unique_key_id(src_bucket, src_key, src_s3_object.version_id)
1732
- src_tags = self._list_object_tags(store, src_key_id)
1733
- self._remove_all_object_tags(store, dest_key_id)
1734
- self._create_object_tags(store, dest_key_id, src_tags)
1705
+ src_tags = store.tags.get_tags(src_key_id)
1706
+ store.tags.delete_all_tags(dest_key_id)
1707
+ store.tags.update_tags(dest_key_id, src_tags)
1735
1708
 
1736
1709
  copy_object_result = CopyObjectResult(
1737
1710
  ETag=s3_object.quoted_etag,
@@ -2878,9 +2851,9 @@ class S3Provider(S3Api, ServiceLifecycleHook):
2878
2851
  s3_bucket.multiparts.pop(s3_multipart.id, None)
2879
2852
 
2880
2853
  key_id = get_unique_key_id(bucket, key, version_id)
2881
- self._remove_all_object_tags(store, key_id)
2854
+ store.tags.delete_all_tags(key_id)
2882
2855
  if s3_multipart.tagging:
2883
- self._create_object_tags(store, key_id, s3_multipart.tagging)
2856
+ store.tags.update_tags(key_id, s3_multipart.tagging)
2884
2857
 
2885
2858
  # RequestCharged: Optional[RequestCharged] TODO
2886
2859
 
@@ -3316,8 +3289,8 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3316
3289
  validate_tag_set(tag_set, type_set="bucket")
3317
3290
 
3318
3291
  # remove the previous tags before setting the new ones, it overwrites the whole TagSet
3319
- self._remove_all_bucket_tags(s3_bucket)
3320
- self._create_bucket_tags(s3_bucket, tag_set)
3292
+ store.tags.delete_all_tags(s3_bucket.bucket_arn)
3293
+ store.tags.update_tags(s3_bucket.bucket_arn, {tag["Key"]: tag["Value"] for tag in tag_set})
3321
3294
 
3322
3295
  def get_bucket_tagging(
3323
3296
  self,
@@ -3327,7 +3300,8 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3327
3300
  **kwargs,
3328
3301
  ) -> GetBucketTaggingOutput:
3329
3302
  store, s3_bucket = self._get_cross_account_bucket(context, bucket)
3330
- tag_set = self._list_bucket_tags(s3_bucket)
3303
+ tags = store.tags.get_tags(s3_bucket.bucket_arn)
3304
+ tag_set = [{"Key": key, "Value": value} for key, value in dict(tags).items()]
3331
3305
  if not tag_set:
3332
3306
  raise NoSuchTagSet(
3333
3307
  "The TagSet does not exist",
@@ -3345,9 +3319,10 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3345
3319
  ) -> None:
3346
3320
  store, s3_bucket = self._get_cross_account_bucket(context, bucket)
3347
3321
 
3348
- # This operation doesn't remove the tags from the store like deleting a resource does, it just sets them as empty.
3349
- self._remove_all_bucket_tags(s3_bucket)
3350
- self._create_bucket_tags(s3_bucket, [])
3322
+ # This operation doesn't remove the tags from the store like deleting a resource does
3323
+ # it just sets them as empty.
3324
+ store.tags.delete_all_tags(s3_bucket.bucket_arn)
3325
+ store.tags.update_tags(s3_bucket.bucket_arn, {})
3351
3326
 
3352
3327
  def put_object_tagging(
3353
3328
  self,
@@ -3374,8 +3349,8 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3374
3349
 
3375
3350
  key_id = get_unique_key_id(bucket, key, s3_object.version_id)
3376
3351
  # remove the previous tags before setting the new ones, it overwrites the whole TagSet
3377
- self._remove_all_object_tags(store, key_id)
3378
- self._create_object_tags(store, key_id, {tag["Key"]: tag["Value"] for tag in tag_set})
3352
+ store.tags.delete_all_tags(key_id)
3353
+ store.tags.update_tags(key_id, {tag["Key"]: tag["Value"] for tag in tag_set})
3379
3354
  response = PutObjectTaggingOutput()
3380
3355
  if s3_object.version_id:
3381
3356
  response["VersionId"] = s3_object.version_id
@@ -3395,7 +3370,6 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3395
3370
  **kwargs,
3396
3371
  ) -> GetObjectTaggingOutput:
3397
3372
  store, s3_bucket = self._get_cross_account_bucket(context, bucket)
3398
-
3399
3373
  try:
3400
3374
  s3_object = s3_bucket.get_object(key=key, version_id=version_id)
3401
3375
  except NoSuchKey as e:
@@ -3419,9 +3393,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3419
3393
  e.Key = f"{bucket}/{key}"
3420
3394
  raise e
3421
3395
 
3422
- object_tags = self._list_object_tags(
3423
- store, get_unique_key_id(bucket, key, s3_object.version_id)
3424
- )
3396
+ object_tags = store.tags.get_tags(get_unique_key_id(bucket, key, s3_object.version_id))
3425
3397
  response = GetObjectTaggingOutput(
3426
3398
  TagSet=[Tag(Key=key, Value=value) for key, value in object_tags.items()]
3427
3399
  )
@@ -3443,7 +3415,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
3443
3415
 
3444
3416
  s3_object = s3_bucket.get_object(key=key, version_id=version_id, http_method="DELETE")
3445
3417
 
3446
- self._remove_all_object_tags(store, get_unique_key_id(bucket, key, s3_object.version_id))
3418
+ store.tags.delete_all_tags(get_unique_key_id(bucket, key, s3_object.version_id))
3447
3419
  response = DeleteObjectTaggingOutput()
3448
3420
  if s3_object.version_id:
3449
3421
  response["VersionId"] = s3_object.version_id
@@ -4632,9 +4604,9 @@ class S3Provider(S3Api, ServiceLifecycleHook):
4632
4604
 
4633
4605
  # in case we are overriding an object, delete the tags entry
4634
4606
  key_id = get_unique_key_id(bucket, object_key, version_id)
4635
- self._remove_all_object_tags(store, key_id)
4607
+ store.tags.delete_all_tags(key_id)
4636
4608
  if tagging:
4637
- self._create_object_tags(store, key_id, tagging)
4609
+ store.tags.update_tags(key_id, tagging)
4638
4610
 
4639
4611
  response = PostResponse()
4640
4612
  # hacky way to set the etag in the headers as well: two locations for one value
@@ -4677,7 +4649,7 @@ class S3Provider(S3Api, ServiceLifecycleHook):
4677
4649
  s3_bucket.lifecycle_rules,
4678
4650
  bucket,
4679
4651
  s3_object,
4680
- self._list_object_tags(store, key_id),
4652
+ store.tags.get_tags(key_id),
4681
4653
  ):
4682
4654
  # TODO: we either apply the lifecycle to existing objects when we set the new rules, or we need to
4683
4655
  # apply them everytime we get/head an object
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.dev104'
32
- __version_tuple__ = version_tuple = (4, 13, 2, 'dev104')
31
+ __version__ = version = '4.13.2.dev106'
32
+ __version_tuple__ = version_tuple = (4, 13, 2, 'dev106')
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.dev104
3
+ Version: 4.13.2.dev106
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=g0E-_q3apmHlOET2Gg5_biUtN2b4XygnI5aeeaZm6ZY,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=FImvQP_ivWK1aCfrrwmnMnRcaoQ67AeSsD4itjZyJt0,723
7
+ localstack/version.py,sha256=pluB_CxCJtcx78qU2ItexzIp8ak5cmK0mfiaMj-lHRo,723
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
@@ -337,11 +337,11 @@ localstack/services/cloudformation/v2/provider.py,sha256=1cr_3flqALbY-H40lrVCcIq
337
337
  localstack/services/cloudformation/v2/types.py,sha256=jsfvn2z6weqruaDvv6qtSILtFiOTRl9fIjl0vXvl108,1060
338
338
  localstack/services/cloudformation/v2/utils.py,sha256=U1-YK7BEfA2lRKuUzDUVQ_dXUXybTHciNZA1G3xuZI8,202
339
339
  localstack/services/cloudwatch/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
340
- localstack/services/cloudwatch/alarm_scheduler.py,sha256=HPzQgZvDVXIXaEkjJ39L-jBwlOi_-ZlAyJ3D_suWngk,15761
340
+ localstack/services/cloudwatch/alarm_scheduler.py,sha256=6C3LIdgoeiALBSglTILsqxx4jHwlaP81JeS_tVycjiM,16233
341
341
  localstack/services/cloudwatch/cloudwatch_database_helper.py,sha256=IK_MgxG3xTkpKbBe-Buv_6wUuHEc3MGQOqMAqHoEOzk,17270
342
342
  localstack/services/cloudwatch/models.py,sha256=gy6kNsAjBggpTgzSX-MfUKYnkpkZ2yanNNNcGYSLASw,4063
343
- localstack/services/cloudwatch/provider.py,sha256=Ss7Mc6XAQhXabUoz_loonp_UcA-VCi5IXCyvqXfn5kw,19701
344
- localstack/services/cloudwatch/provider_v2.py,sha256=vCpcWVTM6Wilm_Jt_x-3vYaD1eVNX9dDzleJ5D5J3pw,44930
343
+ localstack/services/cloudwatch/provider.py,sha256=YTtjQLKOLaRVbkUOrkAPCk7Tf8gydncrdQhU3UOHjdI,19308
344
+ localstack/services/cloudwatch/provider_v2.py,sha256=fkxU9Wx-fjYTrBp1nBihuKtctN_ImAB4btlGptuHykQ,44521
345
345
  localstack/services/cloudwatch/resource_providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
346
346
  localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.py,sha256=T0P5uTDjQO3lNw5w4wcdBgzFthGDjJXUkPtHo1BP13I,5172
347
347
  localstack/services/cloudwatch/resource_providers/aws_cloudwatch_alarm.schema.json,sha256=8Nam5WqGfyW85m55UVCwJF17Re4tPOIJY_m6Wq37y8k,3829
@@ -690,7 +690,7 @@ localstack/services/s3/headers.py,sha256=jh0R2vhdnB5pWiVCoV26kqup53dBWz3iQIE3mhP
690
690
  localstack/services/s3/models.py,sha256=moQL38yVh3Bk5tgMIzW2yiIF1E2GdgO56ahOiTY5GTc,31239
691
691
  localstack/services/s3/notifications.py,sha256=JRvZTs3YpEXX-tPdliarVKjKsp42fdzrTNOC51y2-8I,32568
692
692
  localstack/services/s3/presigned_url.py,sha256=rAp8JdscT8ND4qxaHjSsfibEjEvPJ3CIVI0hwHDyJcA,38868
693
- localstack/services/s3/provider.py,sha256=YlqkZQpCgFw7pwOOV8NF2KHXRkT1lvFVUQfHdAmIf4A,204671
693
+ localstack/services/s3/provider.py,sha256=x7cVaqra2dTfH8iU-9MhvVUBo8WN6DERyOajNmoSQqk,203701
694
694
  localstack/services/s3/utils.py,sha256=CKx6DuarUxxQ2d6gLciqoKY95Q5hfzj4wzgg8n91j1U,44363
695
695
  localstack/services/s3/validation.py,sha256=wMTShZu48Xpjdc6Y_nkztvjja9Rv4JWXkD8CLyAbBSo,20403
696
696
  localstack/services/s3/website_hosting.py,sha256=I4cE7omiN7EBQjdlvueSb_DaD8cwEZxeh7K-H_We30k,16672
@@ -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.dev104.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1315
- localstack_core-4.13.2.dev104.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1316
- localstack_core-4.13.2.dev104.dist-info/METADATA,sha256=zlOpjYIA0k6OfyQvIIPcavWvPwJGFgLKmVu2TjsyxDo,5868
1317
- localstack_core-4.13.2.dev104.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
1318
- localstack_core-4.13.2.dev104.dist-info/entry_points.txt,sha256=59aAnn8KVHWAHkMg2dOgmgYtRZ-xTX9T4UiIchWgK6k,20975
1319
- localstack_core-4.13.2.dev104.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1320
- localstack_core-4.13.2.dev104.dist-info/RECORD,,
1314
+ localstack_core-4.13.2.dev106.data/scripts/localstack-supervisor,sha256=nm1Il2d6ASyOB6Vo4CRHd90w7TK9FdRl9VPp0NN6hUk,6378
1315
+ localstack_core-4.13.2.dev106.dist-info/licenses/LICENSE.txt,sha256=3PC-9Z69UsNARuQ980gNR_JsLx8uvMjdG6C7cc4LBYs,606
1316
+ localstack_core-4.13.2.dev106.dist-info/METADATA,sha256=fEKPTmzZoG9hmSwrprrQkJYyK_fLJ0nNTYHHK0QJkaM,5868
1317
+ localstack_core-4.13.2.dev106.dist-info/WHEEL,sha256=YCfwYGOYMi5Jhw2fU4yNgwErybb2IX5PEwBKV4ZbdBo,91
1318
+ localstack_core-4.13.2.dev106.dist-info/entry_points.txt,sha256=59aAnn8KVHWAHkMg2dOgmgYtRZ-xTX9T4UiIchWgK6k,20975
1319
+ localstack_core-4.13.2.dev106.dist-info/top_level.txt,sha256=3sqmK2lGac8nCy8nwsbS5SpIY_izmtWtgaTFKHYVHbI,11
1320
+ localstack_core-4.13.2.dev106.dist-info/RECORD,,