zenml-nightly 0.70.0.dev20241202__py3-none-any.whl → 0.70.0.dev20241204__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 (35) hide show
  1. zenml/VERSION +1 -1
  2. zenml/cli/__init__.py +4 -4
  3. zenml/cli/base.py +1 -1
  4. zenml/cli/pipeline.py +48 -79
  5. zenml/config/secret_reference_mixin.py +1 -1
  6. zenml/image_builders/base_image_builder.py +5 -2
  7. zenml/image_builders/build_context.py +7 -16
  8. zenml/integrations/aws/__init__.py +3 -0
  9. zenml/integrations/aws/flavors/__init__.py +6 -0
  10. zenml/integrations/aws/flavors/aws_image_builder_flavor.py +146 -0
  11. zenml/integrations/aws/image_builders/__init__.py +20 -0
  12. zenml/integrations/aws/image_builders/aws_image_builder.py +307 -0
  13. zenml/integrations/gcp/orchestrators/vertex_orchestrator.py +1 -1
  14. zenml/integrations/kaniko/image_builders/kaniko_image_builder.py +2 -1
  15. zenml/integrations/kubernetes/flavors/kubernetes_orchestrator_flavor.py +11 -0
  16. zenml/integrations/lightning/flavors/lightning_orchestrator_flavor.py +11 -0
  17. zenml/integrations/neptune/experiment_trackers/neptune_experiment_tracker.py +7 -5
  18. zenml/integrations/neptune/experiment_trackers/run_state.py +69 -53
  19. zenml/integrations/registry.py +2 -2
  20. zenml/integrations/skypilot/flavors/skypilot_orchestrator_base_vm_config.py +12 -0
  21. zenml/materializers/built_in_materializer.py +1 -1
  22. zenml/orchestrators/base_orchestrator.py +13 -1
  23. zenml/orchestrators/output_utils.py +5 -1
  24. zenml/service_connectors/service_connector_utils.py +3 -9
  25. zenml/stack/stack_component.py +1 -1
  26. zenml/stack_deployments/aws_stack_deployment.py +22 -0
  27. zenml/utils/archivable.py +65 -36
  28. zenml/utils/code_utils.py +8 -4
  29. zenml/utils/docker_utils.py +9 -0
  30. zenml/zen_stores/rest_zen_store.py +1 -1
  31. {zenml_nightly-0.70.0.dev20241202.dist-info → zenml_nightly-0.70.0.dev20241204.dist-info}/METADATA +1 -1
  32. {zenml_nightly-0.70.0.dev20241202.dist-info → zenml_nightly-0.70.0.dev20241204.dist-info}/RECORD +35 -32
  33. {zenml_nightly-0.70.0.dev20241202.dist-info → zenml_nightly-0.70.0.dev20241204.dist-info}/LICENSE +0 -0
  34. {zenml_nightly-0.70.0.dev20241202.dist-info → zenml_nightly-0.70.0.dev20241204.dist-info}/WHEEL +0 -0
  35. {zenml_nightly-0.70.0.dev20241202.dist-info → zenml_nightly-0.70.0.dev20241204.dist-info}/entry_points.txt +0 -0
zenml/VERSION CHANGED
@@ -1 +1 @@
1
- 0.70.0.dev20241202
1
+ 0.70.0.dev20241204
zenml/cli/__init__.py CHANGED
@@ -1987,7 +1987,7 @@ Secrets management
1987
1987
  ------------------
1988
1988
 
