flyte 0.0.1b0__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.
Potentially problematic release.
This version of flyte might be problematic. Click here for more details.
- flyte/__init__.py +62 -0
- flyte/_api_commons.py +3 -0
- flyte/_bin/__init__.py +0 -0
- flyte/_bin/runtime.py +126 -0
- flyte/_build.py +25 -0
- flyte/_cache/__init__.py +12 -0
- flyte/_cache/cache.py +146 -0
- flyte/_cache/defaults.py +9 -0
- flyte/_cache/policy_function_body.py +42 -0
- flyte/_cli/__init__.py +0 -0
- flyte/_cli/_common.py +287 -0
- flyte/_cli/_create.py +42 -0
- flyte/_cli/_delete.py +23 -0
- flyte/_cli/_deploy.py +140 -0
- flyte/_cli/_get.py +235 -0
- flyte/_cli/_run.py +152 -0
- flyte/_cli/main.py +72 -0
- flyte/_code_bundle/__init__.py +8 -0
- flyte/_code_bundle/_ignore.py +113 -0
- flyte/_code_bundle/_packaging.py +187 -0
- flyte/_code_bundle/_utils.py +339 -0
- flyte/_code_bundle/bundle.py +178 -0
- flyte/_context.py +146 -0
- flyte/_datastructures.py +342 -0
- flyte/_deploy.py +202 -0
- flyte/_doc.py +29 -0
- flyte/_docstring.py +32 -0
- flyte/_environment.py +43 -0
- flyte/_group.py +31 -0
- flyte/_hash.py +23 -0
- flyte/_image.py +760 -0
- flyte/_initialize.py +634 -0
- flyte/_interface.py +84 -0
- flyte/_internal/__init__.py +3 -0
- flyte/_internal/controllers/__init__.py +115 -0
- flyte/_internal/controllers/_local_controller.py +118 -0
- flyte/_internal/controllers/_trace.py +40 -0
- flyte/_internal/controllers/pbhash.py +39 -0
- flyte/_internal/controllers/remote/__init__.py +40 -0
- flyte/_internal/controllers/remote/_action.py +141 -0
- flyte/_internal/controllers/remote/_client.py +43 -0
- flyte/_internal/controllers/remote/_controller.py +361 -0
- flyte/_internal/controllers/remote/_core.py +402 -0
- flyte/_internal/controllers/remote/_informer.py +361 -0
- flyte/_internal/controllers/remote/_service_protocol.py +50 -0
- flyte/_internal/imagebuild/__init__.py +11 -0
- flyte/_internal/imagebuild/docker_builder.py +416 -0
- flyte/_internal/imagebuild/image_builder.py +241 -0
- flyte/_internal/imagebuild/remote_builder.py +0 -0
- flyte/_internal/resolvers/__init__.py +0 -0
- flyte/_internal/resolvers/_task_module.py +54 -0
- flyte/_internal/resolvers/common.py +31 -0
- flyte/_internal/resolvers/default.py +28 -0
- flyte/_internal/runtime/__init__.py +0 -0
- flyte/_internal/runtime/convert.py +199 -0
- flyte/_internal/runtime/entrypoints.py +135 -0
- flyte/_internal/runtime/io.py +136 -0
- flyte/_internal/runtime/resources_serde.py +138 -0
- flyte/_internal/runtime/task_serde.py +210 -0
- flyte/_internal/runtime/taskrunner.py +190 -0
- flyte/_internal/runtime/types_serde.py +54 -0
- flyte/_logging.py +124 -0
- flyte/_protos/__init__.py +0 -0
- flyte/_protos/common/authorization_pb2.py +66 -0
- flyte/_protos/common/authorization_pb2.pyi +108 -0
- flyte/_protos/common/authorization_pb2_grpc.py +4 -0
- flyte/_protos/common/identifier_pb2.py +71 -0
- flyte/_protos/common/identifier_pb2.pyi +82 -0
- flyte/_protos/common/identifier_pb2_grpc.py +4 -0
- flyte/_protos/common/identity_pb2.py +48 -0
- flyte/_protos/common/identity_pb2.pyi +72 -0
- flyte/_protos/common/identity_pb2_grpc.py +4 -0
- flyte/_protos/common/list_pb2.py +36 -0
- flyte/_protos/common/list_pb2.pyi +69 -0
- flyte/_protos/common/list_pb2_grpc.py +4 -0
- flyte/_protos/common/policy_pb2.py +37 -0
- flyte/_protos/common/policy_pb2.pyi +27 -0
- flyte/_protos/common/policy_pb2_grpc.py +4 -0
- flyte/_protos/common/role_pb2.py +37 -0
- flyte/_protos/common/role_pb2.pyi +53 -0
- flyte/_protos/common/role_pb2_grpc.py +4 -0
- flyte/_protos/common/runtime_version_pb2.py +28 -0
- flyte/_protos/common/runtime_version_pb2.pyi +24 -0
- flyte/_protos/common/runtime_version_pb2_grpc.py +4 -0
- flyte/_protos/logs/dataplane/payload_pb2.py +96 -0
- flyte/_protos/logs/dataplane/payload_pb2.pyi +168 -0
- flyte/_protos/logs/dataplane/payload_pb2_grpc.py +4 -0
- flyte/_protos/secret/definition_pb2.py +49 -0
- flyte/_protos/secret/definition_pb2.pyi +93 -0
- flyte/_protos/secret/definition_pb2_grpc.py +4 -0
- flyte/_protos/secret/payload_pb2.py +62 -0
- flyte/_protos/secret/payload_pb2.pyi +94 -0
- flyte/_protos/secret/payload_pb2_grpc.py +4 -0
- flyte/_protos/secret/secret_pb2.py +38 -0
- flyte/_protos/secret/secret_pb2.pyi +6 -0
- flyte/_protos/secret/secret_pb2_grpc.py +198 -0
- flyte/_protos/secret/secret_pb2_grpc_grpc.py +198 -0
- flyte/_protos/validate/validate/validate_pb2.py +76 -0
- flyte/_protos/workflow/node_execution_service_pb2.py +26 -0
- flyte/_protos/workflow/node_execution_service_pb2.pyi +4 -0
- flyte/_protos/workflow/node_execution_service_pb2_grpc.py +32 -0
- flyte/_protos/workflow/queue_service_pb2.py +106 -0
- flyte/_protos/workflow/queue_service_pb2.pyi +141 -0
- flyte/_protos/workflow/queue_service_pb2_grpc.py +172 -0
- flyte/_protos/workflow/run_definition_pb2.py +128 -0
- flyte/_protos/workflow/run_definition_pb2.pyi +310 -0
- flyte/_protos/workflow/run_definition_pb2_grpc.py +4 -0
- flyte/_protos/workflow/run_logs_service_pb2.py +41 -0
- flyte/_protos/workflow/run_logs_service_pb2.pyi +28 -0
- flyte/_protos/workflow/run_logs_service_pb2_grpc.py +69 -0
- flyte/_protos/workflow/run_service_pb2.py +133 -0
- flyte/_protos/workflow/run_service_pb2.pyi +175 -0
- flyte/_protos/workflow/run_service_pb2_grpc.py +412 -0
- flyte/_protos/workflow/state_service_pb2.py +58 -0
- flyte/_protos/workflow/state_service_pb2.pyi +71 -0
- flyte/_protos/workflow/state_service_pb2_grpc.py +138 -0
- flyte/_protos/workflow/task_definition_pb2.py +72 -0
- flyte/_protos/workflow/task_definition_pb2.pyi +65 -0
- flyte/_protos/workflow/task_definition_pb2_grpc.py +4 -0
- flyte/_protos/workflow/task_service_pb2.py +44 -0
- flyte/_protos/workflow/task_service_pb2.pyi +31 -0
- flyte/_protos/workflow/task_service_pb2_grpc.py +104 -0
- flyte/_resources.py +226 -0
- flyte/_retry.py +32 -0
- flyte/_reusable_environment.py +25 -0
- flyte/_run.py +411 -0
- flyte/_secret.py +61 -0
- flyte/_task.py +367 -0
- flyte/_task_environment.py +200 -0
- flyte/_timeout.py +47 -0
- flyte/_tools.py +27 -0
- flyte/_trace.py +128 -0
- flyte/_utils/__init__.py +20 -0
- flyte/_utils/asyn.py +119 -0
- flyte/_utils/coro_management.py +25 -0
- flyte/_utils/file_handling.py +72 -0
- flyte/_utils/helpers.py +108 -0
- flyte/_utils/lazy_module.py +54 -0
- flyte/_utils/uv_script_parser.py +49 -0
- flyte/_version.py +21 -0
- flyte/connectors/__init__.py +0 -0
- flyte/errors.py +143 -0
- flyte/extras/__init__.py +5 -0
- flyte/extras/_container.py +273 -0
- flyte/io/__init__.py +11 -0
- flyte/io/_dataframe.py +0 -0
- flyte/io/_dir.py +448 -0
- flyte/io/_file.py +468 -0
- flyte/io/pickle/__init__.py +0 -0
- flyte/io/pickle/transformer.py +117 -0
- flyte/io/structured_dataset/__init__.py +129 -0
- flyte/io/structured_dataset/basic_dfs.py +219 -0
- flyte/io/structured_dataset/structured_dataset.py +1061 -0
- flyte/py.typed +0 -0
- flyte/remote/__init__.py +25 -0
- flyte/remote/_client/__init__.py +0 -0
- flyte/remote/_client/_protocols.py +131 -0
- flyte/remote/_client/auth/__init__.py +12 -0
- flyte/remote/_client/auth/_authenticators/__init__.py +0 -0
- flyte/remote/_client/auth/_authenticators/base.py +397 -0
- flyte/remote/_client/auth/_authenticators/client_credentials.py +73 -0
- flyte/remote/_client/auth/_authenticators/device_code.py +118 -0
- flyte/remote/_client/auth/_authenticators/external_command.py +79 -0
- flyte/remote/_client/auth/_authenticators/factory.py +200 -0
- flyte/remote/_client/auth/_authenticators/pkce.py +516 -0
- flyte/remote/_client/auth/_channel.py +184 -0
- flyte/remote/_client/auth/_client_config.py +83 -0
- flyte/remote/_client/auth/_default_html.py +32 -0
- flyte/remote/_client/auth/_grpc_utils/__init__.py +0 -0
- flyte/remote/_client/auth/_grpc_utils/auth_interceptor.py +288 -0
- flyte/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +151 -0
- flyte/remote/_client/auth/_keyring.py +143 -0
- flyte/remote/_client/auth/_token_client.py +260 -0
- flyte/remote/_client/auth/errors.py +16 -0
- flyte/remote/_client/controlplane.py +95 -0
- flyte/remote/_console.py +18 -0
- flyte/remote/_data.py +155 -0
- flyte/remote/_logs.py +116 -0
- flyte/remote/_project.py +86 -0
- flyte/remote/_run.py +873 -0
- flyte/remote/_secret.py +132 -0
- flyte/remote/_task.py +227 -0
- flyte/report/__init__.py +3 -0
- flyte/report/_report.py +178 -0
- flyte/report/_template.html +124 -0
- flyte/storage/__init__.py +24 -0
- flyte/storage/_remote_fs.py +34 -0
- flyte/storage/_storage.py +251 -0
- flyte/storage/_utils.py +5 -0
- flyte/types/__init__.py +13 -0
- flyte/types/_interface.py +25 -0
- flyte/types/_renderer.py +162 -0
- flyte/types/_string_literals.py +120 -0
- flyte/types/_type_engine.py +2210 -0
- flyte/types/_utils.py +80 -0
- flyte-0.0.1b0.dist-info/METADATA +179 -0
- flyte-0.0.1b0.dist-info/RECORD +390 -0
- flyte-0.0.1b0.dist-info/WHEEL +5 -0
- flyte-0.0.1b0.dist-info/entry_points.txt +3 -0
- flyte-0.0.1b0.dist-info/top_level.txt +1 -0
- union/__init__.py +54 -0
- union/_api_commons.py +3 -0
- union/_bin/__init__.py +0 -0
- union/_bin/runtime.py +113 -0
- union/_build.py +25 -0
- union/_cache/__init__.py +12 -0
- union/_cache/cache.py +141 -0
- union/_cache/defaults.py +9 -0
- union/_cache/policy_function_body.py +42 -0
- union/_cli/__init__.py +0 -0
- union/_cli/_common.py +263 -0
- union/_cli/_create.py +40 -0
- union/_cli/_delete.py +23 -0
- union/_cli/_deploy.py +120 -0
- union/_cli/_get.py +162 -0
- union/_cli/_params.py +579 -0
- union/_cli/_run.py +150 -0
- union/_cli/main.py +72 -0
- union/_code_bundle/__init__.py +8 -0
- union/_code_bundle/_ignore.py +113 -0
- union/_code_bundle/_packaging.py +187 -0
- union/_code_bundle/_utils.py +342 -0
- union/_code_bundle/bundle.py +176 -0
- union/_context.py +146 -0
- union/_datastructures.py +295 -0
- union/_deploy.py +185 -0
- union/_doc.py +29 -0
- union/_docstring.py +26 -0
- union/_environment.py +43 -0
- union/_group.py +31 -0
- union/_hash.py +23 -0
- union/_image.py +760 -0
- union/_initialize.py +585 -0
- union/_interface.py +84 -0
- union/_internal/__init__.py +3 -0
- union/_internal/controllers/__init__.py +77 -0
- union/_internal/controllers/_local_controller.py +77 -0
- union/_internal/controllers/pbhash.py +39 -0
- union/_internal/controllers/remote/__init__.py +40 -0
- union/_internal/controllers/remote/_action.py +131 -0
- union/_internal/controllers/remote/_client.py +43 -0
- union/_internal/controllers/remote/_controller.py +169 -0
- union/_internal/controllers/remote/_core.py +341 -0
- union/_internal/controllers/remote/_informer.py +260 -0
- union/_internal/controllers/remote/_service_protocol.py +44 -0
- union/_internal/imagebuild/__init__.py +11 -0
- union/_internal/imagebuild/docker_builder.py +416 -0
- union/_internal/imagebuild/image_builder.py +243 -0
- union/_internal/imagebuild/remote_builder.py +0 -0
- union/_internal/resolvers/__init__.py +0 -0
- union/_internal/resolvers/_task_module.py +31 -0
- union/_internal/resolvers/common.py +24 -0
- union/_internal/resolvers/default.py +27 -0
- union/_internal/runtime/__init__.py +0 -0
- union/_internal/runtime/convert.py +163 -0
- union/_internal/runtime/entrypoints.py +121 -0
- union/_internal/runtime/io.py +136 -0
- union/_internal/runtime/resources_serde.py +134 -0
- union/_internal/runtime/task_serde.py +202 -0
- union/_internal/runtime/taskrunner.py +179 -0
- union/_internal/runtime/types_serde.py +53 -0
- union/_logging.py +124 -0
- union/_protos/__init__.py +0 -0
- union/_protos/common/authorization_pb2.py +66 -0
- union/_protos/common/authorization_pb2.pyi +106 -0
- union/_protos/common/authorization_pb2_grpc.py +4 -0
- union/_protos/common/identifier_pb2.py +71 -0
- union/_protos/common/identifier_pb2.pyi +82 -0
- union/_protos/common/identifier_pb2_grpc.py +4 -0
- union/_protos/common/identity_pb2.py +48 -0
- union/_protos/common/identity_pb2.pyi +72 -0
- union/_protos/common/identity_pb2_grpc.py +4 -0
- union/_protos/common/list_pb2.py +36 -0
- union/_protos/common/list_pb2.pyi +69 -0
- union/_protos/common/list_pb2_grpc.py +4 -0
- union/_protos/common/policy_pb2.py +37 -0
- union/_protos/common/policy_pb2.pyi +27 -0
- union/_protos/common/policy_pb2_grpc.py +4 -0
- union/_protos/common/role_pb2.py +37 -0
- union/_protos/common/role_pb2.pyi +51 -0
- union/_protos/common/role_pb2_grpc.py +4 -0
- union/_protos/common/runtime_version_pb2.py +28 -0
- union/_protos/common/runtime_version_pb2.pyi +24 -0
- union/_protos/common/runtime_version_pb2_grpc.py +4 -0
- union/_protos/logs/dataplane/payload_pb2.py +96 -0
- union/_protos/logs/dataplane/payload_pb2.pyi +168 -0
- union/_protos/logs/dataplane/payload_pb2_grpc.py +4 -0
- union/_protos/secret/definition_pb2.py +49 -0
- union/_protos/secret/definition_pb2.pyi +93 -0
- union/_protos/secret/definition_pb2_grpc.py +4 -0
- union/_protos/secret/payload_pb2.py +62 -0
- union/_protos/secret/payload_pb2.pyi +94 -0
- union/_protos/secret/payload_pb2_grpc.py +4 -0
- union/_protos/secret/secret_pb2.py +38 -0
- union/_protos/secret/secret_pb2.pyi +6 -0
- union/_protos/secret/secret_pb2_grpc.py +198 -0
- union/_protos/validate/validate/validate_pb2.py +76 -0
- union/_protos/workflow/node_execution_service_pb2.py +26 -0
- union/_protos/workflow/node_execution_service_pb2.pyi +4 -0
- union/_protos/workflow/node_execution_service_pb2_grpc.py +32 -0
- union/_protos/workflow/queue_service_pb2.py +75 -0
- union/_protos/workflow/queue_service_pb2.pyi +103 -0
- union/_protos/workflow/queue_service_pb2_grpc.py +172 -0
- union/_protos/workflow/run_definition_pb2.py +100 -0
- union/_protos/workflow/run_definition_pb2.pyi +256 -0
- union/_protos/workflow/run_definition_pb2_grpc.py +4 -0
- union/_protos/workflow/run_logs_service_pb2.py +41 -0
- union/_protos/workflow/run_logs_service_pb2.pyi +28 -0
- union/_protos/workflow/run_logs_service_pb2_grpc.py +69 -0
- union/_protos/workflow/run_service_pb2.py +133 -0
- union/_protos/workflow/run_service_pb2.pyi +173 -0
- union/_protos/workflow/run_service_pb2_grpc.py +412 -0
- union/_protos/workflow/state_service_pb2.py +58 -0
- union/_protos/workflow/state_service_pb2.pyi +69 -0
- union/_protos/workflow/state_service_pb2_grpc.py +138 -0
- union/_protos/workflow/task_definition_pb2.py +72 -0
- union/_protos/workflow/task_definition_pb2.pyi +65 -0
- union/_protos/workflow/task_definition_pb2_grpc.py +4 -0
- union/_protos/workflow/task_service_pb2.py +44 -0
- union/_protos/workflow/task_service_pb2.pyi +31 -0
- union/_protos/workflow/task_service_pb2_grpc.py +104 -0
- union/_resources.py +226 -0
- union/_retry.py +32 -0
- union/_reusable_environment.py +25 -0
- union/_run.py +374 -0
- union/_secret.py +61 -0
- union/_task.py +354 -0
- union/_task_environment.py +186 -0
- union/_timeout.py +47 -0
- union/_tools.py +27 -0
- union/_utils/__init__.py +11 -0
- union/_utils/asyn.py +119 -0
- union/_utils/file_handling.py +71 -0
- union/_utils/helpers.py +46 -0
- union/_utils/lazy_module.py +54 -0
- union/_utils/uv_script_parser.py +49 -0
- union/_version.py +21 -0
- union/connectors/__init__.py +0 -0
- union/errors.py +128 -0
- union/extras/__init__.py +5 -0
- union/extras/_container.py +263 -0
- union/io/__init__.py +11 -0
- union/io/_dataframe.py +0 -0
- union/io/_dir.py +425 -0
- union/io/_file.py +418 -0
- union/io/pickle/__init__.py +0 -0
- union/io/pickle/transformer.py +117 -0
- union/io/structured_dataset/__init__.py +122 -0
- union/io/structured_dataset/basic_dfs.py +219 -0
- union/io/structured_dataset/structured_dataset.py +1057 -0
- union/py.typed +0 -0
- union/remote/__init__.py +23 -0
- union/remote/_client/__init__.py +0 -0
- union/remote/_client/_protocols.py +129 -0
- union/remote/_client/auth/__init__.py +12 -0
- union/remote/_client/auth/_authenticators/__init__.py +0 -0
- union/remote/_client/auth/_authenticators/base.py +391 -0
- union/remote/_client/auth/_authenticators/client_credentials.py +73 -0
- union/remote/_client/auth/_authenticators/device_code.py +120 -0
- union/remote/_client/auth/_authenticators/external_command.py +77 -0
- union/remote/_client/auth/_authenticators/factory.py +200 -0
- union/remote/_client/auth/_authenticators/pkce.py +515 -0
- union/remote/_client/auth/_channel.py +184 -0
- union/remote/_client/auth/_client_config.py +83 -0
- union/remote/_client/auth/_default_html.py +32 -0
- union/remote/_client/auth/_grpc_utils/__init__.py +0 -0
- union/remote/_client/auth/_grpc_utils/auth_interceptor.py +204 -0
- union/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +144 -0
- union/remote/_client/auth/_keyring.py +154 -0
- union/remote/_client/auth/_token_client.py +258 -0
- union/remote/_client/auth/errors.py +16 -0
- union/remote/_client/controlplane.py +86 -0
- union/remote/_data.py +149 -0
- union/remote/_logs.py +74 -0
- union/remote/_project.py +86 -0
- union/remote/_run.py +820 -0
- union/remote/_secret.py +132 -0
- union/remote/_task.py +193 -0
- union/report/__init__.py +3 -0
- union/report/_report.py +178 -0
- union/report/_template.html +124 -0
- union/storage/__init__.py +24 -0
- union/storage/_remote_fs.py +34 -0
- union/storage/_storage.py +247 -0
- union/storage/_utils.py +5 -0
- union/types/__init__.py +11 -0
- union/types/_renderer.py +162 -0
- union/types/_string_literals.py +120 -0
- union/types/_type_engine.py +2131 -0
- union/types/_utils.py +80 -0
flyte/errors.py
ADDED
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Exceptions raised by Union.
|
|
3
|
+
|
|
4
|
+
These errors are raised when the underlying task execution fails, either because of a user error, system error or an
|
|
5
|
+
unknown error.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Literal
|
|
9
|
+
|
|
10
|
+
ErrorKind = Literal["system", "unknown", "user"]
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class BaseRuntimeError(RuntimeError):
|
|
14
|
+
"""
|
|
15
|
+
Base class for all Union runtime errors. These errors are raised when the underlying task execution fails, either
|
|
16
|
+
because of a user error, system error or an unknown error.
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
def __init__(self, code: str, kind: ErrorKind, root_cause_message: str, worker: str | None = None):
|
|
20
|
+
super().__init__(root_cause_message)
|
|
21
|
+
self.code = code
|
|
22
|
+
self.kind = kind
|
|
23
|
+
self.worker = worker
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class InitializationError(BaseRuntimeError):
|
|
27
|
+
"""
|
|
28
|
+
This error is raised when the Union system is tried to access without being initialized.
|
|
29
|
+
"""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class RuntimeSystemError(BaseRuntimeError):
|
|
33
|
+
"""
|
|
34
|
+
This error is raised when the underlying task execution fails because of a system error. This could be a bug in the
|
|
35
|
+
Union system or a bug in the user's code.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
def __init__(self, code: str, message: str, worker: str | None = None):
|
|
39
|
+
super().__init__(code, "system", message, worker)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class UnionRpcError(RuntimeSystemError):
|
|
43
|
+
"""
|
|
44
|
+
This error is raised when communication with the Union server fails.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
class RuntimeUserError(BaseRuntimeError):
|
|
49
|
+
"""
|
|
50
|
+
This error is raised when the underlying task execution fails because of an error in the user's code.
|
|
51
|
+
"""
|
|
52
|
+
|
|
53
|
+
def __init__(self, code: str, message: str, worker: str | None = None):
|
|
54
|
+
super().__init__(code, "user", message, worker)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class RuntimeUnknownError(BaseRuntimeError):
|
|
58
|
+
"""
|
|
59
|
+
This error is raised when the underlying task execution fails because of an unknown error.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
def __init__(self, code: str, message: str, worker: str | None = None):
|
|
63
|
+
super().__init__(code, "unknown", message, worker)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
class OOMError(RuntimeUserError):
|
|
67
|
+
"""
|
|
68
|
+
This error is raised when the underlying task execution fails because of an out-of-memory error.
|
|
69
|
+
"""
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
class TaskInterruptedError(RuntimeUserError):
|
|
73
|
+
"""
|
|
74
|
+
This error is raised when the underlying task execution is interrupted.
|
|
75
|
+
"""
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class PrimaryContainerNotFoundError(RuntimeUserError):
|
|
79
|
+
"""
|
|
80
|
+
This error is raised when the primary container is not found.
|
|
81
|
+
"""
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
class TaskTimeoutError(RuntimeUserError):
|
|
85
|
+
"""
|
|
86
|
+
This error is raised when the underlying task execution runs for longer than the specified timeout.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class RetriesExhaustedError(RuntimeUserError):
|
|
91
|
+
"""
|
|
92
|
+
This error is raised when the underlying task execution fails after all retries have been exhausted.
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class InvalidImageNameError(RuntimeUserError):
|
|
97
|
+
"""
|
|
98
|
+
This error is raised when the image name is invalid.
|
|
99
|
+
"""
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
class ImagePullBackOffError(RuntimeUserError):
|
|
103
|
+
"""
|
|
104
|
+
This error is raised when the image cannot be pulled.
|
|
105
|
+
"""
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class CustomError(RuntimeUserError):
|
|
109
|
+
"""
|
|
110
|
+
This error is raised when the user raises a custom error.
|
|
111
|
+
"""
|
|
112
|
+
|
|
113
|
+
def __init__(self, code: str, message: str):
|
|
114
|
+
super().__init__(code, message, "user")
|
|
115
|
+
|
|
116
|
+
@classmethod
|
|
117
|
+
def from_exception(cls, e: Exception):
|
|
118
|
+
"""
|
|
119
|
+
Create a CustomError from an exception. The exception's class name is used as the error code and the exception
|
|
120
|
+
message is used as the error message.
|
|
121
|
+
"""
|
|
122
|
+
return cls(e.__class__.__name__, str(e))
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
class NotInTaskContextError(RuntimeUserError):
|
|
126
|
+
"""
|
|
127
|
+
This error is raised when the user tries to access the task context outside of a task.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
class ActionNotFoundError(RuntimeError):
|
|
132
|
+
"""
|
|
133
|
+
This error is raised when the user tries to access an action that does not exist.
|
|
134
|
+
"""
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
class ReferenceTaskError(RuntimeUserError):
|
|
138
|
+
"""
|
|
139
|
+
This error is raised when the user tries to access a task that does not exist.
|
|
140
|
+
"""
|
|
141
|
+
|
|
142
|
+
def __init__(self, message: str):
|
|
143
|
+
super().__init__("ReferenceTaskUsageError", message, "user")
|
flyte/extras/__init__.py
ADDED
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import pathlib
|
|
3
|
+
from typing import Any, Dict, List, Literal, Optional, Tuple, Type, Union
|
|
4
|
+
|
|
5
|
+
from flyteidl.core import tasks_pb2
|
|
6
|
+
|
|
7
|
+
from flyte import Image, storage
|
|
8
|
+
from flyte._datastructures import NativeInterface, SerializationContext
|
|
9
|
+
from flyte._logging import logger
|
|
10
|
+
from flyte._task import TaskTemplate
|
|
11
|
+
|
|
12
|
+
_PRIMARY_CONTAINER_NAME_FIELD = "primary_container_name"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _extract_command_key(cmd: str, **kwargs) -> Any:
|
|
16
|
+
"""
|
|
17
|
+
Extract the key from the command using regex.
|
|
18
|
+
"""
|
|
19
|
+
import re
|
|
20
|
+
|
|
21
|
+
input_regex = r"^\{\{\s*\.inputs\.(.*?)\s*\}\}$"
|
|
22
|
+
match = re.match(input_regex, cmd)
|
|
23
|
+
if match:
|
|
24
|
+
return match.group(1)
|
|
25
|
+
return None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def _extract_path_command_key(cmd: str, input_data_dir: Optional[str]) -> Optional[str]:
|
|
29
|
+
"""
|
|
30
|
+
Extract the key from the path-like command using regex.
|
|
31
|
+
"""
|
|
32
|
+
import re
|
|
33
|
+
|
|
34
|
+
input_data_dir = input_data_dir or ""
|
|
35
|
+
input_regex = rf"{re.escape(input_data_dir)}/(.+)$"
|
|
36
|
+
match = re.match(input_regex, cmd)
|
|
37
|
+
if match:
|
|
38
|
+
return match.group(1)
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ContainerTask(TaskTemplate):
|
|
43
|
+
"""
|
|
44
|
+
This is an intermediate class that represents Flyte Tasks that run a container at execution time. This is the vast
|
|
45
|
+
majority of tasks - the typical ``@task`` decorated tasks; for instance, all run a container. An example of
|
|
46
|
+
something that doesn't run a container would be something like the Athena SQL task.
|
|
47
|
+
|
|
48
|
+
:param name: Name of the task
|
|
49
|
+
:param image: The container image to use for the task. This can be a string or an Image object.
|
|
50
|
+
:param command: The command to run in the container. This can be a list of strings or a single string.
|
|
51
|
+
:param inputs: The inputs to the task. This is a dictionary of input names to types.
|
|
52
|
+
:param arguments: The arguments to pass to the command. This is a list of strings.
|
|
53
|
+
:param outputs: The outputs of the task. This is a dictionary of output names to types.
|
|
54
|
+
:param input_data_dir: The directory where the input data is stored. This is a string or a Path object.
|
|
55
|
+
:param output_data_dir: The directory where the output data is stored. This is a string or a Path object.
|
|
56
|
+
:param metadata_format: The format of the output file. This can be "JSON", "YAML", or "PROTO".
|
|
57
|
+
:param local_logs: If True, logs will be printed to the console in the local execution.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
MetadataFormat = Literal["JSON", "YAML", "PROTO"]
|
|
61
|
+
|
|
62
|
+
def __init__(
|
|
63
|
+
self,
|
|
64
|
+
name: str,
|
|
65
|
+
image: Union[str, Image],
|
|
66
|
+
command: List[str],
|
|
67
|
+
inputs: Optional[Dict[str, Type]] = None,
|
|
68
|
+
arguments: Optional[List[str]] = None,
|
|
69
|
+
outputs: Optional[Dict[str, Type]] = None,
|
|
70
|
+
input_data_dir: str | pathlib.Path = "/var/inputs",
|
|
71
|
+
output_data_dir: str | pathlib.Path = "/var/outputs",
|
|
72
|
+
metadata_format: MetadataFormat = "JSON",
|
|
73
|
+
local_logs: bool = False,
|
|
74
|
+
**kwargs,
|
|
75
|
+
):
|
|
76
|
+
super().__init__(
|
|
77
|
+
task_type="raw-container",
|
|
78
|
+
name=name,
|
|
79
|
+
image=image,
|
|
80
|
+
interface=NativeInterface({k: (v, None) for k, v in inputs.items()} if inputs else {}, outputs or {}),
|
|
81
|
+
**kwargs,
|
|
82
|
+
)
|
|
83
|
+
self._image = image
|
|
84
|
+
if isinstance(image, str):
|
|
85
|
+
if image == "auto":
|
|
86
|
+
self._image = Image.auto()
|
|
87
|
+
else:
|
|
88
|
+
self._image = Image.from_prebuilt(image)
|
|
89
|
+
self._cmd = command
|
|
90
|
+
self._args = arguments
|
|
91
|
+
self._input_data_dir = input_data_dir
|
|
92
|
+
if isinstance(input_data_dir, str):
|
|
93
|
+
self._input_data_dir = pathlib.Path(input_data_dir)
|
|
94
|
+
self._output_data_dir = output_data_dir
|
|
95
|
+
if isinstance(output_data_dir, str):
|
|
96
|
+
self._output_data_dir = pathlib.Path(output_data_dir)
|
|
97
|
+
self._metadata_format = metadata_format
|
|
98
|
+
self._inputs = inputs
|
|
99
|
+
self._outputs = outputs
|
|
100
|
+
self.local_logs = local_logs
|
|
101
|
+
|
|
102
|
+
def _render_command_and_volume_binding(self, cmd: str, **kwargs) -> Tuple[str, Dict[str, Dict[str, str]]]:
|
|
103
|
+
"""
|
|
104
|
+
We support template-style references to inputs, e.g., "{{.inputs.infile}}".
|
|
105
|
+
|
|
106
|
+
For FlyteFile and FlyteDirectory commands, e.g., "/var/inputs/inputs", we extract the key from strings that
|
|
107
|
+
begin with the specified `input_data_dir`.
|
|
108
|
+
"""
|
|
109
|
+
# from flytekit.types.directory import FlyteDirectory
|
|
110
|
+
# from flytekit.types.file import FlyteFile
|
|
111
|
+
|
|
112
|
+
volume_binding: Dict[str, Dict[str, str]] = {}
|
|
113
|
+
path_k = _extract_path_command_key(cmd, str(self._input_data_dir))
|
|
114
|
+
k = path_k if path_k else _extract_command_key(cmd)
|
|
115
|
+
|
|
116
|
+
if k:
|
|
117
|
+
input_val = kwargs.get(k)
|
|
118
|
+
# TODO: Add support file and directory transformer first
|
|
119
|
+
# if type(input_val) in [FlyteFile, FlyteDirectory]:
|
|
120
|
+
# if not path_k:
|
|
121
|
+
# raise AssertionError(
|
|
122
|
+
# "FlyteFile and FlyteDirectory commands should not use the template syntax like this:
|
|
123
|
+
# {{.inputs.infile}}\n"
|
|
124
|
+
# "Please use a path-like syntax, such as: /var/inputs/infile.\n"
|
|
125
|
+
# "This requirement is due to how Flyte Propeller processes template syntax inputs."
|
|
126
|
+
# )
|
|
127
|
+
# local_flyte_file_or_dir_path = str(input_val)
|
|
128
|
+
# remote_flyte_file_or_dir_path = os.path.join(self._input_data_dir, k) # type: ignore
|
|
129
|
+
# volume_binding[local_flyte_file_or_dir_path] = {
|
|
130
|
+
# "bind": remote_flyte_file_or_dir_path,
|
|
131
|
+
# "mode": "rw",
|
|
132
|
+
# }
|
|
133
|
+
# command = remote_flyte_file_or_dir_path
|
|
134
|
+
command = str(input_val)
|
|
135
|
+
else:
|
|
136
|
+
command = cmd
|
|
137
|
+
|
|
138
|
+
return command, volume_binding
|
|
139
|
+
|
|
140
|
+
def _prepare_command_and_volumes(
|
|
141
|
+
self, cmd_and_args: List[str], **kwargs
|
|
142
|
+
) -> Tuple[List[str], Dict[str, Dict[str, str]]]:
|
|
143
|
+
"""
|
|
144
|
+
Prepares the command and volume bindings for the container based on input arguments and command templates.
|
|
145
|
+
|
|
146
|
+
Parameters:
|
|
147
|
+
- cmd_and_args (List[str]): The command and arguments to prepare.
|
|
148
|
+
- **kwargs: Keyword arguments representing task inputs.
|
|
149
|
+
|
|
150
|
+
Returns:
|
|
151
|
+
- Tuple[List[str], Dict[str, Dict[str, str]]]: A tuple containing the prepared commands and volume bindings.
|
|
152
|
+
"""
|
|
153
|
+
|
|
154
|
+
commands = []
|
|
155
|
+
volume_bindings = {}
|
|
156
|
+
|
|
157
|
+
for cmd in cmd_and_args:
|
|
158
|
+
command, volume_binding = self._render_command_and_volume_binding(cmd, **kwargs)
|
|
159
|
+
commands.append(command)
|
|
160
|
+
volume_bindings.update(volume_binding)
|
|
161
|
+
|
|
162
|
+
return commands, volume_bindings
|
|
163
|
+
|
|
164
|
+
def _pull_image_if_not_exists(self, client, image: str):
|
|
165
|
+
try:
|
|
166
|
+
if not client.images.list(filters={"reference": image}):
|
|
167
|
+
logger.info(f"Pulling image: {image} for container task: {self.name}")
|
|
168
|
+
client.images.pull(image)
|
|
169
|
+
except Exception as e:
|
|
170
|
+
logger.error(f"Failed to pull image {image}: {e!s}")
|
|
171
|
+
raise
|
|
172
|
+
|
|
173
|
+
def _string_to_timedelta(self, s: str):
|
|
174
|
+
import datetime
|
|
175
|
+
import re
|
|
176
|
+
|
|
177
|
+
regex = r"(?:(\d+) days?, )?(?:(\d+):)?(\d+):(\d+)(?:\.(\d+))?"
|
|
178
|
+
parts = re.match(regex, s)
|
|
179
|
+
if not parts:
|
|
180
|
+
raise ValueError("Invalid timedelta string format")
|
|
181
|
+
|
|
182
|
+
days = int(parts.group(1)) if parts.group(1) else 0
|
|
183
|
+
hours = int(parts.group(2)) if parts.group(2) else 0
|
|
184
|
+
minutes = int(parts.group(3)) if parts.group(3) else 0
|
|
185
|
+
seconds = int(parts.group(4)) if parts.group(4) else 0
|
|
186
|
+
microseconds = int(parts.group(5)) if parts.group(5) else 0
|
|
187
|
+
|
|
188
|
+
return datetime.timedelta(
|
|
189
|
+
days=days,
|
|
190
|
+
hours=hours,
|
|
191
|
+
minutes=minutes,
|
|
192
|
+
seconds=seconds,
|
|
193
|
+
microseconds=microseconds,
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
def _convert_output_val_to_correct_type(self, output_val: Any, output_type: Type) -> Any:
|
|
197
|
+
import datetime
|
|
198
|
+
|
|
199
|
+
if issubclass(output_type, bool):
|
|
200
|
+
return output_val.lower() != "false"
|
|
201
|
+
elif issubclass(output_type, datetime.datetime):
|
|
202
|
+
return datetime.datetime.fromisoformat(output_val)
|
|
203
|
+
elif issubclass(output_type, datetime.timedelta):
|
|
204
|
+
return self._string_to_timedelta(output_val)
|
|
205
|
+
else:
|
|
206
|
+
return output_type(output_val)
|
|
207
|
+
|
|
208
|
+
def _get_output_dict(self, output_directory: pathlib.Path) -> Dict[str, Any]:
|
|
209
|
+
output_dict = {}
|
|
210
|
+
if self._outputs:
|
|
211
|
+
for k, output_type in self._outputs.items():
|
|
212
|
+
output_path = output_directory / k
|
|
213
|
+
with output_path.open("r") as f:
|
|
214
|
+
output_val = f.read()
|
|
215
|
+
output_dict[k] = self._convert_output_val_to_correct_type(output_val, output_type)
|
|
216
|
+
return output_dict
|
|
217
|
+
|
|
218
|
+
def execute(self, **kwargs) -> Any:
|
|
219
|
+
try:
|
|
220
|
+
import docker
|
|
221
|
+
except ImportError:
|
|
222
|
+
raise ImportError("Docker is not installed. Please install Docker by running `pip install docker`.")
|
|
223
|
+
|
|
224
|
+
# Normalize the input and output directories
|
|
225
|
+
self._input_data_dir = os.path.normpath(self._input_data_dir) if self._input_data_dir else ""
|
|
226
|
+
self._output_data_dir = os.path.normpath(self._output_data_dir) if self._output_data_dir else ""
|
|
227
|
+
|
|
228
|
+
output_directory = storage.get_random_local_directory()
|
|
229
|
+
cmd_and_args = (self._cmd or []) + (self._args or [])
|
|
230
|
+
commands, volume_bindings = self._prepare_command_and_volumes(cmd_and_args, **kwargs)
|
|
231
|
+
volume_bindings[str(output_directory)] = {"bind": self._output_data_dir, "mode": "rw"}
|
|
232
|
+
|
|
233
|
+
client = docker.from_env()
|
|
234
|
+
if isinstance(self._image, str):
|
|
235
|
+
raise AssertionError(f"Only Image objects are supported, not strings. Got {self._image} instead.")
|
|
236
|
+
uri = self._image.uri
|
|
237
|
+
self._pull_image_if_not_exists(client, uri)
|
|
238
|
+
|
|
239
|
+
container = client.containers.run(uri, command=commands, remove=True, volumes=volume_bindings, detach=True)
|
|
240
|
+
|
|
241
|
+
# Wait for the container to finish the task
|
|
242
|
+
# TODO: Add a 'timeout' parameter to control the max wait time for the container to finish the task.
|
|
243
|
+
|
|
244
|
+
if self.local_logs:
|
|
245
|
+
for log in container.logs(stream=True):
|
|
246
|
+
print(f"[Local Container] {log.strip()!r}")
|
|
247
|
+
|
|
248
|
+
container.wait()
|
|
249
|
+
|
|
250
|
+
output_dict = self._get_output_dict(output_directory)
|
|
251
|
+
return output_dict
|
|
252
|
+
|
|
253
|
+
def data_loading_config(self, sctx: SerializationContext) -> tasks_pb2.DataLoadingConfig:
|
|
254
|
+
literal_to_protobuf = {
|
|
255
|
+
"JSON": tasks_pb2.DataLoadingConfig.JSON,
|
|
256
|
+
"YAML": tasks_pb2.DataLoadingConfig.YAML,
|
|
257
|
+
"PROTO": tasks_pb2.DataLoadingConfig.PROTO,
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
return tasks_pb2.DataLoadingConfig(
|
|
261
|
+
input_path=self._input_data_dir,
|
|
262
|
+
output_path=self._output_data_dir,
|
|
263
|
+
enabled=True,
|
|
264
|
+
format=literal_to_protobuf.get(self._metadata_format, "JSON"),
|
|
265
|
+
)
|
|
266
|
+
|
|
267
|
+
def container_args(self, sctx: SerializationContext) -> List[str]:
|
|
268
|
+
return self._cmd + (self._args if self._args else [])
|
|
269
|
+
|
|
270
|
+
def config(self, sctx: SerializationContext) -> Dict[str, str]:
|
|
271
|
+
if self.pod_template is None:
|
|
272
|
+
return {}
|
|
273
|
+
return {_PRIMARY_CONTAINER_NAME_FIELD: self.primary_container_name}
|
flyte/io/__init__.py
ADDED
flyte/io/_dataframe.py
ADDED
|
File without changes
|