flyte 0.0.1b0__py3-none-any.whl → 2.0.0b46__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.
- flyte/__init__.py +83 -30
- flyte/_bin/connect.py +61 -0
- flyte/_bin/debug.py +38 -0
- flyte/_bin/runtime.py +87 -19
- flyte/_bin/serve.py +351 -0
- flyte/_build.py +3 -2
- flyte/_cache/cache.py +6 -5
- flyte/_cache/local_cache.py +216 -0
- flyte/_code_bundle/_ignore.py +31 -5
- flyte/_code_bundle/_packaging.py +42 -11
- flyte/_code_bundle/_utils.py +57 -34
- flyte/_code_bundle/bundle.py +130 -27
- flyte/_constants.py +1 -0
- flyte/_context.py +21 -5
- flyte/_custom_context.py +73 -0
- flyte/_debug/constants.py +37 -0
- flyte/_debug/utils.py +17 -0
- flyte/_debug/vscode.py +315 -0
- flyte/_deploy.py +396 -75
- flyte/_deployer.py +109 -0
- flyte/_environment.py +94 -11
- flyte/_excepthook.py +37 -0
- flyte/_group.py +2 -1
- flyte/_hash.py +1 -16
- flyte/_image.py +544 -234
- flyte/_initialize.py +443 -294
- flyte/_interface.py +40 -5
- flyte/_internal/controllers/__init__.py +22 -8
- flyte/_internal/controllers/_local_controller.py +159 -35
- flyte/_internal/controllers/_trace.py +18 -10
- flyte/_internal/controllers/remote/__init__.py +38 -9
- flyte/_internal/controllers/remote/_action.py +82 -12
- flyte/_internal/controllers/remote/_client.py +6 -2
- flyte/_internal/controllers/remote/_controller.py +290 -64
- flyte/_internal/controllers/remote/_core.py +155 -95
- flyte/_internal/controllers/remote/_informer.py +40 -20
- flyte/_internal/controllers/remote/_service_protocol.py +2 -2
- flyte/_internal/imagebuild/__init__.py +2 -10
- flyte/_internal/imagebuild/docker_builder.py +391 -84
- flyte/_internal/imagebuild/image_builder.py +111 -55
- flyte/_internal/imagebuild/remote_builder.py +409 -0
- flyte/_internal/imagebuild/utils.py +79 -0
- flyte/_internal/resolvers/_app_env_module.py +92 -0
- flyte/_internal/resolvers/_task_module.py +5 -38
- flyte/_internal/resolvers/app_env.py +26 -0
- flyte/_internal/resolvers/common.py +8 -1
- flyte/_internal/resolvers/default.py +2 -2
- flyte/_internal/runtime/convert.py +322 -33
- flyte/_internal/runtime/entrypoints.py +106 -18
- flyte/_internal/runtime/io.py +71 -23
- flyte/_internal/runtime/resources_serde.py +21 -7
- flyte/_internal/runtime/reuse.py +125 -0
- flyte/_internal/runtime/rusty.py +196 -0
- flyte/_internal/runtime/task_serde.py +239 -66
- flyte/_internal/runtime/taskrunner.py +48 -8
- flyte/_internal/runtime/trigger_serde.py +162 -0
- flyte/_internal/runtime/types_serde.py +7 -16
- flyte/_keyring/file.py +115 -0
- flyte/_link.py +30 -0
- flyte/_logging.py +241 -42
- flyte/_map.py +312 -0
- flyte/_metrics.py +59 -0
- flyte/_module.py +74 -0
- flyte/_pod.py +30 -0
- flyte/_resources.py +296 -33
- flyte/_retry.py +1 -7
- flyte/_reusable_environment.py +72 -7
- flyte/_run.py +461 -132
- flyte/_secret.py +47 -11
- flyte/_serve.py +333 -0
- flyte/_task.py +245 -56
- flyte/_task_environment.py +219 -97
- flyte/_task_plugins.py +47 -0
- flyte/_tools.py +8 -8
- flyte/_trace.py +15 -24
- flyte/_trigger.py +1027 -0
- flyte/_utils/__init__.py +12 -1
- flyte/_utils/asyn.py +3 -1
- flyte/_utils/async_cache.py +139 -0
- flyte/_utils/coro_management.py +5 -4
- flyte/_utils/description_parser.py +19 -0
- flyte/_utils/docker_credentials.py +173 -0
- flyte/_utils/helpers.py +45 -19
- flyte/_utils/module_loader.py +123 -0
- flyte/_utils/org_discovery.py +57 -0
- flyte/_utils/uv_script_parser.py +8 -1
- flyte/_version.py +16 -3
- flyte/app/__init__.py +27 -0
- flyte/app/_app_environment.py +362 -0
- flyte/app/_connector_environment.py +40 -0
- flyte/app/_deploy.py +130 -0
- flyte/app/_parameter.py +343 -0
- flyte/app/_runtime/__init__.py +3 -0
- flyte/app/_runtime/app_serde.py +383 -0
- flyte/app/_types.py +113 -0
- flyte/app/extras/__init__.py +9 -0
- flyte/app/extras/_auth_middleware.py +217 -0
- flyte/app/extras/_fastapi.py +93 -0
- flyte/app/extras/_model_loader/__init__.py +3 -0
- flyte/app/extras/_model_loader/config.py +7 -0
- flyte/app/extras/_model_loader/loader.py +288 -0
- flyte/cli/__init__.py +12 -0
- flyte/cli/_abort.py +28 -0
- flyte/cli/_build.py +114 -0
- flyte/cli/_common.py +493 -0
- flyte/cli/_create.py +371 -0
- flyte/cli/_delete.py +45 -0
- flyte/cli/_deploy.py +401 -0
- flyte/cli/_gen.py +316 -0
- flyte/cli/_get.py +446 -0
- flyte/cli/_option.py +33 -0
- {union/_cli → flyte/cli}/_params.py +152 -153
- flyte/cli/_plugins.py +209 -0
- flyte/cli/_prefetch.py +292 -0
- flyte/cli/_run.py +690 -0
- flyte/cli/_serve.py +338 -0
- flyte/cli/_update.py +86 -0
- flyte/cli/_user.py +20 -0
- flyte/cli/main.py +246 -0
- flyte/config/__init__.py +3 -0
- flyte/config/_config.py +248 -0
- flyte/config/_internal.py +73 -0
- flyte/config/_reader.py +225 -0
- flyte/connectors/__init__.py +11 -0
- flyte/connectors/_connector.py +330 -0
- flyte/connectors/_server.py +194 -0
- flyte/connectors/utils.py +159 -0
- flyte/errors.py +134 -2
- flyte/extend.py +24 -0
- flyte/extras/_container.py +69 -56
- flyte/git/__init__.py +3 -0
- flyte/git/_config.py +279 -0
- flyte/io/__init__.py +8 -1
- flyte/io/{structured_dataset → _dataframe}/__init__.py +32 -30
- flyte/io/{structured_dataset → _dataframe}/basic_dfs.py +75 -68
- flyte/io/{structured_dataset/structured_dataset.py → _dataframe/dataframe.py} +207 -242
- flyte/io/_dir.py +575 -113
- flyte/io/_file.py +587 -141
- flyte/io/_hashing_io.py +342 -0
- flyte/io/extend.py +7 -0
- flyte/models.py +635 -0
- flyte/prefetch/__init__.py +22 -0
- flyte/prefetch/_hf_model.py +563 -0
- flyte/remote/__init__.py +14 -3
- flyte/remote/_action.py +879 -0
- flyte/remote/_app.py +346 -0
- flyte/remote/_auth_metadata.py +42 -0
- flyte/remote/_client/_protocols.py +62 -4
- flyte/remote/_client/auth/_auth_utils.py +19 -0
- flyte/remote/_client/auth/_authenticators/base.py +8 -2
- flyte/remote/_client/auth/_authenticators/device_code.py +4 -5
- flyte/remote/_client/auth/_authenticators/factory.py +4 -0
- flyte/remote/_client/auth/_authenticators/passthrough.py +79 -0
- flyte/remote/_client/auth/_authenticators/pkce.py +17 -18
- flyte/remote/_client/auth/_channel.py +47 -18
- flyte/remote/_client/auth/_client_config.py +5 -3
- flyte/remote/_client/auth/_keyring.py +15 -2
- flyte/remote/_client/auth/_token_client.py +3 -3
- flyte/remote/_client/controlplane.py +206 -18
- flyte/remote/_common.py +66 -0
- flyte/remote/_data.py +107 -22
- flyte/remote/_logs.py +116 -33
- flyte/remote/_project.py +21 -19
- flyte/remote/_run.py +164 -631
- flyte/remote/_secret.py +72 -29
- flyte/remote/_task.py +387 -46
- flyte/remote/_trigger.py +368 -0
- flyte/remote/_user.py +43 -0
- flyte/report/_report.py +10 -6
- flyte/storage/__init__.py +13 -1
- flyte/storage/_config.py +237 -0
- flyte/storage/_parallel_reader.py +289 -0
- flyte/storage/_storage.py +268 -59
- flyte/syncify/__init__.py +56 -0
- flyte/syncify/_api.py +414 -0
- flyte/types/__init__.py +39 -0
- flyte/types/_interface.py +22 -7
- flyte/{io/pickle/transformer.py → types/_pickle.py} +37 -9
- flyte/types/_string_literals.py +8 -9
- flyte/types/_type_engine.py +230 -129
- flyte/types/_utils.py +1 -1
- flyte-2.0.0b46.data/scripts/debug.py +38 -0
- flyte-2.0.0b46.data/scripts/runtime.py +194 -0
- flyte-2.0.0b46.dist-info/METADATA +352 -0
- flyte-2.0.0b46.dist-info/RECORD +221 -0
- flyte-2.0.0b46.dist-info/entry_points.txt +8 -0
- flyte-2.0.0b46.dist-info/licenses/LICENSE +201 -0
- flyte/_api_commons.py +0 -3
- flyte/_cli/_common.py +0 -287
- flyte/_cli/_create.py +0 -42
- flyte/_cli/_delete.py +0 -23
- flyte/_cli/_deploy.py +0 -140
- flyte/_cli/_get.py +0 -235
- flyte/_cli/_run.py +0 -152
- flyte/_cli/main.py +0 -72
- flyte/_datastructures.py +0 -342
- flyte/_internal/controllers/pbhash.py +0 -39
- flyte/_protos/common/authorization_pb2.py +0 -66
- flyte/_protos/common/authorization_pb2.pyi +0 -108
- flyte/_protos/common/authorization_pb2_grpc.py +0 -4
- flyte/_protos/common/identifier_pb2.py +0 -71
- flyte/_protos/common/identifier_pb2.pyi +0 -82
- flyte/_protos/common/identifier_pb2_grpc.py +0 -4
- flyte/_protos/common/identity_pb2.py +0 -48
- flyte/_protos/common/identity_pb2.pyi +0 -72
- flyte/_protos/common/identity_pb2_grpc.py +0 -4
- flyte/_protos/common/list_pb2.py +0 -36
- flyte/_protos/common/list_pb2.pyi +0 -69
- flyte/_protos/common/list_pb2_grpc.py +0 -4
- flyte/_protos/common/policy_pb2.py +0 -37
- flyte/_protos/common/policy_pb2.pyi +0 -27
- flyte/_protos/common/policy_pb2_grpc.py +0 -4
- flyte/_protos/common/role_pb2.py +0 -37
- flyte/_protos/common/role_pb2.pyi +0 -53
- flyte/_protos/common/role_pb2_grpc.py +0 -4
- flyte/_protos/common/runtime_version_pb2.py +0 -28
- flyte/_protos/common/runtime_version_pb2.pyi +0 -24
- flyte/_protos/common/runtime_version_pb2_grpc.py +0 -4
- flyte/_protos/logs/dataplane/payload_pb2.py +0 -96
- flyte/_protos/logs/dataplane/payload_pb2.pyi +0 -168
- flyte/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
- flyte/_protos/secret/definition_pb2.py +0 -49
- flyte/_protos/secret/definition_pb2.pyi +0 -93
- flyte/_protos/secret/definition_pb2_grpc.py +0 -4
- flyte/_protos/secret/payload_pb2.py +0 -62
- flyte/_protos/secret/payload_pb2.pyi +0 -94
- flyte/_protos/secret/payload_pb2_grpc.py +0 -4
- flyte/_protos/secret/secret_pb2.py +0 -38
- flyte/_protos/secret/secret_pb2.pyi +0 -6
- flyte/_protos/secret/secret_pb2_grpc.py +0 -198
- flyte/_protos/secret/secret_pb2_grpc_grpc.py +0 -198
- flyte/_protos/validate/validate/validate_pb2.py +0 -76
- flyte/_protos/workflow/node_execution_service_pb2.py +0 -26
- flyte/_protos/workflow/node_execution_service_pb2.pyi +0 -4
- flyte/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
- flyte/_protos/workflow/queue_service_pb2.py +0 -106
- flyte/_protos/workflow/queue_service_pb2.pyi +0 -141
- flyte/_protos/workflow/queue_service_pb2_grpc.py +0 -172
- flyte/_protos/workflow/run_definition_pb2.py +0 -128
- flyte/_protos/workflow/run_definition_pb2.pyi +0 -310
- flyte/_protos/workflow/run_definition_pb2_grpc.py +0 -4
- flyte/_protos/workflow/run_logs_service_pb2.py +0 -41
- flyte/_protos/workflow/run_logs_service_pb2.pyi +0 -28
- flyte/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
- flyte/_protos/workflow/run_service_pb2.py +0 -133
- flyte/_protos/workflow/run_service_pb2.pyi +0 -175
- flyte/_protos/workflow/run_service_pb2_grpc.py +0 -412
- flyte/_protos/workflow/state_service_pb2.py +0 -58
- flyte/_protos/workflow/state_service_pb2.pyi +0 -71
- flyte/_protos/workflow/state_service_pb2_grpc.py +0 -138
- flyte/_protos/workflow/task_definition_pb2.py +0 -72
- flyte/_protos/workflow/task_definition_pb2.pyi +0 -65
- flyte/_protos/workflow/task_definition_pb2_grpc.py +0 -4
- flyte/_protos/workflow/task_service_pb2.py +0 -44
- flyte/_protos/workflow/task_service_pb2.pyi +0 -31
- flyte/_protos/workflow/task_service_pb2_grpc.py +0 -104
- flyte/io/_dataframe.py +0 -0
- flyte/io/pickle/__init__.py +0 -0
- flyte/remote/_console.py +0 -18
- flyte-0.0.1b0.dist-info/METADATA +0 -179
- flyte-0.0.1b0.dist-info/RECORD +0 -390
- flyte-0.0.1b0.dist-info/entry_points.txt +0 -3
- union/__init__.py +0 -54
- union/_api_commons.py +0 -3
- union/_bin/__init__.py +0 -0
- union/_bin/runtime.py +0 -113
- union/_build.py +0 -25
- union/_cache/__init__.py +0 -12
- union/_cache/cache.py +0 -141
- union/_cache/defaults.py +0 -9
- union/_cache/policy_function_body.py +0 -42
- union/_cli/__init__.py +0 -0
- union/_cli/_common.py +0 -263
- union/_cli/_create.py +0 -40
- union/_cli/_delete.py +0 -23
- union/_cli/_deploy.py +0 -120
- union/_cli/_get.py +0 -162
- union/_cli/_run.py +0 -150
- union/_cli/main.py +0 -72
- union/_code_bundle/__init__.py +0 -8
- union/_code_bundle/_ignore.py +0 -113
- union/_code_bundle/_packaging.py +0 -187
- union/_code_bundle/_utils.py +0 -342
- union/_code_bundle/bundle.py +0 -176
- union/_context.py +0 -146
- union/_datastructures.py +0 -295
- union/_deploy.py +0 -185
- union/_doc.py +0 -29
- union/_docstring.py +0 -26
- union/_environment.py +0 -43
- union/_group.py +0 -31
- union/_hash.py +0 -23
- union/_image.py +0 -760
- union/_initialize.py +0 -585
- union/_interface.py +0 -84
- union/_internal/__init__.py +0 -3
- union/_internal/controllers/__init__.py +0 -77
- union/_internal/controllers/_local_controller.py +0 -77
- union/_internal/controllers/pbhash.py +0 -39
- union/_internal/controllers/remote/__init__.py +0 -40
- union/_internal/controllers/remote/_action.py +0 -131
- union/_internal/controllers/remote/_client.py +0 -43
- union/_internal/controllers/remote/_controller.py +0 -169
- union/_internal/controllers/remote/_core.py +0 -341
- union/_internal/controllers/remote/_informer.py +0 -260
- union/_internal/controllers/remote/_service_protocol.py +0 -44
- union/_internal/imagebuild/__init__.py +0 -11
- union/_internal/imagebuild/docker_builder.py +0 -416
- union/_internal/imagebuild/image_builder.py +0 -243
- union/_internal/imagebuild/remote_builder.py +0 -0
- union/_internal/resolvers/__init__.py +0 -0
- union/_internal/resolvers/_task_module.py +0 -31
- union/_internal/resolvers/common.py +0 -24
- union/_internal/resolvers/default.py +0 -27
- union/_internal/runtime/__init__.py +0 -0
- union/_internal/runtime/convert.py +0 -163
- union/_internal/runtime/entrypoints.py +0 -121
- union/_internal/runtime/io.py +0 -136
- union/_internal/runtime/resources_serde.py +0 -134
- union/_internal/runtime/task_serde.py +0 -202
- union/_internal/runtime/taskrunner.py +0 -179
- union/_internal/runtime/types_serde.py +0 -53
- union/_logging.py +0 -124
- union/_protos/__init__.py +0 -0
- union/_protos/common/authorization_pb2.py +0 -66
- union/_protos/common/authorization_pb2.pyi +0 -106
- union/_protos/common/authorization_pb2_grpc.py +0 -4
- union/_protos/common/identifier_pb2.py +0 -71
- union/_protos/common/identifier_pb2.pyi +0 -82
- union/_protos/common/identifier_pb2_grpc.py +0 -4
- union/_protos/common/identity_pb2.py +0 -48
- union/_protos/common/identity_pb2.pyi +0 -72
- union/_protos/common/identity_pb2_grpc.py +0 -4
- union/_protos/common/list_pb2.py +0 -36
- union/_protos/common/list_pb2.pyi +0 -69
- union/_protos/common/list_pb2_grpc.py +0 -4
- union/_protos/common/policy_pb2.py +0 -37
- union/_protos/common/policy_pb2.pyi +0 -27
- union/_protos/common/policy_pb2_grpc.py +0 -4
- union/_protos/common/role_pb2.py +0 -37
- union/_protos/common/role_pb2.pyi +0 -51
- union/_protos/common/role_pb2_grpc.py +0 -4
- union/_protos/common/runtime_version_pb2.py +0 -28
- union/_protos/common/runtime_version_pb2.pyi +0 -24
- union/_protos/common/runtime_version_pb2_grpc.py +0 -4
- union/_protos/logs/dataplane/payload_pb2.py +0 -96
- union/_protos/logs/dataplane/payload_pb2.pyi +0 -168
- union/_protos/logs/dataplane/payload_pb2_grpc.py +0 -4
- union/_protos/secret/definition_pb2.py +0 -49
- union/_protos/secret/definition_pb2.pyi +0 -93
- union/_protos/secret/definition_pb2_grpc.py +0 -4
- union/_protos/secret/payload_pb2.py +0 -62
- union/_protos/secret/payload_pb2.pyi +0 -94
- union/_protos/secret/payload_pb2_grpc.py +0 -4
- union/_protos/secret/secret_pb2.py +0 -38
- union/_protos/secret/secret_pb2.pyi +0 -6
- union/_protos/secret/secret_pb2_grpc.py +0 -198
- union/_protos/validate/validate/validate_pb2.py +0 -76
- union/_protos/workflow/node_execution_service_pb2.py +0 -26
- union/_protos/workflow/node_execution_service_pb2.pyi +0 -4
- union/_protos/workflow/node_execution_service_pb2_grpc.py +0 -32
- union/_protos/workflow/queue_service_pb2.py +0 -75
- union/_protos/workflow/queue_service_pb2.pyi +0 -103
- union/_protos/workflow/queue_service_pb2_grpc.py +0 -172
- union/_protos/workflow/run_definition_pb2.py +0 -100
- union/_protos/workflow/run_definition_pb2.pyi +0 -256
- union/_protos/workflow/run_definition_pb2_grpc.py +0 -4
- union/_protos/workflow/run_logs_service_pb2.py +0 -41
- union/_protos/workflow/run_logs_service_pb2.pyi +0 -28
- union/_protos/workflow/run_logs_service_pb2_grpc.py +0 -69
- union/_protos/workflow/run_service_pb2.py +0 -133
- union/_protos/workflow/run_service_pb2.pyi +0 -173
- union/_protos/workflow/run_service_pb2_grpc.py +0 -412
- union/_protos/workflow/state_service_pb2.py +0 -58
- union/_protos/workflow/state_service_pb2.pyi +0 -69
- union/_protos/workflow/state_service_pb2_grpc.py +0 -138
- union/_protos/workflow/task_definition_pb2.py +0 -72
- union/_protos/workflow/task_definition_pb2.pyi +0 -65
- union/_protos/workflow/task_definition_pb2_grpc.py +0 -4
- union/_protos/workflow/task_service_pb2.py +0 -44
- union/_protos/workflow/task_service_pb2.pyi +0 -31
- union/_protos/workflow/task_service_pb2_grpc.py +0 -104
- union/_resources.py +0 -226
- union/_retry.py +0 -32
- union/_reusable_environment.py +0 -25
- union/_run.py +0 -374
- union/_secret.py +0 -61
- union/_task.py +0 -354
- union/_task_environment.py +0 -186
- union/_timeout.py +0 -47
- union/_tools.py +0 -27
- union/_utils/__init__.py +0 -11
- union/_utils/asyn.py +0 -119
- union/_utils/file_handling.py +0 -71
- union/_utils/helpers.py +0 -46
- union/_utils/lazy_module.py +0 -54
- union/_utils/uv_script_parser.py +0 -49
- union/_version.py +0 -21
- union/connectors/__init__.py +0 -0
- union/errors.py +0 -128
- union/extras/__init__.py +0 -5
- union/extras/_container.py +0 -263
- union/io/__init__.py +0 -11
- union/io/_dataframe.py +0 -0
- union/io/_dir.py +0 -425
- union/io/_file.py +0 -418
- union/io/pickle/__init__.py +0 -0
- union/io/pickle/transformer.py +0 -117
- union/io/structured_dataset/__init__.py +0 -122
- union/io/structured_dataset/basic_dfs.py +0 -219
- union/io/structured_dataset/structured_dataset.py +0 -1057
- union/py.typed +0 -0
- union/remote/__init__.py +0 -23
- union/remote/_client/__init__.py +0 -0
- union/remote/_client/_protocols.py +0 -129
- union/remote/_client/auth/__init__.py +0 -12
- union/remote/_client/auth/_authenticators/__init__.py +0 -0
- union/remote/_client/auth/_authenticators/base.py +0 -391
- union/remote/_client/auth/_authenticators/client_credentials.py +0 -73
- union/remote/_client/auth/_authenticators/device_code.py +0 -120
- union/remote/_client/auth/_authenticators/external_command.py +0 -77
- union/remote/_client/auth/_authenticators/factory.py +0 -200
- union/remote/_client/auth/_authenticators/pkce.py +0 -515
- union/remote/_client/auth/_channel.py +0 -184
- union/remote/_client/auth/_client_config.py +0 -83
- union/remote/_client/auth/_default_html.py +0 -32
- union/remote/_client/auth/_grpc_utils/__init__.py +0 -0
- union/remote/_client/auth/_grpc_utils/auth_interceptor.py +0 -204
- union/remote/_client/auth/_grpc_utils/default_metadata_interceptor.py +0 -144
- union/remote/_client/auth/_keyring.py +0 -154
- union/remote/_client/auth/_token_client.py +0 -258
- union/remote/_client/auth/errors.py +0 -16
- union/remote/_client/controlplane.py +0 -86
- union/remote/_data.py +0 -149
- union/remote/_logs.py +0 -74
- union/remote/_project.py +0 -86
- union/remote/_run.py +0 -820
- union/remote/_secret.py +0 -132
- union/remote/_task.py +0 -193
- union/report/__init__.py +0 -3
- union/report/_report.py +0 -178
- union/report/_template.html +0 -124
- union/storage/__init__.py +0 -24
- union/storage/_remote_fs.py +0 -34
- union/storage/_storage.py +0 -247
- union/storage/_utils.py +0 -5
- union/types/__init__.py +0 -11
- union/types/_renderer.py +0 -162
- union/types/_string_literals.py +0 -120
- union/types/_type_engine.py +0 -2131
- union/types/_utils.py +0 -80
- /flyte/{_cli → _debug}/__init__.py +0 -0
- /flyte/{_protos → _keyring}/__init__.py +0 -0
- {flyte-0.0.1b0.dist-info → flyte-2.0.0b46.dist-info}/WHEEL +0 -0
- {flyte-0.0.1b0.dist-info → flyte-2.0.0b46.dist-info}/top_level.txt +0 -0
flyte/models.py
ADDED
|
@@ -0,0 +1,635 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import enum
|
|
4
|
+
import inspect
|
|
5
|
+
import os
|
|
6
|
+
import pathlib
|
|
7
|
+
import typing
|
|
8
|
+
from dataclasses import dataclass, field, replace
|
|
9
|
+
from typing import TYPE_CHECKING, Any, Callable, ClassVar, Dict, List, Literal, Optional, Tuple, Type
|
|
10
|
+
|
|
11
|
+
import rich.repr
|
|
12
|
+
|
|
13
|
+
from flyte._docstring import Docstring
|
|
14
|
+
from flyte._interface import extract_return_annotation, literal_to_enum
|
|
15
|
+
from flyte._logging import logger
|
|
16
|
+
|
|
17
|
+
if TYPE_CHECKING:
|
|
18
|
+
from flyteidl2.core import literals_pb2
|
|
19
|
+
|
|
20
|
+
from flyte._internal.imagebuild.image_builder import ImageCache
|
|
21
|
+
from flyte.report import Report
|
|
22
|
+
|
|
23
|
+
# --- Constants ----
|
|
24
|
+
MAX_INLINE_IO_BYTES = 10 * 1024 * 1024 # 100 MB
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def generate_random_name() -> str:
|
|
28
|
+
"""
|
|
29
|
+
Generate a random name for the task. This is used to create unique names for tasks.
|
|
30
|
+
TODO we can use unique-namer in the future, for now its just guids
|
|
31
|
+
"""
|
|
32
|
+
from uuid import uuid4
|
|
33
|
+
|
|
34
|
+
return str(uuid4()) # Placeholder for actual random name generation logic
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@rich.repr.auto
|
|
38
|
+
@dataclass(frozen=True, kw_only=True)
|
|
39
|
+
class ActionID:
|
|
40
|
+
"""
|
|
41
|
+
A class representing the ID of an Action, nested within a Run. This is used to identify a specific action on a task.
|
|
42
|
+
"""
|
|
43
|
+
|
|
44
|
+
name: str
|
|
45
|
+
run_name: str | None = None
|
|
46
|
+
project: str | None = None
|
|
47
|
+
domain: str | None = None
|
|
48
|
+
org: str | None = None
|
|
49
|
+
|
|
50
|
+
def __post_init__(self):
|
|
51
|
+
if self.run_name is None:
|
|
52
|
+
object.__setattr__(self, "run_name", self.name)
|
|
53
|
+
|
|
54
|
+
@classmethod
|
|
55
|
+
def create_random(cls):
|
|
56
|
+
name = generate_random_name()
|
|
57
|
+
return cls(name=name, run_name=name)
|
|
58
|
+
|
|
59
|
+
def new_sub_action(self, name: str | None = None) -> ActionID:
|
|
60
|
+
"""
|
|
61
|
+
Create a new sub-run with the given name. If name is None, a random name will be generated.
|
|
62
|
+
"""
|
|
63
|
+
if name is None:
|
|
64
|
+
name = generate_random_name()
|
|
65
|
+
return replace(self, name=name)
|
|
66
|
+
|
|
67
|
+
def new_sub_action_from(self, task_call_seq: int, task_hash: str, input_hash: str, group: str | None) -> ActionID:
|
|
68
|
+
"""Make a deterministic name"""
|
|
69
|
+
import hashlib
|
|
70
|
+
|
|
71
|
+
from flyte._utils.helpers import base36_encode
|
|
72
|
+
|
|
73
|
+
components = f"{self.name}-{input_hash}-{task_hash}-{task_call_seq}" + (f"-{group}" if group else "")
|
|
74
|
+
logger.debug(f"----- Generating sub-action ID from components: {components}")
|
|
75
|
+
# has the components into something deterministic
|
|
76
|
+
bytes_digest = hashlib.md5(components.encode()).digest()
|
|
77
|
+
new_name = base36_encode(bytes_digest)
|
|
78
|
+
return self.new_sub_action(new_name)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@rich.repr.auto
|
|
82
|
+
@dataclass
|
|
83
|
+
class PathRewrite:
|
|
84
|
+
"""
|
|
85
|
+
Configuration for rewriting paths during input loading.
|
|
86
|
+
"""
|
|
87
|
+
|
|
88
|
+
# If set, rewrites any path starting with this prefix to the new prefix.
|
|
89
|
+
old_prefix: str
|
|
90
|
+
new_prefix: str
|
|
91
|
+
|
|
92
|
+
def __post_init__(self):
|
|
93
|
+
if not self.old_prefix or not self.new_prefix:
|
|
94
|
+
raise ValueError("Both old_prefix and new_prefix must be non-empty strings.")
|
|
95
|
+
if self.old_prefix == self.new_prefix:
|
|
96
|
+
raise ValueError("old_prefix and new_prefix must be different.")
|
|
97
|
+
|
|
98
|
+
@classmethod
|
|
99
|
+
def from_str(cls, pattern: str) -> PathRewrite:
|
|
100
|
+
"""
|
|
101
|
+
Create a PathRewrite from a string pattern of the form `old_prefix->new_prefix`.
|
|
102
|
+
"""
|
|
103
|
+
parts = pattern.split("->")
|
|
104
|
+
if len(parts) != 2:
|
|
105
|
+
raise ValueError(f"Invalid path rewrite pattern: {pattern}. Expected format 'old_prefix->new_prefix'.")
|
|
106
|
+
return cls(old_prefix=parts[0], new_prefix=parts[1])
|
|
107
|
+
|
|
108
|
+
def __repr__(self) -> str:
|
|
109
|
+
return f"{self.old_prefix}->{self.new_prefix}"
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
@rich.repr.auto
|
|
113
|
+
@dataclass(frozen=True, kw_only=True)
|
|
114
|
+
class RawDataPath:
|
|
115
|
+
"""
|
|
116
|
+
A class representing the raw data path for a task. This is used to store the raw data for the task execution and
|
|
117
|
+
also get mutations on the path.
|
|
118
|
+
"""
|
|
119
|
+
|
|
120
|
+
path: str
|
|
121
|
+
path_rewrite: Optional[PathRewrite] = None
|
|
122
|
+
|
|
123
|
+
@classmethod
|
|
124
|
+
def from_local_folder(cls, local_folder: str | pathlib.Path | None = None) -> RawDataPath:
|
|
125
|
+
"""
|
|
126
|
+
Create a new context attribute object, with local path given. Will be created if it doesn't exist.
|
|
127
|
+
:return: Path to the temporary directory
|
|
128
|
+
"""
|
|
129
|
+
import tempfile
|
|
130
|
+
|
|
131
|
+
match local_folder:
|
|
132
|
+
case pathlib.Path():
|
|
133
|
+
local_folder.mkdir(parents=True, exist_ok=True)
|
|
134
|
+
return RawDataPath(path=str(local_folder))
|
|
135
|
+
case None:
|
|
136
|
+
# Create a temporary directory for data storage
|
|
137
|
+
p = tempfile.mkdtemp()
|
|
138
|
+
logger.debug(f"Creating temporary directory for data storage: {p}")
|
|
139
|
+
pathlib.Path(p).mkdir(parents=True, exist_ok=True)
|
|
140
|
+
return RawDataPath(path=p)
|
|
141
|
+
case str():
|
|
142
|
+
return RawDataPath(path=local_folder)
|
|
143
|
+
case _:
|
|
144
|
+
raise ValueError(f"Invalid local path {local_folder}")
|
|
145
|
+
|
|
146
|
+
def get_random_remote_path(self, file_name: Optional[str] = None) -> str:
|
|
147
|
+
"""
|
|
148
|
+
Returns a random path for uploading a file/directory to. This file/folder will not be created, it's just a path.
|
|
149
|
+
|
|
150
|
+
:param file_name: If given, will be joined after a randomly generated portion.
|
|
151
|
+
:return:
|
|
152
|
+
"""
|
|
153
|
+
import random
|
|
154
|
+
from uuid import UUID
|
|
155
|
+
|
|
156
|
+
import fsspec
|
|
157
|
+
from fsspec.utils import get_protocol
|
|
158
|
+
|
|
159
|
+
random_string = UUID(int=random.getrandbits(128)).hex
|
|
160
|
+
file_prefix = self.path
|
|
161
|
+
|
|
162
|
+
protocol = get_protocol(file_prefix)
|
|
163
|
+
if "file" in protocol:
|
|
164
|
+
parent_folder = pathlib.Path(file_prefix)
|
|
165
|
+
parent_folder.mkdir(exist_ok=True, parents=True)
|
|
166
|
+
if file_name:
|
|
167
|
+
random_folder = parent_folder / random_string
|
|
168
|
+
random_folder.mkdir()
|
|
169
|
+
local_path = random_folder / file_name
|
|
170
|
+
else:
|
|
171
|
+
local_path = parent_folder / random_string
|
|
172
|
+
return str(local_path.absolute())
|
|
173
|
+
|
|
174
|
+
fs = fsspec.filesystem(protocol)
|
|
175
|
+
if file_prefix.endswith(fs.sep):
|
|
176
|
+
file_prefix = file_prefix[:-1]
|
|
177
|
+
remote_path = fs.sep.join([file_prefix, random_string])
|
|
178
|
+
if file_name:
|
|
179
|
+
remote_path = fs.sep.join([remote_path, file_name])
|
|
180
|
+
return remote_path
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
@rich.repr.auto
|
|
184
|
+
@dataclass(frozen=True)
|
|
185
|
+
class GroupData:
|
|
186
|
+
name: str
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
@rich.repr.auto
|
|
190
|
+
@dataclass(frozen=True, kw_only=True)
|
|
191
|
+
class TaskContext:
|
|
192
|
+
"""
|
|
193
|
+
A context class to hold the current task executions context.
|
|
194
|
+
This can be used to access various contextual parameters in the task execution by the user.
|
|
195
|
+
|
|
196
|
+
:param action: The action ID of the current execution. This is always set, within a run.
|
|
197
|
+
:param version: The version of the executed task. This is set when the task is executed by an action and will be
|
|
198
|
+
set on all sub-actions.
|
|
199
|
+
:param custom_context: Context metadata for the action. If an action receives context, it'll automatically pass it
|
|
200
|
+
to any actions it spawns. Context will not be used for cache key computation.
|
|
201
|
+
"""
|
|
202
|
+
|
|
203
|
+
action: ActionID
|
|
204
|
+
version: str
|
|
205
|
+
raw_data_path: RawDataPath
|
|
206
|
+
input_path: str | None = None
|
|
207
|
+
output_path: str
|
|
208
|
+
run_base_dir: str
|
|
209
|
+
report: Report
|
|
210
|
+
group_data: GroupData | None = None
|
|
211
|
+
checkpoints: Checkpoints | None = None
|
|
212
|
+
code_bundle: CodeBundle | None = None
|
|
213
|
+
compiled_image_cache: ImageCache | None = None
|
|
214
|
+
data: Dict[str, Any] = field(default_factory=dict)
|
|
215
|
+
mode: Literal["local", "remote", "hybrid"] = "remote"
|
|
216
|
+
interactive_mode: bool = False
|
|
217
|
+
custom_context: Dict[str, str] = field(default_factory=dict)
|
|
218
|
+
|
|
219
|
+
def replace(self, **kwargs) -> TaskContext:
|
|
220
|
+
if "data" in kwargs:
|
|
221
|
+
rec_data = kwargs.pop("data")
|
|
222
|
+
if rec_data is None:
|
|
223
|
+
return replace(self, **kwargs)
|
|
224
|
+
data = {}
|
|
225
|
+
if self.data is not None:
|
|
226
|
+
data = self.data.copy()
|
|
227
|
+
data.update(rec_data)
|
|
228
|
+
kwargs.update({"data": data})
|
|
229
|
+
return replace(self, **kwargs)
|
|
230
|
+
|
|
231
|
+
def __getitem__(self, key: str) -> Optional[Any]:
|
|
232
|
+
return self.data.get(key)
|
|
233
|
+
|
|
234
|
+
def is_in_cluster(self):
|
|
235
|
+
"""
|
|
236
|
+
Check if the task is running in a cluster.
|
|
237
|
+
:return: bool
|
|
238
|
+
"""
|
|
239
|
+
return self.mode == "remote"
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
@rich.repr.auto
|
|
243
|
+
@dataclass(frozen=True, kw_only=True)
|
|
244
|
+
class CodeBundle:
|
|
245
|
+
"""
|
|
246
|
+
A class representing a code bundle for a task. This is used to package the code and the inflation path.
|
|
247
|
+
The code bundle computes the version of the code using the hash of the code.
|
|
248
|
+
|
|
249
|
+
:param computed_version: The version of the code bundle. This is the hash of the code.
|
|
250
|
+
:param destination: The destination path for the code bundle to be inflated to.
|
|
251
|
+
:param tgz: Optional path to the tgz file.
|
|
252
|
+
:param pkl: Optional path to the pkl file.
|
|
253
|
+
:param downloaded_path: The path to the downloaded code bundle. This is only available during runtime, when
|
|
254
|
+
the code bundle has been downloaded and inflated.
|
|
255
|
+
"""
|
|
256
|
+
|
|
257
|
+
computed_version: str
|
|
258
|
+
destination: str = "."
|
|
259
|
+
tgz: str | None = None
|
|
260
|
+
pkl: str | None = None
|
|
261
|
+
downloaded_path: pathlib.Path | None = None
|
|
262
|
+
files: List[str] | None = None
|
|
263
|
+
|
|
264
|
+
# runtime_dependencies: Tuple[str, ...] = field(default_factory=tuple) In the future if we want we could add this
|
|
265
|
+
# but this messes up actors, spark etc
|
|
266
|
+
|
|
267
|
+
def __post_init__(self):
|
|
268
|
+
if self.tgz is None and self.pkl is None:
|
|
269
|
+
raise ValueError("Either tgz or pkl must be provided")
|
|
270
|
+
|
|
271
|
+
def with_downloaded_path(self, path: pathlib.Path) -> CodeBundle:
|
|
272
|
+
"""
|
|
273
|
+
Create a new CodeBundle with the given downloaded path.
|
|
274
|
+
"""
|
|
275
|
+
return replace(self, downloaded_path=path)
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
@rich.repr.auto
|
|
279
|
+
@dataclass(frozen=True)
|
|
280
|
+
class Checkpoints:
|
|
281
|
+
"""
|
|
282
|
+
A class representing the checkpoints for a task. This is used to store the checkpoints for the task execution.
|
|
283
|
+
"""
|
|
284
|
+
|
|
285
|
+
prev_checkpoint_path: str | None
|
|
286
|
+
checkpoint_path: str | None
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
class _has_default:
|
|
290
|
+
"""
|
|
291
|
+
A marker class to indicate that a specific input has a default value or not.
|
|
292
|
+
This is used to determine if the input is required or not.
|
|
293
|
+
"""
|
|
294
|
+
|
|
295
|
+
|
|
296
|
+
@dataclass(frozen=True)
|
|
297
|
+
class NativeInterface:
|
|
298
|
+
"""
|
|
299
|
+
A class representing the native interface for a task. This is used to interact with the task and its execution
|
|
300
|
+
context.
|
|
301
|
+
"""
|
|
302
|
+
|
|
303
|
+
inputs: Dict[str, Tuple[Type, Any]]
|
|
304
|
+
outputs: Dict[str, Type]
|
|
305
|
+
docstring: Optional[Docstring] = None
|
|
306
|
+
|
|
307
|
+
# This field is used to indicate that the task has a default value for the input, but already in the
|
|
308
|
+
# remote form.
|
|
309
|
+
_remote_defaults: Optional[Dict[str, literals_pb2.Literal]] = field(default=None, repr=False)
|
|
310
|
+
|
|
311
|
+
has_default: ClassVar[Type[_has_default]] = _has_default # This can be used to indicate if a specific input
|
|
312
|
+
|
|
313
|
+
# has a default value or not, in the case when the default value is not known. An example would be remote tasks.
|
|
314
|
+
|
|
315
|
+
def has_outputs(self) -> bool:
|
|
316
|
+
"""
|
|
317
|
+
Check if the task has outputs. This is used to determine if the task has outputs or not.
|
|
318
|
+
"""
|
|
319
|
+
return self.outputs is not None and len(self.outputs) > 0
|
|
320
|
+
|
|
321
|
+
def required_inputs(self) -> List[str]:
|
|
322
|
+
"""
|
|
323
|
+
Get the names of the required inputs for the task. This is used to determine which inputs are required for the
|
|
324
|
+
task execution.
|
|
325
|
+
:return: A list of required input names.
|
|
326
|
+
"""
|
|
327
|
+
return [k for k, v in self.inputs.items() if v[1] is inspect.Parameter.empty]
|
|
328
|
+
|
|
329
|
+
def num_required_inputs(self) -> int:
|
|
330
|
+
"""
|
|
331
|
+
Get the number of required inputs for the task. This is used to determine how many inputs are required for the
|
|
332
|
+
task execution.
|
|
333
|
+
"""
|
|
334
|
+
return sum(1 for t in self.inputs.values() if t[1] is inspect.Parameter.empty)
|
|
335
|
+
|
|
336
|
+
@classmethod
|
|
337
|
+
def from_types(
|
|
338
|
+
cls,
|
|
339
|
+
inputs: Dict[str, Tuple[Type, Type[_has_default] | Type[inspect._empty]]],
|
|
340
|
+
outputs: Dict[str, Type],
|
|
341
|
+
default_inputs: Optional[Dict[str, literals_pb2.Literal]] = None,
|
|
342
|
+
) -> NativeInterface:
|
|
343
|
+
"""
|
|
344
|
+
Create a new NativeInterface from the given types. This is used to create a native interface for the task.
|
|
345
|
+
:param inputs: A dictionary of input names and their types and a value indicating if they have a default value.
|
|
346
|
+
:param outputs: A dictionary of output names and their types.
|
|
347
|
+
:param default_inputs: Optional dictionary of default inputs for remote tasks.
|
|
348
|
+
:return: A NativeInterface object with the given inputs and outputs.
|
|
349
|
+
"""
|
|
350
|
+
for k, v in inputs.items():
|
|
351
|
+
if v[1] is cls.has_default and (default_inputs is None or k not in default_inputs):
|
|
352
|
+
raise ValueError(f"Input {k} has a default value but no default input provided for remote task.")
|
|
353
|
+
return cls(inputs=inputs, outputs=outputs, _remote_defaults=default_inputs)
|
|
354
|
+
|
|
355
|
+
@classmethod
|
|
356
|
+
def from_callable(cls, func: Callable) -> NativeInterface:
|
|
357
|
+
"""
|
|
358
|
+
Extract the native interface from the given function. This is used to create a native interface for the task.
|
|
359
|
+
"""
|
|
360
|
+
# Get function parameters, defaults, varargs info (POSITIONAL_ONLY, VAR_POSITIONAL, KEYWORD_ONLY, etc.).
|
|
361
|
+
sig = inspect.signature(func)
|
|
362
|
+
|
|
363
|
+
# Extract parameter details (name, type, default value)
|
|
364
|
+
param_info = {}
|
|
365
|
+
try:
|
|
366
|
+
# Get fully evaluated, real Python types for type checking.
|
|
367
|
+
hints = typing.get_type_hints(func, include_extras=True)
|
|
368
|
+
except Exception as e:
|
|
369
|
+
logger.warning(f"Could not get type hints for function {func.__name__}: {e}")
|
|
370
|
+
raise
|
|
371
|
+
|
|
372
|
+
for name, param in sig.parameters.items():
|
|
373
|
+
if param.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD):
|
|
374
|
+
raise ValueError(f"Function {func.__name__} cannot have variable positional or keyword arguments.")
|
|
375
|
+
if param.annotation is inspect.Parameter.empty:
|
|
376
|
+
logger.warning(
|
|
377
|
+
f"Function {func.__name__} has parameter {name} without type annotation. Data will be pickled."
|
|
378
|
+
)
|
|
379
|
+
arg_type = hints.get(name, param.annotation)
|
|
380
|
+
if typing.get_origin(arg_type) is Literal:
|
|
381
|
+
param_info[name] = (literal_to_enum(arg_type), param.default)
|
|
382
|
+
else:
|
|
383
|
+
param_info[name] = (arg_type, param.default)
|
|
384
|
+
|
|
385
|
+
# Get return type
|
|
386
|
+
outputs = extract_return_annotation(hints.get("return", sig.return_annotation))
|
|
387
|
+
|
|
388
|
+
# Parse docstring if available
|
|
389
|
+
docstring = Docstring(callable_=func) if func.__doc__ else None
|
|
390
|
+
|
|
391
|
+
return cls(inputs=param_info, outputs=outputs, docstring=docstring)
|
|
392
|
+
|
|
393
|
+
def convert_to_kwargs(self, *args, **kwargs) -> Dict[str, Any]:
|
|
394
|
+
"""
|
|
395
|
+
Convert the given arguments to keyword arguments based on the native interface. This is used to convert the
|
|
396
|
+
arguments to the correct types for the task execution.
|
|
397
|
+
"""
|
|
398
|
+
# Convert positional arguments to keyword arguments
|
|
399
|
+
if len(args) > len(self.inputs):
|
|
400
|
+
raise ValueError(
|
|
401
|
+
f"Too many positional arguments provided, expected inputs {self.inputs.keys()}, args {len(args)}"
|
|
402
|
+
)
|
|
403
|
+
for arg, input_name in zip(args, self.inputs.keys()):
|
|
404
|
+
kwargs[input_name] = arg
|
|
405
|
+
if len(kwargs) > len(self.inputs):
|
|
406
|
+
raise ValueError(
|
|
407
|
+
f"Too many keyword arguments provided, expected inputs {self.inputs.keys()}, args {kwargs.keys()}"
|
|
408
|
+
)
|
|
409
|
+
return kwargs
|
|
410
|
+
|
|
411
|
+
def get_input_types(self) -> Dict[str, Type]:
|
|
412
|
+
"""
|
|
413
|
+
Get the input types for the task. This is used to get the types of the inputs for the task execution.
|
|
414
|
+
"""
|
|
415
|
+
return {k: v[0] for k, v in self.inputs.items()}
|
|
416
|
+
|
|
417
|
+
def __repr__(self):
|
|
418
|
+
"""
|
|
419
|
+
Returns a string representation of the task interface.
|
|
420
|
+
"""
|
|
421
|
+
|
|
422
|
+
def format_type(tpe):
|
|
423
|
+
"""Format a type for display in the interface repr."""
|
|
424
|
+
if isinstance(tpe, str):
|
|
425
|
+
return tpe
|
|
426
|
+
# For simple types (int, str, etc.) use __name__
|
|
427
|
+
# For generic types (list[str], dict[str, int]) use repr()
|
|
428
|
+
# For union types (int | str) use repr()
|
|
429
|
+
if isinstance(tpe, type) and not hasattr(tpe, "__origin__"):
|
|
430
|
+
# Simple type like int, str
|
|
431
|
+
return tpe.__name__
|
|
432
|
+
# Generic types, unions, or other complex types - use repr
|
|
433
|
+
return repr(tpe)
|
|
434
|
+
|
|
435
|
+
i = "("
|
|
436
|
+
if self.inputs:
|
|
437
|
+
initial = True
|
|
438
|
+
for key, tpe in self.inputs.items():
|
|
439
|
+
if not initial:
|
|
440
|
+
i += ", "
|
|
441
|
+
initial = False
|
|
442
|
+
tp = format_type(tpe[0])
|
|
443
|
+
i += f"{key}: {tp}"
|
|
444
|
+
if tpe[1] is not inspect.Parameter.empty:
|
|
445
|
+
if tpe[1] is self.has_default:
|
|
446
|
+
i += " = ..."
|
|
447
|
+
else:
|
|
448
|
+
i += f" = {tpe[1]}"
|
|
449
|
+
i += ")"
|
|
450
|
+
if self.outputs:
|
|
451
|
+
initial = True
|
|
452
|
+
multi = len(self.outputs) > 1
|
|
453
|
+
i += " -> "
|
|
454
|
+
if multi:
|
|
455
|
+
i += "("
|
|
456
|
+
for key, tpe in self.outputs.items():
|
|
457
|
+
if not initial:
|
|
458
|
+
i += ", "
|
|
459
|
+
initial = False
|
|
460
|
+
tp = format_type(tpe)
|
|
461
|
+
i += f"{key}: {tp}"
|
|
462
|
+
if multi:
|
|
463
|
+
i += ")"
|
|
464
|
+
return i + ":"
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@dataclass
|
|
468
|
+
class SerializationContext:
|
|
469
|
+
"""
|
|
470
|
+
This object holds serialization time contextual information, that can be used when serializing the task and
|
|
471
|
+
various parameters of a tasktemplate. This is only available when the task is being serialized and can be
|
|
472
|
+
during a deployment or runtime.
|
|
473
|
+
|
|
474
|
+
:param version: The version of the task
|
|
475
|
+
:param code_bundle: The code bundle for the task. This is used to package the code and the inflation path.
|
|
476
|
+
:param input_path: The path to the inputs for the task. This is used to determine where the inputs will be located
|
|
477
|
+
:param output_path: The path to the outputs for the task. This is used to determine where the outputs will be
|
|
478
|
+
located
|
|
479
|
+
"""
|
|
480
|
+
|
|
481
|
+
version: str
|
|
482
|
+
project: str | None = None
|
|
483
|
+
domain: str | None = None
|
|
484
|
+
org: str | None = None
|
|
485
|
+
code_bundle: Optional[CodeBundle] = None
|
|
486
|
+
input_path: str = "{{.input}}"
|
|
487
|
+
output_path: str = "{{.outputPrefix}}"
|
|
488
|
+
interpreter_path: str = "/opt/venv/bin/python"
|
|
489
|
+
image_cache: ImageCache | None = None
|
|
490
|
+
root_dir: Optional[pathlib.Path] = None
|
|
491
|
+
|
|
492
|
+
def get_entrypoint_path(self, interpreter_path: Optional[str] = None) -> str:
|
|
493
|
+
"""
|
|
494
|
+
Get the entrypoint path for the task. This is used to determine the entrypoint for the task execution.
|
|
495
|
+
:param interpreter_path: The path to the interpreter (python)
|
|
496
|
+
"""
|
|
497
|
+
if interpreter_path is None:
|
|
498
|
+
interpreter_path = self.interpreter_path
|
|
499
|
+
return os.path.join(os.path.dirname(interpreter_path), "runtime.py")
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
# --- Phase Enum ---
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
class ActionPhase(str, enum.Enum):
|
|
506
|
+
"""
|
|
507
|
+
Represents the execution phase of a Flyte action (run).
|
|
508
|
+
|
|
509
|
+
Actions progress through different phases during their lifecycle:
|
|
510
|
+
- Queued: Action is waiting to be scheduled
|
|
511
|
+
- Waiting for resources: Action is waiting for compute resources
|
|
512
|
+
- Initializing: Action is being initialized
|
|
513
|
+
- Running: Action is currently executing
|
|
514
|
+
- Succeeded: Action completed successfully
|
|
515
|
+
- Failed: Action failed during execution
|
|
516
|
+
- Aborted: Action was manually aborted
|
|
517
|
+
- Timed out: Action exceeded its timeout limit
|
|
518
|
+
|
|
519
|
+
This enum can be used for filtering runs and checking execution status.
|
|
520
|
+
|
|
521
|
+
Example:
|
|
522
|
+
>>> from flyte.models import ActionPhase
|
|
523
|
+
>>> from flyte.remote import Run
|
|
524
|
+
>>>
|
|
525
|
+
>>> # Filter runs by phase
|
|
526
|
+
>>> runs = Run.listall(in_phase=(ActionPhase.SUCCEEDED, ActionPhase.FAILED))
|
|
527
|
+
>>>
|
|
528
|
+
>>> # Check if a run succeeded
|
|
529
|
+
>>> run = Run.get("my-run")
|
|
530
|
+
>>> if run.phase == ActionPhase.SUCCEEDED:
|
|
531
|
+
... print("Success!")
|
|
532
|
+
>>>
|
|
533
|
+
>>> # Check if phase is terminal
|
|
534
|
+
>>> if run.phase.is_terminal:
|
|
535
|
+
... print("Run completed")
|
|
536
|
+
"""
|
|
537
|
+
|
|
538
|
+
QUEUED = "queued"
|
|
539
|
+
"""Action is waiting to be scheduled."""
|
|
540
|
+
|
|
541
|
+
WAITING_FOR_RESOURCES = "waiting_for_resources"
|
|
542
|
+
"""Action is waiting for compute resources to become available."""
|
|
543
|
+
|
|
544
|
+
INITIALIZING = "initializing"
|
|
545
|
+
"""Action is being initialized and prepared for execution."""
|
|
546
|
+
|
|
547
|
+
RUNNING = "running"
|
|
548
|
+
"""Action is currently executing."""
|
|
549
|
+
|
|
550
|
+
SUCCEEDED = "succeeded"
|
|
551
|
+
"""Action completed successfully."""
|
|
552
|
+
|
|
553
|
+
FAILED = "failed"
|
|
554
|
+
"""Action failed during execution."""
|
|
555
|
+
|
|
556
|
+
ABORTED = "aborted"
|
|
557
|
+
"""Action was manually aborted by a user."""
|
|
558
|
+
|
|
559
|
+
TIMED_OUT = "timed_out"
|
|
560
|
+
"""Action exceeded its timeout limit and was terminated."""
|
|
561
|
+
|
|
562
|
+
@property
|
|
563
|
+
def is_terminal(self) -> bool:
|
|
564
|
+
"""
|
|
565
|
+
Check if this phase represents a terminal (final) state.
|
|
566
|
+
|
|
567
|
+
Terminal phases are: SUCCEEDED, FAILED, ABORTED, TIMED_OUT.
|
|
568
|
+
Once an action reaches a terminal phase, it will not transition to any other phase.
|
|
569
|
+
|
|
570
|
+
Returns:
|
|
571
|
+
True if this is a terminal phase, False otherwise
|
|
572
|
+
"""
|
|
573
|
+
return self in (
|
|
574
|
+
ActionPhase.SUCCEEDED,
|
|
575
|
+
ActionPhase.FAILED,
|
|
576
|
+
ActionPhase.ABORTED,
|
|
577
|
+
ActionPhase.TIMED_OUT,
|
|
578
|
+
)
|
|
579
|
+
|
|
580
|
+
def to_protobuf_name(self) -> str:
|
|
581
|
+
"""
|
|
582
|
+
Convert to protobuf enum name format.
|
|
583
|
+
|
|
584
|
+
Returns:
|
|
585
|
+
Protobuf enum name (e.g., "ACTION_PHASE_QUEUED")
|
|
586
|
+
|
|
587
|
+
Example:
|
|
588
|
+
>>> ActionPhase.QUEUED.to_protobuf_name()
|
|
589
|
+
'ACTION_PHASE_QUEUED'
|
|
590
|
+
"""
|
|
591
|
+
return f"ACTION_PHASE_{self.value.upper()}"
|
|
592
|
+
|
|
593
|
+
def to_protobuf_value(self) -> int:
|
|
594
|
+
"""
|
|
595
|
+
Convert to protobuf enum integer value.
|
|
596
|
+
|
|
597
|
+
Returns:
|
|
598
|
+
Protobuf enum integer value
|
|
599
|
+
|
|
600
|
+
Example:
|
|
601
|
+
>>> ActionPhase.QUEUED.to_protobuf_value()
|
|
602
|
+
1
|
|
603
|
+
"""
|
|
604
|
+
from flyteidl2.common import phase_pb2
|
|
605
|
+
|
|
606
|
+
return phase_pb2.ActionPhase.Value(self.to_protobuf_name())
|
|
607
|
+
|
|
608
|
+
@classmethod
|
|
609
|
+
def from_protobuf(cls, pb_phase: Any) -> "ActionPhase":
|
|
610
|
+
"""
|
|
611
|
+
Create ActionPhase from protobuf phase value.
|
|
612
|
+
|
|
613
|
+
Args:
|
|
614
|
+
pb_phase: Protobuf ActionPhase enum value
|
|
615
|
+
|
|
616
|
+
Returns:
|
|
617
|
+
Corresponding ActionPhase enum member
|
|
618
|
+
|
|
619
|
+
Raises:
|
|
620
|
+
ValueError: If protobuf phase is UNSPECIFIED or unknown
|
|
621
|
+
|
|
622
|
+
Example:
|
|
623
|
+
>>> from flyteidl2.common import phase_pb2
|
|
624
|
+
>>> ActionPhase.from_protobuf(phase_pb2.ACTION_PHASE_QUEUED)
|
|
625
|
+
<ActionPhase.QUEUED: 'queued'>
|
|
626
|
+
"""
|
|
627
|
+
from flyteidl2.common import phase_pb2
|
|
628
|
+
|
|
629
|
+
name = phase_pb2.ActionPhase.Name(pb_phase)
|
|
630
|
+
if name == "ACTION_PHASE_UNSPECIFIED":
|
|
631
|
+
raise ValueError("Cannot convert UNSPECIFIED phase to ActionPhase")
|
|
632
|
+
|
|
633
|
+
# Remove "ACTION_PHASE_" prefix and convert to lowercase
|
|
634
|
+
phase_value = name.replace("ACTION_PHASE_", "").lower()
|
|
635
|
+
return cls(phase_value)
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Prefetch utilities for Flyte.
|
|
3
|
+
|
|
4
|
+
This module provides functionality to prefetch various artifacts from remote registries,
|
|
5
|
+
such as HuggingFace models.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from ._hf_model import (
|
|
9
|
+
HuggingFaceModelInfo,
|
|
10
|
+
ShardConfig,
|
|
11
|
+
StoredModelInfo,
|
|
12
|
+
VLLMShardArgs,
|
|
13
|
+
hf_model,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"HuggingFaceModelInfo",
|
|
18
|
+
"ShardConfig",
|
|
19
|
+
"StoredModelInfo",
|
|
20
|
+
"VLLMShardArgs",
|
|
21
|
+
"hf_model",
|
|
22
|
+
]
|