1989
1989
  ZenML offers a way to [securely store secrets associated with your other
1990
- stack components and infrastructure](https://docs.zenml.io/getting-started/deploying-zenml/manage-the-deployed-services/secret-management).
1990
+ stack components and infrastructure](https://docs.zenml.io/getting-started/deploying-zenml/secret-management).
1991
1991
  A ZenML Secret is a collection or grouping of key-value pairs stored by the
1992
1992
  ZenML secrets store. ZenML Secrets are identified by a unique name which
1993
1993
  allows you to fetch or reference them in your pipelines and stacks.
@@ -2083,7 +2083,7 @@ challenge in configuring uninterrupted, secure access to infrastructure
2083
2083
  resources. In ZenML, Service Connectors streamline this process by abstracting
2084
2084
  away the complexity of authentication and help you connect your stack to your
2085
2085
  resources. You can find the full docs on the ZenML service connectors
2086
- [here](https://docs.zenml.io/how-to/auth-management).
2086
+ [here](https://docs.zenml.io/how-to/infrastructure-deployment/auth-management).
2087
2087
 
2088
2088
  The ZenML CLI features a variety of commands to help you manage your service
2089
2089
  connectors. First of all, to explore all the types of service connectors
@@ -2113,7 +2113,7 @@ zenml service-connector register SERVICE_CONNECTOR_NAME \
2113
2113
  ```
2114
2114
 
2115
2115
  For more details on how to create a service connector, please refer to our
2116
- [docs](https://docs.zenml.io/how-to/auth-management).
2116
+ [docs](https://docs.zenml.io/how-to/infrastructure-deployment/auth-management).
2117
2117
 
2118
2118
  To check if your service connector is registered properly, you can `verify` it.
2119
2119
  By doing this, you can both check if it is configured correctly and also, you
@@ -2367,7 +2367,7 @@ defining the pipeline is not in your current directory, the module path consists
2367
2367
  of the full path to the file, separated by dots, e.g.
2368
2368
  `some_directory.some_file.my_pipeline`.
2369
2369
 
2370
- To [build Docker images for your pipeline](https://docs.zenml.io/how-to/customize-docker-builds)
2370
+ To [build Docker images for your pipeline](https://docs.zenml.io/how-to/infrastructure-deployment/customize-docker-builds)
2371
2371
  without actually running the pipeline, use:
2372
2372
 
2373
2373
  ```bash
zenml/cli/base.py CHANGED
@@ -264,7 +264,7 @@ def init(
264
264
  f"will only take effect when you're running ZenML from the initialized "
265
265
  f"repository root, or from a subdirectory. For more information on "
266
266
  f"repositories and configurations, please visit "
267
- f"https://docs.zenml.io/user-guide/starter-guide/understand-stacks."
267
+ f"https://docs.zenml.io/user-guide/production-guide/understand-stacks."
268
268
  )
269
269
 
270
270
 
zenml/cli/pipeline.py CHANGED
@@ -40,6 +40,35 @@ from zenml.utils.yaml_utils import write_yaml
40
40
  logger = get_logger(__name__)
41
41
 
42
42
 
43
+ def _import_pipeline(source: str) -> Pipeline:
44
+ """Import a pipeline.
45
+
46
+ Args:
47
+ source: The pipeline source.
48
+
49
+ Returns:
50
+ The pipeline.
51
+ """
52
+ try:
53
+ pipeline_instance = source_utils.load(source)
54
+ except ModuleNotFoundError as e:
55
+ source_root = source_utils.get_source_root()
56
+ cli_utils.error(
57
+ f"Unable to import module `{e.name}`. Make sure the source path is "
58
+ f"relative to your source root `{source_root}`."
59
+ )
60
+ except AttributeError as e:
61
+ cli_utils.error("Unable to load attribute from module: " + str(e))
62
+
63
+ if not isinstance(pipeline_instance, Pipeline):
64
+ cli_utils.error(
65
+ f"The given source path `{source}` does not resolve to a pipeline "
66
+ "object."
67
+ )
68
+
69
+ return pipeline_instance
70
+
71
+
43
72
  @cli.group(cls=TagGroup, tag=CliCategories.MANAGEMENT_TOOLS)
44
73
  def pipeline() -> None:
45
74
  """Interact with pipelines, runs and schedules."""
@@ -85,22 +114,7 @@ def register_pipeline(
85
114
  "source code root."
86
115
  )
87
116
 
88
- try:
89
- pipeline_instance = source_utils.load(source)
90
- except ModuleNotFoundError as e:
91
- source_root = source_utils.get_source_root()
92
- cli_utils.error(
93
- f"Unable to import module `{e.name}`. Make sure the source path is "
94
- f"relative to your source root `{source_root}`."
95
- )
96
- except AttributeError as e:
97
- cli_utils.error("Unable to load attribute from module: " + str(e))
98
-
99
- if not isinstance(pipeline_instance, Pipeline):
100
- cli_utils.error(
101
- f"The given source path `{source}` does not resolve to a pipeline "
102
- "object."
103
- )
117
+ pipeline_instance = _import_pipeline(source=source)
104
118
 
105
119
  parameters: Dict[str, Any] = {}
106
120
  if parameters_path:
@@ -176,24 +190,9 @@ def build_pipeline(
176
190
  "your source code root."
177
191
  )
178
192
 
179
- try:
180
- pipeline_instance = source_utils.load(source)
181
- except ModuleNotFoundError as e:
182
- source_root = source_utils.get_source_root()
183
- cli_utils.error(
184
- f"Unable to import module `{e.name}`. Make sure the source path is "
185
- f"relative to your source root `{source_root}`."
186
- )
187
- except AttributeError as e:
188
- cli_utils.error("Unable to load attribute from module: " + str(e))
189
-
190
- if not isinstance(pipeline_instance, Pipeline):
191
- cli_utils.error(
192
- f"The given source path `{source}` does not resolve to a pipeline "
193
- "object."
194
- )
195
-
196
193
  with cli_utils.temporary_active_stack(stack_name_or_id=stack_name_or_id):
194
+ pipeline_instance = _import_pipeline(source=source)
195
+
197
196
  pipeline_instance = pipeline_instance.with_options(
198
197
  config_path=config_path
199
198
  )
@@ -277,36 +276,21 @@ def run_pipeline(
277
276
  "your source code root."
278
277
  )
279
278
 
280
- try:
281
- pipeline_instance = source_utils.load(source)
282
- except ModuleNotFoundError as e:
283
- source_root = source_utils.get_source_root()
284
- cli_utils.error(
285
- f"Unable to import module `{e.name}`. Make sure the source path is "
286
- f"relative to your source root `{source_root}`."
287
- )
288
- except AttributeError as e:
289
- cli_utils.error("Unable to load attribute from module: " + str(e))
290
-
291
- if not isinstance(pipeline_instance, Pipeline):
292
- cli_utils.error(
293
- f"The given source path `{source}` does not resolve to a pipeline "
294
- "object."
295
- )
296
-
297
- build: Union[str, PipelineBuildBase, None] = None
298
- if build_path_or_id:
299
- if uuid_utils.is_valid_uuid(build_path_or_id):
300
- build = build_path_or_id
301
- elif os.path.exists(build_path_or_id):
302
- build = PipelineBuildBase.from_yaml(build_path_or_id)
303
- else:
304
- cli_utils.error(
305
- f"The specified build {build_path_or_id} is not a valid UUID "
306
- "or file path."
307
- )
308
-
309
279
  with cli_utils.temporary_active_stack(stack_name_or_id=stack_name_or_id):
280
+ pipeline_instance = _import_pipeline(source=source)
281
+
282
+ build: Union[str, PipelineBuildBase, None] = None
283
+ if build_path_or_id:
284
+ if uuid_utils.is_valid_uuid(build_path_or_id):
285
+ build = build_path_or_id
286
+ elif os.path.exists(build_path_or_id):
287
+ build = PipelineBuildBase.from_yaml(build_path_or_id)
288
+ else:
289
+ cli_utils.error(
290
+ f"The specified build {build_path_or_id} is not a valid UUID "
291
+ "or file path."
292
+ )
293
+
310
294
  pipeline_instance = pipeline_instance.with_options(
311
295
  config_path=config_path,
312
296
  build=build,
@@ -369,24 +353,9 @@ def create_run_template(
369
353
  "init` at your source code root."
370
354
  )
371
355
 
372
- try:
373
- pipeline_instance = source_utils.load(source)
374
- except ModuleNotFoundError as e:
375
- source_root = source_utils.get_source_root()
376
- cli_utils.error(
377
- f"Unable to import module `{e.name}`. Make sure the source path is "
378
- f"relative to your source root `{source_root}`."
379
- )
380
- except AttributeError as e:
381
- cli_utils.error("Unable to load attribute from module: " + str(e))
382
-
383
- if not isinstance(pipeline_instance, Pipeline):
384
- cli_utils.error(
385
- f"The given source path `{source}` does not resolve to a pipeline "
386
- "object."
387
- )
388
-
389
356
  with cli_utils.temporary_active_stack(stack_name_or_id=stack_name_or_id):
357
+ pipeline_instance = _import_pipeline(source=source)
358
+
390
359
  pipeline_instance = pipeline_instance.with_options(
391
360
  config_path=config_path
392
361
  )
@@ -66,7 +66,7 @@ class SecretReferenceMixin(BaseModel):
66
66
  "but future versions of ZenML will require you to pass "
67
67
  "in sensitive information as secrets. Check out the "
68
68
  "documentation on how to configure values with secrets "
69
- "here: https://docs.zenml.io/getting-started/deploying-zenml/manage-the-deployed-services/secret-management"
69
+ "here: https://docs.zenml.io/getting-started/deploying-zenml/secret-management"
70
70
  )
71
71
  continue
72
72
 
@@ -25,6 +25,7 @@ from zenml.io import fileio
25
25
  from zenml.logger import get_logger
26
26
  from zenml.stack import Flavor, StackComponent
27
27
  from zenml.stack.stack_component import StackComponentConfig
28
+ from zenml.utils.archivable import ArchiveType
28
29
 
29
30
  if TYPE_CHECKING:
30
31
  from zenml.container_registries import BaseContainerRegistry
@@ -100,6 +101,7 @@ class BaseImageBuilder(StackComponent, ABC):
100
101
  def _upload_build_context(
101
102
  build_context: "BuildContext",
102
103
  parent_path_directory_name: str,
104
+ archive_type: ArchiveType = ArchiveType.TAR_GZ,
103
105
  ) -> str:
104
106
  """Uploads a Docker image build context to a remote location.
105
107
 
@@ -109,6 +111,7 @@ class BaseImageBuilder(StackComponent, ABC):
109
111
  the build context to. It will be appended to the artifact
110
112
  store path to create the parent path where the build context
111
113
  will be uploaded to.
114
+ archive_type: The type of archive to create.
112
115
 
113
116
  Returns:
114
117
  The path to the uploaded build context.
@@ -119,7 +122,7 @@ class BaseImageBuilder(StackComponent, ABC):
119
122
 
120
123
  hash_ = hashlib.sha1() # nosec
121
124
  with tempfile.NamedTemporaryFile(mode="w+b", delete=False) as f:
122
- build_context.write_archive(f, use_gzip=True)
125
+ build_context.write_archive(f, archive_type)
123
126
 
124
127
  while True:
125
128
  data = f.read(64 * 1024)
@@ -127,7 +130,7 @@ class BaseImageBuilder(StackComponent, ABC):
127
130
  break
128
131
  hash_.update(data)
129
132
 
130
- filename = f"{hash_.hexdigest()}.tar.gz"
133
+ filename = f"{hash_.hexdigest()}.{archive_type.value}"
131
134
  filepath = f"{parent_path}/{filename}"
132
135
  if not fileio.exists(filepath):
133
136
  logger.info("Uploading build context to `%s`.", filepath)
@@ -20,7 +20,7 @@ from zenml.constants import REPOSITORY_DIRECTORY_NAME
20
20
  from zenml.io import fileio
21
21
  from zenml.logger import get_logger
22
22
  from zenml.utils import io_utils, string_utils
23
- from zenml.utils.archivable import Archivable
23
+ from zenml.utils.archivable import Archivable, ArchiveType
24
24
 
25
25
  logger = get_logger(__name__)
26
26
 
@@ -69,28 +69,19 @@ class BuildContext(Archivable):
69
69
  return None
70
70
 
71
71
  def write_archive(
72
- self, output_file: IO[bytes], use_gzip: bool = True
72
+ self,
73
+ output_file: IO[bytes],
74
+ archive_type: ArchiveType = ArchiveType.TAR_GZ,
73
75
  ) -> None:
74
76
  """Writes an archive of the build context to the given file.
75
77
 
76
78
  Args:
77
79
  output_file: The file to write the archive to.
78
- use_gzip: Whether to use `gzip` to compress the file.
80
+ archive_type: The type of archive to create.
79
81
  """
80
- from docker.utils import build as docker_build_utils
81
-
82
- files = self.get_files()
83
- extra_files = self.get_extra_files()
84
-
85
- context_archive = docker_build_utils.create_archive(
86
- fileobj=output_file,
87
- root=self._root,
88
- files=sorted(files.keys()),
89
- gzip=use_gzip,
90
- extra_files=list(extra_files.items()),
91
- )
82
+ super().write_archive(output_file, archive_type)
92
83
 
93
- build_context_size = os.path.getsize(context_archive.name)
84
+ build_context_size = os.path.getsize(output_file.name)
94
85
  if (
95
86
  self._root
96
87
  and build_context_size > 50 * 1024 * 1024
@@ -33,6 +33,7 @@ AWS_SAGEMAKER_ORCHESTRATOR_FLAVOR = "sagemaker"
33
33
  AWS_CONNECTOR_TYPE = "aws"
34
34
  AWS_RESOURCE_TYPE = "aws-generic"
35
35
  S3_RESOURCE_TYPE = "s3-bucket"
36
+ AWS_IMAGE_BUILDER_FLAVOR = "aws"
36
37
 
37
38
  class AWSIntegration(Integration):
38
39
  """Definition of AWS integration for ZenML."""
@@ -59,12 +60,14 @@ class AWSIntegration(Integration):
59
60
  """
60
61
  from zenml.integrations.aws.flavors import (
61
62
  AWSContainerRegistryFlavor,
63
+ AWSImageBuilderFlavor,
62
64
  SagemakerOrchestratorFlavor,
63
65
  SagemakerStepOperatorFlavor,
64
66
  )
65
67
 
66
68
  return [
67
69
  AWSContainerRegistryFlavor,
70
+ AWSImageBuilderFlavor,
68
71
  SagemakerStepOperatorFlavor,
69
72
  SagemakerOrchestratorFlavor,
70
73
  ]
@@ -17,6 +17,10 @@ from zenml.integrations.aws.flavors.aws_container_registry_flavor import (
17
17
  AWSContainerRegistryConfig,
18
18
  AWSContainerRegistryFlavor,
19
19
  )
20
+ from zenml.integrations.aws.flavors.aws_image_builder_flavor import (
21
+ AWSImageBuilderConfig,
22
+ AWSImageBuilderFlavor,
23
+ )
20
24
  from zenml.integrations.aws.flavors.sagemaker_orchestrator_flavor import (
21
25
  SagemakerOrchestratorConfig,
22
26
  SagemakerOrchestratorFlavor,
@@ -29,6 +33,8 @@ from zenml.integrations.aws.flavors.sagemaker_step_operator_flavor import (
29
33
  __all__ = [
30
34
  "AWSContainerRegistryFlavor",
31
35
  "AWSContainerRegistryConfig",
36
+ "AWSImageBuilderConfig",
37
+ "AWSImageBuilderFlavor",
32
38
  "SagemakerStepOperatorFlavor",
33
39
  "SagemakerStepOperatorConfig",
34
40
  "SagemakerOrchestratorFlavor",
@@ -0,0 +1,146 @@
1
+ # Copyright (c) ZenML GmbH 2024. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """AWS Code Build image builder flavor."""
15
+
16
+ from typing import TYPE_CHECKING, Dict, Optional, Type
17
+
18
+ from zenml.image_builders import BaseImageBuilderConfig, BaseImageBuilderFlavor
19
+ from zenml.integrations.aws import (
20
+ AWS_CONNECTOR_TYPE,
21
+ AWS_IMAGE_BUILDER_FLAVOR,
22
+ AWS_RESOURCE_TYPE,
23
+ )
24
+ from zenml.models import ServiceConnectorRequirements
25
+
26
+ if TYPE_CHECKING:
27
+ from zenml.integrations.aws.image_builders import AWSImageBuilder
28
+
29
+
30
+ DEFAULT_CLOUDBUILD_IMAGE = "bentolor/docker-dind-awscli"
31
+ DEFAULT_CLOUDBUILD_COMPUTE_TYPE = "BUILD_GENERAL1_SMALL"
32
+
33
+
34
+ class AWSImageBuilderConfig(BaseImageBuilderConfig):
35
+ """AWS Code Build image builder configuration.
36
+
37
+ Attributes:
38
+ code_build_project: The name of an existing AWS CodeBuild project to use
39
+ to build the image. The CodeBuild project must exist in the AWS
40
+ account and region inferred from the AWS service connector
41
+ credentials or implicitly from the local AWS config.
42
+ build_image: The Docker image to use for the AWS CodeBuild environment.
43
+ The image must have Docker installed and be able to run Docker
44
+ commands. The default image is bentolor/docker-dind-awscli.
45
+ This can be customized to use a mirror, if needed, in case the
46
+ Dockerhub image is not accessible or rate-limited.
47
+ custom_env_vars: Custom environment variables to pass to the AWS
48
+ CodeBuild build.
49
+ compute_type: The compute type to use for the AWS CodeBuild build.
50
+ The default is BUILD_GENERAL1_SMALL.
51
+ implicit_container_registry_auth: Whether to use implicit authentication
52
+ to authenticate the AWS Code Build build to the container registry
53
+ when pushing container images. If set to False, the container
54
+ registry credentials must be explicitly configured for the container
55
+ registry stack component or the container registry stack component
56
+ must be linked to a service connector.
57
+ NOTE: When implicit_container_registry_auth is set to False, the
58
+ container registry credentials will be passed to the AWS Code Build
59
+ build as environment variables. This is not recommended for
60
+ production use unless your service connector is configured to
61
+ generate short-lived credentials.
62
+ """
63
+
64
+ code_build_project: str
65
+ build_image: str = DEFAULT_CLOUDBUILD_IMAGE
66
+ custom_env_vars: Optional[Dict[str, str]] = None
67
+ compute_type: str = DEFAULT_CLOUDBUILD_COMPUTE_TYPE
68
+ implicit_container_registry_auth: bool = True
69
+
70
+
71
+ class AWSImageBuilderFlavor(BaseImageBuilderFlavor):
72
+ """AWS Code Build image builder flavor."""
73
+
74
+ @property
75
+ def name(self) -> str:
76
+ """The flavor name.
77
+
78
+ Returns:
79
+ The name of the flavor.
80
+ """
81
+ return AWS_IMAGE_BUILDER_FLAVOR
82
+
83
+ @property
84
+ def service_connector_requirements(
85
+ self,
86
+ ) -> Optional[ServiceConnectorRequirements]:
87
+ """Service connector resource requirements for service connectors.
88
+
89
+ Specifies resource requirements that are used to filter the available
90
+ service connector types that are compatible with this flavor.
91
+
92
+ Returns:
93
+ Requirements for compatible service connectors, if a service
94
+ connector is required for this flavor.
95
+ """
96
+ return ServiceConnectorRequirements(
97
+ connector_type=AWS_CONNECTOR_TYPE,
98
+ resource_type=AWS_RESOURCE_TYPE,
99
+ )
100
+
101
+ @property
102
+ def docs_url(self) -> Optional[str]:
103
+ """A url to point at docs explaining this flavor.
104
+
105
+ Returns:
106
+ A flavor docs url.
107
+ """
108
+ return self.generate_default_docs_url()
109
+
110
+ @property
111
+ def sdk_docs_url(self) -> Optional[str]:
112
+ """A url to point at SDK docs explaining this flavor.
113
+
114
+ Returns:
115
+ A flavor SDK docs url.
116
+ """
117
+ return self.generate_default_sdk_docs_url()
118
+
119
+ @property
120
+ def logo_url(self) -> str:
121
+ """A url to represent the flavor in the dashboard.
122
+
123
+ Returns:
124
+ The flavor logo.
125
+ """
126
+ return "https://public-flavor-logos.s3.eu-central-1.amazonaws.com/image_builder/aws.png"
127
+
128
+ @property
129
+ def config_class(self) -> Type[BaseImageBuilderConfig]:
130
+ """The config class.
131
+
132
+ Returns:
133
+ The config class.
134
+ """
135
+ return AWSImageBuilderConfig
136
+
137
+ @property
138
+ def implementation_class(self) -> Type["AWSImageBuilder"]:
139
+ """Implementation class.
140
+
141
+ Returns:
142
+ The implementation class.
143
+ """
144
+ from zenml.integrations.aws.image_builders import AWSImageBuilder
145
+
146
+ return AWSImageBuilder
@@ -0,0 +1,20 @@
1
+ # Copyright (c) ZenML GmbH 2024. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at:
6
+ #
7
+ # https://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12
+ # or implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+ """Initialization for the AWS image builder."""
15
+
16
+ from zenml.integrations.aws.image_builders.aws_image_builder import (
17
+ AWSImageBuilder,
18
+ )
19
+
20
+ __all__ = ["AWSImageBuilder"]