localstack-core 4.7.1.dev49__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 (253) hide show
  1. localstack/aws/api/cloudformation/__init__.py +18 -4
  2. localstack/aws/api/cloudwatch/__init__.py +41 -1
  3. localstack/aws/api/config/__init__.py +4 -0
  4. localstack/aws/api/core.py +6 -2
  5. localstack/aws/api/dynamodb/__init__.py +30 -0
  6. localstack/aws/api/ec2/__init__.py +1522 -65
  7. localstack/aws/api/iam/__init__.py +7 -0
  8. localstack/aws/api/kinesis/__init__.py +19 -0
  9. localstack/aws/api/kms/__init__.py +6 -0
  10. localstack/aws/api/lambda_/__init__.py +13 -0
  11. localstack/aws/api/logs/__init__.py +15 -0
  12. localstack/aws/api/redshift/__init__.py +9 -3
  13. localstack/aws/api/route53/__init__.py +5 -0
  14. localstack/aws/api/s3/__init__.py +12 -0
  15. localstack/aws/api/s3control/__init__.py +54 -0
  16. localstack/aws/api/ssm/__init__.py +2 -0
  17. localstack/aws/api/transcribe/__init__.py +17 -0
  18. localstack/aws/client.py +7 -2
  19. localstack/aws/forwarder.py +52 -5
  20. localstack/aws/handlers/analytics.py +1 -1
  21. localstack/aws/handlers/internal_requests.py +6 -1
  22. localstack/aws/handlers/logging.py +12 -2
  23. localstack/aws/handlers/metric_handler.py +41 -1
  24. localstack/aws/handlers/service.py +40 -20
  25. localstack/aws/mocking.py +2 -2
  26. localstack/aws/patches.py +2 -2
  27. localstack/aws/protocol/parser.py +459 -32
  28. localstack/aws/protocol/serializer.py +689 -69
  29. localstack/aws/protocol/service_router.py +120 -20
  30. localstack/aws/protocol/validate.py +1 -1
  31. localstack/aws/scaffold.py +1 -1
  32. localstack/aws/skeleton.py +4 -2
  33. localstack/aws/spec-patches.json +58 -0
  34. localstack/aws/spec.py +37 -16
  35. localstack/cli/exceptions.py +1 -1
  36. localstack/cli/localstack.py +6 -6
  37. localstack/cli/lpm.py +3 -4
  38. localstack/cli/plugins.py +1 -1
  39. localstack/cli/profiles.py +1 -2
  40. localstack/config.py +25 -18
  41. localstack/constants.py +4 -29
  42. localstack/dev/kubernetes/__main__.py +130 -7
  43. localstack/dev/run/configurators.py +1 -4
  44. localstack/dev/run/paths.py +1 -1
  45. localstack/dns/plugins.py +5 -1
  46. localstack/dns/server.py +13 -4
  47. localstack/logging/format.py +3 -3
  48. localstack/packages/api.py +9 -8
  49. localstack/packages/core.py +2 -2
  50. localstack/packages/plugins.py +0 -8
  51. localstack/runtime/analytics.py +3 -0
  52. localstack/runtime/hooks.py +1 -1
  53. localstack/runtime/init.py +2 -2
  54. localstack/runtime/main.py +5 -5
  55. localstack/runtime/patches.py +2 -2
  56. localstack/services/apigateway/helpers.py +1 -4
  57. localstack/services/apigateway/legacy/helpers.py +7 -8
  58. localstack/services/apigateway/legacy/integration.py +4 -3
  59. localstack/services/apigateway/legacy/invocations.py +6 -5
  60. localstack/services/apigateway/legacy/provider.py +148 -68
  61. localstack/services/apigateway/legacy/templates.py +1 -1
  62. localstack/services/apigateway/next_gen/execute_api/handlers/method_request.py +7 -2
  63. localstack/services/apigateway/next_gen/execute_api/handlers/resource_router.py +1 -2
  64. localstack/services/apigateway/next_gen/execute_api/integrations/aws.py +3 -0
  65. localstack/services/apigateway/next_gen/execute_api/integrations/http.py +3 -3
  66. localstack/services/apigateway/next_gen/execute_api/template_mapping.py +2 -2
  67. localstack/services/apigateway/next_gen/execute_api/test_invoke.py +114 -9
  68. localstack/services/apigateway/next_gen/provider.py +5 -0
  69. localstack/services/apigateway/resource_providers/aws_apigateway_resource.py +1 -1
  70. localstack/services/cloudformation/api_utils.py +4 -8
  71. localstack/services/cloudformation/cfn_utils.py +1 -1
  72. localstack/services/cloudformation/engine/entities.py +14 -4
  73. localstack/services/cloudformation/engine/template_deployer.py +6 -4
  74. localstack/services/cloudformation/engine/transformers.py +6 -4
  75. localstack/services/cloudformation/engine/v2/change_set_model.py +201 -13
  76. localstack/services/cloudformation/engine/v2/change_set_model_describer.py +52 -3
  77. localstack/services/cloudformation/engine/v2/change_set_model_executor.py +117 -76
  78. localstack/services/cloudformation/engine/v2/change_set_model_preproc.py +205 -52
  79. localstack/services/cloudformation/engine/v2/change_set_model_transform.py +350 -116
  80. localstack/services/cloudformation/engine/v2/change_set_model_validator.py +56 -14
  81. localstack/services/cloudformation/engine/v2/change_set_model_visitor.py +1 -0
  82. localstack/services/cloudformation/engine/v2/resolving.py +7 -5
  83. localstack/services/cloudformation/engine/yaml_parser.py +9 -2
  84. localstack/services/cloudformation/provider.py +7 -5
  85. localstack/services/cloudformation/resource_provider.py +7 -1
  86. localstack/services/cloudformation/resources.py +24149 -0
  87. localstack/services/cloudformation/service_models.py +2 -2
  88. localstack/services/cloudformation/v2/entities.py +19 -9
  89. localstack/services/cloudformation/v2/provider.py +336 -106
  90. localstack/services/cloudformation/v2/types.py +13 -7
  91. localstack/services/cloudformation/v2/utils.py +4 -1
  92. localstack/services/cloudwatch/alarm_scheduler.py +4 -1
  93. localstack/services/cloudwatch/provider.py +18 -13
  94. localstack/services/cloudwatch/provider_v2.py +25 -28
  95. localstack/services/dynamodb/packages.py +2 -1
  96. localstack/services/dynamodb/provider.py +42 -0
  97. localstack/services/dynamodb/server.py +2 -2
  98. localstack/services/dynamodb/v2/provider.py +42 -0
  99. localstack/services/ecr/resource_providers/aws_ecr_repository.py +5 -2
  100. localstack/services/edge.py +1 -1
  101. localstack/services/es/provider.py +2 -2
  102. localstack/services/events/event_rule_engine.py +31 -13
  103. localstack/services/events/models.py +4 -5
  104. localstack/services/events/provider.py +17 -14
  105. localstack/services/events/target.py +17 -9
  106. localstack/services/events/v1/provider.py +5 -5
  107. localstack/services/firehose/provider.py +14 -4
  108. localstack/services/iam/provider.py +11 -116
  109. localstack/services/iam/resources/policy_simulator.py +133 -0
  110. localstack/services/kinesis/models.py +15 -2
  111. localstack/services/kinesis/provider.py +86 -3
  112. localstack/services/kms/provider.py +14 -5
  113. localstack/services/lambda_/api_utils.py +6 -3
  114. localstack/services/lambda_/invocation/docker_runtime_executor.py +1 -1
  115. localstack/services/lambda_/invocation/event_manager.py +1 -1
  116. localstack/services/lambda_/invocation/internal_sqs_queue.py +5 -9
  117. localstack/services/lambda_/invocation/lambda_models.py +10 -7
  118. localstack/services/lambda_/invocation/lambda_service.py +5 -1
  119. localstack/services/lambda_/packages.py +1 -1
  120. localstack/services/lambda_/provider.py +4 -3
  121. localstack/services/lambda_/provider_utils.py +1 -1
  122. localstack/services/logs/provider.py +36 -19
  123. localstack/services/moto.py +2 -1
  124. localstack/services/opensearch/cluster.py +15 -7
  125. localstack/services/opensearch/packages.py +26 -7
  126. localstack/services/opensearch/provider.py +8 -2
  127. localstack/services/opensearch/versions.py +56 -7
  128. localstack/services/plugins.py +11 -7
  129. localstack/services/providers.py +10 -2
  130. localstack/services/redshift/provider.py +0 -21
  131. localstack/services/s3/constants.py +5 -2
  132. localstack/services/s3/cors.py +4 -4
  133. localstack/services/s3/models.py +1 -1
  134. localstack/services/s3/notifications.py +55 -39
  135. localstack/services/s3/presigned_url.py +35 -54
  136. localstack/services/s3/provider.py +73 -15
  137. localstack/services/s3/utils.py +42 -22
  138. localstack/services/s3/validation.py +46 -32
  139. localstack/services/s3/website_hosting.py +4 -2
  140. localstack/services/ses/provider.py +18 -8
  141. localstack/services/sns/constants.py +7 -1
  142. localstack/services/sns/executor.py +9 -2
  143. localstack/services/sns/provider.py +8 -5
  144. localstack/services/sns/publisher.py +31 -16
  145. localstack/services/sns/v2/models.py +167 -0
  146. localstack/services/sns/v2/provider.py +867 -0
  147. localstack/services/sns/v2/utils.py +130 -0
  148. localstack/services/sqs/constants.py +1 -1
  149. localstack/services/sqs/developer_api.py +205 -0
  150. localstack/services/sqs/models.py +48 -5
  151. localstack/services/sqs/provider.py +38 -311
  152. localstack/services/sqs/query_api.py +6 -2
  153. localstack/services/sqs/utils.py +121 -2
  154. localstack/services/ssm/provider.py +1 -1
  155. localstack/services/stepfunctions/asl/component/intrinsic/member.py +1 -1
  156. localstack/services/stepfunctions/asl/component/state/state_choice/comparison/comparison.py +5 -11
  157. localstack/services/stepfunctions/asl/component/state/state_choice/state_choice.py +2 -2
  158. localstack/services/stepfunctions/asl/component/state/state_execution/state_map/state_map.py +2 -2
  159. localstack/services/stepfunctions/asl/component/state/state_execution/state_parallel/state_parallel.py +1 -1
  160. localstack/services/stepfunctions/asl/component/state/state_execution/state_task/state_task.py +2 -2
  161. localstack/services/stepfunctions/asl/component/state/state_fail/state_fail.py +1 -1
  162. localstack/services/stepfunctions/asl/component/state/state_pass/state_pass.py +2 -2
  163. localstack/services/stepfunctions/asl/component/state/state_succeed/state_succeed.py +1 -1
  164. localstack/services/stepfunctions/asl/component/state/state_wait/state_wait.py +1 -1
  165. localstack/services/stepfunctions/asl/eval/environment.py +1 -1
  166. localstack/services/stepfunctions/asl/jsonata/jsonata.py +1 -1
  167. localstack/services/stepfunctions/backend/execution.py +2 -1
  168. localstack/services/stores.py +1 -1
  169. localstack/services/transcribe/provider.py +6 -1
  170. localstack/state/codecs.py +61 -0
  171. localstack/state/core.py +11 -5
  172. localstack/state/pickle.py +10 -49
  173. localstack/testing/aws/cloudformation_utils.py +1 -1
  174. localstack/testing/pytest/cloudformation/fixtures.py +3 -3
  175. localstack/testing/pytest/cloudformation/transformers.py +0 -0
  176. localstack/testing/pytest/container.py +4 -5
  177. localstack/testing/pytest/fixtures.py +33 -31
  178. localstack/testing/pytest/in_memory_localstack.py +0 -4
  179. localstack/testing/pytest/marking.py +38 -11
  180. localstack/testing/pytest/stepfunctions/utils.py +4 -3
  181. localstack/testing/pytest/util.py +1 -1
  182. localstack/testing/pytest/validation_tracking.py +1 -2
  183. localstack/testing/snapshots/transformer_utility.py +6 -1
  184. localstack/utils/analytics/events.py +2 -2
  185. localstack/utils/analytics/metadata.py +6 -4
  186. localstack/utils/analytics/metrics/counter.py +8 -15
  187. localstack/utils/analytics/publisher.py +1 -2
  188. localstack/utils/analytics/service_providers.py +19 -0
  189. localstack/utils/analytics/service_request_aggregator.py +2 -2
  190. localstack/utils/archives.py +11 -11
  191. localstack/utils/asyncio.py +2 -2
  192. localstack/utils/aws/arns.py +24 -29
  193. localstack/utils/aws/aws_responses.py +8 -8
  194. localstack/utils/aws/aws_stack.py +2 -3
  195. localstack/utils/aws/dead_letter_queue.py +1 -5
  196. localstack/utils/aws/message_forwarding.py +1 -2
  197. localstack/utils/aws/request_context.py +4 -5
  198. localstack/utils/aws/resources.py +1 -1
  199. localstack/utils/aws/templating.py +1 -1
  200. localstack/utils/batch_policy.py +3 -3
  201. localstack/utils/bootstrap.py +21 -13
  202. localstack/utils/catalog/catalog.py +139 -0
  203. localstack/utils/catalog/catalog_loader.py +119 -0
  204. localstack/utils/catalog/common.py +58 -0
  205. localstack/utils/catalog/plugins.py +28 -0
  206. localstack/utils/cloudwatch/cloudwatch_util.py +5 -5
  207. localstack/utils/collections.py +7 -8
  208. localstack/utils/config_listener.py +1 -1
  209. localstack/utils/container_networking.py +2 -3
  210. localstack/utils/container_utils/container_client.py +135 -136
  211. localstack/utils/container_utils/docker_cmd_client.py +85 -69
  212. localstack/utils/container_utils/docker_sdk_client.py +69 -66
  213. localstack/utils/crypto.py +10 -10
  214. localstack/utils/diagnose.py +3 -4
  215. localstack/utils/docker_utils.py +9 -5
  216. localstack/utils/files.py +33 -13
  217. localstack/utils/functions.py +4 -3
  218. localstack/utils/http.py +11 -11
  219. localstack/utils/json.py +20 -6
  220. localstack/utils/kinesis/kinesis_connector.py +2 -1
  221. localstack/utils/net.py +15 -9
  222. localstack/utils/no_exit_argument_parser.py +2 -2
  223. localstack/utils/numbers.py +9 -2
  224. localstack/utils/objects.py +7 -6
  225. localstack/utils/patch.py +10 -3
  226. localstack/utils/run.py +12 -11
  227. localstack/utils/scheduler.py +11 -11
  228. localstack/utils/server/tcp_proxy.py +2 -2
  229. localstack/utils/serving.py +3 -4
  230. localstack/utils/strings.py +15 -16
  231. localstack/utils/sync.py +126 -1
  232. localstack/utils/tagging.py +8 -6
  233. localstack/utils/testutil.py +8 -8
  234. localstack/utils/threads.py +2 -2
  235. localstack/utils/time.py +12 -4
  236. localstack/utils/urls.py +1 -3
  237. localstack/utils/xray/traceid.py +1 -1
  238. localstack/version.py +16 -3
  239. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/METADATA +18 -14
  240. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/RECORD +248 -239
  241. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/entry_points.txt +8 -4
  242. localstack_core-4.10.1.dev12.dist-info/plux.json +1 -0
  243. localstack/packages/terraform.py +0 -46
  244. localstack/services/cloudformation/deploy.html +0 -144
  245. localstack/services/cloudformation/deploy_ui.py +0 -47
  246. localstack/services/cloudformation/plugins.py +0 -12
  247. localstack_core-4.7.1.dev49.dist-info/plux.json +0 -1
  248. {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack +0 -0
  249. {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack-supervisor +0 -0
  250. {localstack_core-4.7.1.dev49.data → localstack_core-4.10.1.dev12.data}/scripts/localstack.bat +0 -0
  251. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/WHEEL +0 -0
  252. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/licenses/LICENSE.txt +0 -0
  253. {localstack_core-4.7.1.dev49.dist-info → localstack_core-4.10.1.dev12.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,7 @@
1
1
  import json
2
2
  import logging
3
3
  import re
4
- from typing import Callable
4
+ from collections.abc import Callable
5
5
 
6
6
  from requests.models import Response
7
7
 
@@ -2,7 +2,6 @@ import logging
2
2
  import os
3
3
  import re
4
4
  from functools import lru_cache
5
- from typing import Optional
6
5
 
7
6
  from localstack import config, constants
8
7
  from localstack.utils.container_utils.container_client import ContainerException
@@ -13,7 +12,7 @@ LOG = logging.getLogger(__name__)
13
12
 
14
13
 
15
14
  @lru_cache
16
- def get_main_container_network() -> Optional[str]:
15
+ def get_main_container_network() -> str | None:
17
16
  """
18
17
  Gets the main network of the LocalStack container (if we run in one, bridge otherwise)
19
18
  If there are multiple networks connected to the LocalStack container, we choose the first as "main" network
@@ -50,7 +49,7 @@ def get_main_container_network() -> Optional[str]:
50
49
 
51
50
 
52
51
  @lru_cache
53
- def get_endpoint_for_network(network: Optional[str] = None) -> str:
52
+ def get_endpoint_for_network(network: str | None = None) -> str:
54
53
  """
55
54
  Get the LocalStack endpoint (= IP address) on the given network.
56
55
  If a network is given, it will return the IP address/hostname of LocalStack on that network
@@ -5,21 +5,17 @@ import logging
5
5
  import os
6
6
  import re
7
7
  import shlex
8
- import sys
9
8
  import tarfile
10
9
  import tempfile
11
10
  from abc import ABCMeta, abstractmethod
11
+ from collections.abc import Callable
12
12
  from enum import Enum, unique
13
13
  from pathlib import Path
14
14
  from typing import (
15
- Callable,
16
15
  Literal,
17
16
  NamedTuple,
18
- Optional,
19
17
  Protocol,
20
18
  TypedDict,
21
- Union,
22
- get_args,
23
19
  )
24
20
 
25
21
  import dotenv
@@ -57,7 +53,7 @@ class DockerContainerStats(TypedDict):
57
53
  MemUsage: tuple[int, int]
58
54
  NetIO: tuple[int, int]
59
55
  PIDs: int
60
- SDKStats: Optional[dict]
56
+ SDKStats: dict | None
61
57
 
62
58
 
63
59
  class ContainerException(Exception):
@@ -143,7 +139,7 @@ class Ulimit:
143
139
 
144
140
  name: str
145
141
  soft_limit: int
146
- hard_limit: Optional[int] = None
142
+ hard_limit: int | None = None
147
143
 
148
144
  def __repr__(self):
149
145
  """Format: <type>=<soft limit>[:<hard limit>]"""
@@ -154,19 +150,11 @@ class Ulimit:
154
150
 
155
151
 
156
152
  # defines the type for port mappings (source->target port range)
157
- PortRange = Union[list, HashableList]
153
+ PortRange = list | HashableList
158
154
  # defines the protocol for a port range ("tcp" or "udp")
159
155
  PortProtocol = str
160
156
 
161
157
 
162
- def isinstance_union(obj, class_or_tuple):
163
- # that's some dirty hack
164
- if sys.version_info < (3, 10):
165
- return isinstance(obj, get_args(PortRange))
166
- else:
167
- return isinstance(obj, class_or_tuple)
168
-
169
-
170
158
  class PortMappings:
171
159
  """Maps source to target port ranges for Docker port mappings."""
172
160
 
@@ -181,14 +169,14 @@ class PortMappings:
181
169
 
182
170
  def add(
183
171
  self,
184
- port: Union[int, PortRange],
185
- mapped: Union[int, PortRange] = None,
172
+ port: int | PortRange,
173
+ mapped: int | PortRange = None,
186
174
  protocol: PortProtocol = "tcp",
187
175
  ):
188
176
  mapped = mapped or port
189
- if isinstance_union(port, PortRange):
177
+ if isinstance(port, PortRange):
190
178
  for i in range(port[1] - port[0] + 1):
191
- if isinstance_union(mapped, PortRange):
179
+ if isinstance(mapped, PortRange):
192
180
  self.add(port[0] + i, mapped[0] + i, protocol)
193
181
  else:
194
182
  self.add(port[0] + i, mapped, protocol)
@@ -266,7 +254,7 @@ class PortMappings:
266
254
 
267
255
  return [item for k, v in self.mappings.items() for item in entry(k, v)]
268
256
 
269
- def to_dict(self) -> dict[str, Union[tuple[str, Union[int, list[int]]], int]]:
257
+ def to_dict(self) -> dict[str, tuple[str, int | list[int]] | int]:
270
258
  bind_address = self.bind_host or ""
271
259
 
272
260
  def bind_port(bind_address, host_port):
@@ -452,27 +440,23 @@ class VolumeDirMount:
452
440
 
453
441
 
454
442
  class VolumeMappings:
455
- mappings: list[Union[SimpleVolumeBind, BindMount]]
443
+ mappings: list[SimpleVolumeBind | BindMount]
456
444
 
457
- def __init__(self, mappings: list[Union[SimpleVolumeBind, BindMount, VolumeDirMount]] = None):
445
+ def __init__(self, mappings: list[SimpleVolumeBind | BindMount | VolumeDirMount] = None):
458
446
  self.mappings = mappings if mappings is not None else []
459
447
 
460
- def add(self, mapping: Union[SimpleVolumeBind, BindMount, VolumeDirMount]):
448
+ def add(self, mapping: SimpleVolumeBind | BindMount | VolumeDirMount):
461
449
  self.append(mapping)
462
450
 
463
451
  def append(
464
452
  self,
465
- mapping: Union[
466
- SimpleVolumeBind,
467
- BindMount,
468
- VolumeDirMount,
469
- ],
453
+ mapping: SimpleVolumeBind | BindMount | VolumeDirMount,
470
454
  ):
471
455
  self.mappings.append(mapping)
472
456
 
473
457
  def find_target_mapping(
474
458
  self, container_dir: str
475
- ) -> Optional[Union[SimpleVolumeBind, BindMount, VolumeDirMount]]:
459
+ ) -> SimpleVolumeBind | BindMount | VolumeDirMount | None:
476
460
  """
477
461
  Looks through the volumes and returns the one where the container dir matches ``container_dir``.
478
462
  Returns None if there is no volume mapping to the given container directory.
@@ -511,8 +495,8 @@ class VolumeInfo(NamedTuple):
511
495
  mode: str
512
496
  rw: bool
513
497
  propagation: str
514
- name: Optional[str] = None
515
- driver: Optional[str] = None
498
+ name: str | None = None
499
+ driver: str | None = None
516
500
 
517
501
 
518
502
  @dataclasses.dataclass
@@ -524,13 +508,13 @@ class LogConfig:
524
508
  @dataclasses.dataclass
525
509
  class ContainerConfiguration:
526
510
  image_name: str
527
- name: Optional[str] = None
511
+ name: str | None = None
528
512
  volumes: VolumeMappings = dataclasses.field(default_factory=VolumeMappings)
529
513
  ports: PortMappings = dataclasses.field(default_factory=PortMappings)
530
514
  exposed_ports: list[str] = dataclasses.field(default_factory=list)
531
- entrypoint: Optional[Union[list[str], str]] = None
532
- additional_flags: Optional[str] = None
533
- command: Optional[list[str]] = None
515
+ entrypoint: list[str] | str | None = None
516
+ additional_flags: str | None = None
517
+ command: list[str] | None = None
534
518
  env_vars: dict[str, str] = dataclasses.field(default_factory=dict)
535
519
 
536
520
  privileged: bool = False
@@ -539,19 +523,19 @@ class ContainerConfiguration:
539
523
  tty: bool = False
540
524
  detach: bool = False
541
525
 
542
- stdin: Optional[str] = None
543
- user: Optional[str] = None
544
- cap_add: Optional[list[str]] = None
545
- cap_drop: Optional[list[str]] = None
546
- security_opt: Optional[list[str]] = None
547
- network: Optional[str] = None
548
- dns: Optional[str] = None
549
- workdir: Optional[str] = None
550
- platform: Optional[str] = None
551
- ulimits: Optional[list[Ulimit]] = None
552
- labels: Optional[dict[str, str]] = None
553
- init: Optional[bool] = None
554
- log_config: Optional[LogConfig] = None
526
+ stdin: str | None = None
527
+ user: str | None = None
528
+ cap_add: list[str] | None = None
529
+ cap_drop: list[str] | None = None
530
+ security_opt: list[str] | None = None
531
+ network: str | None = None
532
+ dns: str | None = None
533
+ workdir: str | None = None
534
+ platform: str | None = None
535
+ ulimits: list[Ulimit] | None = None
536
+ labels: dict[str, str] | None = None
537
+ init: bool | None = None
538
+ log_config: LogConfig | None = None
555
539
 
556
540
 
557
541
  class ContainerConfigurator(Protocol):
@@ -574,17 +558,17 @@ class DockerRunFlags:
574
558
  create: https://docs.docker.com/engine/reference/commandline/create/
575
559
  """
576
560
 
577
- env_vars: Optional[dict[str, str]]
578
- extra_hosts: Optional[dict[str, str]]
579
- labels: Optional[dict[str, str]]
580
- volumes: Optional[list[SimpleVolumeBind]]
581
- network: Optional[str]
582
- platform: Optional[DockerPlatform]
583
- privileged: Optional[bool]
584
- ports: Optional[PortMappings]
585
- ulimits: Optional[list[Ulimit]]
586
- user: Optional[str]
587
- dns: Optional[list[str]]
561
+ env_vars: dict[str, str] | None
562
+ extra_hosts: dict[str, str] | None
563
+ labels: dict[str, str] | None
564
+ volumes: list[SimpleVolumeBind] | None
565
+ network: str | None
566
+ platform: DockerPlatform | None
567
+ privileged: bool | None
568
+ ports: PortMappings | None
569
+ ulimits: list[Ulimit] | None
570
+ user: str | None
571
+ dns: list[str] | None
588
572
 
589
573
 
590
574
  class RegistryResolverStrategy(Protocol):
@@ -686,8 +670,16 @@ class ContainerClient(metaclass=ABCMeta):
686
670
  """Unpauses a container with the given name."""
687
671
 
688
672
  @abstractmethod
689
- def remove_container(self, container_name: str, force=True, check_existence=False) -> None:
690
- """Removes container with given name"""
673
+ def remove_container(
674
+ self, container_name: str, force=True, check_existence=False, volumes=False
675
+ ) -> None:
676
+ """Removes container
677
+
678
+ :param container_name: Name of the container
679
+ :param force: Force the removal of a running container (uses SIGKILL)
680
+ :param check_existence: Return if container doesn't exist
681
+ :param volumes: Remove anonymous volumes associated with the container
682
+ """
691
683
 
692
684
  @abstractmethod
693
685
  def remove_image(self, image: str, force: bool = True) -> None:
@@ -698,7 +690,7 @@ class ContainerClient(metaclass=ABCMeta):
698
690
  """
699
691
 
700
692
  @abstractmethod
701
- def list_containers(self, filter: Union[list[str], str, None] = None, all=True) -> list[dict]:
693
+ def list_containers(self, filter: list[str] | str | None = None, all=True) -> list[dict]:
702
694
  """List all containers matching the given filters
703
695
 
704
696
  :return: A list of dicts with keys id, image, name, labels, status
@@ -706,9 +698,11 @@ class ContainerClient(metaclass=ABCMeta):
706
698
 
707
699
  def get_running_container_names(self) -> list[str]:
708
700
  """Returns a list of the names of all running containers"""
709
- result = self.list_containers(all=False)
710
- result = [container["name"] for container in result]
711
- return result
701
+ return self.__get_container_names(return_all=False)
702
+
703
+ def get_all_container_names(self) -> list[str]:
704
+ """Returns a list of the names of all containers including stopped ones"""
705
+ return self.__get_container_names(return_all=True)
712
706
 
713
707
  def is_container_running(self, container_name: str) -> bool:
714
708
  """Checks whether a container with a given name is currently running"""
@@ -719,7 +713,7 @@ class ContainerClient(metaclass=ABCMeta):
719
713
  container_name,
720
714
  file_contents: bytes,
721
715
  container_path: str,
722
- chmod_mode: Optional[int] = None,
716
+ chmod_mode: int | None = None,
723
717
  ) -> None:
724
718
  """
725
719
  Create a file in container with the provided content. Provide the 'chmod_mode' argument if you want the file to have specific permissions.
@@ -751,8 +745,8 @@ class ContainerClient(metaclass=ABCMeta):
751
745
  def pull_image(
752
746
  self,
753
747
  docker_image: str,
754
- platform: Optional[DockerPlatform] = None,
755
- log_handler: Optional[Callable[[str], None]] = None,
748
+ platform: DockerPlatform | None = None,
749
+ log_handler: Callable[[str], None] | None = None,
756
750
  ) -> None:
757
751
  """
758
752
  Pulls an image with a given name from a Docker registry
@@ -770,7 +764,7 @@ class ContainerClient(metaclass=ABCMeta):
770
764
  dockerfile_path: str,
771
765
  image_name: str,
772
766
  context_path: str = None,
773
- platform: Optional[DockerPlatform] = None,
767
+ platform: DockerPlatform | None = None,
774
768
  ) -> str:
775
769
  """Builds an image from the given Dockerfile
776
770
 
@@ -814,7 +808,7 @@ class ContainerClient(metaclass=ABCMeta):
814
808
  """Returns a blocking generator you can iterate over to retrieve log output as it happens."""
815
809
 
816
810
  @abstractmethod
817
- def inspect_container(self, container_name_or_id: str) -> dict[str, Union[dict, str]]:
811
+ def inspect_container(self, container_name_or_id: str) -> dict[str, dict | str]:
818
812
  """Get detailed attributes of a container.
819
813
 
820
814
  :return: Dict containing docker attributes as returned by the daemon
@@ -835,7 +829,7 @@ class ContainerClient(metaclass=ABCMeta):
835
829
  @abstractmethod
836
830
  def inspect_image(
837
831
  self, image_name: str, pull: bool = True, strip_wellknown_repo_prefixes: bool = True
838
- ) -> dict[str, Union[dict, list, str]]:
832
+ ) -> dict[str, dict | list | str]:
839
833
  """Get detailed attributes of an image.
840
834
 
841
835
  :param image_name: Image name to inspect
@@ -861,7 +855,7 @@ class ContainerClient(metaclass=ABCMeta):
861
855
  """
862
856
 
863
857
  @abstractmethod
864
- def inspect_network(self, network_name: str) -> dict[str, Union[dict, str]]:
858
+ def inspect_network(self, network_name: str) -> dict[str, dict | str]:
865
859
  """Get detailed attributes of an network.
866
860
 
867
861
  :return: Dict containing docker attributes as returned by the daemon
@@ -872,7 +866,7 @@ class ContainerClient(metaclass=ABCMeta):
872
866
  self,
873
867
  network_name: str,
874
868
  container_name_or_id: str,
875
- aliases: Optional[list] = None,
869
+ aliases: list | None = None,
876
870
  link_local_ips: list[str] = None,
877
871
  ) -> None:
878
872
  """
@@ -984,31 +978,31 @@ class ContainerClient(metaclass=ABCMeta):
984
978
  self,
985
979
  image_name: str,
986
980
  *,
987
- name: Optional[str] = None,
988
- entrypoint: Optional[Union[list[str], str]] = None,
981
+ name: str | None = None,
982
+ entrypoint: list[str] | str | None = None,
989
983
  remove: bool = False,
990
984
  interactive: bool = False,
991
985
  tty: bool = False,
992
986
  detach: bool = False,
993
- command: Optional[Union[list[str], str]] = None,
994
- volumes: Optional[Union[VolumeMappings, list[SimpleVolumeBind]]] = None,
995
- ports: Optional[PortMappings] = None,
996
- exposed_ports: Optional[list[str]] = None,
997
- env_vars: Optional[dict[str, str]] = None,
998
- user: Optional[str] = None,
999
- cap_add: Optional[list[str]] = None,
1000
- cap_drop: Optional[list[str]] = None,
1001
- security_opt: Optional[list[str]] = None,
1002
- network: Optional[str] = None,
1003
- dns: Optional[Union[str, list[str]]] = None,
1004
- additional_flags: Optional[str] = None,
1005
- workdir: Optional[str] = None,
1006
- privileged: Optional[bool] = None,
1007
- labels: Optional[dict[str, str]] = None,
1008
- platform: Optional[DockerPlatform] = None,
1009
- ulimits: Optional[list[Ulimit]] = None,
1010
- init: Optional[bool] = None,
1011
- log_config: Optional[LogConfig] = None,
987
+ command: list[str] | str | None = None,
988
+ volumes: VolumeMappings | list[SimpleVolumeBind] | None = None,
989
+ ports: PortMappings | None = None,
990
+ exposed_ports: list[str] | None = None,
991
+ env_vars: dict[str, str] | None = None,
992
+ user: str | None = None,
993
+ cap_add: list[str] | None = None,
994
+ cap_drop: list[str] | None = None,
995
+ security_opt: list[str] | None = None,
996
+ network: str | None = None,
997
+ dns: str | list[str] | None = None,
998
+ additional_flags: str | None = None,
999
+ workdir: str | None = None,
1000
+ privileged: bool | None = None,
1001
+ labels: dict[str, str] | None = None,
1002
+ platform: DockerPlatform | None = None,
1003
+ ulimits: list[Ulimit] | None = None,
1004
+ init: bool | None = None,
1005
+ log_config: LogConfig | None = None,
1012
1006
  ) -> str:
1013
1007
  """Creates a container with the given image
1014
1008
 
@@ -1021,31 +1015,31 @@ class ContainerClient(metaclass=ABCMeta):
1021
1015
  image_name: str,
1022
1016
  stdin: bytes = None,
1023
1017
  *,
1024
- name: Optional[str] = None,
1025
- entrypoint: Optional[str] = None,
1018
+ name: str | None = None,
1019
+ entrypoint: str | None = None,
1026
1020
  remove: bool = False,
1027
1021
  interactive: bool = False,
1028
1022
  tty: bool = False,
1029
1023
  detach: bool = False,
1030
- command: Optional[Union[list[str], str]] = None,
1031
- volumes: Optional[Union[VolumeMappings, list[SimpleVolumeBind]]] = None,
1032
- ports: Optional[PortMappings] = None,
1033
- exposed_ports: Optional[list[str]] = None,
1034
- env_vars: Optional[dict[str, str]] = None,
1035
- user: Optional[str] = None,
1036
- cap_add: Optional[list[str]] = None,
1037
- cap_drop: Optional[list[str]] = None,
1038
- security_opt: Optional[list[str]] = None,
1039
- network: Optional[str] = None,
1040
- dns: Optional[str] = None,
1041
- additional_flags: Optional[str] = None,
1042
- workdir: Optional[str] = None,
1043
- labels: Optional[dict[str, str]] = None,
1044
- platform: Optional[DockerPlatform] = None,
1045
- privileged: Optional[bool] = None,
1046
- ulimits: Optional[list[Ulimit]] = None,
1047
- init: Optional[bool] = None,
1048
- log_config: Optional[LogConfig] = None,
1024
+ command: list[str] | str | None = None,
1025
+ volumes: VolumeMappings | list[SimpleVolumeBind] | None = None,
1026
+ ports: PortMappings | None = None,
1027
+ exposed_ports: list[str] | None = None,
1028
+ env_vars: dict[str, str] | None = None,
1029
+ user: str | None = None,
1030
+ cap_add: list[str] | None = None,
1031
+ cap_drop: list[str] | None = None,
1032
+ security_opt: list[str] | None = None,
1033
+ network: str | None = None,
1034
+ dns: str | None = None,
1035
+ additional_flags: str | None = None,
1036
+ workdir: str | None = None,
1037
+ labels: dict[str, str] | None = None,
1038
+ platform: DockerPlatform | None = None,
1039
+ privileged: bool | None = None,
1040
+ ulimits: list[Ulimit] | None = None,
1041
+ init: bool | None = None,
1042
+ log_config: LogConfig | None = None,
1049
1043
  ) -> tuple[bytes, bytes]:
1050
1044
  """Creates and runs a given docker container
1051
1045
 
@@ -1090,13 +1084,13 @@ class ContainerClient(metaclass=ABCMeta):
1090
1084
  def exec_in_container(
1091
1085
  self,
1092
1086
  container_name_or_id: str,
1093
- command: Union[list[str], str],
1087
+ command: list[str] | str,
1094
1088
  interactive: bool = False,
1095
1089
  detach: bool = False,
1096
- env_vars: Optional[dict[str, Optional[str]]] = None,
1097
- stdin: Optional[bytes] = None,
1098
- user: Optional[str] = None,
1099
- workdir: Optional[str] = None,
1090
+ env_vars: dict[str, str | None] | None = None,
1091
+ stdin: bytes | None = None,
1092
+ user: str | None = None,
1093
+ workdir: str | None = None,
1100
1094
  ) -> tuple[bytes, bytes]:
1101
1095
  """Execute a given command in a container
1102
1096
 
@@ -1110,7 +1104,7 @@ class ContainerClient(metaclass=ABCMeta):
1110
1104
  stdin: bytes = None,
1111
1105
  interactive: bool = False,
1112
1106
  attach: bool = False,
1113
- flags: Optional[str] = None,
1107
+ flags: str | None = None,
1114
1108
  ) -> tuple[bytes, bytes]:
1115
1109
  """Start a given, already created container
1116
1110
 
@@ -1124,7 +1118,7 @@ class ContainerClient(metaclass=ABCMeta):
1124
1118
  """
1125
1119
 
1126
1120
  @abstractmethod
1127
- def login(self, username: str, password: str, registry: Optional[str] = None) -> None:
1121
+ def login(self, username: str, password: str, registry: str | None = None) -> None:
1128
1122
  """
1129
1123
  Login into an OCI registry
1130
1124
 
@@ -1133,18 +1127,23 @@ class ContainerClient(metaclass=ABCMeta):
1133
1127
  :param registry: Registry url
1134
1128
  """
1135
1129
 
1130
+ def __get_container_names(self, return_all: bool) -> list[str]:
1131
+ result = self.list_containers(all=return_all)
1132
+ result = [container["name"] for container in result]
1133
+ return result
1134
+
1136
1135
 
1137
1136
  class Util:
1138
1137
  MAX_ENV_ARGS_LENGTH = 20000
1139
1138
 
1140
1139
  @staticmethod
1141
- def format_env_vars(key: str, value: Optional[str]):
1140
+ def format_env_vars(key: str, value: str | None):
1142
1141
  if value is None:
1143
1142
  return key
1144
1143
  return f"{key}={value}"
1145
1144
 
1146
1145
  @classmethod
1147
- def create_env_vars_file_flag(cls, env_vars: dict) -> tuple[list[str], Optional[str]]:
1146
+ def create_env_vars_file_flag(cls, env_vars: dict) -> tuple[list[str], str | None]:
1148
1147
  if not env_vars:
1149
1148
  return [], None
1150
1149
  result = []
@@ -1277,16 +1276,16 @@ class Util:
1277
1276
  @staticmethod
1278
1277
  def parse_additional_flags(
1279
1278
  additional_flags: str,
1280
- env_vars: Optional[dict[str, str]] = None,
1281
- labels: Optional[dict[str, str]] = None,
1282
- volumes: Optional[list[SimpleVolumeBind]] = None,
1283
- network: Optional[str] = None,
1284
- platform: Optional[DockerPlatform] = None,
1285
- ports: Optional[PortMappings] = None,
1286
- privileged: Optional[bool] = None,
1287
- user: Optional[str] = None,
1288
- ulimits: Optional[list[Ulimit]] = None,
1289
- dns: Optional[Union[str, list[str]]] = None,
1279
+ env_vars: dict[str, str] | None = None,
1280
+ labels: dict[str, str] | None = None,
1281
+ volumes: list[SimpleVolumeBind] | None = None,
1282
+ network: str | None = None,
1283
+ platform: DockerPlatform | None = None,
1284
+ ports: PortMappings | None = None,
1285
+ privileged: bool | None = None,
1286
+ user: str | None = None,
1287
+ ulimits: list[Ulimit] | None = None,
1288
+ dns: str | list[str] | None = None,
1290
1289
  ) -> DockerRunFlags:
1291
1290
  """Parses additional CLI-formatted Docker flags, which could overwrite provided defaults.
1292
1291
  :param additional_flags: String which contains the flag definitions inspired by the Docker CLI reference:
@@ -1507,7 +1506,7 @@ class Util:
1507
1506
 
1508
1507
  @staticmethod
1509
1508
  def convert_mount_list_to_dict(
1510
- volumes: Union[list[SimpleVolumeBind], VolumeMappings],
1509
+ volumes: list[SimpleVolumeBind] | VolumeMappings,
1511
1510
  ) -> dict[str, dict[str, str]]:
1512
1511
  """Converts a List of (host_path, container_path) tuples to a Dict suitable as volume argument for docker sdk"""
1513
1512